diff --git a/.ghci b/.ghci
new file mode 100644
--- /dev/null
+++ b/.ghci
@@ -0,0 +1,1 @@
+:set -isrc
diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,45 @@
+dist
+cabal-dev
+.hsenv
+*.md
+*.o
+*.hi
+*.chi
+*.chs.h
+.virthualenv
+*.a
+*.cmxa
+*.cm[oxai]
+*.annot
+*.vmap
+*.di?
+*.native
+*.fqout
+*.out
+*.fq
+*.bfq
+*.annot
+*.cgi
+*.log
+*.html
+*.pyc
+build.sh
+config.make
+*.scalarlog
+*.tags
+_build
+*~
+*.swp
+*.swo
+
+/.stack-work/
+/.vagrant/
+TAGS
+a.out
+*.json
+js/
+css/
+
+*.smt2
+.liquid
+.dir-locals.el
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "liquid-fixpoint"]
+	path = liquid-fixpoint
+	url = https://github.com/ucsd-progsys/liquid-fixpoint.git
+[submodule "ghc-options"]
+	path = ghc-options
+	url = https://github.com/ranjitjhala/ghc-options.git
+[submodule "liquiddesugar"]
+	path = liquiddesugar
+	url = https://github.com/christetreault/liquiddesugar.git
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,70 @@
+sudo: false
+language: c
+
+# Only build master, develop, and PRs
+branches:
+  only:
+  - master
+  - develop
+
+addons:
+  apt:
+    packages:
+    - libgmp-dev
+    - z3
+
+# Caching so the next build will be fast too.
+cache:
+  directories:
+    - $HOME/.stack
+    - .stack-work
+
+before_install:
+# Download and unpack the stack executable
+- 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'
+- travis_retry stack install cabal-install
+# - scripts/travis install_smt "$SMT"
+
+env:
+  global:
+  # - STACK=1.0.0.0
+  - SMT=z3
+  - GHC=ghc-7.10.3
+  matrix:
+  - TESTS=Unit/
+  - TESTS=Benchmarks/text
+  - TESTS=Benchmarks/bytestring
+  - TESTS=Benchmarks/esop
+  - TESTS=Benchmarks/vect-algs
+  - TESTS=Benchmarks/icfp*
+
+ # ugh... Classify.hs is too slow and makes travis think the build is stalled
+ # - TESTS=hscolour
+
+# This line does all of the work: installs GHC if necessary, build the library,
+# executables, and test suites, and runs the test suites. --no-terminal works
+# around some quirks in Travis's terminal implementation.
+#script:
+#- stack $ARGS --no-terminal --install-ghc test liquidhaskell --haddock --no-haddock-deps --test-arguments "-j2 -p $TESTS"
+
+install:
+ # - scripts/travis install_stack "$STACK"
+ - scripts/travis configure_stack "$GHC"
+ - scripts/travis setup_ghc
+ - scripts/travis install_dependencies
+
+script:
+ - scripts/travis do_build && scripts/travis do_test "$TESTS" "$SMT"
+
+after_failure:
+ - scripts/travis dump_fail_logs
+
+notifications:
+  slack:
+    rooms:
+      secure: CPaI+XVTUSM9gLQefB8zSXazawNIaUnClS7FwaujPfM37hNBm5UIoiC80KBEe0KZKBr+Gt/LWq0zv506Zl/vILuPpVmfSi2BQ8zyyKCBbUrE/E0uBTjmT7wjaITf/mn3mqiLLcHbAVXI1bn7HzVvAq4S4eIpttgCapF7pbMhZCk=
+    on_success: change
+    on_failure: always
+    on_start: never
diff --git a/AwakeTODO.md b/AwakeTODO.md
new file mode 100644
--- /dev/null
+++ b/AwakeTODO.md
@@ -0,0 +1,6 @@
+- see the Category issue
+- set-up atom
+- see Jeff's thread on Monoids
+- write a prefix checker
+- check the parser paper
+- check gab's slides
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,169 @@
+# Changes
+
+## NEXT
+
+- **breaking change** Remove the `Bool` vs. `Prop` distinction. This means that: 
+
+    * signatures that use(d) `Prop` as a type, e.g. 
+      `foo :: Int -> Prop` should just be `foo :: Int -> Bool`.
+
+    * refinements that use(d) `Prop v` e.g. 
+      `isNull :: xs:[a] -> {v:Bool | Prop v <=> len xs > 0}`
+      should just be `isNull :: xs:[a] -> {v:Bool | v <=> len xs > 0}`.
+
+- Add `--eliminate={none, some, all}`. Here
+  * `none` means don't use eliminate at all, use qualifiers everywhere (old-style)
+  * `some` which is the **DEFAULT**  -- means eliminate all the **non-cut** variables
+  * `all`  means eliminate where you can, and solve *cut* variables to `True`.
+
+- Change `--higherorder` so that it uses *only* the qualifiers obtained from
+  type aliases (e.g. `type Nat = {v:Int | ... }`) and nothing else. This
+  requires `eliminate=some`.
+
+- Add a `--json` flag that runs in quiet mode where all output is
+  suppressed and only the list of errors is returned as a JSON object to be
+  consumed by an editor.
+
+- Add `--checks` flag (formerly `--binders`), which checks a given binder's
+  definition, assuming specified types for all callees (but inferring types for
+  callees without signatures.)
+
+- Add `--time-binds` which is like the above, but checks all binders in a module
+  and prints out time taken for each.
+
+## 0.5.0.1
+
+- Fixed a bug in the specification for `Data.Traversable.sequence`
+- Make interpreted mul and div the default, when `solver = z3`
+- Use `--higherorder` to allow higher order binders into the fixpoint environment 
+
+## 0.5.0.0
+
+- Added support for building with `stack`
+
+- Added support for GHC 7.10 (in addition to 7.8)
+
+- Added '--cabaldir' option that will automatically find a .cabal file in the ancestor
+  path from which the target file belongs, and then add the relevant source and dependencies
+  to the paths searched for by LiquidHaskell.
+
+  This means we don't have to manually do `-i src` etc. when checking large projects,
+  which can be tedious e.g. within emacs.
+
+
+## 0.4.0.0
+
+- Bounds as an alternative for logical constraints see `benchmarks/icfp15/pos/Overview.lhs`
+
+## 0.3.0.0
+
+- Logical constraints: add extra subtyping constraints to signatures, e.g.
+
+    {-@ 
+    (.) :: forall <p :: b -> c -> Prop, q :: a -> b -> Prop, r :: a -> c -> Prop>. 
+           {x::a, w::b<q x> |- c<p w> <: c<r x>}
+           (y:b -> c<p y>)
+        -> (z:a -> b<q z>)
+        ->  x:a -> c<r x>
+    @-}
+    (.) f g x = f (g x)
+
+- Inlining haskell functions as predicates and expressions, e.g.
+
+    {-@ inline max @-}
+    max x y = if x >= y then x else y
+
+- Refining class instances. For example
+
+    {-@ instance Compare Int where
+        cmax :: Odd -> Odd -> Odd @-}
+
+- Major restructuring of internal APIs
+
+## 0.2.1.0
+- Experimental support for lifting haskell functions to measures
+If you annotate a Haskell function `foo` with {-@ measure foo @-}, LiquidHaskell will attempt to derive an equivalent measure from `foo`'s definition. This should help eliminate some boilerplate measures that used to be required.
+
+## 0.2.0.0
+
+- Move to GHC-7.8.3
+LiquidHaskell now *requires* ghc-7.8.3.
+
+- Termination
+LiquidHaskell will now attempt to prove all recursive functions terminating. It tries to prove that some parameter (or combination thereof) decreases at each recursive callsite. By default, this will be the first parameter with an associated size measure (see Size Measures), but can be overridden with the `Decreases` annotation or a termination expression (see Termination Expressions). 
+
+If proving termination is too big of burden, it can be disabled on a per-module basis with the `--no-termination` flag, or on a per-function basis with the `Lazy` annotation.
+
+- Size Measures
+Data declarations now optionally take a *size measure*, which LiquidHaskell will use to prove termination of recursive functions. The syntax is:
+
+    {-@ data List a [len] = Nil | Cons a (List a) @-}
+
+- Termination Expressions
+Termination Expressions can be used to specify the decreasing metric of a recursive function. They can be any valid LiquidHaskell expression and must be placed after the function's LiquidHaskell type, e.g.
+
+    {-@ map :: (a -> b) -> xs:[a] -> [a] / [len xs] @-}
+
+- Type Holes
+To reduce the annotation burden, LiquidHaskell now accepts `_` as a placeholder for types and refinements. It can take the place of any base Haskell type and LiquidHaskell will query GHC to fill in the blanks, or it can take the place of a refinement predicate, in which case LiquidHaskell will infer an appropriate refinement. For example,
+
+    {-@ add :: x:_ -> y:_ -> {v:_ | v = x + y} @-}
+    add x y = x + y
+
+becomes
+
+    {-@ add :: Num a => x:a -> y:a -> {v:a | v = x + y} @-}
+    add x y = x + y
+
+- Assumed Specifications
+The `assume` annotation now works as you might expect it to, i.e. LiquidHaskell will *not* verify that the implementation is correct. Furthermore, `assume` can be used to locally override the type of an imported function.
+
+- Derived Measure Selectors
+Given a data definition
+
+    {-@ data Foo = Foo { bar :: Int, baz :: Bool } @-}
+
+LiquidHaskell will automatically derive measures
+
+    {-@ measure bar :: Foo -> Int @-}
+    {-@ measure baz :: Foo -> Bool @-}
+
+- Type-Class Specifications
+LiquidHaskell can now verify prove that type-class instances satisfy a specification. Simply use the new `class` annotation
+
+    {-@ class Num a where
+          (+) :: x:a -> y:a -> {v:a | v = x + y}
+          (-) :: x:a -> y:a -> {v:a | v = x - y}
+          ...
+      @-}
+
+and LiquidHaskell will attempt to prove at each instance declaration that the implementations satisfy the class specification.
+
+When defining type-class specifications you may find the need to use overloaded measures, to allow for type-specific definitions (see Type-Indexed Measures).
+
+- Type-Indexed Measures
+LiquidHaskell now accepts measures with *type-specific* definitions, e.g. a measure to describe the size of a value. Such measures are defined using the `class measure` syntax
+
+    {-@ class measure size :: forall a. a -> Int @-}
+
+and instances can be defined using the `instance measure` syntax, which mirrors the regular measure syntax
+
+    {-@ instance measure size :: [a] -> Int
+        size ([])   = 0
+        size (x:xs) = 1 + size xs
+      @-}
+    {-@ instance measure size :: Tree a -> Int
+        size (Leaf)       = 0
+        size (Node l x r) = 1 + size l + size r
+      @-}
+
+- Parsing
+We have greatly improved our parser to require fewer parentheses! Yay!
+
+- Emacs/Vim Support
+LiquidHaskell now comes with syntax checkers for [flycheck](https://github.com/flycheck/flycheck) in Emacs and [syntastic](https://github.com/scrooloose/syntastic) in Vim. 
+
+- Incremental Checking
+LiquidHaskell has a new `--diffcheck` flag that will only check binders that have changed since the last run, which can drastically improve verification times.
+
+- Experimental Support for Z3's theory of real numbers with the `--real` flag.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,4 @@
+Contributing
+------------
+
+Pull requests should be created against *develop* branch.
diff --git a/FAILING_TESTS.txt b/FAILING_TESTS.txt
new file mode 100644
--- /dev/null
+++ b/FAILING_TESTS.txt
@@ -0,0 +1,18 @@
+      
+Language/Haskell/HsColour/Anchors.hs:         FAIL (683.88s)
+  Wrong exit code
+  expected: ExitSuccess
+  but got: ExitFailure 1
+
+Language/Haskell/HsColour/ACSS.hs:            FAIL (1.70s)
+  Wrong exit code
+  expected: ExitSuccess
+  but got: ExitFailure 2
+
+FindRec.hs:                                   FAIL (9.65s)
+  --eliminate crashes due to `cannot unify Tuple with FHandle error`.
+  A cons-gen bug tickled by --eliminate?
+
+CopyRec.hs:                                   FAIL (42.90s)
+  --eliminate seems to blow up (lack of pattern-inline)?
+
diff --git a/HLint.hs b/HLint.hs
new file mode 100644
--- /dev/null
+++ b/HLint.hs
@@ -0,0 +1,5 @@
+import "hint" HLint.Default
+import "hint" HLint.Dollar
+
+ignore "Eta reduce"
+ignore "Use ."
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644
--- /dev/null
+++ b/INSTALL.md
@@ -0,0 +1,77 @@
+# Install LiquidHaskell
+
+To run `liquid` you need to install:
+
+1. An SMT solver
+2. The `liquid` binary via package manager *or* source.
+
+
+## Step 1: Install SMT Solver
+
+Download and install *at least one* of
+
++ [Z3](https://github.com/Z3Prover/z3/releases)
++ [CVC4](http://cvc4.cs.nyu.edu/)
++ [MathSat](http://mathsat.fbk.eu/download.html)
+
+
+## Step 2: Install `liquid` via Package Manager
+
+Simply do:
+
+    cabal install liquidhaskell
+
+We are working to put `liquid` on `stackage`.
+
+Note: Currently, LiquidHaskell on hackage does not compile against GHC 8.
+Please make sure you are installing with GHC version less than 8. You can
+designate a specific version of LiquidHaskell to ensure that the correct
+GHC version is in the environment. As an example,
+
+    cabal install liquidhaskell-0.6.0.0
+
+## Step 2: Install `liquid` from Source
+
+If you want the most recent version, you can build from source as follows,
+either using `stack` (recommended) or `cabal`. In either case: *recursively*
+clone the repo and then build:
+
+### Build with `stack` (recommended)
+
+This requires that you have installed [stack][stack] (which we strongly recommend!)
+
+    git clone --recursive git@github.com:ucsd-progsys/liquidhaskell.git
+    cd liquidhaskell
+    stack install
+
+## Build with `cabal`
+
+    git clone --recursive git@github.com:ucsd-progsys/liquidhaskell.git
+    cd liquidhaskell
+
+    cabal sandbox init
+    cabal sandbox add-source ./liquid-fixpoint
+    cabal sandbox add-source ./liquiddesugar
+    cabal install
+
+## Troubleshooting
+
+
+1. If you're on Windows, please make sure the SMT solver is installed
+    in the **same** directory as LiquidHaskell itself (i.e. wherever
+    `cabal` or `stack` puts your binaries). That is, do:
+
+    ```
+    which liquid
+    ```
+
+    and make sure that `z3` or `cvc4` or `mathsat` are in the `PATH`
+    returned by the above.
+
+2. If you installed via `stack` and are experiencing path related woes, try:
+
+    ```
+    stack exec -- liquid path/to/file.hs
+    ```
+
+[stack]: https://github.com/commercialhaskell/stack/blob/master/doc/install_and_upgrade.md
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,110 @@
+THREADS=1
+SMTSOLVER=z3
+
+FASTOPTS=-O0
+DISTOPTS=-O2
+PROFOPTS=-O2 --enable-library-profiling --enable-executable-profiling
+LIQUIDOPTS=
+
+CABAL=cabal
+CABALI=$(CABAL) install
+CABALP=$(CABAL) install --enable-library-profiling
+
+# to deal with cabal sandboxes using dist/dist-sandbox-xxxxxx/build/test/test
+# TASTY=find dist -type f -name test | head -n1
+TASTY=./dist/build/test/test
+
+DEPS=--dependencies-only
+
+##############################################################################
+##############################################################################
+##############################################################################
+
+fast:
+	$(CABAL) install -fdevel $(FASTOPTS)
+
+first:
+	$(CABAL) install $(FASTOPTS) --only-dependencies --enable-tests --enable-benchmarks
+
+dist:
+	# $(CABAL) install $(DISTOPTS)
+	$(CABAL) configure -fdevel --enable-tests --disable-library-profiling -O2
+	$(CABAL) build
+	
+prof:
+	$(CABAL) install $(PROFOPTS)
+
+igotgoto:
+	$(CABAL) build $(OPTS)
+	cp dist/build/liquid/liquid ~/.cabal/bin/
+
+clean:
+	cabal clean
+
+docs:
+	$(CABAL) hscolour
+	$(CABAL) haddock --hoogle
+
+deps:
+	$(CABALI) $(DEPS)
+
+pdeps:
+	$(CABALP) $(DEPS)
+
+all-test-py:
+	cd tests && ./regrtest.py -a -t $(THREADS) && cd ../
+
+test-py:
+	cd tests && ./regrtest.py -t $(THREADS) && cd ../
+
+test:
+	$(CABAL) configure -fdevel --enable-tests --disable-library-profiling -O2
+	$(CABAL) build
+	$(CABAL) exec $(TASTY) -- --smtsolver $(SMTSOLVER) --hide-successes --rerun-update -p 'Unit/' -j$(THREADS) +RTS -N$(THREADS) -RTS
+	# $(CABAL) exec $(TASTY) -- --smtsolver $(SMTSOLVER) --liquid-opts='$(LIQUIDOPTS)' --hide-successes --rerun-update -p 'Unit/' -j$(THREADS) +RTS -N$(THREADS) -RTS
+
+test710:
+	$(CABAL) configure -fdevel --enable-tests --disable-library-profiling -O2
+	$(CABAL) build
+	$(TASTY) --smtsolver $(SMTSOLVER) --hide-successes --rerun-update -p 'Unit/' -j$(THREADS) +RTS -N$(THREADS) -RTS
+
+
+retest:
+	cabal configure -fdevel --enable-tests --disable-library-profiling -O2
+	cabal build
+	cabal exec $(TASTY) -- --smtsolver $(SMTSOLVER) --hide-successes --rerun-filter "exceptions,failures,new" --rerun-update -p 'Unit/' -j$(THREADS) +RTS -N$(THREADS) -RTS
+
+all-test:
+	cabal configure -fdevel --enable-tests --disable-library-profiling -O2
+	cabal build
+	cabal exec $(TASTY) -- --smtsolver $(SMTSOLVER) --hide-successes --rerun-update -j$(THREADS) +RTS -N$(THREADS) -RTS
+
+all-test-710:
+	cabal configure -fdevel --enable-tests --disable-library-profiling -O2
+	cabal build
+	$(TASTY) --smtsolver $(SMTSOLVER) --hide-successes --rerun-update -j$(THREADS) +RTS -N$(THREADS) -RTS
+
+
+
+all-retest:
+	cabal configure -fdevel --enable-tests --disable-library-profiling -O2
+	cabal build
+	cabal exec $(TASTY) -- --smtsolver $(SMTSOLVER) --hide-successes --rerun-filter "exceptions,failures,new" --rerun-update -j$(THREADS) +RTS -N$(THREADS) -RTS
+
+all-retest-710:
+	cabal configure -fdevel --enable-tests --disable-library-profiling -O2
+	cabal build
+	$(TASTY) --smtsolver $(SMTSOLVER) --hide-successes --rerun-filter "exceptions,failures,new" --rerun-update -j$(THREADS) +RTS -N$(THREADS) -RTS
+
+
+
+lint:
+	hlint --colour --report .
+
+tags:
+	hasktags -x -c src/
+	# hasktags -c src/
+	# hasktags -e src/
+
+ghcid:
+	ghcid --command "stack ghci --main-is liquidhaskell:exe:liquid"
diff --git a/NVTODO.md b/NVTODO.md
new file mode 100644
--- /dev/null
+++ b/NVTODO.md
@@ -0,0 +1,12 @@
+- Gradual Refinement Types
+ - [x] clean up code
+ - [x] compare numbers
+ - [x] pull request 
+ - [ ] without elimination Interpratations.f has an bad/interesting result
+ - [ ] Implement Eric's validity with measures 
+ - [x] Check how elimination interacts with graduals (eg Interpretation fails with elimination now)
+ - [ ] Find interesting application
+ - [ ] Present weakest result 
+
+
+- Proof by Symbolic Evaluation 
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1250 @@
+![LiquidHaskell](/resources/logo.png)
+
+
+[![Hackage](https://img.shields.io/hackage/v/liquidhaskell.svg)](https://hackage.haskell.org/package/liquidhaskell) [![Hackage-Deps](https://img.shields.io/hackage-deps/v/liquidhaskell.svg)](http://packdeps.haskellers.com/feed?needle=liquidhaskell) [![Build Status](https://img.shields.io/circleci/project/ucsd-progsys/liquidhaskell/master.svg)](https://circleci.com/gh/ucsd-progsys/liquidhaskell)
+
+Main Web site
+-------------
+
+The UCSD web site for liquid haskell is [here](https://ucsd-progsys.github.io/liquidhaskell-blog/)
+
+Examples
+--------
+
+Jump to examples here [TODO]
+
+
+
+Contributing Guide
+------------------
+
+Please see the [contributing guide](CONTRIBUTING.md)
+
+Requirements
+------------
+
+LiquidHaskell requires (in addition to the cabal dependencies)
+
+- SMTLIB2 compatible solver
+
+How To Clone, Build and Install
+-------------------------------
+
+See [install instructions](INSTALL.md)
+
+How To Run
+----------
+
+To verify a file called `foo.hs` at type
+
+    $ liquid foo.hs
+
+How to Run inside GHCi
+----------------------
+
+To run inside `ghci` e.g. when developing do:
+
+    $ stack ghci liquidhaskell
+    ghci> :m +Language.Haskell.Liquid.Liquid
+    ghci> liquid ["tests/pos/Abs.hs"]
+
+How To Run Regression Tests
+---------------------------
+
+    $ stack test
+
+To use threads to speed up the tests
+
+    $ make THREADS=30 test
+
+Or your favorite number of threads, depending on cores etc.
+
+You can directly extend and run the tests by modifying
+
+    tests/test.hs
+
+To run the regression test *and* the benchmarks run
+
+    $ make all-test
+
+How to Profile
+--------------
+
+1. Build with profiling on
+
+    ```
+    $ make pdeps && make prof
+    ```
+
+2. Run with profiling
+
+    ```
+    $ time liquid range.hs +RTS -hc -p
+    $ time liquid range.hs +RTS -hy -p
+    ```
+
+    Followed by this which shows the stats file
+
+    ```
+    $ more liquid.prof
+    ```
+
+    or by this to see the graph
+
+    ```
+    $ hp2ps -e8in -c liquid.hp
+    $ gv liquid.ps
+    ```
+
+    etc.
+
+How to Get Stack Traces On Exceptions
+-------------------------------------
+
+1. Build with profiling on
+
+    ```
+    $ make pdeps && make prof
+    ```
+
+2. Run with backtraces
+
+    ```
+    $ liquid +RTS -xc -RTS foo.hs
+    ```
+
+Working With Submodules
+-----------------------
+
+ - To update the `liquid-fixpoint` submodule, run
+
+    ```
+    cd ./liquid-fixpoint
+    git fetch --all
+    git checkout <remote>/<branch>
+    cd ..
+    ```
+
+   This will update `liquid-fixpoint` to the latest version on `<branch>`
+   (usually `master`) from `<remote>` (usually `origin`).
+
+ - After updating `liquid-fixpoint`, make sure to include this change in a
+   commit! Running
+
+    ```
+    git add ./liquid-fixpoint
+    ```
+
+   will save the current commit hash of `liquid-fixpoint` in your next commit
+   to the `liquidhaskell` repository.
+
+ - For the best experience, **don't** make changes directly to the
+   `./liquid-fixpoint` submodule, or else git may get confused. Do any
+   `liquid-fixpoint` development inside a separate clone/copy elsewhere.
+
+ - If something goes wrong, run
+
+    ```
+    rm -r ./liquid-fixpoint
+    git submodule update --init
+    ```
+
+   to blow away your copy of the `liquid-fixpoint` submodule and revert to the
+   last saved commit hash.
+
+ - Want to work fully offline? git lets you add a local directory as a remote.
+   Run
+
+    ```
+    cd ./liquid-fixpoint
+    git remote add local /path/to/your/fixpoint/clone
+    cd ..
+    ```
+
+   Then to update the submodule from your local clone, you can run
+
+    ```
+    cd ./liquid-fixpoint
+    git fetch local
+    git checkout local/<branch>
+    cd ..
+    ```
+
+Command Line Options
+====================
+
+LiquidHaskell supports several command line options, to configure the
+checking. Each option can be passed in at the command line, or directly
+added to the source file via:
+
+    {-@ LIQUID "option-within-quotes" @-}
+
+for example, to disable termination checking (see below)
+
+    {-@ LIQUID "--notermination" @-}
+
+You may also put command line options in the environment variable
+`LIQUIDHASKELL_OPTS`. For example, if you add the line:
+
+    LIQUIDHASKELL_OPTS="--diff"
+
+to your `.bashrc` then, by default, all files will be
+*incrementally checked* unless you run with the overriding
+`--full` flag (see below).
+
+Incremental Checking
+--------------------
+
+LiquidHaskell supports *incremental* checking where each run only checks
+the part of the program that has been modified since the previous run.
+
+    $ liquid --diff foo.hs
+
+Each run of `liquid` saves the file to a `.bak` file and the *subsequent*
+run
+    + does a `diff` to see what has changed w.r.t. the `.bak` file
+    + only generates constraints for the `[CoreBind]` corresponding to the
+       changed top-level binders and their transitive dependencies.
+
+The time savings are quite significant. For example:
+
+    $ time liquid --notermination -i . Data/ByteString.hs > log 2>&1
+
+    real	7m3.179s
+    user	4m18.628s
+    sys	    0m21.549s
+
+Now if you go and tweak the definition of `spanEnd` on line 1192 and re-run:
+
+    $ time liquid -d --notermination -i . Data/ByteString.hs > log 2>&1
+
+    real	0m11.584s
+    user	0m6.008s
+    sys	    0m0.696s
+
+The diff is only performed against **code**, i.e. if you only change
+specifications, qualifiers, measures, etc. `liquid -d` will not perform
+any checks. In this case, you may specify individual definitions to verify:
+
+    $ liquid -b bar -b baz foo.hs
+
+This will verify `bar` and `baz`, as well as any functions they use.
+
+If you always want to run a given file with diff-checking, add
+the pragma:
+
+    {-@ LIQUID "--diff" @-}
+
+
+Full Checking (DEFAULT)
+-----------------------
+
+To force LiquidHaskell to check the **whole** file (DEFAULT), use:
+
+    $ liquid --full foo.hs
+
+to the file. This will override any other `--diff` incantation
+elsewhere (e.g. inside the file.)
+
+
+If you always want to run a given file with full-checking, add
+the pragma:
+
+    {-@ LIQUID "--full" @-}
+
+Specifying Different SMT Solvers
+--------------------------------
+
+By default, LiquidHaskell uses the SMTLIB2 interface for Z3.
+
+To run a different solver (supporting SMTLIB2) do:
+
+    $ liquid --smtsolver=NAME foo.hs
+
+Currently, LiquidHaskell supports
+
++ [CVC4](http://cvc4.cs.nyu.edu/)
++ [MathSat](http://mathsat.fbk.eu/download.html )
+
+To use these solvers, you must install the corresponding binaries
+from the above web-pages into your `PATH`.
+
+You can also build and link against the Z3 API (faster but requires more
+dependencies). If you do so, you can use that interface with:
+
+    $ liquid --smtsolver=z3mem foo.hs
+
+
+Short Error Messages
+--------------------
+
+By default, subtyping error messages will contain the inferred type, the
+expected type -- which is **not** a super-type, hence the error -- and a
+context containing relevant variables and their type to help you understand
+the error. If you don't want the above and instead, want only the
+**source position** of the error use:
+
+    --short-errors
+
+Short (Unqualified) Module Names
+-------------------------------
+
+By default, the inferred types will have fully qualified module names.
+To use unqualified names, much easier to read, use:
+
+    --short-names
+
+
+Totality Check
+--------------
+
+LiquidHaskell can prove the absence of pattern match failures.
+Use the `totality` flag to prove that all defined functions are total.
+
+    liquid --totality test.hs
+
+For example, the definition
+
+    fromJust :: Maybe a -> a
+    fromJust (Just a) = a
+
+is not total and it will create an error message.
+If we exclude `Nothing` from its domain, for example using the following specification
+
+    {-@ fromJust :: {v:Maybe a | (isJust v)} -> a @-}
+
+`fromJust` will be safe.
+
+Termination Check
+-----------------
+
+By **default** a termination check is performed on all recursive functions.
+
+Use the `no-termination` option to disable the check
+
+    liquid --no-termination test.hs
+
+In recursive functions the *first* algebraic or integer argument should be decreasing.
+
+The default decreasing measure for lists is length and Integers its value.
+
+The user can specify the decreasing measure in data definitions:
+
+    {-@ data L [llen] a = Nil | Cons (x::a) (xs:: L a) @-}
+
+Defines that `llen` is the decreasing measure (to be defined by the user).
+
+For example, in the function `foldl`
+
+    foldl k acc N           = acc
+    foldl k acc (Cons x xs) = foldl k (x `k` acc) xs
+
+by default the *second* argument (the first non-function argument) will be
+checked to be decreasing. However, the explicit hint
+
+    {-@ Decrease foo 3 @-}
+
+tells LiquidHaskell to instead use the *third* argument.
+
+Apart from specifying a specific decreasing measure for an Algebraic Data Type,
+the user can specify that the ADT follows the expected decreasing measure by
+
+    {-@ autosize L @-}
+
+Then, LiquidHaskell will define an instance of the function `autosize` for `L` that decreases by 1 at each recursive call and use `autosize` at functions that recurse on `L`.
+
+For example, `autosize L` will refine the data constructors of `L a` with the `autosize :: a -> Int` information, such that
+
+    Nil  :: {v:L a | autosize v = 0}
+    Cons :: x:a -> xs:L a -> {v:L a | autosize v = 1 + autosize xs}
+
+Also, an invariant that `autosize` is non negative will be generated
+
+    invariant  {v:L a| autosize v >= 0 }
+
+This information is all LiquidHaskell needs to prove termination on functions that recurse on `L a` (on ADTs in general.)
+
+
+To *disable* termination checking for `foo` that is, to *assume* that it
+is terminating (possibly for some complicated reason currently beyond the
+scope of LiquidHaskell) you can write
+
+    {-@ Lazy foo @-}
+
+Some functions do not decrease on a single argument, but rather a
+combination of arguments, e.g. the Ackermann function.
+
+    ack m n
+      | m == 0          = n + 1
+      | m > 0 && n == 0 = ack (m-1) 1
+      | m > 0 && n >  0 = ack (m-1) (ack m (n-1))
+
+In all but one recursive call `m` decreases, in the final call `m`
+does not decrease but `n` does. We can capture this notion of "x
+normally decreases, but if it does not, y will" with an extended
+annotation
+
+    {-@ Decrease ack 1 2 @-}
+
+An alternative way to express this specification is by annotating
+the function's type with the appropriate *numeric* decreasing expressions.
+As an example, you can give `ack` a type
+
+    {-@ ack :: m:Nat -> n:Nat -> Nat / [m,n] @-}
+
+stating that the *numeric* expressions `[m, n]` are lexicographically decreasing.
+
+Decreasing expressions can be arbitrary refinement expressions, e.g.,
+
+    {-@ merge :: Ord a => xs:[a] -> ys:[a] -> [a] / [(len xs) + (len ys)] @-}
+
+states that at each recursive call of `merge` the sum of the lengths
+of its arguments will be decreased.
+
+When dealing with mutually recursive functions you may run into a
+situation where the decreasing parameter must be measured *across* a
+series of invocations, e.g.
+
+    even 0 = True
+    even n = odd (n-1)
+
+    odd  n = not $ even n
+
+In this case, you can introduce a ghost parameter that orders the *functions*
+
+    even 0 _ = True
+    even n _ = odd (n-1) 1
+
+    odd  n _ = not $ even n 0
+
+thus recovering a decreasing measure for the pair of functions, the
+pair of arguments. This can be encoded with the lexicographic
+termination annotation `{-@ Decrease even 1 2 @-}` (see
+[tests/pos/mutrec.hs](tests/pos/mutrec.hs) for the full example).
+
+
+
+Total Haskell
+--------------
+
+LiquidHaskell provides a total Haskell flag that checks both totallity and termination of the program,
+overriding a potential no-termination flag.
+
+    liquid --total-Haskell test.hs
+
+
+Lazy Variables
+--------------
+
+A variable can be specified as `LAZYVAR`
+
+    {-@ LAZYVAR z @-}
+
+With this annotation the definition of `z` will be checked at the points where
+it is used. For example, with the above annotation the following code is SAFE:
+
+    foo   = if x > 0 then z else x
+      where
+        z = 42 `safeDiv` x
+        x = choose 0
+
+By default, all the variables starting with `fail` are marked as LAZY, to defer
+failing checks at the point where these variables are used.
+
+No measure fields
+------------------
+
+When a data type is refined, Liquid Haskell automatically turns the data constructor fields into measures.
+For example,
+
+   {-@ data L a = N | C {hd :: a, tl :: L a} @-}
+
+will automatically create two measures `hd` and `td`.
+To deactivate this automatic measure definition, and speed up verification, you can use the `no-measure-fields` flag.
+
+  liquid --no-measure-fields test.hs
+
+
+
+Prune Unsorted Predicates
+-------------------------
+
+Consider a measure over lists of integers
+
+  sum :: [Int] -> Int
+  sum [] = 0 
+  sum (x:xs) = 1 + sum xs 
+
+This measure will translate into strengthening the types of list constructors 
+
+  [] :: {v:[Int] | sum v = 0 }
+  (:) :: x:Int -> xs:[Int] -> {v:[Int] | sum v = x + sum xs}
+
+But what if our list is polymorphic `[a]` and later instantiate to list of ints?
+The hack we do right now is to strengthen the polymorphic list with the `sum` information 
+
+  [] :: {v:[a] | sum v = 0 }
+  (:) :: x:a -> xs:[a] -> {v:[a] | sum v = x + sum xs}
+
+But for non numeric `a`s, expressions like `x + sum xs` is unsorted causing the logic to crash. 
+We use the flag `--prune-unsorted` to prune away unsorted expressions (like `x + sum xs`) in the logic. 
+
+
+    liquid --prune-unsorted test.hs
+
+
+Case Expansion
+-------------------------
+
+By default LiquidHaskell expands all data constructors to the case statements.
+For example,
+if `F = A1 | A2 | .. | A10`,
+then LiquidHaskell will expand the code
+`case f of {A1 -> True; _ -> False}`
+to `case f of {A1 -> True; A2 -> False; ...; A10 -> False}`.
+This expansion can lead to more precise code analysis
+but it can get really expensive due to code explosion.
+The `no-case-expand` flag prevents this expansion and keeps the user
+provided cases for the case expression.
+
+    liquid --no-case-expand test.hs
+
+
+Higher order logic
+-------------------
+The flag `--higherorder` allows reasoning about higher order functions.
+
+
+Restriction to Linear Arithmetic
+---------------------------------
+When using `z3` as the solver, LiquidHaskell allows for non-linear arithmetic:
+division and multiplication on integers are interpreted by `z3`. To treat division
+and multiplication as uninterpreted functions use the `linear` flag
+
+    liquid --linear test.hs
+
+Counter examples (Experimental!)
+--------------------------------
+When given the `--counter-examples` flag, LiquidHaskell will attempt to produce
+counter-examples for the type errors it discovers. For example, see
+[tests/neg/ListElem.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/neg/ListElem.hs)
+
+```
+% liquid --counter-examples tests/neg/ListElem.hs
+
+...
+
+tests/neg/ListElem.hs:12:1-8: Error: Liquid Type Mismatch
+
+ 12 | listElem _ []      = False
+      ^^^^^^^^
+
+   Inferred type
+     VV : {VV : Bool | VV == True}
+     VV = True
+
+   not a subtype of Required type
+     VV : {VV : Bool | Prop VV <=> Set_mem ?b (listElts ?a)}
+
+   In Context
+     ?a : {?a : [a] | len ?a >= 0}
+     ?a = [1]
+
+     ?b : a
+     ?b = 0
+```
+
+The `--counter-examples` flag requires that each type in the context be
+an instance of `GHC.Generics.Generic` or `Test.Targetable.Targetable`
+(provided as part of LiquidHaskell).  LiquidHaskell cannot generate
+counter-examples for polymorphic types, but will try (naively) to
+instantiate type variables with `Int` (as seen in the example above).
+
+Writing Specifications
+======================
+
+Modules WITHOUT code
+--------------------
+
+When checking a file `target.hs`, you can specify an _include_ directory by
+
+    liquid -i /path/to/include/  target.hs
+
+Now, to write specifications for some **external module** `Foo.Bar.Baz` for which
+you **do not have the code**, you can create a `.spec` file at:
+
+    /path/to/include/Foo/Bar/Baz.spec
+
+See, for example, the contents of
+
++ [include/Prelude.spec](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Prelude.spec)
++ [include/Data/List.spec](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Data/List.spec)
++ [include/Data/Vector.spec](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Data/Vector.spec)
+
+**Note**:
+
++ The above directories are part of the LH prelude, and included by
+  default when running `liquid`.
++ The `.spec` mechanism is *only for external modules** without code,
+  see below for standalone specifications for **internal** or **home** modules.
+
+
+Modules WITH code: Data
+-----------------------
+
+Write the specification directly into the .hs or .lhs file,
+above the data definition. See, for example, [tests/pos/Map.hs](tests/pos/Map.hs)
+
+    {-@
+    data Map k a <l :: k -> k -> Prop, r :: k -> k -> Prop>
+      = Tip
+      | Bin (sz    :: Size)
+            (key   :: k)
+            (value :: a)
+            (left  :: Map <l, r> (k <l key>) a)
+            (right :: Map <l, r> (k <r key>) a)
+    @-}
+    data Map k a = Tip
+                 | Bin Size k a (Map k a) (Map k a)
+
+You can also write invariants for data type definitions
+together with the types. For example, see [tests/pos/record0.hs](tests/pos/record0.hs)
+
+    {-@ data LL a = BXYZ { size  :: {v: Int | v > 0 }
+                         , elems :: {v: [a] | (len v) = size }
+                         }
+    @-}
+
+Finally you can specify the variance of type variables for data types.
+For example, see [tests/pos/Variance.hs](tests/pos/Variance.hs), where data type `Foo` has four
+type variables `a`, `b`, `c`, `d`, specified as invariant, bivariant,
+covariant and contravariant, respectively.
+
+    data Foo a b c d
+    {-@ data variance Foo invariant bivariant covariant contravariant @-}
+
+
+Modules WITH code: Functions
+----------------------------
+
+Write the specification directly into the .hs or .lhs file,
+above the function definition. [For example](tests/pos/spec0.hs)
+
+    {-@ incr :: x:{v: Int | v > 0} -> {v: Int | v > x} @-}
+    incr   :: Int -> Int
+    incr x = x + 1
+
+Modules WITH code: Type Classes
+-------------------------------
+
+Write the specification directly into the .hs or .lhs file,
+above the type class definition. [For example](tests/pos/Class.hs)
+
+    {-@ class Sized s where
+          size :: forall a. x:s a -> {v:Int | v = (size x)}
+    @-}
+    class Sized s where
+      size :: s a -> Int
+
+Any measures used in the refined class definition will need to be
+*generic* (see [Specifying Measures](#specifying-measures)).
+
+
+As an alternative, you can refine class instances.
+[For example](tests/pos/LiquidClass.hs)
+
+~~~~
+instance Compare Int where
+
+{-@ instance Compare Int where
+    cmax :: Odd -> Odd -> Odd
+  @-}
+
+cmax y x = if x >= y then x else y
+~~~~
+
+When `cmax` method is used on `Int`, liquidHaskell will give it
+the refined type `Odd -> Odd -> Odd`.
+
+Note that currently liquidHaskell does not allow refining instances of
+refined classes.
+
+Modules WITH code: QuasiQuotation
+---------------------------------
+
+Instead of writing both a Haskell type signature *and* a
+LiquidHaskell specification for a function, the `lq`
+quasiquoter in the `LiquidHaskell` module can be used
+to generate both from just the LiquidHaskell specification.
+
+```haskell
+module Nats (nats) where
+
+{-@ nats :: [{v:Int | 0 <= v}] @-}
+nats :: [Int]
+nats = [1,2,3]
+```
+
+can be written as
+
+```haskell
+{-# LANGUAGE QuasiQuotes #-}
+module Nats (nats) where
+
+import LiquidHaskell
+
+[lq| nats :: [{v:Int | 0 <= v}] |]
+nats = [1,2,3]
+```
+
+and the `lq` quasiquoter will generate the plain `nats :: [Int]` when GHC
+compiles the module.
+
+Refined type aliases (see the next section) can also be written inside `lq`; for
+example:
+
+```haskell
+{-# LANGUAGE QuasiQuoters #-}
+module Nats (Nat, nats) where
+
+[lq| type Nat = {v:Int | 0 <= v} |]
+
+[lq| nats :: [Nat] |]
+nats = [1,2,3]
+```
+
+Here, the `lq` quasiquoter will generate a plain Haskell
+type synonym for `Nat` as well as the refined one.
+
+Note that this is still an experimental feature, and
+currently requires that one depend on LiquidHaskell
+as a build dependency for your project; the quasiquoter
+will be split out eventually into an independent,
+dependency-light package. Also, at this time, writing
+a type inside `lq` which refers to a refined type alias
+for which there is not a plain Haskell type synonym of the
+same name will result in a "not in scope" error from GHC.
+
+Standalone Specifications for Internal Modules
+----------------------------------------------
+
+Recall that the `.spec` mechanism is only for modules whose
+code is absent; if code is present then there can be multiple,
+possibly conflicting specifications. Nevertheless, you may want,
+for one reason or another, to write (assumed) specifications
+outside the file implementing the module.
+
+You can do this as follows.
+
+`Lib.hs`
+
+```haskell
+module Lib (foo) where
+
+foo a = a
+```
+
+now, instead of a `.spec` file, just use a haskell module, e.g. `LibSpec.hs`
+
+```haskell
+module LibSpec ( module Lib ) where
+
+import Lib
+
+-- Don't forget to qualify the name!
+
+{-@ Lib.foo :: {v:a | false} -> a @-}
+```
+
+and then here's `Client.hs`
+
+```haskell
+module Client where
+
+import Lib      -- use this if you DON'T want the spec
+import LibSpec  -- use this if you DO want the spec, in addition to OR instead of the previous import.
+
+bar = foo 1     -- if you `import LibSpec` then this call is rejected by LH
+```
+Refinement Type Aliases
+-----------------------
+
+#### Predicate Aliases
+
+Often, the propositions in the refinements can get rather long and
+verbose. You can write predicate aliases like so:
+
+    {-@ predicate Lt X Y = X < Y        @-}
+    {-@ predicate Ge X Y = not (Lt X Y) @-}
+
+and then use the aliases inside refinements, [for example](tests/pos/pred.hs)
+
+    {-@ incr :: x:{v:Int | (Pos v)} -> { v:Int | ((Pos v) && (Ge v x))} @-}
+    incr :: Int -> Int
+    incr x = x + 1
+
+See [Data.Map](benchmarks/esop2013-submission/Base.hs) for a more substantial
+and compelling example.
+
+**Syntax:** The key requirements for type aliases are:
+
+- Value parameters are specified in **upper**case: `X`, `Y`, `Z` etc.
+
+
+#### Type Aliases
+
+
+Similarly, it is often quite tedious to keep writing
+
+    {v: Int | v > 0}
+
+Thus, LiquidHaskell supports refinement-type aliases of the form:
+
+    {-@ type Gt      N = {v: Int | N <  v} @-}
+    {-@ type GeNum a N = {v: a   | N <= v} @-}
+
+or
+
+    {-@ type SortedList a = [a]<{\fld v -> (v >= fld)}> @-}
+
+or
+
+    {-@ type OMap k a = Map <{\root v -> v < root}, {\root v -> v > root}> k a @-}
+
+or
+
+    {-@ type MinSPair a = (a, OSplay a) <\fld -> {v : Splay {v:a|v>fld} | 0=0}> @-}
+
+and then use the above in signatures like:
+
+    {-@ incr: x: Int -> GeNum Int x @-}
+
+or
+
+    {-@ incr: x: Int -> Gt x @-}
+
+and:
+
+    {-@ assert insert :: (Ord a) => a -> SortedList a -> SortedList a @-}
+
+see [tests/pos/ListSort.hs](tests/pos/ListSort.hs)
+
+and:
+
+    {-@ assert insert :: (Ord k) => k -> a -> OMap k a -> OMap k a @-}
+
+see [tests/pos/Map.hs](tests/pos/Map.hs)
+
+**Syntax:** The key requirements for type aliases are:
+
+1. Type parameters are specified in **lower**case: `a`, `b`, `c` etc.
+2. Value parameters are specified in **upper**case: `X`, `Y`, `Z` etc.
+
+
+Infix Logic Operators
+---------------------
+
+You can define infix operators in logic, following [Haskell's infix notation](Build in Haskell ops https://www.haskell.org/onlinereport/decls.html#fixity).
+For example, if (+++) is defined as a measure or reflected function, you can use it infix by declaring
+
+   {-@ infixl 9 +++ @-}
+
+
+Note: infix operators cannot contain the dot character `.`.
+
+
+Specifying Measures
+-------------------
+
+Can be placed in .spec file or in .hs/.lhs file wrapped around `{-@ @-}`
+
+Value measures: [include/GHC/Base.spec](include/GHC/Base.spec)
+
+    measure len :: forall a. [a] -> GHC.Types.Int
+    len ([])     = 0
+    len (y:ys)   = 1 + len(ys)
+
+Propositional measures: [tests/pos/LambdaEval.hs](tests/pos/LambdaEval.hs)
+
+    {-@
+    measure isValue      :: Expr -> Bool
+    isValue (Const i)    = true
+    isValue (Lam x e)    = true
+    isValue (Var x)      = false
+    isValue (App e1 e2)  = false
+    isValue (Plus e1 e2) = false
+    isValue (Fst e)      = false
+    isValue (Snd e)      = false
+    isValue (Pair e1 e2) = ((? (isValue(e1))) && (? (isValue(e2))))
+    @-}
+
+Raw measures: [tests/pos/meas8.hs](tests/pos/meas8.hs)
+
+    {-@ measure rlen :: [a] -> Int
+    rlen ([])   = {v | v = 0}
+    rlen (y:ys) = {v | v = (1 + rlen(ys))}
+    @-}
+
+Generic measures: [tests/pos/Class.hs](tests/pos/Class.hs)
+
+    {-@ class measure size :: a -> Int @-}
+    {-@ instance measure size :: [a] -> Int
+        size ([])   = 0
+        size (x:xs) = 1 + (size xs)
+    @-}
+    {-@ instance measure size :: Tree a -> Int
+        size (Leaf)       = 0
+        size (Node x l r) = 1 + (size l) + (size r)
+    @-}
+
+**Note:** Measure names **do not** have to be the same as
+field name, e.g. we could call the measure `sz` in the above
+as shown in [tests/pos/Class2.hs](tests/pos/Class2.hs).
+
+
+Haskell Functions as Measures (beta): [tests/pos/HaskellMeasure.hs](tests/pos/HaskellMeasure.hs)
+
+Inductive Haskell Functions from Data Types to some type can be lifted to logic
+
+    {-@ measure llen @-}
+    llen        :: [a] -> Int
+    llen []     = 0
+    llen (x:xs) = 1 + llen xs
+
+The above definition
+  - refines list's data constructors types with the llen information, and
+  - specifies a singleton type for the haskell function
+        `llen :: xs:[a] -> {v:Int | v == llen xs}`
+    If the user specifies another type for llen, say
+        `llen :: xs:[a] -> {v:Int | llen xs >= 0}`
+    then the auto generated singleton type is overwritten.
+
+Self-Invariants
+===============
+
+Sometimes, we require specifications that allow *inner* components of a
+type to refer to the *outer* components, typically, to measure-based
+properties of outer components. For example, the following invariant
+about `Maybe` values
+
+    {-@ type IMaybe a = {v0 : Maybe {v : a | ((isJust v0) && v = (fromJust v0))} | 0 = 0 } @-}
+
+states that the *inner* `a` enjoys the property that the *outer* container
+is definitely a `Just` and furthermore, the inner value is exactly the same
+as the `fromJust` property of the outer container.
+
+As another example, suppose we have a [measure](include/Data/Set.spec):
+
+    measure listElts :: [a] -> (Set a)
+    listElts([])   = {v | (? Set_emp(v))}
+    listElts(x:xs) = {v | v = Set_cup(Set_sng(x), listElts(xs)) }
+
+Now, all lists enjoy the property
+
+    {-@ type IList a = {v0 : List  {v : a | (Set_mem v (listElts v0)) } | true } @-}
+
+which simply states that each *inner* element is indeed, a member of the
+set of the elements belonging to the entire list.
+
+One often needs these *circular* or *self* invariants to connect different
+levels (or rather, to *reify* the connections between the two levels.) See
+[this test](tests/pos/maybe4.hs) for a simple example and `hedgeUnion` and
+[Data.Map.Base](benchmarks/esop2013-submission/Base.hs) for a complex one.
+
+Abstract and Bounded Refinements
+================================
+
+This is probably the best example of the abstract refinement syntax:
+
++ [Abstract Refinements](tests/pos/Map.hs)
++ [Bounded Refinements](benchmarks/icfp15/pos/Overview.lhs)
+
+Unfortunately, the best documentation for these two advanced features
+is the relevant papers at
+
++ [ESOP 2013](https://ranjitjhala.github.io/static/abstract_refinement_types.pdf)
++ [ICFP 2015](https://arxiv.org/abs/1507.00385)
+
+The bounds correspond to Horn implications between abstract refinements,
+which, as in the classical setting, correspond to subtyping constraints
+that must be satisfied by the concrete refinements used at any call-site.
+
+Invariants
+==========
+
+LH lets you locally associate invariants with specific data types.
+
+For example, in [tests/pos/StreamInvariants.hs](tests/pos/StreamInvariants.hs) every
+list is treated as a Stream. To establish this local invariant one can use the
+`using` declaration
+
+    {-@ using ([a]) as  {v:[a] | (len v > 0)} @-}
+
+denoting that each list is not empty.
+
+Then, LiquidHaskell will prove that this invariant holds, by proving that *all
+calls* to List's constructors (ie., `:` and `[]`) satisfy it, and
+will assume that each list element that is created satisfies
+this invariant.
+
+With this, at the [above](tests/neg/StreamInvariants.hs) test LiquidHaskell
+proves that taking the `head` of a list is safe.
+But, at [tests/neg/StreamInvariants.hs](tests/neg/StreamInvariants.hs) the usage of
+`[]` falsifies this local invariant resulting in an "Invariant Check" error.
+
+
+**WARNING:** There is an older _global_ invariant mechanism that 
+attaches a refinement to a datatype globally.
+Do not use this mechanism -- it is *unsound* and about to 
+deprecated in favor of something that is [actually sound](https://github.com/ucsd-progsys/liquidhaskell/issues/126)
+
+Forexample,  the length of a list cannot be negative
+
+    {-@ invariant {v:[a] | (len v >= 0)} @-}
+
+LiquidHaskell can prove that this invariant holds, by proving that all List's
+constructors (ie., `:` and `[]`) satisfy it.(TODO!) Then, LiquidHaskell 
+assumes that each list element that is created satisfies
+this invariant.
+
+Formal Grammar of Refinement Predicates
+=======================================
+
+(C)onstants
+-----------
+
+    c := 0, 1, 2, ...
+
+(V)ariables
+-----------
+
+    v := x, y, z, ...
+
+
+(E)xpressions
+-------------
+
+    e := v                      -- variable
+       | c                      -- constant
+       | (e + e)                -- addition
+       | (e - e)                -- subtraction
+       | (c * e)                -- multiplication by constant
+       | (v e1 e2 ... en)       -- uninterpreted function application
+       | (if p then e else e)   -- if-then-else
+
+(R)elations
+-----------
+
+    r := ==               -- equality
+       | /=               -- disequality
+       | >=               -- greater than or equal
+       | <=               -- less than or equal
+       | >                -- greater than
+       | <                -- less than
+
+
+(P)redicates
+------------
+
+    p := (e r e)          -- binary relation
+       | (v e1 e2 ... en) -- predicate (or alias) application
+       | (p && p)         -- and
+       | (p || p)         -- or
+       | (p => p)         -- implies
+       | (not p)          -- negation
+       | true
+       | false
+
+
+Specifying Qualifiers
+=====================
+
+There are several ways to specify qualifiers.
+
+By Separate `.hquals` Files
+---------------------------
+
+You can write qualifier files e.g. [Prelude.hquals](include/Prelude.hquals)
+
+If a module is called or imports
+
+    Foo.Bar.Baz
+
+Then the system automatically searches for
+
+    include/Foo/Bar/Baz.hquals
+
+By Including `.hquals` Files
+----------------------------
+
+Additional qualifiers may be used by adding lines of the form:
+
+    {-@ include <path/to/file.hquals> @-}
+
+to the Haskell source. See, [this](tests/pos/meas5.hs) for example.
+
+
+In Haskell Source or Spec Files
+-------------------------------
+
+Finally, you can specifiers directly inside source (.hs or .lhs) or spec (.spec)
+files by writing as shown [here](tests/pos/qualTest.hs)
+
+    {-@ qualif Foo(v:Int, a: Int) : (v = a + 100)   @-}
+
+
+**Note** In addition to these, LiquidHaskell scrapes qualifiers from all
+the specifications you write i.e.
+
+1. all imported type signatures,
+2. measure bodies and,
+3. data constructor definitions.
+
+
+Generating HTML Output
+======================
+
+The system produces HTML files with colorized source, and mouseover
+inferred type annotations, which are quite handy for debugging failed
+verification attempts.
+
+- **Regular Haskell** When you run: `liquid foo.hs` you get a file
+  `foo.hs.html` with the annotations. The coloring is done using
+  `hscolour`.
+
+- **Markdown + Literate Haskell** You can also feed in literate haskell files
+  where the comments are in [Pandoc markdown](http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html).
+  In this case, the tool will run `pandoc` to generate the HTML from the comments.
+  Of course, this requires that you have `pandoc` installed as a binary on
+  your system. If not, `hscolour` is used to render the HTML.
+
+  It is also possible to generate *slide shows* from the above.
+  See the [slides directory](docs/slides) for an example.
+
+Editor Integration
+==================
+
++ [Emacs/Flycheck](https://github.com/ucsd-progsys/liquid-types.el)
++ [Vim/Syntastic](https://github.com/ucsd-progsys/liquid-types.vim)
+
+Command Line Options
+====================
+
+To see all options, run `liquid --help`. Here are some common options:
+
+- `--cabaldir` will automatically find a .cabal file in the ancestor
+  path from which the target file belongs, and then add the relevant
+  source and dependencies to the paths searched for by LiquidHaskell.
+
+  This means we don't have to manually do `-i src` etc. when checking
+  large projects, which can be tedious e.g. within emacs.
+
+- `--diff` performs differential checking, i.e. only checks those binders
+  that have transitively affected by edits since the previous check.
+  Can speed things up greatly during editing.
+
+- `--short-names` prints out non-qualified names i.e. `Int` instead of
+  `GHC.Types.Int` for inferred type annotations and error messages.
+
+**Pragmas** are useful for embedding options directly within the source file,
+that is, somewhere in the file (perhaps at the top) put in:
+
+    {-@ LIQUID "--diff"        @-}
+    {-@ LIQUID "--short-names" @-}
+    {-@ LIQUID "--cabaldir"    @-}
+
+to have the relevant option be used for that file.
+
+Generating Performance Reports
+------------------------------
+
+We have set up infrastructure to generate performance reports using [Gipeda](https://github.com/nomeata/gipeda).
+
+Gipeda will generate a static webpage that tracks the performance improvements
+and regressions between commits. To generate the site, first ensure you have the
+following dependencies available:
+
+* Git
+* Cabal >= 1.18
+* GHC
+* Make
+* Bash (installed at `/bin/bash`)
+
+After ensuring all dependencies are available, from the Liquid Haskell
+directory, execute:
+
+    cd scripts/performance
+    ./deploy-gipeda.bash
+
+This will download and install all the relevant repositories and files. Next, to
+generate the performance report, use the `generate-site.bash` script. This script
+has a few options:
+
+* `-s [hash]`: Do not attempt to generate performance reports for any commit
+older than the commit specified by the entered git hash
+* `-e [hash]`: Do not attempt to generate performance reports for any commit
+newer than the commit specified by the entered git hash
+* `-f`: The default behavior of `generate-site.bash` is to first check if logs
+have been created for a given hash. If logs already exist, `generate-site.bash`
+will not recreate them. Specify this option to skip this check and regenerate
+all logs.
+
+You should expect this process to take a very long time. `generate-site.bash`
+will compile each commit, then run the entire test suite and benchmark suite
+for each commit. It is suggested to provide a manageable range to `generate-site.bash`:
+
+    ./generate-site.bash -s [starting hash] -e [ending hash]
+
+...will generate reports for all commits between (inclusive) [starting hash]
+and [ending hash].
+
+    ./generate-site.bash -s [starting hash]
+
+... will generate reports for all commits newer than [starting hash]. This command
+can be the basis for some automated report generation process (i.e. a cron job).
+
+Finally, to remove the Gipeda infrastructure from your computer, you may execute:
+
+    ./cleanup-gipeda.bash
+
+...which will remove any files created by `deploy-gipeda.bash` and `generate-site.bash`
+from your computer.
+
+
+Configuration Management
+------------------------
+
+It is very important that the version of Liquid Haskell be maintained properly.
+
+Suppose that the current version of Liquid Haskell is `A.B.C.D`:
+
++ After a release to hackage is made, if any of the components `B`, `C`, or `D` are missing, they shall be added and set to `0`. Then the `D` component of Liquid Haskell shall be incremented by `1`. The version of Liquid Haskell is now `A.B.C.(D + 1)`
+
++ The first time a new function or type is exported from Liquid Haskell, if any of the components `B`, or `C` are missing, they shall be added and set to `0`. Then the `C` component shall be incremented by `1`, and the `D` component shall stripped. The version of Liquid Haskell is now `A.B.(C + 1)`
+
++ The first time the signature of an exported function or type is changed, or an exported function or type is removed (this includes functions or types that Liquid Haskell re-exports from its own dependencies), if the `B` component is missing, it shall be added and set to `0`. Then the `B` component shall be incremented by `1`, and the `C` and `D` components shall be stripped. The version of Liquid Haskell is now `A.(B + 1)`
+
++ The `A` component shall be updated at the sole discretion of the project owners.
+
+Proof Automation
+----------------
+The `liquidinstances` automatically generates proof terms using symbolic evaluation. [See](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/benchmarks/proofautomation/pos/MonoidList.hs).
+
+```
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+```
+
+This flag is **global** and will symbolically evaluation all the terms that appear in the specifications. 
+
+As an alternative, the `liquidinstanceslocal` flag has local behavior. [See](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/benchmarks/proofautomation/pos/Unification.hs)
+
+```
+{-@ LIQUID "--automatic-instances=liquidinstanceslocal" @-}
+```
+
+will only evaluate terms appearing in the specifications of the function `theorem`, in the function `theorem` is annotated 
+for automatic instantiation using the following liquid annotation
+
+```
+{-@ automatic-instances theorem @-}
+```
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,9 +1,11 @@
 import Distribution.Simple
 
 
+
 main = defaultMain
 
--- main = defaultMainWithHooks fixpointHooks 
+-- 
+-- --- main = defaultMainWithHooks fixpointHooks 
 --  
 -- fixpointHooks   = defaultUserHooks { postInst = cpFix }
 --    where 
diff --git a/Syntax.md b/Syntax.md
new file mode 100644
--- /dev/null
+++ b/Syntax.md
@@ -0,0 +1,40 @@
+- Niki Vazou
+
+|                      | Current Syntax                | Future Syntax                 |
+|----------------------|-------------------------------|-------------------------------|
+| Abstract Refinements | `List <{\x v -> v >= x}> Int` | `List Int (\x v -> v >= x)`   |
+|                      | `[a<p>]<{\x v -> v >= x}>`    | `[a p] (\x v -> v >= x) (??)` |
+|                      | `Int<p>`                      | `Int p`                       |
+|                      | `Int<\x -> x >=0>`            | `Int (\x -> x >= 0)`          |
+|                      | `Maybe <<p>> (a<q>) (?)`      | `Maybe (a q) p`               |
+|                      | `Map <l, r> <<p>> k v  (?)`   | `Maybe k v l r p`             |
+| Type Arguments       | `ListN a {len xs + len ys}`   | `ListN a (len xs + len ys)`   |
+
+Q: How do I distinguish `Int p` with `ListN a n`?
+(`p` is a abstract refinement and `n` is an `Integer`)
+
+A: From the context!
+Use simple kinds, i.e.
+`ListN :: * -> Int -> *`
+`Int :: ?AR -> *`
+
+----------------------------
+
+- Chris Tetreault
+
+Currently for specifications, we write them as such:
+
+`{-@ unsafeLookup :: n:Nat ->  {v:Vector a | n < (vlen v)} -> a @-}`
+
+... where we bind `n` as a `Nat` and `v` as a `Vector a` _such that_ `[stuff]`. As a Haskeller, I find it strange to put logic into something that appears to be a function signature. I propose:
+
+```
+{-@
+   unsafeLookup :: Nat -> Vector a -> a
+   unsafeLookup n v _ | n < vlen v
+@-}
+```
+
+Here we have a "function" that takes a refined type `Nat` and a Haskell type `Vector a` and returns a Haskell type `a`. The definition of this refinement binds the `Nat` to `n` and the `Vector a` to `v`, and doesn't care about the `a`. Next, it specifies that `n < vlen v`.
+
+We could mix the syntax up a bit more to address my previous concern that it not look "too much like haskell", presuably drawing from the list of symbols that get used elsewhere, but I'm more concerned with getting this sort of "function syntax" than with what specific glyphs get used.
diff --git a/TODO.EASY.md b/TODO.EASY.md
new file mode 100644
--- /dev/null
+++ b/TODO.EASY.md
@@ -0,0 +1,22 @@
+- Verification of Libraries 
+  - [zlib](https://hackage.haskell.org/package/zlib)
+  - [probability](https://github.com/nikivazou/probability)
+  
+- fix parser error message
+  - Parse Errors [#241](https://github.com/ucsd-progsys/liquidhaskell/issues/241)
+  - Liquid Haskell doesn't accept Haskell names containing ' (single-quote) [#273](https://github.com/ucsd-progsys/liquidhaskell/issues/273)
+  - Error messages [#400](https://github.com/ucsd-progsys/liquidhaskell/issues/400)
+  - Add list of reserved tokens
+
+- Parse Propositional Variables in Refinements [#338](https://github.com/ucsd-progsys/liquidhaskell/issues/338)
+
+- Combine GHC and Liquid Type Aliases [#381](https://github.com/ucsd-progsys/liquidhaskell/issues/381)
+
+- Applying data type with wrong number of abstract refinement params could give better errors [#297](https://github.com/ucsd-progsys/liquidhaskell/issues/297)
+
+- Export qualifiers from measure types [#302](https://github.com/ucsd-progsys/liquidhaskell/issues/302)
+
+- systematically remove all error calls 
+
+ NV: Not sure how easy this is, as it requires deep understanding of the code
+    to distinguish dead code from our errors.
diff --git a/TODO.markdown b/TODO.markdown
new file mode 100644
--- /dev/null
+++ b/TODO.markdown
@@ -0,0 +1,1216 @@
+- Reader
+  - Applicative crashing
+  - Functor crashing
+  - Functor.NoEx
+  - Monad (...)
+
+TODO
+====
+
+Prune Unsorted Refs
+-------------------
+
+* mergeDataConTypes
+* makeMeasureSpec'
+* meetDataConSpec
+
+The below gives a nice SORT error
+
+```haskell
+import Data.Set
+
+data RBTree a = Leaf | Node
+
+{-@ measure isB :: RBTree a -> (Set a)
+    isB (Leaf) = 1
+    isB (Node) = (Set_empty 0)
+  @-}
+```
+
+rjhala@borscht ~/r/s/liquidhaskell (prune-unsorted-error)> stack exec -- liquid tests/todo/prune.hs
+
+ /Users/rjhala/research/stack/liquidhaskell/tests/todo/prune.hs:7:13-15: Error: Bad Type Specification
+ measure isB :: (RBTree a b) -> (Set a)
+     Type constructor Prune.RBTree expects a maximum 1 arguments but was given 2 arguments
+
+ /Users/rjhala/research/stack/liquidhaskell/tests/todo/prune.hs:14:13: Error: Bad Measure Specification
+ measure  isB
+     The sort (Set_Set  @(42)) is not numeric
+     because
+        Cannot unify (Set_Set  @(42)) with int in expression: 1
+     because
+        Cannot cast 1 of sort int to incompatible sort func(1, [(Set_Set  @(0))])
+
+now put another SORT CHECK for measures:
+
+  * Input type should be "isGeneric"
+
+    isGeneric T if
+
+    * T is a TyConApp `c [t1...tn]`
+
+    where t1 .. tn are DISTINCT type variables.
+
+If the above SORT CHECK fails for any measure print an ERROR message saying:
+
+   please rerun with --prune-unsorted
+
+```haskell
+
+(:) :: Int -> [Int] -> [Int]
+
+sum :: [Int] -> Int
+sum []     = 0
+sum (x:xs) = x + sum xs
+
+
+sum :: Tree Int a -> Int
+sum Leaf         = 0
+sum Node k _ l r = k + sum l + sum r
+```
+
+Check Covariance
+----------------
+
+See https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/todo/kmpMonad.hs#L55
+It is safe is 100 is changed to 0. WHY?
+
+LAZYVAR
+-------
+
+Restore LAZYVARS in `Data/Text.hs`, `Data/Text/Unsafe.hs`
+
+
+Automatically refine *inductors*
+--------------------------------
+
+Proposed by Valentine: in dependent languages (Coq)
+inductors (like our `loop` for natural numbers)
+automatically get types abstracted over properties.
+Traversal should create such functions.
+Maybe we can automatically refine them.
+
+benchmarks
+-----------
+
+* benchmarks: Data.Bytestring
+    ? readsPrec
+    ? big constants issue : _word64 34534523452134213524525 due to (deriving Typeable)
+    - see others below
+
+* hmatrix
+
+* error messages (see issues on github)
+
+Benchmarks
+==========
+
+                        time(O|N|C)    TOTAL(O|N)   solve (O|N)      refines       iterfreq
+    Map.hs          :    54/50/32/10    21/15/8.7      14/8/4.3    9100/4900/2700    16/28/7
+    ListSort.hs     :   */7.5/5.5/2    */2.5/1.8     */1.5/1.0      */1100/600       */9/7
+    GhcListSort.hs  :    23/22/17/5    7.3/7.8/5   4.5/5.0/2.7    3700/4400/1900   10/23/6
+    LambdaEval.hs   :    36/32/25/12    17/12/10     11.7/6.0/5    8500/3100/2400   12/5/5
+    Base.hs         :        26mi/2m
+
+
+Benchmarks
+==========
+
+[OK]    Data.KMeans
+[OK]    GHC.List   (../benchmarks/ghc-7.4.1/List.lhs)
+[OK]    bytestring
+[OK]    text
+
+[??-PP] Data.Map (supersedes set)
+        - ordering [OK]
+        - size
+        - key-set-properties
+        - key-dependence
+        - balance (NO)
+
+-   vector-algorithms "vector bounds checking"
+      - e.g. "unsafeSlice"
+      - maybe only specify types for Vector?
+
+-   vector
+-   repa
+-   repa-algorithms
+- 	xmonad (stackset)
+-   snap/security
+-   hmatrix
+      > http://hackage.haskell.org/packages/archive/hmatrix/0.12.0.1/doc/html/src/Data-Packed-Internal-Matrix.html#Matrix
+      > http://hackage.haskell.org/packages/archive/hmatrix/0.12.0.1/doc/html/src/Data-Packed-Internal-Vector.html#fromList
+
+Other Benchmarks
+================
+
+->   FingerTrees (containers / Data.Seq)
+->   Union-Find (PLDI09 port if necessary?)
+->   BDD        (PLDI09 port if necessary?)
+
+[NO] Data.Set (Map redux)
+        > ordering
+        > size
+        > set-properties
+        > balance (NO)
+
+[NO] Data.IntSet
+     > tricky bit-level operations/invariants
+
+Paper #2
+
+-> Haskell + DB / Yesod / Snap
+-> NDM/catch benchmarks (with refinements)
+
+Known Bugs
+==========
+
+-> tests/todo/fft.hs
+
+-> binsearch crashes because you have chains like:
+
+        x1 = 2
+        x2 = x1
+        x3 = x2
+        z  = x3 / 2
+
+  so I guess you need some constprop inside the constraint simplification.
+
+- tests/pos/data-mono0.hs
+  partial pattern match desugars into exception syntax with unhandled
+  casts. Throws an error in fixpoint. At least throw error in Constraint Gen?
+          (\ _ ->
+             (Control.Exception.Base.irrefutPatError
+                @ () "pos/data-mono0.hs:8:9-23|(Test.Cons x _)")
+             `cast` (UnsafeCo () GHC.Types.Int :: () ~ GHC.Types.Int))
+            GHC.Prim.realWorld#;
+
+
+Xmonad Case Study
+=================
+
+Theorems (from Wouter Swierstra's Coq Development)
+
+    - Invariant: NoDuplicates
+
+    - prop_empty_I      : new  : ? -> {v | invariant(v)}
+    - prop_view_I       : view : ? -> {v | invariant(v)}
+    - prop_greedyView_I : view : ? -> {v | invariant(v)}
+    - prop_focusUp_I
+    - prop_focusMaster_I
+    - prop_focusDown_I
+    - prop_focus_I
+    - prop_insertUp_I
+    - prop_delete_I
+    - prop_swap_master_I
+    - prop_swap_left_I  
+    - prop_swap_right_I
+    - prop_shift_I
+    - prop_shift_win_I
+
+[prop_FOO_I] check that various functions outputs satisfy "invariant"
+
+    FOO :: ??? -> {v: StackSet | invariant(v)}
+
+    > Theorem prop_swap_master_I (s : StackSet.stackSet i l a sd) :
+    > Theorem prop_view_I (l a sd : Set) (n : nat) (s : StackSet.stackSet nat l a sd) :
+    > Theorem prop_greedyView_I (l a sd : Set) (n : nat) (s : StackSet.stackSet nat l a sd) :
+    > Theorem prop_focusUp_I (l a sd : Set) (n : nat) (s : StackSet.stackSet nat l a sd) :
+    > Theorem prop_focusDown_I (l a sd : Set) (n : nat) (s : StackSet.stackSet nat l a sd) :
+    > Theorem prop_focusMaster_I (l a sd : Set) (n : nat) (s : StackSet.stackSet nat l a sd) :
+    > Theorem prop_empty_I (m : l) (wids : {wids : list i | wids <> nil})
+    > Theorem prop_empty (m : l) (wids : {wids : list i | wids <> nil})
+    > Theorem prop_differentiate (xs : list a) :
+
+[prop_FOO_local] check that various functions preserve a [hidden_spaces] MEASURE
+
+    FOO :: x: StackSet -> {v: StackSet | hidden_spaces(v) = hidden_spaces(x) }
+
+    > Theorem prop_focus_down_local (s : stackSet i l a sd) :
+    > Theorem prop_focus_up_local (s : stackSet i l a sd) :
+    > Theorem prop_focus_master_local (s : stackSet i l a sd) :
+    > Theorem prop_delete_local (s : stackSet i l a sd) (eq_dec : forall x y, {x = y} + {x <> y}) :
+    > Theorem prop_swap_master_local (s : stackSet i l a sd) :
+    > Theorem prop_swap_left_local (s : stackSet i l a sd) :
+    > Theorem prop_swap_right_local (s : stackSet i l a sd) :
+    > Theorem prop_shift_master_local (s : stackSet i l a sd) :
+    > Theorem prop_insert_local (x : stackSet i l a sd) (eq_dec : forall x y, {x = y} + {x <> y}) :
+
+
+BAD: these check that: forall x: foo (bar x) == x
+
+    > Theorem prop_focus_right (s : StackSet.stackSet i l a sd) :
+    > Theorem prop_focus_left (s : StackSet.stackSet i l a sd) :
+
+[prop_swap_*_focus] check that various functions preserve a [peek] MEASURE
+    > Theorem prop_swap_master_focus (x : StackSet.stackSet i l a sd) :
+    > Theorem prop_swap_left_focus (x : StackSet.stackSet i l a sd) :
+    > Theorem prop_swap_right_focus (x : StackSet.stackSet i l a sd) :
+
+
+BAD? forall x. swapMaster (swapMaster x) == x
+    > Theorem prop_swap_master_idempotent (x : StackSet.stackSet i l a sd) :
+
+BAD? forall x. view i (view i x) == (view i x)
+    > Theorem prop_focusMaster_idem (x : StackSet.stackSet i l a sd) :
+
+    NO. Prove: view :: i -> x -> {v: focus(v) = i}
+                    :: i -> x -> {v: focus(x) = i => x = v }
+
+    To prove foo_IDEMPOTENT, find a property P such that:
+
+                foo :: x:t -> {v:t | P(v)}
+                foo :: x:t -> {v:t | P(x) => v = x }
+
+SETS:
+    > Theorem prop_screens (s : stackSet i l a sd) :
+
+
+TRIV/HARD: (function definition)
+    > [TRIV]  Theorem prop_screens_work (x : stackSet i l a sd) :
+    > Theorem prop_mapWorkspaceId (x : stackSet i l a sd) :
+    > Theorem prop_mapLayoutId (s : stackSet i l a sd) :
+    > Theorem prop_mapLayoutInverse (s : stackSet i nat a sd) :
+    > Theorem prop_mapWorkspaceInverse (s : stackSet nat l a sd) :
+
+Theorem prop_lookup_current (x : stackSet i l a sd) :
+Theorem prop_lookup_visible (x : stackSet i l a sd) :
+
+
+Random Links
+============
+
+- Useful for DIGRAPH VIZ: http://arborjs.org/halfviz/#
+
+
+Benchmark Tags
+==============
+
+- LIQUIDFAIL : impossible to do verify the spec here
+- LIQUIDTODO : possible with some further hacking
+
+
+
+----------------------------------------------------------------------------
+
+http://www.cs.st-andrews.ac.uk/~eb/writings/fi-cbc.pdf
+
+McBride's Stack Machine youtube mcbride icfp 2012 monday keynote agda-curious
+
+    data Instr = Push Val | Add
+    type Val   = Int
+
+    measure needs                :: [Instr] -> Int
+    needs (Add    : is)          = min (2, 1 + needs(is))
+    needs (Push v : is)          = 0
+
+    run                          :: is:[Instr] -> {v:[Val] | len(v) >= needs(is)} -> [Val]
+    run (Add:is)      (x1:x2:vs) = run is (x1 + x2 : vs)
+    run (Push v : is) vs         = run is (v : vs)
+
+PROJECT: Termination for Combinator-based Parsers
+-------------------------------------------------
+
+btw, did you guys see this:
+
+http://www.reddit.com/r/haskell/comments/1okcmh/odd_space_leak_when_using_parsec/
+
+the poster probably feels silly, but I have, on several occasions, hit
+this issue with parsec. Wonder whether our termination checker could be used... hmm...
+
+Sure! You just have to give
+
+type GenParser tok st = Parsec [tok] st
+
+a size, I guess (len [tok]). The hard part will be to prove it when the size is actually decreasing...
+
+Hmm... Surely we need to track somehow the "effect" of executing a single parsing action.
+
+For example,
+
+    chars :: Char -> Parser [Char]
+    chars c = do z  <- char c
+                 zs <- chars c
+                 return (z:zs)
+
+What is the machinery by which the "recursive call" is run on a "smaller" GenParser?
+Does it help if we remove the `do` block?
+
+    chars :: Char -> Parser [Char]
+    chars c = char c  >>= \z  ->   
+              chars c >>= \zs ->
+              return (z:zs)
+
+I guess the question becomes, how/where do we specify (let alone verify) that the function
+`char c` *consumes* one character, hence causing the `chars` to run on a *smaller* input?
+
+
+Phew, after banging my head against this all day, this is what I came up with.
+
+You need a measure
+
+   measure eats :: Parser a -> Nat
+
+which describes (a lower bound) on the number of tokens consumed by the action `Parser a`.
+
+Now, you give
+
+   return :: a -> {v: Parser a | (eats v) = 0}
+
+and most importantly,
+
+   (>>=)  :: forall <Q :: Parser b -> Prop>
+             x: Parser a
+          -> f:{v: a -> Parser b <Q> | (rec v) => (eats x) > 0}
+          -> exists z:Parser b <Q>. {v:Parser b | (eats v) = (eats z) + (eats x)}
+
+(Of course you have to give appropriate signatures for the parsec combinators
+-- perhaps one can even PROVE the `eats` measure. However, note that
+
+   type Parser a = [Char] -> (a, [Char])
+
+roughly speaking, and here `eats` is actually the DIFFERENCE of the lengths of
+the input and output [Char] ... so I'm not sure how exactly we would reason about
+the IMPLEMENTATION of `eats` but certainly we should be able to USE it in clients
+of parsec.
+
+Note that you need a refinement ON the function type, the idea being that:
+
+1. the BODY of a recursive function is checked in the termination-strengthened
+environment that constrains the function to satisfy the predicate `rec`
+
+2. whenever you use >>= on a recursive function, the PRECEDING action must have
+consumed some tokens.
+
+3. the number of tokens consumed by the combined action equals the sum of the two
+actions (all the business about exists z and Q is to allow us to depend on the output
+value of `f` (c.f. tests/pos/cont1.hs)
+
+
+PROJECT: HTT style ST/IO reasoning with Abstract Refinements
+------------------------------------------------------------
+
++ Create a test case: `tests/todo/Eff*.hs`
+
++ Introduce a new sort of refinement `Ref` (with alias `RTProp`)
+   + Types.hs: Add to `Ref` -- in addition to `RMono` [---> `RPropP`] and `RPoly` [---> `RProp`]
+   + Types.hs: Add a `World t` for SL formulas...
+
+
++ Allow `PVar` to have the sort `HProp`
+   + CHANGE `ptype :: PVKind t` where `data PVKind t = PVProp t | PVHProp`
+   + Can we reuse `RAllP` to encode `HProp`-quantification? (YES)
+   + Update `RTyCon` to store `HProp` vars
+
+- Update consgen
+   + Can we reuse type-application sites for `HProp`-instantiation? (Yes)
+   - Constraint.hs  :1642:   = errorstar "TODO:EFFECTS:freshPredRef"
+   - PredType.hs         : go _ (_, RHProp _ _)    = errorstar "TODO:EFFECTS:replacePreds"
+
+- Write cons-solve
+  - eliminate/solve `HProp` constraints prior to subtype splitting.
+
+- Index `IO` or `State` by `HProp`
+   - Parse.hs: Update `data` parser to allow `TyCon` to be indexed by abstract `HProp`
+   - Bare.hs        :482 : addSymSortRef _ (RHProp _ _)   = errorstar "TODO:EFFECTS:addSymSortRef"
+
+**TODO:EFFECTS:ASKNIKI**
++ What is `isBind`,`pushConsBind` in Constraint.hs?
+
+
+3. Suitable signatures for monadic operators
+
+### RHProp
+
+a. Following `RProp` we should have
+
+	* RHProp := x1:t1,...,xn:tn -> World
+
+b. Where `World` is a _spatial conjunction_ of
+
+	* WPreds : (h v1 ... vn), h2, ...
+	* Wbinds : x1 := T1, x2 := T2, ...
+
+c. Such that each `World` has _at most one_ `WPred` (that is _not rigid_ i.e. can be solved for.)
+
+**Problem:** rejigger _inference_ to account for parameters in heap variables.
+
+
+
+### RPoly  (---> RProp)
+
+Per Niki:
+
+	RProp := x1:t1,...,xn:tn -> RType
+
+with the 'predicate' application implicitly buried as a `ur_pred` inside the RType
+
+For example, we represent
+
+	[a]<p>
+
+as
+
+	RApp [] a (RPoly  [(h:a)] {v:a<p>}) true
+
+which is the `RTycon` for lists `[]` applied to:
+
++ Tyvar `a`
+
++ RPoly with:
+	* _params_ `h:a`
+	* _body_   `{v:a<p> | true}` which is really, `RVar a {ur_reft = true, ur_pred = (Predicate 'p' with params 'h')}`
+
++ Outer refinement `true`
+
+
+
+
+
+
+
+**Heap Propositions** `HProp`
+
+```haskell
+CP := l :-> T * CP  -- Concrete Heap
+    | emp
+
+HP := CP       
+    | CP * H        -- Heap Variable
+```
+
+That is, an `HProp` is of the form:
+
+    H * l1 |-> T1 * ... * ln |-> Tn
+
+or
+
+    l1 |-> T1 * ... * ln |-> Tn
+
+I am disallowing multiple variables because it causes problems...
+
+
+**Abstractly Refined ST/IO**
+
+```haskell
+data IO a <Pre :: HProp, Post :: a -> HProp>
+```
+
+**Refined Monadic Operators**
+
+```haskell
+return :: forall a, <H :: HProp>.
+            a -> IO <H, \_ -> H> a
+
+(>>=)  :: forall a, b, <P :: HProp, Q :: a -> HProp, R :: b -> HProp>.
+            IO<P, Q> a -> (x:a -> IO<Q x, R> b) -> IO<P, R> b
+```
+
+**Q1.** How does LH *reason* about `HProp`?
+
+Via subtyping as always, so:
+
+         forall i. Γ |- Ti <: Ti'
+    -----------------------------------
+    Γ |- *_i li :-> Ti <: *_i li -> Ti'
+
+For this, we need to put in explicit `HProp` instantiations, just like
+tyvar (α) and  predvar (π) instinstatntiations. This is doable with a
+pre-pass that generates and solves `HProp` constraints as follows:
+
+1. At each instantiation, make up _fresh_ variables `h`
+2. Treat _bound_ heap-variables as **constants**
+3. Instantiation yields a set of constraints over `h`
+4. Solve constraints via algorithm below.
+
+**Q2.** Can you _name_ values inside `HProp`?
+
+Nope. There's no reason for this, but its tedious to have to make up
+new heap binders and what not. Clutters stuff. This is _slightly_
+problematic. For example, how do you write a function of the form:
+
+```haskell
+incr :: p:IORef Int -> IO Int
+```
+
+which _increments_ the value stored at the reference? Solution is slightly
+clunky: rather than the _implicit_ heap binder, add an explicit pure parameter:
+
+```haskell
+incr :: p:IORef Int -> i:Int -> IO {v:Int| v = i} <p |-> {v = i}, p |-> {v = i + 1}>
+```
+
+**Q3.** How to relate `Post`-condition to the `Pre`-conditions?
+
+Note that the `Post`-condition is a unary predicate -- i.e. _does not_
+refer to the input world. How then do we relate the input and output heaps?
+As above: _name_ the values of the input heap that you care about, and then
+relate `Post` to `Pre` via the name.
+
+**Q4.** How to _read_ values off the heap?
+
+Given that we don't have heap binders, this might seem like a problem? Not
+really. Just write signatures like:
+
+    read :: IORef a -> IO a
+
+aha, but there's a problem: the `a` is too _coarse_ or flow-insensitive: it
+holds a supertype of all the values written at the location, as opposed to the
+_current_ value. No matter, abstract refinements to the rescue:
+
+    read :: forall <I :: a -> Prop>.
+              p:IORef a -> IO <p |-> a<I>, p |-> a<I>> a<I>
+
+**Q5.** How do you do _subtyping_ on heaps/frame rule?
+
+Wait, how do I write _compositional_ signatures that only talk about a
+particular part of the state but allow me to say _other_ parts are unmodified
+etc? Don't you need heap subtyping? No: we can make the frame rule explicit by
+abstracting over heaps:
+
+    read :: forall <I :: a -> Prop, H :: HProp>.
+              p:IORef a -> IO <p |-> a<I> * H, p |-> a<I> * H> a<I>
+
+**Q6.** How to solve heap constraints?
+
+Heap constraints are of the form:
+
++ (C0)  `ch1      = ch2`        -- constants
++ (C1)  `H1 * ch1 = ch2`        -- 1-variable
++ (C2)  `H1 * ch1 = H2 * ch2`   -- 2-variable
+
+Here, each `ch` is of the form:
+
+    l1 |-> τ1 * ... * ln -> τn * A1 * ... * An
+
+where each `Ai` is a _rigid_ or quantified heap var that is atomic,
+i.e. cannot be further solved for. For solving, we throw away _all_
+refinements, and just use the shape τ.
+
+```
+solve :: Sol -> [Constraint] -> Maybe Sol
+solve σ []     
+  = Just σ
+solve σ (c:cs)
+  = case c of
+      C0 ch1 ch2 ->
+        if ch1 `equals` ch2  then
+          -- c is trivially SAT,
+          solve σ cs
+        else
+          -- c and hence all constraints are unsat
+          Nothing
+
+      C1 (H1 * ch1) ch2 ->
+        if ch1 `subset` ch2 then
+          let σ' = [H1 := c2 `minus` c1]
+          solve (σ . σ') (σ' <$> cs)
+        else
+          -- c and hence all constraints are unsat
+          Nothing
+
+      C2 (H1 * ch1) (H2 * ch2) ->
+        let H = fresh heap variable
+        let σ'  = [H1 := H * ch2, H2 := H * ch1]
+        solve (σ . σ') (σ' <$> cs)
+```
+
+
+
+PROJECT: (OLD) HTT style ST/IO reasoning with Abstract Refinements
+------------------------------------------------------------------
+
+
+Can we use abstract refinements to do "stateful reasoning",
+e.g. about stuff in `IO` ? For example, to read files, this
+is the API:
+
+    open  :: FilePath -> IO Handle
+    read  :: Handle   -> IO String
+    write :: Handle   -> String -> IO ()
+    close :: Handle   -> IO ()
+
+The catch is that:
+
++ `read` and `write` require the `Handle` to be in an "open" state,
++ which is the state of the `Handle` returned by `open`,
++ while `close` presumably puts the `Handle` in a "closed" state.
+
+So, suppose we parameterize IO with two predicates a `Pre` and `Post` condition
+
+    data IO a <Pre :: World -> Prop> <Post :: a -> World -> World -> Prop>
+
+where `World` is some abstract type denoting the global machine state.
+Now, it should be possible to give types like:
+
+   (>>=)  :: IO a <P, Q> -> (x:a -> IO b<Q x, R>) -> IO b<P, R>
+   return :: a -> IO a <P, P>
+
+which basically state whats going on with connecting the conditions, and then,
+give types to the File API:
+
+   open  :: FilePath -> IO Handle <\_ -> True> <\h _ w -> (IsOpen h w)>
+   read  :: h:Handle -> IO String <\w -> (IsOpen h w)> <\_ _ w -> (IsOpen h w)>
+   close :: h:Handle -> IO ()     <\w -> (IsOpen h w)> <\_ _ w -> not (IsOpen h w)>
+
+Wonder if something like this would work?
+
+Niki:
+My question is how do you make Q from a post-condition (Q :: a -> Word -> Word -> Prop)
+to a pre-condition.
+I guess you need to apply a value x :: a and a w :: Word to write (a -> IO b<Q x w, R>).
+
+I think the problem is that the "correct" values x and w are not "in scope"
+
+
+So assume
+
+    data IO a <P :: Word -> Prop, Q: a -> Word -> Word -> Prop>
+      = IO (x:Word<P> -> (y:a, Word<Q y x>))
+
+and you want to type
+
+    bind :: IO a <P,Q> -> (a -> IO b <Q x w, R>) -> IO b <P,R>
+    bind (IO m) k = IO $ \s -> case m s of
+                                 (a, s') -> unIO (k a) s'
+
+
+You have
+
+    IO m :: IO a <P. Q> => m :: xx:Word <P> -> (y:a, Word <Q y xx>)
+
+you can assume
+
+    s:: Word <P>
+
+so
+
+    m s         :: (y:a, Word <Q y s>)
+    k a         :: IO b <Q x w, R>
+    uniIO (k a) :: z:Word <Q x w> -> (xx:b, Word <R xx z>)
+
+and we want
+
+    (uniIO k a) s :: (xx:b , Word <R xx s>)
+
+so basically we need
+
+    P  => Q x w
+
+to be able to make the final application
+
+**Ranjit**
+You are right. We need to convert the "post" of the first action into the "pre"
+of the second, which is a problem since the former takes three, parameters while
+the latter takes only one.
+
+BUT, how about this (basically, all you need is an EXISTS).
+
+   -- | the type for `return` says that the output world satisfies
+   --   whatever predicate the input world satisfied.
+
+   return :: a -> IO a <P, {\_ _ w' -> (P w')}>
+
+   -- | the type for `bind` says that its action requires as input a world that satisfies
+   --   Q (for SOME input world w0) and produces as output an R world.
+   (>>=)  :: IO a <P, Q>
+          -> (x:a -> \exists w0:World. IO b<{\w -> (Q x w0 w)}, R>)
+          -> IO b<P, {\xb w w' -> \exists xa:a w0:World<Q xa w>.(R xb w0 w')}>
+
+
+
+Basically, I am using exists in the same way as in the "compose"
+
+https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/pos/funcomposition.hs
+
+to name the intermediate worlds and results (after all, this seems
+like a super fancy version of `.` ) -- may have not put them in the
+right place...
+
+Btw, the existential is also how the HOARE rule for strongest postcondition works,
+if you recall:
+
+   {P} x := e {exists x'. P[x'/x] /\ x = e[x'/x]}
+
+
+
+
+One of the hardest steps seem to type the monad function (>>=):
+
+
+So, suppose we parameterize IO with two predicates a `Pre` and `Post` condition
+
+    data IO a <Pre :: World -> Prop> <Post :: a -> World -> World -> Prop>
+
+where `World` is some abstract type denoting the global machine state.
+Now, it should be possible to give types like:
+
+   (>>=)  :: IO a <P, Q> -> (a -> IO b<Q, R>) -> IO b<P, R>
+   return :: a -> IO a <P, P>
+
+
+
+My question is how do you make Q from a post-condition (Q :: a -> Word -> Word -> Prop)
+to a pre-condition.
+I guess you need to apply a value x :: a and a w :: Word to write (a -> IO b<Q x w, R>).
+
+I think the problem is that the "correct" values x and w are not "in scope"
+
+
+So assume
+data IO a <P :: Word -> Prop, Q: a -> Word -> Word -> Prop> = IO (x:Word<P> -> (y:a, Word<Q y x>))
+
+and you want to type
+
+bind :: IO a <P,Q> -> (a -> IO b <Q x w, R>) -> IO b <P,R>
+bind (IO m) k = IO $ \s -> case m s of (a, s') -> (unIO (k a)) s'
+
+You have
+
+IO m :: IO a <P. Q>  
+             => m :: xx:Word <P> -> (y:a, Word <Q y xx>)
+
+you can assume
+s:: Word <P>
+
+so
+m s :: (y:a, Word <Q y s>)
+
+k a :: IO b <Q x w, R>
+
+uniIO (k a) :: z:Word <Q x w> -> (xx:b, Word <R xx z>)
+
+and we want
+(uniIO k a) s :: (xx:b , Word <R xx s>)
+
+so basically we need
+P  => Q x w
+to be able to make the final application
+
+
+bind :: ST a <P,Q> -> (a -> ST b <Q x w, R>) -> ST b <P,R>
+bind (ST f1) k = ST $ \s0 -> let (x, s1) = f1 s0  
+                                 ST f2   = k x
+                                 (y, s2) = f2 s1
+                             in
+                                 (y, s2)
+
+
+PROJECT: Using `Dynamic` + Refinements for Mixed Records
+--------------------------------------------------------
+
+Haskell has a class (and related functions)
+
+    toDyn   :: (Typeable a) => a -> Dynamic
+    fromDyn :: (Typeable a) => Dynamic -> Maybe a
+
+Q: How to encode *heterogenous* maps like:
+
+    d1 = { "name"  : "Ranjit"
+         , "age"   : 36
+         , "alive" : True
+         }
+
+   and also:
+
+    d2 = { "name"    : "Jupiter"
+         , "position": 5
+         }
+
+   so that you can write generic *duck-typed* functions like
+
+    showName :: Dict -> String
+
+   and write
+
+    showName d1
+    showName d2
+
+   or even
+
+    map showName [d1, d2]
+
+Step 1: Encode dictionary as vanilla Haskell type
+
+    type Dict <Q :: String -> Dynamic -> Prop> = Map String Dynamic <Q>
+    empty :: Dict
+    put   :: (Dynamic a) => String -> a -> Dict -> Dict
+    get   :: (Dynamic a) => String -> Dict -> Dict
+
+Step 2: **Create** dictionaries
+
+    d1 = put "name"   "RJ"
+       $ put "age"    36
+       $ put "alive"  True
+       $ empty
+
+    d1 = put "name"   "Jupiter"
+       $ put "pos"    5
+       $ empty
+
+Step 3: **Lookup** dictionaries
+
+    showName :: Dict -> String
+    showName d = get "name" d
+
+    -- TODO: how to support
+    showName :: Dict -> Dict
+    incrAge d = put "age" (n + 1) d
+      where
+            n = get "age" d
+
+    -- TODO: how to support
+    concat :: Dict -> Dict -> Dict
+
+Step 4: Can directly, without any casting nonsense, call
+
+    showName d1
+    showName d2
+
+Need to reflect *Haskell Type* (or at least, `TypeRep` values)
+inside logic, so you can write measures like
+
+    measure TypeOf :: a -> Type
+
+and use it to define refinements like
+
+    (TypeOf v = Int)
+
+(TODO: too bad we don't have relational measures... or multi-param measures ... yet!)
+
+which we can macro up thus.
+
+    predicate HasType V T = (TypeOf V = T)
+
+    predicate Fld K V N T = (K = N => (HasType V T))
+
+Step 5: Refined Signatures for `Dict` API
+
+    put :: (Dynamic a) => key:String
+                       -> {value:a | (Q key value)}
+                       -> d:Dict <Q /\ {\k _ -> k /= key}>
+                       -> Dict <Q /\ {\k v -> (Fld k v key a)}>
+
+    get :: (Dynamic a) => key:String
+                       -> d:Dict <{\k v -> (Fld k v key a)}>
+                       -> a
+
+Step 6: Now, for example, we should be able to type our dictionaries as
+
+    {-@ d1 :: Dict<Q1> @-}
+
+where
+
+    Q1 == \k v -> Fld k v "name"  String /\
+                  Fld k v "age"   Int    /\
+                  Fld k v "alive" Bool   
+
+and
+
+    {-@ d2 :: Dict<Q2> @-}
+
+where
+
+    Q2 == \k v -> Fld k v "name"  String /\
+                  Fld k v "pos"   Int    /\
+
+**TODO:**
+
++ add support for `Type` inside logic
+  + needed for `TypeOf` measure, equality checks
+  + requires doing type-substitutions inside refinements
+
++ add support for
+  + update [isn't that just `put`?]
+  + concat
+
++ add support traversals (cf. *Ur*)
+  - Fold   (over all fields, eg. to serialize into a String)
+  - Map?   (transform all fields to serialize) toDB?
+  - Filter (takes a predicate that should only read valid columns of the record)
+
+
+PROJECT: Equational Reasoning
+-----------------------------
+
+e.g. Type class laws.
+
+Many type-classes come with a set of laws that instances are expected
+to abide by, e.g.
+
+```
+fmap id  ==  id
+
+fmap (f . g)  ==  fmap f . fmap g
+```
+
+```
+mappend mempty x = x
+
+mappend x mempty = x
+
+mappend x (mappend y z) = mappend (mappend x y) z
+```
+
+**Strategy**
+
+**1. Representing Proofs**
+
+```
+data Proof  = Proof           -- void, pure refinement
+
+type Pf P   = {v:Proof | P}
+
+type Eq X Y = Pf (X == Y)
+```
+
+**2. Combining Proofs**
+
+```
+bound Imp P Q R = P => Q => R
+
+eq, imp :: (Imp P Q R) => Pf P -> Pf Q -> Pf R
+
+refl    :: x:a -> Eq a x x
+```
+
+**3. Axiomatizing arithmetic**
+
+```
+add :: x:Int -> y:Int -> {z:Int | z = x + y} -> Eq (x + y) z
+add x y z = auto
+```
+
+
+**Example 1: Arithmetic**
+
+Lets drill in: how to represent the following "equational" proof in LH?
+
+```
+     (1 + 2) + (3 + 4)       -- e0
+
+     { 1 + 2 == 3}
+
+  == 3 + (3 + 4)             -- e1
+
+     { 3 + 4 == 7}
+
+  == 3 + 7                   -- e2
+
+     { 3 + 7 == 10}
+
+  == 10                      -- e3
+```
+
+Now the above proof looks like this:
+
+```
+e0 :: Int
+e0 = (1 + 2) + (3 + 4)
+
+prop :: Eq e0 10
+prop = (((refl e0  `imp` (add 1 2 3))   -- :: Eq e0 (3 + (3 + 4))
+
+                   `imp` (add 3 4 7))   -- :: Eq e0 (3 + 7)
+
+                   `imp` (add 3 7 10))  -- :: Eq e0 10  
+```
+
+
+**Example 2: Lists**
+
+A more interesting example: Lets prove `prop_app_nil`:
+
+    prop_app_nil: forall xs. append xs [] = xs
+
+The definition of
+
+```
+append []     ys = ys
+append (x:xs) ys = x : append xs ys
+```
+
+yields the *axioms*
+
+```
+append_nil  :: ys:_ -> Eq (append [] ys) ys
+append_cons :: x:_ -> xs:_ -> ys:_ -> Eq (append (x:xs) ys) (x : append xs ys)
+```
+
+Code on left, "equations" on right.
+
+```
+prop_app_nil    :: xs:[a] -> Eq (append xs []) xs
+
+prop_app_nil []     = refl (append [] [])             
+                                                   -- append [] []
+                       `by` (append_nil [])        -- { append_nil [] }    
+                                                   -- == []  
+
+prop_app_nil (x:xs) = refl (append (x:xs) [])       
+                                                   -- append (x:xs) []
+                       `by` (append_cons x xs [])  -- { append_cons x xs [] }
+                                                   -- == x : append xs []
+                       `by` (prop_app_nil xs)      -- { IH: prop_app xs }
+                                                   -- == x : xs
+```
+
+**Example 4: Append Associates**
+
+
+```
+prop_app_assoc :: xs:_ -> ys:_ -> zs:_ ->
+                     Eq ((xs ++ ys) ++ zs) (xs ++ (ys ++ zs))
+
+prop_app_assoc [] ys zs
+  ([] ++ ys) ++ zs
+  { append_nil _ }    
+  == ys ++ zs
+  { append_nil _ }
+  == [] ++ (ys ++ zs)
+
+prop_app_assoc (x:xs) ys zs
+  ((x:xs) ++ ys) ++ zs
+  { append_cons _ _ _ }    
+  == (x : (xs ++ ys)) ++ zs
+  { append_cons _ _ _ }
+  == x : ((xs ++ ys) ++ zs)
+  { prop_app_assoc _ _ _ }
+  == x : (xs ++ (ys ++ zs))
+  { append_cons _ _ _ }
+  == (x : xs) ++ (ys ++ zs)
+```
+
+
+**Example 4: Map Fusion**
+
+Lets go fancier:
+
+
+    forall xs. map (f . g) xs = (map f . map g) xs
+
+Here's the classical (?) equational proof:
+
+```
+map (f . g) []   
+   { map_nil (f . g) }
+   == []
+   { map_nil f }
+   == map f []
+   { map_nil g }
+   == map f (map g [])
+   { dot f g }
+   == (map f . map g) []
+
+map (f . g) (x:xs)  
+   { map_cons (f . g) x xs }
+   == (f . g) x : map (f . g) xs
+   { map_dot f g xs }
+   == (f . g) x : (map f . map g) xs
+   { dot (map f) (map g) }
+   == (f . g) x : map f (map g xs)
+   { dot f g }
+   == f (g x) : map f (map g xs)
+   {map_cons f (g x) (map g xs) }
+   == map f (g x : map g xs)
+   {map_cons g x xs}
+   == map f (map g (x : xs))
+   { dot (map f) (map g) }
+   ==  (map f . map g) (x : xs)
+```
+
+Formalize thus (with functions/axioms)
+
+```
+map f []     = []               -- map_nil
+map f (x:xs) = f x  : map f xs  -- map_cons
+
+(f . g) x    =  f (g x)         -- dot
+```
+
+Now, we formalize map-fusion as:
+
+```
+map_fusion :: f:_ -> g:_ -> xs:_ ->
+              Eq (map (f . g) xs) (map f . map g) xs
+
+map_fusion f g []     = map_dot_nil f g
+map_fusion f g (x:xs) = map_dot_cons f g x xs
+```
+
+The hard work happens in the two "lemmas"
+
+```
+map_dot_nil :: f:_ -> g:_ ->
+               Eq (map (f . g) []) ((map f . map g) [])
+map_dot_nil f g
+  = refl (map (f . g) [])   
+                              -- map (f . g) []
+     `by` (map_nil (f . g))
+                              -- == []
+     `by` (map_nil f)
+                              -- == map f []
+     `by` (map_nil g)
+                              -- == map f (map g [])
+     `by` (dot f g)
+                              -- == (map f . map g) []
+```
+
+and
+
+```
+map_dot_cons :: f:_ -> g:_ -> x:_ -> xs:_ ->
+               Eq (map (f . g) (x:xs)) ((map f . map g) (x:xs))
+map_dot_cons f g x xs
+  = refl (map (f . g) (x:xs))
+                                          -- map (f . g) (x : xs)
+      `by` (map_cons (f . g) x xs)
+                                          -- == (f . g) x : map (f . g) xs
+      `by` (map_dot f g xs)
+                                          -- == (f . g) x : (map f . map g) xs
+      `by` (dot (map f) (map g))
+                                          -- == (f . g) x : map f (map g xs)
+      `by` (dot f g)
+                                          -- == f (g x) : map f (map g xs)
+      `by` (map_cons f (g x) (map g xs))
+                                          -- == map f (g x : map g xs)
+      `by` (map_cons g x xs)
+                                          -- == map f (map g (x : xs))
+      `by` (dot (map f) (map g))
+                                          -- ==  (map f . map g) (x : xs)
+```
+
+
+
+GHC 7.10
+--------
+
+- **DONE** singleton type classes represented by newtype
+  - tried to work around by translating
+
+      foo `cast` (co :: a -> b ~ Foo)
+
+    to
+
+      D:Foo foo
+
+    but it still breaks when we don't have an LH class decl
+  - without LH class decl we never see D:Foo, so it doesn't go in CGEnv
+  - SOLUTION: put ALL visible dict constructors in CGEnv
+
+- `cast`s are used more often and we seem to lose information..
+  - seems particularly problematic with ST
+
+- srcloc annotations
+  - -g adds SourceNotes, but the html output is borked
+  - in particular, infix operators aren't annotated correctly (at all?)
+  - are we missing some SrcLocs??
+    - clearly not, if you look at the output of
+
+          ghc -g -ddump-ds -dppr-ticks <file.hs>
+
+      somewhere along our pipeline the ticks are either being dropped,
+      or the SrcSpans don't quite match the way they used to...
+
+- termination metrics are required in a few places where they were not previously
+  - my guess is that ghc's behaviour for grouping functions in a `Rec` binder have changed
diff --git a/cabal.project b/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal.project
@@ -0,0 +1,12 @@
+-- For more information see
+--  http://cabal.readthedocs.io/en/latest/nix-local-build-overview.html
+
+packages: .
+          ./liquid-fixpoint
+          ./liquiddesugar
+
+package liquid-fixpoint
+  flags: devel
+
+package liquidhaskell
+  flags: devel
diff --git a/circle.yml b/circle.yml
new file mode 100644
--- /dev/null
+++ b/circle.yml
@@ -0,0 +1,56 @@
+machine:
+  #ghc:
+  #  version: 7.10.2
+  pre:
+    - sudo add-apt-repository -y ppa:hvr/z3
+    # - sudo add-apt-repository -y ppa:hvr/ghc
+    - sudo apt-get -y update
+    - sudo apt-get -y install z3 # ghc-7.10.3
+
+checkout:
+  post:
+    - git submodule sync
+    - sed -i '/fixpoint.git/a fetch = +refs/pull/*/head:refs/remotes/origin/pr/*' .git/modules/liquid-fixpoint/config
+    - git submodule update --init
+    - pwd
+
+dependencies:
+  cache_directories:
+    - "~/.stack"
+    - ".stack-work"
+  pre:
+    # - curl -sSL https://get.haskellstack.org/ | sh
+    - curl -SL https://www.stackage.org/stack/linux-x86_64-static | tar zx -C /tmp
+    # - curl -L https://github.com/commercialhaskell/stack/releases/download/v1.0.4/stack-1.0.4-linux-x86_64.tar.gz | tar zx -C /tmp
+    - sudo mv /tmp/stack-*-linux-x86_64-static/stack /usr/bin
+  override:
+    - stack setup
+    - rm -fr $(stack path --dist-dir) $(stack path --local-install-root)
+    - stack install --fast hlint packdeps cabal-install
+    - stack build liquidhaskell --fast --only-dependencies --test --no-run-tests
+    
+compile:
+  override:
+    # - stack build liquidhaskell --fast --pedantic --flag liquidhaskell:include --flag liquidhaskell:devel
+    - stack build liquidhaskell --fast --flag liquidhaskell:include --flag liquidhaskell:devel
+    - stack build liquidhaskell --fast --flag liquidhaskell:include --flag liquidhaskell:devel --test --no-run-tests
+
+test:
+  override:
+    - mkdir -p $CIRCLE_TEST_REPORTS/junit
+    - stack test liquidhaskell:test --flag liquidhaskell:include --flag liquidhaskell:devel --test-arguments="-j1 --xml=$CIRCLE_TEST_REPORTS/junit/main-test-results.xml --liquid-opts='--cores=1'":
+        timeout: 1800
+    - stack test liquidhaskell:liquidhaskell-parser --test-arguments="-j2 --xml=$CIRCLE_TEST_REPORTS/junit/parser-test-results.xml":
+        timeout: 1800
+    # - git ls-files | grep '\.l\?hs$' | xargs stack exec -- hlint -X QuasiQuotes "$@"
+    # - stack exec -- cabal update
+    # - stack exec --no-ghc-package-path -- cabal install --only-dependencies --dry-run --reorder-goals
+    # - stack exec -- packdeps *.cabal || true
+    # - stack exec -- cabal check
+    - stack sdist
+  post:
+    - stack haddock liquidhaskell --no-haddock-deps --haddock-arguments="--no-print-missing-docs --odir=$CIRCLE_ARTIFACTS"
+    # - cp -r dist/doc $CIRCLE_ARTIFACTS
+    - mkdir -p $CIRCLE_TEST_REPORTS/tasty
+    - cp -r tests/logs/cur $CIRCLE_TEST_REPORTS/tasty/log
+    # - hpc-coveralls --exclude-dir=tests --repo-token=$COVERALLS_REPO_TOKEN
diff --git a/cleanup b/cleanup
new file mode 100644
--- /dev/null
+++ b/cleanup
@@ -0,0 +1,1 @@
+find . | grep -E -e '\.(smt2|bak|json|css|md|hi|out|fqout|fq|o|err|annot|log|html|cgi|liquid)$' | xargs rm -rf
diff --git a/default.nix b/default.nix
new file mode 100644
--- /dev/null
+++ b/default.nix
@@ -0,0 +1,38 @@
+{ fetchgitLocal }:
+{ mkDerivation, aeson, array, base, bifunctors, bytestring, Cabal
+, cereal, cmdargs, containers, cpphs, daemons, data-default
+, deepseq, Diff, directory, filepath, fingertree, ghc, ghc-paths
+, hashable, hpc, hscolour, liquid-fixpoint, located-base, mtl
+, network, optparse-applicative, parsec, pretty, process
+, stdenv, stm, syb, tagged, tasty, tasty-hunit, tasty-rerun
+, template-haskell, text, time, transformers, unix
+, unordered-containers, vector, z3
+, tasty-ant-xml
+}:
+mkDerivation {
+  pname = "liquidhaskell";
+  version = "9.9.9.9";
+  src = fetchgitLocal ./.;
+  isLibrary = true;
+  isExecutable = true;
+  libraryHaskellDepends = [
+    aeson array base bifunctors bytestring Cabal cereal cmdargs
+    containers cpphs data-default deepseq Diff directory filepath
+    fingertree ghc ghc-paths hashable hpc hscolour liquid-fixpoint
+    located-base mtl parsec pretty process syb template-haskell
+    text time unordered-containers vector hscolour
+  ];
+  executableHaskellDepends = [
+    base bytestring cereal cmdargs daemons data-default deepseq
+    directory ghc liquid-fixpoint located-base network pretty process
+    unix unordered-containers
+  ];
+  testHaskellDepends = [
+    base containers directory filepath mtl optparse-applicative process
+    stm tagged tasty tasty-hunit tasty-rerun transformers tasty-ant-xml
+  ];
+  testSystemDepends = [ z3 ];
+  homepage = "http://goto.ucsd.edu/liquidhaskell";
+  description = "Liquid Types for Haskell";
+  license = stdenv.lib.licenses.bsd3;
+}
diff --git a/devel/Paths_liquidhaskell.hs b/devel/Paths_liquidhaskell.hs
new file mode 100644
--- /dev/null
+++ b/devel/Paths_liquidhaskell.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE TemplateHaskell #-}
+module Paths_liquidhaskell where
+
+import Language.Haskell.TH
+import System.Directory
+import System.FilePath
+
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName f = do
+  let loc = $(do { loc <- location; f <- runIO (canonicalizePath (loc_filename loc)); litE (stringL f); })
+  let root = takeDirectory (takeDirectory loc)
+  return (root </> f)
diff --git a/docs/blog/2013-01-01-refinement-types-101.lhs b/docs/blog/2013-01-01-refinement-types-101.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-01-01-refinement-types-101.lhs
@@ -0,0 +1,312 @@
+---
+layout: post
+title: "Refinement Types 101"
+date: 2013-01-01 16:12
+author: Ranjit Jhala
+published: true
+comments: true
+external-url:
+categories: basic
+demo: refinements101.hs
+---
+
+One of the great things about Haskell is its brainy type system that
+allows one to enforce a variety of invariants at compile time, thereby
+nipping a large swathe of run-time errors in the bud. Refinement types
+allow us to use modern logic solvers (*aka* SAT and SMT engines) to
+dramatically extend the scope of invariants that can be statically
+verified.
+
+What is a Refinement Type?
+--------------------------
+
+In a nutshell, 
+
+<blockquote><p>
+Refinement Types = Types + Logical Predicates
+</p></blockquote>
+
+That is, refinement types allow us to decorate types with 
+*logical predicates* (think *boolean-valued* Haskell expressions) 
+which constrain the set of values described by the type, and hence 
+allow us to specify sophisticated invariants of the underlying values. 
+
+Say what? 
+
+<!-- more -->
+
+(Btw, *click the title* to demo LiquidHaskell on the code in this article)
+
+\begin{code}
+module Intro where
+
+import Language.Haskell.Liquid.Prelude  (liquidAssert)
+\end{code}
+
+Let us jump right in with a simple example, the number `0 :: Int`. 
+As far as Haskell is concerned, the number is simply an `Int` (lets not
+worry about things like `Num` for the moment). So are `2`, `7`, and 
+`904`. With refinements we can dress up these values so that they 
+stand apart. For example, consider the binder
+
+\begin{code}
+zero' :: Int
+zero' = 0
+\end{code}
+
+We can ascribe to the variable `zero'` the refinement type
+
+\begin{code}
+{-@ zero' :: {v: Int | 0 <= v} @-}
+\end{code}
+
+which is simply the basic type `Int` dressed up with a predicate.
+The binder `v` is called the *value variable*, and so the above denotes 
+the set of `Int` values which are greater than `0`. Of course, we can
+attach other predicates to the above value, for example
+
+**Note:** We will use `@`-marked comments to write refinement type 
+annotations the Haskell source file, making these types, quite literally,
+machine-checked comments!
+
+
+\begin{code}
+{-@ zero'' :: {v: Int | (0 <= v && v < 100) } @-}
+zero'' :: Int
+zero'' = 0
+\end{code}
+
+which states that the number is in the range `0` to `100`, or
+
+\begin{code}
+{-@ zero''' :: {v: Int | ((v mod 2) = 0) } @-}
+zero''' :: Int
+zero''' = 0
+\end{code}
+
+where `mod` is the *modulus* operator in the refinement logic. Thus, the type
+above states that zero is an *even* number.
+
+We can also use a singleton type that precisely describes the constant
+
+\begin{code}
+{-@ zero'''' :: {v: Int | v = 0 } @-}
+zero'''' :: Int
+zero'''' = 0
+\end{code}
+
+(Aside: we use a different names `zero'`, `zero''` etc. for a silly technical 
+reason -- LiquidHaskell requires that we ascribe a single refinement type to 
+a top-level name.)
+
+Finally, we could write a single type that captures all the properties above:
+
+\begin{code}
+{-@ zero :: {v: Int | ((0 <= v) && ((v mod 2) = 0) && (v < 100)) } @-}
+zero     :: Int
+zero     =  0
+\end{code}
+
+The key points are:
+
+1. A refinement type is just a type *decorated* with logical predicates.
+2. A value can have *different* refinement types that describe different properties.
+3. If we *erase* the green bits (i.e. the logical predicates) we get back *exactly* 
+   the usual Haskell types that we know and love.
+4. A vanilla Haskell type, say `Int` has the trivial refinement `true` i.e. is 
+   really `{v: Int | true}`.
+
+We have built a refinement type-based verifier called LiquidHaskell. 
+Lets see how we can use refinement types to specify and verify interesting 
+program invariants in LiquidHaskell.
+
+Writing Safety Specifications
+-----------------------------
+
+We can use refinement types to write various kinds of more interesting
+safety specifications.
+
+First, we can write a wrapper around the usual `error` function 
+
+\begin{code}
+{-@ error' :: {v: String | false } -> a  @-}
+error'     :: String -> a
+error'     = error
+\end{code}
+
+The interesting thing about the type signature for `error'` is that the
+input type has the refinement `false`. That is, the function must only be
+called with `String`s that satisfy the predicate `false`. Of course, there
+are *no* such values. Thus, a program containing the above function
+typechecks *exactly* when LiquidHaskell can prove that the function
+`error'` is *never called*.
+
+Next, we can use refinements to encode arbitrary programmer-specified 
+**assertions** by defining a function
+
+\begin{code}
+{-@ lAssert     :: {v:Bool | (Prop v)} -> a -> a  @-}
+lAssert         :: Bool -> a -> a 
+lAssert True  x = x
+lAssert False _ = error' "lAssert failure" 
+\end{code}
+
+In the refinement, `(Prop v)` denotes the Haskell `Bool` value `v` 
+interpreted as a logical predicate. In other words, the input type for 
+this function specifies that the function must *only* be called with
+the value `True`.
+
+
+Refining Function Types : Preconditions
+---------------------------------------
+
+Lets use the above to write a *divide* function that *only accepts* non-zero
+denominators. 
+
+\begin{code}
+divide     :: Int -> Int -> Int
+divide n 0 = error' "divide by zero"
+divide n d = n `div` d
+\end{code}
+
+We can specify that the non-zero denominator *precondition* with a suitable 
+refinement on the *input* component of the function's type 
+
+\begin{code}
+{-@ divide :: Int -> {v: Int | v != 0 } -> Int @-}
+\end{code}
+
+How *does* LiquidHaskell verify the above function? 
+
+The key step is that LiquidHaskell deduces that the expression 
+`"divide by zero"` is not merely of type `String`, but in fact 
+has the the refined type `{v:String | false}` *in the context* 
+in which the call to `error'` occurs.
+
+LiquidHaskell arrives at this conclusion by using the fact that 
+in the first equation for `divide` the *denominator* parameter 
+is in fact `0 :: {v: Int | v = 0}` which *contradicts* the 
+precondition (i.e. input) type.
+
+In other words, LiquidHaskell deduces by contradiction, that 
+the first equation is **dead code** and hence `error'` will 
+not be called at run-time.
+
+If you are paranoid, you can put in an explicit assertion
+
+\begin{code}
+{-@ divide' :: Int  -> {v:Int | v /= 0} -> Int @-}
+divide'     :: Int -> Int -> Int
+divide' n 0 = error' "divide by zero"
+divide' n d = lAssert (d /= 0) $ n `div` d
+\end{code}
+
+and LiquidHaskell will verify the assertion (by verifying the call to
+`lAssert`) for you.
+
+Refining Function Types : Postconditions
+----------------------------------------
+
+Next, lets see how we can use refinements to describe the *outputs* of a
+function. Consider the following simple *absolute value* function
+
+\begin{code}
+abz               :: Int -> Int
+abz n | 0 < n     = n
+      | otherwise = 0 - n
+\end{code}
+
+We can use a refinement on the output type to specify that the function 
+returns non-negative values
+
+\begin{code}
+{-@ abz :: Int -> {v: Int | 0 <= v } @-}
+\end{code}
+
+LiquidHaskell *verifies* that `abz` indeed enjoys the above type by
+deducing that `n` is trivially non-negative when `0 < n` and that in 
+the `otherwise` case, i.e. when `not (0 < n)` the value `0 - n` is
+indeed non-negative (lets not worry about underflows for the moment.)
+LiquidHaskell is able to automatically make these arithmetic deductions
+by using an [SMT solver](http://rise4fun.com/Z3/) which has decision
+built-in procedures for arithmetic, to reason about the logical
+refinements.
+
+
+
+Putting It All Together
+-----------------------
+
+Lets wrap up this introduction with a simple `truncate` function 
+that connects all the dots. 
+
+\begin{code}
+{-@ truncate :: Int -> Int -> Int @-}
+truncate i max  
+  | i' <= max' = i
+  | otherwise  = max' * (i `divide` i')
+    where i'   = abz i
+          max' = abz max 
+\end{code}
+
+`truncate i n` simply returns `i` if its absolute value is less the
+upper bound `max`, and otherwise *truncates* the value at the maximum.
+LiquidHaskell verifies that the use of `divide` is safe by inferring that 
+at the call site
+
+1. `i' > max'` from the branch condition.
+2. `0 <= i'`   from the `abz` postcondition (hover mouse over `i'`).
+3. `0 <= max'` from the `abz` postcondition (hover mouse over `max'`).
+
+From the above, LiquidHaskell infers that `i' != 0`. That is, at the
+call site `i' :: {v: Int | v != 0}`, thereby satisfying the
+precondition for `divide` and verifying that the program has no pesky 
+divide-by-zero errors. Again, if you *really* want to make sure, put 
+in an assertion
+
+\begin{code}
+{-@ truncate' :: Int -> Int -> Int @-}
+truncate' i max  
+  | i' <= max' = i
+  | otherwise  = lAssert (i' /= 0) $ max' * (i `divide` i')
+    where i'   = abz i
+          max' = abz max 
+\end{code}
+
+and *lo!* LiquidHaskell will verify it for you.
+
+Modular Verification
+--------------------
+
+Incidentally, note the `import` statement at the top. Rather than rolling
+our own `lAssert` we can import and use a pre-defined version `liquidAssert` 
+defined in an external [module](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Language/Haskell/Liquid/Prelude.hs)
+
+\begin{code}
+{-@ truncate'' :: Int -> Int -> Int @-}
+truncate'' i max  
+  | i' <= max' = i
+  | otherwise  = liquidAssert (i' /= 0) $ max' * (i `divide` i')
+    where i'   = abz i
+          max' = abz max 
+\end{code}
+
+In fact, LiquidHaskell comes equipped with suitable refinements for
+standard functions and it is easy to add refinements as we shall
+demonstrate in subsequent articles.
+
+Conclusion
+----------
+
+This concludes our quick introduction to Refinement Types and
+LiquidHaskell. Hopefully you have some sense of how to 
+
+1. **Specify** fine-grained properties of values by decorating their
+   types with logical predicates.
+2. **Encode** assertions, preconditions, and postconditions with suitable
+   function types.
+3. **Verify** semantic properties of code by using automatic logic engines 
+   (SMT solvers) to track and establish the key relationships between 
+   program values.
+
+
diff --git a/docs/blog/2013-01-27-refinements101-reax.lhs b/docs/blog/2013-01-27-refinements101-reax.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-01-27-refinements101-reax.lhs
@@ -0,0 +1,262 @@
+---
+layout: post
+title: "Refinements 101 (contd.)" 
+date: 2013-01-27 16:12
+author: Ranjit Jhala
+published: true 
+comments: true
+external-url:
+categories: basic
+demo: refinements101reax.hs
+---
+
+Hopefully, the [previous][ref101] article gave you a basic idea about what
+refinement types look like. Several folks had interesting questions, that
+are worth discussing in a separate post, since they throw a lot of light 
+on the strengths (or weaknesses, depending on your point of view!) of
+LiquidHaskell.
+
+<!-- more -->
+
+\begin{code}
+module Refinements101Reax where
+\end{code}
+
+How to relate outputs and inputs 
+--------------------------------
+
+Recall the function `divide`
+
+\begin{code}
+{-@ divide :: Int -> {v: Int | v /= 0 } -> Int @-}
+divide     :: Int -> Int -> Int
+divide n 0 = error "divide by zero"
+divide n d = n `div` d
+\end{code}
+
+and `abz` was the absolute value function
+
+\begin{code}
+abz               :: Int -> Int
+abz n | 0 < n     = n
+      | otherwise = 0 - n
+\end{code}
+
+[nanothief](http://www.reddit.com/user/nanothief) [remarked][qreddit101]
+that LiquidHaskell was unable to verify the safety of the following call to
+`divide` (i.e. was unable to show that `x` was non-zero at the callsite).
+
+\begin{code}
+{-@ f :: Int -> Int @-}
+f x | abz x == 0 = 3
+    | otherwise  = 3 `divide` x
+\end{code}
+
+Nanothief correctly argues that the code is clearly safe as *"`abz x == 0` being false implies `x /= 0`"*. 
+Indeed, the code *is safe*, however, the reason that LiquidHaskell
+rejected it has nothing to do with its inability
+to  *"track the constraints of values based on tests using new values derived from that value"* as Nanothief surmised,
+but instead, because LiquidHaskell supports **modular verification** 
+where the *only* thing known about `abz` at a *use site* is 
+whatever is specified in its *type*. 
+
+\begin{code}Concretely speaking, the type 
+abz :: Int -> {v: Int | 0 <= v }
+\end{code}
+
+is too anemic to verify `f` above, as it tells us nothing 
+about the *relationship* between the output and input -- looking at it,
+we have now way of telling that when the *output* (of `abz`) is 
+non-zero, the *input*  must also have been non-zero.
+
+\begin{code}Instead, we can write a *stronger* type which does capture this information, for example
+abz :: x:Int -> {v:Int | v = (if (x > 0) then x else (0 - x))}
+\end{code}
+
+\begin{code} where 
+v = (if p then e1 else e2)
+\end{code}
+
+\begin{code} is an abbreviation for the formula 
+(p => v == e1) && ((not p) => v = e2)
+\end{code}
+
+With this specification for `abz`, LiquidHaskell is able to reason that
+when `abz x` is non-zero, `x` is also non-zero. Of course, `abz` is trivial 
+enough that we can very precisely capture its *exact* semantics in the 
+refinement type, but thats is rarely the case. 
+
+Nevertheless, even here, you could write a somewhat *weaker* specification,
+that still had enough juice to allow the verification of the `divide` call
+in `f`. In particular, we might write
+
+\begin{code}
+{-@ abz :: x:Int -> {v:Int | ((0 <= v) && ((v = 0) <=> (x = 0))) } @-}
+\end{code}
+
+which states the output is `0` *if and only if* the input is `0`.
+LiquidHaskell will happily verify that `abz` implements this specification,
+and will use it to verify the safety of `f` above.
+
+(BTW, follow the link above to *demo this code*  yourself.)
+
+How to tell a Fib
+-----------------
+
+[Chris Done](https://twitter.com/christopherdone) [asked][qblog101]
+why LiquidHaskell refused to verify the following definition of `fib`.
+
+\begin{code}
+{-@ fib :: n:Int -> { b:Int | (n >= 0 && b >= n) } @-}
+fib :: Int -> Int
+fib 0 = 0
+fib 1 = 1
+fib n = fib (n-1) + fib (n-2)
+\end{code}
+
+Indeed, the both the *specification* and the *implementation* look pretty
+legit, so what gives?  It turns out that there are *two* different reasons why. 
+
+**Reason 1: Assumptions vs. Guarantees**
+
+What we really want to say over here is that the *input* `n` 
+is non-negative. However, putting the refinement `n >= 0` in 
+the *output* constraint means that it becomes something that 
+LiquidHaskell checks that the function `fib` **guarantees** 
+(or **ensures**).
+That is, the type states that we can pass `fib` *any* value 
+`n` (including *negative* values) and yet, `fib` must return 
+values `b` such that `b >= n` *and* `n >= 0`. 
+
+The latter requirement is a rather tall order when an arbitrary `n` 
+is passed in as input. `fib` can make no such guarantees since 
+it was *given* the value `n` as a parameter. The only way `n` could 
+be non-negative was that if the caller had sent in a non-negative value. 
+Thus, we want to put the *burden of proof* on the right entity here, 
+namely the caller.
+
+To assign the burden of proof appropriately, we place the
+non-negative refinement on the *input type*
+
+\begin{code}
+{-@ fib' :: n:{v:Int | v >= 0} -> {b:Int | (n >= 0 && b >= n) } @-}
+fib' :: Int -> Int
+fib' 0 = 0
+fib' 1 = 1
+fib' n = fib (n-1) + fib (n-2)
+\end{code}
+
+where now at *calls to* `fib'` LiquidHaskell will check that the argument
+is non-negative, and furthermore, when checking `fib'` LiquidHaskell will 
+**assume** that the parameter `n` is indeed non-negative. So now the
+constraint `n >= 0` on the output is somewhat redundant, and the
+non-negative `n` guarantee holds trivially.
+
+**Reason 2: The Specification is a Fib**
+
+If you run the above in the demo, you will see that LiquidHaskell still
+doth protest loudly, and frankly, one might start getting a little
+frustrated at the stubbornness and petulance of the checker.
+
+\begin{code} However, if you stare at the implementation, you will see that it in fact, *does not* meet the specification, as
+fib' 2  == fib' 1 + fib' 0
+        == 0 + 1
+        == 1
+\end{code}
+
+LiquidHaskell is reluctant to prove things that are false. Rather than 
+anthropomorphize frivolously, lets see why it is unhappy. 
+
+\begin{code}First, recall the somewhat simplified specification 
+fib' :: n:Int -> { b:Int | (b >= n) } 
+\end{code}
+
+As we saw in the discussion about `abz`, at each recursive callsite
+the *only information* LiquidHaskell uses about the returned value, 
+is that described in the *output type* for that function call.
+
+\begin{code}Thus, LiquidHaskell reasons that the expression:
+fib' (n-1) + fib' (n-2)
+\end{code}
+
+\begin{code}has the type
+{b: Int | exists b1, b2. b  == b1 + b2 
+                      && b1 >= n-1 
+                      && b2 >= n-2     }
+\end{code}
+
+where the `b1` and `b2` denote the values returned by the 
+recursive calls --- we get the above by plugging the parameters
+`n-1` and `n-2` in for the parameter `n` in output type for `fib'`.
+
+\begin{code}The SMT solver simplifies the above to
+{b: Int | b >= 2n - 3}
+\end{code}
+
+\begin{code} Finally, to check the output guarantee is met, LiquidHaskell asks the SMT solver to prove that
+(b >= 2n - 2)  =>  (b >= n)
+\end{code}
+
+The SMT solver will refuse, of course, since the above implication is 
+*not valid* (e.g. when `n` is `2`) Thus, via SMT, LiquidHaskell proclaims
+that the function `fib'` does not implement the advertised type and hence
+marks it *unsafe*.
+
+Fixing The Code
+---------------
+
+How then, do we get Chris' specification to work out? It seems like it 
+*should* hold (except for that pesky case where `n=2`. Indeed,
+let's rig the code, so that all the base cases return `1`.
+
+\begin{code}
+{-@ fibOK :: n:Int -> {b:Int | ((b >= n) && (b >= 1))} @-}
+fibOK :: Int -> Int
+fibOK 0 = 1
+fibOK 1 = 1
+fibOK n = fibOK (n-1) + fibOK (n-2)
+\end{code}
+
+Here' we specify that not only is the output greater than the input, it is
+**also** greater than `1`. 
+
+\begin{code} Now in the recursive case, LiquidHaskell reasons that the value being output is
+{b: Int | exists b1, b2. b  == b1 + b2 
+                      && b1 >= n-1 && b1 >= 1 
+                      && b2 >= n-2 && b2 >= 1 }
+\end{code}
+
+\begin{code}which reduces to 
+{b: Int | b = 2n - 3 && n >= 2 }
+\end{code}
+
+\begin{code}which, the SMT solver is happy to verify, is indeed a subtype
+of (i.e. implies the refinement of) the specified output
+{b: Int | b >= n && b >= 1 } 
+\end{code}
+
+Conclusion
+----------
+
+There are several things to take away. 
+
+1. We need to distinguish between *assumptions* and *guarantees* 
+   when writing specifications for functions.
+
+2. For *modularity*, LiquidHaskell, like every type system, uses only
+   the (refinement) *type*  of each function at each use site, and not the 
+   function's *body*.
+
+3. Some seemingly intuitive specifications often aren't; in future work it
+   would be useful to actually [generate][mlton]  [tests][concolic] as 
+   [counterexamples][icse04] that illustrate when a specification
+   [fails][dsd].
+
+[qblog101]: /blog/2013/01/01/refinement-types-101.lhs/#comment-772807850
+[qreddit101]: http://www.reddit.com/r/haskell/comments/16w3hp/liquidhaskell_refinement_types_in_haskell_via_smt/c809160
+[ref101]:  /blog/2013/01/01/refinement-types-101.lhs/ 
+[concolic]: http://en.wikipedia.org/wiki/Concolic_testing
+[icse04]: http://goto.ucsd.edu/~rjhala/papers/generating_tests_from_counterexamples.html
+[dsd]: http://dl.acm.org/citation.cfm?doid=1348250.1348254
+[mlton]: http://www.cs.purdue.edu/homes/zhu103/pubs/vmcai13.pdf
+
diff --git a/docs/blog/2013-01-31-safely-catching-a-list-by-its-tail.lhs b/docs/blog/2013-01-31-safely-catching-a-list-by-its-tail.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-01-31-safely-catching-a-list-by-its-tail.lhs
@@ -0,0 +1,378 @@
+---
+layout: post
+title: "Safely Catching A List By Its Tail"
+date: 2013-01-31 16:12
+author: Ranjit Jhala
+published: true 
+comments: true
+external-url:
+categories: measures 
+demo: lenMapReduce.hs
+---
+
+[Previously][ref101] we [saw][ref102] some examples of how refinements
+could be used to encode invariants about basic `Int` values.  Today, let's
+see how refinements allow us specify and verify *structural invariants*
+about recursive data types like lists. In particular, we will
+learn about at a new mechanism called a `measure`, 
+use measures to describe the **length** of a list, and 
+use the resulting refinement types to obtain compile-time assurances
+that canonical list manipulating operations like `head`, `tail`, `foldl1`
+and (incomplete) pattern matches will not *blow up* at run-time.
+
+<!-- more -->
+
+\begin{code}
+module ListLengths where
+
+import Prelude hiding (length, map, filter, head, tail, foldl1)
+import Language.Haskell.Liquid.Prelude (liquidError)
+import qualified Data.HashMap.Strict as M
+import Data.Hashable 
+\end{code}
+
+Measuring the Length of a List
+------------------------------
+
+To begin, we need some instrument by which to measure the length of a list.
+To this end, let's introduce a new mechanism called **measures** which 
+define auxiliary (or so-called **ghost**) properties of data values.
+These properties are useful for specification and verification, but
+**don't actually exist at run-time**.
+That is, measures will appear in specifications but *never* inside code.
+
+
+
+
+\begin{code} Let's reuse this mechanism, this time, providing a [definition](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/GHC/Base.spec) for the measure
+measure len :: forall a. [a] -> GHC.Types.Int
+len ([])     = 0
+len (y:ys)   = 1 + (len ys) 
+\end{code}
+
+The description of `len` above should be quite easy to follow. Underneath the 
+covers, LiquidHaskell transforms the above description into refined versions 
+of the types for the constructors `(:)` and `[]`,
+\begin{code}Something like 
+data [a] where 
+  []  :: forall a. {v: [a] | (len v) = 0 }
+  (:) :: forall a. y:a -> ys:[a] -> {v: [a] | (len v) = 1 + (len ys) } 
+\end{code}
+
+To appreciate this, note that we can now check that
+
+\begin{code}
+{-@ xs :: {v:[String] | (len v) = 1 } @-}
+xs = "dog" : []
+
+{-@ ys :: {v:[String] | (len v) = 2 } @-}
+ys = ["cat", "dog"]
+
+{-@ zs :: {v:[String] | (len v) = 3 } @-}
+zs = "hippo" : ys
+\end{code}
+
+Dually, when we *de-construct* the lists, LiquidHaskell is able to relate
+the type of the outer list with its constituents. For example,
+
+\begin{code}
+{-@ zs' :: {v:[String] | (len v) = 2 } @-}
+zs' = case zs of 
+        h : t -> t
+\end{code}
+
+Here, from the use of the `:` in the pattern, LiquidHaskell can determine
+that `(len zs) = 1 + (len t)`; by combining this fact with the nugget
+that `(len zs) = 3` LiquidHaskell concludes that `t`, and hence, `zs'`
+contains two elements.
+
+Reasoning about Lengths
+-----------------------
+
+Let's flex our new vocabulary by uttering types that describe the
+behavior of the usual list functions. 
+
+First up: a version of the [standard][ghclist] 
+`length` function, slightly simplified for exposition.
+
+\begin{code}
+{-@ length :: xs:[a] -> {v: Int | v = (len xs)} @-}
+length :: [a] -> Int
+length []     = 0
+length (x:xs) = 1 + length xs
+\end{code}
+
+**Note:** Recall that `measure` values don't actually exist at run-time.
+However, functions like `length` are useful in that they allow us to
+effectively *pull* or *materialize* the ghost values from the refinement
+world into the actual code world (since the value returned by `length` is
+logically equal to the `len` of the input list.)
+
+Similarly, we can speak and have confirmed, the types for the usual
+list-manipulators like
+
+\begin{code}
+{-@ map      :: (a -> b) -> xs:[a] -> {v:[b] | (len v) = (len xs)} @-}
+map _ []     = [] 
+map f (x:xs) = (f x) : (map f xs)
+\end{code}
+
+and
+
+\begin{code}
+{-@ filter :: (a -> Bool) -> xs:[a] -> {v:[a] | (len v) <= (len xs)} @-}
+filter _ []     = []
+filter f (x:xs) 
+  | f x         = x : filter f xs
+  | otherwise   = filter f xs
+\end{code}
+
+and, since doubtless you are wondering,
+
+\begin{code}
+{-@ append :: xs:[a] -> ys:[a] -> {v:[a] | (len v) = (len xs) + (len ys)} @-}
+append [] ys     = ys 
+append (x:xs) ys = x : append xs ys
+\end{code}
+
+We will return to the above at some later date. Right now, let's look at
+some interesting programs that LiquidHaskell can prove safe, by reasoning
+about the size of various lists.
+
+
+
+Example 1: Safely Catching A List by Its Tail (or Head) 
+-------------------------------------------------------
+
+Now, let's see how we can use these new incantations to banish, forever,
+certain irritating kinds of errors. 
+\begin{code}Recall how we always summon functions like `head` and `tail` with a degree of trepidation, unsure whether the arguments are empty, which will awaken certain beasts
+Prelude> head []
+*** Exception: Prelude.head: empty list
+\end{code}
+
+LiquidHaskell allows us to use these functions with 
+confidence and surety! First off, let's define a predicate
+alias that describes non-empty lists:
+
+\begin{code}
+{-@ predicate NonNull X = ((len X) > 0) @-}
+\end{code}
+
+Now, we can type the potentially dangerous `head` as:
+
+\begin{code}
+{-@ head   :: {v:[a] | (NonNull v)} -> a @-}
+head (x:_) = x
+head []    = liquidError "Fear not! 'twill ne'er come to pass"
+\end{code}
+
+As with the case of [divide-by-zero][ref101], LiquidHaskell deduces that
+the second equation is *dead code* since the precondition (input) type
+states that the length of the input is strictly positive, which *precludes*
+the case where the parameter is `[]`.
+
+Similarly, we can write
+
+\begin{code}
+{-@ tail :: {v:[a] | (NonNull v)} -> [a] @-}
+tail (_:xs) = xs
+tail []     = liquidError "Relaxeth! this too shall ne'er be"
+\end{code}
+
+Once again, LiquidHaskell will use the precondition to verify that the 
+`liquidError` is never invoked. 
+
+Let's use the above to write a function that eliminates stuttering, that
+is which converts `"ssstringssss liiiiiike thisss"` to `"strings like this"`.
+
+\begin{code}
+{-@ eliminateStutter :: (Eq a) => [a] -> [a] @-}
+eliminateStutter xs = map head $ groupEq xs 
+\end{code}
+
+The heavy lifting is done by `groupEq`
+
+\begin{code}
+groupEq []     = []
+groupEq (x:xs) = (x:ys) : groupEq zs
+                 where (ys,zs) = span (x ==) xs
+\end{code}
+
+which gathers consecutive equal elements in the list into a single list.
+By using the fact that *each element* in the output returned by 
+`groupEq` is in fact of the form `x:ys`, LiquidHaskell infers that
+`groupEq` returns a *list of non-empty lists*. 
+(Hover over the `groupEq` identifier in the code above to see this.)
+Next, by automatically instantiating the type parameter for the `map` 
+in `eliminateStutter` to `(len v) > 0` LiquidHaskell deduces `head` 
+is only called on non-empty lists, thereby verifying the safety of 
+`eliminateStutter`. (Hover your mouse over `map` above to see the
+instantiated type for it!)
+
+Example 2: Risers 
+-----------------
+
+The above examples of `head` and `tail` are simple, but non-empty lists pop
+up in many places, and it is rather convenient to have the type system
+track non-emptiness without having to make up special types. Let's look at a
+more interesting example, popularized by [Neil Mitchell][risersMitchell]
+which is a key step in an efficient sorting procedure, which we may return
+to in the future when we discuss sorting algorithms.
+
+\begin{code}
+risers           :: (Ord a) => [a] -> [[a]]
+risers []        = []
+risers [x]       = [[x]]
+risers (x:y:etc) = if x <= y then (x:s):ss else [x]:(s:ss)
+    where 
+      (s, ss)    = safeSplit $ risers (y:etc)
+\end{code}
+
+The bit that should cause some worry is `safeSplit` which 
+simply returns the `head` and `tail` of its input, if they
+exist, and otherwise, crashes and burns
+
+\begin{code}
+safeSplit (x:xs)  = (x, xs)
+safeSplit _       = liquidError "don't worry, be happy"
+\end{code}
+
+How can we verify that `safeSplit` *will not crash* ?
+
+The matter is complicated by the fact that since `risers` 
+*does* sometimes return an empty list, we cannot blithely 
+specify that its output type has a `NonNull` refinement.
+
+Once again, logic rides to our rescue!
+
+The crucial property upon which the safety of `risers` rests
+is that when the input list is non-empty, the output list 
+returned by risers is *also* non-empty. It is quite easy to clue 
+LiquidHaskell in on this, namely through a type specification:
+
+\begin{code}
+{-@ risers :: (Ord a) 
+           => zs:[a] 
+           -> {v: [[a]] | ((NonNull zs) => (NonNull v)) } @-} 
+\end{code}
+
+Note how we relate the output's non-emptiness to the input's
+non-emptiness,through the (dependent) refinement type. With this 
+specification in place, LiquidHaskell is pleased to verify `risers` 
+(i.e. the call to `safeSplit`).
+
+Example 3: MapReduce 
+--------------------
+
+Here's a longer example that illustrates this: a toy *map-reduce* implementation.
+
+First, let's write a function `keyMap` that expands a list of inputs into a 
+list of key-value pairs:
+
+\begin{code}
+keyMap :: (a -> [(k, v)]) -> [a] -> [(k, v)]
+keyMap f xs = concatMap f xs
+\end{code}
+
+Next, let's write a function `group` that gathers the key-value pairs into a
+`Map` from *keys* to the lists of values with that same key.
+
+\begin{code}
+group kvs = foldr (\(k, v) m -> inserts k v m) M.empty kvs 
+\end{code}
+
+The function `inserts` simply adds the new value `v` to the list of 
+previously known values `lookupDefault [] k m` for the key `k`.
+
+\begin{code}
+inserts k v m = M.insert k (v : vs) m 
+  where vs    = M.lookupDefault [] k m
+\end{code}
+
+Finally, a function that *reduces* the list of values for a given
+key in the table to a single value:
+
+\begin{code}
+reduce    :: (v -> v -> v) -> M.HashMap k [v] -> M.HashMap k v
+reduce op = M.map (foldl1 op)
+\end{code}
+
+where `foldl1` is a [left-fold over *non-empty* lists][foldl1]
+
+\begin{code}
+{-@ foldl1      :: (a -> a -> a) -> {v:[a] | (NonNull v)} -> a @-}
+foldl1 f (x:xs) =  foldl f x xs
+foldl1 _ []     =  liquidError "will. never. happen."
+\end{code}
+
+We can put the whole thing together to write a (*very*) simple *Map-Reduce* library
+
+\begin{code}
+mapReduce   :: (Eq k, Hashable k) 
+            => (a -> [(k, v)])    -- ^ key-mapper
+            -> (v -> v -> v)      -- ^ reduction operator
+            -> [a]                -- ^ inputs
+            -> [(k, v)]           -- ^ output key-values
+
+mapReduce f op  = M.toList 
+                . reduce op 
+                . group 
+                . keyMap f
+\end{code}
+
+Now, if we want to compute the frequency of `Char` in a given list of words, we can write:
+
+\begin{code}
+{-@ charFrequency :: [String] -> [(Char, Int)] @-}
+charFrequency     :: [String] -> [(Char, Int)]
+charFrequency     = mapReduce wordChars (+)
+  where wordChars = map (\c -> (c, 1)) 
+\end{code}
+
+You can take it out for a spin like so:
+
+\begin{code}
+f0 = charFrequency [ "the", "quick" , "brown"
+                   , "fox", "jumped", "over"
+                   , "the", "lazy"  , "cow"   ]
+\end{code}
+
+**Look Ma! No Types:** LiquidHaskell will gobble the whole thing up, and
+verify that none of the undesirable `liquidError` calls are triggered. By
+the way, notice that we didn't write down any types for `mapReduce` and
+friends.  The main invariant, from which safety follows is that the `Map`
+returned by the `group` function binds each key to a *non-empty* list of
+values.  LiquidHaskell deduces this invariant by inferring suitable types
+for `group`, `inserts`, `foldl1` and `reduce`, thereby relieving us of that
+tedium. In short, by riding on the broad and high shoulders of SMT and
+abstract interpretation, LiquidHaskell makes a little typing go a long way. 
+
+
+Conclusions
+-----------
+
+Well folks, thats all for now. I trust this article gave you a sense of
+
+1. How we can describe certain *structural properties* of data types, 
+   such as the length of a list, 
+
+2. How we might use refinements over these properties to describe key
+   invariants and establish, at compile-time, the safety of operations that
+   might blow up on unexpected values at run-time, and perhaps, most
+   importantly,
+
+3. How we can achieve the above, whilst just working with good old lists, 
+   without having to [make up new types][risersApple] (which have the 
+   unfortunate effect of cluttering programs with their attendant new 
+   functions) in order to enforce special invariants.
+
+
+[vecbounds]:  /blog/2013/01/05/bounding-vectors.lhs/ 
+[ghclist]:    https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/GHC/List.lhs#L125
+[foldl1]:     http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#foldl1
+[risersMitchell]: http://neilmitchell.blogspot.com/2008/03/sorting-at-speed.html
+[risersApple]: http://blog.jbapple.com/2008/01/extra-type-safety-using-polymorphic.html
+[ref101]:  /blog/2013/01/01/refinement-types-101.lhs/ 
+[ref102]:  /blog/2013/01/27/refinements101-reax.lhs/ 
+
diff --git a/docs/blog/2013-02-16-kmeans-clustering-I.lhs b/docs/blog/2013-02-16-kmeans-clustering-I.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-02-16-kmeans-clustering-I.lhs
@@ -0,0 +1,335 @@
+---
+layout: post
+title: "KMeans Clustering I"
+date: 2013-02-16 16:12
+author: Ranjit Jhala
+published: true
+comments: true
+external-url:
+categories: basic measures
+demo: KMeansHelper.hs
+---
+
+[Last time][safeList] we introduced a new specification mechanism called a
+*measure* and demonstrated how to use it to encode the *length* of a list.
+We saw how measures could be used to verify that functions like `head` and
+`tail` were only called with non-empty lists (whose length was strictly
+positive). As several folks pointed out, once LiquidHaskell can reason about
+lengths, it can do a lot more than just analyze non-emptiness.
+
+Indeed!
+
+Over the next *two* posts, lets see how one might implement a Kmeans
+algorithm that clusters `n`-dimensional points groups, and how LiquidHaskell
+can help us write and enforce various dimensionality invariants along the way.
+
+<!-- more -->
+
+<!-- For example, XXX pointed out that we can use the type system to give an *upper* bound on the size of a list, e.g. using lists
+     upper bounded by a gigantic `MAX_INT` value as a proxy for finite lists. -->
+
+
+\begin{code}
+module KMeansHelper where
+
+import Prelude                          hiding  (zipWith)
+import Data.List                                (span)
+import Language.Haskell.Liquid.Prelude          (liquidError)
+\end{code}
+
+Rather than reinvent the wheel, we will modify an existing implementation
+of K-Means, [available on hackage][URL-kmeans]. This may not be the
+most efficient implementation, but its a nice introduction to the algorithm,
+and the general invariants will hold for more sophisticated implementations.
+
+We have broken this entry into two convenient, bite-sized chunks:
+
++ **Part I**  Introduces the basic types and list operations needed by KMeans,
+
++ **Part II** Describes how the operations are used in the KMeans implementation.
+
+The Game: Clustering Points
+---------------------------
+
+The goal of [K-Means clustering](http://en.wikipedia.org/wiki/K-means_clustering)
+is the following. Given
+
+- **Input** : A set of *points* represented by *n-dimensional points*
+  in *Euclidian* space, return
+
+- **Output** : A partitioning of the points, into K clusters, in a manner that
+  minimizes sum of distances between each point and its cluster center.
+
+
+The Players: Types
+------------------
+
+Lets make matters concrete by creating types for the different elements of the algorithm.
+
+**1. Fixed-Length Lists**  We will represent n-dimensional points using
+good old Haskell lists, refined with a predicate that describes the
+dimensionality (i.e. length.) To simplify matters, lets package this
+into a *type alias* that denotes lists of a given length `N`.
+
+\begin{code}
+{-@ type List a N = {v : [a] | (len v) = N} @-}
+\end{code}
+
+**2. Points** Next, we can represent an `N`-dimensional point as list of `Double` of length `N`,
+
+\begin{code}
+{-@ type Point N = List Double N @-}
+\end{code}
+
+**3. Clusters** A cluster is a **non-empty** list of points,
+
+\begin{code}
+{-@ type NonEmptyList a = {v : [a] | (len v) > 0} @-}
+\end{code}
+
+**4. Clustering** And finally, a clustering is a list of (non-empty) clusters.
+
+\begin{code}
+{-@ type Clustering a  = [(NonEmptyList a)] @-}
+\end{code}
+
+**Notation:** When defining refinement type aliases, we use uppercase variables like `N`
+to distinguish value- parameters from the lowercase type parameters like `a`.
+
+
+**Aside:** By the way, if you are familiar with the *index-style* length
+encoding e.g. as found in [DML][dml] or [Agda][agdavec], then its worth
+noting that despite appearances, our `List` and `Point` definitions are
+*not* indexed. We're just using the indices to define abbreviations for the
+refinement predicates, and we have deliberately chosen the predicates to
+facilitate SMT based checking and inference.
+
+Basic Operations on Points and Clusters
+=======================================
+
+Ok, with the types firmly in hand, let us go forth and develop the KMeans
+clustering implementation. We will use a variety of small helper functions
+(of the kind found in `Data.List`.) Lets get started by looking at them
+through our newly *refined* eyes.
+
+Grouping
+--------
+
+The first such function is [groupBy][URL-groupBy]. We can
+refine its type so that instead of just producing a `[[a]]`
+we know that it produces a `Clustering a` which is a list
+of *non-empty* lists.
+
+\begin{code}
+{-@ groupBy       ::(a -> a -> Bool) -> [a] -> (Clustering a) @-}
+groupBy _  []     = []
+groupBy eq (x:xs) = (x:ys) : groupBy eq zs
+  where (ys,zs)   = span (eq x) xs
+\end{code}
+
+Intuitively, its pretty easy to see how LiquidHaskell verifies the refined
+specification:
+
+- Each element of the output list is of the form `x:ys`
+- For any list `ys` the length is non-negative, i.e. `(len ys) >= 0`
+- The `len` of `x:ys` is `1 + (len ys)`, that is, strictly positive.
+
+Partitioning
+------------
+
+Next, lets look the function
+
+\begin{code}
+{-@ partition :: size:PosInt -> [a] -> (Clustering a) @-}
+{-@ type PosInt = {v: Int | v > 0 } @-}
+\end{code}
+
+which is given a *strictly positive* integer argument,
+a list of `a` values, and returns a `Clustering a`,
+that is, a list of non-empty lists. (Each inner list has a length
+that is less than `size`, but we shall elide this for simplicity.)
+
+The function is implemented in a straightforward manner, using the
+library functions `take` and `drop`
+
+\begin{code}
+partition size []       = []
+partition size ys@(_:_) = zs : partition size zs'
+  where
+    zs                  = take size ys
+    zs'                 = drop size ys
+\end{code}
+
+To verify that a valid `Clustering` is produced, LiquidHaskell needs only
+verify that the list `zs` above is non-empty, by suitably connecting the
+properties of the inputs `size` and `ys` with the output.
+
+\begin{code} We have [verified elsewhere][URL-take] that
+take :: n:{v: Int | v >= 0 }
+     -> xs:[a]
+     -> {v:[a] | (len v) = (if ((len xs) < n) then (len xs) else n) }
+\end{code}
+
+In other words, the output list's length is the *smaller of* the input
+list's length and `n`.  Thus, since both `size` and the `(len ys)` are
+greater than `1`, LiquidHaskell deduces that the list returned by `take
+size ys` has a length greater than `1`, i.e., is non-empty.
+
+Zipping
+-------
+
+To compute the *Euclidean distance* between two points, we will use
+the `zipWith` function. We must make sure that it is invoked on points
+with the same number of dimensions, so we write
+
+\begin{code}
+{-@ zipWith :: (a -> b -> c)
+            -> xs:[a] -> (List b (len xs)) -> (List c (len xs)) @-}
+zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
+zipWith _ [] []         = []
+\end{code}
+
+The type stipulates that the second input list and the output have
+the same length as the first input. Furthermore, it rules out the
+case where one list is empty and the other is not, as in that case
+the former's length is zero while the latter's is not.
+
+Transposing
+-----------
+
+The last basic operation that we will require is a means to
+*transpose* a `Matrix`, which itself is just a list of lists:
+
+\begin{code}
+{-@ type Matrix a Rows Cols = (List (List a Cols) Rows) @-}
+\end{code}
+
+The `transpose` operation flips the rows and columns. I confess that I
+can never really understand matrices without concrete examples,
+and even then, barely.
+
+\begin{code} So, lets say we have a *matrix*
+m1  :: Matrix Int 4 2
+m1  =  [ [1, 2]
+       , [3, 4]
+       , [5, 6]
+       , [7, 8] ]
+\end{code}
+
+\begin{code} then the matrix `m2 = transpose 2 3 m1` should be
+m2 :: Matrix Int 2 4
+m2  =  [ [1, 3, 5, 7]
+       , [2, 4, 6, 8] ]
+\end{code}
+
+We will use a `Matrix a m n` to represent a *single cluster* of `m` points
+each of which has `n` dimensions. We will transpose the matrix to make it
+easy to *sum* and *average* the points along *each* dimension, in order to
+compute the *center* of the cluster.
+
+As you can work out from the above, the code for `transpose` is quite
+straightforward: each *output row* is simply the list of `head`s of
+the *input rows*:
+
+\begin{code}
+transpose       :: Int -> Int -> [[a]] -> [[a]]
+
+transpose 0 _ _ = []
+
+transpose c r ((col00 : col01s) : row1s)
+  = row0' : row1s'
+    where
+      row0'  = col00  : [ col0  | (col0 : _)  <- row1s ]
+      rest   = col01s : [ col1s | (_ : col1s) <- row1s ]
+      row1s' = transpose (c-1) r rest
+\end{code}
+
+LiquidHaskell verifies that
+
+\begin{code}
+{-@ transpose :: c:Int -> r:PosInt -> Matrix a r c -> Matrix a c r @-}
+\end{code}
+
+Try to work it out for yourself on pencil and paper.
+
+If you like you can get a hint by seeing how LiquidHaskell figures it out.
+Lets work *backwards*.
+
+\begin{code} LiquidHaskell verifies the output type by inferring that
+row0'        :: (List a r)
+row1s'       :: List (List a r) (c - 1) -- i.e. Matrix a (c - 1) r
+\end{code}
+
+\begin{code} and so, by simply using the *measure-refined* type for `:`
+(:)          :: x:a -> xs:[a] -> { v : [a] | (len v) = 1 + (len xs) }
+\end{code}
+
+\begin{code} LiquidHaskell deduces that
+row0 : rows' :: List (List a r) c
+\end{code}
+
+\begin{code} That is,
+row0 : rows' :: Matrix a c r
+\end{code}
+
+Excellent! Now, lets work backwards. How does it infer the types of `row0'` and `row1s'`?
+
+The first case is easy: `row0'` is just the list of *heads* of each row, hence a `List a r`.
+
+\begin{code} Now, lets look at `row1s'`. Notice that `row1s` is the matrix of all *except* the first row of the input Matrix, and so
+row1s        :: Matrix a (r-1) c
+\end{code}
+
+\begin{code} and so, as
+col01s       :: List a (c-1)
+col1s        :: List a (c-1)
+\end{code}
+
+\begin{code} LiquidHaskell deduces that since `rest` is the concatenation of `r-1` tails from `row1s`
+rest         = col01s : [ col1s | (_ : col1s) <- row1s ]
+\end{code}
+
+\begin{code} the type of `rest` is
+rest         :: List (List a (c - 1)) r
+\end{code}
+
+\begin{code} which is just
+rest         :: Matrix a r (c-1)
+\end{code}
+
+Now, LiquidHaskell deduces `row1s' :: Matrix a (c-1) r` by inductively
+plugging in the output type of the recursive call, thereby checking the
+function's signature.
+
+
+*Whew!* That was a fair bit of work, wasn't it!
+
+Happily, we didn't have to do *any* of it. Instead, using the SMT solver,
+LiquidHaskell ploughs through calculations like that and guarantees to us
+that `transpose` indeed flips the dimensions of the inner and outer lists.
+
+**Aside: Comprehensions vs. Map** Incidentally, the code above is essentially
+that of `transpose` [from the Prelude][URL-transpose] with some extra
+local variables for exposition. You could instead use a `map head` and `map tail`
+and I encourage you to go ahead and [see for yourself.][demo]
+
+Intermission
+------------
+
+Time for a break -- [go see a cat video!][maru] -- or skip it, stretch your
+legs, and return post-haste for the [next installment][kmeansII], in which
+we will use the types and functions described above, to develop the clustering
+algorithm.
+
+[safeList]:      /blog/2013/01/31/safely-catching-a-list-by-its-tail.lhs/
+[kmeansI]:       /blog/2013/02/16/kmeans-clustering-I.lhs/
+[kmeansII]:      /blog/2013/02/17/kmeans-clustering-II.lhs/
+[URL-take]:      https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/GHC/List.lhs#L334
+[URL-groupBy]:   http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:groupBy
+[URL-transpose]: http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#transpose
+[maru]:          http://www.youtube.com/watch?v=8uDuls5TyNE
+[demo]:          http://goto.ucsd.edu/~rjhala/liquid/haskell/demo/#?demo=KMeansHelper.hs
+[URL-kmeans]:    http://hackage.haskell.org/package/kmeans
+[dml]:           http://www.cs.bu.edu/~hwxi/DML/DML.html
+[agdavec]:       http://code.haskell.org/Agda/examples/Vec.agda
+
diff --git a/docs/blog/2013-02-17-kmeans-clustering-II.lhs b/docs/blog/2013-02-17-kmeans-clustering-II.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-02-17-kmeans-clustering-II.lhs
@@ -0,0 +1,436 @@
+---
+layout: post
+title: "KMeans Clustering II"
+date: 2013-02-17 16:12
+author: Ranjit Jhala
+published: true
+comments: true
+external-url:
+categories: basic measures
+demo: KMeans.hs
+---
+
+**The story so far:** [Previously][kmeansI] we saw
+
+- how to encode `n`-dimensional points using plain old Haskell lists,
+- how to encode a matrix with `r` rows and `c` columns as a list of lists,
+- some basic operations on points and matrices via list-manipulating functions
+
+More importantly, we saw how easy it was to encode dimensionality with refinements over
+the `len` measure, thereby allowing LiquidHaskell to precisely track the dimensions across
+the various operations.
+
+Next, lets use the basic types and operations to develop the actual *KMeans clustering*
+algorithm, and, along the way, see how LiquidHaskell lets us write precise module
+contracts which will ward against various unpleasant *lumpenexceptions*.
+
+<!-- more -->
+
+\begin{code}
+{-# LANGUAGE ScopedTypeVariables, TypeSynonymInstances, FlexibleInstances #-}
+
+module KMeans (kmeans, kmeansGen) where
+
+import KMeansHelper
+import Prelude              hiding      (zipWith)
+import Data.List                        (sort, span, minimumBy)
+import Data.Function                    (on)
+import Data.Ord                         (comparing)
+import Language.Haskell.Liquid.Prelude  (liquidAssert, liquidError)
+
+instance Eq (WrapType [Double] a) where
+   (==) = (==) `on` getVect
+
+instance Ord (WrapType [Double] a) where
+    compare = comparing getVect
+\end{code}
+
+Recall that we are using a modified version of an [existing KMeans implementation][URL-kmeans].
+While not the swiftest implementation, it serves as a nice introduction to the algorithm,
+and the general invariants carry over to more sophisticated implementations.
+
+A Quick Recap
+-------------
+
+Before embarking on the journey, lets remind ourselves of our destination:
+the goal of [K-Means clustering](http://en.wikipedia.org/wiki/K-means_clustering) is
+
+- **Take as Input** : A set of *points* represented by *n-dimensional points* in *Euclidian* space
+
+- **Return as Ouptut** : A partitioning of the points, into upto K clusters, in a manner that
+  minimizes the sum of distances between each point and its cluster center.
+
+Last time, we introduced a variety of refinement type aliases for Haskell lists
+
+\begin{code} **Fixed Length Lists**
+type List a N = {v : [a] | (len v) = N}
+\end{code}
+
+\begin{code} **Non-empty Lists**
+type NonEmptyList a = {v : [a] | (len v) > 0}
+\end{code}
+
+\begin{code} **N-Dimensional Points**
+type Point N = List Double N
+\end{code}
+
+\begin{code} **Matrices**
+type Matrix a Rows Cols = List (List a Cols) Rows
+\end{code}
+
+\begin{code} We also saw several basic list operations
+groupBy   :: (a -> a -> Bool) -> [a] -> (Clustering a)
+partition :: PosInt -> [a] -> (Clustering a)
+zipWith   :: (a -> b -> c) -> xs:[a] -> (List b (len xs)) -> (List c (len xs))
+transpose :: c:Int -> r:PosInt -> Matrix a r c -> Matrix a c r
+\end{code}
+
+whose types will prove essential in order to verify the invariants of the
+clustering algorithm. You might open the [previous episode][kmeansI] in a
+separate tab to keep those functions handy, but fear not, we will refresh
+our memory about them when we get around to using them below.
+
+Generalized Points
+------------------
+
+To be more flexible, we will support *arbitrary* points as long as they can
+be **projected** to Euclidian space. In addition to supporting, say, an
+image or a [cat video][maru] as a point, this will allow us to *weight*
+different dimensions to different degrees.
+
+We represent generalized points with a record
+
+\begin{code}
+data WrapType b a = WrapType {getVect :: b, getVal :: a}
+\end{code}
+
+and we can define an alias that captures the dimensionality of the point
+
+\begin{code}
+{-@ type GenPoint a N  = WrapType (Point N) a @-}
+\end{code}
+
+That is, `GenPoint a N` denotes a general `a` value that has an
+`N`-dimensional projection into Euclidean space.
+
+Algorithm: Iterative Clustering
+-------------------------------
+
+Terrific, now that all the pieces are in place lets look at the KMeans
+algorithm. We have implemented a function `kmeans'`, which takes as input a
+dimension `n`, the maximum number of clusters `k` (which must be positive),
+a list of *generalized points* of dimension `n`, and returns a `Clustering`
+(i.e. a list of *non-empty lists*) of the generalized points.
+
+So much verbiage -- a type is worth a thousand comments!
+
+\begin{code}
+{-@ kmeans' :: n:Int
+            -> k:PosInt
+            -> points:[(GenPoint a n)]
+            -> (Clustering (GenPoint a n)) @-}
+\end{code}
+
+There! Crisp and to the point. Sorry. Anyhoo, the function implements the
+above type.
+
+\begin{code}
+kmeans' n k points    = fixpoint (refineCluster n) initialClustering
+  where
+    initialClustering = partition clusterSize points
+    clusterSize       = max 1 ((length points + k - 1) `div` k)
+
+    fixpoint          :: (Eq a) => (a -> a) -> a -> a
+    fixpoint f x      = if (f x) == x then x else fixpoint f (f x)
+\end{code}
+
+That is, `kmeans'` creates an `initialClustering` by
+`partition`-ing the `points` into chunks with `clusterSize` elements.
+Then, it invokes `fixpoint` to *iteratively refine* the initial
+clustering  with `refineCluster` until it converges to a stable
+clustering that cannot be improved upon. This stable clustering
+is returned as the output.
+
+LiquidHaskell verifies that `kmeans'` adheres to the given signature in two steps.
+
+**1. Initial Clustering**
+
+\begin{code} First, LiquidHaskell determines from
+max       :: (Ord a) => x:a -> y:a -> {v: a | (v >= x) && ( v >= y) }
+\end{code}
+
+\begin{code} that `clusterSize` is strictly positive, and hence, from
+partition :: size:PosInt -> [a] -> (Clustering a)
+\end{code}
+
+which we saw [last time][kmeansI], that `initialClustering` is indeed
+a valid `Clustering` of `(GenPoint a n)`.
+
+**2. Fixpoint**
+
+Next, LiquidHaskell infers that at the call `fixpoint (refineCluster n)
+...`, that the type parameter `a` of `fixpoint` can be *instantiated* with
+`Clustering (GenPoint a n)`.  This is because `initialClustering` is a
+valid clustering, as we saw above, and because `refineCluster` takes -- and
+returns -- valid `n`-dimensional clusterings, as we shall see below.
+Consequently, the value returned by `kmeans'` is also `Clustering` of
+`GenPoint a n` as required.
+
+Refining A Clustering
+---------------------
+
+Thus, the real work in KMeans happens inside `refineCluster`, which takes a
+clustering and improves it, like so:
+
+\begin{code}
+refineCluster n clusters = clusters'
+  where
+    -- 1. Compute cluster centers
+    centers        = map (clusterCenter n) clusters
+
+    -- 2. Map points to their nearest center
+    points         = concat clusters
+    centeredPoints = sort [(nearestCenter n p centers, p) | p <- points]
+
+    -- 3. Group points by nearest center to get new clusters
+    centeredGroups = groupBy ((==) `on` fst) centeredPoints
+    clusters'      = map (map snd) centeredGroups
+\end{code}
+
+The behavior of `refineCluster` is pithily captured by its type
+
+\begin{code}
+{-@ refineCluster :: n:Int
+                  -> Clustering (GenPoint a n)
+                  -> Clustering (GenPoint a n) @-}
+\end{code}
+
+The refined clustering is computed in three steps.
+
+1. First, we compute the `centers :: [(Point n)]` of the current `clusters`.
+   This is achieved by using `clusterCenter`, which maps a list of generalized
+   `n`-dimensional points to a *single* `n` dimensional point (i.e. `Point n`).
+
+2. Next, we pair each point `p` in the list of all `points` with its `nearestCenter`.
+
+3. Finally, the pairs in the list of `centeredPoints` are grouped by the
+   center, i.e. the first element of the tuple. The resulting groups are
+   projected back to the original generalized points yielding the new
+   clustering.
+
+\begin{code} The type of the output follows directly from
+groupBy :: (a -> a -> Bool) -> [a] -> (Clustering a)
+\end{code}
+
+from [last time][kmeansI]. At the call site above, LiquidHaskell infers that
+`a` can be instantiated with `((Point n), (GenPoint a n))` thereby establishing
+that, after *projecting away* the first element, the output is a list of
+non-empty lists of generalized `n`-dimensional points.
+
+That leaves us with the two crucial bits of the algorithm: `clusterCenter`
+and `nearestCenter`.
+
+Computing the Center of a Cluster
+---------------------------------
+
+The center of an `n`-dimensional cluster is simply an `n`-dimensional point
+whose value in each dimension is equal to the *average* value of that
+dimension across all the points in the cluster.
+
+\begin{code} For example, consider a cluster of 2-dimensional points,
+exampleCluster = [ [0,  0]
+                 , [1, 10]
+                 , [2, 20]
+                 , [4, 40]
+                 , [5, 50] ]
+\end{code}
+
+\begin{code} The center of the cluster is
+exampleCenter = [ (0 + 1  + 2  + 4  + 5 ) / 5
+                , (0 + 10 + 20 + 40 + 50) / 5 ]
+\end{code}
+
+\begin{code} which is just
+exampleCenter = [ 3, 30 ]
+\end{code}
+
+Thus, we can compute a `clusterCenter` via the following procedure
+
+\begin{code}
+clusterCenter n xs = map average xs'
+  where
+    numPoints      = length xs
+    xs'            = transpose n numPoints (map getVect xs)
+
+    average        :: [Double] -> Double
+    average        = (`safeDiv` numPoints) . sum
+\end{code}
+
+First, we `transpose` the matrix of points in the cluster.
+Suppose that `xs` is the `exampleCluster` from above
+(and so `n` is `2` and `numPoints` is `5`.)
+
+\begin{code} In this scenario, `xs'` is
+xs' = [ [0,  1,  2,  4,  5]
+      , [0, 10, 20, 40, 50] ]
+\end{code}
+
+and so `map average xs'` evaluates to `exampleCenter` from above.
+
+We have ensured that the division in the average does not lead to
+any nasty surprises via a *safe division* function whose precondition
+checks that the denominator is non-zero, [as illustrated here][ref101].
+
+\begin{code}
+{- safeDiv   :: (Fractional a) => a -> {v:Int | v != 0} -> a -}
+safeDiv     :: (Fractional a) => a -> Int -> a
+safeDiv n 0 = liquidError "divide by zero"
+safeDiv n d = n / (fromIntegral d)
+\end{code}
+
+LiquidHaskell verifies that the divide-by-zero never occurs, and furthermore,
+that `clusterCenter` indeed computes an `n`-dimensional center by inferring that
+
+\begin{code}
+{-@ clusterCenter :: n:Int -> NonEmptyList (GenPoint a n) -> Point n @-}
+\end{code}
+
+LiquidHaskell deduces that the *input* list of points `xs` is non-empty
+from the fact that `clusterCenter` is only invoked on the elements of a
+`Clustering` which comprise only non-empty lists. Since `xs` is non-empty,
+i.e. `(len xs) > 0`, LiquidHaskell infers that `numPoints` is positive
+(hover over `length` to understand why), and hence, LiquidHaskell is
+satisfied that the call to `safeDiv` will always proceed without any
+incident.
+
+\begin{code} To establish the *output* type `Point n` LiquidHaskell leans on the fact that
+transpose :: n:Int -> m:PosInt -> Matrix a m n -> Matrix a n m
+\end{code}
+
+to deduce that `xs'` is of type `Matrix Double n numPoints`, that is to
+say, a list of length `n` containing lists of length `numPoints`. Since
+`map` preserves the length, the value `map average xs'` is also a list
+of length `n`, i.e. `Point n`.
+
+
+Finding the Nearest Center
+--------------------------
+
+The last piece of the puzzle is `nearestCenter` which maps each
+(generalized) point to the center that it is nearest. The code is
+pretty self-explanatory:
+
+\begin{code}
+nearestCenter     :: Int -> WrapType [Double] a -> [[Double]] -> [Double]
+nearestCenter n x = minKey . map (\c -> (c, distance c (getVect x)))
+\end{code}
+
+We `map` the centers to a tuple of center `c` and the `distance` between
+`x` and `c`, and then we select the tuple with the smallest distance
+
+\begin{code}
+minKey  :: (Ord v) => [(k, v)] -> k
+minKey  = fst . minimumBy (\x y -> compare (snd x) (snd y))
+\end{code}
+
+The interesting bit is that the `distance` function uses `zipWith` to
+ensure that the dimensionality of the center and the point match up.
+
+\begin{code}
+distance     :: [Double] -> [Double] -> Double
+distance a b = sqrt . sum $ zipWith (\v1 v2 -> (v1 - v2) ^ 2) a b
+\end{code}
+
+LiquidHaskell verifies `distance` by inferring that
+
+\begin{code}
+{-@ nearestCenter :: n:Int -> (GenPoint a n) -> [(Point n)] -> (Point n) @-}
+\end{code}
+
+First, LiquidHaskell deduces that each center in `cs` is indeed `n`-dimensional, which
+follows from the output type of `clusterCenter`. Since `x` is a `(GenPoint a n)`
+LiquidHaskell infers that both `c` and `getVect x` are of an equal length `n`.
+
+\begin{code} Consequently, the call to
+zipWith :: (a -> b -> c) -> xs:[a] -> (List b (len xs)) -> (List c (len xs))
+\end{code}
+
+[discussed last time][kmeansI] is determined to be safe.
+
+Finally, the value returned is just one of the input centers and so is a `(Point n)`.
+
+
+Putting It All Together: Top-Level API
+--------------------------------------
+
+We can bundle the algorithm into two top-level API functions.
+
+First, a version that clusters *generalized* points. In this case, we
+require a function that can `project` an `a` value to an `n`-dimensional
+point. This function just wraps each `a`, clusters via `kmeans'` and then
+unwraps the points.
+
+\begin{code}
+{-@ kmeansGen :: n:Int
+              -> (a -> (Point n))
+              -> k:PosInt
+              -> xs:[a]
+              -> (Clustering a)
+  @-}
+
+kmeansGen n project k = map (map getVal)
+                      . kmeans' n k
+                      . map (\x -> WrapType (project x) x)
+\end{code}
+
+Second, a specialized version that operates directly on `n`-dimensional
+points. The specialized version just calls the general version with a
+trivial `id` projection.
+
+\begin{code}
+{-@ kmeans :: n:Int
+           -> k:PosInt
+           -> points:[(Point n)]
+           -> (Clustering (Point n))
+  @-}
+
+kmeans n   = kmeansGen n id
+\end{code}
+
+Conclusions
+-----------
+
+I hope that over the last two posts you have gotten a sense of
+
+1. What KMeans clustering is all about,
+
+2. How measures and refinements can be used to describe the behavior
+   of common list operations like `map`, `transpose`, `groupBy`, `zipWith`, and so on,
+
+3. How LiquidHaskell's automated inference makes it easy to write and
+   verify invariants of non-trivial programs.
+
+The sharp reader will have noticed that the one *major*, non syntactic, change to the
+[original code][URL-kmeans] is the addition of the dimension parameter `n` throughout
+the code. This is critically required so that we can specify the relevant
+invariants (which are in terms of `n`.) The value is actually a ghost, and
+never ever used. Fortunately, Haskell's laziness means that we don't have
+to worry about it (or other ghost variables) imposing any run-time overhead
+at all.
+
+**Exercise:** Incidentally, if you have followed thus far I would
+encourage you to ponder about how you might modify the types (and
+implementation) to verify that KMeans indeed produces at most `k` clusters...
+
+[ref101]:        /blog/2013/01/01/refinement-types-101.lhs/
+[safeList]:      /blog/2013/01/31/safely-catching-a-list-by-its-tail.lhs/
+[kmeansI]:       /blog/2013/02/16/kmeans-clustering-I.lhs/
+[kmeansII]:      /blog/2013/02/17/kmeans-clustering-II.lhs/
+[URL-take]:      https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/GHC/List.lhs#L334
+[URL-groupBy]:   http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:groupBy
+[URL-transpose]: http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#transpose
+[maru]:          http://www.youtube.com/watch?v=8uDuls5TyNE
+[demo]:          http://goto.ucsd.edu/~rjhala/liquid/haskell/demo/#?demo=KMeansHelper.hs
+[URL-kmeans]:    http://hackage.haskell.org/package/kmeans
+
+
diff --git a/docs/blog/2013-03-04-bounding-vectors.lhs b/docs/blog/2013-03-04-bounding-vectors.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-03-04-bounding-vectors.lhs
@@ -0,0 +1,428 @@
+---
+layout: post
+title: "Bounding Vectors"
+date: 2013-03-04 16:12
+author: Ranjit Jhala
+published: true 
+comments: true
+external-url:
+categories: basic
+demo: vectorbounds.hs
+---
+
+Today, lets look at a classic use-case for refinement types, namely, 
+the static verification of **vector access bounds**. Along the way, 
+we'll see some examples that illustrate how LiquidHaskell reasons 
+about *recursion*, *higher-order functions*, *data types*, and 
+*polymorphism*.
+
+<!-- more -->
+
+\begin{code}
+module VectorBounds (
+    safeLookup 
+  , unsafeLookup, unsafeLookup'
+  , absoluteSum, absoluteSum'
+  , dotProduct
+  , sparseProduct, sparseProduct'
+  ) where
+
+import Prelude      hiding (length)
+import Data.List    (foldl')
+import Data.Vector  hiding (foldl') 
+\end{code}
+
+Specifying Bounds for Vectors
+-----------------------------
+
+One [classical][dmlarray] use-case for refinement types is to verify
+the safety of accesses of arrays and vectors and such, by proving that
+the indices used in such accesses are *within* the vector bounds. 
+Lets see how to do this with LiquidHaskell by writing a few short
+functions that manipulate vectors, in particular, those from the 
+popular [vector][vec] library. 
+
+First things first. Lets **specify** bounds safety by *refining* 
+the types for the [key functions][vecspec] exported by the module 
+`Data.Vector`. 
+
+\begin{code}Specifications for `Data.Vector`
+module spec Data.Vector where
+
+import GHC.Base
+
+measure vlen  ::   (Vector a) -> Int 
+assume length :: x:(Vector a) -> {v:Int | v = (vlen x)}
+assume !      :: x:(Vector a) -> {v:Int | 0 <= v && v < (vlen x)} -> a 
+\end{code}
+
+In particular, we 
+
+- **define** a *property* called `vlen` which denotes the size of the vector,
+- **assume** that the `length` function *returns* an integer equal to the vector's size, and
+- **assume** that the lookup function `!` *requires* an index between `0` and the vector's size.
+
+There are several things worth paying close attention to in the above snippet.
+
+**Measures**
+
+[Recall][listtail] that measures define auxiliary (or so-called **ghost**)
+properties of data values that are useful for specification and verification, 
+but which *don't actually exist at run-time*. Thus, they will 
+*only appear in specifications*, i.e. inside type refinements, but *never* 
+inside code. Often we will use helper functions like `length` in this case, 
+which *pull* or *materialize* the ghost values from the refinement world 
+into the actual code world.
+
+**Assumes**
+
+We write `assume` because in this scenario we are not *verifying* the
+implementation of `Data.Vector`, we are simply *using* the properties of
+the library to verify client code.  If we wanted to verify the library
+itself, we would ascribe the above types to the relevant functions in the
+Haskell source for `Data.Vector`. 
+
+**Dependent Refinements**
+
+Notice that in the function type (e.g. for `length`) we have *named* the *input*
+parameter `x` so that we can refer to it in the *output* refinement. 
+
+\begin{code} In this case, the type 
+assume length   :: x:(Vector a) -> {v : Int | v = (vlen x)}
+\end{code}
+
+states that the `Int` output is exactly equal to the size of the input `Vector` named `x`.
+
+In other words, the output refinement **depends on** the input value, which
+crucially allows us to write properties that *relate* different program values.
+
+**Verifying a Simple Wrapper**
+
+Lets try write some simple functions to sanity check the above specifications. 
+First, consider an *unsafe* vector lookup function:
+
+\begin{code}
+unsafeLookup vec index = vec ! index
+\end{code}
+
+If we run this through LiquidHaskell, it will spit back a type error for
+the expression `x ! i` because (happily!) it cannot prove that `index` is
+between `0` and the `vlen vec`. Of course, we can specify the bounds 
+requirement in the input type
+
+\begin{code}
+{-@ unsafeLookup :: vec:Vector a 
+                 -> {v: Int | (0 <= v && v < (vlen vec))} 
+                 -> a 
+  @-}
+\end{code}
+
+then LiquidHaskell is happy to verify the lookup. Of course, now the burden
+of ensuring the index is valid is pushed to clients of `unsafeLookup`.
+
+Instead, we might write a *safe* lookup function that performs the *bounds check*
+before looking up the vector:
+
+\begin{code}
+{-@ safeLookup :: Vector a -> Int -> Maybe a @-}
+safeLookup x i 
+  | 0 <= i && i < length x = Just (x ! i)
+  | otherwise              = Nothing 
+\end{code}
+
+**Predicate Aliases**
+
+The type for `unsafeLookup` above is rather verbose as we have to spell out
+the upper and lower bounds and conjoin them. Just as we enjoy abstractions
+when programming, we will find it handy to have abstractions in the
+specification mechanism. To this end, LiquidHaskell supports 
+*predicate aliases*, which are best illustrated by example
+
+\begin{code}
+{-@ predicate Btwn Lo I Hi = (Lo <= I && I < Hi) @-}
+{-@ predicate InBounds I A = (Btwn 0 I (vlen A)) @-}
+\end{code}
+
+Now, we can simplify the type for the unsafe lookup function to
+
+\begin{code}
+{-@ unsafeLookup' :: x:Vector a -> {v:Int | (InBounds v x)} -> a @-}
+unsafeLookup' :: Vector a -> Int -> a
+unsafeLookup' x i = x ! i
+\end{code}
+
+
+Our First Recursive Function
+----------------------------
+
+OK, with the tedious preliminaries out of the way, lets write some code!
+
+To start: a vanilla recursive function that adds up the absolute values of
+the elements of an integer vector.
+
+\begin{code}
+absoluteSum       :: Vector Int -> Int 
+absoluteSum vec   = if 0 < n then go 0 0 else 0
+  where
+    go acc i 
+      | i /= n    = go (acc + abz (vec ! i)) (i + 1)
+      | otherwise = acc 
+    n             = length vec
+\end{code}
+
+where the function `abz` is the absolute value function from [before][ref101].
+
+\begin{code}
+abz n = if 0 <= n then n else (0 - n) 
+\end{code}
+
+Digression: Introducing Errors  
+------------------------------
+
+If you are following along in the demo page -- I heartily 
+recommend that you try the following modifications, 
+one at a time, and see what happens.
+
+**What happens if:** 
+
+1. You *remove* the check `0 < n` (see `absoluteSumNT` in the demo code)
+
+2. You *replace* the guard with `i <= n`
+
+In the *former* case, LiquidHaskell will *verify* safety, but
+in the *latter* case, it will grumble that your program is *unsafe*. 
+
+Do you understand why? 
+(Thanks to [smog_alado][smog_alado] for pointing this out :))
+
+
+Refinement Type Inference
+-------------------------
+
+LiquidHaskell happily verifies `absoluteSum` -- or, to be precise, 
+the safety of the vector accesses `vec ! i`. The verification works 
+out because LiquidHaskell is able to automatically infer a suitable 
+type for `go`. Shuffle your mouse over the identifier above to see 
+the inferred type. Observe that the type states that the first 
+parameter `acc` (and the output) is `0 <= V`. That is, the returned
+value is non-negative.
+
+More importantly, the type states that the second parameter `i` is 
+`0 <= V` and `V <= n` and `V <= (vlen vec)`. That is, the parameter `i` 
+is between `0` and the vector length (inclusive). LiquidHaskell uses these 
+and the test that `i /= n` to establish that `i` is in fact between `0` 
+and `(vlen vec)` thereby verifing safety. 
+
+In fact, if we want to use the function externally (i.e. in another module) 
+we can go ahead and strengthen its type to specify that the output is 
+non-negative.
+
+\begin{code}
+{-@ absoluteSum :: Vector Int -> {v: Int | 0 <= v}  @-} 
+\end{code}
+
+**What happens if:** You *replace* the output type for `absoluteSum` with `{v: Int | 0 < v }` ?
+
+Bottling Recursion With a Higher-Order `loop`
+---------------------------------------------
+
+Next, lets refactor the above low-level recursive function 
+into a generic higher-order `loop`.
+
+\begin{code}
+loop :: Int -> Int -> a -> (Int -> a -> a) -> a 
+loop lo hi base f = go base lo
+  where
+    go acc i     
+      | i /= hi   = go (f i acc) (i + 1)
+      | otherwise = acc
+\end{code}
+
+**Using `loop` to compute `absoluteSum`**
+
+We can now use `loop` to implement `absoluteSum` like so:
+
+\begin{code}
+absoluteSum' vec = if 0 < n then loop 0 n 0 body else 0
+  where body     = \i acc -> acc + (vec ! i)
+        n        = length vec
+\end{code}
+
+LiquidHaskell verifies `absoluteSum'` without any trouble.
+
+It is very instructive to see the type that LiquidHaskell *infers* 
+for `loop` -- it looks something like
+
+\begin{code}
+{-@ loop :: lo: {v: Int | (0 <= v) }  
+         -> hi: {v: Int | (lo <= v) } 
+         -> a 
+         -> (i: {v: Int | (Btwn lo v hi)} -> a -> a)
+         -> a 
+  @-}
+\end{code}
+
+In english, the above type states that 
+
+- `lo` the loop *lower* bound is a non-negative integer
+- `hi` the loop *upper* bound is a greater than `lo`,
+- `f`  the loop *body* is only called with integers between `lo` and `hi`.
+
+Inference is a rather convenient option -- it can be tedious to have to keep 
+typing things like the above! Of course, if we wanted to make `loop` a
+public or exported function, we could use the inferred type to generate 
+an explicit signature too.
+
+\begin{code}At the call 
+loop 0 n 0 body 
+\end{code}
+
+the parameters `lo` and `hi` are instantiated with `0` and `n` respectively
+(which, by the way is where the inference engine deduces non-negativity
+from) and thus LiquidHaskell concludes that `body` is only called with
+values of `i` that are *between* `0` and `(vlen vec)`, which shows the 
+safety of the call `vec ! i`.
+
+**Using `loop` to compute `dotProduct`**
+
+Here's another use of `loop` -- this time to compute the `dotProduct` 
+of two vectors. 
+
+\begin{code}
+dotProduct     :: Vector Int -> Vector Int -> Int
+dotProduct x y = loop 0 (length x) 0 (\i -> (+ (x ! i) * (y ! i))) 
+\end{code}
+
+The gimlet-eyed reader will realize that the above is quite unsafe -- what
+if `x` is a 10-dimensional vector while `y` has only 3-dimensions? 
+
+\begin{code}A nasty
+*** Exception: ./Data/Vector/Generic.hs:244 ((!)): index out of bounds ...
+\end{code}
+
+*Yech*. 
+
+This is precisely the sort of unwelcome surprise we want to do away with at 
+compile-time. Refinements to the rescue! We can specify that the vectors 
+have the same dimensions quite easily
+
+\begin{code}
+{-@ dotProduct :: x:(Vector Int) 
+               -> y:{v: (Vector Int) | (vlen v) = (vlen x)} 
+               -> Int 
+  @-}
+\end{code}
+
+after which LiquidHaskell will gladly verify that the implementation of
+`dotProduct` is indeed safe!
+
+Refining Data Types
+-------------------
+
+Next, suppose we want to write a *sparse dot product*, that is, 
+the dot product of a vector and a **sparse vector** represented
+by a list of index-value tuples.
+
+**Representing Sparse Vectors**
+
+We can represent the sparse vector with a **refinement type alias** 
+
+\begin{code}
+{-@ type SparseVector a N = [({v: Int | (Btwn 0 v N)}, a)] @-}
+\end{code}
+
+As with usual types, the alias `SparseVector` on the left is just a 
+shorthand for the (longer) type on the right, it does not actually 
+define a new type. Thus, the above alias is simply a refinement of
+Haskell's `[(Int, a)]` type, with a size parameter `N` that facilitates 
+easy specification reuse. In this way, refinements let us express 
+invariants of containers like lists in a straightforward manner. 
+
+**Aside:** If you are familiar with the *index-style* length 
+encoding e.g. as found in [DML][dml] or [Agda][agdavec], then note
+that despite appearances, our `SparseVector` definition is *not* 
+indexed. Instead, we deliberately choose to encode properties 
+with logical refinement predicates, to facilitate SMT based 
+checking and inference.
+
+**Verifying Uses of Sparse Vectors**
+
+Next, we can write a recursive procedure that computes the sparse product
+
+\begin{code}
+{-@ sparseProduct :: (Num a) => x:(Vector a) 
+                             -> SparseVector a (vlen x) 
+                             -> a 
+  @-}
+sparseProduct x y  = go 0 y
+  where 
+    go sum ((i, v) : y') = go (sum + (x ! i) * v) y' 
+    go sum []            = sum
+\end{code}
+
+LiquidHaskell verifies the above by using the specification for `y` to
+conclude that for each tuple `(i, v)` in the list, the value of `i` is 
+within the bounds of the vector `x`, thereby proving the safety of the 
+access `x ! i`.
+
+Refinements and Polymorphism
+----------------------------
+
+The sharp reader will have undoubtedly noticed that the sparse product 
+can be more cleanly expressed as a [fold][foldl]. 
+
+\begin{code} Indeed! Let us recall the type of the `foldl` operation
+foldl' :: (a -> b -> a) -> a -> [b] -> a
+\end{code}
+
+Thus, we can simply fold over the sparse vector, accumulating the `sum`
+as we go along
+
+\begin{code}
+{-@ sparseProduct' :: (Num a) => x:(Vector a) 
+                             -> SparseVector a (vlen x) 
+                             -> a 
+  @-}
+sparseProduct' x y  = foldl' body 0 y   
+  where 
+    body sum (i, v) = sum + (x ! i) * v
+\end{code}
+
+LiquidHaskell digests this too, without much difficulty. 
+
+The main trick is in how the polymorphism of `foldl'` is instantiated. 
+
+1. The GHC type inference engine deduces that at this site, the type variable
+   `b` from the signature of `foldl'` is instantiated to the Haskell type `(Int, a)`. 
+
+2. Correspondingly, LiquidHaskell infers that in fact `b` can be instantiated
+   to the *refined* type `({v: Int | (Btwn 0 v (vlen x))}, a)`. 
+   
+Walk the mouse over to `i` to see this inferred type. (You can also hover over
+`foldl'`above to see the rather more verbose fully instantiated type.)
+
+Thus, the inference mechanism saves us a fair bit of typing and allows us to
+reuse existing polymorphic functions over containers and such without ceremony.
+
+Conclusion
+----------
+
+That's all for now folks! Hopefully the above gives you a reasonable idea of
+how one can use refinements to verify size related properties, and more
+generally, to specify and verify properties of recursive, and polymorphic
+functions operating over datatypes. Next time, we'll look at how we can
+teach LiquidHaskell to think about properties of recursive structures
+like lists and trees.
+
+[smog_alado]: http://www.reddit.com/user/smog_alado
+
+[vecspec]:  https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Data/Vector.spec
+[vec]:      http://hackage.haskell.org/package/vector
+[dml]:      http://www.cs.bu.edu/~hwxi/DML/DML.html
+[agdavec]:  http://code.haskell.org/Agda/examples/Vec.agda
+[ref101]:   /blog/2013/01/01/refinement-types-101.lhs/ 
+[ref102]:   /blog/2013/01/27/refinements-101-reax.lhs/ 
+[foldl]:    http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html
+[listtail]: /blog/2013/01/31/safely-catching-a-list-by-its-tail.lhs/
+[dmlarray]: http://www.cs.bu.edu/~hwxi/academic/papers/pldi98.pdf
+
diff --git a/docs/blog/2013-03-26-talking-about-sets.lhs b/docs/blog/2013-03-26-talking-about-sets.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-03-26-talking-about-sets.lhs
@@ -0,0 +1,383 @@
+---
+layout: post
+title: "Talking About Sets"
+date: 2013-03-26 16:12
+comments: true
+external-url:
+categories: basic measures sets
+author: Ranjit Jhala
+published: true 
+demo: TalkingAboutSets.hs
+---
+
+In the posts so far, we've seen how LiquidHaskell allows you to use SMT 
+solvers to specify and verify *numeric* invariants -- denominators 
+that are non-zero, integer indices that are within the range of an 
+array, vectors that have the right number of dimensions and so on.
+
+However, SMT solvers are not limited to numbers, and in fact, support
+rather expressive logics. In the next couple of posts, let's see how
+LiquidHaskell uses SMT to talk about **sets of values**, for example, 
+the contents of a list, and to specify and verify properties about 
+those sets.
+
+<!-- more -->
+
+\begin{code}
+module TalkingAboutSets where
+
+import Data.Set hiding (filter, split)
+import Prelude  hiding (reverse, filter)
+
+\end{code}
+
+Talking about Sets (In Logic)
+=============================
+
+First, we need a way to talk about sets in the refinement logic. We could
+roll our own special Haskell type, but why not just use the `Set a` type
+from `Data.Set`.
+
+The `import Data.Set` , also instructs LiquidHaskell to import in the various 
+specifications defined for the `Data.Set` module that we have *predefined* 
+in [Data/Set.spec][setspec] 
+
+\begin{code} Let's look at the specifications.
+module spec Data.Set where
+
+embed Set as Set_Set
+\end{code}
+
+The `embed` directive tells LiquidHaskell to model the **Haskell** 
+type constructor `Set` with the **SMT** type constructor `Set_Set`.
+
+\begin{code} First, we define the logical operators (i.e. `measure`s) 
+measure Set_sng  :: a -> (Set a)                    -- ^ singleton
+measure Set_cup  :: (Set a) -> (Set a) -> (Set a)   -- ^ union
+measure Set_cap  :: (Set a) -> (Set a) -> (Set a)   -- ^ intersection
+measure Set_dif  :: (Set a) -> (Set a) -> (Set a)   -- ^ difference 
+\end{code}
+
+\begin{code} Next, we define predicates on `Set`s 
+measure Set_emp  :: (Set a) -> Prop                 -- ^ emptiness
+measure Set_mem  :: a -> (Set a) -> Prop            -- ^ membership
+measure Set_sub  :: (Set a) -> (Set a) -> Prop      -- ^ inclusion 
+\end{code}
+
+
+Interpreted Operations
+----------------------
+
+The above operators are *interpreted* by the SMT solver. 
+
+\begin{code} That is, just like the SMT solver "knows that"
+2 + 2 == 4
+\end{code}
+
+\begin{code} the SMT solver also "knows that"
+(Set_sng 1) == (Set_cap (Set_sng 1) (Set_cup (Set_sng 2) (Set_sng 1)))
+\end{code}
+
+This is because, the above formulas belong to a decidable Theory of Sets
+which can be reduced to McCarthy's more general [Theory of Arrays][mccarthy]. 
+See [this recent paper][z3cal] if you want to learn more about how modern SMT 
+solvers "know" the above equality holds...
+
+Talking about Sets (In Code)
+============================
+
+Of course, the above operators exist purely in the realm of the 
+refinement logic, beyond the grasp of the programmer.
+
+To bring them down (or up, or left or right) within reach of Haskell code, 
+we can simply *assume* that the various public functions in `Data.Set` do 
+the *Right Thing* i.e. produce values that reflect the logical set operations:
+
+\begin{code} First, the functions that create `Set` values
+empty     :: {v:(Set a) | (Set_emp v)}
+singleton :: x:a -> {v:(Set a) | v = (Set_sng x)}
+\end{code}
+
+\begin{code} Next, the functions that operate on elements and `Set` values
+insert :: Ord a => x:a 
+                -> xs:(Set a) 
+                -> {v:(Set a) | v = (Set_cup xs (Set_sng x))}
+
+delete :: Ord a => x:a 
+                -> xs:(Set a) 
+                -> {v:(Set a) | v = (Set_dif xs (Set_sng x))}
+\end{code}
+
+\begin{code} Then, the binary `Set` operators
+union        :: Ord a => xs:(Set a) 
+                      -> ys:(Set a) 
+                      -> {v:(Set a) | v = (Set_cup xs ys)}
+
+intersection :: Ord a => xs:(Set a) 
+                      -> ys:(Set a) 
+                      -> {v:(Set a) | v = (Set_cap xs ys)}
+
+difference   :: Ord a => xs:(Set a) 
+                      -> ys:(Set a) 
+                      -> {v:(Set a) | v = (Set_dif xs ys)}
+\end{code}
+
+\begin{code} And finally, the predicates on `Set` values:
+isSubsetOf :: Ord a => xs:(Set a) 
+                    -> ys:(Set a) 
+                    -> {v:Bool | (Prop v) <=> (Set_sub xs ys)}
+
+member     :: Ord a => x:a 
+                    -> xs:(Set a) 
+                    -> {v:Bool | (Prop v) <=> (Set_mem x xs)}
+\end{code}
+
+**Note:** Of course we shouldn't and needn't really *assume*, but should and
+will *guarantee* that the functions from `Data.Set` implement the above types. 
+But thats a story for another day...
+
+Proving Theorems With LiquidHaskell
+===================================
+
+OK, let's take our refined operators from `Data.Set` out for a spin!
+One pleasant consequence of being able to precisely type the operators 
+from `Data.Set` is that we have a pleasant interface for using the SMT
+solver to *prove theorems* about sets, while remaining firmly rooted in
+Haskell. 
+
+First, let's write a simple function that asserts that its input is `True`
+
+\begin{code}
+{-@ boolAssert :: {v: Bool | (Prop v)} -> {v:Bool | (Prop v)} @-}
+boolAssert True   = True
+boolAssert False  = error "boolAssert: False? Never!"
+\end{code}
+
+Now, we can use `boolAssert` to write some simple properties. (Yes, these do
+indeed look like QuickCheck properties -- but here, instead of generating
+tests and executing the code, the type system is proving to us that the
+properties will *always* evaluate to `True`) 
+
+Let's check that `intersection` is commutative ...
+
+\begin{code}
+prop_cap_comm x y 
+  = boolAssert 
+  $ (x `intersection` y) == (y `intersection` x)
+\end{code}
+
+that `union` is associative ...
+
+\begin{code}
+prop_cup_assoc x y z 
+  = boolAssert 
+  $ (x `union` (y `union` z)) == (x `union` y) `union` z
+\end{code}
+
+and that `union` distributes over `intersection`.
+
+\begin{code}
+prop_cap_dist x y z 
+  = boolAssert 
+  $  (x `intersection` (y `union` z)) 
+  == (x `intersection` y) `union` (x `intersection` z) 
+\end{code}
+  
+Of course, while we're at it, let's make sure LiquidHaskell
+doesn't prove anything that *isn't* true ...
+
+\begin{code}
+prop_cup_dif_bad x y
+   = boolAssert 
+   $ x == (x `union` y) `difference` y
+\end{code}
+
+Hmm. You do know why the above doesn't hold, right? It would be nice to
+get a *counterexample* wouldn't it? Well, for the moment, there is
+QuickCheck!
+
+Thus, the refined types offer a nice interface for interacting with the SMT
+solver in order to prove theorems in LiquidHaskell. (BTW, The [SBV project][sbv]
+describes another approach for using SMT solvers from Haskell, without the 
+indirection of refinement types.)
+
+While the above is a nice warm up exercise to understanding how
+LiquidHaskell reasons about sets, our overall goal is not to prove 
+theorems about set operators, but instead to specify and verify 
+properties of programs. 
+
+
+
+The Set of Values in a List
+===========================
+
+Let's see how we might reason about sets of values in regular Haskell programs.
+
+We'll begin with Lists, the jack-of-all-data-types. Now, instead of just
+talking about the **number of** elements in a list, we can write a measure
+that describes the **set of** elements in a list:
+
+\begin{code} A measure for the elements of a list, from [Data/Set.spec][setspec]
+
+measure listElts :: [a] -> (Set a) 
+listElts ([])    = {v | (? Set_emp(v))}
+listElts (x:xs)  = {v | v = (Set_cup (Set_sng x) (listElts xs)) }
+\end{code}
+
+That is, `(listElts xs)` describes the set of elements contained in a list `xs`.
+
+Next, to make the specifications concise, let's define a few predicate aliases:
+
+\begin{code}
+{-@ predicate EqElts  X Y = 
+      ((listElts X) = (listElts Y))                        @-}
+
+{-@ predicate SubElts   X Y = 
+      (Set_sub (listElts X) (listElts Y))                  @-}
+
+{-@ predicate UnionElts X Y Z = 
+      ((listElts X) = (Set_cup (listElts Y) (listElts Z))) @-}
+\end{code}
+
+A Trivial Identity
+------------------
+
+OK, now let's write some code to check that the `listElts` measure is sensible!
+
+\begin{code}
+{-@ listId    :: xs:[a] -> {v:[a] | (EqElts v xs)} @-}
+listId []     = []
+listId (x:xs) = x : listId xs
+\end{code}
+
+That is, LiquidHaskell checks that the set of elements of the output list
+is the same as those in the input.
+
+A Less Trivial Identity
+-----------------------
+
+Next, let's write a function to `reverse` a list. Of course, we'd like to
+verify that `reverse` doesn't leave any elements behind; that is that the 
+output has the same set of values as the input list. This is somewhat more 
+interesting because of the *tail recursive* helper `go`. Do you understand 
+the type that is inferred for it? (Put your mouse over `go` to see the 
+inferred type.)
+
+\begin{code}
+{-@ reverse       :: xs:[a] -> {v:[a] | (EqElts v xs)} @-}
+reverse           = go [] 
+  where 
+    go acc []     = acc
+    go acc (y:ys) = go (y:acc) ys
+\end{code}
+
+Appending Lists
+---------------
+
+Next, here's good old `append`, but now with a specification that states
+that the output indeed includes the elements from both the input lists.
+
+\begin{code}
+{-@ append       :: xs:[a] -> ys:[a] -> {v:[a]| (UnionElts v xs ys)} @-}
+append []     ys = ys
+append (x:xs) ys = x : append xs ys
+\end{code}
+
+Filtering Lists
+---------------
+
+Let's round off the list trilogy, with `filter`. Here, we can verify
+that it returns a **subset of** the values of the input list.
+
+\begin{code}
+{-@ filter      :: (a -> Bool) -> xs:[a] -> {v:[a]| (SubElts v xs)} @-}
+
+filter f []     = []
+filter f (x:xs) 
+  | f x         = x : filter f xs 
+  | otherwise   = filter f xs
+\end{code}
+
+Merge Sort
+==========
+
+Let's conclude this entry with one larger example: `mergeSort`.
+We'd like to verify that, well, the list that is returned 
+contains the same set of elements as the input list. 
+
+And so we will!
+
+But first, let's remind ourselves of how `mergeSort` works:
+
+1. `split` the input list into two halves, 
+2. `sort`  each half, recursively, 
+3. `merge` the sorted halves to obtain the sorted list.
+
+
+Split
+-----
+
+We can `split` a list into two, roughly equal parts like so:
+
+\begin{code}
+split []     = ([], [])
+split (x:xs) = (x:zs, ys)
+  where 
+    (ys, zs) = split xs
+\end{code}
+
+LiquidHaskell verifies that the relevant property of split is
+
+\begin{code} 
+{-@ split :: xs:[a] -> ([a], [a])<{\ys zs -> (UnionElts xs ys zs)}> @-}
+\end{code}
+
+The funny syntax with angle brackets simply says that the output of `split` 
+is a *pair* `(ys, zs)` whose union is the list of elements of the input `xs`.
+(Yes, this is indeed a dependent pair; we will revisit these later to
+understand whats going on with the odd syntax.)
+
+Merge
+-----
+
+Next, we can `merge` two (sorted) lists like so:
+
+\begin{code}
+merge xs []         = xs
+merge [] ys         = ys
+merge (x:xs) (y:ys) 
+  | x <= y          = x : merge xs (y : ys)
+  | otherwise       = y : merge (x : xs) ys
+\end{code}
+
+As you might expect, the elements of the returned list are the union of the
+elements of the input, or as LiquidHaskell might say,
+
+\begin{code}
+{-@ merge :: (Ord a) => x:[a] -> y:[a] -> {v:[a]| (UnionElts v x y)} @-}
+\end{code}
+
+Sort
+----
+
+Finally, we put all the pieces together by
+
+\begin{code}
+{-@ mergeSort :: (Ord a) => xs:[a] -> {v:[a] | (EqElts v xs)} @-}
+mergeSort []  = []
+mergeSort [x] = [x]
+mergeSort xs  = merge (mergeSort ys) (mergeSort zs) 
+  where 
+    (ys, zs)  = split xs
+\end{code}
+
+The type given to `mergeSort`guarantees that the set of elements in the 
+output list is indeed the same as in the input list. Of course, it says 
+nothing about whether the list is *actually sorted*. 
+
+Well, Rome wasn't built in a day...
+
+[sbv]:      https://github.com/LeventErkok/sbv
+[setspec]:  https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Data/Set.spec
+[mccarthy]: http://www-formal.stanford.edu/jmc/towards.ps
+[z3cal]:    http://research.microsoft.com/en-us/um/people/leonardo/fmcad09.pdf
diff --git a/docs/blog/2013-05-16-unique-zippers.lhs b/docs/blog/2013-05-16-unique-zippers.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-05-16-unique-zippers.lhs
@@ -0,0 +1,313 @@
+---
+layout: post
+title: "Unique Zippers"
+date: 2013-05-10 16:12
+comments: true
+external-url:
+categories: basic measures sets zipper uniqueness
+author: Niki Vazou
+published: false 
+demo: TalkingAboutUniqueSets.hs
+---
+
+**The story so far:** [Previously][talking-about-sets] we saw
+how we can use LiquidHaskell to talk about set of values and specifically
+the set of values in a list.
+
+In this post, we will extend this vocabulary to talk about the 
+set of duplicate values in a list. 
+If we constrain this set to be empty, 
+we encode a list without duplicates, or an **unique list**. 
+Once we express uniqueness on lists, it is straightforward to 
+describe uniqueness on other data structures that contain lists.
+As an example, we will illustrate the properties of a **unique zipper**.
+
+\begin{code}
+module UniqueZipper where
+
+import Prelude  hiding (reverse, (++), filter)
+import Data.Set hiding (filter)
+\end{code}
+
+
+A Quick Recap
+=============
+
+\begin{code} In the previous post we used a measure for the elements of a list, from [Data/Set.spec][setspec]
+measure listElts :: [a] -> (Set a)
+listElts ([])    = {v | (? Set_emp(v))}
+listElts (x:xs)  = {v | v = (Set_cup (Set_sng x) (listElts xs)) }
+\end{code}
+
+With this measure we defined predicate aliases 
+that describe relations between lists:
+
+\begin{code}
+{-@ predicate EqElts  X Y      = ((listElts X) = (listElts Y))                        @-}
+
+{-@ predicate DisjointElts X Y = (Set_emp (Set_cap (listElts X) (listElts Y)))        @-}
+
+{-@ predicate SubElts X Y      = (Set_sub (listElts X) (listElts Y))                  @-}
+
+{-@ predicate UnionElts X Y Z  = ((listElts X) = (Set_cup (listElts Y) (listElts Z))) @-}
+
+{-@ predicate ListElt N X      = (Set_mem N (listElts X))                             @-}
+\end{code}
+
+
+These predicates were our vocabulary on specifying properties of list functions.
+Remember, that `reverse` returns an output list that has the same elements, i.e., `EqElts`, with the input list.
+We can extend these predicates and express list uniqueness.
+So reversing a unique list should again return an output list that has the same
+elements as the input list, and also it is unique.
+
+Describing Unique Lists
+======================
+
+To describe unique lists, we follow two steps:
+first, we describe the set of duplicate values of
+a list;
+then, we demand this set to be empty.
+
+Towards the first step, we define a measure `listDup`
+that returns the duplicate values of its input list.
+This measure is recursively defined:
+The duplicates of an empty list is the empty set.
+We compute the duplicates of a non-empty list, 
+namely `x:xs`, as follows:
+
+- If `x` is member of the list values of `xs`, then `x` is a duplicate
+so `listDup` returns a set that contains `x` and the 
+list duplicates of `xs`, as computed recursively.
+
+- Otherwise, we can ignore `x` and recursively compute the duplicates of `xs`.
+
+\begin{code}
+{-@
+  measure listDup :: [a] -> (Set a)
+  listDup([])   = {v | (? (Set_emp v))}
+  listDup(x:xs) = {v | v = ((Set_mem x (listElts xs))?(Set_cup (Set_sng x) (listDup xs)):(listDup xs)) }
+  @-}
+\end{code}
+
+With `listDup` at hand, it is direct to describe unique lists.
+A list is unique, if the set of duplicates, 
+as computed by `listDup`
+is the empty set.
+We create a type alias for unique lists and name it `UList`.
+
+\begin{code}
+{-@ predicate ListUnique X = (Set_emp (listDup X)) @-}
+
+{-@ type UList a = {v:[a] | (ListUnique v)}        @-}
+\end{code}
+
+
+Functions on Unique Lists
+==========================
+
+In the previous post, we proved interesting properties about 
+the list trilogy, i.e., `append`, `reverse`, and `filter`.
+Now, we will prove that apart from these properties,
+all these function preserve list uniqueness.
+
+To begin with, 
+we proved that the output of append
+indeed includes the elements from both the input lists.
+Now, we can also prove that if both input lists are unique and 
+their values form disjoint sets, then the output list is also unique.
+
+\begin{code}
+infixr 5 ++
+{-@ UniqueZipper.++ :: xs:(UList a)
+                    -> ys:{v: UList a | (DisjointElts v xs)}
+                    -> {v: UList a | (UnionElts v xs ys)}
+  @-}
+(++)         :: [a] -> [a] -> [a]
+[] ++ ys     = ys
+(x:xs) ++ ys = x: (xs ++ ys)
+\end{code}
+
+Next, we can prove that if a unique list is reversed, 
+the output list has the same elements as the input,
+and also it is unique.
+\begin{code}
+{-@ reverse :: xs:(UList a)
+            -> {v: UList a | (EqElts v xs)} 
+  @-}
+reverse :: [a] -> [a]
+reverse = go []
+  where
+    go a []     = a
+    go a (x:xs) = go (x:a) xs 
+\end{code}
+
+Finally, filtering a unique list returns a list
+with a subset of values of the input list, that once again is unique! 
+
+\begin{code}
+{-@ filter :: (a -> Bool) -> xs:(UList a) -> {v:UList a | (SubElts v xs)} @-}
+filter      :: (a -> Bool) -> [a] -> [a]
+filter p [] = []
+filter p (x:xs) 
+  | p x       = x : filter p xs
+  | otherwise = filter p xs
+\end{code}
+
+Unique Zipper
+=============
+
+A [zipper][http://en.wikipedia.org/wiki/Zipper_(data_structure)] is an aggregate data stucture 
+that is used to arbitrary traverse the structure and update its contents.
+We define a zipper as a data type that contains 
+an element (called `focus`) that we are currently using,
+a list of elements (called `up`) before the current one,
+and a list of elements (called `down`) after the current one.
+
+\begin{code}
+data Zipper a = Zipper { focus :: a       -- focused element in this set
+                       , up    :: [a]     -- elements to the left
+                       , down  :: [a] }   -- elements to the right
+\end{code}
+
+
+We would like to state that all the values in the zipper 
+are unique.
+To start with, we would like to refine the `Zipper` data declaration
+to express that both the lists in the structure
+are unique **and** do not include `focus` in their values.
+
+LiquidHaskell allow us to refine data type declarations, 
+using the liquid comments.
+So, apart from above definition definition for the `Zipper`, 
+we add a refined one, stating that the data structure always enjoys 
+the desired properties.
+
+\begin{code}
+{-@ 
+data Zipper a = Zipper { focus :: a
+                       , up    :: UListDif a focus
+                       , down  :: UListDif a focus}
+  @-}
+
+{-@ type UListDif a N = {v:(UList a) | (not (ListElt N v))} @-}
+\end{code}
+
+With this annotation any time we use a `Zipper` in the code
+LiquidHaskell knows that 
+the `up` and `down` components are unique lists that do not include `focus`.
+Moreover, when a new `Zipper` is constructed we should prove that
+this property holds,
+otherwise a liquid error will occur.
+
+You may notice values inside the `Zipper` are not unique, as
+a value can appear in both the `up` and the `down` components.
+So, we have to specify that 
+these two elements form disjoint lists.
+To this end, we define two measures `getUp` and `getDown`
+that return the relevant parts of the `Zipper`
+
+\begin{code}
+{-@ measure getUp :: forall a. (Zipper a) -> [a] 
+    getUp (Zipper focus up down) = up
+  @-}
+
+{-@ measure getDown :: forall a. (Zipper a) -> [a] 
+    getDown (Zipper focus up down) = down
+  @-}
+\end{code}
+
+With these definitions, we create a type alias `UZipper` that states that 
+the two list components are disjoint.
+
+\begin{code}
+{-@ type UZipper a = {v:Zipper a | (DisjointElts (getUp v) (getDown v))} @-}
+\end{code}
+
+Functions on Unique Zipper
+===========================
+
+Since we defined a unique zipper, it is straightforward for
+LiquidHaskell to prove that
+operations on zippers preserve uniqueness.
+
+We can prove that a zipper that contains elements 
+from a unique list is indeed unique.
+
+\begin{code}
+{-@ differentiate :: UList a -> Maybe (UZipper a) @-}
+differentiate :: [a] -> Maybe (Zipper a)
+differentiate []     = Nothing
+differentiate (x:xs) = Just $ Zipper x [] xs
+\end{code}
+
+And vice versa, all elements of a unique zipper 
+can construct a unique list.
+
+\begin{code}
+{-@ integrate :: UZipper a -> UList a @-}
+integrate :: Zipper a -> [a]
+integrate (Zipper x l r) = reverse l ++ x : r
+\end{code}
+
+By the definition of `UZipper` we know that `l` is a unique list
+and that `x` is not an element of `l`.
+Thus, if `l` is reversed using the descriptive type of `reverse` 
+that we provided before, it preserves both these properties.
+The append operator also uses the 
+type that we show before. So LiquidHaskell, can prove that `x : r`
+is indeed a unique list with elements disjoint from `reverse l` and so we can append it to `reverse l` 
+and get a unique list.
+
+
+With the exact same reasoning, 
+we use the above list operations to create more zipper operations.
+
+So we can reverse a unique zipper
+\begin{code}
+{-@ reverseZipper :: UZipper a -> UZipper a @-}
+reverseZipper :: Zipper a -> Zipper a
+reverseZipper (Zipper t ls rs) = Zipper t rs ls
+\end{code}
+
+
+More the focus up or down
+\begin{code}
+{-@ focusUp, focusDown :: UZipper a -> UZipper a @-}
+focusUp, focusDown :: Zipper a -> Zipper a
+focusUp (Zipper t [] rs)     = Zipper x xs [] where (x:xs) = reverse (t:rs)
+focusUp (Zipper t (l:ls) rs) = Zipper l ls (t:rs)
+
+focusDown = reverseZipper . focusUp . reverseZipper
+
+{-@ q :: x:a ->  {v:[a] |(not (Set_mem x (listElts v)))} @-}
+q :: a -> [a]
+q _ = []
+\end{code}
+
+Finally, using the filter operation on lists
+allows LiquidHaskell to prove that filtering a zipper 
+also preserves uniqueness.
+\begin{code}
+{-@ filterZipper :: (a -> Bool) -> UZipper a -> Maybe (UZipper a) @-}
+filterZipper :: (a -> Bool) -> Zipper a -> Maybe (Zipper a)
+filterZipper p (Zipper f ls rs) = case filter p (f:rs) of
+    f':rs' -> Just $ Zipper f' (filter p ls) rs'    -- maybe move focus down
+    []     -> case filter p ls of                  -- filter back up
+                    f':ls' -> Just $ Zipper f' ls' [] -- else up
+                    []     -> Nothing
+\end{code}
+
+Conclusion
+==========
+
+That's all for now!
+This post illustrated
+
+- How we can use set theory to express properties the values of the list,
+such as list uniqueness.
+- How we can use LuquidHaskell to prove that these properties are preserved through list operations.
+- How we can embed this properties in complicated data structures that use lists, such as a zipper.
+
+
+
diff --git a/docs/blog/2013-05-24-unique-zipper.lhs b/docs/blog/2013-05-24-unique-zipper.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-05-24-unique-zipper.lhs
@@ -0,0 +1,396 @@
+---
+layout: post
+title: "Unique Zippers"
+date: 2013-05-10 16:12
+comments: true
+external-url:
+categories: basic measures sets zipper uniqueness
+author: Niki Vazou
+published: true
+demo: UniqueZipper.hs
+---
+
+**The story so far:** [Previously][about-sets] we saw
+how we can use LiquidHaskell to talk about set of values
+and specifically the *set of values* in a list.
+
+Often, we want to enforce the invariant that a particular data structure
+contains *no duplicates*. For example, we may have a structure that holds
+a collection of file handles, or other resources, where the presence of
+duplicates could lead to unpleasant leaks.
+
+In this post, we will see how to use LiquidHaskell to talk
+about the set of duplicate values in data structures, and 
+hence, let us specify and verify uniqueness, that is, the
+absence of duplicates.
+
+<!-- more -->
+
+To begin, lets extend our vocabulary to talk about the *set of duplicate
+values* in lists.  By constraining this set to be empty, we can specify a
+list without duplicates, or an **unique list**.  Once we express uniqueness
+on lists, it is straightforward to describe uniqueness on other data
+structures that contain lists.  As an example, we will illustrate the
+properties of a **unique zipper**.
+
+\begin{code}
+module UniqueZipper where
+
+import Prelude  hiding (reverse, (++), filter)
+import Data.Set hiding (filter)
+\end{code}
+
+
+A Quick Recap
+=============
+
+\begin{code} In the previous post we used a measure for the elements of a list, from [Data/Set.spec][setspec]
+measure listElts :: [a] -> (Set a)
+listElts ([])    = {v | (? (Set_emp v))}
+listElts (x:xs)  = {v | v = (Set_cup (Set_sng x) (listElts xs)) }
+\end{code}
+
+With this measure we defined predicate aliases 
+that describe relations between lists:
+
+\begin{code}
+{-@ predicate EqElts  X Y      = 
+      ((listElts X) = (listElts Y))                        @-}
+
+{-@ predicate DisjointElts X Y = 
+      (Set_emp (Set_cap (listElts X) (listElts Y)))        @-}
+
+{-@ predicate SubElts X Y      = 
+      (Set_sub (listElts X) (listElts Y))                  @-}
+
+{-@ predicate UnionElts X Y Z  = 
+      ((listElts X) = (Set_cup (listElts Y) (listElts Z))) @-}
+
+{-@ predicate ListElt N X      = 
+      (Set_mem N (listElts X))                             @-}
+\end{code}
+
+
+These predicates were our vocabulary on specifying properties of list functions.
+Remember, that `reverse` returns an output list that has the same elements, i.e., `EqElts`, with the input list.
+We can extend these predicates and express list uniqueness.
+So reversing a unique list should again return an output list that has the same
+elements as the input list, and also it is unique.
+
+Describing Unique Lists
+======================
+
+To describe unique lists, we follow two steps:
+
+1. we describe the set of duplicate values of a list; and 
+2. we demand this set to be empty.
+
+Towards the first step, we define a measure `dups`
+that returns the duplicate values of its input list.
+This measure is recursively defined:
+The duplicates of an empty list is the empty set.
+We compute the duplicates of a non-empty list, 
+namely `x:xs`, as follows:
+
+- If `x` is an element of `xs`, then `x` is a duplicate.
+  Hence, `dups` is `x` plus the (recursively computed) 
+  duplicates in `xs`.
+
+- Otherwise, we can ignore `x` and recursively compute 
+  the duplicates of `xs`.
+
+The above intuition can be formalized as a measure:
+
+\begin{code}
+{-@
+  measure dups :: [a] -> (Set a)
+  dups([])   = {v | (? (Set_emp v))}
+  dups(x:xs) = {v | v = (if (Set_mem x (listElts xs))
+                         then (Set_cup (Set_sng x) (dups xs))
+                         else (dups xs)) }
+  @-}
+\end{code}
+
+With `dups` in hand, it is direct to describe unique lists:
+
+A list is unique, if the set of duplicates, as computed by `dups` is empty.
+
+We create a type alias for unique lists and name it `UList`.
+
+\begin{code}
+{-@ predicate ListUnique X = (Set_emp (dups X)) @-}
+
+{-@ type UList a = {v:[a] | (ListUnique v)}     @-}
+\end{code}
+
+
+Functions on Unique Lists
+==========================
+
+In the previous post, we proved interesting properties about 
+the list trilogy, i.e., `append`, `reverse`, and `filter`.
+Now, we will prove that apart from these properties,
+all these functions preserve list uniqueness.
+
+Append
+------
+
+To begin with, we proved that the output of append
+indeed includes the elements from both the input lists.
+Now, we can also prove that if both input lists are 
+unique *and their elements are disjoint*, then the 
+output list is also unique.
+
+\begin{code}
+infixr 5 ++
+{-@ UniqueZipper.++ :: xs:(UList a)
+                    -> ys:{v: UList a | (DisjointElts v xs)}
+                    -> {v: UList a | (UnionElts v xs ys)}
+  @-}
+(++)         :: [a] -> [a] -> [a]
+[] ++ ys     = ys
+(x:xs) ++ ys = x:(xs ++ ys)
+\end{code}
+
+Reverse
+-------
+
+Next, we can prove that if a unique list is reversed, 
+the output list has the same elements as the input,
+and also it is unique.
+
+\begin{code}
+{-@ reverse :: xs:(UList a) -> {v: UList a | (EqElts v xs)} @-}
+reverse :: [a] -> [a]
+reverse = go []
+  where
+    go a []     = a
+    go a (x:xs) = go (x:a) xs 
+\end{code}
+
+Filter
+------
+
+Finally, filtering a unique list returns a list with a subset of
+values of the input list, that once again is unique! 
+
+\begin{code}
+{-@ filter :: (a -> Bool) 
+           -> xs:(UList a) 
+           -> {v:UList a | (SubElts v xs)} 
+  @-}
+filter p [] = []
+filter p (x:xs) 
+  | p x       = x : filter p xs
+  | otherwise = filter p xs
+\end{code}
+
+
+Unique Zipper
+=============
+
+That was easy enough! Now, lets look at a slightly more interesting
+structure fashioned from lists.  A [zipper][wiki-zipper] is an aggregate
+data stucture that is used to arbitrary traverse the structure and update
+its contents.
+
+We define a zipper as a data type that contains an element (called `focus`)
+that we are currently using, a list of elements (called `up`) before
+the current one, and a list of elements (called `down`) after the current one.
+
+\begin{code}
+data Zipper a = Zipper { focus :: a       -- focused element in this set
+                       , up    :: [a]     -- elements to the left
+                       , down  :: [a] }   -- elements to the right
+\end{code}
+
+
+One well-known application of zippers is in the
+[XMonad](http://xmonad.org/) tiling window manager. 
+The set of windows being managed is stored in a zipper 
+similar to the above. The `focus` happily coincides with 
+the window currently in focus, and the `up` and `down` 
+to the list of windows that come before and after it.
+
+One crucial invariant maintained by XMonad is that the zipper structure is
+unique -- i.e. each window appears at most once inside the zipper.
+
+Lets see how we can state and check that all the values in a zipper are unique.
+
+To start with, we would like to refine the `Zipper` data declaration
+to express that both the lists in the structure are unique **and** 
+do not include `focus` in their values.
+
+LiquidHaskell allow us to refine data type declarations, using the liquid comments.
+So, apart from above definition definition for the `Zipper`, we add a refined one,
+stating that the data structure always enjoys the desired properties.
+
+\begin{code}
+{-@ data Zipper a = Zipper { focus :: a
+                           , up    :: UListDif a focus
+                           , down  :: UListDif a focus}
+  @-}
+
+{-@ type UListDif a N = {v:(UList a) | (not (ListElt N v))} @-}
+\end{code}
+
+It is worth noting that the above is kind of *dependent* record in that
+the types of the `up` and `down` fields depend on the value of the `focus`
+field.
+
+With this annotation any time we use a `Zipper` in the code LiquidHaskell
+knows that the `up` and `down` components are unique lists
+that do not include `focus`. Moreover, when a new `Zipper` is constructed
+LiquidHaskell proves that this property holds, otherwise a liquid type 
+error is reported.
+
+
+Hold on a minute!
+
+The awake reader will have noticed that values inside the `Zipper` as 
+specified so far, are *not unique*, as nothing prevents a value from 
+appearing in both the `up` and the `down` components.
+
+So, we have to specify that the contents of those two fields are *disjoint*.
+
+One way to achieve this is by defining two measures `getUp` and `getDown`
+that return the relevant parts of the `Zipper`
+
+\begin{code}
+{-@ measure getUp :: forall a. (Zipper a) -> [a] 
+    getUp (Zipper focus up down) = up
+  @-}
+
+{-@ measure getDown :: forall a. (Zipper a) -> [a] 
+    getDown (Zipper focus up down) = down
+  @-}
+\end{code}
+
+With these definitions, we create a type alias `UZipper`
+that states that the two list components are disjoint, and hence,
+that we have a *unique zipper* with no duplicates.
+
+\begin{code}
+{-@ 
+  type UZipper a = {v:Zipper a | (DisjointElts (getUp v) (getDown v))} 
+  @-}
+\end{code}
+
+
+Functions on Unique Zippers
+===========================
+
+Now that we have defined a unique zipper, it is straightforward for
+LiquidHaskell to prove that operations on zippers preserve uniqueness.
+
+Differentiation
+---------------
+
+We can prove that a zipper that built from elements from a unique list is
+indeed unique.
+
+\begin{code}
+{-@ differentiate :: UList a -> Maybe (UZipper a) @-}
+differentiate []     = Nothing
+differentiate (x:xs) = Just $ Zipper x [] xs
+\end{code}
+
+Integration
+-----------
+
+And vice versa, all elements of a unique zipper yield a unique list.
+
+\begin{code}
+{-@ integrate :: UZipper a -> UList a @-}
+integrate (Zipper x l r) = reverse l ++ x : r
+\end{code}
+
+Recall the types for `++` and `reverse` that we proved earlier -- hover
+your mouse over the identifiers to refresh your memory. Those types are
+essential for establishing the type of `integrate`. 
+
+- By the definition of `UZipper` we know that `l` is a unique list
+  and that `x` is not an element of `l`.
+
+- Thus via the type of `reverse` we know that  `reverse l` is also
+  unique and disjoint from `x` and `r`.
+
+- Finally, using the previously established type for `++` 
+  LiquidHaskell can prove that since `x : r` is a unique 
+  list with elements disjoint from `reverse l` the concatenation
+  of the two lists is also a unique list.
+
+
+With the exact same reasoning, we use the above list operations to create more zipper operations.
+
+Reverse
+-------
+
+We can reverse a unique zipper
+
+\begin{code}
+{-@ reverseZipper :: UZipper a -> UZipper a @-}
+reverseZipper :: Zipper a -> Zipper a
+reverseZipper (Zipper t ls rs) = Zipper t rs ls
+\end{code}
+
+Shifting Focus
+--------------
+
+More the focus up or down
+
+\begin{code}
+{-@ focusUp   :: UZipper a -> UZipper a @-}
+focusUp (Zipper t [] rs)     = Zipper x xs [] 
+  where 
+    (x:xs)                   = reverse (t:rs)
+
+focusUp (Zipper t (l:ls) rs) = Zipper l ls (t:rs)
+
+{-@ focusDown :: UZipper a -> UZipper a @-}
+focusDown = reverseZipper . focusUp . reverseZipper
+\end{code}
+
+Filter
+------
+
+Finally, using the filter operation on lists allows LiquidHaskell to prove
+that filtering a zipper also preserves uniqueness.
+
+\begin{code}
+{-@ filterZipper :: (a -> Bool) -> UZipper a -> Maybe (UZipper a) @-}
+filterZipper p (Zipper f ls rs) 
+  = case filter p (f:rs) of
+      f':rs' -> Just $ Zipper f' (filter p ls) rs'
+      []     -> case filter p ls of                  
+                  f':ls' -> Just $ Zipper f' ls' []
+                  []     -> Nothing
+\end{code}
+
+Conclusion
+==========
+
+That's all for now! This post illustrated
+
+1. How we can use set theory to express properties the values of the list,
+   such as list uniqueness.
+
+2. How we can use LuquidHaskell to prove that these properties are
+   preserved through list operations.
+
+3. How we can embed this properties in complicated data structures that use
+   lists, such as a zipper.
+
+
+[wiki-zipper]: http://en.wikipedia.org/wiki/Zipper_(data_structure)
+[about-sets]:  blog/2013/03/26/talking-about-sets.lhs/
+[setspec]:     https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Data/Set.spec
+
+\begin{code}
+-- TODO: Dummy function to provide qualifier hint.
+{-@ q :: x:a ->  {v:[a] |(not (Set_mem x (listElts v)))} @-}
+q :: a -> [a]
+q _ = []
+\end{code}
+
+
diff --git a/docs/blog/2013-06-03-abstracting-over-refinements.lhs b/docs/blog/2013-06-03-abstracting-over-refinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-06-03-abstracting-over-refinements.lhs
@@ -0,0 +1,315 @@
+---
+layout: post
+title: "Abstracting Over Refinements"
+date: 2013-06-03 16:12
+comments: true
+external-url:
+author: Ranjit Jhala and Niki Vazou 
+published: true 
+categories: abstract-refinements
+demo: absref101.hs
+---
+
+We've seen all sorts of interesting invariants that can be expressed with
+refinement predicates. For example, whether a divisor is [non-zero][blog-dbz], 
+the [dimension][blog-len] of lists, ensuring the safety of 
+[vector indices][blog-vec] and reasoning about the [set][blog-set] of values
+in containers and verifying their [uniqueness][blog-zip].
+In each of these cases, we were working with *specific* refinement predicates
+that described whatever property was of interest.
+
+Today, (drumroll please), I want to unveil a brand new feature of
+LiquidHaskell, which allows us to *abstract* over specific properties or
+invariants, which significantly increases the expressiveness of the 
+system, whilst still allowing our friend the SMT solver to carry 
+out verification and inference automatically.
+
+<!-- more -->
+
+\begin{code}
+
+module MickeyMouse where
+
+import Language.Haskell.Liquid.Prelude (isEven)
+\end{code}
+
+Pin The Specification On the Function 
+-------------------------------------
+
+Lets look at some tiny *mickey-mouse* examples to see why we may want
+to abstract over refinements in the first place.
+
+Consider the following monomorphic `max` function on `Int` values:
+
+\begin{code}
+maxInt     :: Int -> Int -> Int 
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+\begin{code} We could give `maxInt` many, quite different and incomparable refinement types like
+maxInt :: {v:Int | v >= 0} -> {v:Int | v >= 0} -> {v:Int | v >= 0}
+\end{code}
+
+\begin{code}or
+maxInt :: {v:Int | v < 10} -> {v:Int | v < 10} -> {v:Int | v < 10}
+\end{code}
+
+\begin{code}or even 
+maxInt :: {v:Int | (Even v)} -> {v:Int | (Even v)} -> {v:Int | (Even v)}
+\end{code}
+
+All of the above are valid. 
+
+But which one is the *right* type? 
+
+At this point, you might be exasperated for one of two reasons.
+
+First, the type enthusiasts among you may cry out -- "What? Does this funny
+refinement type system not have **principal types**?"
+
+No. Or, to be precise, of course not!
+
+Principal typing is a lovely feature that is one of the many 
+reasons why Hindley-Milner is such a delightful sweet spot. 
+Unfortunately, the moment one wants fancier specifications 
+one must tearfully kiss principal typing good bye.
+
+Oh well.
+
+Second, you may very well say, "Yes yes, does it even matter? Just pick
+one and get on with it already!"
+
+Unfortunately, it matters quite a bit.
+
+Suppose we had a refined type describing valid RGB values:
+
+\begin{code}
+{-@ type RGB = {v: Int | ((0 <= v) && (v < 256)) } @-}
+\end{code}
+
+Now, if I wrote a function that selected the larger, that is to say, the
+more intense, of two RGB values, I would certainly like to check that it 
+produced an RGB value!
+
+\begin{code}
+{-@ intenser   :: RGB -> RGB -> RGB @-}
+intenser c1 c2 = maxInt c1 c2
+\end{code}
+
+Well, guess what. The first type (with `v >= 0`) one would tell us that 
+the output was non-negative, losing the upper bound. The second type (with
+`v < 10`) would cause LiquidHaskell to bellyache about `maxInt` being 
+called with improper arguments -- muttering darkly that an RGB value 
+is not necesarily less than `10`. As for the third type ... well, you get the idea.
+
+So alas, the choice of type *does* matter. 
+
+\begin{code} If we were clairvoyant, we would give `maxInt` a type like
+maxInt :: RGB -> RGB -> RGB 
+\end{code}
+
+but of course, that has its own issues. ("What? I have to write a
+*separate* function for picking the larger of two *4* digit numbers?!")
+
+Defining Parametric Invariants 
+------------------------------
+
+Lets take a step back from the types, and turn to a spot of handwaving.
+
+What's *really* going on with `maxInt`?
+
+Well, the function returns *one of* its two arguments `x` and `y`. 
+
+This means that if *both* arguments satisfy some property then the output
+*must* satisfy that property, *regardless of what that property was!*
+
+To teach LiquidHaskell to understand this notion of "regardless of
+property" we introduce the idea of **abstracting over refinements**
+or, if you prefer, parameterizing a type over its refinements.
+
+In particular, we type `maxInt` as
+
+\begin{code}
+{-@ maxInt :: forall <p :: Int -> Prop>. Int<p> -> Int<p> -> Int<p>@-}
+\end{code}
+
+Here, the definition says explicitly: *for any property* `p` that is a
+property of `Int`, the function takes two inputs each of which satisfy `p`
+and returns an output that satisfies `p`. That is to say, `Int<p>` is 
+just an abbreviation for `{v:Int | (p v)}`
+
+**Digression: Whither Decidability?** 
+At first glance, it may appear that these abstract `p` have taken us into
+the realm of higher-order logics, where we must leave decidable checking
+and our faithful SMT companion at that door, and instead roll up our 
+sleeves for interactive proofs (not that there's anything wrong with that!) 
+Fortunately, that's not the case. We simply encode abstract refinements `p` 
+as *uninterpreted function symbols* in the refinement logic. 
+
+\begin{code} Uninterpreted functions are special symbols `p` which satisfy only the *congruence axiom*.
+forall X, Y. if (X = Y) then  p(X) = p(Y)
+\end{code}
+
+Happily, reasoning with such uninterpreted functions is quite decidable
+(thanks to Ackermann, yes, *that* Ackermann) and actually rather efficient.
+Thus, via SMT, LiquidHaskell happily verifies that `maxInt` indeed behaves
+as advertised: the input types ensure that both `(p x)` and `(p y)` hold 
+and hence that the returned value in either branch of `maxInt` satisfies 
+the refinement  `{v:Int | p(v)}`, thereby ensuring the output type. 
+
+By the same reasoning, we can define the `maximumInt` operator on lists:
+
+\begin{code}
+{-@ maximumInt :: forall <p :: Int -> Prop>. x:[Int <p>] -> Int <p>@-}
+maximumInt (x:xs) = foldr maxInt x xs
+\end{code}
+
+Using Parametric Invariants
+---------------------------
+
+Its only useful to parametrize over invariants if there is some easy way 
+to *instantiate* the parameters. 
+
+Concretely, consider the function:
+
+\begin{code}
+{-@ maxEvens1 :: xs:[Int] -> {v:Int | (Even v)} @-}
+maxEvens1 xs = maximumInt xs''
+  where 
+    xs'      = [ x | x <- xs, isEven x]
+    xs''     = 0 : xs'
+\end{code}
+
+\begin{code} where the function `isEven` is from the Language.Haskell.Liquid.Prelude library:
+{- isEven :: x:Int -> {v:Bool | (Prop(v) <=> (Even x))} -}
+isEven   :: Int -> Bool
+isEven x = x `mod` 2 == 0
+\end{code}
+
+where the predicate `Even` is defined as
+
+\begin{code}
+{-@ predicate Even X = ((X mod 2) = 0) @-}
+\end{code}
+
+To verify that `maxEvens1` returns an even number, LiquidHaskell 
+
+1. infers that the list `(0:xs')` has type `[{v:Int | (Even v)}]`, 
+   that is, is a list of even numbers.
+
+2. automatically instantiates the *refinement* parameter of 
+   `maximumInt` with the concrete refinement `{\v -> (Even v)}` and so
+
+3. concludes that the value returned by `maxEvens1` is indeed `Even`.
+
+Parametric Invariants and Type Classes
+--------------------------------------
+
+Ok, lets be honest, the above is clearly quite contrived. After all,
+wouldn't you write a *polymorphic* `max` function? And having done so,
+we'd just get all the above goodness from old fashioned parametricity.
+
+\begin{code} That is to say, if we just wrote:
+max     :: forall a. a -> a -> a 
+max x y = if x > y then x else y
+
+maximum :: forall a. [a] -> a
+maximum (x:xs) = foldr max x xs
+\end{code}
+
+then we could happily *instantiate* the `a` with `{v:Int | v > 0}` or
+`{v:Int | (Even v)}` or whatever was needed at the call-site of `max`.
+Sigh. Perhaps we are still pining for Hindley-Milner.
+
+\begin{code} Well, if this was an ML perhaps we could but in Haskell, the types would be 
+(>)     :: (Ord a) => a -> a -> Bool
+max     :: (Ord a) => a -> a -> a
+maximum :: (Ord a) => [a] -> a
+\end{code}
+
+Our first temptation may be to furtively look over our shoulders, and
+convinced no one was watching, just pretend that funny `(Ord a)` business
+was not there, and quietly just treat `maximum` as `[a] -> a` and summon
+parametricity.
+
+That would be most unwise. We may get away with it with the harmless `Ord` but what of, say, `Num`. 
+
+\begin{code} Clearly a function 
+numCrunch :: (Num a) => [a] -> a
+\end{code}
+
+is not going to necessarily return one of its inputs as an output. 
+Thus, it is laughable to believe that `numCrunch` would, if given 
+a list of  of even (or positive, negative, prime, RGB, ...) integers, 
+return a even (or positive, negative, prime, RGB, ...) integer, since 
+the function might add or subtract or multiply or do other unspeakable
+things to the numbers in order to produce the output value.
+
+And yet, typeclasses are everywhere. 
+
+How could we possibly verify that
+
+\begin{code}
+{-@ maxEvens2 :: xs:[Int] -> {v:Int | (Even v) } @-}
+maxEvens2 xs = maximumPoly xs''
+  where 
+     xs'     = [ x | x <- xs, isEven x]
+     xs''    = 0 : xs'
+\end{code}
+
+where the helpers were in the usual `Ord` style?
+
+\begin{code}
+maximumPoly :: (Ord a) => [a] -> a
+maximumPoly (x:xs) = foldr maxPoly x xs
+
+maxPoly     :: (Ord a) => a -> a -> a 
+maxPoly x y = if x <= y then y else x
+\end{code}
+
+The answer: abstract refinements.
+
+First, via the same analysis as the monomorphic `Int` case, LiquidHaskell
+establishes that
+
+\begin{code}
+{-@ maxPoly :: forall <p :: a -> Prop>. 
+                 (Ord a) => x:a<p> -> y:a<p> -> a<p> @-}
+\end{code}
+
+and hence, that
+
+\begin{code}
+{-@ maximumPoly :: forall <p :: a -> Prop>. 
+                     (Ord a) => x:[a<p>] -> a<p>     @-}
+\end{code}
+
+Second, at the call-site for `maximumPoly` in `maxEvens2` LiquidHaskell 
+instantiates the type variable `a` with `Int`, and the abstract refinement
+parameter `p` with `{\v -> (Even v)}` after which, the verification proceeds 
+as described earlier (for the `Int` case).
+
+And So
+------
+
+If you've courageously slogged through to this point then you've learnt
+that 
+
+1. Sometimes, choosing the right type can be quite difficult! 
+
+2. But fortunately, with *abstract refinements* we needn't choose, but 
+   can write types that are parameterized over the actual concrete 
+   invariants or refinements, which
+
+3. Can be instantiated at the call-sites i.e. users of the functions.
+
+We started with some really frivolous examples, but buckle your seatbelt 
+and hold on tight, because we're going to see some rather nifty things that
+this new technique makes possible, including induction, reasoning about
+memoizing functions, and *ordering* and *sorting* data. Stay tuned.
+
+[blog-dbz]:     /blog/2013/01/01/refinement-types-101.lhs/ 
+[blog-len]:     /blog/2013/01/31/safely-catching-a-list-by-its-tail.lhs/ 
+[blog-vec]:     /blog/2013/03/04/bounding-vectors.lhs/
+[blog-set]:     /blog/2013/03/26/talking/about/sets.lhs/
+[blog-zip]:     /blog/2013/05/16/unique-zipper.lhs/
diff --git a/docs/blog/2013-07-29-putting-things-in-order.lhs b/docs/blog/2013-07-29-putting-things-in-order.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-07-29-putting-things-in-order.lhs
@@ -0,0 +1,608 @@
+---
+layout: post
+title: "Putting Things In Order"
+date: 2013-07-29 16:12
+comments: true
+external-url:
+categories: abstract-refinements
+author: Niki Vazou and Ranjit Jhala
+published: true 
+demo: Order.hs
+---
+
+Hello again! Since we last met, much has happened that
+we're rather excited about, and which we promise to get
+to in the fullness of time.
+
+Today, however, lets continue with our exploration of
+abstract refinements. We'll see that this rather innocent 
+looking mechanism packs quite a punch, by showing how 
+it can encode various **ordering** properties of 
+recursive data structures.
+
+<!-- more -->
+
+\begin{code}
+module PuttingThingsInOrder where
+
+import Prelude hiding (break)
+
+-- Haskell Type Definitions
+plusOnes                         :: [(Int, Int)]
+insertSort, mergeSort, quickSort :: (Ord a) => [a] -> [a]
+\end{code}
+
+Abstract Refinements
+--------------------
+
+\begin{code} Recall that *abstract refinements* are a mechanism that let us write and check types of the form
+maxInt :: forall <p :: Int -> Prop>. Int<p> -> Int<p> -> Int<p>
+\end{code}
+
+which states that the output of `maxInt` preserves 
+*whatever* invariants held for its two inputs as 
+long as both those inputs *also* satisfied those 
+invariants. 
+
+First, lets see how we can (and why we may want to) 
+abstractly refine data types. 
+
+Polymorphic Association Lists
+-----------------------------
+
+Suppose, we require a type for association lists. 
+Lets define one that is polymorphic over keys `k` 
+and values `v` 
+
+\begin{code}
+data AssocP k v = KVP [(k, v)]
+\end{code}
+
+Now, in a program, you might have multiple association
+lists, whose keys satisfy different properties. 
+For example, we might have a table for mapping digits 
+to the corresponding English string
+
+\begin{code}
+digitsP :: AssocP Int String
+digitsP = KVP [ (1, "one")
+              , (2, "two")
+              , (3, "three") ]
+\end{code}
+
+We could have a separate table for *sparsely* storing 
+the contents of an array of size `1000`.
+
+\begin{code}
+sparseVecP :: AssocP Int Double
+sparseVecP = KVP [ (12 ,  34.1 )
+                 , (92 , 902.83)
+                 , (451,   2.95)
+                 , (877,   3.1 )]
+\end{code}
+
+The **keys** used in the two tables have rather 
+different properties, which we may want to track 
+at compile time.
+
+- In `digitsP` the keys are between `0` and `9` 
+- In `sparseVecP` the keys are between `0` and `999`. 
+
+Well, since we had the foresight to parameterize 
+the key type in `AssocP`, we can express the above 
+properties by appropriately **instantiating** the type
+of `k` with refined versions
+
+\begin{code}
+{-@ digitsP :: AssocP {v:Int | (Btwn 0 v 9)} String @-}
+\end{code}
+
+and 
+
+\begin{code}
+{-@ sparseVecP :: AssocP {v:Int | (Btwn 0 v 1000)} Double @-}
+\end{code}
+
+where `Btwn` is just an alias 
+
+\begin{code}
+{-@ predicate Btwn Lo V Hi = (Lo <= V && V <= Hi) @-}
+\end{code}
+
+Monomorphic Association Lists
+-----------------------------
+
+Now, suppose that for one reason or another, we want to 
+specialize our association list so that the keys are of 
+type `Int`. 
+
+\begin{code}
+data Assoc v = KV [(Int, v)]
+\end{code}
+
+(We'd probably also want to exploit the `Int`-ness 
+in the implementation but thats a tale for another day.)
+
+Now, we have our two tables
+
+\begin{code}
+digits    :: Assoc String
+digits    = KV [ (1, "one")
+               , (2, "two")
+               , (3, "three") ]
+
+sparseVec :: Assoc Double
+sparseVec = KV [ (12 ,  34.1 )
+               , (92 , 902.83)
+               , (451,   2.95)
+               , (877,   3.1 )]
+\end{code}
+
+but since we didn't make the key type generic, it seems 
+we have no way to distinguish between the invariants of 
+the two sets of keys. Bummer!
+
+Abstractly Refined Data
+-----------------------
+
+We *could* define *two separate* types of association 
+lists that capture different invariants, but frankly, 
+thats rather unfortunate, as we'd then have to 
+duplicate the code the manipulates the structures. 
+Of course, we'd like to have (type) systems help 
+keep an eye on different invariants, but we'd 
+*really* rather not have to duplicate code to 
+achieve that end. Thats the sort of thing that
+drives a person to JavaScript ;-).
+
+Fortunately, all is not lost. 
+
+If you were paying attention [last time][blog-absref] 
+then you'd realize that this is the perfect job for 
+an abstract refinement, this time applied to a `data` 
+definition:
+
+\begin{code}
+{-@ data Assoc v <p :: Int -> Prop> 
+      = KV (z :: [(Int<p>, v)]) @-} 
+\end{code}
+
+The definition refines the type for `Assoc` to introduce
+an abstract refinement `p` which is, informally speaking,
+a property of `Int`. The definition states that each `Int`
+in the association list in fact satisfies `p` as, `Int<p>`
+is an abbreviation for `{v:Int| (p v)}`.
+
+Now, we can *have* our `Int` keys and *refine* them too!
+For example, we can write:
+
+\begin{code}
+{-@ digits :: Assoc (String) <{\v -> (Btwn 0 v 9)}> @-}
+\end{code}
+
+to track the invariant for the `digits` map, and write
+
+\begin{code}
+{-@ sparseVec :: Assoc Double <{\v -> (Btwn 0 v 1000)}> @-}
+\end{code}
+
+Thus, we can recover (some of) the benefits of abstracting 
+over the type of the key by instead parameterizing the type
+directly over the possible invariants. We will have much 
+[more to say][blog-absref-vec] on association lists 
+(or more generally, finite maps) and abstract refinements, 
+but lets move on for the moment.
+
+Dependent Tuples
+----------------
+
+It is no accident that we have reused Haskell's function 
+type syntax to define abstract refinements (`p :: Int -> Prop`);
+interesting things start to happen if we use multiple parameters.
+
+Consider the function `break` from the Prelude. 
+
+\begin{code}
+break                   :: (a -> Bool) -> [a] -> ([a], [a])
+break _ xs@[]           =  (xs, xs)
+break p xs@(x:xs')
+           | p x        =  ([], xs)
+           | otherwise  =  let (ys, zs) = break p xs' 
+                           in (x:ys,zs)
+\end{code}
+
+From the comments in [Data.List][data-list], `break p xs`: 
+"returns a tuple where the first element is longest prefix (possibly empty)
+`xs` of elements that do not satisfy `p` and second element is the 
+remainder of the list."
+
+We could formalize the notion of the *second-element-being-the-remainder* 
+using sizes. That is, we'd like to specify that the length of the second 
+element equals the length of `xs` minus the length of the first element.  
+That is, we need a way to allow the refinement of the second element to 
+*depend on* the value in the first refinement.
+Again, we could define a special kind of tuple-of-lists-type that 
+has the above property *baked in*, but thats just not how we roll.
+
+\begin{code} Instead, lets use abstract refinements to give us **dependent tuples**
+data (a,b)<p :: a -> b -> Prop> = (x:a, b<p x>) 
+\end{code}
+
+Here, the abstract refinement takes two parameters, 
+an `a` and a `b`. In the body of the tuple, the 
+first element is named `x` and we specify that 
+the second element satisfies the refinement `p x`, 
+i.e. a partial application of `p` with the first element. 
+In other words, the second element is a value of type
+`{v:b | (p x v)}`.
+
+As before, we can instantiate the `p` in *different* ways. 
+For example the whimsical
+
+\begin{code}
+{-@ plusOnes :: [(Int, Int)<{\x1 x2 -> x2 = x1 + 1}>] @-}
+plusOnes = [(0,1), (5,6), (999,1000)]
+\end{code}
+
+and returning to the *remainder* property for  `break` 
+
+\begin{code}
+{-@ break :: (a -> Bool) -> x:[a] 
+          -> ([a], [a])<{\y z -> (Break x y z)}> @-}
+\end{code}
+
+using the predicate alias
+
+\begin{code}
+{-@ predicate Break X Y Z   = (len X) = (len Y) + (len Z) @-}
+\end{code}
+
+
+Abstractly Refined Lists
+------------------------
+
+Right, we've been going on for a bit. Time to put things *in order*.
+
+To recap: we've already seen one way to abstractly refine lists: 
+to recover a *generic* means of refining a *monomorphic* list 
+(e.g. the list of `Int` keys.) However, in that case we were 
+talking about *individual* keys.
+Next, we build upon the dependent-tuples technique we just 
+saw to use abstract refinements to relate *different* 
+elements inside containers.
+
+In particular, we can use them to specify that *every pair* 
+of elements inside the list is related according to some 
+abstract relation `p`. By *instantiating* `p` appropriately,
+we will be able to recover various forms of (dis) order. 
+
+\begin{code} Consider the refined definition of good old Haskell lists:
+data [a] <p :: a -> a -> Prop> where
+  | []  :: [a] <p>
+  | (:) :: h:a -> [a<p h>]<p> -> [a]<p>
+\end{code}
+
+Whoa! Thats a bit of a mouthful. Lets break it down.
+
+* The type is parameterized with a refinement `p :: a -> a -> Prop` 
+  Think of `p` as a *binary relation* over the `a` values comprising
+  the list.
+
+* The empty list `[]` is a `[]<p>`. Clearly, the empty list has no
+  elements whatsoever and so every pair is trivially, or rather, 
+  vacuously related by `p`.
+
+* The cons constructor `(:)` takes a head `h` of type `a` and a tail
+  of `a<p h>` values, each of which is *related to* `h` **and** which 
+  (recursively) are pairwise related `[...]<p>` and returns a list where 
+  *all* elements are pairwise related `[a]<p>`.
+
+Pairwise Related
+----------------
+
+Note that we're being a bit sloppy when we say *pairwise* related.
+
+\begin{code} What we really mean is that if a list
+[x1,...,xn] :: [a]<p>
+\end{code}
+
+then for each `1 <= i < j <= n` we have `(p xi xj)`.
+
+\begin{code} To see why, consider the list
+[x1, x2, x3, ...] :: [a]<p>
+\end{code}
+
+\begin{code} This list unfolds into a head and tail 
+x1                :: a
+[x2, x3,...]      :: [a<p x1>]<p>
+\end{code}
+
+\begin{code} The above tail unfolds into
+x2                :: a<p x1>
+[x3, ...]         :: [a<p x1 && p x2>]<p>
+\end{code}
+
+\begin{code} And finally into 
+x3                :: a<p x1 && p x2>
+[...]             :: [a<p x1 && p x2 && p x3>]<p>
+\end{code}
+
+That is, each element `xj` satisfies the refinement 
+`(p xi xj)` for each `i < j`.
+
+Using Abstractly Refined Lists
+------------------------------
+
+Urgh. *Math is hard!*  
+
+Lets see how we can *program* with these funnily refined lists.
+
+For starters, we can define a few helpful type aliases.
+
+\begin{code}
+{-@ type IncrList a = [a]<{\xi xj -> xi <= xj}> @-}      
+{-@ type DecrList a = [a]<{\xi xj -> xi >= xj}> @-}
+{-@ type UniqList a = [a]<{\xi xj -> xi /= xj}> @-}
+\end{code}
+
+As you might expect, an `IncrList` is a list of values in *increasing* order:
+
+\begin{code}
+{-@ whatGosUp :: IncrList Integer @-}
+whatGosUp = [1,2,3]
+\end{code}
+
+Similarly, a `DecrList` contains its values in *decreasing* order:
+
+\begin{code}
+{-@ mustGoDown :: DecrList Integer @-}
+mustGoDown = [3,2,1]
+\end{code}
+
+My personal favorite though, is a `UniqList` which has *no duplicates*:
+
+\begin{code}
+{-@ noDuplicates :: UniqList Integer @-}
+noDuplicates = [1,3,2]
+\end{code}
+
+Sorting Lists
+-------------
+
+Its all very well to *specify* lists with various kinds of invariants. 
+The question is, how easy is it to *establish* these invariants?
+
+Lets find out, by turning inevitably to that staple of all forms of
+formal verification: your usual textbook sorting procedures.
+
+**Insertion Sort**
+
+First up: insertion sort. Well, no surprises here:
+
+\begin{code}
+{-@ insertSort    :: (Ord a) => xs:[a] -> (IncrList a) @-}
+insertSort []     = []
+insertSort (x:xs) = insert x (insertSort xs) 
+\end{code}
+
+The hard work is done by `insert` which places an 
+element into the correct position of a sorted list
+
+\begin{code}
+insert y []     = [y]
+insert y (x:xs) 
+  | y <= x      = y : x : xs 
+  | otherwise   = x : insert y xs
+\end{code}
+
+LiquidHaskell infers that if you give `insert` an element 
+and a sorted list, it returns a sorted list.
+
+\begin{code}
+{-@ insert :: (Ord a) => a -> IncrList a -> IncrList a @-}
+\end{code}
+
+If you prefer the more Haskelly way of writing insertion sort, 
+i.e. with a `foldr`, that works too. Can you figure out why?
+
+\begin{code}
+{-@ insertSort' :: (Ord a) => [a] -> IncrList a @-}
+insertSort' xs  = foldr insert [] xs
+\end{code}
+
+**Merge Sort**
+
+Well, you know the song goes. First, we write a function 
+that **splits** the input into two parts:
+
+\begin{code}
+split          :: [a] -> ([a], [a])
+split (x:y:zs) = (x:xs, y:ys) 
+  where 
+    (xs, ys)   = split zs
+split xs       = (xs, [])
+\end{code}
+
+Then we need a function that **merges** two (sorted) lists
+
+\begin{code}
+merge xs []         = xs
+merge [] ys         = ys
+merge (x:xs) (y:ys) 
+  | x <= y          = x : merge xs (y:ys)
+  | otherwise       = y : merge (x:xs) ys
+\end{code}
+
+LiquidHaskell deduces that if both inputs are 
+ordered, then so is the output.
+
+\begin{code}
+{-@ merge :: (Ord a) => IncrList a 
+                     -> IncrList a 
+                     -> IncrList a 
+  @-}
+\end{code}
+
+Finally, using the above functions we write `mergeSort`:
+
+\begin{code}
+{-@ mergeSort :: (Ord a) => [a] -> IncrList a @-}
+mergeSort []  = []
+mergeSort [x] = [x]
+mergeSort xs  = merge (mergeSort ys) (mergeSort zs) 
+  where 
+    (ys, zs)  = split xs
+\end{code}
+
+Lets see how LiquidHaskell proves the output type. 
+
++ The first two cases are trivial: for an empty 
+  or singleton list, we can vacuously instantiate 
+  the abstract refinement with *any* concrete 
+  refinement.
+
++ For the last case, we can inductively assume 
+ `mergeSort ys` and `mergeSort zs` are sorted 
+  lists, after which the type inferred for 
+  `merge` kicks in, allowing LiquidHaskell to conclude
+  that the output is also sorted.
+
+**Quick Sort**
+
+The previous two were remarkable because they were, well, quite *unremarkable*. 
+Pretty much the standard textbook implementations work *as is*. 
+Unlike the [classical][omega-sort] [developments][hasochism] 
+using indexed types we don't have to define any auxiliary 
+types for increasing lists, or lists whose value is in a 
+particular range, or any specialized `cons` operators and 
+so on.
+
+With *quick sort* we need to do a tiny bit of work.
+
+
+\begin{code} We would like to define `quickSort` as
+{-@ quickSort'    :: (Ord a) => [a] -> IncrList a @-}
+quickSort' []     = []
+quickSort' (x:xs) = lts ++ (x : gts) 
+  where 
+    lts           = quickSort' [y | y <- xs, y < x]
+    gts           = quickSort' [z | z <- xs, z >= x]
+\end{code}
+
+But, if you try it out, you'll see that LiquidHaskell 
+*does not approve*. What could possibly be the trouble?
+
+The problem lies with *append*. What type do we give `++`? 
+
+\begin{code} We might try something like
+(++) :: IncrList a -> IncrList a -> IncrList a
+\end{code}
+
+\begin{code} but of course, this is bogus, as 
+[1,2,4] ++ [3,5,6]
+\end{code}
+
+is decidedly not an `IncrList`!
+
+Instead, at this particular use of `++`, there is
+an extra nugget of information: there is a *pivot*
+element `x` such that every element in the first 
+argument is less than `x` and every element in 
+the second argument is greater than `x`. 
+
+There is no way we can give the usual append `++` 
+a type that reflects the above as there is no pivot 
+`x` to refer to. Thus, with a heavy heart, we must
+write a specialized pivot-append that uses this fact:
+
+\begin{code}
+pivApp piv []     ys  = piv : ys
+pivApp piv (x:xs) ys  = x   : pivApp piv xs ys
+\end{code}
+
+Now, LiquidHaskell infers that 
+
+\begin{code}
+{-@ pivApp :: piv:a 
+           -> IncrList {v:a | v <  piv} 
+           -> IncrList {v:a | v >= piv} 
+           -> IncrList a 
+  @-}
+\end{code}
+
+And we can use `pivApp` to define `quickSort' simply as:
+
+\begin{code}
+{-@ quickSort    :: (Ord a) => [a] -> IncrList a @-}
+quickSort []     = []
+quickSort (x:xs) = pivApp x lts gts 
+  where 
+    lts          = quickSort [y | y <- xs, y < x ]
+    gts          = quickSort [z | z <- xs, z >= x]
+\end{code}
+
+Really Sorting Lists
+--------------------
+
+The convenient thing about our encoding is that the 
+underlying datatype is plain Haskell lists. 
+This yields two very concrete benefits. 
+First, as mentioned before, we can manipulate 
+sorted lists with the same functions we'd use 
+for regular lists.
+Second, by decoupling (or rather, parameterizing)
+the relation or property or invariant from the actual 
+data structure we can plug in different invariants, 
+sometimes in the *same* program.
+
+To see why this is useful, lets look at a *real-world* 
+sorting algorithm: the one used inside GHC's 
+`Data.List` [module][data-list].
+
+\begin{code}
+sort :: (Ord a) => [a] -> [a]
+sort = mergeAll . sequences
+  where
+    sequences (a:b:xs)
+      | a `compare` b == GT = descending b [a]  xs
+      | otherwise           = ascending  b (a:) xs
+    sequences [x] = [[x]]
+    sequences []  = [[]]
+
+    descending a as (b:bs)
+      | a `compare` b == GT = descending b (a:as) bs
+    descending a as bs      = (a:as): sequences bs
+
+    ascending a as (b:bs)
+      | a `compare` b /= GT = ascending b (\ys -> as (a:ys)) bs
+    ascending a as bs       = as [a]: sequences bs
+
+    mergeAll [x] = x
+    mergeAll xs  = mergeAll (mergePairs xs)
+
+    mergePairs (a:b:xs) = merge a b: mergePairs xs
+    mergePairs [x]      = [x]
+    mergePairs []       = []
+\end{code}
+
+The interesting thing about the procedure is that it 
+generates some intermediate lists that are increasing 
+*and* others that are decreasing, and then somehow
+miraculously whips this whirlygig into a single 
+increasing list.
+
+Yet, to check this rather tricky algorithm with 
+LiquidHaskell we need merely write:
+
+\begin{code}
+{-@ sort :: (Ord a) => [a] -> IncrList a  @-}
+\end{code}
+
+
+
+[blog-absref]:     /blog/2013/06/3/abstracting-over-refinements.lhs/
+[blog-absref-vec]: http://goto.ucsd.edu/~rjhala/liquid/abstract_refinement_types.pdf
+[data-list]:        http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html#sort
+[omega-sort]:      http://web.cecs.pdx.edu/~sheard/Code/InsertMergeSort.html
+[hasochism]:       https://personal.cis.strath.ac.uk/conor.mcbride/pub/hasochism.pdf
+
diff --git a/docs/blog/2013-11-23-telling_lies.lhs b/docs/blog/2013-11-23-telling_lies.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-11-23-telling_lies.lhs
@@ -0,0 +1,128 @@
+---
+layout: post
+title: "LiquidHaskell Caught Telling Lies!"
+date: 2013-11-23 16:12
+comments: true
+external-url:
+categories: termination
+author: Ranjit Jhala, Niki Vazou 
+published: true
+demo: TellingLies.hs
+---
+
+One crucial goal of a type system is to provide the guarantee, 
+memorably phrased by Milner as *well-typed programs don't go wrong*. 
+The whole point of LiquidHaskell (and related systems) is to provide
+the above guarantee for expanded notions of "going wrong". 
+All this time, we've claimed (and believed) that LiquidHaskell 
+provided such a guarantee.
+
+We were wrong. 
+
+LiquidHaskell tells lies.
+
+<!-- more -->
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+
+module TellingLies where
+
+import Language.Haskell.Liquid.Prelude (liquidError)
+
+divide  :: Int -> Int -> Int
+foo     :: Int -> Int
+explode :: Int
+\end{code}
+
+To catch LiquidHaskell red-handed, we require
+
+1. a notion of **going wrong**,
+2. a **program** that clearly goes wrong, and the smoking gun,
+3. a **lie** from LiquidHaskell that the program is safe.
+
+The Going Wrong
+---------------
+
+Lets keep things simple with an old fashioned `div`-ision operator.
+A division by zero would be, clearly *going wrong*.
+
+To alert LiquidHaskell to this possibility, we encode "not going wrong"
+with the precondition that the denominator be  non-zero.
+
+\begin{code}
+{-@ divide :: n:Int -> d:{v:Int | v /= 0} -> Int @-}
+divide n 0 = liquidError "no you didn't!"
+divide n d = n `div` d
+\end{code}
+
+The Program 
+-----------
+
+Now, consider the function `foo`.
+
+\begin{code}
+{-@ foo :: n:Int -> {v:Nat | v < n} @-}
+foo n | n > 0     = n - 1
+      | otherwise = foo n
+\end{code}
+
+Now, `foo` should only be called with strictly positive values. 
+In which case, the function returns a `Nat` that is strictly 
+smaller than the input. 
+The function diverges when called with `0` or negative inputs. 
+
+Note that the signature of `foo` is slightly different, but 
+nevertheless, legitimate, as *when* the function returns an 
+output, the output is indeed a `Nat` that is *strictly less than* 
+the input parameter `n`. Hence, LiquidHaskell happily checks 
+that `foo` does indeed satisfy its given type.
+
+So far, nothing has gone wrong either in the program, or 
+with LiquidHaskell, but consider this innocent little 
+function:
+
+\begin{code}
+explode = let z = 0
+          in  (\x -> (2013 `divide` z)) (foo z)
+\end{code}
+
+Thanks to *lazy evaluation*, the call to `foo` is ignored,
+and hence evaluating `explode` leads to a crash! Ugh!
+
+The Lie
+-------
+
+However, LiquidHaskell produces a polyannish prognosis and 
+cheerfully declares the program *safe*. 
+
+Huh?
+
+Well, LiquidHaskell deduces that
+
+a. `z == 0`  from the binding,
+b. `x : Nat` from the output type for `foo`
+c. `x <  z`  from the output type for `foo`
+
+\begin{code} Of course, no such `x` exists! Or, rather, the SMT solver reasons
+    z == 0 && x >= 0 && x < z  => z /= 0
+\end{code}
+
+as the hypotheses are inconsistent. In other words, LiquidHaskell 
+deduces that the call to `divide` happens in an *impossible* environment,
+i.e. is dead code, and hence, the program is safe.
+
+In our defence, the above, sunny prognosis is not *totally misguided*. 
+Indeed, if Haskell was like ML and had *strict evaluation* then 
+indeed the program would be safe in that we would *not* go wrong 
+i.e. would not crash with a divide-by-zero.  
+
+But of course, thats a pretty lame excuse, since Haskell doesn't have 
+strict semantics. So looks like LiquidHaskell (and hence, we) 
+have been caught red-handed.
+
+Well then, is there a way to prevent LiquidHaskell from telling lies?
+That is, can we get Milner's *well-typed programs don't go wrong* 
+guarantee under lazy evaluation? 
+
+Thankfully, there is.
diff --git a/docs/blog/2013-12-01-getting-to-the-bottom.lhs b/docs/blog/2013-12-01-getting-to-the-bottom.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-12-01-getting-to-the-bottom.lhs
@@ -0,0 +1,103 @@
+---
+layout: post
+title: "Getting To the Bottom of The Lies"
+date: 2013-12-01 16:12
+comments: true
+external-url:
+categories: termination
+author: Ranjit Jhala, Niki Vazou
+published: true
+demo: BasicTermination.hs
+---
+
+[Previously][ref-lies], we caught LiquidHaskell telling a lie. Today, lets try to
+get to the bottom of this mendacity, in order to understand how we can ensure
+that it always tells the truth.
+
+<!-- more -->
+
+\begin{code}
+module GettingToTheBottom where
+\end{code}
+The Truth Lies At the Bottom
+----------------------------
+
+To figure out how we might prevent such mendacity, lets try to understand 
+whats really going on. We need to go back to the beginning.
+
+\begin{code} Recall that the refinement type:
+{v:Int | 0 <= v}
+\end{code}
+
+is supposed to denote the set of `Int` values that are greater than `0`.
+
+\begin{code} Consider a function:
+fib :: {n:Int | 0 <= n} -> {v:Int | 0 <= v}
+fib n = e
+\end{code}
+
+Intuitively, the type signature states that when checking the body `e` 
+we can **assume** that `0 <= n`. 
+
+This is indeed the case with **strict** evaluation, as we are guaranteed 
+that `n` will be evaluated before `e`. Thus, either:
+
+1. `n` diverges and so we don't care about `e` as we won't evaluate it, or,
+2. `n` is a non-negative value.
+
+Thus, either way, `e` is only evaluated in a context where `0 <= n`.
+
+But of course, this is not the case with **lazy** evaluation, as we may 
+well start evaluating `e` without evaluating `n`. Indeed, we may *finish*
+evaluating `e` without evaluating `n`. 
+
+Now of course, we know that *if* `n` is evaluated, it will yield a 
+non-negative value, but if it is not (or does not) evaluate to a
+value, we **cannot assume** that the rest of the computation is dead 
+(as with eager evaluation). 
+
+\begin{code} Thus, really with lazy evaluation, the refinement type `{n:Int | 0 <= n}` *actually* means:
+(n = _|_) || (0 <= n)
+\end{code}
+
+Keeping LiquidHaskell Honest
+----------------------------
+
+One approach to forcing LiquidHaskell to telling the truth is to force 
+it to *always* split cases and reason about `_|_`.
+
+\begin{code} Lets revisit `explode`
+explode = let z = 0
+          in  (\x -> 2013 `divide` z) (foo z)
+\end{code}
+
+\begin{code}This prevents the cheerful but bogus prognosis that `explode` above was safe, because the SMT solver cannot prove that at the call to `divide` 
+    z == 0 && (x = _|_ || (x >= 0 && x < z))  => z /= 0
+\end{code}
+
+PIC: PESSIMISTIC-ALWAYS-NO
+
+But alas, this cure is worse than the disease. Effectively it would end up
+lobotomizing LiquidHaskell making it unable to prove even trivial things like:
+
+\begin{code}_
+{-@ trivial    :: x:Int -> y:Int -> {pf: () | x < y} -> Int @-}
+trivial x y pf = liquidAssert (x < y) 10
+\end{code}
+
+\begin{code}as the corresponding SMT query
+    (pf = _|_ || x < y) => (x < y)
+\end{code}
+
+is, thanks to the pesky `_|_`, not valid. 
+
+Terminating The Bottom
+----------------------
+
+Thus, to make LiquidHaskell tell the truth while also not just pessimistically 
+rejecting perfectly good programs, we need a way to get rid of the `_|_`. That 
+is, we require a means of teaching LiquidHaskell to determine when a value
+is *definitely* not bottom. 
+
+In other words, we need to teach LiquidHaskell how to prove that a computation 
+definitely terminates.
diff --git a/docs/blog/2013-12-02-getting-to-the-bottom.lhs b/docs/blog/2013-12-02-getting-to-the-bottom.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-12-02-getting-to-the-bottom.lhs
@@ -0,0 +1,103 @@
+---
+layout: post
+title: "Getting To the Bottom"
+date: 2013-12-02 16:12
+comments: true
+external-url:
+categories: termination
+author: Ranjit Jhala, Niki Vazou
+published: true 
+demo: TellingLies.hs
+---
+
+[Previously][ref-lies], we caught LiquidHaskell telling a lie. Today, lets try to
+get to the bottom of this mendacity, in order to understand how we can ensure
+that it always tells the truth.
+
+<!-- more -->
+
+\begin{code}
+module GettingToTheBottom where
+\end{code}
+
+The Truth Lies At the Bottom
+----------------------------
+
+To figure out how we might prevent falsehoods, lets try to understand 
+whats really going on. We need to go back to the beginning.
+
+\begin{code} Recall that the refinement type:
+{v:Int | 0 <= v}
+\end{code}
+
+is supposed to denote the set of `Int` values that are greater than `0`.
+
+\begin{code} Consider a function:
+fib :: {n:Int | 0 <= n} -> {v:Int | 0 <= v}
+fib n = e
+\end{code}
+
+Intuitively, the type signature states that when checking the body `e` 
+we can **assume** that `0 <= n`. 
+
+This is indeed the case with **strict** evaluation, as we are guaranteed 
+that `n` will be evaluated before `e`. Thus, either:
+
+1. `n` diverges and so we don't care about `e` as we won't evaluate it, or,
+2. `n` is a non-negative value.
+
+Thus, either way, `e` is only evaluated in a context where `0 <= n`.
+
+But this is *not* the case with **lazy** evaluation, as we may 
+well start evaluating `e` without evaluating `n`. Indeed, we may
+*finish* evaluating `e` without evaluating `n`. 
+
+Of course, *if* `n` is evaluated, it will yield a non-negative value, 
+but if it is not (or does not) evaluate to a value, we **cannot assume** 
+that the rest of the computation is dead (as with eager evaluation). 
+
+\begin{code} That is, with lazy evaluation, the refinement type `{n:Int | 0 <= n}` *actually* means:
+(n = _|_) || (0 <= n)
+\end{code}
+
+Keeping LiquidHaskell Honest
+----------------------------
+
+One approach to forcing LiquidHaskell to telling the truth is to force 
+it to *always* split cases and reason about `_|_`.
+
+\begin{code} Lets revisit `explode`
+explode = let z = 0
+          in  (\x -> 2013 `divide` z) (foo z)
+\end{code}
+
+\begin{code}The case splitting prevents the cheerful but bogus prognosis that `explode` above was safe, because the SMT solver cannot prove that at the call to `divide` 
+    z == 0 && (x = _|_ || (x >= 0 && x < z))  => z /= 0
+\end{code}
+
+But alas, this cure is worse than the disease. 
+It would end up lobotomizing LiquidHaskell making it unable to prove even trivial things like:
+
+\begin{code}_
+{-@ trivial    :: x:Int -> y:Int -> {pf: () | x < y} -> Int @-}
+trivial x y pf = liquidAssert (x < y) 10
+\end{code}
+
+\begin{code}as the corresponding SMT query
+    (pf = _|_ || x < y) => (x < y)
+\end{code}
+
+is, thanks to the pesky `_|_`, not valid. 
+
+Terminating The Bottom
+----------------------
+
+Thus, to make LiquidHaskell tell the truth while also not just pessimistically 
+rejecting perfectly good programs, we need a way to get rid of the `_|_`. That 
+is, we require a means of teaching LiquidHaskell to determine when a value
+is *definitely* not bottom. 
+
+In other words, we need to teach LiquidHaskell how to prove that a computation 
+definitely terminates.
+
+[ref-lies]:  /blog/2013/11/23/telling_lies.lhs/ 
diff --git a/docs/blog/2013-12-09-checking-termination.lhs b/docs/blog/2013-12-09-checking-termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-12-09-checking-termination.lhs
@@ -0,0 +1,173 @@
+---
+layout: post
+title: "Checking Termination"
+date: 2013-12-09 16:12
+comments: true
+external-url:
+categories: termination
+author: Niki Vazou
+published: true 
+demo: Termination.hs
+---
+
+As explained in the [last][ref-lies] [two][ref-bottom] posts, we need a termination
+checker to ensure that LiquidHaskell is not tricked by divergent, lazy
+computations into telling lies. Happily, it turns out that with very 
+little retrofitting, and a bit of jiu jitsu, we can use refinements 
+themselves to prove termination!
+
+<!-- more -->
+
+<div class="row-fluid">
+   <div class="span12 pagination-centered">
+       <img src="http://img.dailymail.co.uk/i/pix/2007/06_01/TombstoneSWNS_468x526.jpg"
+       alt="Falling Down" width="300">
+       <br>
+       <br>
+       <br>
+       How do you prove this fellow will <b>stop falling?</b>
+       <br>
+       <br>
+       <br>
+   </div>
+</div>
+
+
+
+\begin{code}
+module Termination where
+
+import Prelude     hiding (sum)
+import Data.Vector hiding (sum)
+\end{code}
+
+Lets first see how LiquidHaskell proves termination on simple 
+recursive functions, and then later, we'll see how to look at 
+fancier cases.
+
+Looping Over Vectors
+--------------------
+
+Lets write a bunch of little functions that operate on 1-dimensional vectors
+
+\begin{code}
+type Val = Int
+type Vec = Vector Val
+\end{code}
+
+Next, lets write a simple recursive function that loops over to add up
+the first `n` elements of a vector:
+
+\begin{code}
+sum     :: Vec -> Int -> Val
+sum a 0 = 0
+sum a n = (a ! (n-1)) + sum a (n-1)
+\end{code}
+
+Proving Termination By Hand(waving) 
+-----------------------------------
+
+Does `sum` terminate? 
+
+First off, it is apparent that if we call `sum` with a
+negative `n` then it **will not** terminate. 
+Thus, we should only call `sum` with non-negative integers.
+
+Fine, lets assume `n` is non-negative. Why then does it terminate?
+
+Intuitively,
+
+1. If `n` is `0` then it trivially returns with the value `0`.
+
+2. If `n` is non-zero, then we recurse *but* with a strictly smaller `n` ...
+
+3. ... but ultimately hit `0` at which point it terminates.
+
+Thus we can, somewhat more formally, prove termination by induction on `n`. 
+
+**Base Case** `n == 0` The function clearly terminates for the base case input of `0`.
+
+**Inductive Hypothesis** Lets assume that `sum` terminates on all `0 <= k < n`.
+
+**Inductive Step** Prove that `sum n` only recursively invokes `sum` with values that
+satisfy the inductive hypothesis and hence, which terminate.
+
+This reasoning suffices to convince ourselves that `sum i` terminates for 
+every natural number `i`. That is, we have shown that `sum` terminates 
+because a *well-founded metric* (i.e., the natural number `i`) is decreasing 
+at each recursive call.
+
+Proving Termination By Types
+----------------------------
+
+We can teach LiquidHaskell to prove termination by applying the same reasoning 
+as above, by rephrasing it in terms of refinement types.
+
+First, we specify that the input is restricted to the set of `Nat`ural numbers
+
+\begin{code}
+{-@ sum :: a:Vec -> {v:Nat | v < (vlen a)} -> Val @-}
+\end{code}
+
+where recall that `Nat` is just the refinement type `{v:Int | v >= 0}`.
+
+Second, we typecheck the *body* of `sum` under an environment that
+restricts `sum` to only be called on inputs less than `n`, i.e. using
+an environment:
+
+-  `a   :: Vec`
+-  `n   :: Nat`
+-  `sum :: Vec -> n':{v:Nat | v < n} -> Val`
+
+This ensures that any (recursive) call in the body only calls `sum` 
+with inputs smaller than the current parameter `n`. Since its body 
+typechecks in this environment, i.e. `sum` is called with `n-1` which 
+is smaller than `n` and, in this case, a `Nat`, LiquidHaskell proves 
+that sum terminates for all `n`.
+
+For those keeping track at home, this is the technique of 
+[sized types](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.124.5589), 
+, expressed using refinements. Sized types themselves are an instance of 
+the classical method of proving termination via well founded metrics that 
+goes back, at least, to [Turing](http://www.turingarchive.org/viewer/?id=462&title=01b).
+
+Choosing the Correct Argument
+-----------------------------
+
+The example above is quite straightforward, and you might well wonder if this
+method works well for ``real-world" programs. With a few generalizations
+and extensions, and by judiciously using the wealth of information captured in
+refinement types, the answer is an emphatic, yes!
+
+Lets see one extension today.
+
+We saw that liquidHaskell can happily check that some Natural number is decreasing
+at each iteration, but it uses a na&#239;ve heuristic to choose which one -- for
+now, assume that it always chooses *the first* `Int` parameter.
+
+As you might imagine, this is quite simpleminded. 
+
+Consider, a tail-recursive implementation of `sum`:
+
+\begin{code}
+{-@ sum' :: a:Vec -> Val -> {v:Nat| v < (vlen a)} -> Val @-}
+sum' :: Vec -> Val -> Int -> Val
+sum' a acc 0 = acc + a!0 
+sum' a acc n = sum' a (acc + a!n) (n-1)
+\end{code}
+
+Clearly, the proof fails as liquidHaskell wants to prove that the `acc`umulator 
+is a `Nat`ural number that decreases at each iteration, neither of which may be
+true.
+
+\begin{code}The remedy is easy. We can point liquidHaskell to the correct argument `n` using a `Decrease` annotation: 
+{-@ Decrease sum' 3 @-}
+\end{code}
+which directs liquidHaskell to verify that the *third* argument (i.e., `n`) is decreasing. 
+With this hint, liquidHaskell will happily verify that `sum'` is indeed a terminating function.
+
+Thats all for now, next time we'll see how the basic technique can be extended
+to a variety of real-world settings.
+
+[ref-lies]:  /blog/2013/11/23/telling-lies.lhs/ 
+[ref-bottom]: /blog/2013/12/01/getting-to-the-bottom.lhs/
diff --git a/docs/blog/2013-12-14-gcd.lhs b/docs/blog/2013-12-14-gcd.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-12-14-gcd.lhs
@@ -0,0 +1,110 @@
+---
+layout: post
+title: "Termination Requires Refinements"
+date: 2013-12-14 16:12
+comments: true
+external-url:
+categories: termination 
+author: Niki Vazou
+published: true 
+demo: GCD.hs
+---
+
+We've seen how, in the presence of [lazy evaluation][ref-lies], refinements
+[require termination][ref-bottom]. [Next][ref-termination], we saw how 
+LiquidHaskell can be used to prove termination. 
+
+Today, lets see how **termination requires refinements**. 
+
+That is, a crucial feature of LiquidHaskell's termination prover is that it is 
+not syntactically driven, i.e. is not limited to say, structural recursion. 
+Instead, it uses the wealth of information captured by refinements that are
+at our disposal, in order to prove termination. 
+
+This turns out to be crucial in practice.
+As a quick toy example -- motivated by a question by [Elias][comment-elias] -- 
+lets see how, unlike purely syntax-directed (structural) approaches, 
+LiquidHaskell proves that recursive functions, such as Euclid's GCD 
+algorithm, terminates.
+
+<!-- more -->
+
+<br>
+<br>
+<br>
+
+<div class="row-fluid">
+  <div class="span12 pagination-centered">
+  <img src="http://faculty.etsu.edu/gardnerr/Geometry-History/Euclid_7-Raphael.jpg"
+       alt="Euclid" width="300">
+       <br>
+       <br>
+       <br>
+       With LiquidHaskell, Euclid wouldn't have had to wave his hands.
+       <br>
+       <br>
+       <br>
+  </div>
+</div>
+
+\begin{code}
+module GCD where
+
+import Prelude hiding (gcd, mod)
+
+mod :: Int -> Int -> Int
+gcd :: Int -> Int -> Int
+\end{code}
+
+The [Euclidean algorithm][ref-euclidean] is one of the oldest numerical algorithms 
+still in common use and calculates the the greatest common divisor (GCD) of two 
+natural numbers `a` and `b`.
+
+Assume that `a > b` and consider the following implementation of `gcd`
+
+\begin{code}
+{-@ gcd :: a:Nat -> b:{v:Nat | v < a} -> Int @-}
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+\end{code}
+
+From our previous post, to prove that `gcd` is terminating, it suffices to prove
+that the first argument decreases as each recursive call.
+
+By `gcd`'s type signature, `a < b` holds at each iteration, thus liquidHaskell 
+will happily discharge the terminating condition.
+
+The only condition left to prove is that `gcd`'s second argument, ie., `a `mod`
+b` is less that `b`. 
+
+This property follows from the behavior of the `mod` operator.
+
+So, to prove `gcd` terminating, liquidHaskell needs a refined signature for 
+`mod` that captures this behavior, i.e., that for any `a` and `b` the value 
+`mod a b` is less than `b`. Fortunately, we can stipulate this via a refined
+type:
+
+\begin{code}
+{-@ mod :: a:Nat -> b:{v:Nat| 0 < v} -> {v:Nat | v < b} @-}
+mod a b
+  | a < b = a
+  | otherwise = mod (a - b) b
+\end{code}
+
+\begin{code}Euclid's original version of `gcd` is different
+gcd' :: Int -> Int -> Int
+gcd' a b | a == b = a
+         | a >  b = gcd' (a - b) b 
+         | a <  b = gcd' a (b - a) 
+\end{code}
+
+Though this version is simpler, turns out that LiquidHaskell needs 
+a more sophisticated mechanism, called **lexicographic ordering**, to 
+prove it terminates. Stay tuned!
+
+
+[ref-euclidean]:    http://en.wikipedia.org/wiki/Euclidean_algorithm
+[ref-termination]:  /blog/2013/12/09/checking-termination.lhs/ 
+[ref-lies]:  /blog/2013/11/23/telling-lies.lhs/ 
+[ref-bottom]: /blog/2013/12/01/getting-to-the-bottom.lhs/
+[comment-elias]: http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/blog/2013/12/09/checking-termination.lhs/#comment-1159606500
diff --git a/docs/blog/2013-12-22-measuring-the-size-of-structures.lhs b/docs/blog/2013-12-22-measuring-the-size-of-structures.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-12-22-measuring-the-size-of-structures.lhs
@@ -0,0 +1,184 @@
+---
+layout: post
+title: "Measuring the size of Structures"
+date: 2013-12-22 16:12
+comments: false
+external-url:
+categories: termination, measures
+author: Niki Vazou
+published: false
+demo: TheSizeOfStructures.hs
+---
+
+In the [previous][ref-termination] [two][ref-lexicographic] posts we saw how refinements can be used to prove
+termination. 
+In both posts functions recurse on integers.
+In Haskell the most common type of recursion is over recursive data structures.
+
+Today lets see how to prove termination on functions defined over
+recursive data structures.
+
+<!-- more -->
+
+\begin{code}
+module TheSizeOfStructures where
+
+import Prelude hiding (map)
+\end{code}
+
+Does list map Terminate?
+------------------------
+
+Lets define a `List` structure
+
+\begin{code}
+infixr `C`
+data List a = N | C a (List a)
+\end{code}
+
+and a map function `lmap` on it
+
+\begin{code}
+lmap              :: (a -> b) -> (List a) -> (List b)
+lmap _ N          = N
+lmap f (x `C` xs) = f x `C` lmap f xs
+\end{code}
+
+Does `lmap` terminate?
+
+At each iteration `lmap` is called with the tail of the input list.
+So, the *length* of the list is decreasing at each iteration
+and 
+if the input list is finite, its length will reach `0` and `lmap` will terminate.
+
+Since the length of the list is a natural number, it is
+a *well-founded metric*.
+
+From the [previous][ref-lexicographic] [two][ref-termination] posts a
+well-founded metric that decreases at each iteration is all
+liquidHaskell needs to prove termination on a recursive function.
+
+Two things are left to do: teach liquidHaskell to
+
+1. compute the length of a List
+
+2. use this length as the decreasing metric that decreases in `lmap`.
+
+
+Express Termination Metric
+--------------------------
+
+First things first,
+we need to teach liquidHaskell to compute the length of the list.
+
+Remember *measures*?
+They were introduced in a [previous][ref-measure] post and in short measures
+provide a mechanism to define auxiliary properties on data
+values.
+
+Now we can define a measure `llen` than maps a list to its length:
+\begin{code}
+{-@ measure llen  :: (List a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)
+  @-}
+\end{code}
+
+
+and then, inform liquidHaskell that this measure is *well-formed*, ie., cannot
+be negative:
+
+\begin{code}
+{-@ invariant {v:(List a) | (llen v) >= 0}@-}
+\end{code}
+
+
+Relate List with its length
+---------------------------
+
+The final step towards verification of `lmap`'s termination is to relate the List
+structure with its length `llen`.
+We can do this with the usual `data` annotation
+
+\begin{code}
+{-@ data List [llen] @-}
+\end{code}
+
+that informs the tool that `llen` measures the size of a list. 
+So each time the termination checker checks if a list is decreasing, it
+checks if its *default* size `llen` decreases. 
+
+
+Choosing the correct argument
+-----------------------------
+
+To prove termination liquidHaskell chooses one argument and tries to prove that
+is decreasing.
+But which argument? 
+It chooses the first one for which decreasing information exists.
+We have that for an integer to decrease its value should decrease 
+and we specified that a list decreases if its length `llen` decreases.
+
+In `lmap` there is no decreasing information for the function `f`, 
+so liquidHaskell will correclty guess that the list argument (ie., the second
+argument) should be
+decreasing.
+
+In a function that many arguments with decreasing information exist,
+liquidHaskell will na&#239;vely choose the first one.
+
+As an example, the following `posSum` function could not be proven to terminate
+without our `Decrease` hint.
+
+\begin{code}
+{-@ Decrease posSum 2 @-}
+posSum                            :: Int -> (List Int) -> Int
+posSum acc N                      = acc
+posSum acc (x `C` xs) | x > 0     = posSum (acc + x) xs
+                      | otherwise = posSum (acc)     xs
+\end{code}
+
+Standard lists
+--------------
+You may think that all this is much work to prove that a function on a recursive
+structure is terminating.
+You have to both define the size of the structure and relate it with the
+structure.
+The good news is that this work is just performed once!
+
+Even better, for structures like standard lists liquidHaskell has done all this
+work for you!
+
+
+\begin{code} The standard list `[a]` comes with the build in measure 'len', defined as
+ measure len :: [a] -> Int
+ len ([])   = 1
+ len (x:xs) = 1 + (len xs)
+\end{code}
+
+Thus liquidHaskell will just prove that functions recursive on standard lists
+shall terminate:
+
+\begin{code}
+map          :: (a -> b) -> [a] -> [b]
+map _ []     = []
+map f (x:xs) = f x : map f xs
+\end{code}
+
+Today we shaw how to prove termination on functions recursive over a data
+structure.
+You need to 
+
+1. define the size of the structure
+
+2. associate this size with the structure.
+
+In the next post, 
+we shall see our final mechanism to prove termination: *decreasing expressions*
+Stay tuned!
+
+[ref-measure]:       /blog/2013/01/31/sately-catching-a-list-by-its-tails.lhs/
+[ref-lies]:          /blog/2013/11/23/telling-lies.lhs/ 
+[ref-bottom]:        /blog/2013/12/01/getting-to-the-bottom.lhs/
+[ref-termination]:   /blog/2013/12/08/termination-checking.lhs/
+[ref-lexicographic]: /blog/2013/12/15/lexicographic-termination.lhs/
diff --git a/docs/blog/2013-12-24-lexicographic-termination.lhs b/docs/blog/2013-12-24-lexicographic-termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-12-24-lexicographic-termination.lhs
@@ -0,0 +1,125 @@
+---
+layout: post
+title: "Lexicographic Termination"
+date: 2013-12-15 16:12
+comments: true
+external-url:
+categories: termination, lexicographic ordering
+author: Niki Vazou
+published: true 
+demo: LexicographicTermination.hs
+---
+
+[Previously][ref-termination] we saw how refinements can be used to prove termination
+and we promised to extend our termination checker to handle "real-word" programs.
+
+Keeping our promise, today we shall see a trick that allows liquidHaskell to prove termination on
+more recursive functions, namely *lexicographic termination*.
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+module LexicographicTermination where
+
+import Language.Haskell.Liquid.Prelude (liquidError)
+\end{code}
+
+</div>
+
+Does Ackermann Function Terminate?
+----------------------------------
+
+Consider the famous [Ackermann
+function](http://en.wikipedia.org/wiki/Ackermann_function)
+
+\begin{code}
+{-@ ack :: m:Nat -> n:Nat -> Nat @-}
+ack :: Int -> Int -> Int
+ack m n
+    | m == 0          = n + 1
+    | m > 0 && n == 0 = ack (m-1) 1
+    | m > 0 && n >  0 = ack (m-1) (ack m (n-1))
+    | otherwise       = liquidError "Bad arguments!!!"
+\end{code}
+
+Does `ack` terminate?
+
+At each iteration
+
+1. Either `m` decreases, 
+
+2. or `m` remains the same and `n` decreases.
+
+Each time that `n` reaches `0`, `m` decreases, so `m` will
+eventaully reach `0` and `ack` will terminate.
+
+Expressed more technically the pair `(m, n)`
+decreases in the [lexicographic order](htpp://en.wikipedia/wiki/Lexicographic_order)
+on pairs, which is a well-ordering, ie.,
+we cannot go down infinitely many times.
+
+Express Termination Metric
+--------------------------
+
+Great! The pair `(m, n)` is a *well-founded metric* on the Ackermann function that decreases.
+From the [previous post][ref-termination] a well-founded metric is all
+liquidHaskell needs to prove termination.
+So, we should feed the tool with this information.
+
+Remember the `Decrease` token?
+We used it [previously][ref-termination]
+to specify which is the decreasing argument.
+Now, we will use it with more arguments to specify 
+our decreasing pair. So,
+
+\begin{code}
+{-@ Decrease ack 1 2 @-}
+\end{code}
+
+says that the decreasing metric is the pair of the first
+and the second arguments, 
+ie., the pair `(m, n)`.
+
+Finally, we will see how liquidHaskell uses this annotation to prove
+termination.
+
+Proving Termination By Types
+----------------------------
+
+Following once more our [previous post][ref-termination],
+liquidHaskell typechecks the *body* of `ack` under an environment that
+restricts `ack` to only be called on inputs *less than* `(m,n)`.
+This time "less than" referes not to ordering on natural numbers, but to lexicographic
+ordering
+, i.e., using
+an environment:
+
+-  `m   :: Nat`
+-  `n   :: Nat`
+-  `ack :: m':Nat -> n':{v:Nat | m' < m || (m' = m && v < n)} -> Nat`
+
+This ensures that any (recursive) call in the body only calls `ack` 
+with inputs smaller than the current parameter `(m, n)`. Since its body 
+typechecks in this environment, i.e. `ack` is called with smaller parameters, LiquidHaskell proves 
+that `ack` terminates.
+
+
+Someone may find the `Decrease` token annoying:
+if we insert another argument we should also update the decrease information.
+LiquidHaskell supports an alternative notation, 
+which lets you annotate the type signature 
+with a list of *decreasing expressions*.
+
+\begin{code} So, `ack` will also typecheck against the signature:
+{-@ ack :: m:Nat -> n:Nat -> Nat / [m, n] @-}
+\end{code}
+
+But what is the syntax of the decreasing expressions?
+Are they restricted to function parameters?
+No, but that is the subject of a next post!
+
+[ref-lies]:        /blog/2013/11/23/telling-lies.lhs/ 
+[ref-bottom]:      /blog/2013/12/01/getting-to-the-bottom.lhs/
+[ref-termination]: /blog/2013/12/08/termination-checking.lhs/
diff --git a/docs/blog/2013-12-29-decreasing-expressions.lhs b/docs/blog/2013-12-29-decreasing-expressions.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2013-12-29-decreasing-expressions.lhs
@@ -0,0 +1,153 @@
+---
+layout: post
+title: "Decreasing Expressions"
+date: 2013-12-29 16:12
+comments: true
+external-url:
+categories: termination, measures
+author: Niki Vazou
+published: false
+demo: DecreasingExpressions.hs
+---
+
+So far we proved that many recursive functions terminate.
+All the functions we used share a characteristic.
+They had (a list of) arguments that were (lexicographically) decreasing.
+
+What if no argument decreases?
+Consider an argument `i` that increases up to a higher value `hi`.
+As `i` increases the difference `hi - i` decreases and will eventually reach
+`0`.
+This difference "witnesses" termination.
+
+Today we will describe 
+the last mechanism liquidHaskell uses to prove termination:
+*decreasing expressions*
+that allow us to annotate functions with termination withnesses.
+
+<!-- more -->
+
+\begin{code}
+module DecreasingExpressions where
+
+range ::          Int -> Int -> [Int]
+merge :: Ord a => [a] -> [a] -> [a]
+\end{code}
+
+Termination on Increasing Arguments
+-----------------------------------
+
+Consider a `range` function that takes two integers 
+a `lo`wer and a `hi`gher and returns the list `[lo, lo+1, ..., hi-1]`
+
+\begin{code}
+range lo hi | lo < hi   = lo : range (lo + 1) hi
+            | otherwise = []
+\end{code}
+
+Clearly the difference `hi - lo` is decreasing at each iteration and will
+eventually reach `0`.
+That is, `hi - lo` is a *well-founded metric* that decreases.
+[Previously][ref-termination] we discussed that this is exactly what 
+liquidHaksell needs to prove termination.
+
+Sadly, liquidHaskell cannot synthesize this metric.
+But provides a mechanism for the user to specify it.
+With *decreasing expressions*, 
+we can annotate the type of a recursive function
+with the termination witness. Thus
+
+\begin{code}
+{-@ range :: lo:Int -> hi:Int -> [Int] / [(hi - lo)] @-}
+\end{code}
+
+makes liquidHaskell 
+prove that `hi - lo` is a non-negative quantily that decreases at
+each iteration, 
+
+Termination on a Function of the Arguments
+------------------------------------------
+
+Lets illustrate the power of decreasing expressions with a more involved
+example.
+
+Consider the standard `merge` from the homonymous sorting function 
+
+\begin{code}
+merge (x:xs) (y:ys) 
+  | x < y     = x : merge xs     (y:ys)
+  | otherwise = y : merge (x:xs) ys
+\end{code}
+
+Does `merge` terminate?
+Well it does because at each iteration the sum of the lengths of the two
+arguments decreases. 
+Using liquidHaskell's build in [measure][ref-measure] `len`
+to get the length of a list, we can specify 
+`(len xs) + (len ys)`
+as the decreasing expression for `merge`
+
+\begin{code}_
+{-@ merge :: Ord a => xs:[a] -> ys:[a] -> [a] / [(len xs) + (len ys)] @-}
+\end{code}
+
+
+By the way, the power of liquidHaskell does not stop at proving `merge`
+terminating. 
+It extends to proving that given two sorted lists, `merge` will actually return
+a sorted list!
+
+[Some time ago][ref-slist], we represented Sorted Lists as
+\begin{code}
+{-@ type SL a = [a]<{\x v -> x <= v}> @-}
+\end{code}
+
+With this, all we need to prove that sortedness is preserved is to type `merge`
+as
+\begin{code}
+{-@ merge :: Ord a => xs:(SL a) -> ys:(SL a) -> (SL a) 
+           / [(len xs) + (len ys)]                                    @-}
+\end{code}
+
+
+Wrapping Up Termination Checking
+--------------------------------
+
+In the last couple of posts, we presented the mechanisms liquidHaskell uses to
+prove termination
+
+- We [started][ref-termination] with functions recursive on some natural namber
+  `i` that served as a decreasing metric to prove termination.
+
+- [Then][ref-lex], we used lexicographic ordering to prove termination on functions where
+  the decreasing metric constists of a list of arguments.
+
+- [After][ref-structures], we saw how to handle recursion on data structures: by proving the size of
+  this structure is decreasing, and
+
+- Today, we saw how to express more complicated decreasing metrics.
+
+Obviously liquidHaskell does not solve the halting problem: there do exist
+terminating functions that cannot be proven terminating.
+Worse, there do exist some cases of non-terminating functions tha fool
+liquidHaskell: 
+for instance, you can trick the tool 
+if you encode termination via [recursive types][ref-rec] or
+[references][ref-ref].
+We aim to soon address such corner cases.
+
+We claim that the above mechanisms suffice to prove 
+termination on numerous functions.
+Even *mutually recursive* ones, as we shall soon see.
+
+
+
+[ref-ref]:          https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/todo/Recursion1.hs
+[ref-rec]:          http://en.wikipedia.org/wiki/Fixed-point_combinator#Example_of_encoding_via_recursive_types 
+[ref-lies]:        /blog/2013/11/23/telling-lies.lhs/ 
+[ref-bottom]:      /blog/2013/12/01/getting-to-the-bottom.lhs/
+[ref-termination]: /blog/2013/12/08/termination-checking.lhs/
+[ref-lex]:         /blog/2013/12/15/lexicographic-termination.lhs/
+[ref-structures]:  /blog/2013/12/22/measuring-the-size-of-structures.lhs/
+[ref-measure]:     /blog/2013/01/31/safely-catching-a-list-by-its-tail.lhs/
+[ref-slist]:       /blog/2013/07/29/putting-things-in-order.lhs/
diff --git a/docs/blog/2014-02-11-the-advantage-of-measures.lhs b/docs/blog/2014-02-11-the-advantage-of-measures.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2014-02-11-the-advantage-of-measures.lhs
@@ -0,0 +1,375 @@
+---
+layout: post
+title: "The Advantage of Measures"
+date: 2014-02-11
+author: Eric Seidel
+published: true
+comments: true
+external-url:
+categories: basic measures
+---
+
+Yesterday someone asked on [Reddit][] how one might define GHC's [OrdList][] 
+in a way that statically enforces its three key invariants. The accepted
+solution required rewriting `OrdList` as a `GADT` indexed by a proof of
+*emptiness* (which is essentially created by a run-time check), and used
+the new Closed Type Families extension in GHC 7.8 to define a type-level 
+join of the Emptiness index.
+
+Today, let's see a somewhat more direct way of tackling this problem in 
+LiquidHaskell, in which we need not change a single line of code 
+(well.. maybe one), and need not perform any dynamic checks. 
+
+<!-- more -->
+
+<div class="hidden">
+\begin{code}
+module OrdList(
+    OrdList, 
+        nilOL, isNilOL, unitOL, appOL, consOL, snocOL, concatOL,
+        mapOL, fromOL, toOL, foldrOL, foldlOL, foldr', concatOL'
+) where
+
+infixl 5  `appOL`
+infixl 5  `snocOL`
+infixr 5  `consOL`
+-- UGH parsing issues...
+{-@
+data OrdList [olen] a = None
+                      | One  (x  :: a)
+                      | Many (xs :: ListNE a)
+                      | Cons (x  :: a)           (xs :: OrdList a)
+                      | Snoc (xs :: OrdList a)   (x  :: a)
+                      | Two  (x  :: OrdListNE a) (y  :: OrdListNE a)
+@-}
+\end{code}
+</div>
+
+The OrdList Type
+----------------
+
+The `OrdList` type is defined as follows:
+
+\begin{code}
+data OrdList a
+  = None
+  | One a
+  | Many [a]        -- Invariant: non-empty
+  | Cons a (OrdList a)
+  | Snoc (OrdList a) a
+  | Two (OrdList a) -- Invariant: non-empty
+        (OrdList a) -- Invariant: non-empty
+\end{code}
+
+As indicated by the comments the key invariants are that:
+
+* `Many` should take a *non-empty* list,
+* `Two` takes two non-empty `OrdList`s. 
+
+What is a Non-Empty OrdList?
+----------------------------
+
+To proceed, we must tell LiquidHaskell what non-empty means. We do this
+with a [measure][] that describes the *number of elements* in a structure.
+When this number is strictly positive, the structure is non-empty.
+
+\begin{code} We've previously seen how to measure the size of a list.
+measure len :: [a] -> Int
+len ([])   = 0
+len (x:xs) = 1 + (len xs)
+\end{code}
+
+We can use the same technique to measure the size of an `OrdList`.
+
+\begin{code}
+{-@ measure olen :: OrdList a -> Int
+    olen (None)      = 0
+    olen (One x)     = 1
+    olen (Many xs)   = (len xs)
+    olen (Cons x xs) = 1 + (olen xs)
+    olen (Snoc xs x) = 1 + (olen xs)
+    olen (Two x y)   = (olen x) + (olen y)
+  @-}
+
+{-@ invariant {v:OrdList a | (olen v) >= 0} @-}
+\end{code}
+
+Now, we can use the measures to define aliases for **non-empty** lists and `OrdList`s.
+
+\begin{code}
+{-@ type ListNE    a = {v:[a]       | (len v)  > 0} @-}
+{-@ type OrdListNE a = {v:OrdList a | (olen v) > 0} @-}
+\end{code}
+
+Capturing the Invariants In a Refined Type
+------------------------------------------
+
+Let's return to the original type, and refine it with the above non-empty
+variants to specify the invariants as
+\begin{code} part of the data declaration
+{-@ data OrdList [olen] a
+      = None
+      | One  (x  :: a)
+      | Many (xs :: ListNE a)
+      | Cons (x  :: a)           (xs :: OrdList a)
+      | Snoc (xs :: OrdList a)   (x  :: a)
+      | Two  (x  :: OrdListNE a) (y  :: OrdListNE a)
+  @-}
+\end{code}
+
+Notice immediately that LiquidHaskell can use the refined definition to warn us 
+about malformed `OrdList` values.
+
+\begin{code}
+ok     = Many [1,2,3]
+bad    = Many []
+badder = Two None ok
+\end{code}
+
+All of the above are accepted by GHC, but only the first one is actually a valid
+`OrdList`. Happily, LiquidHaskell will reject the latter two, as they violate
+the invariants.
+
+
+Basic Functions
+---------------
+
+Now let's look at some of the functions!
+
+First, we'll define a handy alias for `OrdList`s of a given size:
+
+\begin{code}
+{-@ type OrdListN a N = {v:OrdList a | (olen v) = N} @-}
+\end{code}
+
+Now, the `nilOL` constructor returns an empty `OrdList`:
+
+\begin{code}
+{-@ nilOL :: OrdListN a {0} @-}
+nilOL = None
+\end{code}
+
+the `unitOL` constructor returns an `OrdList` with one element:
+
+\begin{code}
+{-@ unitOL :: a -> OrdListN a {1} @-}
+unitOL as = One as
+\end{code}
+
+and `snocOL` and `consOL` return outputs with precisely one more element:
+
+\begin{code}
+{-@ snocOL :: xs:OrdList a -> a -> OrdListN a {1 + (olen xs)} @-}
+snocOL as b = Snoc as b
+
+{-@ consOL :: a -> xs:OrdList a -> OrdListN a {1 + (olen xs)} @-}
+consOL a bs = Cons a bs
+\end{code}
+
+**Note:** The `OrdListN a {e}` syntax just lets us use LiquidHaskell 
+expressions `e` as a parameter to the type alias `OrdListN`.
+
+
+<div class="hidden">
+\begin{code}
+{-@ isNilOL :: xs:OrdList a -> {v:Bool | ((Prop v) <=> ((olen xs) = 0))} @-}
+isNilOL None = True
+isNilOL _    = False
+\end{code}
+</div>
+
+Appending `OrdList`s
+--------------------
+
+The above functions really aren't terribly interesting, however, since their 
+types fall right out of the definition of `olen`. 
+
+So how about something that takes a little thinking?
+
+\begin{code}
+{-@ appOL :: xs:OrdList a -> ys:OrdList a
+          -> OrdListN a {(olen xs) + (olen ys)}
+  @-}
+None  `appOL` b     = b
+a     `appOL` None  = a
+One a `appOL` b     = Cons a b
+a     `appOL` One b = Snoc a b
+a     `appOL` b     = Two a b
+\end{code}
+
+`appOL` takes two `OrdList`s and returns a list whose length is the **sum of** 
+the two input lists. The most important thing to notice here is that we haven't 
+had to insert any extra checks in `appOL`, unlike the [GADT][] solution. 
+
+LiquidHaskell uses the definition of `olen` to infer that in the last case of 
+`appOL`, `a` and `b` *must be non-empty*, so they are valid arguments to `Two`.
+
+We can prove other things about `OrdList`s as well, like the fact
+that converting an `OrdList` to a Haskell list preserves length
+
+\begin{code}
+{-@ toOL :: xs:[a] -> OrdListN a {(len xs)} @-}
+toOL [] = None
+toOL xs = Many xs
+\end{code}
+
+as does mapping over an `OrdList`
+
+\begin{code}
+{-@ mapOL :: (a -> b) -> xs:OrdList a -> OrdListN b {(olen xs)} @-}
+mapOL _ None        = None
+mapOL f (One x)     = One (f x)
+mapOL f (Cons x xs) = Cons (f x) (mapOL f xs)
+mapOL f (Snoc xs x) = Snoc (mapOL f xs) (f x)
+mapOL f (Two x y)   = Two (mapOL f x) (mapOL f y)
+mapOL f (Many xs)   = Many (map f xs)
+\end{code}
+
+as does converting a Haskell list to an `OrdList`.
+
+\begin{code}
+{-@ type ListN a N = {v:[a] | (len v) = N} @-}
+
+{-@ fromOL :: xs:OrdList a -> ListN a {(olen xs)} @-}
+fromOL a = go a []
+  where
+    {-@ go :: xs:_ -> ys:_
+           -> {v:_ | (len v) = (olen xs) + (len ys)}
+      @-}
+    go None       acc = acc
+    go (One a)    acc = a : acc
+    go (Cons a b) acc = a : go b acc
+    go (Snoc a b) acc = go a (b:acc)
+    go (Two a b)  acc = go a (go b acc)
+    go (Many xs)  acc = xs ++ acc
+\end{code}
+
+<div class="hidden">
+though for this last one we actually need to provide an explicit
+qualifier, which we haven't really seen so far. Can anyone guess why?
+
+\begin{code}
+{-@ qualif Go(v:List a, xs:OrdList a, ys:List a):
+      (len v) = (olen xs) + (len ys)
+  @-}
+\end{code}
+
+The answer is that the return type of `go` must refer to the length
+of the `OrdList` that it's folding over *as well as* the length of
+the accumulator `acc`! We haven't written a refinement like that in
+any of our type signatures in this module, so LiquidHaskell doesn't
+know to guess that type.
+</div>
+
+There's nothing super interesting to say about the `foldOL`s but I'll
+include them here for completeness' sake.
+
+\begin{code}
+foldrOL :: (a->b->b) -> b -> OrdList a -> b
+foldrOL _ z None        = z
+foldrOL k z (One x)     = k x z
+foldrOL k z (Cons x xs) = k x (foldrOL k z xs)
+foldrOL k z (Snoc xs x) = foldrOL k (k x z) xs
+foldrOL k z (Two b1 b2) = foldrOL k (foldrOL k z b2) b1
+foldrOL k z (Many xs)   = foldr k z xs
+
+foldlOL :: (b->a->b) -> b -> OrdList a -> b
+foldlOL _ z None        = z
+foldlOL k z (One x)     = k z x
+foldlOL k z (Cons x xs) = foldlOL k (k z x) xs
+foldlOL k z (Snoc xs x) = k (foldlOL k z xs) x
+foldlOL k z (Two b1 b2) = foldlOL k (foldlOL k z b1) b2
+foldlOL k z (Many xs)   = foldl k z xs
+\end{code}
+
+
+Concatenatation: Nested Measures
+--------------------------------
+
+Now, the astute readers will have probably noticed that I'm missing 
+one function, `concatOL`, which glues a list of `OrdList`s into a 
+single long `OrdList`.
+
+With LiquidHaskell we can give `concatOL` a super precise type, which 
+states that the size of the output list equals the *sum-of-the-sizes* 
+of the input `OrdLists`.
+
+\begin{code}
+{-@ concatOL :: xs:[OrdList a] -> OrdListN a {(olens xs)} @-}
+concatOL []       = None
+concatOL (ol:ols) = ol `appOL` concatOL ols
+\end{code}
+
+The notion of *sum-of-the-sizes* of the input lists is specifed by the measure
+
+\begin{code}
+{-@ measure olens :: [OrdList a] -> Int
+    olens ([])     = 0
+    olens (ol:ols) = (olen ol) + (olens ols)
+  @-}
+
+{-@ invariant {v:[OrdList a] | (olens v) >= 0} @-}
+\end{code}
+
+LiquidHaskell is happy to verify the above signature, again without 
+requiring any explict proofs. 
+
+Conclusion
+----------
+
+The above illustrates the flexibility provided by LiquidHaskell *measures*.
+
+Instead of having to bake particular invariants into a datatype using indices
+or phantom types (as in the [GADT][] approach), we are able to split our 
+properties out into independent *views* of the datatype, yielding an approach
+that is more modular as 
+
+* we didn't have to go back and change the definition of `[]` to talk about `OrdList`s,
+* we didn't have to provide explict non-emptiness witnesses,
+* we obtained extra information about the behavior of API functions like `concatOL`.
+
+
+<div class="hidden">
+We can actually even verify the original definition of `concatOL` with a
+clever use of *abstract refinements*, but we have to slightly change
+the signature of `foldr`.
+
+\begin{code}
+{- UGH CAN'T PARSE `GHC.Types.:`...
+foldr' :: forall <p :: [a] -> b -> Prop>.
+          (xs:[a] -> x:a -> b<p xs> -> b<p (GHC.Types.: x xs)>)
+       -> b<p GHC.Types.[]>
+       -> ys:[a]
+       -> b<p ys>
+@-}
+foldr' f z []     = z
+foldr' f z (x:xs) = f xs x (foldr' f z xs)
+\end{code}
+
+We've added a *ghost parameter* to the folding function, letting us
+refer to the tail of the list at each folding step. This lets us
+encode inductive reasoning in the type of `foldr`, specifically that
+
+1. given a base case `z` that satisfies `p []`
+2. and a function that, given a value that satisfies `p xs`, returns
+a value satisfying `p (x:xs)`
+3. the value returned by `foldr f z ys` must satisfy `p ys`!
+
+LiquidHaskell can use this signature, instantiating `p` with `\xs
+-> {v:OrdList a | (olen v) = (olens xs)}` to prove the original
+definition of `concatOL`!
+
+\begin{code}
+{- concatOL' :: xs:[OrdList a] -> OrdListN a {(olens xs)} @-}
+concatOL' aas = foldr' (const appOL) None aas
+\end{code}
+
+We haven't added the modified version of `foldr` to the LiquidHaskell
+Prelude yet because it adds the ghost variable to the Haskell
+type-signature.
+</div>
+
+[GADT]: http://www.reddit.com/r/haskell/comments/1xiurm/how_to_define_append_for_ordlist_defined_as_gadt/cfbrinr
+[Reddit]: http://www.reddit.com/r/haskell/comments/1xiurm/how_to_define_append_for_ordlist_defined_as_gadt/
+[OrdList]: http://www.haskell.org/platform/doc/2013.2.0.0/ghc-api/OrdList.html
+[measure]: http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/blog/2013/01/31/safely-catching-a-list-by-its-tail.lhs/
diff --git a/docs/blog/2014-02-16-text-read.lhs b/docs/blog/2014-02-16-text-read.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2014-02-16-text-read.lhs
@@ -0,0 +1,345 @@
+---
+layout: post
+title: "Text Read"
+date: 2014-02-16
+comments: true
+external-url:
+author: Eric Seidel
+published: false
+categories: benchmarks, text
+demo: TextRead.hs
+---
+
+Welcome back! Last time we left off on a bit of a cliffhanger with the
+`unstream` example. Remember, the issue we found was that some `Char`s
+can't fit into a single `Word16`, so the safety of a write depends not
+only on the *index*, but also on the *value* being written! Before we
+can resolve this issue with `unstream` we'll have to learn about
+UTF-16, so let's take a short detour and look at how one *consumes* a
+`Text`.
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types,
+    RecordWildCards, UnboxedTuples, ExistentialQuantification #-}
+{-@ LIQUID "--no-termination" @-}
+module TextRead where
+
+import GHC.Base hiding (unsafeChr)
+import GHC.ST
+import GHC.Word (Word16(..))
+import Data.Bits hiding (shiftL)
+import Data.Word
+
+import Language.Haskell.Liquid.Prelude
+
+
+--------------------------------------------------------------------------------
+--- From TextInternal
+--------------------------------------------------------------------------------
+
+{-@ shiftL :: i:Nat -> n:Nat -> {v:Nat | ((n = 1) => (v = (i * 2)))} @-}
+shiftL :: Int -> Int -> Int
+shiftL = undefined -- (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+{-@ data Array = Array { aBA  :: ByteArray#
+                       , aLen :: Nat 
+                       } 
+  @-}
+
+data Array = Array {
+    aBA  :: ByteArray#
+  , aLen :: !Int
+  }
+
+{-@ measure alen     :: Array -> Int
+    alen (Array a n) = n
+  @-}
+
+{-@ aLen :: a:Array -> {v:Nat | v = (alen a)}  @-}
+
+{-@ type ArrayN  N   = {v:Array | (alen v) = N} @-}
+
+{-@ type AValidI A   = {v:Nat | v     <  (alen A)} @-}
+{-@ type AValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type AValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+{-@ data MArray s = MArray { maBA  :: MutableByteArray# s
+                           , maLen :: Nat } @-}
+
+data MArray s = MArray {
+    maBA  :: MutableByteArray# s
+  , maLen :: !Int
+  }
+
+{-@ measure malen :: MArray s -> Int
+    malen (MArray a n) = n
+  @-}
+
+{-@ maLen :: a:MArray s -> {v:Nat | v = (malen a)}  @-}
+
+{-@ type MArrayN s N = {v:MArray s | (malen v) = N} @-}
+
+{-@ type MAValidO MA = {v:Nat | v <= (malen MA)} @-}
+
+{-@ new :: forall s. n:Nat -> ST s (MArrayN s n) @-}
+new          :: forall s. Int -> ST s (MArray s)
+new n
+  | n < 0 || n .&. highBit /= 0 = error $ "Data.Text.Array.new: size overflow"
+  | otherwise = ST $ \s1# ->
+       case newByteArray# len# s1# of
+         (# s2#, marr# #) -> (# s2#, MArray marr# n #)
+  where !(I# len#) = bytesInArray n
+        highBit    = maxBound `xor` (maxBound `shiftR` 1)
+        bytesInArray n = n `shiftL` 1
+
+{-@ unsafeFreeze :: ma:MArray s -> ST s (ArrayN (malen ma)) @-}
+unsafeFreeze :: MArray s -> ST s Array
+unsafeFreeze MArray{..} = ST $ \s# ->
+                          (# s#, Array (unsafeCoerce# maBA) maLen #)
+
+{-@ unsafeIndex :: a:Array -> AValidI a -> Word16 @-}
+unsafeIndex  :: Array -> Int -> Word16
+unsafeIndex Array{..} i@(I# i#)
+  | i < 0 || i >= aLen = liquidError "out of bounds"
+  | otherwise = case indexWord16Array# aBA i# of
+                  r# -> (W16# r#)
+
+data Text = Text Array Int Int
+{-@ data Text [tlen] = Text (tarr :: Array)
+                            (toff :: TValidO tarr)
+                            (tlen :: TValidL toff tarr)
+  @-}
+
+{-@ type TValidI T   = {v:Nat | v     <  (tlen T)} @-}
+{-@ type TValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type TValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+
+--------------------------------------------------------------------------------
+--- Helpers
+--------------------------------------------------------------------------------
+
+{-@ invariant {v:Text | (tlength v) = (numchars (tarr v) (toff v) (tlen v))} @-}
+
+{-@ axiom_lead_surr :: x:Word16 -> a:Array -> o:Nat -> l:Nat -> i:Nat
+                  -> {v:Bool | ((Prop v) <=> (if (55296 <= x && x <= 56319)
+                                              then (SpanChar 2 a o l i)
+                                              else (SpanChar 1 a o l i)))}
+  @-}
+axiom_lead_surr :: Word16 -> Array -> Int -> Int -> Int -> Bool
+axiom_lead_surr = undefined
+
+{-@ empty :: {v:Text | (tlen v) = 0} @-}
+empty :: Text
+empty = Text arrEmpty 0 0
+  where
+    {-@ arrEmpty :: (ArrayN {0}) @-}
+    arrEmpty = runST $ new 0 >>= unsafeFreeze
+
+unsafeChr :: Word16 -> Char
+unsafeChr (W16# w#) = C# (chr# (word2Int# w#))
+
+chr2 :: Word16 -> Word16 -> Char
+chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#))
+    where
+      !x# = word2Int# a#
+      !y# = word2Int# b#
+      !upper# = uncheckedIShiftL# (x# -# 0xD800#) 10#
+      !lower# = y# -# 0xDC00#
+
+{-@ qualif Min(v:int, t:Text, i:int):
+      (if ((tlength t) < i)
+       then ((numchars (tarr t) (toff t) v) = (tlength t))
+       else ((numchars (tarr t) (toff t) v) = i))
+  @-}
+
+{-@ qualif NumChars(v:int, t:Text, i:int): v = (numchars (tarr t) (toff t) i) @-}
+
+{-@ qualif TLengthLE(v:int, t:Text): v <= (tlength t) @-}
+
+\end{code}
+
+</div>
+
+Let's begin with a simple example, `unsafeHead`.
+
+\begin{code}
+{-@ type TextNE = {v:Text | (tlen v) > 0} @-}
+
+{-@ unsafeHead :: TextNE -> Char @-}
+unsafeHead :: Text -> Char
+unsafeHead (Text arr off _len)
+    | m < 0xD800 || m > 0xDBFF = unsafeChr m
+    | otherwise                = chr2 m n
+    where m = unsafeIndex arr off
+          n = unsafeIndex arr (off+1)
+\end{code}
+
+LiquidHaskell can prove the first `unsafeIndex` is safe because the
+precondition states that the `Text` must not be empty, i.e. `_len > 0`
+must hold. Combine this with the core `Text` invariant that
+`off + _len <= alen arr` and we get that `off < alen arr`, which satisfies
+the precondition for `unsafeIndex`.
+
+However, the same calculation *fails* for the second index because we
+can't prove that `off + 1 < alen arr`. The solution is going to
+require some understanding of UTF-16, so let's take a brief detour.
+
+The UTF-16 standard represents all code points below `U+10000` with a
+single 16-bit word; all others are split into two 16-bit words, known
+as a *surrogate pair*. The first word, or *lead*, is guaranteed to be
+in the range `[0xD800, 0xDBFF]` and the second, or *trail*, is
+guaranteed to be in the range `[0xDC00, 0xDFFF]`.
+
+Armed with this knowledge of UTF-16 we can return to
+`unsafeHead`. Note the case-split on `m`, which determines whether `m`
+is a lead surrogate. If `m` is a lead surrogate then we know there
+must be a trail surrogate at `off+1`; we can define a specialized
+version of `unsafeIndex` that encodes this domain knowledge.
+
+\begin{code}
+{-@ unsafeIndexF :: a:Array -> o:AValidO a -> l:AValidL o a
+                 -> i:{v:Nat | (o <= v && v < (o + l))}
+                 -> {v:Word16 | (if (55296 <= v && v <= 56319)
+                                 then (SpanChar 2 a o l i)
+                                 else (SpanChar 1 a o l i))}
+  @-}
+unsafeIndexF :: Array -> Int -> Int -> Int -> Word16
+unsafeIndexF a o l i = let x = unsafeIndex a i
+                       in liquidAssume (axiom_lead_surr x a o l i) x
+\end{code}
+
+Our variant `unsafeIndexF` (F as in "forward") takes an array, an
+offset, and a length (which together must form a valid `Text`); a
+valid index into the `Text`; and returns a `Word16` with an
+interesting type. The best way to read this type would be "if `v` is
+in the range `[0xD800, 0xDBFF]`, then the character that starts at
+index `i` in the array `a` spans two slots, otherwise it only spans
+one slot." Intuitively, we know what it means for a character to span
+`n` slots, but LiquidHaskell needs to know three things:
+
+1. `a[o:i+n]` contains one more character than `a[o:i]` (borrowing
+   Python's wonderful slicing syntax)
+2. `a[o:i+n]` contains no more characters than `a[o:l]`
+3. `i-o+n <= l`
+
+2 and 3 encode the well-formedness of a `Text` value, i.e. `i+1`
+*must* be a valid index if a lead surrogate is at index `i`.
+
+We can encode these properties in the refinement logic as follows.
+
+\begin{code}
+{-@ measure numchars :: Array -> Int -> Int -> Int @-}
+{-@ predicate SpanChar N A O L I =
+      (((numchars (A) (O) ((I-O)+N)) = (1 + (numchars (A) (O) (I-O))))
+    && ((numchars (A) (O) ((I-O)+N)) <= (numchars A O L))
+    && (((I-O)+N) <= L))
+  @-}
+\end{code}
+
+The `numchars` measure takes an array, an offset, and a length
+(e.g. the `arr`, `off`, and `len` fields of a `Text`) and denotes the
+number of characters contained in the `length` slots beginning at
+`offset`. Since we can't compute this in the refinement logic, we
+leave the measure abstract. We can, however, provide LiquidHaskell
+with a few invariants about the behavior of `numchars`, specifically
+that (1) `numchars` always returns a `Nat`, (2) there are no
+characters contained in a empty span, and (3) there are at most as
+many characters as words in a `Text`. We encode these using a special
+`invariant` annotation.
+
+\begin{code}
+{-@ invariant {v:Text | (numchars (tarr v) (toff v) (tlen v)) >= 0}        @-}
+{-@ invariant {v:Text | (numchars (tarr v) (toff v) 0)         = 0}        @-}
+{-@ invariant {v:Text | (numchars (tarr v) (toff v) (tlen v)) <= (tlen v)} @-}
+\end{code}
+
+Finally returning to `unsafeHead`, we can use `unsafeIndexF` to
+strengthen the inferred type for `m`. LiquidHaskell can now prove that
+the second `unsafeIndex` is in fact safe, because it is only demanded
+if `m` is a lead surrogate.
+
+\begin{code}
+{-@ unsafeHead' :: TextNE -> Char @-}
+unsafeHead' :: Text -> Char
+unsafeHead' (Text arr off _len)
+    | m < 0xD800 || m > 0xDBFF = unsafeChr m
+    | otherwise                = chr2 m n
+    where m = unsafeIndexF arr off _len off
+          {-@ LAZYVAR n @-}
+          n = unsafeIndex arr (off+1)
+\end{code}
+
+The `LAZYVAR` annotation is currently required because LiquidHaskell
+doesn't know that `n` will only be demanded in one branch; one can
+imagine a transformation that would push the `where` bindings inward
+to the use-site, which would alleviate this issue.
+
+Before signing off, let's take a look at a slightly more interesting
+function, `take`.
+
+\begin{code}
+{-@ take :: n:Nat -> t:Text -> {v:Text | (Min (tlength v) (tlength t) n)} @-}
+take :: Int -> Text -> Text
+take n t@(Text arr off len)
+    | n <= 0    = empty
+    | n >= len  = t
+    | otherwise = Text arr off (loop 0 0)
+  where
+     loop !i !cnt
+          | i >= len || cnt >= n = i
+          | otherwise            = let d = iter_ t i
+                                   in loop (i+d) (cnt+1)
+\end{code}
+
+`take` gets a `Nat` and a `Text`, and returns a `Text` that contains
+the first `n` characters of `t`. That is, unless `n >= tlength t`, in
+which case it just returns `t`.
+
+`tlength` is a simple wrapper around `numchars`.
+
+\begin{code}
+{-@ measure tlength :: Text -> Int
+    tlength (Text a o l) = (numchars a o l)
+  @-}
+\end{code}
+
+The bulk of the work is done by the
+inner `loop`, which has to track the current index `i` and the number
+of characters we have seen, `cnt`. `loop` uses an auxiliary function
+`iter_` to determine the *width* of the character that starts at `i`,
+bumps `cnt`, and recursively calls itself at `i+d` until it either
+reaches the end of `t` or sees `n` characters, returning the final
+index.
+
+The `iter_` function is quite simple, it just determines whether the
+word at index `i` is a lead surrogate, and returns the appropriate
+span.
+
+\begin{code}
+{-@ predicate SpanCharT N T I =
+      (SpanChar N (tarr T) (toff T) (tlen T) ((toff T)+I))
+  @-}
+
+{-@ iter_ :: t:Text -> i:TValidI t
+          -> {v:Nat | (SpanCharT v t i)}
+  @-}
+iter_ :: Text -> Int -> Int
+iter_ (Text arr off len) i
+    | m < 0xD800 || m > 0xDBFF = 1
+    | otherwise                = 2
+ where m = unsafeIndexF arr off len (off+i)
+\end{code}
+
+Again, we use `unsafeIndexF` to learn more about the structure of `t`
+by observing a small piece of it. It's also worth noting that we've
+encoded all of the domain knowledge we need into a single function,
+which has the benefit of letting us focus our attention on one type
+when we try to ensure that we've encoded it correctly.
+
+Next time, we'll continue our exploration of `text` and see how to
+construct a `Text` while ensuring the absence of out-of-bounds writes.
diff --git a/docs/blog/2014-02-23-text-write.lhs b/docs/blog/2014-02-23-text-write.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2014-02-23-text-write.lhs
@@ -0,0 +1,323 @@
+---
+layout: post
+title: "Text Write"
+date: 2014-02-23
+comments: true
+external-url:
+author: Eric Seidel
+published: false
+categories: benchmarks, text
+demo: TextWrite.hs
+---
+
+Last time, we showed how to reason about Unicode and a variable-width
+encoding of `Char`s when consuming a `Text` value, today we'll look at
+the same issue from the perspective of *building* a `Text`.
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types,
+    RecordWildCards, UnboxedTuples, ExistentialQuantification #-}
+{-@ LIQUID "--no-termination" @-}
+module TextWrite where
+
+import Control.Monad.ST.Unsafe (unsafeIOToST)
+import Foreign.C.Types (CSize)
+import GHC.Base hiding (unsafeChr)
+import GHC.ST
+import GHC.Word (Word16(..))
+import Data.Bits hiding (shiftL)
+import Data.Word
+
+import Language.Haskell.Liquid.Prelude
+
+--------------------------------------------------------------------------------
+--- From TextInternal
+--------------------------------------------------------------------------------
+
+{-@ shiftL :: i:Nat -> n:Nat -> {v:Nat | ((n = 1) => (v = (i * 2)))} @-}
+shiftL :: Int -> Int -> Int
+shiftL = undefined -- (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+{-@ measure isUnknown :: Size -> Prop
+    isUnknown (Exact n) = false
+    isUnknown (Max   n) = false
+    isUnknown (Unknown) = true
+  @-}
+{-@ measure getSize :: Size -> Int
+    getSize (Exact n) = n
+    getSize (Max   n) = n
+  @-}
+
+{-@ invariant {v:Size | (getSize v) >= 0} @-}
+
+data Size = Exact {-# UNPACK #-} !Int -- ^ Exact size.
+          | Max   {-# UNPACK #-} !Int -- ^ Upper bound on size.
+          | Unknown                   -- ^ Unknown size.
+            deriving (Eq, Show)
+
+{-@ upperBound :: k:Nat -> s:Size -> {v:Nat | v = ((isUnknown s) ? k : (getSize s))} @-}
+upperBound :: Int -> Size -> Int
+upperBound _ (Exact n) = n
+upperBound _ (Max   n) = n
+upperBound k _         = k
+
+data Step s a = Done
+              | Skip !s
+              | Yield !a !s
+
+data Stream a =
+    forall s. Stream
+    (s -> Step s a)             -- stepper function
+    !s                          -- current state
+    !Size                       -- size hint
+
+{-@ data Array = Array { aBA  :: ByteArray#
+                       , aLen :: Nat 
+                       } 
+  @-}
+
+data Array = Array {
+    aBA  :: ByteArray#
+  , aLen :: !Int
+  }
+
+{-@ measure alen     :: Array -> Int
+    alen (Array a n) = n
+  @-}
+
+{-@ aLen :: a:Array -> {v:Nat | v = (alen a)}  @-}
+
+{-@ type ArrayN  N   = {v:Array | (alen v) = N} @-}
+
+{-@ type AValidI A   = {v:Nat | v     <  (alen A)} @-}
+{-@ type AValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type AValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+{-@ data MArray s = MArray { maBA  :: MutableByteArray# s
+                           , maLen :: Nat } @-}
+
+data MArray s = MArray {
+    maBA  :: MutableByteArray# s
+  , maLen :: !Int
+  }
+
+{-@ measure malen :: MArray s -> Int
+    malen (MArray a n) = n
+  @-}
+
+{-@ maLen :: a:MArray s -> {v:Nat | v = (malen a)}  @-}
+
+{-@ type MArrayN s N = {v:MArray s | (malen v) = N} @-}
+
+{-@ type MAValidI MA = {v:Nat | v <  (malen MA)} @-}
+{-@ type MAValidO MA = {v:Nat | v <= (malen MA)} @-}
+
+{-@ new :: forall s. n:Nat -> ST s (MArrayN s n) @-}
+new          :: forall s. Int -> ST s (MArray s)
+new n
+  | n < 0 || n .&. highBit /= 0 = error $ "Data.Text.Array.new: size overflow"
+  | otherwise = ST $ \s1# ->
+       case newByteArray# len# s1# of
+         (# s2#, marr# #) -> (# s2#, MArray marr# n #)
+  where !(I# len#) = bytesInArray n
+        highBit    = maxBound `xor` (maxBound `shiftR` 1)
+        bytesInArray n = n `shiftL` 1
+
+{-@ unsafeWrite :: ma:MArray s -> MAValidI ma -> Word16 -> ST s () @-}
+unsafeWrite  :: MArray s -> Int -> Word16 -> ST s ()
+unsafeWrite MArray{..} i@(I# i#) (W16# e#)
+  | i < 0 || i >= maLen = liquidError "out of bounds"
+  | otherwise = ST $ \s1# ->
+      case writeWord16Array# maBA i# e# s1# of
+        s2# -> (# s2#, () #)
+
+{-@ copyM :: dest:MArray s 
+          -> didx:MAValidO dest
+          -> src:MArray s 
+          -> sidx:MAValidO src
+          -> {v:Nat | (((didx + v) <= (malen dest))
+                    && ((sidx + v) <= (malen src)))}
+          -> ST s ()
+  @-}
+copyM        :: MArray s               -- ^ Destination
+             -> Int                    -- ^ Destination offset
+             -> MArray s               -- ^ Source
+             -> Int                    -- ^ Source offset
+             -> Int                    -- ^ Count
+             -> ST s ()
+copyM dest didx src sidx count
+    | count <= 0 = return ()
+    | otherwise =
+    liquidAssert (sidx + count <= maLen src) .
+    liquidAssert (didx + count <= maLen dest) .
+    unsafeIOToST $ memcpyM (maBA dest) (fromIntegral didx)
+                           (maBA src) (fromIntegral sidx)
+                           (fromIntegral count)
+
+{-@ memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO () @-}
+memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO ()
+memcpyM = undefined
+
+{-@ unsafeFreeze :: ma:MArray s -> ST s (ArrayN (malen ma)) @-}
+unsafeFreeze :: MArray s -> ST s Array
+unsafeFreeze MArray{..} = ST $ \s# ->
+                          (# s#, Array (unsafeCoerce# maBA) maLen #)
+
+{-@ unsafeIndex :: a:Array -> AValidI a -> Word16 @-}
+unsafeIndex  :: Array -> Int -> Word16
+unsafeIndex Array{..} i@(I# i#)
+  | i < 0 || i >= aLen = liquidError "out of bounds"
+  | otherwise = case indexWord16Array# aBA i# of
+                  r# -> (W16# r#)
+
+data Text = Text Array Int Int
+{-@ data Text [tlen] = Text (tarr :: Array)
+                            (toff :: TValidO tarr)
+                            (tlen :: TValidL toff tarr)
+  @-}
+
+{-@ type TValidI T   = {v:Nat | v     <  (tlen T)} @-}
+{-@ type TValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type TValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+
+--------------------------------------------------------------------------------
+--- From TextRead
+--------------------------------------------------------------------------------
+
+{-@ measure numchars :: Array -> Int -> Int -> Int @-}
+{-@ measure tlength :: Text -> Int @-}
+{-@ invariant {v:Text | (tlength v) = (numchars (tarr v) (toff v) (tlen v))} @-}
+
+--------------------------------------------------------------------------------
+--- Helpers
+--------------------------------------------------------------------------------
+
+{-@ qualif Ord(v:int, i:int, x:Char)
+        : ((((ord x) <  65536) => (v = i))
+        && (((ord x) >= 65536) => (v = (i + 1))))
+  @-}
+
+\end{code}
+
+</div>
+
+We mentioned previously that `text` uses stream fusion to optimize
+multiple loops over a `Text` into a single loop; as a result many of
+the top-level API functions are simple wrappers around equivalent
+functions over `Stream`s. The creation of `Text` values is then
+largely handled by a single function, `unstream`, which converts a
+`Stream` into a `Text`.
+
+\begin{code}
+unstream :: Stream Char -> Text
+unstream (Stream next0 s0 len) = runST $ do
+  let mlen = upperBound 4 len
+  arr0 <- new mlen
+  let outer arr top = loop
+       where
+        loop !s !i =
+            case next0 s of
+              Done          -> do
+                arr' <- unsafeFreeze arr
+                return $! Text arr' 0 i
+              Skip s'       -> loop s' i
+              Yield x s'
+                | j >= top  -> do
+                  let top' = (top + 1) `shiftL` 1
+                  arr' <- new top'
+                  copyM arr' 0 arr 0 top
+                  outer arr' top' s i
+                | otherwise -> do
+                  d <- writeChar arr i x
+                  loop s' (i+d)
+                where j | ord x < 0x10000 = i
+                        | otherwise       = i + 1
+  outer arr0 mlen s0 0
+\end{code}
+
+Since we're focusing on memory safety here we won't go into detail
+about how `Stream`s work. Let's instead jump right into the inner
+`loop` and look at the `Yield` case. Here we need to write a char `x`
+into `arr`, so we compute the maximal index `j` to which we will
+write -- i.e. if `x >= U+10000` then `j = i + 1` -- and determine
+whether we can safely write at `j`. If the write is unsafe we have to
+allocate a larger array before continuing, otherwise we write `x` and
+increment `i` by `x`s width.
+
+Since `writeChar` has to handle writing *any* Unicode value, we need
+to assure it that there will always be room to write `x` into `arr`,
+regardless of `x`s width. Indeed, this is expressed in the type we
+give to `writeChar`.
+
+\begin{code}
+{-@ writeChar :: ma:MArray s -> i:Nat -> {v:Char | (Room v ma i)}
+              -> ST s {v:Nat | (RoomN v ma i)}
+  @-}
+\end{code}
+
+The predicate aliases `Room` and `RoomN` express that a character can
+fit in the array at index `i` and that there are at least `n` slots
+available starting at `i` respectively.
+
+\begin{code}
+{-@ predicate Room C MA I = (((One C) => (RoomN 1 MA I))
+                          && ((Two C) => (RoomN 2 MA I)))
+  @-}
+{-@ predicate RoomN N MA I = (I+N <= (malen MA)) @-}
+\end{code}
+
+The `One` and `Two` predicates express that a character will be
+encoded in one or two 16-bit words, by reasoning about its ordinal
+value.
+
+\begin{code}
+{-@ predicate One C = ((ord C) <  65536) @-}
+{-@ predicate Two C = ((ord C) >= 65536) @-}
+\end{code}
+
+As with `numchars`, we leave `ord` abstract, but inform LiquidHaskell
+that the `ord` *function* does in fact return the ordinal value of the
+character.
+
+\begin{code}
+{-@ measure ord :: Char -> Int @-}
+{-@ ord :: c:Char -> {v:Int | v = (ord c)} @-}
+\end{code}
+
+Since `writeChar` assumes that it will never be called unless there is room to
+write `c`, it is safe to just split `c` into 16-bit words and write them into
+the array.
+
+\begin{code}
+writeChar :: MArray s -> Int -> Char -> ST s Int
+writeChar marr i c
+    | n < 0x10000 = do
+        unsafeWrite marr i (fromIntegral n)
+        return 1
+    | otherwise = do
+        unsafeWrite marr i lo
+        unsafeWrite marr (i+1) hi
+        return 2
+    where n = ord c
+          m = n - 0x10000
+          lo = fromIntegral $ (m `shiftR` 10) + 0xD800
+          hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
+\end{code}
+
+In typical design-by-contract style, we're putting the burden of proof to
+establish safety on `writeChar`s caller. Now, scroll back up to
+`unstream` and mouse over `j` to see its inferred type.
+\begin{code} You should see something like
+{v:Int | ((ord x >= 65536) => (v == i+1))
+      && ((ord x <  65536) => (v == i))}
+\end{code}
+which, combined with the case-split on `j >= top`, provides the proof that
+writing `x` will be safe!
+
+Stay tuned, next time we'll look at another example of building a `Text` where
+LiquidHaskell fails to infer this crucial refinement...
diff --git a/docs/blog/2014-03-01-text-bug.lhs b/docs/blog/2014-03-01-text-bug.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2014-03-01-text-bug.lhs
@@ -0,0 +1,333 @@
+---
+layout: post
+title: "Text Bug"
+date: 2014-03-01
+comments: true
+external-url:
+author: Eric Seidel
+published: false
+categories: benchmarks, text
+demo: TextBug.hs
+---
+
+For our last post on `text`, we return to the topic of building a new `Text`
+value, i.e. proving the safety of write operations.
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types,
+    RecordWildCards, UnboxedTuples, ExistentialQuantification #-}
+{-@ LIQUID "--no-termination" @-}
+module TextBug where
+
+import Control.Monad.ST.Unsafe (unsafeIOToST)
+import Foreign.C.Types (CSize)
+import GHC.Base hiding (unsafeChr)
+import GHC.ST
+import GHC.Word (Word16(..))
+import Data.Bits hiding (shiftL)
+import Data.Word
+
+import Language.Haskell.Liquid.Prelude
+
+--------------------------------------------------------------------------------
+--- From TextInternal
+--------------------------------------------------------------------------------
+
+{-@ shiftL :: i:Nat -> n:Nat -> {v:Nat | ((n = 1) => (v = (i * 2)))} @-}
+shiftL :: Int -> Int -> Int
+shiftL = undefined -- (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+{-@ measure isUnknown :: Size -> Prop
+    isUnknown (Exact n) = false
+    isUnknown (Max   n) = false
+    isUnknown (Unknown) = true
+  @-}
+{-@ measure getSize :: Size -> Int
+    getSize (Exact n) = n
+    getSize (Max   n) = n
+  @-}
+
+{-@ invariant {v:Size | (getSize v) >= 0} @-}
+
+data Size = Exact {-# UNPACK #-} !Int -- ^ Exact size.
+          | Max   {-# UNPACK #-} !Int -- ^ Upper bound on size.
+          | Unknown                   -- ^ Unknown size.
+            deriving (Eq, Show)
+
+{-@ upperBound :: k:Nat -> s:Size -> {v:Nat | v = ((isUnknown s) ? k : (getSize s))} @-}
+upperBound :: Int -> Size -> Int
+upperBound _ (Exact n) = n
+upperBound _ (Max   n) = n
+upperBound k _         = k
+
+data Step s a = Done
+              | Skip !s
+              | Yield !a !s
+
+data Stream a =
+    forall s. Stream
+    (s -> Step s a)             -- stepper function
+    !s                          -- current state
+    !Size                       -- size hint
+
+{-@ data Array = Array { aBA  :: ByteArray#
+                       , aLen :: Nat 
+                       } 
+  @-}
+
+data Array = Array {
+    aBA  :: ByteArray#
+  , aLen :: !Int
+  }
+
+{-@ measure alen     :: Array -> Int
+    alen (Array a n) = n
+  @-}
+
+{-@ aLen :: a:Array -> {v:Nat | v = (alen a)}  @-}
+
+{-@ type ArrayN  N   = {v:Array | (alen v) = N} @-}
+
+{-@ type AValidI A   = {v:Nat | v     <  (alen A)} @-}
+{-@ type AValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type AValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+{-@ data MArray s = MArray { maBA  :: MutableByteArray# s
+                           , maLen :: Nat } @-}
+
+data MArray s = MArray {
+    maBA  :: MutableByteArray# s
+  , maLen :: !Int
+  }
+
+{-@ measure malen :: MArray s -> Int
+    malen (MArray a n) = n
+  @-}
+
+{-@ maLen :: a:MArray s -> {v:Nat | v = (malen a)}  @-}
+
+{-@ type MArrayN s N = {v:MArray s | (malen v) = N} @-}
+
+{-@ type MAValidI MA = {v:Nat | v <  (malen MA)} @-}
+{-@ type MAValidO MA = {v:Nat | v <= (malen MA)} @-}
+
+{-@ new :: forall s. n:Nat -> ST s (MArrayN s n) @-}
+new          :: forall s. Int -> ST s (MArray s)
+new n
+  | n < 0 || n .&. highBit /= 0 = error $ "Data.Text.Array.new: size overflow"
+  | otherwise = ST $ \s1# ->
+       case newByteArray# len# s1# of
+         (# s2#, marr# #) -> (# s2#, MArray marr# n #)
+  where !(I# len#) = bytesInArray n
+        highBit    = maxBound `xor` (maxBound `shiftR` 1)
+        bytesInArray n = n `shiftL` 1
+
+{-@ unsafeWrite :: ma:MArray s -> MAValidI ma -> Word16 -> ST s () @-}
+unsafeWrite  :: MArray s -> Int -> Word16 -> ST s ()
+unsafeWrite MArray{..} i@(I# i#) (W16# e#)
+  | i < 0 || i >= maLen = liquidError "out of bounds"
+  | otherwise = ST $ \s1# ->
+      case writeWord16Array# maBA i# e# s1# of
+        s2# -> (# s2#, () #)
+
+{-@ copyM :: dest:MArray s 
+          -> didx:MAValidO dest
+          -> src:MArray s 
+          -> sidx:MAValidO src
+          -> {v:Nat | (((didx + v) <= (malen dest))
+                    && ((sidx + v) <= (malen src)))}
+          -> ST s ()
+  @-}
+copyM        :: MArray s               -- ^ Destination
+             -> Int                    -- ^ Destination offset
+             -> MArray s               -- ^ Source
+             -> Int                    -- ^ Source offset
+             -> Int                    -- ^ Count
+             -> ST s ()
+copyM dest didx src sidx count
+    | count <= 0 = return ()
+    | otherwise =
+    liquidAssert (sidx + count <= maLen src) .
+    liquidAssert (didx + count <= maLen dest) .
+    unsafeIOToST $ memcpyM (maBA dest) (fromIntegral didx)
+                           (maBA src) (fromIntegral sidx)
+                           (fromIntegral count)
+
+{-@ memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO () @-}
+memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO ()
+memcpyM = undefined
+
+{-@ unsafeFreeze :: ma:MArray s -> ST s (ArrayN (malen ma)) @-}
+unsafeFreeze :: MArray s -> ST s Array
+unsafeFreeze MArray{..} = ST $ \s# ->
+                          (# s#, Array (unsafeCoerce# maBA) maLen #)
+
+{-@ unsafeIndex :: a:Array -> AValidI a -> Word16 @-}
+unsafeIndex  :: Array -> Int -> Word16
+unsafeIndex Array{..} i@(I# i#)
+  | i < 0 || i >= aLen = liquidError "out of bounds"
+  | otherwise = case indexWord16Array# aBA i# of
+                  r# -> (W16# r#)
+
+data Text = Text Array Int Int
+{-@ data Text [tlen] = Text (tarr :: Array)
+                            (toff :: TValidO tarr)
+                            (tlen :: TValidL toff tarr)
+  @-}
+
+{-@ type TValidI T   = {v:Nat | v     <  (tlen T)} @-}
+{-@ type TValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type TValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+
+--------------------------------------------------------------------------------
+--- From TextRead
+--------------------------------------------------------------------------------
+
+{-@ measure numchars :: Array -> Int -> Int -> Int @-}
+{-@ measure tlength :: Text -> Int @-}
+{-@ invariant {v:Text | (tlength v) = (numchars (tarr v) (toff v) (tlen v))} @-}
+
+--------------------------------------------------------------------------------
+--- From TextWrite
+--------------------------------------------------------------------------------
+
+{-@ qualif Ord(v:int, i:int, x:Char)
+        : ((((ord x) <  65536) => (v = i))
+        && (((ord x) >= 65536) => (v = (i + 1))))
+  @-}
+
+{-@ predicate Room C MA I = (((One C) => (RoomN 1 MA I))
+                          && ((Two C) => (RoomN 2 MA I)))
+  @-}
+{-@ predicate RoomN N MA I = (I+N <= (malen MA)) @-}
+
+{-@ measure ord :: Char -> Int @-}
+{-@ ord :: c:Char -> {v:Int | v = (ord c)} @-}
+{-@ predicate One C = ((ord C) <  65536) @-}
+{-@ predicate Two C = ((ord C) >= 65536) @-}
+
+{-@ writeChar :: ma:MArray s -> i:Nat -> {v:Char | (Room v ma i)}
+              -> ST s {v:Nat | (RoomN v ma i)}
+  @-}
+writeChar :: MArray s -> Int -> Char -> ST s Int
+writeChar marr i c
+    | n < 0x10000 = do
+        unsafeWrite marr i (fromIntegral n)
+        return 1
+    | otherwise = do
+        unsafeWrite marr i lo
+        unsafeWrite marr (i+1) hi
+        return 2
+    where n = ord c
+          m = n - 0x10000
+          lo = fromIntegral $ (m `shiftR` 10) + 0xD800
+          hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
+
+--------------------------------------------------------------------------------
+--- Helpers
+--------------------------------------------------------------------------------
+
+{-@ qualif MALenLE(v:int, a:MArray s): v <= (malen a) @-}
+{-@ qualif ALenLE(v:int, a:Array): v <= (alen a) @-}
+
+\end{code}
+
+</div>
+
+Let's take a look at `mapAccumL`, which combines a map and a fold
+over a `Stream` and bundles the result of the map into a new `Text`.
+Again, we'll want to focus our attention on the `Yield` case of the
+inner loop.
+
+\begin{code}
+mapAccumL f z0 (Stream next0 s0 len) =
+  (nz, Text na 0 nl)
+ where
+  mlen = upperBound 4 len
+  (na,(nz,nl)) = runST $ do
+       (marr,x) <- (new mlen >>= \arr ->
+                    outer arr mlen z0 s0 0)
+       arr      <- unsafeFreeze marr
+       return (arr,x)
+  outer arr top = loop
+   where
+    loop !z !s !i =
+      case next0 s of
+        Done          -> return (arr, (z,i))
+        Skip s'       -> loop z s' i
+        Yield x s'
+          | j >= top  -> do
+            let top' = (top + 1) `shiftL` 1
+            arr' <- new top'
+            copyM arr' 0 arr 0 top
+            outer arr' top' z s i
+          | otherwise -> do
+            let (z',c) = f z x
+            d <- writeChar arr i c
+            loop z' s' (i+d)
+          where j | ord x < 0x10000 = i
+                  | otherwise       = i + 1
+\end{code}
+
+If you recall `unstream` from last time, you'll notice that this loop body
+looks almost identical to the one found in `unstream`, but LiquidHaskell has
+flagged the `writeChar` call as unsafe! What's going on here?
+
+Let's take a look at `j`, recalling that it carried a crucial part of the safety
+\begin{code} proof last time, and see what LiquidHaskell was able to infer.
+{v:Int | ((ord x >= 65536) => (v == i+1))
+      && ((ord x <  65536) => (v == i))}
+\end{code}
+
+Well that's not very useful at all! LiquidHaskell can prove that it's safe to
+write `x` but here we are trying to write `c` into the array. This is actually
+a *good* thing though, because `c` is the result of calling an arbitrary
+function `f` on `x`! We haven't constrained `f` in any way, so it could easily
+return a character above `U+10000` given any input.
+
+So `mapAccumL` is actually *unsafe*, and our first wild bug caught by
+LiquidHaskell! The fix is luckily easy, we simply have to lift the
+`let (z',c) = f z x` binder into the `where` clause, and change `j` to
+depend on `ord c` instead.
+
+\begin{code}
+mapAccumL' f z0 (Stream next0 s0 len) =
+  (nz, Text na 0 nl)
+ where
+  mlen = upperBound 4 len
+  (na,(nz,nl)) = runST $ do
+       (marr,x) <- (new mlen >>= \arr ->
+                    outer arr mlen z0 s0 0)
+       arr      <- unsafeFreeze marr
+       return (arr,x)
+  outer arr top = loop
+   where
+    loop !z !s !i =
+      case next0 s of
+        Done          -> return (arr, (z,i))
+        Skip s'       -> loop z s' i
+        Yield x s'
+          | j >= top  -> do
+            let top' = (top + 1) `shiftL` 1
+            arr' <- new top'
+            copyM arr' 0 arr 0 top
+            outer arr' top' z s i
+          | otherwise -> do
+            d <- writeChar arr i c
+            loop z' s' (i+d)
+          where (z',c) = f z x
+                j | ord c < 0x10000 = i
+                  | otherwise       = i + 1
+\end{code}
+
+LiquidHaskell happily accepts our revised `mapAccumL`, as did the `text`
+maintainers.
+
+We hope you've enjoyed this whirlwind tour of using LiquidHaskell to verify
+production code, we have many more examples in the `benchmarks` folder of
+our GitHub repository for the intrepid reader.
diff --git a/docs/blog/2014-05-28-pointers-gone-wild.lhs b/docs/blog/2014-05-28-pointers-gone-wild.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2014-05-28-pointers-gone-wild.lhs
@@ -0,0 +1,467 @@
+---
+layout: post
+title: "Pointers Gone Wild"
+date: 2014-05-28
+comments: true
+external-url:
+author: Eric Seidel
+published: true
+categories: benchmarks, text
+demo: TextInternal.hs
+---
+
+A large part of the allure of Haskell is its elegant, high-level ADTs
+that ensure[^compilercorrectness] that programs won't be plagued by problems
+like the infamous [SSL heartbleed bug](http://en.wikipedia.org/wiki/Heartbleed).
+
+[^compilercorrectness]: Assuming the absence of errors in the compiler and run-time...
+
+However, another part of Haskell's charm is that when you really really 
+need to, you can drop down to low-level pointer twiddling to squeeze the 
+most performance out of your machine. But of course, that opens the door 
+to the #heartbleeds.
+
+Can we have have our cake and eat it too? 
+
+Can we twiddle pointers and still get the nice safety assurances of high-level types?
+
+<!-- more -->
+
+To understand the potential for potential bleeding,
+let's study the popular `text` library for efficient 
+text processing. The library provides the high-level 
+API Haskellers have come to expect while using stream 
+fusion and byte arrays under the hood to guarantee 
+high performance.
+
+Suppose we wanted to get the *i*th `Char` of a `Text`,
+\begin{code} we could write a function[^bad]
+charAt (Text a o l) i = word2char $ unsafeIndex a (o+i)
+  where 
+    word2char         = chr . fromIntegral
+\end{code}
+which extracts the underlying array `a`, indexes into it starting
+at the offset `o` and casts the `Word16` to a `Char`, using 
+functions exported by `text`.
+
+[^bad]: This function is bad for numerous reasons, least of which is that `Data.Text.index` is already provided, but stay with us...
+
+\begin{code}Let's try this out in GHCi.
+ghci> let t = pack ['d','o','g']
+ghci> charAt t 0
+'d'
+ghci> charAt t 2
+'g'
+\end{code}
+
+\begin{code}Looks good so far, what happens if we keep going?
+ghci> charAt t 3
+'\NUL'
+ghci> charAt t 100
+'\8745'
+\end{code}
+
+Oh dear, not only did we not get any sort of exception from Haskell, 
+we weren't even stopped by the OS with a segfault. This is quite 
+dangerous since we have no idea what sort of data we just read! 
+To be fair to the library's authors, we did use a function that 
+was clearly branded `unsafe`, but these functions, while not 
+intended for *clients*, pervade the implementation of the *library*.
+
+Wouldn't it be nice to have these last two calls *rejected at compile time*?
+
+In this post we'll see exactly how prevent invalid memory accesses 
+like this with LiquidHaskell.
+
+
+<div class="hidden">
+
+\begin{code}
+{-# LANGUAGE BangPatterns, MagicHash, Rank2Types,
+    RecordWildCards, UnboxedTuples, ExistentialQuantification #-}
+{-@ LIQUID "--no-termination" @-}
+module TextInternal (test, goodMain, badMain, charAt, charAt') where
+
+import qualified Control.Exception as Ex
+import Control.Applicative     ((<$>))
+import Control.Monad           (when)
+import Control.Monad.ST.Unsafe (unsafeIOToST)
+import Data.Bits (shiftR, xor, (.&.))
+import Data.Char
+import Foreign.C.Types (CSize)
+import GHC.Base (Int(..), ByteArray#, MutableByteArray#, newByteArray#,
+                 writeWord16Array#, indexWord16Array#, unsafeCoerce#, ord,
+                 iShiftL#)
+import GHC.ST (ST(..), runST)
+import GHC.Word (Word16(..))
+
+import qualified Data.Text.Lazy.IO as TIO
+import qualified Data.Text as T
+import qualified Data.Text.Internal as T
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ aLen :: a:Array -> {v:Nat | v = (aLen a)}  @-}
+
+{-@ maLen :: a:MArray s -> {v:Nat | v = (maLen a)}  @-}
+
+new          :: forall s. Int -> ST s (MArray s)
+unsafeWrite  :: MArray s -> Int -> Word16 -> ST s ()
+unsafeFreeze :: MArray s -> ST s Array
+unsafeIndex  :: Array -> Int -> Word16
+copyM        :: MArray s               -- ^ Destination
+             -> Int                    -- ^ Destination offset
+             -> MArray s               -- ^ Source
+             -> Int                    -- ^ Source offset
+             -> Int                    -- ^ Count
+             -> ST s ()
+
+{-@ memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO () @-}
+memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO ()
+memcpyM = undefined
+
+--------------------------------------------------------------------------------
+--- Helper Code
+--------------------------------------------------------------------------------
+{-@ shiftL :: i:Nat -> n:Nat -> {v:Nat | ((n = 1) => (v = (i * 2)))} @-}
+shiftL :: Int -> Int -> Int
+shiftL = undefined -- (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+pack :: String -> Text
+pack = undefined -- not "actually" using
+
+assert b a = Ex.assert b a
+
+
+data Text = Text Array Int Int
+
+{-@ tLength :: t:Text -> {v:_ | v = (tLen t)} @-}
+tLength (Text _ _ n)  =  n
+\end{code}
+
+</div>
+
+The `Text` Lifecycle
+--------------------
+`text` splits the reading and writing array operations between two
+types of arrays, immutable `Array`s and mutable `MArray`s. This leads to
+the following general lifecycle:
+
+![The lifecycle of a `Text`](/images/text-lifecycle.png)
+
+The main four array operations we care about are:
+
+1. **creating** an `MArray`,
+2. **writing** into an `MArray`,
+3. **freezing** an `MArray` into an `Array`, and
+4. **reading** from an `Array`.
+
+Creating an `MArray`
+--------------------
+
+The (mutable) `MArray` is a thin wrapper around GHC's primitive
+`MutableByteArray#`, additionally carrying the number of `Word16`s it
+can store.
+
+\begin{code}
+data MArray s = MArray { maBA  :: MutableByteArray# s
+                       , maLen :: !Int
+                       }
+\end{code}
+
+It doesn't make any sense to have a negative length, so we *refine*
+the data definition to require that `maLen` be non-negative. 
+
+\begin{code}
+{-@ data MArray s = MArray { maBA  :: MutableByteArray# s
+                           , maLen :: Nat
+                           }
+  @-}
+\end{code}
+
+
+\begin{code} As an added bonus, the above specification generates **field-accessor measures** that we will use inside the refined types:
+{-@ measure maLen :: MArray s -> Int
+    maLen (MArray a l) = l
+  @-}
+\end{code}
+
+We can use these accessor measures to define `MArray`s of size `N`:
+
+\begin{code}
+{-@ type MArrayN a N = {v:MArray a | (maLen v) = N} @-}
+\end{code}
+
+and we can use the above alias, to write a type that tracks the size
+of an `MArray` at the point where it is created:
+
+\begin{code}
+{-@ new :: forall s. n:Nat -> ST s (MArrayN s n) @-}
+new n
+  | n < 0 || n .&. highBit /= 0 = error "size overflow"
+  | otherwise = ST $ \s1# ->
+       case newByteArray# len# s1# of
+         (# s2#, marr# #) -> (# s2#, MArray marr# n #)
+  where !(I# len#) = bytesInArray n
+        highBit    = maxBound `xor` (maxBound `shiftR` 1)
+        bytesInArray n = n `shiftL` 1
+\end{code}
+
+`new n` is an `ST` action that produces an `MArray s` with `n` slots each 
+of which is 2 bytes (as internally `text` manipulates `Word16`s).
+
+The verification process here is quite simple; LH recognizes that 
+the `n` used to construct the returned array (`MArray marr# n`) 
+the same `n` passed to `new`. 
+
+Writing into an `MArray`
+------------------------
+
+Once we have *created* an `MArray`, we'll want to write our data into it. 
+
+A `Nat` is a valid index into an `MArray` if it is *strictly less than* 
+the size of the array.
+
+\begin{code}
+{-@ type MAValidI MA = {v:Nat | v < (maLen MA)} @-}
+\end{code}
+
+We use this valid index alias to refine the type of `unsafeWrite`
+
+\begin{code}
+{-@ unsafeWrite :: ma:MArray s -> MAValidI ma -> Word16 -> ST s () @-}
+unsafeWrite MArray{..} i@(I# i#) (W16# e#)
+  | i < 0 || i >= maLen = assert False $ error "out of bounds"
+  | otherwise = ST $ \s1# ->
+      case writeWord16Array# maBA i# e# s1# of
+        s2# -> (# s2#, () #)
+\end{code}
+
+Note that, when compiled with appropriate options, the implementation of
+`text` checks the bounds at run-time. However, LiquidHaskell can statically
+prove that the error branch is unreachable, i.e. the `assert` **cannot fail**
+(as long as the inputs adhere to the given specification) by giving `assert`
+the type:
+
+\begin{code}
+{-@ assert assert :: {v:Bool | (Prop v)} -> a -> a @-}
+\end{code}
+
+Bulk Writing into an `MArray`
+-----------------------------
+
+So now we can write individual `Word16`s into an array, but maybe we
+have a whole bunch of text we want to dump into the array. Remember,
+`text` is supposed to be fast! C has `memcpy` for cases like this but 
+it's notoriously unsafe; with the right type however, we can regain safety. 
+`text` provides a wrapper around `memcpy` to copy `n` elements from 
+one `MArray` to another.
+
+`copyM` requires two `MArray`s and valid offsets into each -- note
+that a valid offset is **not** necessarily a valid *index*, it may
+be one element out-of-bounds
+
+\begin{code}
+{-@ type MAValidO MA = {v:Nat | v <= (maLen MA)} @-}
+\end{code}
+
+-- and a `count` of elements to copy.
+The `count` must represent a valid region in each `MArray`, in
+other words `offset + count <= length` must hold for each array.
+
+\begin{code}
+{-@ copyM :: dest:MArray s
+          -> didx:MAValidO dest
+          -> src:MArray s
+          -> sidx:MAValidO src
+          -> {v:Nat | (((didx + v) <= (maLen dest))
+                    && ((sidx + v) <= (maLen src)))}
+          -> ST s ()
+  @-}
+copyM dest didx src sidx count
+    | count <= 0 = return ()
+    | otherwise =
+    assert (sidx + count <= maLen src) .
+    assert (didx + count <= maLen dest) .
+    unsafeIOToST $ memcpyM (maBA dest) (fromIntegral didx)
+                           (maBA src) (fromIntegral sidx)
+                           (fromIntegral count)
+\end{code}
+
+Again, the two `assert`s in the function were in the original code as 
+(optionally compiled out) run-time checks of the precondition, but with 
+LiquidHaskell we can actually *prove* that the `assert`s **always succeed**.
+
+Freezing an `MArray` into an `Array`
+------------------------------------
+
+Before we can package up our `MArray` into a `Text`, we need to
+*freeze* it, preventing any further mutation. The key property 
+here is of course that the frozen `Array` should have the same 
+length as the `MArray`.
+
+Just as `MArray` wraps a mutable array, `Array` wraps an *immutable*
+`ByteArray#` and carries its length in `Word16`s.
+
+\begin{code}
+data Array = Array { aBA  :: ByteArray#
+                   , aLen :: !Int
+                   }
+\end{code}
+
+As before, we get free accessor measures `aBA` and `aLen` just by
+refining the data definition
+
+\begin{code}
+{-@ data Array = Array { aBA  :: ByteArray#
+                       , aLen :: Nat
+                       }
+  @-}
+\end{code}
+
+so we can refer to the components of an `Array` in our refinements.
+Using these measures, we can define
+
+\begin{code}
+{-@ type ArrayN N = {v:Array | (aLen v) = N} @-}
+{-@ unsafeFreeze :: ma:MArray s -> ST s (ArrayN (maLen ma)) @-}
+unsafeFreeze MArray{..} = ST $ \s# ->
+                          (# s#, Array (unsafeCoerce# maBA) maLen #)
+\end{code}
+
+Again, LiquidHaskell is happy to prove our specification as we simply
+copy the length parameter `maLen` over into the `Array`.
+
+Reading from an `Array`
+------------------------
+Finally, we will eventually want to read a value out of the
+`Array`. As with `unsafeWrite` we require a valid index into the
+`Array`, which we denote using the `AValidI` alias.
+
+\begin{code}
+{-@ type AValidI A = {v:Nat | v < (aLen A)} @-}
+{-@ unsafeIndex :: a:Array -> AValidI a -> Word16 @-}
+unsafeIndex Array{..} i@(I# i#)
+  | i < 0 || i >= aLen = assert False $ error "out of bounds"
+  | otherwise = case indexWord16Array# aBA i# of
+                  r# -> (W16# r#)
+\end{code}
+
+As before, LiquidHaskell can easily prove that the error branch
+is unreachable, i.e. is *never* executed at run-time.
+
+Wrapping it all up
+------------------
+
+Now we can finally define the core datatype of the `text` package!
+A `Text` value consists of three fields:
+
+A. an `Array`,
+
+B. an `Int` offset into the *middle* of the array, and
+
+C. an `Int` length denoting the number of valid indices *after* the offset.
+
+We can specify the invariants for fields (b) and (c) with the refined type:
+
+\begin{code}
+{-@ data Text
+      = Text { tArr :: Array
+             , tOff :: {v:Nat | v      <= (aLen tArr)}
+             , tLen :: {v:Nat | v+tOff <= (aLen tArr)}
+             }
+  @-}
+\end{code}
+
+These invariants ensure that any *index* we pick between `tOff` and
+`tOff + tLen` will be a valid index into `tArr`. 
+
+As shown above with `new`, `unsafeWrite`, and `unsafeFreeze`, we can type the
+top-level function that creates a `Text` from a `[Char]` as:
+
+\begin{code}
+{-@ pack :: s:String -> {v:Text | (tLen v) = (len s)} @-}
+\end{code}
+
+Preventing Bleeds
+-----------------
+
+Now, let us close the circle and return to potentially *bleeding* function:
+
+\begin{code}
+charAt' (Text a o l) i = word2char $ unsafeIndex a (o+i)
+  where 
+    word2char          = chr . fromIntegral
+\end{code}
+
+Aha! LiquidHaskell flags the call to `unsafeIndex` because of course, `i` may fall
+outside the bounds of the given array `a`! We can remedy that by specifying
+a bound for the index:
+
+\begin{code}
+{-@ charAt :: t:Text -> {v:Nat | v < (tLen t)} -> Char @-}
+charAt (Text a o l) i = word2char $ unsafeIndex a (o+i)
+  where 
+    word2char         = chr . fromIntegral
+\end{code}
+
+That is, we can access the `i`th `Char` as long as `i` is a `Nat` less
+than the the size of the text, namely `tLen t`. Now LiquidHaskell is convinced
+that the call to `unsafeIndex` is safe, but of course, we have passed
+the burden of proof onto users of `charAt`.
+
+Now, if we try calling `charAt` as we did at the beginning
+
+\begin{code}
+test = [good,bad]
+  where
+    dog  = ['d','o','g']
+    good = charAt (pack dog) 2
+    bad  = charAt (pack dog) 3
+\end{code}
+
+we see that LiquidHaskell verifies the `good` call, but flags `bad` as
+**unsafe**.
+
+Enforcing Sanitization
+----------------------
+
+EDIT: As several folks have pointed out, the #heartbleed error was
+due to inputs not being properly sanitized. The above approach 
+**ensures, at compile time**, that proper sanitization has been 
+performed. 
+
+To see this in action, lets write a little function that just shows the 
+character at a given position:
+
+\begin{code}
+{-@ showCharAt :: t:_ -> {v:Nat | v < (tLen t)} -> _ @-}
+showCharAt t i = putStrLn $ show $ charAt t i
+\end{code}
+
+Now, the following function, that correctly sanitizes is **accepted**
+
+\begin{code}
+goodMain :: IO ()
+goodMain 
+  = do txt <- pack <$> getLine
+       i   <- readLn
+       if 0 <= i && i < tLength txt 
+         then showCharAt txt i 
+         else putStrLn "Bad Input!"
+\end{code}
+
+but this function, which has insufficient sanitization, is **rejected**
+
+\begin{code}
+badMain :: IO ()
+badMain 
+  = do txt <- pack <$> getLine 
+       i   <- readLn
+       if 0 <= i 
+         then showCharAt txt i 
+         else putStrLn "Bad Input!"
+\end{code}
+
+Thus, we can use LiquidHaskell to block, at compile time, any serious bleeding
+from pointers gone wild.
diff --git a/docs/blog/2014-08-15-a-finer-filter.lhs b/docs/blog/2014-08-15-a-finer-filter.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2014-08-15-a-finer-filter.lhs
@@ -0,0 +1,303 @@
+---
+layout: post
+title: "A Finer Filter"
+date: 2014-08-15 16:12
+author: Ranjit Jhala
+published: true
+comments: true
+external-url:
+categories: abstract-refinements 
+demo: filter.hs
+---
+
+This morning, I came across this [nice post](https://twitter.com/ertesx/status/500034598042996736) which describes how one can write a very expressive type for 
+`filter` using [singletons](https://hackage.haskell.org/package/singletons).
+
+Lets see how one might achieve this with [abstract refinements][absref].
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+
+{-@ LIQUID "--short-names" @-}
+
+module Filter (filter) where
+
+import Prelude hiding (filter)
+import Data.Set (Set)
+
+import Prelude hiding (filter)
+isPos, isEven, isOdd :: Int -> Maybe Int
+filter, filter3 :: (a -> Maybe a) -> [a] -> [a]
+
+{-@ measure elts :: [a] -> (Set a) 
+    elts ([])   = {v | Set_emp v }
+    elts (x:xs) = {v | v = Set_cup (Set_sng x) (elts xs) }
+  @-}
+ 
+\end{code}
+
+</div>
+
+Goal
+----
+
+What we're after is a way to write a `filter` function such that:
+
+\begin{code} 
+{-@ getPoss  :: [Int] -> [Pos] @-}
+getPoss      = filter isPos
+
+{-@ getEvens :: [Int] -> [Even] @-}
+getEvens     = filter isEven
+
+{-@ getOdds  :: [Int] -> [Odd] @-}
+getOdds      = filter isOdd
+\end{code}
+
+where `Pos`, `Even` and `Odd` are just subsets of `Int`:
+
+\begin{code}
+{-@ type Pos  = {v:Int| 0 < v}        @-}
+
+{-@ type Even = {v:Int| v mod 2 == 0} @-}
+
+{-@ type Odd  = {v:Int| v mod 2 /= 0} @-}
+\end{code}
+
+Take 1: Map, maybe?
+-------------------
+
+Bowing to the anti-boolean sentiment currently in the air, lets eschew 
+the classical approach where the predicates (`isPos` etc.) return `True` 
+or `False` and instead implement `filter` using a map.
+
+\begin{code}
+filter1          :: (a -> Maybe b) -> [a] -> [b]
+
+filter1 f []     = []
+filter1 f (x:xs) = case f x of
+                     Just y  -> y : filter1 f xs 
+                     Nothing ->     filter1 f xs
+\end{code}
+
+To complete the picture, we need just define the predicates as
+functions returning a `Maybe`:
+
+\begin{code}
+{- isPos          :: Int -> Maybe Pos  @-}
+isPos x
+  | x > 0          = Just x
+  | otherwise      = Nothing
+
+{- isEven         :: Int -> Maybe Even @-}
+isEven x
+  | x `mod` 2 == 0 = Just x
+  | otherwise      = Nothing
+
+{- isOdd          :: Int -> Maybe Odd  @-}
+isOdd x
+  | x `mod` 2 /= 0 = Just x
+  | otherwise      = Nothing
+\end{code}
+
+and now, we can achieve our goal!
+
+\begin{code}
+{-@ getPoss1 :: [Int] -> [Pos] @-}
+getPoss1     = filter1 isPos
+
+{-@ getEvens1 :: [Int] -> [Even] @-}
+getEvens1    = filter1 isEven
+
+{-@ getOdds1 :: [Int] -> [Odd] @-}
+getOdds1     = filter1 isOdd
+\end{code}
+
+**The Subset Guarantee**
+
+Well that was easy! Or was it?
+
+I fear we've *cheated* a little bit.
+
+One of the nice things about the *classical* `filter` is that by eyeballing
+the signature:
+
+\begin{spec}
+filter :: (a -> Bool) -> [a] -> [a]
+\end{spec}
+
+we are guaranteed, via parametricity, that the output list's elements are
+a *subset of* the input list's elements. The signature for our new-fangled
+
+\begin{spec}
+filter1 :: (a -> Maybe b) -> [a] -> [b]
+\end{spec}
+
+yields no such guarantee!
+
+In this case, things work out, because in each case, LiquidHaskell *instantiates*
+the type variables `a` and `b` in the signature of `filter1` suitably:
+
+* In `getPoss ` LH instantiates `a := Int` and `b := Pos`
+* In `getEvens` LH instantiates `a := Int` and `b := Even`
+* In `getOdds ` LH instantiates `a := Int` and `b := Odd`
+
+(Hover over the different instances of `filter1` above to confirm this.)
+
+But in general, we'd rather *not* lose the nice "subset" guarantee that the
+classical `filter` provides.
+
+
+Take 2: One Type Variable
+-------------------------
+
+Easy enough! Why do we need *two* type variables anyway?
+
+\begin{code}
+filter2          :: (a -> Maybe a) -> [a] -> [a]
+
+filter2 f []     = []
+filter2 f (x:xs) = case f x of
+                     Just y  -> y : filter2 f xs 
+                     Nothing ->     filter2 f xs
+\end{code}
+
+There! Now the `f` is forced to take or leave its input `x`, 
+and so we can breathe easy knowing that `filter2` returns a 
+subset of its inputs.
+
+But...
+
+\begin{code}
+{-@ getPoss2 :: [Int] -> [Pos] @-}
+getPoss2     = filter2 isPos
+
+{-@ getEvens2 :: [Int] -> [Even] @-}
+getEvens2    = filter2 isEven
+
+{-@ getOdds2 :: [Int] -> [Odd] @-}
+getOdds2     = filter2 isOdd
+\end{code}
+
+Yikes, LH is not impressed -- the red highlight indicates that LH is not
+convinced that the functions have the specified types.
+
+Perhaps you know why already?
+
+Since we used **the same** type variable `a` for *both* the 
+input *and* output, LH must instantiate `a` with a type that 
+matches *both* the input and output, i.e. is a *super-type*
+of both, which is simply `Int` in all the cases. 
+
+Consequently, we get the errors above -- "expected `Pos` but got `Int`".
+
+Take 3: Add Abstract Refinement
+-------------------------------
+
+What we need is a generic way of specifying that the 
+output of the predicate is not just an `a` but an `a` 
+that *also* enjoys whatever property we are filtering for. 
+
+This sounds like a job for [abstract refinements][absref] which
+let us parameterize a signature over its refinements:
+
+\begin{code}
+{-@ filter3      :: forall a <p :: a -> Prop>.
+                      (a -> Maybe a<p>) -> [a] -> [a<p>] @-}
+filter3 f []     = []
+filter3 f (x:xs) = case f x of
+                     Just x'  -> x' : filter3 f xs 
+                     Nothing ->       filter3 f xs
+\end{code}
+
+ Now, we've **decoupled** the filter-property from the type variable `a`.
+
+The input still is a mere `a`, but the output is an `a` with bells on,
+specifically, which satisfies the (abstract) refinement `p`.
+
+Voila!
+
+\begin{code}
+{-@ getPoss3  :: [Int] -> [Pos] @-}
+getPoss3      = filter3 isPos
+
+{-@ getEvens3 :: [Int] -> [Even] @-}
+getEvens3     = filter3 isEven
+
+{-@ getOdds3  :: [Int] -> [Odd] @-}
+getOdds3      = filter3 isOdd
+\end{code}
+
+Now, LH happily accepts each of the above.
+
+At each *use* of `filter` LH separately *instantiates* the `a` and
+the `p`. In each case, the `a` is just `Int` but the `p` is instantiated as:
+
++ In `getPoss ` LH instantiates `p := \v -> 0 <= v`
++ In `getEvens` LH instantiates `p := \v -> v mod 2 == 0`
++ In `getOdds ` LH instantiates `p := \v -> v mod 2 /= 0`
+
+That is, in each case, LH instantiates `p` with the refinement that describes
+the output type we are looking for.
+
+**Edit:** At this point, I was ready to go to bed, and so happily 
+declared victory and turned in. The next morning, [mypetclone](http://www.reddit.com/r/haskell/comments/2dozs5/liquidhaskell_a_finer_filter/cjrrx3y)
+graciously pointed out my folly: the signature for `filter3` makes no guarantees
+about the subset property. In fact, 
+
+\begin{code}
+doubles = filter3 (\x -> Just (x + x)) 
+\end{code}
+
+typechecks just fine, while `doubles` clearly violates the subset property. 
+
+Take 4: 
+-------
+
+I suppose the moral is that it may be tricky -- for me at least! -- to read more into
+a type than what it *actually says*. Fortunately, with refinements, our types can say
+quite a lot.
+
+In particular, lets make the subset property explicit, by
+
+1. Requiring the predicate return its input (or nothing), and,
+2. Ensuring  the output is indeed a subset of the inputs.
+
+\begin{code}
+{-@ filter      :: forall a <p :: a -> Prop>.
+                       (x:a -> Maybe {v:a<p> | v = x})
+                    -> xs:[a]
+                    -> {v:[a<p>] | Set_sub (elts v) (elts xs)} @-}
+
+filter f []     = []
+filter f (x:xs) = case f x of
+                    Just x'  -> x' : filter f xs 
+                    Nothing ->       filter f xs
+\end{code}
+
+where `elts` describes the [set of elements in a list][sets].
+
+**Note:** The *implementation* of each of the above `filter` functions are
+the same; they only differ in their type *specification*.
+
+Conclusion
+----------
+
+And so, using abstract refinements, we've written a `filter` whose signature guarantees:
+
+* The outputs must be a *subset* of the inputs, and
+* The outputs indeed satisfy the property being filtered for.
+
+Another thing that I've learnt from this exercise, is that the old 
+school `Boolean` approach has its merits. Take a look at the clever 
+"latent predicates" technique of [Tobin-Hochstadt and Felleisen][racket]
+or this lovely new [paper by Kaki and Jagannathan][catalyst] which
+shows how refinements can be further generalized to make Boolean filters fine.
+
+[sets]:   /blog/2013/03/26/talking-about-sets.lhs/ 
+[absref]:   /blog/2013/06/03/abstracting-over-refinements.lhs/ 
+[racket]:   http://www.ccs.neu.edu/racket/pubs/popl08-thf.pdf
+[catalyst]: http://gowthamk.github.io/docs/icfp77-kaki.pdf
diff --git a/docs/blog/2015-01-30-okasakis-lazy-queue.lhs b/docs/blog/2015-01-30-okasakis-lazy-queue.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2015-01-30-okasakis-lazy-queue.lhs
@@ -0,0 +1,338 @@
+---
+layout: post
+title: "Okasaki's Lazy Queues"
+date: 2015-01-28
+comments: true
+external-url:
+author: Ranjit Jhala 
+published: true
+categories: measures
+demo: LazyQueue.hs
+---
+
+The "Hello World!" example for fancy type systems is probably the sized vector
+or list `append` function ("The output has size equal to the *sum* of the
+inputs!").  One the one hand, it is perfect: simple enough to explain without
+pages of code, yet complex enough to show off whats cool about dependency. On
+the other hand, like the sweater I'm sporting right now, it's a bit well-worn and
+worse, was never wholly convincing ("Why do I *care* what the *size* of the
+output list is anyway?")
+
+Recently, I came across a nice example that is almost as simple, but is also
+well motivated: Okasaki's beautiful [Lazy Amortized Queues][okasaki95].  This
+structure leans heavily on an invariant to provide fast *insertion* and
+*deletion*. Let's see how to enforce that invariant with LiquidHaskell.
+
+<!-- more -->
+
+<div class="hidden">
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--total"          @-}
+{-@ LIQUID "--maxparams=3"    @-}
+
+module LazyQueue (Queue, insert, remove, emp) where
+
+import Prelude hiding (length)
+
+-- | Size function actually returns the size: (Duh!)
+
+{-@ size :: q:SList a -> {v:Nat | v = size q} @-}
+data Queue a = Q  { front :: SList a
+                  , back  :: SList a
+                  }
+
+-- Source: Okasaki, JFP 1995
+-- http://www.westpoint.edu/eecs/SiteAssets/SitePages/Faculty%20Publication%20Documents/Okasaki/jfp95queue.pdf
+
+\end{code}
+</div>
+
+Queues 
+------
+
+A [queue][queue-wiki] is a structure into which we can `insert` and `remove` data
+such that the order in which the data is removed is the same as the order in which
+it was inserted.
+
+![A Queue](/images/queue.png)
+
+To implement a queue *efficiently* one needs to have rapid access to both
+the "head" as well as the "tail" because we `remove` elements from former
+and `insert` elements into the latter. This is quite straightforward with
+explicit pointers and mutation -- one uses an old school linked list and
+maintains pointers to the head and the tail. But can we implement the
+structure efficiently without having stoop so low?
+
+Queues = Pair of Lists
+----------------------
+
+Almost two decades ago, Chris Okasaki came up with a very cunning way
+to implement queues using a *pair* of lists -- let's call them `front`
+and `back` which represent the corresponding parts of the Queue.
+
++ To `insert` elements, we just *cons* them onto the `back` list,
++ To `remove` elements, we just *un-cons* them from the `front` list.
+
+![A Queue is Two Lists](/images/queue-lists.png)
+
+
+The catch is that we need to shunt elements from the back to the
+front every so often, e.g. when
+
+1. a `remove` call is triggered, and
+2. the `front` list is empty,
+
+We can transfer the elements from the `back` to the `front`.
+
+
+![Transferring Elements from Back to Front](/images/queue-rotate.png)
+
+Okasaki observed that every element is only moved *once* from the
+front to the back; hence, the time for `insert` and `lookup` could be
+`O(1)` when *amortized* over all the operations. Awesome, right?!
+
+Almost. Some set of unlucky `remove` calls (which occur when
+the `front` is empty) are stuck paying the bill. They have a
+rather high latency up to `O(n)` where `n` is the total number
+of operations. Oops.
+
+Queue = Balanced Lazy Lists
+---------------------------
+
+This is where Okasaki's beautiful insights kick in. Okasaki
+observed that all we need to do is to enforce a simple invariant:
+
+**Invariant:** Size of `front` >= Size of `back`
+
+Now, if the lists are *lazy* i.e. only constructed as the head
+value is demanded, then a single `remove` needs only a tiny `O(log n)`
+in the worst case, and so no single `remove` is stuck paying the bill.
+
+Let's see how to represent these Queues and ensure the crucial invariant(s)
+with LiquidHaskell. What we need are the following ingredients:
+
+1. A type for `List`s, and a way to track their `size`,
+
+2. A type for `Queue`s which encodes the *balance* invariant -- ``front longer than back",
+
+3. A way to implement the `insert`, `remove` and `transfer` operations.
+
+Sized Lists
+------------
+
+The first part is super easy. Let's define a type:
+
+\begin{code}
+data SList a = SL { size :: Int, elems :: [a]}
+\end{code}
+
+We have a special field that saves the `size` because otherwise, we
+have a linear time computation that wrecks Okasaki's careful
+analysis. (Actually, he presents a variant which does *not* require
+saving the size as well, but that's for another day.)
+
+But how can we be sure that `size` is indeed the *real size* of `elems`?
+
+Let's write a function to *measure* the real size:
+
+\begin{code}
+{-@ measure realSize @-}
+realSize      :: [a] -> Int
+realSize []     = 0
+realSize (_:xs) = 1 + realSize xs
+\end{code}
+
+and now, we can simply specify a *refined* type for `SList` that ensures
+that the *real* size is saved in the `size` field:
+
+\begin{code}
+{-@ data SList a = SL {
+       size  :: Nat 
+     , elems :: {v:[a] | realSize v = size}
+     }
+  @-}
+\end{code}
+
+As a sanity check, consider this:
+
+\begin{code}
+okList  = SL 1 ["cat"]    -- accepted
+
+badList = SL 1 []         -- rejected
+\end{code}
+
+It is helpful to define a few aliases for `SList`s of a size `N` and
+non-empty `SList`s:
+
+\begin{code}
+-- | SList of size N
+
+{-@ type SListN a N = {v:SList a | size v = N} @-}
+
+-- | Non-Empty SLists:
+
+{-@ type NEList a = {v:SList a | size v > 0} @-}
+
+\end{code}
+
+Finally, we can define a basic API for `SList`.
+
+**To Construct** lists, we use `nil` and `cons`:
+
+\begin{code}
+{-@ nil          :: SListN a 0  @-}
+nil              = SL 0 []
+
+{-@ cons         :: a -> xs:SList a -> SListN a {size xs + 1}   @-}
+cons x (SL n xs) = SL (n+1) (x:xs)
+\end{code}
+
+**To Destruct** lists, we have `hd` and `tl`.
+
+\begin{code}
+{-@ tl           :: xs:NEList a -> SListN a {size xs - 1}  @-}
+tl (SL n (_:xs)) = SL (n-1) xs
+
+{-@ hd           :: xs:NEList a -> a @-}
+hd (SL _ (x:_))  = x 
+\end{code}
+
+Don't worry, they are perfectly *safe* as LiquidHaskell will make
+sure we *only* call these operators on non-empty `SList`s. For example,
+
+\begin{code}
+okHd  = hd okList       -- accepted
+
+badHd = hd (tl okList)  -- rejected
+\end{code}
+
+
+Queue Type
+-----------
+
+Now, it is quite straightforward to define the `Queue` type, as a pair of lists,
+`front` and `back`, such that the latter is always smaller than the former:
+
+\begin{code}
+{-@ data Queue a = Q {
+       front :: SList a 
+     , back  :: SListLE a (size front)
+     }
+  @-}
+\end{code}
+
+Where the alias `SListLE a L` corresponds to lists with less than `N` elements:
+
+\begin{code}
+{-@ type SListLE a N = {v:SList a | size v <= N} @-}
+\end{code}
+
+As a quick check, notice that we *cannot represent illegal Queues*:
+
+\begin{code}
+okQ  = Q okList nil  -- accepted, |front| > |back| 
+
+badQ = Q nil okList  -- rejected, |front| < |back|
+\end{code}
+
+**To Measure Queue Size** let us define a function
+
+\begin{code}
+{-@ measure qsize @-}
+qsize         :: Queue a -> Int
+qsize (Q l r) = size l + size r
+\end{code}
+
+This will prove helpful to define `Queue`s of a given size `N` and
+non-empty `Queue`s (from which values can be safely removed.)
+
+\begin{code}
+{-@ type QueueN a N = {v:Queue a | N = qsize v} @-}
+{-@ type NEQueue a  = {v:Queue a | 0 < qsize v} @-}
+\end{code}
+
+
+Queue Operations
+----------------
+
+Almost there! Now all that remains is to define the `Queue` API. The
+code below is more or less identical to Okasaki's (I prefer `front`
+and `back` to his `left` and `right`.)
+
+
+**The Empty Queue** is simply one where both `front` and `back` are `nil`.
+
+\begin{code}
+{-@ emp :: QueueN a 0 @-}
+emp = Q nil nil
+\end{code}
+
+**To Insert** an element we just `cons` it to the `back` list, and call
+the *smart constructor* `makeq` to ensure that the balance invariant holds:
+
+\begin{code}
+{-@ insert       :: a -> q:Queue a -> QueueN a {qsize q + 1}   @-}
+insert e (Q f b) = makeq f (e `cons` b)
+\end{code}
+
+**To Remove** an element we pop it off the `front` by using `hd` and `tl`.
+Notice that the `remove` is only called on non-empty `Queue`s, which together
+with the key balance invariant, ensures that the calls to `hd` and `tl` are safe.
+
+\begin{code}
+{-@ remove       :: q:NEQueue a -> (a, QueueN a {qsize q - 1}) @-}
+remove (Q f b)   = (hd f, makeq (tl f) b)
+\end{code}
+
+*Aside:* Why didn't we (or Okasaki) use a pattern match here?
+
+**To Ensure the Invariant** we use the smart constructor `makeq`,
+which is where the heavy lifting, such as it is, happens. The
+constructor takes two lists, the front `f` and back `b` and if they
+are balanced, directly returns the `Queue`, and otherwise transfers
+the elements from `b` over using `rot`ate.
+
+\begin{code}
+{-@ makeq :: f:SList a
+          -> b:SListLE a {size f + 1 }
+          -> QueueN a {size f + size b}
+  @-}
+makeq l r
+  | size r <= size l = Q l r
+  | otherwise        = Q (rot l r nil) nil
+\end{code}
+
+**The Rotate** function is only called when the `back` is one larger
+than the `front` (we never let things drift beyond that). It is
+arranged so that it the `hd` is built up fast, before the entire
+computation finishes; which, combined with laziness provides the
+efficient worst-case guarantee.
+
+\begin{code}
+{-@ rot :: l:SList a
+        -> r:SListN _ {1 + size l}
+        -> a:SList _
+        -> SListN _ {size l + size r + size a}
+  @-}
+rot l r a
+  | size l == 0 = hd r `cons` a
+  | otherwise   = hd l `cons` rot (tl l) (tl r) (hd r `cons` a)
+\end{code}
+
+Conclusion
+----------
+
+Well there you have it; Okasaki's beautiful lazy Queue, with the
+invariants easily expressed and checked with LiquidHaskell. I find
+this example particularly interesting because the refinements express
+invariants that are critical for efficiency, and furthermore the code
+introspects on the `size` in order to guarantee the invariants.  Plus,
+it's just marginally more complicated than `append` and so, (I hope!)
+was easy to follow.
+
+
+
+[okasaki95]: http://www.westpoint.edu/eecs/SiteAssets/SitePages/Faculty%20Publication%20Documents/Okasaki/jfp95queue.pdf
+
+[queue-wiki]: http://en.wikipedia.org/wiki/Queue_%28abstract_data_type%29
diff --git a/docs/blog/2015-06-13-bounded-refinement-types.lhs b/docs/blog/2015-06-13-bounded-refinement-types.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2015-06-13-bounded-refinement-types.lhs
@@ -0,0 +1,337 @@
+---
+layout: post
+title: "Bounded Refinement Types"
+date: 2015-06-13
+comments: true
+external-url:
+author: Niki Vazou
+published: true
+categories: bounded-refinements, abstract-refinements, function-composition
+demo: BoundedRefinementTypes.hs
+---
+
+While refinement types let SMT solvers do a lot of the "boring" analysis,
+they are limited to decidable (first order) logics which can prevent us
+from writing *modular* and *reusable* specifications for *higher-order*
+functions. Next, lets see why modularity is important, and how we can
+recover it using a new technique called **Bounded Refinements**.
+
+<!-- more -->
+
+<div class="hidden">
+\begin{code}
+module BoundedRefinementTypes where
+import Prelude hiding ((.), maximum)
+import Language.Haskell.Liquid.Prelude
+
+incr  :: Int -> Int
+incr2 :: Int -> Int
+incr3 :: Int -> Int
+
+compose1 :: (Int -> Int) -> (Int -> Int) -> Int -> Int
+compose1 f g x = f (g x)
+incr2'     :: Int -> Int
+compose2 :: (b -> c) -> (a -> b) -> a -> c
+\end{code}
+</div>
+
+Reusable Specifications
+-----------------------
+
+Let us suppose, for just a moment, that we live in a dystopian future
+where parametric polymorphism and typeclasses have been eliminated
+from Haskell. Now, consider the function that returns the largest
+element of a list:
+
+\begin{code}
+maximum         :: [Int] -> Int
+maximum [x]    = x
+maximum (x:xs) = max x (maximum xs)
+  where
+    max a b    = if a < b then b else a
+\end{code}
+
+Now, suppose we have refinements:
+
+\begin{code}
+{-@ type Pos  = {v:Int | 0 < v} @-}
+{-@ type Neg  = {v:Int | 0 > v} @-}
+\end{code}
+
+**Here's the problem:** how can *specify* the behavior of `maximum`
+in a way that lets us verify that:
+
+\begin{code}
+{-@ posMax :: [Int] -> Pos @-}
+posMax xs = maximum [x | x <- xs, x > 0]
+
+{-@ negMax :: [Int] -> Neg @-}
+negMax xs = maximum [x | x <- xs, x < 0]
+\end{code}
+
+In the first case, the output of `maximum` must be
+a `Pos` because *every* input was a `Pos`. Thus, we
+might try to type:
+
+\begin{spec}
+maximum :: [Pos] -> Pos
+\end{spec}
+
+But this specification will not let us verify `negMax`.
+Thus, we have a problem: how can we write a precise
+specification for `maximum` that we can *reuse* at
+different call-sites. Further, how can we do so
+enumerating *a priori* the possible contexts (e.g.
+`Pos` and `Neg` lists) in which the function may
+be used?
+
+Abstracting Refinements
+-----------------------
+
+The first idea is one we've [seen before][AbstractRefinements].
+Notice that `maximum` returns _one of_ the elements in its input
+list. Thus, if *every* element of the list satisfies some
+refinement `p` then the output value is also guaranteed to
+satisfy `p`. We formalize this notion by *abstracting refinements*
+over type specifications. That is, we can type `maximum` as:
+
+\begin{code}
+{-@ maximum :: forall <p:: Int -> Prop>. [Int<p>] -> Int<p> @-}
+\end{code}
+
+Informally, `Int<p>` stands for `{v:Int | p v}`, that is, `Int`s that
+satisfy the property `p`. The signature states that for any property
+`p` (of `Int`s), if the input is a list of elements satisfying `p` then
+the output is an `Int` satisfying `p`. We can coax SMT solvers into
+proving the above type by encoding `p v` as an [uninterpreted function](https://en.wikipedia.org/wiki/Uninterpreted_function)
+in the refinement logic.
+
+Thus, refinement abstraction is analagous to type abstraction: it lets us
+parameterize signatures over *all* refinements (analogously, types) that
+may be _passed in_ at the call-site.
+
+Capturing Dependencies between Relations
+----------------------------------------
+
+Unfortunately, in the dependent setting, this is not enough.
+Consider `incr` which bumps up its input by 1:
+
+\begin{code}
+{-@ incr :: x:Int -> {v:Int | v = x + 1} @-}
+incr x = x + 1
+\end{code}
+
+We can use `incr` to write and check:
+
+\begin{code}
+{-@ incr2 :: x:Int -> {v:Int | v = x + 2} @-}
+incr2 x = let y = incr x
+              z = incr y
+          in
+              z
+\end{code}
+
+LH uses the specification of `incr` to infer that
+
++ `y :: {v:Int | v = x + 1}`
++ `z :: {v:Int | v = y + 1}`
+
+and hence, that the result `z` equals `x + 2`.
+
+Now, you're probably wondering to yourself: isn't
+this what _function composition_ is for? Indeed!
+Lets define:
+
+\begin{code}
+{-@ compose' :: (b -> c) -> (a -> b) -> a -> c @-}
+compose' f g x = f (g x)
+\end{code}
+
+Now, we might try:
+
+\begin{code}
+{-@ incr2' :: x:Int -> {v:Int | v = x + 2} @-}
+incr2' = compose' incr incr
+\end{code}
+
+**Problem 1: Cannot Relate Abstracted Types**
+
+LH _rejects_ the above. This might seem counterintuitive but
+in fact, its the right thing to do given the specification of
+`compose'` -- at this call-site, each of `a`, `b` and `c` are
+instantiated with `Int` as we have no way of *relating* the
+invariants associated with those types, e.g. that `b` is one
+greater than `a` and `c` is one greater than `b`.
+
+**Problem 2: Cannot Reuse Concrete Types**
+
+At the other extreme, we might try to give compose a concrete
+signature:
+
+\begin{code}
+{-@ compose'' :: (y:Int -> {z:Int | z = y + 1})
+              -> (x:Int -> {z:Int | z = x + 1})
+              ->  x:Int -> {z:Int | z = x + 2} @-}
+compose'' f g x = f (g x)
+\end{code}
+
+This time, LH does verify
+
+\begin{code}
+{-@ incr2'' :: x:Int -> {v:Int | v = x + 2} @-}
+incr2'' = compose'' incr incr
+\end{code}
+
+but this is a pyrhhic victory as we can only `compose` the
+toy `incr` function (with itself!) and any attempt to use
+it elsewhere will throw a type error.
+
+Goal: Relate Refinements But Keep them Abstract
+-----------------------------------------------
+
+The above toy example illustrates the _real_ problem: how
+can we **relate** the invariants of the type parameters for
+`compose` while simultaneously keeping them **abstract** ?
+
+**Can Abstract Refinements Help?**
+
+HEREHEREHERE
+
+Onto abstracting the type of compose we follow the route of [Abstract Refinements][AbstractRefinements].
+We make a second attempt to type function composition and give
+`compose2` a type that states that
+forall abstract refinements `p`, `q` and `r`
+if (1) the first functional argument `f` returns a value that satisfies a relation `p` with respect to its argument `y`, and
+   (2) the second functional argument `g` returns a value that satisfies a relation `q` with respect to its argument `x`,
+then the result function returns a value that satisfies a relation `r` with respect to its argument `x`:
+
+\begin{code}
+{-@ compose''' :: forall <p :: b -> c -> Prop,
+                          q :: a -> b -> Prop,
+                          r :: a -> c -> Prop>.
+                   (y:b -> c<p y>)
+                -> (x:a -> b<q x>)
+                -> x:a -> c<r x>                   @-}
+\end{code}
+
+With this type for `compose2` liquidHaskell will prove that composing `incr` by itself
+gives a function that increased its argument by `2`:
+
+\begin{code}
+{-@ incr2'' :: x:Int -> {v:Int | v = x + 2} @-}
+incr2''      = compose2 incr incr
+\end{code}
+
+To do so, liquidHaskell will employ the Abstract Refinement Types inference and guess
+the appropriate instantiations for `p`, `q`, and `r`.
+That is, liquidHaskell will infer that `p` and `q` relate two consecutive numbers
+`p, q := \x v -> v = x + 1`
+while `r` relates two numbers with distance `2`:
+`r := \x v -> v = x + 2`.
+Thus, at this specific call site the abstract type of `compose2` will be instantiated to
+the concrete type we gave to `compose1`.
+And, verification of `incr2''` will succeed.
+
+
+What is the catch now?
+In this second attempt we abstracted the type of `compose2` too much!
+In fact, LiquidHaskell cannot prove that the body of `compose2` satisfies its type, just because it does not.
+
+\begin{code}
+compose2 f g x = let z = g x in f z
+\end{code}
+
+By the precondition of `compose2` we know the result refinements of the functional arguments `f` and `g`.
+From the type of `g` we know that `z` satisfies `q` on `x`, i.e. `q x z` holds.
+Similarly, from the type of `f` we know that `f z` satisfies `q` on `x`, i.e. `q x z` holds.
+
+With these, liquidHaskell needs to prove that the result `f z` satisfies `r` on `x`, i.e., `r x z` holds.
+The required property `r x z` is not satisfied for _arbitrary_ abstract refinements `p`, `q` and `r`, but only for ones that satisfy a _chain property_ that states that for all `x`, `y` and `z`, if `q x y` and `p y z` holds, then `r x z` holds:
+
+<br>
+
+`\ x y z -> q x y ==> p y z ==> r x z`
+
+Bound Abstract Refinements by the Chain Property
+------------------------------------------------
+
+We made two attempts to type `compose`.
+The first one "failed" as our type was unrealistically specific.
+The second failed as it was unsoundly general.
+In our third and final attempt
+we give `compose` a type that is abstracted over three abstract refinements `p`, `q` and `r`.
+But, this time the three refinements are not arbitrary:
+they are bounded to satisfy the chain property.
+
+We encode the chain property as a boolean Haskell function:
+
+\begin{code}
+chain :: (b -> c -> Bool) -> (a -> b -> Bool)
+      -> (a -> c -> Bool) ->  a -> b -> c -> Bool
+chain p q r = \ x y z -> q x y ==> p y z ==> r x z
+\end{code}
+
+Then we use the new liquidHaskell keyword `bound` to lift the
+`chain` function into the a logical bound that
+can be used to constrain abstract refinements
+
+\begin{code}
+{-@ bound chain @-}
+\end{code}
+
+The above bound annotation defines the bound `Chain` that is used as a
+constraint that relates the abstract refinements `p`, `q` and `r`
+in the type signature of `compose`
+
+\begin{code}
+{-@
+compose :: forall <p :: b -> c -> Prop,
+                   q :: a -> b -> Prop,
+                   r :: a -> c -> Prop>.
+           (Chain b c a p q r)
+        => (y:b -> c<p y>)
+        -> (z:a -> b<q z>)
+        ->  x:a -> c<r x>
+@-}
+\end{code}
+
+This type of `compose` is both sound and general enough,
+as now we can easily prove that composing `incr` with `incr2`
+results in a function that increases its argument by `3`.
+
+\begin{code}
+{-@ incr2''' :: x:Int -> {v:Int | v = x + 2} @-}
+incr2'''      = compose incr incr
+
+{-@ incr3'' :: x:Int -> {v:Int | v = x + 3} @-}
+incr3''      = compose incr2'' incr
+\end{code}
+
+
+Conclusion
+----------
+We saw how bounds in refinement types allow us to specify a
+precise and general type for function composition.
+Bounds in refinement types are (haskell typeclases-like) constraints
+that constraint the abstract refinement variables to specify certain properties.
+
+We note that liquidHaskell desugars bounds to unbounded refinement types,
+thus verification is still performed decidably using the power of the SMT solvers.
+
+Moreover, function composition is not the exclusive user of
+Bounded Refinement Types.
+On the contrary, we used Bounded Refinement Types
+to verify a variety of code, from list-filtering to relational databases.
+
+Read more about bounds in our [ICFP'15 paper][icfp15],
+and stay tuned!
+
+<div class="hidden">
+\begin{code}
+\end{code}
+</div>
+
+
+[icfp15]: http://goto.ucsd.edu/~nvazou/icfp15/main.pdf
+[AbstractRefinements]: http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/blog/2013/06/03/abstracting-over-refinements.lhs
+[queue-wiki]: http://en.wikipedia.org/wiki/Queue_%28abstract_data_type%29
diff --git a/docs/blog/2016-09-01-normal-forms.lhs b/docs/blog/2016-09-01-normal-forms.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2016-09-01-normal-forms.lhs
@@ -0,0 +1,411 @@
+---
+layout: post
+title: "Normal Forms"
+date: 2016-09-05
+comments: true
+external-url:
+author: Ranjit Jhala
+published: true
+categories: measures
+demo: ANF.hs
+---
+
+I have been preparing an undergraduate course on
+Compilers in which we build a compiler that crunches
+an ML-like language to X86 assembly.
+One of my favorite steps in the compilation is the
+[conversion to A-Normal Form (ANF)][anf-felleisen]
+where, informally speaking, each call or primitive
+operation's arguments are **immediate** values,
+i.e. constants or variable lookups whose values can
+be loaded with a single machine instruction. For example,
+the expression
+
+```haskell
+((2 + 3) * (12 - 4)) * (7 + 8)
+```
+
+has the A-Normal Form:
+
+```haskell
+"let anf0 = 2 + 3
+     anf1 = 12 - 4
+     anf2 = anf0 * anf1
+     anf3 = 7 + 8
+  in
+    anf2 * anf3
+```
+
+The usual presentation of ANF conversion
+is very elegant but relies upon a clever
+use of [continuations][anf-might].
+Lets look at another perhaps simpler approach,
+where we can use refinements to light the way.
+
+<!-- more -->
+
+<div class="hidden">
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--total"          @-}
+
+module ANF (Op (..), Expr (..), isImm, isAnf, toAnf) where
+
+import Control.Monad.State.Lazy
+
+mkLet :: [(Var, AnfExpr)] -> AnfExpr -> AnfExpr
+imm, immExpr :: Expr -> AnfM ([(Var, AnfExpr)], ImmExpr)
+anf   :: Expr -> AnfM AnfExpr
+
+-- data IExpr
+  -- = IInt Int
+  -- | IVar Var
+--
+-- data AExpr
+  -- = AImm IExpr
+  -- | ABin Op    IExpr IExpr
+  -- | ALet Var   AExpr AExpr
+  -- | ALam Var   AExpr
+  -- | AApp IExpr IExpr
+
+type AnfExpr = Expr
+type ImmExpr = Expr
+\end{code}
+</div>
+
+Source Language
+---------------
+
+Lets commence by defining the source language that we wish to work with:
+
+\begin{code}
+data Expr
+  = EInt  Int               -- ^ Integers
+  | EVar  Var               -- ^ Variables
+  | EBin  Op   Expr Expr    -- ^ Binary Operators
+  | ELet  Var  Expr Expr    -- ^ Let-binders
+  | ELam  Var  Expr         -- ^ Function definitions
+  | EApp  Expr Expr         -- ^ Function applications
+  deriving (Show)
+\end{code}
+
+The language, defined by `Expr` has integers, variables, binary operators,
+let-binders and function definitions (lambdas) and calls (applications).
+In the above, `Var` and `Op` are simply:
+
+\begin{code}
+type Var = String
+
+data Op  = Plus | Minus | Times
+         deriving (Show)
+\end{code}
+
+For example, the source expression above corresponds to the value:
+
+\begin{code}
+-- ((2 + 3) * (12 - 4)) * (7 + 8)
+srcExpr :: Expr
+srcExpr = EBin Times
+            (EBin Times
+              (EBin Plus  (EInt  2) (EInt 3))
+              (EBin Minus (EInt 12) (EInt 4)))
+            (EBin Plus (EInt 7) (EInt 8))
+\end{code}
+
+A-Normal Form
+-------------
+
+Before we can describe a _conversion_ to A-Normal Form (ANF),
+we must pin down what ANF _is_. Our informal description was:
+``each call or primitive operation's arguments are immediate
+  values, i.e. constants or variable lookups''.
+
+We _could_ define a brand new datatypes, say `IExpr` and `AExpr`
+whose values correspond to _immediate_ and _ANF_ terms.
+(Try it, as an exercise.) Unfortunately, doing so leads to a
+bunch of code duplication, e.g. duplicate printers for `Expr`
+and `AExpr`. Instead, lets see how we can use refinements to
+carve out suitable subsets.
+
+**Immediate Expressions**
+
+An `Expr` is **immediate** if it is a `Number` or a `Var`;
+we can formalize this as a Haskell predicate:
+
+\begin{code}
+{-@ measure isImm @-}
+isImm :: Expr -> Bool
+isImm (EInt _) = True
+isImm (EVar _) = True
+isImm _        = False
+\end{code}
+
+and then we can use the predicate to define a refinement type
+for _immediate_ expressions:
+
+\begin{code}
+{-@ type ImmExpr = {v:Expr | isImm v} @-}
+\end{code}
+
+For example, `e1` is immediate but `e2` is not:
+
+\begin{code}
+{-@ e1 :: ImmExpr @-}
+e1 = EInt 7
+
+{-@ e2 :: ImmExpr @-}
+e2 = EBin Plus e1 e1
+\end{code}
+
+**ANF Expressions**
+
+Similiarly, an `Expr` is in **ANF** if all arguments for operators
+and applications are **immediate**. Once again, we can formalize
+this intuition as a Haskell predicate:
+
+\begin{code}
+{-@ measure isAnf @-}
+isAnf :: Expr -> Bool
+isAnf (EInt {})      = True
+isAnf (EVar {})      = True
+isAnf (EBin _ e1 e2) = isImm e1 && isImm e2  -- args for operators
+isAnf (EApp e1 e2)   = isImm e1 && isImm e2  -- must be immediate,
+isAnf (ELet _ e1 e2) = isAnf e1 && isAnf e2  -- and sub-expressions
+isAnf (ELam _ e)     = isAnf e               -- must be in ANF
+\end{code}
+
+and then use the predicate to define the subset of _legal_ ANF expressions:
+
+\begin{code}
+{-@ type AnfExpr = {v:Expr | isAnf v} @-}
+\end{code}
+
+For example, `e2` above _is_ in ANF but `e3` is not:
+
+\begin{code}
+{-@ e2' :: AnfExpr @-}
+e2' = EBin Plus e1 e1
+
+{-@ e3 :: AnfExpr @-}
+e3 = EBin Plus e2' e2'
+\end{code}
+
+ANF Conversion: Intuition
+-------------------------
+
+Now that we have clearly demarcated the territories belonging to plain `Expr`,
+immediate `ImmExpr` and A-Normal `AnfExpr`, lets see how we can convert the
+former to the latter.
+
+Our goal is to convert expressions like
+
+```haskell
+((2 + 3) * (12 - 4)) * (7 + 8)
+```
+
+into
+
+```haskell
+let anf0 = 2 + 3
+    anf1 = 12 - 4
+    anf2 = anf0 * anf1
+    anf3 = 7 + 8
+in
+    anf2 * anf3
+```
+
+Generalising a bit, we want to convert
+
+```haskell
+e1 + e2
+```
+
+into
+
+```
+let x1  = a1  ... xn  = an
+    x1' = a1' ... xm' = am'
+in
+    v1 + v2
+```
+
+where, `v1` and `v2` are immediate, and `ai` are ANF.
+
+**Making Arguments Immediate**
+
+In other words, the key requirement is a way to crunch
+arbitrary _argument expressions_ like `e1` into **a pair**
+
+```haskell
+([(x1, a1) ... (xn, an)], v1)
+```
+
+where
+
+1. `a1...an` are `AnfExpr`, and
+2. `v1` is an immediate `ImmExpr`
+
+such that `e1` is _equivalent_ to `let x1 = a1 ... xn = an in v1`.
+Thus, we need a function
+
+```haskell
+imm :: Expr -> ([(Var, AnfExpr)], ImmExpr)
+```
+
+which we will use to **make arguments immediate** thereby yielding
+a top level conversion function
+
+```haskell
+anf :: Expr -> AnfExpr
+```
+
+As we need to generate "temporary" intermediate
+binders, it will be convenient to work within a
+monad that generates `fresh` variables:
+
+\begin{code}
+type AnfM a = State Int a
+
+fresh :: AnfM Var
+fresh = do
+  n <- get
+  put (n+1)
+  return ("anf" ++ show n)
+\end{code}
+
+Thus, the conversion functions will have the types:
+
+```haskell
+anf :: Expr -> AnfM AnfExpr
+imm :: Expr -> AnfM ([(Var, AnfExpr)], ImmExpr)
+```
+
+ANF Conversion: Code
+--------------------
+
+We can now define the top-level conversion thus:
+
+\begin{code}
+--------------------------------------------------------------------------------
+{-@ anf :: Expr -> AnfM AnfExpr @-}
+--------------------------------------------------------------------------------
+anf (EInt n) =
+  return (EInt n)
+
+anf (EVar x) =
+  return (EVar x)
+
+anf (ELet x e1 e2) = do
+  a1 <- anf e1
+  a2 <- anf e2
+  return (ELet x a1 a2)
+
+anf (EBin o e1 e2) = do
+  (b1s, v1) <- imm e1
+  (b2s, v2) <- imm e2
+  return (mkLet (b1s ++ b2s) (EBin o v1 v2))
+
+anf (ELam x e) = do
+  a <- anf e
+  return (ELam x a)
+
+anf (EApp e1 e2) = do
+  (b1s, v1) <- imm e1
+  (b2s, v2) <- imm e2
+  return (mkLet (b1s ++ b2s) (EApp v1 v2))
+\end{code}
+
+In `anf` the real work happens inside `imm` which takes an arbitary
+_argument_ expression and makes it **immediate** by generating temporary
+(ANF) bindings. The resulting bindings (and immediate values) are
+composed by the helper `mkLet` that takes a list of binders and a body
+`AnfExpr` and stitches them into a single `AnfExpr`:
+
+\begin{code}
+{-@ mkLet :: [(Var, AnfExpr)] -> AnfExpr -> AnfExpr @-}
+mkLet []         e' = e'
+mkLet ((x,e):bs) e' = ELet x e (mkLet bs e')
+\end{code}
+
+The arguments are made immediate by `imm` defined as:
+
+\begin{code}
+--------------------------------------------------------------------------------
+{-@ imm :: Expr -> AnfM ([(Var, AnfExpr)], ImmExpr) @-}
+--------------------------------------------------------------------------------
+imm (EInt n)       = return ([], EInt n)
+imm (EVar x)       = return ([], EVar x)
+imm e@(ELet {})    = immExpr e
+imm e@(ELam {})    = immExpr e
+imm (EBin o e1 e2) = imm2 e1 e2 (EBin o)
+imm (EApp e1 e2)   = imm2 e1 e2 EApp
+\end{code}
+
+* Numbers and variables are already immediate, and are returned directly.
+
+* Let-binders and lambdas are simply converted to ANF, and assigned to a fresh
+  binder:
+
+\begin{code}
+{-@ immExpr :: Expr -> AnfM ([(Var, AnfExpr)], ImmExpr) @-}
+immExpr e = do
+  a <- anf e
+  t <- fresh
+  return ([(t, a)], EVar t)
+\end{code}
+
+* Finally, binary operators and applications are converted by `imm2` that
+  takes two arbitrary expressions and an expression constructor, yielding
+  the anf-binders and immediate expression.
+
+\begin{code}
+imm2 :: Expr -> Expr -> (ImmExpr -> ImmExpr -> AnfExpr)
+     -> AnfM ([(Var, AnfExpr)], ImmExpr)
+imm2 e1 e2 f = do
+  (b1s, v1) <- imm e1
+  (b2s, v2) <- imm e2
+  t         <- fresh
+  let bs'    = b1s ++ b2s ++ [(t, f v1 v2)]
+  return      (bs', EVar t)
+\end{code}
+
+
+You can run it thus:
+
+\begin{code}
+toAnf :: Expr -> AnfExpr
+toAnf e = evalState (anf e) 0
+\end{code}
+
+```haskell
+ghci> toAnf srcExpr
+ELet "anf0" (EBin Plus (EInt 2) (EInt 3))
+ (ELet "anf1" (EBin Minus (EInt 12) (EInt 4))
+   (ELet "anf2" (EBin Times (EVar "anf0") (EVar "anf1"))
+     (ELet "anf3" (EBin Plus (EInt 7) (EInt 8))
+       (EBin Times (EVar "anf2") (EVar "anf3")))))
+```
+
+which, can be pretty-printed to yield exactly the outcome desired at the top:
+
+```haskell
+let anf0 = 2 + 3
+    anf1 = 12 - 4
+    anf2 = anf0 * anf1
+    anf3 = 7 + 8
+in
+    anf2 * anf3
+```
+
+
+There! The refinements make this tricky conversion quite
+straightforward and natural, without requiring us to
+duplicate types and code. As an exercise, can you use
+refinements to:
+
+1. Port the classic [continuation-based conversion ?][anf-might]
+2. Check that the conversion yields [well-scoped terms ?][lh-scoped]
+
+[lh-scoped]: http://ucsd-progsys.github.io/liquidhaskell-tutorial/10-case-study-associative-maps.html#/using-maps-well-scoped-expressions
+[anf-felleisen]: https://users.soe.ucsc.edu/~cormac/papers/pldi93.pdf
+[anf-might]: http://matt.might.net/articles/a-normalization/
diff --git a/docs/blog/2016-09-18-refinement-reflection.lhs b/docs/blog/2016-09-18-refinement-reflection.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2016-09-18-refinement-reflection.lhs
@@ -0,0 +1,408 @@
+---
+layout: post
+title: "Refinement Reflection: Haskell as a theorem prover"
+date: 2016-09-18
+comments: true
+external-url:
+author: Niki Vazou
+published: true
+categories: reflection
+demo: RefinementReflection.hs
+---
+
+We've taught LiquidHaskell a new trick that we call ``Refinement Reflection''
+which lets us turn Haskell into a theorem prover capable of proving arbitrary
+properties of code. The key idea is to **reflect** the code of the function into
+its **output type**, which lets us then reason about the function at the
+(refinement) type level. Lets see how to use refinement types to express a
+theorem, for example that fibonacci is a monotonically increasing function, 
+then write plain Haskell code to reify a paper-and-pencil-style proof 
+for that theorem, that can be machine checked by LiquidHaskell.
+
+<!-- more -->
+
+<br>
+<br>
+<br>
+
+<div class="row-fluid">
+  <div class="span12 pagination-centered">
+  <img src="https://eyesofodysseus.files.wordpress.com/2013/06/full-moon-over-ocean-reflection.jpg"
+       alt="Reflection" width="300">
+       <br>
+       <br>
+       <br>
+       The beauty of Liquid Reflection.
+       <br>
+       <br>
+       <br>
+  </div>
+</div>
+
+
+<div class="hidden">
+\begin{code}
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+module RefinementReflection where
+import Language.Haskell.Liquid.ProofCombinators
+
+fib :: Int -> Int
+propPlusComm :: Int -> Int -> Proof 
+propOnePlueOne :: () -> Proof 
+fibTwo :: () -> Proof 
+fibCongruence :: Int -> Int -> Proof
+fibUp :: Int -> Proof 
+fibTwoPretty :: Proof 
+fibThree :: () -> Proof 
+fMono :: (Int -> Int)
+      -> (Int -> Proof)
+      -> Int
+      -> Int 
+      -> Proof 
+fibMono :: Int -> Int -> Proof 
+
+\end{code}
+</div>
+
+Shallow vs. Deep Specifications
+-------------------------------
+
+Up to now, we have been using Liquid Haskell to specify and verify "shallow"
+specifications that abstractly describe the behavior of functions.  For example,
+below, we specify and verify that `fib`restricted to natural numbers, always
+terminates returning a natural number.
+
+\begin{code}
+{-@ fib :: i:Nat -> Nat / [i] @-}
+fib i | i == 0    = 0 
+      | i == 1    = 1 
+      | otherwise = fib (i-1) + fib (i-2)
+\end{code}
+
+In this post we present how refinement reflection is used to verify 
+"deep" specifications that use the exact definition of Haskell functions. 
+For example, we will prove that the Haskell `fib` function is increasing.
+
+
+
+Propositions
+------------
+
+To begin, we import [ProofCombinators][proofcomb], a (Liquid) Haskell 
+library that defines and manipulates logical proofs. 
+
+```haskell
+import Language.Haskell.Liquid.ProofCombinators
+```
+
+A `Proof` is a data type that carries no run time information
+
+```haskell
+type Proof = ()
+```
+
+but can be refined with desired logical propositions.
+For example, the following type states that `1 + 1 == 2`
+
+\begin{code}
+{-@ type OnePlusOne = {v: Proof | 1 + 1 == 2} @-}
+\end{code}
+
+Since the `v` and `Proof` are irrelevant, we may as well abbreviate 
+the above to 
+
+\begin{code}
+{-@ type OnePlusOne' = { 1 + 1 == 2 } @-}
+\end{code}
+
+
+As another example, the following function type declares 
+that _for each_ `x` and `y` the plus operator commutes. 
+
+\begin{code}
+{-@ type PlusComm = x:Int -> y:Int -> {x + y == y + x} @-} 
+\end{code}
+
+
+
+Trivial Proofs
+--------------
+
+We prove the above theorems using Haskell programs. 
+The `ProofCombinators` module defines the `trivial` proof
+
+```haskell
+trivial :: Proof 
+trivial = ()
+```
+
+and the "casting" operator `(***)` that makes proof terms look 
+nice:
+
+```haskell
+data QED = QED
+
+(***) :: a -> QED -> Proof
+_ *** _ = ()
+```
+
+Using the underlying SMT's knowledge on linear arithmetic, 
+we can trivially prove the above propositions.
+
+\begin{code}
+{-@ propOnePlusOne :: _ -> OnePlusOne @-} 
+propOnePlusOne _ = trivial *** QED 
+
+{-@ propPlusComm :: PlusComm @-} 
+propPlusComm _ _ = trivial *** QED 
+\end{code}
+
+
+We saw how we use SMT's knowledge on linear arithmetic 
+to trivially prove arithmetic properties. But how can 
+we prove ``deep'' properties on Haskell's functions?
+
+
+Refinement Reflection 
+---------------------
+
+Refinement Reflection allows deep specification and 
+verification by reflecting the code implementing a Haskell
+function into the function’s output refinement type.
+
+Refinement Reflection proceeds in 3 steps: definition, reflection, and application.
+Consider reflecting the definition of `fib` into the logic
+
+\begin{code}
+{-@ reflect fib @-}
+\end{code}
+
+then the following three reflection steps will occur. 
+
+Step 1: Definition 
+------------------
+
+Reflection of the Haskell function `fib` defines in logic 
+an _uninterpreted_ function `fib` that satisfies the congruence axiom.
+
+In the logic the function `fib` is defined.
+
+```haskell
+fib :: Int -> Int 
+```
+
+SMT only knows that `fib` satisfies the congruence axiom.
+
+\begin{code}
+{-@ fibCongruence :: i:Nat -> j:Nat -> {i == j => fib i == fib j} @-}
+fibCongruence _ _ = trivial *** QED 
+\end{code}
+
+Other than congruence, SMT knowns nothing for the function `fib`,
+until reflection happens!
+
+
+Step 2: Reflection
+------------------
+
+As a second step, Liquid Haskell connects the Haskell function `fib`
+with the homonymous logical function, 
+by reflecting the implementation of `fib` in its result type. 
+
+
+The result type of `fib` is automatically strengthened to the following.
+
+```haskell
+fib :: i:Nat -> {v:Nat | v == fib i && v = fibP i }
+```
+
+That is, the result satisfies the `fibP` predicate
+exactly reflecting the implementation of `fib`.
+
+```haskell
+fibP i = if i == 0 then 0 else
+         if i == 1 then 1 else
+         fib (i-1) + fib (i-2)
+```
+
+Step 3: Application 
+-------------------
+
+With the reflected refinement type,
+each application of `fib` automatically unfolds the definition of `fib` 
+once. 
+As an example, applying `fib` to `0`, `1`, and `2` allows us to prove that `fib 2 == 1`:
+
+\begin{code}
+{-@ fibTwo :: _ -> { fib 2 == 1 } @-}
+fibTwo _ = [fib 0, fib 1, fib 2] *** QED
+\end{code}
+
+Though valid, the above `fibTwo` proof is not pretty! 
+
+
+Structuring Proofs 
+------------------
+
+To make our proofs look nice, we use combinators from 
+the `ProofCombinators` library, which exports a family 
+of operators `(*.)` where `*` comes from the theory of 
+linear arithmetic and the refinement type of `x *. y` 
+
++ **requires** that `x *. y` holds and 
++ **ensures** that the returned value is equal to `x`.
+
+For example, `(==.)` and `(<=.)` are predefined in `ProofCombinators` as
+
+```haskell
+(==.) :: x:a -> y:{a| x==y} -> {v:a| v==x}
+x ==. _ = x
+
+(<=.) :: x:a -> y:{a| x<=y} -> {v:a| v==x}
+x <=. _ = x
+```
+
+Using these predefined operators, we construct paper and pencil-like proofs 
+for the `fib` function.
+
+\begin{code}
+{-@ fibTwoPretty :: { fib 2 == 1 } @-}
+fibTwoPretty 
+  =   fib 2 
+  ==. fib 1 + fib 0 
+  *** QED
+\end{code}
+
+
+
+Because operator 
+-----------------
+
+To allow the reuse of existing proofs, `ProofCombinators` defines the because 
+operator `(∵)`
+
+```haskell
+(∵) :: (Proof -> a) -> Proof -> a
+f ∵ y = f y
+```
+
+For example, `fib 3 == 2` holds because `fib 2 == 1`:
+
+\begin{code}
+{-@ fibThree :: _ -> { fib 3 == 2 } @-}
+fibThree _ 
+  =   fib 3 
+  ==. fib 2 + fib 1
+  ==. 1     + 1      ∵ fibTwoPretty
+  ==. 2 
+  *** QED
+\end{code}
+
+
+
+Proofs by Induction (i.e. Recursion) 
+------------------------------------
+
+Next, combining the above operators we specify and prove that 
+`fib` is increasing, that is for each natural number `i`, 
+`fib i <= fib (i+1)`. 
+
+We specify the theorem as a refinement type for `fibUp`
+and use Haskell code to persuade Liquid Haskell that 
+the theorem holds. 
+
+\begin{code}
+{-@ fibUp :: i:Nat -> {fib i <= fib (i+1)} @-}
+fibUp i
+  | i == 0
+  =   fib 0 <. fib 1
+  *** QED
+
+  | i == 1
+  =   fib 1 <=. fib 1 + fib 0 <=. fib 2
+  *** QED
+
+  | otherwise
+  =   fib i
+  ==. fib (i-1) + fib (i-2)
+  <=. fib i     + fib (i-2) ∵ fibUp (i-1)
+  <=. fib i     + fib (i-1) ∵ fibUp (i-2)
+  <=. fib (i+1)
+  *** QED
+\end{code}
+
+The proof proceeds _by induction on_ `i`. 
+
++ The base cases `i == 0` and `i == 1` are represented 
+  as Haskell's case splitting. 
+
++ The inductive hypothesis is represented by recursive calls 
+  on smaller inputs. 
+
+Finally, the SMT solves arithmetic reasoning to conclude the proof.  
+
+Higher Order Theorems
+----------------------
+
+Refinement Reflection can be used to express and verify higher order theorems!
+For example, `fMono` specifies that each locally increasing function is monotonic! 
+
+\begin{code}
+{-@ fMono :: f:(Nat -> Int)
+          -> fUp:(z:Nat -> {f z <= f (z+1)})
+          -> x:Nat
+          -> y:{Nat|x < y}
+          -> {f x <= f y} / [y] 
+  @-}
+fMono f thm x y  
+  | x + 1 == y
+  = f y ==. f (x + 1)
+         >. f x       ∵ thm x
+        *** QED
+
+  | x + 1 < y
+  = f x
+  <.  f (y-1)         ∵ fMono f thm x (y-1)
+  <.  f y             ∵ thm (y-1)
+  *** QED
+\end{code}
+
+Again, the recursive implementation of `fMono` depicts the paper and pencil 
+proof of `fMono` by induction on the decreasing argument `/ [y]`. 
+
+Since `fib` is proven to be locally increasing by `fUp`, we use `fMono` 
+to prove that `fib` is monotonic. 
+
+\begin{code}
+{-@ fibMono :: n:Nat -> m:{Nat | n < m }  -> {fib n <= fib m} @-}
+fibMono = fMono fib fibUp
+\end{code}
+
+
+Conclusion
+----------
+
+We saw how refinement reflection turns Haskell
+into a theorem prover by reflecting the code 
+implementing a Haskell function into the 
+function’s output refinement type.
+
+Refinement Types are used to express theorems, 
+Haskell code is used to prove such theorems
+expressing paper pencil proofs, and Liquid Haskell 
+verifies the validity of the proofs!
+
+Proving `fib` monotonic is great, but this is Haskell!
+Wouldn’t it be nice to prove theorems about inductive data types 
+and higher order functions? Like fusions and folds? 
+Or program equivalence on run-time optimizations like map-reduce?
+
+Stay tuned!
+
+Even better, if you happen you be in Nara for ICFP'16, 
+come to my [CUFP tutorial][cufp16] for more!
+
+
+[cufp16]: http://cufp.org/2016/t6-niki-vazou-liquid-haskell-intro.html
+[proofcomb]:https://github.com/ucsd-progsys/liquidhaskell/blob/develop/include/Language/Haskell/Liquid/ProofCombinators.hs
diff --git a/docs/blog/2016-10-06-structural-induction.lhs b/docs/blog/2016-10-06-structural-induction.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2016-10-06-structural-induction.lhs
@@ -0,0 +1,280 @@
+---
+layout: post
+title: "Refinement Reflection on ADTs: Lists are Monoids"
+date: 2016-10-06
+comments: true
+external-url:
+author: Niki Vazou
+published: true
+categories: reflection, induction, measures, monoids
+demo: MonoidList.hs
+---
+
+[Previously][refinement-reflection] we saw how Refinement Reflection
+can be used to write and prove **in Haskell** theorems **about Haskell**
+functions and have such proofs machine checked.
+
+Today, we will see how Refinement Reflection works on **recursive data types**.
+
+As an example, we will prove that **lists are monoids** (under nil and append).
+
+Lets see how to express
+
+* the (monoid) laws as liquid types,
+* the (monoid) proofs as plain haskell functions,
+
+and have LiquidHaskell check that the code indeed
+proves the corresponding laws.
+
+<!-- more -->
+
+<br>
+<br>
+<br>
+
+<div class="row-fluid">
+  <div class="span12 pagination-centered">
+  <img src="http://www.aaronartprints.org/images/Paintings/4597.jpg"
+       alt="Recursion" width="300">
+       <br>
+       <br>
+       <br>
+       Recursive Paper and Pencil Proofs.
+       "Drawing Hands" by Escher.
+       <br>
+       <br>
+       <br>
+  </div>
+</div>
+
+
+<div class="hidden">
+\begin{code}
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+module StructuralInduction where
+import Language.Haskell.Liquid.ProofCombinators
+
+import Prelude hiding (length)
+
+length :: List a -> Int
+leftId :: List a -> Proof
+rightId :: List a -> Proof
+associativity :: List a -> List a -> List a -> Proof
+\end{code}
+</div>
+
+Lists
+-----
+
+First, lets define the `List a` data type
+
+\begin{code}
+data List a = N | C a (List a)
+\end{code}
+
+Induction on Lists
+------------------
+
+As we will see, *proofs* by structural induction will correspond to
+*programs* that perform *recursion* on lists. To keep things legit,
+we must verify that those programs are total and terminating.
+
+To that end, lets define a `length` function that
+computes the natural number that is the size of a
+list.
+
+\begin{code}
+{-@ measure length               @-}
+{-@ length      :: List a -> Nat @-}
+length N        = 0
+length (C x xs) = 1 + length xs
+\end{code}
+
+We lift `length` in the logic, as a [measure][the-advantage-of-measures].
+
+We can now tell Liquid Haskell that when proving termination
+on recursive functions with a list argument `xs`, it should
+check whether the `length xs` is decreasing.
+
+\begin{code}
+{-@ data List [length] a = N | C {hd :: a, tl :: List a} @-}
+\end{code}
+
+
+Reflecting Lists into the Logic
+-------------------------------
+
+To talk about lists in the logic, we use the annotation
+
+\begin{code}
+{-@ LIQUID "--exact-data-cons" @-}
+\end{code}
+
+which **automatically** derives measures for
+
+* *testing* if a value has a given data constructor, and
+* *extracting* the corresponding field's value.
+
+For our example, LH will automatically derive the following
+functions in the refinement logic.
+
+\begin{spec}
+isN :: L a -> Bool         -- Haskell's null
+isC :: L a -> Bool         -- Haskell's not . null
+
+select_C_1 :: L a -> a     -- Haskell's head
+select_C_2 :: L a -> L a   -- Haskell's tail
+\end{spec}
+
+A programmer *never* sees the above operators; they are internally
+used by LH to **reflect** Haskell functions into the refinement logic,
+as we shall see shortly.
+
+Defining the Monoid Operators
+-----------------------------
+
+A structure is a monoid, when it has two operators:
+
+* the identity element `empty` and
+* an associative operator `<>`.
+
+Lets define these two operators for our `List`.
+
+* the identity element is the empty list, and
+* the associative operator `<>` is list append.
+
+\begin{code}
+{-@ reflect empty @-}
+empty  :: List a
+empty  = N
+
+{-@ infix   <> @-}
+{-@ reflect <> @-}
+(<>)           :: List a -> List a -> List a
+N        <> ys = ys
+(C x xs) <> ys = C x (xs <> ys)
+\end{code}
+
+LiquidHaskell automatically checked that the recursive `(<>)` 
+is terminating, by checking that the `length` of its first
+argument is decreasing. Since both the above operators are 
+provably terminating, LH lets us reflect them into logic.
+
+As with our [previous][refinement-reflection]
+`fibonacci` example, reflection of a function
+into logic, means strengthening the result type
+of the function with its implementation.
+
+Thus, the **automatically** derived, strengthened
+types for `empty` and `(<>)` will be
+
+\begin{spec}
+empty   :: {v:List a | v == empty && v == N }
+
+(<>) :: xs:List a -> ys:List a
+     -> {v:List a | v == xs <> ys &&
+                    v == if isN xs then ys else
+                         C (select_C_1 xs) (select_C_2 xs <> ys)
+        }
+\end{spec}
+
+In effect, the derived checker and selector functions are used
+to translate Haskell to logic. The above is just to *explain*
+how LH reasons about the operators; the programmer never (directly) 
+reads or writes the operators `isN` or `select_C_1` etc.
+
+Proving the Monoid Laws
+------------------------
+
+Finally, we have set everything up, (actually LiquidHaskell
+did most of the work for us) and we are ready to prove the
+monoid laws for the `List`.
+
+First we prove left identity of `empty`.
+
+\begin{code}
+{-@ leftId  :: x:List a -> { empty <> x == x } @-}
+leftId x
+   =   empty <> x
+   ==. N <> x
+   ==. x
+   *** QED
+\end{code}
+
+This proof was trivial, because left identity is satisfied
+by the way we defined `(<>)`.
+
+Next, we prove right identity of `empty`.
+
+\begin{code}
+{-@ rightId  :: x:List a -> { x <> empty  == x } @-}
+rightId N
+   =   N <> empty
+   ==. N
+   *** QED
+
+rightId (C x xs)
+   =   (C x xs) <> empty
+   ==. C x (xs <> empty)
+   ==. C x xs        ∵ rightId xs
+   *** QED
+\end{code}
+
+This proof is more tricky, as it requires **structural induction** which is
+encoded in LH proofs simply as **recursion**.  LH ensures that the inductive
+hypothesis is appropriately applied by checking that the recursive proof is
+total and terminating.  In the `rightId` case, for termination, Liquid Haskell
+checked that `length xs < length (C x xs)`.
+
+It turns out that we can prove lots of properties about lists using structural 
+induction, encoded in Haskell as
+
+* case splitting,
+* recursive calls, and
+* rewriting,
+
+To see a last example, lets prove the associativity of `(<>)`.
+
+\begin{code}
+{-@ associativity :: x:List a -> y:List a -> z:List a
+                  -> { x <> (y <> z) == (x <> y) <> z } @-}
+associativity N y z
+  =   N <> (y <> z)
+  ==. y <> z
+  ==. (N <> y) <> z
+  *** QED
+
+associativity (C x xs) y z
+  =  (C x xs) <> (y <> z)
+  ==. C x (xs <> (y <> z))
+  ==. C x ((xs <> y) <> z) ∵ associativity xs y z
+  ==. (C x (xs <> y)) <> z
+  ==. ((C x xs) <> y) <> z
+  *** QED
+\end{code}
+
+The above proof of associativity reifies the paper and pencil 
+proof by structural induction.
+
+With that, we can safely conclude that our user defined list
+is a monoid!
+
+
+Conclusion
+----------
+
+We saw how Refinement Reflection can be used to
+
+- specify properties of `ADTs`,
+- naturally encode structural inductive proofs of these properties, and
+- have these proofs machine checked by Liquid Haskell.
+
+Why is this useful? Because the theorems we prove refer to your Haskell
+functions!  Thus you (or in the future, the compiler) can use properties like
+monoid or monad laws to optimize your Haskell code.  In the future, we will
+present examples of code optimizations using monoid laws. Stay tuned!
+
+
+[refinement-reflection]: http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/blog/2016/09/18/refinement-reflection.lhs/
+[the-advantage-of-measures]: http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/blog/2014/02/11/the-advantage-of-measures.lhs/
diff --git a/docs/blog/2016-12-25-isomorphisms.lhs b/docs/blog/2016-12-25-isomorphisms.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2016-12-25-isomorphisms.lhs
@@ -0,0 +1,342 @@
+---
+layout: post
+title: Isomorphisms for Proof Reductions
+date: 2016-12-25
+comments: true
+external-url:
+author: Vikraman Choudhury and Niki Vazou
+published: true
+categories: reflection 
+demo: Iso.hs
+---
+
+[Previously][refinement-reflection] we saw how Refinement Reflection
+can be used to write and prove **in Haskell** theorems **about Haskell**
+functions and have such proofs machine checked by Liquid Haskell.
+
+As a limitation, Liquid Haskell offers no proof generation techniques: 
+The user needs to manually provide all the proofs. 
+
+Today we will see how proof generation can be simplified by data type isomorphisms. 
+
+As an example, a user defined `Peano` data type enjoyes all the 
+arithmetic properties of natural numbers since `Peano` and natural numbers 
+are provably **isomorphic**. 
+
+<!-- more -->
+
+<br>
+<br>
+<br>
+
+<div class="row-fluid">
+  <div class="span12 pagination-centered">
+  <img src="http://www.aaronartprints.org/images/Paintings/4597.jpg"
+       alt="Recursion" width="300">
+       <br>
+       <br>
+       <br>
+       Recursive Paper and Pencil Proofs.
+       "Drawing Hands" by Escher.
+       <br>
+       <br>
+       <br>
+  </div>
+</div>
+
+
+<div class="hidden">
+\begin{code}
+{-@ LIQUID "--higherorder" @-}
+{-@ LIQUID "--totalhaskell" @-}
+{-@ LIQUID "--exactdc" @-}
+{-@ LIQUID "--diffcheck" @-}
+{-@ LIQUID "--eliminate=some" @-}
+
+module Iso where
+
+import Language.Haskell.Liquid.ProofCombinators
+\end{code}
+
+</div>
+
+First, we define `Peano` numbers as a data type 
+and the function `leqPeano` that compares two peano numbers.
+
+
+\begin{code}
+{-@ data Peano [toNat] = Z | S Peano @-}
+data Peano = Z | S Peano deriving (Eq)
+
+{-@ axiomatize leqPeano @-}
+leqPeano :: Peano -> Peano -> Bool
+leqPeano Z _         = True
+leqPeano _ Z         = False
+leqPeano (S n) (S m) = leqPeano n m
+\end{code}
+
+We can use Refinement Reflection to provide an 
+explicit proof that comparison on peano numbers is *total*, 
+that is, for every two numbers `n` and `m` 
+either `leqPeano n m` or `leqPeano m n` always holds. 
+
+\begin{code}
+{-@ leqNTotal :: n:Peano -> m:Peano 
+              -> {(leqPeano n m) || (leqPeano m n)} 
+              / [toNat n + toNat m] @-}
+leqNTotal :: Peano -> Peano -> Proof
+leqNTotal Z m = leqPeano Z m *** QED
+leqNTotal n Z = leqPeano Z n *** QED
+leqNTotal (S n) (S m)
+  =   (leqPeano (S n) (S m) || leqPeano (S m) (S n))
+  ==. (leqPeano n m || leqPeano (S m) (S n)) 
+      ? (leqNTotal n m)
+  ==. (leqPeano n m || leqPeano m n) 
+      ? (leqNTotal m n)
+  *** QED
+\end{code}
+
+The proof proceeds by induction on the sum of `n` and `m`. 
+Liquid Haskell captures this generalized induction by 
+ensuring that the value `toNat n + toNat m` is decreasing
+where `toNat` maps Peano to Natural numbers. 
+
+\begin{code}
+{-@ measure toNat @-}
+{-@ toNat :: Peano -> Nat @-}
+toNat :: Peano -> Int
+toNat Z = 0
+toNat (S n) = 1 + toNat n
+\end{code}
+
+Note, that the type `Nat` is just a refinement for the Haskell's integers
+\begin{spec}
+type Nat = {v:Int | 0 <= v}
+\end{spec}
+
+
+First, we'll express verified typeclasses using Haskell records, but with LiquidHaskell refinements to express laws. As
+an example, let's define `VerifiedOrd`, which is the same as the `Ord` typeclass, but with total order laws added.
+
+\begin{code}
+{-@ data VerifiedOrd a = VerifiedOrd {
+      leq     :: a -> a -> Bool
+    , refl    :: x:a -> { leq x x }
+    , antisym :: x:a -> y:a -> { leq x y && leq y x ==> x == y }
+    , trans   :: x:a -> y:a -> z:a -> { leq x y && leq y z ==> leq x z }
+    , total   :: x:a -> y:a -> { leq x y || leq y x }
+    }
+@-}
+data VerifiedOrd a = VerifiedOrd {
+    leq     :: a -> a -> Bool
+  , refl    :: a -> Proof
+  , antisym :: a -> a -> Proof
+  , trans   :: a -> a -> a -> Proof
+  , total   :: a -> a -> Proof
+}
+\end{code}
+
+The `leq` function represents the `<=` operator in `Ord`, and `refl`, `antisym`, `trans`, `total`, express the
+reflexivity, antisymmetry, transitivity and totality properties respectively, that a total order requires. Notice how
+the refinements express the laws, and the actual code is simply a function that returns `Proof` or `()`.
+
+Now, let's see how to define some simple verified instances. We need to instantiate `leq` for our type, "reflect" it
+into the logic, and prove all the required properties. For primitive types like `Int` or `Double`, it's "trivial"
+because we trust the SMT solver which already knows about integers.
+
+\begin{code}
+{-@ axiomatize leqInt @-}
+leqInt :: Int -> Int -> Bool
+leqInt x y = x <= y
+
+{-@ leqIntRefl :: x:Int -> { leqInt x x } @-}
+leqIntRefl :: Int -> Proof
+leqIntRefl x = leqInt x x ==. x <= x *** QED
+
+{-@ leqIntAntisym :: x:Int -> y:Int -> { leqInt x y && leqInt y x ==> x == y } @-}
+leqIntAntisym :: Int -> Int -> Proof
+leqIntAntisym x y = (leqInt x y && leqInt y x) ==. (x <= y && y <= x) ==. x == y *** QED
+
+{-@ leqIntTrans :: x:Int -> y:Int -> z:Int -> { leqInt x y && leqInt y z ==> leqInt x z } @-}
+leqIntTrans :: Int -> Int -> Int -> Proof
+leqIntTrans x y z = (leqInt x y && leqInt y z) ==. (x <= y && y <= z) ==. x <= z ==. leqInt x z *** QED
+
+{-@ leqIntTotal :: x:Int -> y:Int -> { leqInt x y || leqInt y x } @-}
+leqIntTotal :: Int -> Int -> Proof
+leqIntTotal x y = (leqInt x y || leqInt y x) ==. (x <= y || y <= x) *** QED
+
+vordInt :: VerifiedOrd Int
+vordInt = VerifiedOrd leqInt leqIntRefl leqIntAntisym leqIntTrans leqIntTotal
+\end{code}
+
+How about a complex datatype? Let's consider an inductive datatype, the peano natural numbers. Not surprisingly, the
+proofs follow by induction. For conciseness, we only show totality and elide the rest.
+
+Writing down proofs for more complex datatypes is tedious, it requires case analysis for each constructor and using the
+induction hypothesis. However, we can decompose Haskell datatypes into sums and products, and we can build up compound
+proofs using isomorphisms! To that end, we design some machinery to express isomorphisms, and prove that laws are
+preserved under isomorphic images.
+
+\begin{code}
+{-@ data Iso a b = Iso {
+      to   :: a -> b
+    , from :: b -> a
+    , tof  :: y:b -> { to (from y) == y }
+    , fot  :: x:a -> { from (to x) == x }
+    }
+@-}
+data Iso a b = Iso {
+    to   :: a -> b
+  , from :: b -> a
+  , tof  :: b -> Proof
+  , fot  :: a -> Proof
+}
+\end{code}
+
+An isomorphism between types `a` and `b` is a pair of functions `to :: a -> b` and `from :: b -> a` that are mutually
+inverse to each other. We now claim that total order laws are preserved under `Iso`; this amounts to building up a
+`VerifiedOrd b`, given a `VerifiedOrd a` and an `Iso a b`.
+
+\begin{code}
+{-@ axiomatize leqFrom @-}
+leqFrom :: (a -> a -> Bool)
+        -> (b -> a)
+        -> (b -> b -> Bool)
+leqFrom leqa from x y = leqa (from x) (from y)
+
+{-@ leqFromRefl :: leqa:(a -> a -> Bool) -> leqaRefl:(x:a -> { leqa x x })
+                -> from:(b -> a)
+                -> x:b -> { leqFrom leqa from x x }
+@-}
+leqFromRefl :: (a -> a -> Bool) -> (a -> Proof)
+            -> (b -> a)
+            -> b -> Proof
+leqFromRefl leqa leqaRefl from x =
+      leqFrom leqa from x x
+  ==. leqa (from x) (from x)
+  ==. True ? leqaRefl (from x)
+  *** QED
+
+{-@ leqFromAntisym :: leqa:(a -> a -> Bool)
+                   -> leqaAntisym:(x:a -> y:a -> { leqa x y && leqa y x ==> x == y })
+                   -> to:(a -> b) -> from:(b -> a) -> tof:(y:b -> { to (from y) == y })
+                   -> x:b -> y:b -> { leqFrom leqa from x y && leqFrom leqa from y x ==> x == y }
+@-}
+leqFromAntisym :: (Eq a, Eq b)
+               => (a -> a -> Bool) -> (a -> a -> Proof)
+               -> (a -> b) -> (b -> a) -> (b -> Proof)
+               -> b -> b -> Proof
+leqFromAntisym leqa leqaAntisym to from tof x y
+  =   (leqFrom leqa from x y && leqFrom leqa from y x)
+  ==. (leqa (from x) (from y) && leqa (from y) (from x))
+  ==. from x == from y ? leqaAntisym (from x) (from y)
+  ==. to (from x) == to (from y)
+  ==. x == to (from y) ? tof x
+  ==. x == y           ? tof y
+  *** QED
+
+{-@ leqFromTrans :: leqa:(a -> a -> Bool)
+                 -> leqaTrans:(x:a -> y:a -> z:a -> { (leqa x y) && (leqa y z) ==> (leqa x z) })
+                 -> from:(b -> a)
+                 -> x:b -> y:b -> z:b
+                 -> { leqFrom leqa from x y && leqFrom leqa from y z ==> leqFrom leqa from x z }
+@-}
+leqFromTrans :: (a -> a -> Bool) -> (a -> a -> a -> Proof)
+             -> (b -> a)
+             -> b -> b -> b -> Proof
+leqFromTrans leqa leqaTrans from x y z =
+      (leqFrom leqa from x y && leqFrom leqa from y z)
+  ==. (leqa (from x) (from y) && leqa (from y) (from z))
+  ==. leqa (from x) (from z) ? leqaTrans (from x) (from y) (from z)
+  ==. leqFrom leqa from x z
+  *** QED
+
+{-@ leqFromTotal :: leqa:(a -> a -> Bool) -> leqaTotal:(x:a -> y:a -> { (leqa x y) || (leqa y x) })
+                 -> from:(b -> a) -> x:b -> y:b -> { leqFrom leqa from x y || leqFrom leqa from y x }
+@-}
+leqFromTotal :: (a -> a -> Bool) -> (a -> a -> Proof)
+             -> (b -> a) -> b -> b -> Proof
+leqFromTotal leqa leqaTotal from x y =
+      (leqFrom leqa from x y || leqFrom leqa from y x)
+  ==. (leqa (from x) (from y) || leqa (from y) (from x))
+  ==. True ? leqaTotal (from x) (from y)
+  ==. leqFrom leqa from y x
+  *** QED
+
+vordIso :: (Eq a, Eq b) => Iso a b -> VerifiedOrd a -> VerifiedOrd b
+vordIso (Iso to from tof fot) (VerifiedOrd leqa leqaRefl leqaAntisym leqaTrans leqaTotal) =
+  VerifiedOrd
+    (leqFrom leqa from)
+    (leqFromRefl leqa leqaRefl from)
+    (leqFromAntisym leqa leqaAntisym to from tof)
+    (leqFromTrans leqa leqaTrans from)
+    (leqFromTotal leqa leqaTotal from)
+\end{code}
+
+We can now write a `VerifiedOrd` for `Peano` by mapping it onto `type Nat = { n:Int | 0 <= n }`, which is easier to
+prove properties about because it's just an integer!
+
+\begin{code}
+{-@ type Nat = { n:Int | 0 <= n } @-}
+type Nat = Int
+
+{-@ axiomatize fromNat @-}
+{-@ fromNat :: Nat -> Peano @-}
+fromNat :: Nat -> Peano
+fromNat n
+  | n == 0 = Z
+  | otherwise = S (fromNat (n - 1))
+
+{-@ toFrom :: x:Nat -> { toNat (fromNat x) == x } @-}
+toFrom :: Nat -> Proof
+toFrom n
+  | n == 0 = toNat (fromNat 0) ==. toNat Z ==. 0 *** QED
+  | n > 0 = toNat (fromNat n)
+        ==. toNat (S (fromNat (n - 1)))
+        ==. 1 + toNat (fromNat (n - 1))
+        ==. 1 + (n - 1) ? toFrom (n - 1)
+        ==. n
+        *** QED
+
+{-@ fromTo :: x:Peano -> { fromNat (toNat x) == x } @-}
+fromTo :: Peano -> Proof
+fromTo Z = fromNat (toNat Z) ==. fromNat 0 ==. Z *** QED
+fromTo (S n) = fromNat (toNat (S n))
+           ==. fromNat (1 + toNat n)
+           ==. S (fromNat ((1 + toNat n) - 1))
+           ==. S (fromNat (toNat n))
+           ==. S n ? fromTo n
+           *** QED
+
+{-@ isoNatPeano :: Iso Nat Peano @-}
+isoNatPeano :: Iso Nat Peano
+isoNatPeano = Iso fromNat toNat fromTo toFrom
+
+vordNat :: VerifiedOrd Nat
+vordNat = VerifiedOrd leqInt leqIntRefl leqIntAntisym leqIntTrans leqIntTotal
+
+vordPeano :: VerifiedOrd Peano
+vordPeano = vordIso isoNatPeano vordNat
+\end{code}
+
+Similarly, we can break down compound datatypes into sums and products, just like what happens in `GHC.Generics`, and
+use the isomorphism to write down `VerifiedOrd` instances. We do however need to provide instances of `VerifiedOrd` for
+sums and products.
+
+\begin{code}
+vordProd :: VerifiedOrd a -> VerifiedOrd b -> VerifiedOrd (a, b)
+vordSum :: VerifiedOrd a -> VerifiedOrd b -> VerifiedOrd (Either a b)
+\end{code}
+
+\begin{comment}
+\begin{code}
+vordSum = undefined
+vordProd = undefined
+\end{code}
+\end{comment}
+
+Our [library](https://github.com/iu-parfunc/verified-instances) explores this idea to build some verified typeclasses,
+such as `VerifiedOrd` and `VerifiedMonoid`. We also provide combinators to build verified instances by using
+isomorphisms. Also, using a [reflection hack](https://www.schoolofhaskell.com/user/thoughtpolice/using-reflection), we
+can reify these "verified" terms to typeclass dictionaries at runtime, to call legacy functions which require `Ord`
+constraints and so on.
diff --git a/docs/blog/2017-01-06-reductions.lhs b/docs/blog/2017-01-06-reductions.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2017-01-06-reductions.lhs
@@ -0,0 +1,261 @@
+---
+layout: post
+title: Proof Reductions on Homomorphisms
+date: 2017-01-02
+comments: true
+external-url:
+author: Niki Vazou and Vikraman Choudhury
+published: true
+categories: reflection, abstract-refinements
+demo: Reductions.hs
+---
+
+[Previously][refinement-reflection] we saw how Refinement Reflection
+can be used to specify and prove theorems about Haskell code.
+
+Today we will see how proof generation can be simplified by 
+proof reduction on homomorphic data types. 
+
+As an example, we define a user-defined `Peano` data type
+and prove that it enjoys various arithmetic properties 
+(like totality of comparison) by 
+
+1. creating a proof that an arithmetic property holds on Natural numbers, and then 
+2. reduce the proof from Natural numbers to Peano numbers. 
+This proof reduction is possible since Peano numbers are homomorphic to Natural numbers. 
+
+<!-- more -->
+
+<br>
+<br>
+<br>
+
+<div class="row-fluid">
+  <div class="span12 pagination-centered">
+  <img src="http://4.bp.blogspot.com/-oltF9WI2KhY/VBMwdj15IvI/AAAAAAAAAtg/V3-k6IylIZM/s1600/picasso_bull.jpg"
+       alt="Picasso bull" width="400">
+       <br>
+       <br>
+       <br>
+  </div>
+</div>
+
+
+<div class="hidden">
+\begin{code}
+{-@ LIQUID "--higherorder"    @-}
+{-@ LIQUID "--totalhaskell"   @-}
+{-@ LIQUID "--exactdc"        @-}
+{-@ LIQUID "--diffcheck"      @-}
+{-@ LIQUID "--pruneunsorted"  @-}
+{-@ LIQUID "--eliminate=some" @-}
+
+module Reductions where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+geqZero  :: Peano -> Proof 
+leqTotal :: Peano -> Peano -> Proof
+toNat    :: Peano -> Int
+
+geqZeroNat          :: Nat -> Proof 
+geqZeroByReduction  :: Peano -> Proof 
+leqTotalByReduction :: Peano -> Peano -> Proof 
+leqTotalNat         :: Nat -> Nat -> Proof
+
+\end{code}
+
+</div>
+
+Properties of Peano Numbers
+----------------------------
+
+First, we define `Peano` numbers as a data type 
+and the function `leqPeano` that compares two Peano numbers.
+
+
+\begin{code}
+{-@ data Peano [toNat] = Z | S {prev :: Peano } @-}
+data Peano = Z | S { prev :: Peano } deriving (Eq)
+
+{-@ reflect leqPeano @-}
+leqPeano :: Peano -> Peano -> Bool
+leqPeano Z _         = True
+leqPeano _ Z         = False
+leqPeano (S n) (S m) = leqPeano n m
+\end{code}
+
+We can use Refinement Reflection to provide an 
+**explicit proof** that no Peano number is greater than zero (`Z`).
+
+\begin{code}
+{-@ geqZero :: n:Peano -> {leqPeano Z n} @-}
+geqZero n = leqPeano Z n *** QED 
+\end{code}
+
+The proof proceeds simply by invocation of the 
+first case of the `leqPeano` definition. 
+
+As another Peano property, we can use Refinement Reflection to 
+show that comparison on Peano numbers is *total*, 
+that is, for every two numbers `n` and `m` 
+either `leqPeano n m` or `leqPeano m n` always holds. 
+
+\begin{code}
+{-@ leqTotal :: n:Peano -> m:Peano 
+             -> {(leqPeano n m) || (leqPeano m n)} 
+             /  [toNat n + toNat m] @-}
+leqTotal Z m = leqPeano Z m *** QED
+leqTotal n Z = leqPeano Z n *** QED
+leqTotal (S n) (S m)
+  =   (leqPeano (S n) (S m) || leqPeano (S m) (S n))
+  ==. (leqPeano n m || leqPeano (S m) (S n)) 
+      ? (leqTotal n m)
+  ==. (leqPeano n m || leqPeano m n) 
+      ? (leqTotal m n)
+  *** QED
+\end{code}
+
+The proof proceeds by induction on the sum of `n` and `m`. 
+Liquid Haskell captures this generalized induction by 
+ensuring that the value `toNat n + toNat m` is decreasing
+where `toNat` maps Peano to Natural numbers. 
+
+\begin{code}
+{-@ measure toNat @-}
+{-@ toNat :: Peano -> Nat @-}
+toNat Z     = 0
+toNat (S n) = 1 + toNat n
+\end{code}
+
+Note, that the type `Nat` is just a refinement on the Haskell's integers
+\begin{code}
+{-@ type Nat = { n:Int | 0 <= n } @-}
+type Nat     = Int
+\end{code}
+
+Following the totality proof, 
+one can prove further properties of Peano comparisons, 
+like reflexivity and transitivity.
+
+The above totality proof is verbose! 
+Moreover, it is very similar 
+to the classic totality on Natural numbers. 
+Since the SMT knowns that comparison of Nat is total, we can just reduce 
+Peano to Natural number totality!
+
+
+Reduction of Operators 
+-----------------------
+
+Since `toNat` is a homomorphism (i.e., a transformation) from `Peano` to `Nat`
+one can compare two Peano numbers via comparison of Natural numbers. 
+
+\begin{code}
+{-@ reflect leqPeanoNat @-}
+leqPeanoNat :: Peano -> Peano -> Bool 
+leqPeanoNat n m = toNat n `leqInt` toNat m  
+\end{code}
+
+where `leqInt` the Haskell comparison operator restricted to `Ints`.
+
+\begin{code}
+{-@ reflect leqInt @-}
+leqInt :: Int -> Int -> Bool 
+leqInt x y = x <= y
+\end{code}
+
+Note that `leqPeanoNat` is exactly equivalent to `leqPeano`. 
+For this blog post, we leave the equivalence proof as an exercise for the reader.
+
+
+Proof Reductions
+-----------------
+
+After reducing the Peano comparison operator to
+comparison on Natural numbers, we can reduce 
+proofs on Peano numbers to proofs on Natural numbers.
+The great benefit of this reduction is that proofs on Natural number
+are automated by the underlying SMT solver!
+
+For example, we prove that no Natural number is less than `0`
+by unfolding `leqInt` on `0` 
+and then let linear arithmetic decision procedure of the SMT complete the proof. 
+\begin{code}
+{-@ geqZeroNat :: n:Nat -> {leqInt 0 n} @-}
+geqZeroNat n = leqInt 0 n *** QED 
+\end{code}
+
+
+We then reduce the above property to the respective property on Peano numbers.
+\begin{code}
+{-@ geqZeroByReduction :: n:Peano -> {leqPeanoNat Z n} @-}
+geqZeroByReduction n 
+  = leqPeanoNat Z n ==. True 
+  ? reduction toNat geqZeroNat n 
+  *** QED 
+\end{code}
+
+The reduction occurs via the function `reduction`.
+The function `reduction f thm n`, for each homomorphism `f :: a -> b`, 
+reduces a theorem `thm x` on `a`s to the respective theorems on `b` via 
+[Abstract Refinements][abstract-refinements].
+\begin{code}
+{-@ reduction :: forall<p :: a -> Proof -> Bool>. 
+                 f:(b -> a) 
+              -> (x:a -> Proof<p x>) 
+              -> (y:b -> Proof<p (f y)>) @-}
+reduction :: (b -> a) -> (a -> Proof) -> (b -> Proof)
+reduction f thm y = thm (f y)              
+\end{code}
+
+Users with model theoretic background may observe that `reduction` 
+is actually encoding [Łoś–Tarski preservation theorem][preservation-theorem]!
+
+Similarly, `reduction2` reduces theorems with two `a` arguments
+to theorems with two `b` arguments via a homomorphism. 
+
+\begin{code}
+{-@ reduction2 :: forall<p :: a -> a -> Proof -> Bool >. 
+                  f:(b -> a) 
+               -> (x1:a -> x2:a -> Proof<p x1 x2>) 
+               -> (y1:b -> y2:b-> Proof<p (f y1) (f y2)>) @-}
+reduction2 :: (b -> a) -> (a -> a -> Proof) -> (b -> b -> Proof)
+reduction2 f thm y1 y2  = thm (f y1) (f y2)
+\end{code}
+
+For example, the SMT-automated proof of totality on Natural numbers 
+\begin{code}
+{-@ leqTotalNat :: n:Nat -> m:Nat -> { leqInt n m || leqInt m n } @-}
+leqTotalNat n m = (leqInt n m || leqInt m n) *** QED 
+\end{code}
+
+can be easily reduced to totality on Peano numbers
+
+\begin{code}
+{-@ leqTotalByReduction :: n:Peano -> m:Peano
+   -> { leqPeanoNat n m || leqPeanoNat m n } @-}
+leqTotalByReduction n m 
+  = (leqPeanoNat n m || leqPeanoNat m n) ==. True 
+  ? reduction2 toNat leqTotalNat n m  
+  *** QED 
+\end{code}
+
+
+Conclusion
+-----------
+
+We presented an example of how the SMT-automated proofs on 
+Natural numbers can be reduced to the respective proofs on the 
+Peano numbers, because Peano are homomorphic to Natural numbers. 
+
+Proof reduction greatly simplifies proof composition
+as it allows for shorter and more elegant proofs 
+that take advantage of SMT-automated or other existing
+proofs on homomorphic data structures. 
+
+
+[refinement-reflection]: http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/blog/2016/09/18/refinement-reflection.lhs/
+[reduction-lib]: https://github.com/ucsd-progsys/liquidhaskell/tree/develop/include/Language/Haskell/Liquid/Reduction.hs
+[abstract-refinements]: http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/blog/2013/06/03/abstracting-over-refinements.lhs/
+[preservation-theorem]: https://en.wikipedia.org/wiki/%C5%81o%C5%9B%E2%80%93Tarski_preservation_theorem
diff --git a/docs/blog/2017-03-20-arithmetic-overflows.lhs b/docs/blog/2017-03-20-arithmetic-overflows.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/2017-03-20-arithmetic-overflows.lhs
@@ -0,0 +1,363 @@
+---
+layout: post
+title: Arithmetic Overflows
+date: 2017-03-20
+author: Ranjit Jhala
+published: true
+comments: true
+tags: basic
+demo: overflow.hs
+---
+
+
+Computers are great at crunching numbers.
+However, if programmers aren't careful, their
+machines can end up biting off more than
+they can chew: simple arithmetic operations
+over very large (or very tiny) inputs can
+*overflow* leading to bizarre crashes
+or vulnerabilities. For example,
+[Joshua Bloch's classic post][bloch]
+argues that nearly all binary searches
+are broken due to integer overflows.
+Lets see how we can teach LiquidHaskell
+to spot such overflows.
+
+<!-- more -->
+
+<div class="hidden">
+\begin{code}
+module Bounded where
+
+import           Control.Exception (assert)
+import           Prelude hiding (Num (..))
+import qualified Prelude
+
+plusStrict :: Int -> Int -> Int
+plusLazy   :: Int -> Int -> Int
+mono       :: Int -> Bool
+\end{code}
+</div>
+
+1. The Problem
+--------------
+
+
+LiquidHaskell, like some programmers, likes to make believe
+that `Int` represents the set of integers. For example, you
+might define a function `plus` as:
+
+\begin{code}
+{-@ plus :: x:Int -> y:Int -> {v:Int | v == x + y} @-}
+plus :: Int -> Int -> Int
+plus x y = x Prelude.+ y
+\end{code}
+
+The output type of the function states that the returned value
+is equal to the \emph{logical} result of adding the two inputs.
+
+The above signature lets us "prove" facts like addition by one
+yields a bigger number:
+
+\begin{code}
+{-@ monoPlus :: Int -> {v:Bool | v <=> true } @-}
+monoPlus :: Int -> Bool
+monoPlus x = x < plus x 1
+\end{code}
+
+Unfortunately, the signature for plus and hence, the above
+"fact" are both lies.
+
+LH _checks_ `plus` as the same signature is _assumed_
+for the primitive `Int` addition operator `Prelude.+`.
+LH has to assume _some_ signature for this "foreign"
+machine operation, and by default, LH assumes that
+machine addition behaves like logical addition.
+
+However, this assumption, and its consequences are
+only true upto a point:
+
+```haskell
+λ>  monoPlus 0
+True
+λ>  monoPlus 100
+True
+λ>  monoPlus 10000
+True
+λ>  monoPlus 1000000
+True
+```
+
+Once we get to `maxBound` at the very edge of `Int`,
+a tiny bump is enough to send us tumbling backwards
+into a twilight zone.
+
+```haskell
+λ> monoPlus maxBound
+False
+
+λ> plus maxBound 1
+-9223372036854775808
+```
+
+2. Keeping Int In Their Place
+-----------------------------
+
+The news isn't all bad: the glass half full
+view is that for "reasonable" values
+like 10, 100, 10000 and 1000000, the
+machine's arithmetic _is_ the same as
+logical arithmetic. Lets see how to impart
+this wisdom to LH. We do this in two steps:
+define the *biggest* `Int` value, and then,
+use this value to type the arithmetic operations.
+
+**A. The Biggest Int**
+
+First, we need a way to talk about
+"the edge" -- i.e. the largest `Int`
+value at which overflows occur.
+
+We could use the concrete number
+
+```haskell
+λ> maxBound :: Int
+9223372036854775807
+```
+
+However, instead of hardwiring a particular number,
+a more general strategy is to define a symbolic
+constant `maxInt` to represent _any_ arbitrary
+overflow value and thus, make the type checking
+robust to different machine integer widths.
+
+\begin{code}
+-- defines an Int constant called `maxInt`
+{-@ measure maxInt :: Int @-}
+\end{code}
+
+To tell LH that `maxInt` is the "biggest" `Int`,
+we write a predicate that describes values bounded
+by `maxInt`:
+
+\begin{code}
+{-@ predicate Bounded N = 0 < N + maxInt && N < maxInt @-}
+\end{code}
+
+Thus, `Bounded n` means that the number `n` is in
+the range `[-maxInt, maxInt]`.
+
+**B.  Bounded Machine Arithmetic**
+
+Next, we can assign the machine arithmetic operations
+types that properly capture the possibility of arithmetic
+overflows. Here are _two_ possible specifications.
+
+**Strict: Thou Shalt Not Overflow** A _strict_ specification
+simply prohibits any overflow:
+
+\begin{code}
+{-@ plusStrict :: x:Int -> y:{Int|Bounded(x+y)} -> {v:Int|v = x+y} @-}
+plusStrict x y = x Prelude.+ y
+\end{code}
+
+The inputs `x` and `y` _must_ be such that the result is `Bounded`,
+and in that case, the output value is indeed their logical sum.
+
+**Lazy: Overflow at Thine Own Risk** Instead, a _lazy_
+specification could permit overflows but gives no
+guarantees about the output when they occur.
+
+\begin{code}
+{-@ plusLazy :: x:Int -> y:Int -> {v:Int|Bounded(x+y) => v = x+y} @-}
+plusLazy x y = x Prelude.+ y
+\end{code}
+
+The lazy specification says that while `plusLazy`
+can be called with any values you like, the
+result is the logical sum
+*only if there is no overflow*.
+
+
+To understand the difference between the two
+specifications, lets revisit the `monoPlus`
+property using the new machine-arithmetic
+sensitive signatures:
+
+\begin{code}
+{-@ monoPlusStrict :: Int -> {v:Bool | v <=> true } @-}
+monoPlusStrict x = x < plusStrict x 1
+
+{-@ monoPlusLazy :: Int -> {v:Bool | v <=> true } @-}
+monoPlusLazy x = x < plusLazy x 1
+\end{code}
+
+Both are rejected by LH, since, as we saw earlier,
+the functions _do not_ always evaluate to `True`.
+However, in the strict version the error is at the
+possibly overflowing call to `plusStrict`.
+In the lazy version, the call to `plusLazy` is
+accepted, but as the returned value is some
+arbitrary `Int` (not the logical `x+1`), the
+comparison may return `False` hence the output
+is not always `True`.
+
+**Exercise:** Can you fix the specification
+for `monoPlusStrict` and `monoPlusLazy` to
+get LH to verify the implementation?
+
+
+3. A Typeclass for Machine Arithmetic
+-------------------------------------
+
+Its a bit inconvenient to write `plusStrict` and `plusLazy`,
+and really, we'd just like to write `+` and `-` and so on.
+We can do so, by tucking the above specifications into
+a _bounded numeric_ typeclass whose signatures capture machine
+arithmetic. First, we define a `BoundedNum` variant of `Num`
+
+\begin{code}
+class BoundedNum a where
+  (+) :: a -> a -> a
+  (-) :: a -> a -> a
+  -- other operations ...
+\end{code}
+
+and now, we can define its `Int` instance just as wrappers
+around the `Prelude` operations:
+
+\begin{code}
+instance BoundedNum Int where
+  x + y = x Prelude.+ y
+  x - y = x Prelude.- y
+\end{code}
+
+Finally, we can tell LH that the above above instance obeys the
+(strict) specifications for machine arithmetic:
+
+\begin{code}
+{-@ instance BoundedNum Int where
+      + :: x:Int -> y:{Int | Bounded (x+y)} -> {v:Int | v == x+y };
+      - :: x:Int -> y:{Int | Bounded (x-y)} -> {v:Int | v == x-y }
+  @-}
+\end{code}
+
+With the above instance in scope, we can just use the plain `+`
+operator and have LH flag potential overflows:
+
+\begin{code}
+{-@ mono :: Int -> {v:Bool | v <=> true} @-}
+mono x = x < x + 1
+\end{code}
+
+
+4. An Application: Binary Search
+--------------------------------
+
+The above seems a bit paranoid. Do overflows _really_ matter?
+And if they do, is it really practical to check for them using
+the above?
+
+[Joshua Bloch's][bloch] famous article describes a
+tricky overflow bug in an implementation of binary-search
+that lay hidden in plain sight in classic textbooks and his
+own implementation in the JDK for nearly a decade.
+Gabriel Gonzalez wrote a lovely [introduction to LH][lh-gonzalez]
+using binary-search as an example, and a careful reader
+[pointed out][lh-overflow-reddit] that it had the same
+overflow bug!
+
+Lets see how we might spot and fix such bugs using `BoundedNum`.
+
+<div class="row">
+<div class="col-md-4">
+**A. Off by One** Lets begin by just using
+the default `Num Int` which ignores overflow.
+As Gabriel explains, LH flags a bunch of errors
+if we start the search with `loop x v 0 n` as
+the resulting search can access `v` at any
+index between `0` and `n` inclusive, which
+may lead to an out of bounds at `n`.
+We can fix the off-by-one by correcting the
+upper bound to `n-1`, at which point LH
+reports the code free of errors.
+</div>
+
+<div class="col-md-8">
+<img id="splash-binarySearch-A"
+     class="center-block anim"
+     png="/liquidhaskell-blog/static/img/splash-binarySearch-A.png"
+     src="/liquidhaskell-blog/static/img/splash-binarySearch-A.png">
+</div>
+</div>
+
+<br>
+
+
+<div class="row">
+<div class="col-md-8">
+<img id="splash-binarySearch-B"
+     class="center-block anim"
+     png="/liquidhaskell-blog/static/img/splash-binarySearch-B.png"
+     src="/liquidhaskell-blog/static/img/splash-binarySearch-B.png">
+</div>
+
+<div class="col-md-4">
+**B. Lots of Overflows** To spot arithmetic overflows, we need
+only hide the default `Prelude` and instead import the `BoundedNum`
+instance described above. Upon doing so, LH flags a whole bunch of
+potential errors -- essentially *all* the arithmetic operations which
+seems rather dire!
+</div>
+</div>
+
+
+<div class="row">
+<div class="col-md-4">
+**C. Vector Sizes are Bounded** Of course, things
+aren't _so_ bad. LH is missing the information that
+the size of any `Vector` must be `Bounded`. Once we
+inform LH about this invariant with the
+[`using` directive][lh-invariants], it infers that
+as the `lo` and `hi` indices are upper-bounded by
+the `Vector`'s size, all the arithmetic on them is
+also `Bounded` and hence, free of overflows.
+</div>
+
+<div class="col-md-8">
+<img id="splash-binarySearch-C"
+     class="center-block anim"
+     png="/liquidhaskell-blog/static/img/splash-binarySearch-C.png"
+     src="/liquidhaskell-blog/static/img/splash-binarySearch-C.png">
+</div>
+</div>
+
+<br>
+
+<div class="row">
+<div class="col-md-8">
+<img id="splash-binarySearch-D"
+     class="center-block anim"
+     png="/liquidhaskell-blog/static/img/splash-binarySearch-D.png"
+     src="/liquidhaskell-blog/static/img/splash-binarySearch-D.png">
+</div>
+
+<div class="col-md-4">
+**D. Staying In The Middle**
+Well, *almost* all. The one pesky pink highlight that
+remains is exactly the bug that Bloch made famous. Namely:
+the addition used to compute the new midpoint between `lo`
+and `hi` could overflow e.g. if the array was large and both
+those indices were near the end. To ensure the machine doesn't
+choke, we follow Bloch's suggestion and re-jigger the computation
+to instead compute the midpoint by splitting the difference
+between `hi` and `lo`! the code is now free of arithmetic
+overflows and truly memory safe.
+</div>
+</div>
+
+
+[lh-invariants]: https://github.com/ucsd-progsys/liquidhaskell/blob/develop/README.md#invariants
+[lh-gonzalez]: http://www.haskellforall.com/2015/12/compile-time-memory-safety-using-liquid.html
+[bloch]: https://research.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html
+[lh-overflow-reddit]: https://www.reddit.com/r/haskell/comments/3ysh9k/haskell_for_all_compiletime_memory_safety_using/cyg8g60/
diff --git a/docs/blog/todo/Iso.lhs b/docs/blog/todo/Iso.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/Iso.lhs
@@ -0,0 +1,281 @@
+---
+layout: post
+title: "Isomorphisms"
+date: 2016-24-12 
+author: Vikraman Choudhury 
+published: false
+comments: true
+external-url:
+categories: basic
+demo: Iso.hs
+---
+
+\begin{comment}
+\begin{code}
+{-@ LIQUID "--higherorder" @-}
+{-@ LIQUID "--totalhaskell" @-}
+{-@ LIQUID "--exactdc" @-}
+{-@ LIQUID "--diffcheck" @-}
+
+module Iso where
+
+import Language.Haskell.Liquid.ProofCombinators
+\end{code}
+\end{comment}
+
+In this blog post, we show how to use Liquid Haskell to build "verified" typeclasses. A verified typeclass allows one to
+express typeclass laws directly as Haskell code. We also show a technique to build verified instances and scale them up
+to compound datatypes using isomorphisms.
+
+First, we'll express verified typeclasses using Haskell records, but with LiquidHaskell refinements to express laws. As
+an example, let's define `VerifiedOrd`, which is the same as the `Ord` typeclass, but with total order laws added.
+
+\begin{code}
+{-@ data VerifiedOrd a = VerifiedOrd {
+      leq     :: a -> a -> Bool
+    , refl    :: x:a -> { Prop (leq x x) }
+    , antisym :: x:a -> y:a -> { Prop (leq x y) && Prop (leq y x) ==> x == y }
+    , trans   :: x:a -> y:a -> z:a -> { Prop (leq x y) && Prop (leq y z) ==> Prop (leq x z) }
+    , total   :: x:a -> y:a -> { Prop (leq x y) || Prop (leq y x) }
+    }
+@-}
+data VerifiedOrd a = VerifiedOrd {
+    leq     :: a -> a -> Bool
+  , refl    :: a -> Proof
+  , antisym :: a -> a -> Proof
+  , trans   :: a -> a -> a -> Proof
+  , total   :: a -> a -> Proof
+}
+\end{code}
+
+The `leq` function represents the `<=` operator in `Ord`, and `refl`, `antisym`, `trans`, `total`, express the
+reflexivity, antisymmetry, transitivity and totality properties respectively, that a total order requires. Notice how
+the refinements express the laws, and the actual code is simply a function that returns `Proof` or `()`.
+
+Now, let's see how to define some simple verified instances. We need to instantiate `leq` for our type, "reflect" it
+into the logic, and prove all the required properties. For primitive types like `Int` or `Double`, it's "trivial"
+because we trust the SMT solver which already knows about integers.
+
+\begin{code}
+{-@ axiomatize leqInt @-}
+leqInt :: Int -> Int -> Bool
+leqInt x y = x <= y
+
+{-@ leqIntRefl :: x:Int -> { leqInt x x } @-}
+leqIntRefl :: Int -> Proof
+leqIntRefl x = leqInt x x ==. x <= x *** QED
+
+{-@ leqIntAntisym :: x:Int -> y:Int -> { leqInt x y && leqInt y x ==> x == y } @-}
+leqIntAntisym :: Int -> Int -> Proof
+leqIntAntisym x y = (leqInt x y && leqInt y x) ==. (x <= y && y <= x) ==. x == y *** QED
+
+{-@ leqIntTrans :: x:Int -> y:Int -> z:Int -> { leqInt x y && leqInt y z ==> leqInt x z } @-}
+leqIntTrans :: Int -> Int -> Int -> Proof
+leqIntTrans x y z = (leqInt x y && leqInt y z) ==. (x <= y && y <= z) ==. x <= z ==. leqInt x z *** QED
+
+{-@ leqIntTotal :: x:Int -> y:Int -> { leqInt x y || leqInt y x } @-}
+leqIntTotal :: Int -> Int -> Proof
+leqIntTotal x y = (leqInt x y || leqInt y x) ==. (x <= y || y <= x) *** QED
+
+vordInt :: VerifiedOrd Int
+vordInt = VerifiedOrd leqInt leqIntRefl leqIntAntisym leqIntTrans leqIntTotal
+\end{code}
+
+How about a complex datatype? Let's consider an inductive datatype, the peano natural numbers. Not surprisingly, the
+proofs follow by induction. For conciseness, we only show totality and elide the rest.
+
+\begin{code}
+{-@ data Peano [toNat] = Z | S Peano @-}
+data Peano = Z | S Peano deriving (Eq)
+
+{-@ measure toNat @-}
+{-@ toNat :: Peano -> { n:Int | 0 <= n } @-}
+toNat :: Peano -> Int
+toNat Z = 0
+toNat (S n) = 1 + toNat n
+
+{-@ axiomatize leqPeano @-}
+leqPeano :: Peano -> Peano -> Bool
+leqPeano Z _ = True
+leqPeano _ Z = False
+leqPeano (S n) (S m) = leqPeano n m
+
+{-@ leqNTotal :: n:Peano -> m:Peano -> {(leqPeano n m) || (leqPeano m n)} / [toNat n + toNat m] @-}
+leqNTotal :: Peano -> Peano -> Proof
+leqNTotal Z m = leqPeano Z m *** QED
+leqNTotal n Z = leqPeano Z n *** QED
+leqNTotal (S n) (S m)
+  =   (leqPeano (S n) (S m) || leqPeano (S m) (S n))
+  ==. (leqPeano n m || leqPeano (S m) (S n)) ? (leqNTotal n m )
+  ==. (leqPeano n m || leqPeano m n) ? (leqNTotal m n)
+  *** QED
+\end{code}
+
+Writing down proofs for more complex datatypes is tedious, it requires case analysis for each constructor and using the
+induction hypothesis. However, we can decompose Haskell datatypes into sums and products, and we can build up compound
+proofs using isomorphisms! To that end, we design some machinery to express isomorphisms, and prove that laws are
+preserved under isomorphic images.
+
+\begin{code}
+{-@ data Iso a b = Iso {
+      to   :: a -> b
+    , from :: b -> a
+    , tof  :: y:b -> { to (from y) == y }
+    , fot  :: x:a -> { from (to x) == x }
+    }
+@-}
+data Iso a b = Iso {
+    to   :: a -> b
+  , from :: b -> a
+  , tof  :: b -> Proof
+  , fot  :: a -> Proof
+}
+\end{code}
+
+An isomorphism between types `a` and `b` is a pair of functions `to :: a -> b` and `from :: b -> a` that are mutually
+inverse to each other. We now claim that total order laws are preserved under `Iso`; this amounts to building up a
+`VerifiedOrd b`, given a `VerifiedOrd a` and an `Iso a b`.
+
+\begin{code}
+{-@ axiomatize leqFrom @-}
+leqFrom :: (a -> a -> Bool)
+        -> (b -> a)
+        -> (b -> b -> Bool)
+leqFrom leqa from x y = leqa (from x) (from y)
+
+{-@ leqFromRefl :: leqa:(a -> a -> Bool) -> leqaRefl:(x:a -> { Prop (leqa x x) })
+                -> from:(b -> a)
+                -> x:b -> { leqFrom leqa from x x }
+@-}
+leqFromRefl :: (a -> a -> Bool) -> (a -> Proof)
+            -> (b -> a)
+            -> b -> Proof
+leqFromRefl leqa leqaRefl from x =
+      leqFrom leqa from x x
+  ==. leqa (from x) (from x)
+  ==. True ? leqaRefl (from x)
+  *** QED
+
+{-@ leqFromAntisym :: leqa:(a -> a -> Bool)
+                   -> leqaAntisym:(x:a -> y:a -> { Prop (leqa x y) && Prop (leqa y x) ==> x == y })
+                   -> to:(a -> b) -> from:(b -> a) -> tof:(y:b -> { to (from y) == y })
+                   -> x:b -> y:b -> { leqFrom leqa from x y && leqFrom leqa from y x ==> x == y }
+@-}
+leqFromAntisym :: (Eq a, Eq b)
+               => (a -> a -> Bool) -> (a -> a -> Proof)
+               -> (a -> b) -> (b -> a) -> (b -> Proof)
+               -> b -> b -> Proof
+leqFromAntisym leqa leqaAntisym to from tof x y
+  =   (leqFrom leqa from x y && leqFrom leqa from y x)
+  ==. (leqa (from x) (from y) && leqa (from y) (from x))
+  ==. from x == from y ? leqaAntisym (from x) (from y)
+  ==. to (from x) == to (from y)
+  ==. x == to (from y) ? tof x
+  ==. x == y           ? tof y
+  *** QED
+
+{-@ leqFromTrans :: leqa:(a -> a -> Bool)
+                 -> leqaTrans:(x:a -> y:a -> z:a -> { Prop (leqa x y) && Prop (leqa y z) ==> Prop (leqa x z) })
+                 -> from:(b -> a)
+                 -> x:b -> y:b -> z:b
+                 -> { leqFrom leqa from x y && leqFrom leqa from y z ==> leqFrom leqa from x z }
+@-}
+leqFromTrans :: (a -> a -> Bool) -> (a -> a -> a -> Proof)
+             -> (b -> a)
+             -> b -> b -> b -> Proof
+leqFromTrans leqa leqaTrans from x y z =
+      (leqFrom leqa from x y && leqFrom leqa from y z)
+  ==. (leqa (from x) (from y) && leqa (from y) (from z))
+  ==. leqa (from x) (from z) ? leqaTrans (from x) (from y) (from z)
+  ==. leqFrom leqa from x z
+  *** QED
+
+{-@ leqFromTotal :: leqa:(a -> a -> Bool) -> leqaTotal:(x:a -> y:a -> { Prop (leqa x y) || Prop (leqa y x) })
+                 -> from:(b -> a) -> x:b -> y:b -> { leqFrom leqa from x y || leqFrom leqa from y x }
+@-}
+leqFromTotal :: (a -> a -> Bool) -> (a -> a -> Proof)
+             -> (b -> a) -> b -> b -> Proof
+leqFromTotal leqa leqaTotal from x y =
+      (leqFrom leqa from x y || leqFrom leqa from y x)
+  ==. (leqa (from x) (from y) || leqa (from y) (from x))
+  ==. True ? leqaTotal (from x) (from y)
+  ==. leqFrom leqa from y x
+  *** QED
+
+vordIso :: (Eq a, Eq b) => Iso a b -> VerifiedOrd a -> VerifiedOrd b
+vordIso (Iso to from tof fot) (VerifiedOrd leqa leqaRefl leqaAntisym leqaTrans leqaTotal) =
+  VerifiedOrd
+    (leqFrom leqa from)
+    (leqFromRefl leqa leqaRefl from)
+    (leqFromAntisym leqa leqaAntisym to from tof)
+    (leqFromTrans leqa leqaTrans from)
+    (leqFromTotal leqa leqaTotal from)
+\end{code}
+
+We can now write a `VerifiedOrd` for `Peano` by mapping it onto `type Nat = { n:Int | 0 <= n }`, which is easier to
+prove properties about because it's just an integer!
+
+\begin{code}
+{-@ type Nat = { n:Int | 0 <= n } @-}
+type Nat = Int
+
+{-@ axiomatize fromNat @-}
+{-@ fromNat :: Nat -> Peano @-}
+fromNat :: Nat -> Peano
+fromNat n
+  | n == 0 = Z
+  | otherwise = S (fromNat (n - 1))
+
+{-@ toFrom :: x:Nat -> { toNat (fromNat x) == x } @-}
+toFrom :: Nat -> Proof
+toFrom n
+  | n == 0 = toNat (fromNat 0) ==. toNat Z ==. 0 *** QED
+  | n > 0 = toNat (fromNat n)
+        ==. toNat (S (fromNat (n - 1)))
+        ==. 1 + toNat (fromNat (n - 1))
+        ==. 1 + (n - 1) ? toFrom (n - 1)
+        ==. n
+        *** QED
+
+{-@ fromTo :: x:Peano -> { fromNat (toNat x) == x } @-}
+fromTo :: Peano -> Proof
+fromTo Z = fromNat (toNat Z) ==. fromNat 0 ==. Z *** QED
+fromTo (S n) = fromNat (toNat (S n))
+           ==. fromNat (1 + toNat n)
+           ==. S (fromNat ((1 + toNat n) - 1))
+           ==. S (fromNat (toNat n))
+           ==. S n ? fromTo n
+           *** QED
+
+{-@ isoNatPeano :: Iso Nat Peano @-}
+isoNatPeano :: Iso Nat Peano
+isoNatPeano = Iso fromNat toNat fromTo toFrom
+
+vordNat :: VerifiedOrd Nat
+vordNat = VerifiedOrd leqInt leqIntRefl leqIntAntisym leqIntTrans leqIntTotal
+
+vordPeano :: VerifiedOrd Peano
+vordPeano = vordIso isoNatPeano vordNat
+\end{code}
+
+Similarly, we can break down compound datatypes into sums and products, just like what happens in `GHC.Generics`, and
+use the isomorphism to write down `VerifiedOrd` instances. We do however need to provide instances of `VerifiedOrd` for
+sums and products.
+
+\begin{code}
+vordProd :: VerifiedOrd a -> VerifiedOrd b -> VerifiedOrd (a, b)
+vordSum :: VerifiedOrd a -> VerifiedOrd b -> VerifiedOrd (Either a b)
+\end{code}
+
+\begin{comment}
+\begin{code}
+vordSum = undefined
+vordProd = undefined
+\end{code}
+\end{comment}
+
+Our [library](https://github.com/iu-parfunc/verified-instances) explores this idea to build some verified typeclasses,
+such as `VerifiedOrd` and `VerifiedMonoid`. We also provide combinators to build verified instances by using
+isomorphisms. Also, using a [reflection hack](https://www.schoolofhaskell.com/user/thoughtpolice/using-reflection), we
+can reify these "verified" terms to typeclass dictionaries at runtime, to call legacy functions which require `Ord`
+constraints and so on.
diff --git a/docs/blog/todo/LambdaEval.hs b/docs/blog/todo/LambdaEval.hs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/LambdaEval.hs
@@ -0,0 +1,125 @@
+module LambdaEval where
+
+import Data.List        (lookup)
+
+import Language.Haskell.Liquid.Prelude   
+
+---------------------------------------------------------------------
+----------------------- Datatype Definition -------------------------
+---------------------------------------------------------------------
+
+type Bndr 
+  = Int
+
+data Expr 
+  = Lam Bndr Expr
+  | Var Bndr  
+  | App Expr Expr
+  | Const Int
+  | Plus Expr Expr
+  | Pair Expr Expr
+  | Fst Expr
+  | Snd Expr
+
+{-@
+measure isValue      :: Expr -> Prop
+isValue (Const i)    = true 
+isValue (Lam x e)    = true 
+isValue (Var x)      = false
+isValue (App e1 e2)  = false
+isValue (Plus e1 e2) = false 
+isValue (Fst e)      = false
+isValue (Snd e)      = false
+isValue (Pair e1 e2) = ((? (isValue(e1))) && (? (isValue(e2))))
+@-}
+
+{-@ type Value = {v: Expr | (? (isValue([v]))) } @-}
+
+---------------------------------------------------------------------
+-------------------------- The Evaluator ----------------------------
+---------------------------------------------------------------------
+
+evalVar :: Bndr -> [(Bndr, Expr)] -> Expr
+evalVar x ((y,v):sto) 
+  | x == y
+  = v
+  | otherwise
+  = evalVar x sto
+
+evalVar x []      
+  = error "unbound variable"
+
+
+{-@ eval :: [(Bndr, Value)] -> Expr -> ([(Bndr, Value)], Value) @-}
+eval sto (Const i) 
+  = (sto, Const i)
+
+eval sto (Var x)  
+  = (sto, evalVar x sto) 
+
+eval sto (Plus e1 e2)
+  = let (_, e1') = eval sto e1
+        (_, e2') = eval sto e2
+    in case (e1, e2) of
+         (Const i1, Const i2) -> (sto, Const (i1 + i2))
+         _                    -> error "non-integer addition"
+
+eval sto (App e1 e2)
+  = let (_,    v2 ) = eval sto e2 
+        (sto1, e1') = eval sto e1
+    in case e1' of
+         (Lam x e) -> eval ((x, v2): sto1) e
+         _         -> error "non-function application"
+
+eval sto (Lam x e) 
+  = (sto, Lam x e)
+
+eval sto (Pair e1 e2)
+  = (sto, Pair v1 v2)
+  where (_, v1) = eval sto e1
+        (_, v2) = eval sto e2
+
+eval sto (Fst e)
+  = let (sto', e') = eval sto e in
+    case e' of
+      Pair v _ -> (sto', v)
+      _        -> error "non-tuple fst"
+
+eval sto (Snd e)
+  = let (sto', e') = eval sto e in
+    case e' of
+      Pair _ v -> (sto', v)
+      _        -> error "non-tuple snd"
+
+---------------------------------------------------------------------
+-------------------------- Value Checker ----------------------------
+---------------------------------------------------------------------
+
+{-@ assert check :: {v: Expr | (? (isValue([v]))) } -> Bool @-}
+check (Const _)    = True
+check (Lam _ _)    = True
+check (Var _)      = liquidAssertB False
+check (App _ _)    = liquidAssertB False
+check (Pair v1 v2) = check v1 && check v2
+check (Fst _)      = liquidAssertB False
+check (Snd _)      = liquidAssertB False
+check (Plus _ _)   = liquidAssertB False
+
+---------------------------------------------------------------------
+-------------------------- Unit Tests -------------------------------
+---------------------------------------------------------------------
+
+tests =
+  let (f,g,x) = (0,1,2) 
+      e1      = Lam x (Var x)
+      e2      = App e1 e1 
+      e3      = Lam f (Lam g (Lam x (App (Var f)  (App (Var g) (Var x)))))
+      e4      = Const 10
+      e5      = App e1 e4
+      e6      = Lam x (Plus (Var x) e4)
+      e7      = App (App e3 e6) e6
+      e8      = Pair (App e7 (Const 0)) (App e7 (Const 100))
+      e9      = Fst e8
+      e10     = Snd e9
+      vs      = map (snd . eval []) [e1, e2, e3, e4, e5, e6, e7, e8, e9, e10]
+  in map check vs
diff --git a/docs/blog/todo/Termination.hs b/docs/blog/todo/Termination.hs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/Termination.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Term where
+
+import Data.Vector.Algorithms.Common (shiftRI)
+import Language.Haskell.Liquid.Prelude (choose)
+
+
+{-@ loop :: twit:Nat -> l:Nat -> u:{v:Nat | v = l + twit} -> Int @-}
+loop :: Int -> Int -> Int -> Int
+loop twit l u 
+   | u <= l    = l
+   | otherwise = case compare (choose 0) 0 of
+                   LT -> loop (u - (k + 1)) (k+1) u 
+                   EQ -> k
+                   GT -> loop (k - l) l     k 
+  where k = (u + l) `shiftRI` 1
+
+{-@ loop1 :: l:Nat -> u:{v:Nat | l <= v} -> Int / [u + l] @-}
+loop1 :: Int -> Int -> Int
+loop1 l u 
+   | u <= l    = l
+   | otherwise = case compare (choose 0) 0 of
+                   LT -> loop1 (k+1) u 
+                   EQ -> k
+                   GT -> loop1 l     k 
+  where k = (u + l) `shiftRI` 1
+
diff --git a/docs/blog/todo/TextBug.lhs b/docs/blog/todo/TextBug.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/TextBug.lhs
@@ -0,0 +1,345 @@
+---
+layout: post
+title: "Text Bug"
+date: 2014-03-01
+comments: true
+external-url:
+author: Eric Seidel
+published: false
+categories: benchmarks, text
+demo: TextBug.hs
+---
+
+For our last post on `text`, we return to the topic of building a new `Text`
+value, i.e. proving the safety of write operations.
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types,
+    RecordWildCards, UnboxedTuples, ExistentialQuantification #-}
+{-@ LIQUID "--no-termination" @-}
+module TextBug where
+
+import Control.Monad.ST.Unsafe (unsafeIOToST)
+import Foreign.C.Types (CSize)
+import GHC.Base hiding (unsafeChr)
+import GHC.ST
+import GHC.Word (Word16(..))
+import Data.Bits hiding (shiftL)
+import Data.Word
+
+import Language.Haskell.Liquid.Prelude
+
+--------------------------------------------------------------------------------
+--- From TextInternal
+--------------------------------------------------------------------------------
+
+{-@ shiftL :: i:Nat -> n:Nat -> {v:Nat | ((n = 1) => (v = (i * 2)))} @-}
+shiftL :: Int -> Int -> Int
+shiftL = undefined -- (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+{-@ measure isUnknown :: Size -> Prop
+    isUnknown (Exact n) = false
+    isUnknown (Max   n) = false
+    isUnknown (Unknown) = true
+  @-}
+{-@ measure getSize :: Size -> Int
+    getSize (Exact n) = n
+    getSize (Max   n) = n
+  @-}
+
+{-@ invariant {v:Size | (getSize v) >= 0} @-}
+
+data Size = Exact {-# UNPACK #-} !Int -- ^ Exact size.
+          | Max   {-# UNPACK #-} !Int -- ^ Upper bound on size.
+          | Unknown                   -- ^ Unknown size.
+            deriving (Eq, Show)
+
+{-@ upperBound :: k:Nat -> s:Size -> {v:Nat | v = ((isUnknown s) ? k : (getSize s))} @-}
+upperBound :: Int -> Size -> Int
+upperBound _ (Exact n) = n
+upperBound _ (Max   n) = n
+upperBound k _         = k
+
+data Step s a = Done
+              | Skip !s
+              | Yield !a !s
+
+data Stream a =
+    forall s. Stream
+    (s -> Step s a)             -- stepper function
+    !s                          -- current state
+    !Size                       -- size hint
+
+{-@ data Array = Array { aBA  :: ByteArray#
+                       , aLen :: Nat 
+                       } 
+  @-}
+
+data Array = Array {
+    aBA  :: ByteArray#
+  , aLen :: !Int
+  }
+
+{-@ measure alen     :: Array -> Int
+    alen (Array a n) = n
+  @-}
+
+{-@ aLen :: a:Array -> {v:Nat | v = (alen a)}  @-}
+
+{-@ type ArrayN  N   = {v:Array | (alen v) = N} @-}
+
+{-@ type AValidI A   = {v:Nat | v     <  (alen A)} @-}
+{-@ type AValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type AValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+{-@ data MArray s = MArray { maBA  :: MutableByteArray# s
+                           , maLen :: Nat } @-}
+
+data MArray s = MArray {
+    maBA  :: MutableByteArray# s
+  , maLen :: !Int
+  }
+
+{-@ measure malen :: MArray s -> Int
+    malen (MArray a n) = n
+  @-}
+
+{-@ maLen :: a:MArray s -> {v:Nat | v = (malen a)}  @-}
+
+{-@ type MArrayN s N = {v:MArray s | (malen v) = N} @-}
+
+{-@ type MAValidI MA = {v:Nat | v <  (malen MA)} @-}
+{-@ type MAValidO MA = {v:Nat | v <= (malen MA)} @-}
+
+{-@ new :: forall s. n:Nat -> ST s (MArrayN s n) @-}
+new          :: forall s. Int -> ST s (MArray s)
+new n
+  | n < 0 || n .&. highBit /= 0 = error $ "new: size overflow"
+  | otherwise = ST $ \s1# ->
+       case newByteArray# len# s1# of
+         (# s2#, marr# #) -> (# s2#, MArray marr# n #)
+  where !(I# len#) = bytesInArray n
+        highBit    = maxBound `xor` (maxBound `shiftR` 1)
+        bytesInArray n = n `shiftL` 1
+
+{-@ unsafeWrite :: ma:MArray s -> MAValidI ma -> Word16 -> ST s () @-}
+unsafeWrite  :: MArray s -> Int -> Word16 -> ST s ()
+unsafeWrite MArray{..} i@(I# i#) (W16# e#)
+  | i < 0 || i >= maLen = liquidError "out of bounds"
+  | otherwise = ST $ \s1# ->
+      case writeWord16Array# maBA i# e# s1# of
+        s2# -> (# s2#, () #)
+
+{-@ copyM :: dest:MArray s 
+          -> didx:MAValidO dest
+          -> src:MArray s 
+          -> sidx:MAValidO src
+          -> {v:Nat | (((didx + v) <= (malen dest))
+                    && ((sidx + v) <= (malen src)))}
+          -> ST s ()
+  @-}
+copyM        :: MArray s               -- ^ Destination
+             -> Int                    -- ^ Destination offset
+             -> MArray s               -- ^ Source
+             -> Int                    -- ^ Source offset
+             -> Int                    -- ^ Count
+             -> ST s ()
+copyM dest didx src sidx count
+    | count <= 0 = return ()
+    | otherwise =
+    liquidAssert (sidx + count <= maLen src) .
+    liquidAssert (didx + count <= maLen dest) .
+    unsafeIOToST $ memcpyM (maBA dest) (fromIntegral didx)
+                           (maBA src) (fromIntegral sidx)
+                           (fromIntegral count)
+
+{-@ memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO () @-}
+memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO ()
+memcpyM = undefined
+
+{-@ unsafeFreeze :: ma:MArray s -> ST s (ArrayN (malen ma)) @-}
+unsafeFreeze :: MArray s -> ST s Array
+unsafeFreeze MArray{..} = ST $ \s# ->
+                          (# s#, Array (unsafeCoerce# maBA) maLen #)
+
+{-@ unsafeIndex :: a:Array -> AValidI a -> Word16 @-}
+unsafeIndex  :: Array -> Int -> Word16
+unsafeIndex Array{..} i@(I# i#)
+  | i < 0 || i >= aLen = liquidError "out of bounds"
+  | otherwise = case indexWord16Array# aBA i# of
+                  r# -> (W16# r#)
+
+data Text = Text Array Int Int
+{-@ data Text [tlen] = Text (arr :: Array)
+                            (off :: TValidO arr)
+                            (len :: TValidL off arr)
+  @-}
+
+{-@ measure tarr :: Text -> Array
+    tarr (Text a o l) = a
+  @-}
+
+{-@ measure toff :: Text -> Int
+    toff (Text a o l) = o
+  @-}
+
+{-@ measure tlen :: Text -> Int
+    tlen (Text a o l) = l
+  @-}
+
+{-@ type TValidI T   = {v:Nat | v     <  (tlen T)} @-}
+{-@ type TValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type TValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+
+--------------------------------------------------------------------------------
+--- From TextRead
+--------------------------------------------------------------------------------
+
+{-@ measure numchars :: Array -> Int -> Int -> Int @-}
+{-@ measure tlength :: Text -> Int @-}
+{-@ invariant {v:Text | (tlength v) = (numchars (tarr v) (toff v) (tlen v))} @-}
+
+--------------------------------------------------------------------------------
+--- From TextWrite
+--------------------------------------------------------------------------------
+
+{-@ qualif Ord(v:int, i:int, x:Char)
+        : ((((ord x) <  65536) => (v = i))
+        && (((ord x) >= 65536) => (v = (i + 1))))
+  @-}
+
+{-@ predicate Room C MA I = (((One C) => (RoomN 1 MA I))
+                          && ((Two C) => (RoomN 2 MA I)))
+  @-}
+{-@ predicate RoomN N MA I = (I+N <= (malen MA)) @-}
+
+{-@ measure ord :: Char -> Int @-}
+{-@ ord :: c:Char -> {v:Int | v = (ord c)} @-}
+{-@ predicate One C = ((ord C) <  65536) @-}
+{-@ predicate Two C = ((ord C) >= 65536) @-}
+
+{-@ writeChar :: ma:MArray s -> i:Nat -> {v:Char | (Room v ma i)}
+              -> ST s {v:Nat | (RoomN v ma i)}
+  @-}
+writeChar :: MArray s -> Int -> Char -> ST s Int
+writeChar marr i c
+    | n < 0x10000 = do
+        unsafeWrite marr i (fromIntegral n)
+        return 1
+    | otherwise = do
+        unsafeWrite marr i lo
+        unsafeWrite marr (i+1) hi
+        return 2
+    where n = ord c
+          m = n - 0x10000
+          lo = fromIntegral $ (m `shiftR` 10) + 0xD800
+          hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
+
+--------------------------------------------------------------------------------
+--- Helpers
+--------------------------------------------------------------------------------
+
+{-@ qualif MALenLE(v:int, a:MArray s): v <= (malen a) @-}
+{-@ qualif ALenLE(v:int, a:Array): v <= (alen a) @-}
+
+\end{code}
+
+</div>
+
+Let's take a look at `mapAccumL`, which combines a map and a fold
+over a `Stream` and bundles the result of the map into a new `Text`.
+Again, we'll want to focus our attention on the `Yield` case of the
+inner loop.
+
+\begin{code}
+mapAccumL f z0 (Stream next0 s0 len) =
+  (nz, Text na 0 nl)
+ where
+  mlen = upperBound 4 len
+  (na,(nz,nl)) = runST $ do
+       (marr,x) <- (new mlen >>= \arr ->
+                    outer arr mlen z0 s0 0)
+       arr      <- unsafeFreeze marr
+       return (arr,x)
+  outer arr top = loop
+   where
+    loop !z !s !i =
+      case next0 s of
+        Done          -> return (arr, (z,i))
+        Skip s'       -> loop z s' i
+        Yield x s'
+          | j >= top  -> do
+            let top' = (top + 1) `shiftL` 1
+            arr' <- new top'
+            copyM arr' 0 arr 0 top
+            outer arr' top' z s i
+          | otherwise -> do
+            let (z',c) = f z x
+            d <- writeChar arr i c
+            loop z' s' (i+d)
+          where j | ord x < 0x10000 = i
+                  | otherwise       = i + 1
+\end{code}
+
+If you recall `unstream` from last time, you'll notice that this loop body
+looks almost identical to the one found in `unstream`, but LiquidHaskell has
+flagged the `writeChar` call as unsafe! What's going on here?
+
+Let's take a look at `j`, recalling that it carried a crucial part of the safety
+\begin{code} proof last time, and see what LiquidHaskell was able to infer.
+{v:Int | ((ord x >= 65536) => (v == i+1))
+      && ((ord x <  65536) => (v == i))}
+\end{code}
+
+Well that's not very useful at all! LiquidHaskell can prove that it's safe to
+write `x` but here we are trying to write `c` into the array. This is actually
+a *good* thing though, because `c` is the result of calling an arbitrary
+function `f` on `x`! We haven't constrained `f` in any way, so it could easily
+return a character above `U+10000` given any input.
+
+So `mapAccumL` is actually *unsafe*, and our first wild bug caught by
+LiquidHaskell! The fix is luckily easy, we simply have to lift the
+`let (z',c) = f z x` binder into the `where` clause, and change `j` to
+depend on `ord c` instead.
+
+\begin{code}
+mapAccumL' f z0 (Stream next0 s0 len) =
+  (nz, Text na 0 nl)
+ where
+  mlen = upperBound 4 len
+  (na,(nz,nl)) = runST $ do
+       (marr,x) <- (new mlen >>= \arr ->
+                    outer arr mlen z0 s0 0)
+       arr      <- unsafeFreeze marr
+       return (arr,x)
+  outer arr top = loop
+   where
+    loop !z !s !i =
+      case next0 s of
+        Done          -> return (arr, (z,i))
+        Skip s'       -> loop z s' i
+        Yield x s'
+          | j >= top  -> do
+            let top' = (top + 1) `shiftL` 1
+            arr' <- new top'
+            copyM arr' 0 arr 0 top
+            outer arr' top' z s i
+          | otherwise -> do
+            d <- writeChar arr i c
+            loop z' s' (i+d)
+          where (z',c) = f z x
+                j | ord c < 0x10000 = i
+                  | otherwise       = i + 1
+\end{code}
+
+LiquidHaskell happily accepts our revised `mapAccumL`, as did the `text`
+maintainers.
+
+We hope you've enjoyed this whirlwind tour of using LiquidHaskell to verify
+production code, we have many more examples in the `benchmarks` folder of
+our GitHub repository for the intrepid reader.
diff --git a/docs/blog/todo/TextInternal.lhs b/docs/blog/todo/TextInternal.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/TextInternal.lhs
@@ -0,0 +1,384 @@
+---
+layout: post
+title: "Text Internals"
+date: 2014-02-09
+comments: true
+external-url:
+author: Eric Seidel
+published: false
+categories: benchmarks, text
+demo: TextInternal.hs
+---
+
+So far we have mostly discussed LiquidHaskell in the context of
+recursive data structures like lists, but there comes a time in 
+many programs when you have to put down the list and pick up an 
+array for the sake of performance. 
+In this series we're going to examine the `text` library, which 
+does exactly this in addition to having extensive Unicode support.
+
+`text` is a popular library for efficient text processing. 
+It provides the high-level API haskellers have come to expect while 
+using stream fusion and byte arrays under the hood to guarantee high
+performance. 
+
+The thing that makes `text` stand out as an interesting target for 
+LiquidHaskell, however, is its use of Unicode. 
+Specifically, `text` uses UTF-16 as its internal encoding, where 
+each character is represented with either two or four bytes. 
+We'll see later on how this encoding presents a challenge for 
+verifying memory-safety, but first let us look at how a `Text` 
+is represented.
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types,
+    RecordWildCards, UnboxedTuples, ExistentialQuantification #-}
+{-@ LIQUID "--no-termination" @-}
+module TextInternal where
+
+import Control.Monad.ST.Unsafe (unsafeIOToST)
+import Data.Bits (shiftR, xor, (.&.))
+import Foreign.C.Types (CSize)
+import GHC.Base (Int(..), ByteArray#, MutableByteArray#, newByteArray#,
+                 writeWord16Array#, indexWord16Array#, unsafeCoerce#, ord,
+                 iShiftL#)
+import GHC.ST (ST(..), runST)
+import GHC.Word (Word16(..))
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ data Array = Array { aBA  :: ByteArray#
+                       , aLen :: Nat 
+                       } 
+  @-}
+
+{-@ aLen :: a:Array -> {v:Nat | v = (alen a)}  @-}
+
+{-@ data MArray s = MArray { maBA  :: MutableByteArray# s
+                           , maLen :: Nat } @-}
+
+{-@ maLen :: a:MArray s -> {v:Nat | v = (malen a)}  @-}
+
+new          :: forall s. Int -> ST s (MArray s)
+unsafeWrite  :: MArray s -> Int -> Word16 -> ST s ()
+unsafeFreeze :: MArray s -> ST s Array
+unsafeIndex  :: Array -> Int -> Word16
+copyM        :: MArray s               -- ^ Destination
+             -> Int                    -- ^ Destination offset
+             -> MArray s               -- ^ Source
+             -> Int                    -- ^ Source offset
+             -> Int                    -- ^ Count
+             -> ST s ()
+
+--------------------------------------------------------------------------------
+--- Helper Code
+--------------------------------------------------------------------------------
+{-@ predicate RoomN N MA I = (I+N <= (malen MA)) @-}
+
+{-@ writeChar :: ma:MArray s -> i:{Nat | i < (malen ma) - 1} -> Char
+              -> ST s {v:Nat | (RoomN v ma i)}
+  @-}
+writeChar :: MArray s -> Int -> Char -> ST s Int
+writeChar marr i c
+    | n < 0x10000 = do
+        unsafeWrite marr i (fromIntegral n)
+        return 1
+    | otherwise = do
+        unsafeWrite marr i lo
+        unsafeWrite marr (i+1) hi
+        return 2
+    where n = ord c
+          m = n - 0x10000
+          lo = fromIntegral $ (m `shiftR` 10) + 0xD800
+          hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
+
+
+{-@ measure isUnknown :: Size -> Prop
+    isUnknown (Exact n) = false
+    isUnknown (Max   n) = false
+    isUnknown (Unknown) = true
+  @-}
+{-@ measure getSize :: Size -> Int
+    getSize (Exact n) = n
+    getSize (Max   n) = n
+  @-}
+
+{-@ invariant {v:Size | (getSize v) >= 0} @-}
+
+data Size = Exact {-# UNPACK #-} !Int -- ^ Exact size.
+          | Max   {-# UNPACK #-} !Int -- ^ Upper bound on size.
+          | Unknown                   -- ^ Unknown size.
+            deriving (Eq, Show)
+
+{-@ upperBound :: k:Nat -> s:Size -> {v:Nat | v = ((isUnknown s) ? k : (getSize s))} @-}
+upperBound :: Int -> Size -> Int
+upperBound _ (Exact n) = n
+upperBound _ (Max   n) = n
+upperBound k _         = k
+
+data Step s a = Done
+              | Skip !s
+              | Yield !a !s
+
+data Stream a =
+    forall s. Stream
+    (s -> Step s a)             -- stepper function
+    !s                          -- current state
+    !Size                       -- size hint
+
+{-@ shiftL :: i:Nat -> n:Nat -> {v:Nat | ((n = 1) => (v = (i * 2)))} @-}
+shiftL :: Int -> Int -> Int
+shiftL = undefined -- (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+{-@ memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO () @-}
+memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO ()
+memcpyM = undefined
+
+\end{code}
+
+</div>
+
+`text` splits the reading and writing array operations between two
+types of arrays, immutable `Array`s and mutable `MArray`s. This leads to
+the following general lifecycle:
+
+![The lifecycle of a `Text`](/images/text-lifecycle.png)
+
+
+\begin{code}
+data Array = Array {
+    aBA  :: ByteArray#
+  , aLen :: !Int
+  }
+
+{-@ measure alen     :: Array -> Int
+    alen (Array a n) = n
+  @-}
+
+data MArray s = MArray {
+    maBA  :: MutableByteArray# s
+  , maLen :: !Int
+  }
+
+{-@ measure malen :: MArray s -> Int
+    malen (MArray a n) = n
+  @-}
+
+\end{code}
+
+Both types carry around with them the number of `Word16`s they can
+hold (this is actually only true when you compile with asserts turned
+on, but we use this to ease the verification process).
+
+The main three array operations we care about are: 
+
+1. **writing** into an `MArray`, 
+2. **reading** from an `Array`, and 
+3. **freezing** an `MArray` into an `Array`. 
+
+But first, let's see how one creates an `MArray`.
+
+\begin{code}
+{-@ type MArrayN s N = {v:MArray s | (malen v) = N} @-}
+
+{-@ new :: forall s. n:Nat -> ST s (MArrayN s n) @-}
+new n
+  | n < 0 || n .&. highBit /= 0 = error $ "new: size overflow"
+  | otherwise = ST $ \s1# ->
+       case newByteArray# len# s1# of
+         (# s2#, marr# #) -> (# s2#, MArray marr# n #)
+  where !(I# len#) = bytesInArray n
+        highBit    = maxBound `xor` (maxBound `shiftR` 1)
+        bytesInArray n = n `shiftL` 1
+\end{code}
+
+`new n` is an `ST` action that produces an `MArray s` with `n` slots,
+denoted by the type alias `MArrayN s n`. Note that we are not talking
+about bytes here, `text` deals with `Word16`s internally and as such
+we actualy allocate `2*n` bytes.  While this may seem like a lot of
+code to just create an array, the verification process here is quite
+simple. LiquidHaskell simply recognizes that the `n` used to construct
+the returned array (`MArray marr# n`) is the same `n` passed to
+`new`. It should be noted that we're abstracting away some detail here
+with respect to the underlying `MutableByteArray#`, specifically we're
+making the assumption that any *unsafe* operation will be caught and
+dealt with before the `MutableByteArray#` is touched.
+
+Once we have an `MArray` in hand, we'll want to be able to write our
+data into it. A `Nat` is a valid index into an `MArray` `ma` if it is
+less than the number of slots, for which we have another type alias
+`MAValidI ma`. `text` includes run-time assertions that check this
+property, but LiquidHaskell can statically prove the assertions will
+always pass.
+
+\begin{code}
+{-@ type MAValidI MA = {v:Nat | v < (malen MA)} @-}
+{-@ unsafeWrite :: ma:MArray s -> MAValidI ma -> Word16 -> ST s () @-}
+unsafeWrite MArray{..} i@(I# i#) (W16# e#)
+  | i < 0 || i >= maLen = liquidError "out of bounds"
+  | otherwise = ST $ \s1# ->
+      case writeWord16Array# maBA i# e# s1# of
+        s2# -> (# s2#, () #)
+\end{code}
+
+So now we can write individual `Word16`s into an array, but maybe we
+have a whole bunch of text we want to dump into the array. Remember,
+`text` is supposed to be fast!
+C has `memcpy` for cases like this but it's notoriously unsafe; with
+the right type however, we can regain safety. `text` provides a wrapper around
+`memcpy` to copy `n` elements from one `MArray` to another.
+
+\begin{code}
+{-@ type MAValidO MA = {v:Nat | v <= (malen MA)} @-}
+{-@ copyM :: dest:MArray s
+          -> didx:MAValidO dest
+          -> src:MArray s 
+          -> sidx:MAValidO src
+          -> {v:Nat | (((didx + v) <= (malen dest))
+                    && ((sidx + v) <= (malen src)))}
+          -> ST s ()
+  @-}
+copyM dest didx src sidx count
+    | count <= 0 = return ()
+    | otherwise =
+    liquidAssert (sidx + count <= maLen src) .
+    liquidAssert (didx + count <= maLen dest) .
+    unsafeIOToST $ memcpyM (maBA dest) (fromIntegral didx)
+                           (maBA src) (fromIntegral sidx)
+                           (fromIntegral count)
+\end{code}
+
+`copyM` requires two `MArray`s and valid offsets into each -- note 
+that a valid offset is **not** necessarily a valid *index*, it may 
+be one element out-of-bounds -- and a `count` of elements to copy.
+The `count` must represent a valid region in each `MArray`, in 
+other words `offset + count <= length` must hold for each array. 
+`memcpyM` is an FFI function writen in C, which we don't currently
+support, so we simply leave it `undefined`.
+
+Before we can package up our `MArray` into a `Text`, we need to
+*freeze* it, preventing any further mutation. The key property here is
+of course that the frozen `Array` should have the same length as the
+`MArray`.
+
+\begin{code}
+{-@ type ArrayN N = {v:Array | (alen v) = N} @-}
+{-@ unsafeFreeze :: ma:MArray s -> ST s (ArrayN (malen ma)) @-}
+unsafeFreeze MArray{..} = ST $ \s# ->
+                          (# s#, Array (unsafeCoerce# maBA) maLen #)
+\end{code}
+
+Again, LiquidHaskell is happy to prove our specification as we simply
+copy the length parameter `maLen` over into the `Array`.
+
+Finally, we will eventually want to read a value out of the
+`Array`. As with `unsafeWrite` we require a valid index into the
+`Array`, which we denote using the `AValidI` alias.
+
+\begin{code}
+{-@ type AValidI A = {v:Nat | v < (alen A)} @-}
+{-@ unsafeIndex :: a:Array -> AValidI a -> Word16 @-}
+unsafeIndex Array{..} i@(I# i#)
+  | i < 0 || i >= aLen = liquidError "out of bounds"
+  | otherwise = case indexWord16Array# aBA i# of
+                  r# -> (W16# r#)
+\end{code}
+
+As before, LiquidHaskell can easily prove that the run-time assertions
+will never fail.
+
+
+Now we can finally define the core datatype of the `text` package! 
+A `Text` value consists of an *array*, an *offset*, and a *length*. 
+The offset and length are `Nat`s satisfying two properties: 
+
+1. `off <= alen arr`, and 
+2. `off + len <= alen arr`
+
+These invariants ensure that any *index* we pick between `off` and
+`off + len` will be a valid index into `arr`. If you're not quite
+convinced, consider the following `Text`s.
+
+![Multiple valid `Text` configurations, all using an `Array` with 10 slots. The valid slots are shaded. Note that the key invariant is that `off + len <= alen`.](/images/text-layout.png)
+
+\begin{code}
+data Text = Text Array Int Int
+{-@ data Text [tlen] = Text (arr :: Array)
+                            (off :: TValidO arr)
+                            (len :: TValidL off arr)
+  @-}
+
+{-@ measure tarr :: Text -> Array
+    tarr (Text a o l) = a
+  @-}
+
+{-@ measure toff :: Text -> Int
+    toff (Text a o l) = o
+  @-}
+
+{-@ measure tlen :: Text -> Int
+    tlen (Text a o l) = l
+  @-}
+\end{code}
+
+The liquid-type for `Text` makes use of the following two type-aliases to
+express the core invariant.
+
+\begin{code}
+{-@ type TValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type TValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+\end{code}
+
+Before we go, let's take a quick look at a function that combines
+`MArray`s, `Array`s, and `Text`s. `unstream` is a major workhorse of
+the `text` library. It transforms a `Stream` of `Char`s into a `Text`,
+and enables GHC use a technique called *stream fusion* to combine
+multiple loops over a sequence into a single loop.
+
+\begin{code}
+unstream :: Stream Char -> Text
+unstream (Stream next0 s0 len) = runST $ do
+  let mlen = upperBound 4 len
+  arr0 <- new mlen
+  let outer arr top = loop
+       where
+        loop !s !i =
+            case next0 s of
+              Done          -> do
+                arr' <- unsafeFreeze arr
+                return $! Text arr' 0 i
+              Skip s'       -> loop s' i
+              Yield x s'
+                | j >= top  -> do
+                  let top' = (top + 1) `shiftL` 1
+                  arr' <- new top'
+                  copyM arr' 0 arr 0 top
+                  outer arr' top' s i
+                | otherwise -> do
+                  d <- writeChar arr i x
+                  loop s' (i+d)
+                where j | ord x < 0x10000 = i
+                        | otherwise       = i + 1
+  outer arr0 mlen s0 0
+\end{code}
+
+`unstream` repeatedly writes the characters coming out of the `Stream`
+into the `arr`, until it runs out of room. Then it has to allocate a
+new, larger `MArray` and copy everything into the new array before
+continuing. Note that LiquidHaskell has successfully inferred that
+`arr'` is longer than `arr` and that `top` is a valid offset into
+both, thus proving that the call to `copyM` is safe! Unfortunately for
+us, however, the `writeChar` call is flagged as *unsafe*.. Astute
+readers will notice that `writeChar` (whose implementation we haven't
+yet seen) has a slightly odd type, it requires that the index `i` be
+less than `malen arr - 1`. This is indeed odd and, I should add, not
+the final type, but it is a safe approximation because not all `Char`s
+are created equal. Depending on your encoding, some won't fit into a
+single `Word16`, so we may need extra room to write!
+
+Stay tuned, next time we'll dig into how `text` uses Unicode to
+represent `Char`s internally.
diff --git a/docs/blog/todo/TextRead.lhs b/docs/blog/todo/TextRead.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/TextRead.lhs
@@ -0,0 +1,357 @@
+---
+layout: post
+title: "Text Read"
+date: 2014-02-16
+comments: true
+external-url:
+author: Eric Seidel
+published: false
+categories: benchmarks, text
+demo: TextRead.hs
+---
+
+Welcome back! Last time we left off on a bit of a cliffhanger with the
+`unstream` example. Remember, the issue we found was that some `Char`s
+can't fit into a single `Word16`, so the safety of a write depends not
+only on the *index*, but also on the *value* being written! Before we
+can resolve this issue with `unstream` we'll have to learn about
+UTF-16, so let's take a short detour and look at how one *consumes* a
+`Text`.
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types,
+    RecordWildCards, UnboxedTuples, ExistentialQuantification #-}
+{-@ LIQUID "--no-termination" @-}
+module TextRead where
+
+import GHC.Base hiding (unsafeChr)
+import GHC.ST
+import GHC.Word (Word16(..))
+import Data.Bits hiding (shiftL)
+import Data.Word
+
+import Language.Haskell.Liquid.Prelude
+
+
+--------------------------------------------------------------------------------
+--- From TextInternal
+--------------------------------------------------------------------------------
+
+{-@ shiftL :: i:Nat -> n:Nat -> {v:Nat | ((n = 1) => (v = (i * 2)))} @-}
+shiftL :: Int -> Int -> Int
+shiftL = undefined -- (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+{-@ data Array = Array { aBA  :: ByteArray#
+                       , aLen :: Nat 
+                       } 
+  @-}
+
+data Array = Array {
+    aBA  :: ByteArray#
+  , aLen :: !Int
+  }
+
+{-@ measure alen     :: Array -> Int
+    alen (Array a n) = n
+  @-}
+
+{-@ aLen :: a:Array -> {v:Nat | v = (alen a)}  @-}
+
+{-@ type ArrayN  N   = {v:Array | (alen v) = N} @-}
+
+{-@ type AValidI A   = {v:Nat | v     <  (alen A)} @-}
+{-@ type AValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type AValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+{-@ data MArray s = MArray { maBA  :: MutableByteArray# s
+                           , maLen :: Nat } @-}
+
+data MArray s = MArray {
+    maBA  :: MutableByteArray# s
+  , maLen :: !Int
+  }
+
+{-@ measure malen :: MArray s -> Int
+    malen (MArray a n) = n
+  @-}
+
+{-@ maLen :: a:MArray s -> {v:Nat | v = (malen a)}  @-}
+
+{-@ type MArrayN s N = {v:MArray s | (malen v) = N} @-}
+
+{-@ type MAValidO MA = {v:Nat | v <= (malen MA)} @-}
+
+{-@ new :: forall s. n:Nat -> ST s (MArrayN s n) @-}
+new          :: forall s. Int -> ST s (MArray s)
+new n
+  | n < 0 || n .&. highBit /= 0 = error $ "new: size overflow"
+  | otherwise = ST $ \s1# ->
+       case newByteArray# len# s1# of
+         (# s2#, marr# #) -> (# s2#, MArray marr# n #)
+  where !(I# len#) = bytesInArray n
+        highBit    = maxBound `xor` (maxBound `shiftR` 1)
+        bytesInArray n = n `shiftL` 1
+
+{-@ unsafeFreeze :: ma:MArray s -> ST s (ArrayN (malen ma)) @-}
+unsafeFreeze :: MArray s -> ST s Array
+unsafeFreeze MArray{..} = ST $ \s# ->
+                          (# s#, Array (unsafeCoerce# maBA) maLen #)
+
+{-@ unsafeIndex :: a:Array -> AValidI a -> Word16 @-}
+unsafeIndex  :: Array -> Int -> Word16
+unsafeIndex Array{..} i@(I# i#)
+  | i < 0 || i >= aLen = liquidError "out of bounds"
+  | otherwise = case indexWord16Array# aBA i# of
+                  r# -> (W16# r#)
+
+data Text = Text Array Int Int
+{-@ data Text [tlen] = Text (arr :: Array)
+                            (off :: TValidO arr)
+                            (len :: TValidL off arr)
+  @-}
+
+{-@ measure tarr :: Text -> Array
+    tarr (Text a o l) = a
+  @-}
+
+{-@ measure toff :: Text -> Int
+    toff (Text a o l) = o
+  @-}
+
+{-@ measure tlen :: Text -> Int
+    tlen (Text a o l) = l
+  @-}
+
+{-@ type TValidI T   = {v:Nat | v     <  (tlen T)} @-}
+{-@ type TValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type TValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+
+--------------------------------------------------------------------------------
+--- Helpers
+--------------------------------------------------------------------------------
+
+{-@ invariant {v:Text | (tlength v) = (numchars (tarr v) (toff v) (tlen v))} @-}
+
+{-@ axiom_lead_surr :: x:Word16 -> a:Array -> o:Nat -> l:Nat -> i:Nat
+                  -> {v:Bool | ((Prop v) <=> (if (55296 <= x && x <= 56319)
+                                              then (SpanChar 2 a o l i)
+                                              else (SpanChar 1 a o l i)))}
+  @-}
+axiom_lead_surr :: Word16 -> Array -> Int -> Int -> Int -> Bool
+axiom_lead_surr = undefined
+
+{-@ empty :: {v:Text | (tlen v) = 0} @-}
+empty :: Text
+empty = Text arrEmpty 0 0
+  where
+    {-@ arrEmpty :: (ArrayN {0}) @-}
+    arrEmpty = runST $ new 0 >>= unsafeFreeze
+
+unsafeChr :: Word16 -> Char
+unsafeChr (W16# w#) = C# (chr# (word2Int# w#))
+
+chr2 :: Word16 -> Word16 -> Char
+chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#))
+    where
+      !x# = word2Int# a#
+      !y# = word2Int# b#
+      !upper# = uncheckedIShiftL# (x# -# 0xD800#) 10#
+      !lower# = y# -# 0xDC00#
+
+{-@ qualif Min(v:int, t:Text, i:int):
+      (if ((tlength t) < i)
+       then ((numchars (tarr t) (toff t) v) = (tlength t))
+       else ((numchars (tarr t) (toff t) v) = i))
+  @-}
+
+{-@ qualif NumChars(v:int, t:Text, i:int): v = (numchars (tarr t) (toff t) i) @-}
+
+{-@ qualif TLengthLE(v:int, t:Text): v <= (tlength t) @-}
+
+\end{code}
+
+</div>
+
+Let's begin with a simple example, `unsafeHead`.
+
+\begin{code}
+{-@ type TextNE = {v:Text | (tlen v) > 0} @-}
+
+{-@ unsafeHead :: TextNE -> Char @-}
+unsafeHead :: Text -> Char
+unsafeHead (Text arr off _len)
+    | m < 0xD800 || m > 0xDBFF = unsafeChr m
+    | otherwise                = chr2 m n
+    where m = unsafeIndex arr off
+          n = unsafeIndex arr (off+1)
+\end{code}
+
+LiquidHaskell can prove the first `unsafeIndex` is safe because the
+precondition states that the `Text` must not be empty, i.e. `_len > 0`
+must hold. Combine this with the core `Text` invariant that
+`off + _len <= alen arr` and we get that `off < alen arr`, which satisfies
+the precondition for `unsafeIndex`.
+
+However, the same calculation *fails* for the second index because we
+can't prove that `off + 1 < alen arr`. The solution is going to
+require some understanding of UTF-16, so let's take a brief detour.
+
+The UTF-16 standard represents all code points below `U+10000` with a
+single 16-bit word; all others are split into two 16-bit words, known
+as a *surrogate pair*. The first word, or *lead*, is guaranteed to be
+in the range `[0xD800, 0xDBFF]` and the second, or *trail*, is
+guaranteed to be in the range `[0xDC00, 0xDFFF]`.
+
+Armed with this knowledge of UTF-16 we can return to
+`unsafeHead`. Note the case-split on `m`, which determines whether `m`
+is a lead surrogate. If `m` is a lead surrogate then we know there
+must be a trail surrogate at `off+1`; we can define a specialized
+version of `unsafeIndex` that encodes this domain knowledge.
+
+\begin{code}
+{-@ unsafeIndexF :: a:Array -> o:AValidO a -> l:AValidL o a
+                 -> i:{v:Nat | (o <= v && v < (o + l))}
+                 -> {v:Word16 | (if (55296 <= v && v <= 56319)
+                                 then (SpanChar 2 a o l i)
+                                 else (SpanChar 1 a o l i))}
+  @-}
+unsafeIndexF :: Array -> Int -> Int -> Int -> Word16
+unsafeIndexF a o l i = let x = unsafeIndex a i
+                       in liquidAssume (axiom_lead_surr x a o l i) x
+\end{code}
+
+Our variant `unsafeIndexF` (F as in "forward") takes an array, an
+offset, and a length (which together must form a valid `Text`); a
+valid index into the `Text`; and returns a `Word16` with an
+interesting type. The best way to read this type would be "if `v` is
+in the range `[0xD800, 0xDBFF]`, then the character that starts at
+index `i` in the array `a` spans two slots, otherwise it only spans
+one slot." Intuitively, we know what it means for a character to span
+`n` slots, but LiquidHaskell needs to know three things:
+
+1. `a[o:i+n]` contains one more character than `a[o:i]` (borrowing
+   Python's wonderful slicing syntax)
+2. `a[o:i+n]` contains no more characters than `a[o:l]`
+3. `i-o+n <= l`
+
+2 and 3 encode the well-formedness of a `Text` value, i.e. `i+1`
+*must* be a valid index if a lead surrogate is at index `i`.
+
+We can encode these properties in the refinement logic as follows.
+
+\begin{code}
+{-@ measure numchars :: Array -> Int -> Int -> Int @-}
+{-@ predicate SpanChar N A O L I =
+      (((numchars (A) (O) ((I-O)+N)) = (1 + (numchars (A) (O) (I-O))))
+    && ((numchars (A) (O) ((I-O)+N)) <= (numchars A O L))
+    && (((I-O)+N) <= L))
+  @-}
+\end{code}
+
+The `numchars` measure takes an array, an offset, and a length
+(e.g. the `arr`, `off`, and `len` fields of a `Text`) and denotes the
+number of characters contained in the `length` slots beginning at
+`offset`. Since we can't compute this in the refinement logic, we
+leave the measure abstract. We can, however, provide LiquidHaskell
+with a few invariants about the behavior of `numchars`, specifically
+that (1) `numchars` always returns a `Nat`, (2) there are no
+characters contained in a empty span, and (3) there are at most as
+many characters as words in a `Text`. We encode these using a special
+`invariant` annotation.
+
+\begin{code}
+{-@ invariant {v:Text | (numchars (tarr v) (toff v) (tlen v)) >= 0}        @-}
+{-@ invariant {v:Text | (numchars (tarr v) (toff v) 0)         = 0}        @-}
+{-@ invariant {v:Text | (numchars (tarr v) (toff v) (tlen v)) <= (tlen v)} @-}
+\end{code}
+
+Finally returning to `unsafeHead`, we can use `unsafeIndexF` to
+strengthen the inferred type for `m`. LiquidHaskell can now prove that
+the second `unsafeIndex` is in fact safe, because it is only demanded
+if `m` is a lead surrogate.
+
+\begin{code}
+{-@ unsafeHead' :: TextNE -> Char @-}
+unsafeHead' :: Text -> Char
+unsafeHead' (Text arr off _len)
+    | m < 0xD800 || m > 0xDBFF = unsafeChr m
+    | otherwise                = chr2 m n
+    where m = unsafeIndexF arr off _len off
+          {-@ LAZYVAR n @-}
+          n = unsafeIndex arr (off+1)
+\end{code}
+
+The `LAZYVAR` annotation is currently required because LiquidHaskell
+doesn't know that `n` will only be demanded in one branch; one can
+imagine a transformation that would push the `where` bindings inward
+to the use-site, which would alleviate this issue.
+
+Before signing off, let's take a look at a slightly more interesting
+function, `take`.
+
+\begin{code}
+{-@ take :: n:Nat -> t:Text -> {v:Text | (Min (tlength v) (tlength t) n)} @-}
+take :: Int -> Text -> Text
+take n t@(Text arr off len)
+    | n <= 0    = empty
+    | n >= len  = t
+    | otherwise = Text arr off (loop 0 0)
+  where
+     loop !i !cnt
+          | i >= len || cnt >= n = i
+          | otherwise            = let d = iter_ t i
+                                   in loop (i+d) (cnt+1)
+\end{code}
+
+`take` gets a `Nat` and a `Text`, and returns a `Text` that contains
+the first `n` characters of `t`. That is, unless `n >= tlength t`, in
+which case it just returns `t`.
+
+`tlength` is a simple wrapper around `numchars`.
+
+\begin{code}
+{-@ measure tlength :: Text -> Int
+    tlength (Text a o l) = (numchars a o l)
+  @-}
+\end{code}
+
+The bulk of the work is done by the
+inner `loop`, which has to track the current index `i` and the number
+of characters we have seen, `cnt`. `loop` uses an auxiliary function
+`iter_` to determine the *width* of the character that starts at `i`,
+bumps `cnt`, and recursively calls itself at `i+d` until it either
+reaches the end of `t` or sees `n` characters, returning the final
+index.
+
+The `iter_` function is quite simple, it just determines whether the
+word at index `i` is a lead surrogate, and returns the appropriate
+span.
+
+\begin{code}
+{-@ predicate SpanCharT N T I =
+      (SpanChar N (tarr T) (toff T) (tlen T) ((toff T)+I))
+  @-}
+
+{-@ iter_ :: t:Text -> i:TValidI t
+          -> {v:Nat | (SpanCharT v t i)}
+  @-}
+iter_ :: Text -> Int -> Int
+iter_ (Text arr off len) i
+    | m < 0xD800 || m > 0xDBFF = 1
+    | otherwise                = 2
+ where m = unsafeIndexF arr off len (off+i)
+\end{code}
+
+Again, we use `unsafeIndexF` to learn more about the structure of `t`
+by observing a small piece of it. It's also worth noting that we've
+encoded all of the domain knowledge we need into a single function,
+which has the benefit of letting us focus our attention on one type
+when we try to ensure that we've encoded it correctly.
+
+Next time, we'll continue our exploration of `text` and see how to
+construct a `Text` while ensuring the absence of out-of-bounds writes.
diff --git a/docs/blog/todo/TextWrite.lhs b/docs/blog/todo/TextWrite.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/TextWrite.lhs
@@ -0,0 +1,335 @@
+---
+layout: post
+title: "Text Write"
+date: 2014-02-23
+comments: true
+external-url:
+author: Eric Seidel
+published: false
+categories: benchmarks, text
+demo: TextWrite.hs
+---
+
+Last time, we showed how to reason about Unicode and a variable-width
+encoding of `Char`s when consuming a `Text` value, today we'll look at
+the same issue from the perspective of *building* a `Text`.
+
+<!-- more -->
+
+<div class="hidden">
+
+\begin{code}
+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types,
+    RecordWildCards, UnboxedTuples, ExistentialQuantification #-}
+{-@ LIQUID "--no-termination" @-}
+module TextWrite where
+
+import Control.Monad.ST.Unsafe (unsafeIOToST)
+import Foreign.C.Types (CSize)
+import GHC.Base hiding (unsafeChr)
+import GHC.ST
+import GHC.Word (Word16(..))
+import Data.Bits hiding (shiftL)
+import Data.Word
+
+import Language.Haskell.Liquid.Prelude
+
+--------------------------------------------------------------------------------
+--- From TextInternal
+--------------------------------------------------------------------------------
+
+{-@ shiftL :: i:Nat -> n:Nat -> {v:Nat | ((n = 1) => (v = (i * 2)))} @-}
+shiftL :: Int -> Int -> Int
+shiftL = undefined -- (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+{-@ measure isUnknown :: Size -> Prop
+    isUnknown (Exact n) = false
+    isUnknown (Max   n) = false
+    isUnknown (Unknown) = true
+  @-}
+{-@ measure getSize :: Size -> Int
+    getSize (Exact n) = n
+    getSize (Max   n) = n
+  @-}
+
+{-@ invariant {v:Size | (getSize v) >= 0} @-}
+
+data Size = Exact {-# UNPACK #-} !Int -- ^ Exact size.
+          | Max   {-# UNPACK #-} !Int -- ^ Upper bound on size.
+          | Unknown                   -- ^ Unknown size.
+            deriving (Eq, Show)
+
+{-@ upperBound :: k:Nat -> s:Size -> {v:Nat | v = ((isUnknown s) ? k : (getSize s))} @-}
+upperBound :: Int -> Size -> Int
+upperBound _ (Exact n) = n
+upperBound _ (Max   n) = n
+upperBound k _         = k
+
+data Step s a = Done
+              | Skip !s
+              | Yield !a !s
+
+data Stream a =
+    forall s. Stream
+    (s -> Step s a)             -- stepper function
+    !s                          -- current state
+    !Size                       -- size hint
+
+{-@ data Array = Array { aBA  :: ByteArray#
+                       , aLen :: Nat 
+                       } 
+  @-}
+
+data Array = Array {
+    aBA  :: ByteArray#
+  , aLen :: !Int
+  }
+
+{-@ measure alen     :: Array -> Int
+    alen (Array a n) = n
+  @-}
+
+{-@ aLen :: a:Array -> {v:Nat | v = (alen a)}  @-}
+
+{-@ type ArrayN  N   = {v:Array | (alen v) = N} @-}
+
+{-@ type AValidI A   = {v:Nat | v     <  (alen A)} @-}
+{-@ type AValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type AValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+{-@ data MArray s = MArray { maBA  :: MutableByteArray# s
+                           , maLen :: Nat } @-}
+
+data MArray s = MArray {
+    maBA  :: MutableByteArray# s
+  , maLen :: !Int
+  }
+
+{-@ measure malen :: MArray s -> Int
+    malen (MArray a n) = n
+  @-}
+
+{-@ maLen :: a:MArray s -> {v:Nat | v = (malen a)}  @-}
+
+{-@ type MArrayN s N = {v:MArray s | (malen v) = N} @-}
+
+{-@ type MAValidI MA = {v:Nat | v <  (malen MA)} @-}
+{-@ type MAValidO MA = {v:Nat | v <= (malen MA)} @-}
+
+{-@ new :: forall s. n:Nat -> ST s (MArrayN s n) @-}
+new          :: forall s. Int -> ST s (MArray s)
+new n
+  | n < 0 || n .&. highBit /= 0 = error $ "new: size overflow"
+  | otherwise = ST $ \s1# ->
+       case newByteArray# len# s1# of
+         (# s2#, marr# #) -> (# s2#, MArray marr# n #)
+  where !(I# len#) = bytesInArray n
+        highBit    = maxBound `xor` (maxBound `shiftR` 1)
+        bytesInArray n = n `shiftL` 1
+
+{-@ unsafeWrite :: ma:MArray s -> MAValidI ma -> Word16 -> ST s () @-}
+unsafeWrite  :: MArray s -> Int -> Word16 -> ST s ()
+unsafeWrite MArray{..} i@(I# i#) (W16# e#)
+  | i < 0 || i >= maLen = liquidError "out of bounds"
+  | otherwise = ST $ \s1# ->
+      case writeWord16Array# maBA i# e# s1# of
+        s2# -> (# s2#, () #)
+
+{-@ copyM :: dest:MArray s 
+          -> didx:MAValidO dest
+          -> src:MArray s 
+          -> sidx:MAValidO src
+          -> {v:Nat | (((didx + v) <= (malen dest))
+                    && ((sidx + v) <= (malen src)))}
+          -> ST s ()
+  @-}
+copyM        :: MArray s               -- ^ Destination
+             -> Int                    -- ^ Destination offset
+             -> MArray s               -- ^ Source
+             -> Int                    -- ^ Source offset
+             -> Int                    -- ^ Count
+             -> ST s ()
+copyM dest didx src sidx count
+    | count <= 0 = return ()
+    | otherwise =
+    liquidAssert (sidx + count <= maLen src) .
+    liquidAssert (didx + count <= maLen dest) .
+    unsafeIOToST $ memcpyM (maBA dest) (fromIntegral didx)
+                           (maBA src) (fromIntegral sidx)
+                           (fromIntegral count)
+
+{-@ memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO () @-}
+memcpyM :: MutableByteArray# s -> CSize -> MutableByteArray# s -> CSize -> CSize -> IO ()
+memcpyM = undefined
+
+{-@ unsafeFreeze :: ma:MArray s -> ST s (ArrayN (malen ma)) @-}
+unsafeFreeze :: MArray s -> ST s Array
+unsafeFreeze MArray{..} = ST $ \s# ->
+                          (# s#, Array (unsafeCoerce# maBA) maLen #)
+
+{-@ unsafeIndex :: a:Array -> AValidI a -> Word16 @-}
+unsafeIndex  :: Array -> Int -> Word16
+unsafeIndex Array{..} i@(I# i#)
+  | i < 0 || i >= aLen = liquidError "out of bounds"
+  | otherwise = case indexWord16Array# aBA i# of
+                  r# -> (W16# r#)
+
+data Text = Text Array Int Int
+{-@ data Text [tlen] = Text (arr :: Array)
+                            (off :: TValidO arr)
+                            (len :: TValidL off arr)
+  @-}
+
+{-@ measure tarr :: Text -> Array
+    tarr (Text a o l) = a
+  @-}
+
+{-@ measure toff :: Text -> Int
+    toff (Text a o l) = o
+  @-}
+
+{-@ measure tlen :: Text -> Int
+    tlen (Text a o l) = l
+  @-}
+
+{-@ type TValidI T   = {v:Nat | v     <  (tlen T)} @-}
+{-@ type TValidO A   = {v:Nat | v     <= (alen A)} @-}
+{-@ type TValidL O A = {v:Nat | (v+O) <= (alen A)} @-}
+
+
+--------------------------------------------------------------------------------
+--- From TextRead
+--------------------------------------------------------------------------------
+
+{-@ measure numchars :: Array -> Int -> Int -> Int @-}
+{-@ measure tlength :: Text -> Int @-}
+{-@ invariant {v:Text | (tlength v) = (numchars (tarr v) (toff v) (tlen v))} @-}
+
+--------------------------------------------------------------------------------
+--- Helpers
+--------------------------------------------------------------------------------
+
+{-@ qualif Ord(v:int, i:int, x:Char)
+        : ((((ord x) <  65536) => (v = i))
+        && (((ord x) >= 65536) => (v = (i + 1))))
+  @-}
+
+\end{code}
+
+</div>
+
+We mentioned previously that `text` uses stream fusion to optimize
+multiple loops over a `Text` into a single loop; as a result many of
+the top-level API functions are simple wrappers around equivalent
+functions over `Stream`s. The creation of `Text` values is then
+largely handled by a single function, `unstream`, which converts a
+`Stream` into a `Text`.
+
+\begin{code}
+unstream :: Stream Char -> Text
+unstream (Stream next0 s0 len) = runST $ do
+  let mlen = upperBound 4 len
+  arr0 <- new mlen
+  let outer arr top = loop
+       where
+        loop !s !i =
+            case next0 s of
+              Done          -> do
+                arr' <- unsafeFreeze arr
+                return $! Text arr' 0 i
+              Skip s'       -> loop s' i
+              Yield x s'
+                | j >= top  -> do
+                  let top' = (top + 1) `shiftL` 1
+                  arr' <- new top'
+                  copyM arr' 0 arr 0 top
+                  outer arr' top' s i
+                | otherwise -> do
+                  d <- writeChar arr i x
+                  loop s' (i+d)
+                where j | ord x < 0x10000 = i
+                        | otherwise       = i + 1
+  outer arr0 mlen s0 0
+\end{code}
+
+Since we're focusing on memory safety here we won't go into detail
+about how `Stream`s work. Let's instead jump right into the inner
+`loop` and look at the `Yield` case. Here we need to write a char `x`
+into `arr`, so we compute the maximal index `j` to which we will
+write -- i.e. if `x >= U+10000` then `j = i + 1` -- and determine
+whether we can safely write at `j`. If the write is unsafe we have to
+allocate a larger array before continuing, otherwise we write `x` and
+increment `i` by `x`s width.
+
+Since `writeChar` has to handle writing *any* Unicode value, we need
+to assure it that there will always be room to write `x` into `arr`,
+regardless of `x`s width. Indeed, this is expressed in the type we
+give to `writeChar`.
+
+\begin{code}
+{-@ writeChar :: ma:MArray s -> i:Nat -> {v:Char | (Room v ma i)}
+              -> ST s {v:Nat | (RoomN v ma i)}
+  @-}
+\end{code}
+
+The predicate aliases `Room` and `RoomN` express that a character can
+fit in the array at index `i` and that there are at least `n` slots
+available starting at `i` respectively.
+
+\begin{code}
+{-@ predicate Room C MA I = (((One C) => (RoomN 1 MA I))
+                          && ((Two C) => (RoomN 2 MA I)))
+  @-}
+{-@ predicate RoomN N MA I = (I+N <= (malen MA)) @-}
+\end{code}
+
+The `One` and `Two` predicates express that a character will be
+encoded in one or two 16-bit words, by reasoning about its ordinal
+value.
+
+\begin{code}
+{-@ predicate One C = ((ord C) <  65536) @-}
+{-@ predicate Two C = ((ord C) >= 65536) @-}
+\end{code}
+
+As with `numchars`, we leave `ord` abstract, but inform LiquidHaskell
+that the `ord` *function* does in fact return the ordinal value of the
+character.
+
+\begin{code}
+{-@ measure ord :: Char -> Int @-}
+{-@ ord :: c:Char -> {v:Int | v = (ord c)} @-}
+\end{code}
+
+Since `writeChar` assumes that it will never be called unless there is room to
+write `c`, it is safe to just split `c` into 16-bit words and write them into
+the array.
+
+\begin{code}
+writeChar :: MArray s -> Int -> Char -> ST s Int
+writeChar marr i c
+    | n < 0x10000 = do
+        unsafeWrite marr i (fromIntegral n)
+        return 1
+    | otherwise = do
+        unsafeWrite marr i lo
+        unsafeWrite marr (i+1) hi
+        return 2
+    where n = ord c
+          m = n - 0x10000
+          lo = fromIntegral $ (m `shiftR` 10) + 0xD800
+          hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
+\end{code}
+
+In typical design-by-contract style, we're putting the burden of proof to
+establish safety on `writeChar`s caller. Now, scroll back up to
+`unstream` and mouse over `j` to see its inferred type.
+\begin{code} You should see something like
+{v:Int | ((ord x >= 65536) => (v == i+1))
+      && ((ord x <  65536) => (v == i))}
+\end{code}
+which, combined with the case-split on `j >= top`, provides the proof that
+writing `x` will be safe!
+
+Stay tuned, next time we'll look at another example of building a `Text` where
+LiquidHaskell fails to infer this crucial refinement...
diff --git a/docs/blog/todo/basic_termination.lhs b/docs/blog/todo/basic_termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/basic_termination.lhs
@@ -0,0 +1,192 @@
+---
+layout: post
+title: "Termination Checking"
+date: 2013-11-18 16:12
+comments: true
+external-url:
+categories: termination
+author: Niki Vazou
+published: false 
+demo: TerminationBasic.hs
+---
+
+As explained in the [last](LINK) [two](LINK) posts, we need a termination
+checker to ensure that LiquidHaskell is not tricked by divergent, lazy
+computations into telling lies. Well, proving termination is not easy, but
+happily, it turns out that with very little retrofitting, we can use 
+refinements to prove termination.
+
+In this post, lets see how LiquidHaskell proves termination on simple 
+recursive functions, and then later, we'll see how to look at fancier 
+cases.
+
+<!-- more -->
+
+\begin{code}
+module Termination where
+
+import Prelude hiding (sum, (!!))
+import Data.List      (lookup)
+\end{code}
+
+Termination Check with Refinement Types
+---------------------------------------
+
+Consider a `Vec`tor that maps `Int`egers to `Val`ues:
+
+\begin{code}
+type Val   = Int
+data Vec   = V [(Int, Val)]
+
+(!!)       :: Vec -> Int -> Val
+(V a) !! i = case i `lookup` a of {Just v -> v; _ -> 0}
+\end{code}
+
+Let `sum a i` add the `i` first elements of the vector `a`:
+
+\begin{code}
+sum     :: Vec -> Int -> Val
+sum a 0 = 0
+sum a i = (a !! (i-1)) + sum a (i-1)
+\end{code}
+
+Does `sum` terminate?
+We observe that if `i` is not `0` then `sum i` will call `sum (i-1)`, otherwise
+it will return.
+This reasoning suffices to convince ourselves that `sum i` terminates for every
+natural number `i`.
+Formally, we shown that `sum` terminates because a *well-founded metric* (i.e., the
+natural number `i`) is decreasing at each iteration.
+Thus, to ensure termination it suffices to restrict `i` on Natural numbers,
+which we can do with a liquid-type signature.
+\begin{code}
+{-@ sum :: Vec -> Nat -> Val @-}
+\end{code}
+
+LiquidHaskell will apply the same reasoning to prove `sum`
+terminates:
+Conventionally, to typecheck `sum` we would check the body assuming an
+environment
+
+`a:Vec`, `i:Nat`, `sum:Vec -> Nat -> Val`
+
+Instead, we *weaken* the environment to 
+
+`a:Vec`, `i:Nat`, `sum:Vec -> {v:Nat| v < i} -> Val`
+
+Now, the type of `sum` stipulates that it *only* be recursively called with
+`Nat` (so well-founded) values that are *strictly less than* the current parameter `i`. 
+Since its body typechecks in this environment, `sum` terminates for
+every `i` on `Nat`s.
+
+Choosing the correct argument
+-----------------------------
+
+We saw that liquidHaskell can happily check that a Natural number is decreasing
+at each iteration; but it uses a na&#239;ve heuristic to choose which one. 
+For this post we can assume that it always chooses *the first* Integer. 
+
+So, a tail-recursive implementation of `sum`:
+\begin{code}
+{-@ sum' :: Vec -> Val -> Nat -> Val @-}
+sum' :: Vec -> Val -> Int -> Val
+sum' a acc 0 = acc + a!!0 
+sum' a acc i = sum' a (acc + a!!i) (i-1)
+\end{code}
+
+will fail, as liquidHaskell wants to prove that the `acc`umulator is the `Nat`ural
+number that
+decreases at each iteration.
+
+\begin{code}The remedy is simple. We can direct liquidHaskell to the correct argument `i` using a `Decrease` annotation: 
+{-@ Decrease sum' 3 @-}
+\end{code}
+which directs liquidHaskell to check whether the *third*
+argument (i.e., `i`) is decreasing.
+With this hint, liquidHaskell will happily verify that `sum'` is indeed a
+terminating function.
+
+
+Lexicographic Termination
+-------------------------
+
+Lets complicate the things a little bit.
+To do so, lets compute the `sum` of a 2D `Vec`tor:
+
+\begin{code}
+data Vec2D    = V2D [((Int, Int), Val)]
+
+(!!!)         :: Vec2D -> (Int,Int) -> Val
+(V2D a) !!! i = case i `lookup` a of {Just v -> v; _ -> 0}
+\end{code}
+
+Now we write a `sum2D a n m` function that computes the sum of the first 
+`(n+1)(m+1)` elements of `a`
+
+\begin{code}
+{-@ sum2D :: Vec2D -> Nat -> Nat -> Val @-}
+sum2D :: Vec2D -> Int -> Int -> Val
+sum2D a n m = go n m
+  where 
+       {-@ Decrease go 1 2 @-}
+        go 0 0             = 0
+        go i j | j == 0    =  a!!!(i, 0) + go (i-1) m
+               | otherwise =  a!!!(i, j) + go i (j-1)
+\end{code}
+
+Here there is no decreasing argument, 
+if `j>0`, `j` decreases (line `139`), otherwise `i` decreases (line `138`).
+Though, liquidHaskell succeed in verifying that `sum2D` terminates and the reason
+is our `Decrease go 1 2` annotation.
+This annotation informs the tool that the decreasing measure is the
+*lexicographically ordered* pair `[i,j]`. 
+LiquidHaskell will verify that this pair is indeed decreasing: at each
+iteration either `i` decreases (line `138`) or `i` remains the same and `j`
+decreases (line `139`).
+
+\begin{code}An alternative annotation to express the above decreasing measure is:
+       {-@ go :: i:Nat -> j:Nat -> Val / [i, j] @-}
+\end{code}
+where after the type signature for `go` we write the list of lexicographic
+decreasing *expressions*.
+This mechanism, as we shall see, allows us to prove termination in functions
+where the decreasing measure in a *function* of the arguments.
+
+Decreasing expressions
+----------------------
+Back to our `1D` Vector, 
+we now define a function `sumFromTo a lo hi` that sums the elements form `a!!lo`
+to `a!!hi`:
+
+\begin{code}
+{-@ sumFromTo :: Vec -> lo:Nat -> hi:{v:Nat|v>=lo} -> Val @-}
+sumFromTo :: Vec -> Int -> Int ->  Val
+sumFromTo a lo hi = go lo hi
+  where 
+       {-@ go :: lo:Nat -> hi:{v:Nat|v>=lo} -> Val / [hi-lo] @-}
+        go lo hi | lo == hi  =  a!!lo
+                 | otherwise =  a!!lo + go (lo+1) hi
+\end{code}
+
+No argument is decreasing in this function, 
+but still it does terminate, as at each iteration `lo` is increased and
+execution will terminate when `lo` reaches `hi`.
+Here the decreasing measure is the expression `hi-lo`.
+LiquidHaskell has no way to generate such a measure, but,
+if the user generates it, i.e., by annotating `go`'s signature,
+liquidHaskell will happily check that `lo-hi` is indeed a well-founded measure (as it is
+a natural number) that decreases at each iteration.
+
+
+Powered with decreasing expressions and the `Decrease` hint,
+we can prove termination on a great number of functions 
+ranging from 
+ones defined on recursive data structures
+to mutual recursive ones. 
+We shall soon see how to prove termination on more complicated functions, why
+is termination analysis required by liquidHaskell and when is it safe to
+deactivate it.
+
+\begin{code}Until then, bear in mind that you can disable termination checking using the `no-termination` flag:
+{-@ LIQUID "--no-termination" @-}
+\end{code}
diff --git a/docs/blog/todo/binary-search-trees.lhs b/docs/blog/todo/binary-search-trees.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/binary-search-trees.lhs
@@ -0,0 +1,167 @@
+---
+layout: post
+title: "Binary Search Trees"
+date: 2013-02-15 16:12
+comments: true
+external-url:
+categories: abstract-refinements
+author: Niki Vazou
+published: false
+---
+
+In this example, we show how we can use multi-parameter abstract refinements 
+to encode ordering invarants on tree structures.
+
+\begin{code}
+module Map where
+\end{code}
+
+Take for example the following refined type used to encode functional maps (from Data.Map):
+
+\begin{code}
+{-@ 
+  data Map k a <l :: root:k -> k -> Prop, r :: root:k -> k -> Prop>
+      = Tip 
+      | Bin (sz    :: Size) 
+            (key   :: k) 
+            (value :: a) 
+            (left  :: Map <l, r> (k <l key>) a) 
+            (right :: Map <l, r> (k <r key>) a) 
+  @-}
+
+data Map k a = Tip
+             | Bin Size k a (Map k a) (Map k a)
+
+type Size    = Int
+\end{code}
+
+The abstract refinements `l` and `r` relate each `key` of the tree with `all` the keys in the `left` and `right` subtrees of `key`, as those keys are respectively of type `k <l key>` and `k <r key>`.
+
+Thus, if we instantiate the refinements with the following predicates
+
+\begin{code}
+{-@ type BST k a     = Map <\r -> {v:k | v < r }, \r -> {v:k | v > r }> k a @-}
+{-@ type MinHeap k a = Map <\r -> {v:k | r <= v}, \r -> {v:k | r <= v}> k a @-}
+{-@ type MaxHeap k a = Map <\r -> {v:k | r >= v}, \r -> {v:k | r >= v}> k a @-}
+\end{code}
+
+then `BST k v`, `MinHeap k v` and `MaxHeap k v` denote exactly binary-search-ordered, min-heap-ordered, and max-heap-ordered trees (with keys and values of types `k` and `v`).  
+
+We can use the above types to automatically verify ordering properties of complex libraries.
+
+For example, we cab use `BST` to prove that `Data.Map`'s `insert` and `delete` functions return a binary search tree:
+
+\begin{code}
+{-@ insert :: Ord k => k:k -> a:a -> t:BST k a -> BST k a @-}
+insert :: Ord k => k -> a -> Map k a -> Map k a
+insert kx x t
+  = case t of 
+     Tip -> singleton kx x
+     Bin sz ky y l r
+         -> case compare kx ky of
+              LT -> balance ky y (insert kx x l) r
+              GT -> balance ky y l (insert kx x r)
+              EQ -> Bin sz kx x l r
+
+{-@ delete :: (Ord k) => k:k -> t:BST k a -> BST k a @-}
+delete :: Ord k => k -> Map k a -> Map k a
+delete k t 
+  = case t of 
+      Tip -> Tip
+      Bin _ kx x l r
+          -> case compare k kx of 
+               LT -> balance kx x (delete k l) r
+               GT -> balance kx x l (delete k r)
+               EQ -> glue kx l r
+\end{code}
+
+
+Below are the functions used by `insert` and `delete`:
+
+\begin{code}
+singleton :: k -> a -> Map k a
+singleton k x
+  = Bin 1 k x Tip Tip
+
+
+glue :: k -> Map k a -> Map k a -> Map k a
+glue k Tip r = r
+glue k l Tip = l
+glue k l r
+  | size l > size r = let (km1, vm, lm) = deleteFindMax l in balance km1 vm lm r
+  | otherwise       = let (km2, vm, rm) = deleteFindMin r in balance km2 vm l rm
+
+deleteFindMax t 
+  = case t of
+      Bin _ k x l Tip -> (k, x, l)
+      Bin _ k x l r -> let (km3, vm, rm) = deleteFindMax r in 
+                       (km3, vm, (balance k x l rm))
+      Tip           -> (error ms, error ms, Tip)
+  where ms = "Map.deleteFindMax : can not return the maximal element of an empty Map"   
+
+
+deleteFindMin t 
+  = case t of
+      Bin _ k x Tip r -> (k, x, r)
+      Bin _ k x l r -> let (km4, vm, lm) = deleteFindMin l in 
+                       (km4, vm, (balance k x lm r))
+      Tip             -> (error ms, error ms, Tip)
+  where ms = "Map.deleteFindMin : can not return the maximal element of an empty Map"   
+
+
+-------------------------------------------------------------------------------
+--------------------------------- BALANCE -------------------------------------
+-------------------------------------------------------------------------------
+
+delta, ratio :: Int
+delta = 5
+ratio = 2
+
+balance :: k -> a -> Map k a -> Map k a -> Map k a 
+balance k x l r 
+  | sizeL + sizeR <= 1   = Bin sizeX k x l r
+  | sizeR >= delta*sizeL = rotateL k x l r
+  | sizeL >= delta*sizeR = rotateR k x l r
+  | otherwise            = Bin sizeX k x l r
+  where sizeL = size l
+        sizeR = size r
+        sizeX = sizeL + sizeR + 1
+
+-- rotate
+rotateL :: a -> b -> Map a b -> Map a b -> Map a b
+rotateL k x l r@(Bin _ _ _ ly ry) 
+  | size ly < ratio*size ry  = singleL k x l r
+  | otherwise                = doubleL k x l r
+rotateL _ _ _ Tip = error "rotateL Tip"
+
+rotateR :: a -> b -> Map a b -> Map a b -> Map a b
+rotateR k x l@(Bin _ _ _ ly ry) r
+  | size ry < ratio*size ly  = singleR k x l r
+  | otherwise                = doubleR k x l r
+rotateR _ _ _ Tip = error "rotateR Tip"
+
+-- basic rotations
+singleL, singleR :: a -> b -> Map a b -> Map a b -> Map a b
+singleL k1 x1 t1 (Bin _ k2 x2 t2 t3) = bin k2 x2 (bin k1 x1 t1 t2) t3
+singleL _  _  _ Tip = error "sinlgeL Tip"
+singleR k1 x1 (Bin _ k2 x2 t1 t2) t3 = Bin 0 k2 x2 t1 (Bin 0 k1 x1 t2 t3)
+singleR _  _  _ Tip = error "sinlgeR Tip"
+
+doubleL, doubleR :: a -> b -> Map a b -> Map a b -> Map a b
+doubleL k1 x1 t1 (Bin _ k2 x2 (Bin _ k3 x3 t2 t3) t4)
+ =bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4)
+doubleL _ _ _ _ = error "doubleL" 
+doubleR k1 x1 (Bin _ k2 x2 t1 (Bin _ k3 x3 t2 t3)) t4 
+  = bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4)
+doubleR _ _ _ _ = error "doubleR" 
+
+bin :: k -> a -> Map k a -> Map k a -> Map k a
+bin k x l r 
+  = Bin (size l + size r + 1) k x l r
+
+size :: Map k a -> Int
+size t 
+  = case t of 
+      Tip            -> 0
+      Bin sz _ _ _ _ -> sz
+\end{code}
diff --git a/docs/blog/todo/encoding-induction.lhs b/docs/blog/todo/encoding-induction.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/encoding-induction.lhs
@@ -0,0 +1,122 @@
+
+---
+layout: post
+title: "Encoding Induction with Abstract Refinements"
+date: 2013-02-20 16:12
+comments: true
+external-url:
+categories: abstract-refinements 
+author: Niki Vazou
+published: false
+---
+
+In this example, we explain how abstract refinements allow us to formalize
+some kinds of structural induction within the type system. 
+
+\begin{code}
+module Inductive where
+\end{code}
+
+Measures
+--------
+First, lets define an inductive data type `Vec`
+
+\begin{code}
+data Vec a = Nil | Cons a (Vec a)
+\end{code}
+
+And let us formalize a notion of _length_ for lists within the refinement logic. 
+
+To do so, we define a special `llen` measure by structural induction
+
+\begin{code}
+{-@ measure llen     :: forall a. Vec a -> Int 
+    llen (Nil)       = 0 
+    llen (Cons x xs) = 1 + llen(xs)
+  @-}
+\end{code}
+
+
+Note that the symbol `llen` is encoded as an _uninterpreted_ function in the refinement logic, and is, except for the congruence axiom, opaque to the SMT solver. The measures are guaranteed, by construction, to terminate, and so we can soundly use them as uninterpreted functions in the refinement logic. Notice also, that we can define _multiple_ measures for a type; in this case we simply conjoin the refinements from each measure when refining each data constructor.
+
+As a warmup, lets check that a _real_ length function indeed computes the length of the list:
+
+\begin{code}
+{-@ sizeOf :: xs:Vec a -> {v: Int | v = llen(xs)} @-}
+sizeOf             :: Vec a -> Int
+sizeOf Nil         = 0
+sizeOf (Cons _ xs) = 1 + sizeOf xs
+\end{code}
+
+
+
+With these strengthened constructor types, we can verify, for example, that `myappend` produces a list whose length is the sum of the input lists'
+lengths:
+
+\begin{code}
+{-@ myappend :: l: (Vec a) -> m: (Vec a) -> {v: Vec a | llen(v)=llen(l)+llen(m)} @-}
+myappend Nil         zs = zs
+myappend (Cons y ys) zs = Cons y (myappend ys zs)
+\end{code}
+
+
+\begin{code}However, consider an alternate definition of `myappend` that uses `foldr`
+myappend' ys zs = foldr (:) zs ys 
+\end{code}
+
+where `foldr :: (a -> b -> b) -> b -> [a] -> b`.
+It is unclear how to give `foldr` a (first-order) refinement type that captures the rather complex fact that the fold-function is ''applied'' all over the list argument, or, that it is a catamorphism. Hence, hitherto, it has not been possible to verify the second definition of `append`.
+
+
+Typing Folds
+------------
+
+Abstract refinements allow us to solve this problem with a very expressive type for _foldr_ whilst remaining firmly within the boundaries of SMT-based decidability. We write a slightly modified fold:
+
+\begin{code}
+{-@ efoldr :: forall a b <p :: x0:Vec a -> x1:b -> Prop>. 
+                op:(xs:Vec a -> x:a -> b:b <p xs> -> 
+                  exists [xxs : {v: Vec a | v = (Inductive.Cons x xs)}].
+                     b <p xxs>) 
+              -> vs:(exists [zz: {v: Vec a | v = Inductive.Nil}]. b <p zz>) 
+              -> ys: Vec a
+              -> b <p ys>
+  @-}
+efoldr :: (Vec a -> a -> b -> b) -> b -> Vec a -> b
+efoldr op b Nil         = b
+efoldr op b (Cons x xs) = op xs x (efoldr op b xs) 
+\end{code}
+
+The trick is simply to quantify over the relationship `p` that `efoldr` establishes between the input list `xs` and the output `b` value. This is formalized by the type signature, which encodes an induction principle for lists: 
+the base value `b` must (1) satisfy the relation with the empty list, and the function `op` must take (2) a value that satisfies the relationship with the tail `xs` (we have added the `xs` as an extra "ghost" parameter to `op`), (3) a head value `x`, and return (4) a new folded value that satisfies the relationship with `x:xs`.
+If all the above are met, then the value returned by `efoldr` satisfies the relation with the input list `ys`.
+
+This scheme is not novel in itself --- what is new is the encoding, via uninterpreted predicate symbols, in an SMT-decidable refinement type system.
+
+Using Folds
+-----------
+
+Finally, we can use the expressive type for the above `foldr` to verify various inductive properties of client functions:
+
+\begin{code}
+{-@ size :: xs:Vec a -> {v: Int | v = llen(xs)} @-}
+size :: Vec a -> Int
+size = efoldr (\_ _ n -> suc n) 0
+
+{-@ suc :: x:Int -> {v: Int | v = x + 1} @-}
+suc :: Int -> Int
+suc x = x + 1 
+
+{-@ 
+   myappend'  :: xs: Vec a -> ys: Vec a -> {v: Vec a | llen(v) = llen(xs) + llen(ys)} 
+  @-} 
+myappend' xs ys = efoldr (\_ z zs -> Cons z zs) ys xs 
+\end{code}
+
+
+\begin{code}The verification proceeds by just (automatically) instantiating the refinement parameter `p` of `efoldr` with the concrete refinements, via Liquid typing:
+
+{\xs v -> v = llen(xs)}                   -- for size
+{\xs v -> llen(v) = llen(xs) + llen(zs)}  -- for myappend'
+\end{code}
+
diff --git a/docs/blog/todo/index-dependent-maps.hs b/docs/blog/todo/index-dependent-maps.hs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/index-dependent-maps.hs
@@ -0,0 +1,217 @@
+-- ---
+-- layout: post
+-- title: "Index-Dependent Maps"
+-- date: 2013-01-20 16:12
+-- comments: true
+-- external-url:
+-- categories: abstract-refinement, basic
+-- author: Niki Vazou
+-- published: false
+-- ---
+
+-- In this example, we illustrate how abstract invariants allow us to specify
+-- and verify index-dependent invariants of key-value maps.  To this end, we
+-- develop a small library of _extensible vectors_ encoded, for purposes of
+-- illustration, as functions from `Int` to some generic range `a`.
+
+
+module LiquidArray where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume)
+
+
+-- \begin{code}We specify vectors as
+-- type Vec a <dom :: Int -> Prop, rng :: Int -> a -> Prop>
+--   = (i:Int <dom> -> a<rng i>)
+-- \end{code}
+
+
+type Vec a = Int -> a
+
+
+-- Here, we are parametrizing the definition of the type `Vec` with _two_ abstract refinements, `dom` and `rng`, which respectively describe the _domain_ and _range_ of the vector.
+-- That is, `dom` describes the set of _valid_ indices, and `rng` specifies an invariant relating each `Int` index with the value stored at that index.
+
+-- Creating Vectors
+-- ----------------
+
+-- We can use the following basic functions to create vectors:
+
+
+{- empty :: forall <rng :: Int -> a -> Prop>.
+              i:{v: Int | 0 = 1} ->  a<rng> -}
+
+{-@ empty :: i: {v: Int | 0 = 1} -> a @-}
+empty :: Vec a
+empty = \_ -> (error "Empty Vec")
+
+{-@ create :: x:a -> (i:Int -> {v:a | v = x}) @-}
+create :: a -> Vec a
+create x = (\_ -> x)
+
+
+-- The signature for `empty` states that its domain is empty (ie is the set of indices satisfying the predicate `False`), and that the range satisfies _any_ invariant. The signature for `create`, instead, defines a _constant_ vector that maps every index to the constant `x`.
+
+-- Accessing Vectors
+-- -----------------
+
+-- We can write the following `get` function for reading the contents of a vector at a given index:
+
+
+{-@ get :: forall a <d :: x0:Int -> Prop, r :: x0: Int -> x1:a -> Prop>.
+             i: Int<d> ->
+             a: (j: Int<d> -> a<r j>) ->
+             a<r i>
+  @-}
+get :: Int -> Vec a -> a
+get i a = a i
+
+
+-- The signature states that for any domain `d` and range `r`, if the index `i` is a valid index, ie is of type, `Int<d>` then the returned value is an `a` that additionally satisfies the range refinement at the index `i`.
+
+-- The type for `set`, which _updates_ the vector at a given index, is even more interesting, as it allows us to _extend_ the domain of the vector:
+
+
+{-@ set :: forall a <r :: x0: Int -> x1: a -> Prop, d :: x0: Int -> Prop>.
+      i: Int<d> ->
+      x: a<r i> ->
+      a: (j: {v: Int<d> | v != i} -> a<r j>) ->
+      (k : Int<d> -> a<r k>)
+  @-}
+set :: Int -> a -> Vec a -> Vec a
+set i x a = \k -> if k == i then x else a k
+
+
+-- The signature for `set` requires that (a) the input vector is defined everywhere at `d` _except_ the index `i`, and (b) the value supplied must be of type `a<r i>`, ie satisfy the range relation at the index `i` at which the vector is being updated.
+-- The signature ensures that the output vector is defined at `d` and each value satisfies the index-dependent range refinement `r`.
+
+-- Note that it is legal to call `get` with a vector that is _also_ defined at the index `i` since, by contravariance, such a vector is a subtype of that required by (a).
+
+
+-- Initializing Vectors
+-- --------------------
+
+-- Next, we can write the following function, `init`, that ''loops'' over a vector, to `set` each index to a value given by some function.
+
+
+{-@ initialize :: forall a <r :: x0: Int -> x1: a -> Prop>.
+      f: (z: Int -> a<r z>) ->
+      i: {v: Int | v >= 0} ->
+      n: Int ->
+      a: (j: {v: Int | (0 <= v && v < i)} -> a<r j>) ->
+      (k: {v: Int | (0 <= v && v < n)} -> a<r k>) @-}
+initialize :: (Int -> a) -> Int -> Int -> Vec a -> Vec a
+initialize f i n a
+  | i >= n    = a
+  | otherwise = initialize f (i + 1) n (set i (f i) a)
+
+
+-- The signature requires that (a) the higher-order function `f` produces values that satisfy the range refinement `r`, and (b) the vector is initialized from `0` to `i`.
+-- The function ensures that the output vector is initialized from `0`
+-- through `n`.
+
+-- We can thus verify that
+
+
+{-@ idVec :: n:Int -> (k: {v: Int | (0 <= v && v < n)} -> {v: Int | v = k}) @-}
+idVec :: Int -> (Vec Int)
+idVec n = initialize (\i -> i) 0 n empty
+
+
+-- ie `idVec` returns an vector of size `n` where each key is mapped to itself. Thus, abstract refinement types allow us to verify low-level idioms such as the incremental initialization of vectors, which have previously required special analyses.
+
+-- Null-Terminated Strings
+-- -----------------------
+
+-- We can also use abstract refinements to verify code which manipulates C-style null-terminated strings, where each character is represented as an `Int` and the termination character `\0`, and only that, is represented as `0`.
+
+-- \begin{code}Formally, a null-terminated string, represented by `Int`s, of size `n` has the type
+-- type NullTerm n
+--      = Vec <{\v -> 0<=v<n}, {\i v -> i=n-1 => v=0}> Int
+-- \end{code}
+
+-- The above type describes a length-`n` vector of characters whose last element must be a null character, signalling the end of the string.
+
+-- We can use this type in the specification of a function, `upperCase`, which iterates through the characters of a string, uppercasing each one until it encounters the null terminator:
+
+
+ucs :: Int -> Int -> Vec Int -> Vec Int
+ucs n i s =
+  case get i s of
+  0 -> s
+  c -> ucs n (i + 1) (set i (c + 32) s)
+
+{-@ upperCaseString ::
+      n: {v: Int | v > 0} ->
+      s: (j: {v : Int | (0 <= v && v < n)} ->
+          {v: Int | (j = n - 1 => v = 0)}) ->
+      (j: {v : Int | (0 <= v && v < n)} ->
+       {v: Int | (j = n - 1 => v = 0)})
+@-}
+upperCaseString :: Int -> Vec Int -> Vec Int
+upperCaseString n s = ucs n 0 s
+
+
+
+-- Note that the length parameter `n` is provided solely as a ''witness'' for the length of the string `s`, which allows us to use the length of `s` in the type of `upperCaseString`; `n` is not used in the computation.
+
+-- In order to establish that each call to `get` accesses string `s` within its bounds, our type system must establish that, at each call to the inner function `ucs`, `i` satisfies the type `{v: Int | 0 <= v && v < n}`.
+
+-- This invariant is established as follows:
+
+-- First, the invariant trivially holds on the first call to `ucs`, as
+-- `n` is positive and `i` is `0`.
+-- Second, we assume that `i` satisfies the type `{v: Int | 0 <= v && v < n}`, and, further, we know from the types of `s` and `get` that `c` has the type `{v: Int | i = n - 1 => c = 0}`.
+-- Thus, if `c` is non-null, then `i` cannot be equal to `n - 1`.
+-- This allows us to strengthen our type for `i` in the else branch to `{v: Int | 0 <= v && v < n - 1}` and thus to conclude that the value `i + 1` recursively passed as the `i` parameter to `ucs` satisfies the type `{v: Int | 0 <= v && v < n}`, establishing the inductive invariant and thus the safety of the `upperCaseString` function.
+
+
+
+-- Memoization
+-- -----------
+
+-- Next, let us illustrate how the same expressive signatures allow us to verify memoizing functions. We can specify to the SMT solver the definition of the Fibonacci function via an uninterpreted function `fib` and an axiom:
+
+
+{-@ measure fib :: Int -> Int @-}
+
+{-@ axiom_fib :: i:Int -> {v: Bool | (Prop(v) <=>
+                            (fib(i) = ((i <= 1) ? 1 : ((fib(i-1)) + (fib(i-2))))))}
+  @-}
+axiom_fib :: Int -> Bool
+axiom_fib i = undefined
+
+
+-- Next, we define a type alias `FibV` for the vector whose values are either `0` (ie undefined), or equal to the Fibonacci number of the corresponding index.
+
+
+{-@ type FibV = j:Int -> {v:Int| ((v != 0) => (v = fib(j)))} @-}
+
+
+-- Finally, we can use the above alias to verify `fastFib`, an implementation of the Fibonacci function, which uses an vector memoize intermediate results
+
+
+{-@ fastFib :: x:Int -> {v:Int | v = fib(x)} @-}
+fastFib     :: Int -> Int
+fastFib n   = snd $ fibMemo (\_ -> 0) n
+
+{-@ fibMemo :: FibV -> i:Int -> (FibV, {v: Int | v = fib(i)}) @-}
+fibMemo t i
+  | i <= 1
+  = (t, liquidAssume (axiom_fib i) (1 :: Int))
+
+  | otherwise
+  = case get i t of
+      0 -> let (t1, n1) = fibMemo t  (i-1)
+               (t2, n2) = fibMemo t1 (i-2)
+               n        = liquidAssume (axiom_fib i) (n1 + n2)
+           in  (set i n t2,  n)
+      n -> (t, n)
+
+
+-- Thus, abstract refinements allow us to define key-value maps with index-dependent refinements for the domain and range.
+-- Quantification over the domain and range refinements allows us to define generic access operations (eg. `get`, `set`, `create`, `empty`) whose types enable us establish a variety of precise invariants.
+
+
+
+
diff --git a/docs/blog/todo/index-dependent-maps.lhs b/docs/blog/todo/index-dependent-maps.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/index-dependent-maps.lhs
@@ -0,0 +1,217 @@
+---
+layout: post
+title: "Index-Dependent Maps"
+date: 2013-01-20 16:12
+comments: true
+external-url:
+categories: abstract-refinement, basic
+author: Niki Vazou
+published: false
+---
+
+In this example, we illustrate how abstract invariants allow us to specify
+and verify index-dependent invariants of key-value maps.  To this end, we
+develop a small library of _extensible vectors_ encoded, for purposes of
+illustration, as functions from `Int` to some generic range `a`. 
+
+\begin{code}
+module LiquidArray where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume)
+\end{code}
+
+\begin{code}We specify vectors as 
+type Vec a <dom :: Int -> Prop, rng :: Int -> a -> Prop>
+  = (i:Int <dom> -> a<rng i>)
+\end{code}
+
+\begin{code}
+type Vec a = Int -> a
+\end{code}
+
+Here, we are parametrizing the definition of the type `Vec` with _two_ abstract refinements, `dom` and `rng`, which respectively describe the _domain_ and _range_ of the vector.
+That is, `dom` describes the set of _valid_ indices, and `rng` specifies an invariant relating each `Int` index with the value stored at that index.
+
+Creating Vectors
+----------------
+
+We can use the following basic functions to create vectors:
+
+\begin{code}
+{- empty :: forall <rng :: Int -> a -> Prop>. 
+              i:{v: Int | 0 = 1} ->  a<rng> -}
+
+{-@ empty :: i: {v: Int | 0 = 1} -> a @-}
+empty :: Vec a
+empty = \_ -> (error "Empty Vec")
+
+{-@ create :: x:a -> (i:Int -> {v:a | v = x}) @-}
+create :: a -> Vec a
+create x = (\_ -> x)
+\end{code}
+
+The signature for `empty` states that its domain is empty (ie is the set of indices satisfying the predicate `False`), and that the range satisfies _any_ invariant. The signature for `create`, instead, defines a _constant_ vector that maps every index to the constant `x`.
+
+Accessing Vectors
+-----------------
+
+We can write the following `get` function for reading the contents of a vector at a given index:
+
+\begin{code}
+{-@ get :: forall a <d :: x0:Int -> Prop, r :: x0: Int -> x1:a -> Prop>.
+             i: Int<d> ->
+             a: (j: Int<d> -> a<r j>) ->
+             a<r i> 
+  @-}
+get :: Int -> Vec a -> a
+get i a = a i
+\end{code}
+
+The signature states that for any domain `d` and range `r`, if the index `i` is a valid index, ie is of type, `Int<d>` then the returned value is an `a` that additionally satisfies the range refinement at the index `i`.
+
+The type for `set`, which _updates_ the vector at a given index, is even more interesting, as it allows us to _extend_ the domain of the vector:
+
+\begin{code}
+{-@ set :: forall a <r :: x0: Int -> x1: a -> Prop, d :: x0: Int -> Prop>.
+      i: Int<d> ->
+      x: a<r i> ->
+      a: (j: {v: Int<d> | v != i} -> a<r j>) ->
+      (k : Int<d> -> a<r k>)
+  @-}
+set :: Int -> a -> Vec a -> Vec a
+set i x a = \k -> if k == i then x else a k
+\end{code}
+
+The signature for `set` requires that (a) the input vector is defined everywhere at `d` _except_ the index `i`, and (b) the value supplied must be of type `a<r i>`, ie satisfy the range relation at the index `i` at which the vector is being updated.
+The signature ensures that the output vector is defined at `d` and each value satisfies the index-dependent range refinement `r`.
+
+Note that it is legal to call `get` with a vector that is _also_ defined at the index `i` since, by contravariance, such a vector is a subtype of that required by (a).
+
+
+Initializing Vectors
+--------------------
+
+Next, we can write the following function, `init`, that ''loops'' over a vector, to `set` each index to a value given by some function.
+
+\begin{code}
+{-@ initialize :: forall a <r :: x0: Int -> x1: a -> Prop>.
+      f: (z: Int -> a<r z>) ->
+      i: {v: Int | v >= 0} ->
+      n: Int ->
+      a: (j: {v: Int | (0 <= v && v < i)} -> a<r j>) ->
+      (k: {v: Int | (0 <= v && v < n)} -> a<r k>) @-}
+initialize :: (Int -> a) -> Int -> Int -> Vec a -> Vec a
+initialize f i n a 
+  | i >= n    = a
+  | otherwise = initialize f (i + 1) n (set i (f i) a)
+\end{code}
+
+The signature requires that (a) the higher-order function `f` produces values that satisfy the range refinement `r`, and (b) the vector is initialized from `0` to `i`.
+The function ensures that the output vector is initialized from `0`
+through `n`.
+
+We can thus verify that
+
+\begin{code}
+{-@ idVec :: n:Int -> (k: {v: Int | (0 <= v && v < n)} -> {v: Int | v = k}) @-}
+idVec :: Int -> (Vec Int)
+idVec n = initialize (\i -> i) 0 n empty
+\end{code}
+
+ie `idVec` returns an vector of size `n` where each key is mapped to itself. Thus, abstract refinement types allow us to verify low-level idioms such as the incremental initialization of vectors, which have previously required special analyses.
+
+Null-Terminated Strings
+-----------------------
+
+We can also use abstract refinements to verify code which manipulates C-style null-terminated strings, where each character is represented as an `Int` and the termination character `\0`, and only that, is represented as `0`.
+
+\begin{code}Formally, a null-terminated string, represented by `Int`s, of size `n` has the type
+type NullTerm n 
+     = Vec <{\v -> 0<=v<n}, {\i v -> i=n-1 => v=0}> Int
+\end{code}
+
+The above type describes a length-`n` vector of characters whose last element must be a null character, signalling the end of the string.
+
+We can use this type in the specification of a function, `upperCase`, which iterates through the characters of a string, uppercasing each one until it encounters the null terminator:
+
+\begin{code}
+ucs :: Int -> Int -> Vec Int -> Vec Int
+ucs n i s =
+  case get i s of
+  0 -> s
+  c -> ucs n (i + 1) (set i (c + 32) s)
+
+{-@ upperCaseString ::
+      n: {v: Int | v > 0} ->
+      s: (j: {v : Int | (0 <= v && v < n)} ->
+          {v: Int | (j = n - 1 => v = 0)}) ->
+      (j: {v : Int | (0 <= v && v < n)} ->
+       {v: Int | (j = n - 1 => v = 0)})
+@-}
+upperCaseString :: Int -> Vec Int -> Vec Int
+upperCaseString n s = ucs n 0 s
+\end{code}
+
+
+Note that the length parameter `n` is provided solely as a ''witness'' for the length of the string `s`, which allows us to use the length of `s` in the type of `upperCaseString`; `n` is not used in the computation.
+
+In order to establish that each call to `get` accesses string `s` within its bounds, our type system must establish that, at each call to the inner function `ucs`, `i` satisfies the type `{v: Int | 0 <= v && v < n}`.
+
+This invariant is established as follows:
+
+First, the invariant trivially holds on the first call to `ucs`, as
+`n` is positive and `i` is `0`.
+Second, we assume that `i` satisfies the type `{v: Int | 0 <= v && v < n}`, and, further, we know from the types of `s` and `get` that `c` has the type `{v: Int | i = n - 1 => c = 0}`.
+Thus, if `c` is non-null, then `i` cannot be equal to `n - 1`.
+This allows us to strengthen our type for `i` in the else branch to `{v: Int | 0 <= v && v < n - 1}` and thus to conclude that the value `i + 1` recursively passed as the `i` parameter to `ucs` satisfies the type `{v: Int | 0 <= v && v < n}`, establishing the inductive invariant and thus the safety of the `upperCaseString` function.
+
+
+
+Memoization 
+-----------
+
+Next, let us illustrate how the same expressive signatures allow us to verify memoizing functions. We can specify to the SMT solver the definition of the Fibonacci function via an uninterpreted function `fib` and an axiom:
+
+\begin{code}
+{-@ measure fib :: Int -> Int @-}
+
+{-@ axiom_fib :: i:Int -> {v: Bool | (Prop(v) <=> 
+                            (fib(i) = ((i <= 1) ? 1 : ((fib(i-1)) + (fib(i-2))))))} 
+  @-}
+axiom_fib :: Int -> Bool
+axiom_fib i = undefined
+\end{code}
+
+Next, we define a type alias `FibV` for the vector whose values are either `0` (ie undefined), or equal to the Fibonacci number of the corresponding index. 
+
+\begin{code}
+{-@ type FibV = j:Int -> {v:Int| ((v != 0) => (v = fib(j)))} @-}
+\end{code}
+
+Finally, we can use the above alias to verify `fastFib`, an implementation of the Fibonacci function, which uses an vector memoize intermediate results 
+
+\begin{code}
+{-@ fastFib :: x:Int -> {v:Int | v = fib(x)} @-}
+fastFib     :: Int -> Int
+fastFib n   = snd $ fibMemo (\_ -> 0) n
+
+{-@ fibMemo :: FibV -> i:Int -> (FibV, {v: Int | v = fib(i)}) @-}
+fibMemo t i 
+  | i <= 1    
+  = (t, liquidAssume (axiom_fib i) (1 :: Int))
+  
+  | otherwise 
+  = case get i t of   
+      0 -> let (t1, n1) = fibMemo t  (i-1)
+               (t2, n2) = fibMemo t1 (i-2)
+               n        = liquidAssume (axiom_fib i) (n1 + n2)
+           in  (set i n t2,  n)
+      n -> (t, n)
+\end{code}
+
+Thus, abstract refinements allow us to define key-value maps with index-dependent refinements for the domain and range. 
+Quantification over the domain and range refinements allows us to define generic access operations (eg. `get`, `set`, `create`, `empty`) whose types enable us establish a variety of precise invariants.
+
+
+
+
diff --git a/docs/blog/todo/kmeans-full.lhs b/docs/blog/todo/kmeans-full.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/kmeans-full.lhs
@@ -0,0 +1,270 @@
+---
+layout: post
+title: "KMeans Clustering N-Dimensional Points"
+date: 2013-02-14 16:12
+author: Ranjit Jhala
+published: false 
+comments: true
+external-url:
+categories: basic measures 
+demo: kmeans.hs
+---
+
+[Last time][safeList] we introduced a new specification called a *measure*
+and demonstrated how to use it to encode the *length* of a list, and
+thereby verify that functions like `head` and `tail` were only called with
+non-empty lists (whose length was *strictly* greater than `0`.) As several
+folks pointed out, once LiquidHaskell can reason about lengths, it can do a
+lot more than just analyze non-emptiness. 
+
+Indeed! 
+
+So today, let me show you how one might implement a k-means algorithm that
+clusters `n`-dimensional points into at most k groups, and how
+LiquidHaskell can help us write and enforce these size requirements. 
+
+<!-- For example, XXX pointed out that we can use the type
+system to give an *upper* bound on the size of a list, e.g. 
+using lists upper bounded by a gigantic `MAX_INT` value as
+a proxy for finite lists.
+-->
+
+<!-- more -->
+
+Rather than reinvent the wheel, lets start with an existing implementation
+of K-Means, available [on hackage](hackage-kmeans). This may not be the most 
+efficient implementation, but its a nice introduction to the algorithm, and we 
+speculate that the general invariants will hold for more sophisticated
+implementations.
+
+
+\begin{code}
+
+nearest centers x   = minimumKey distances
+  where distances   = M.map (distance x) centers
+
+minimumKey   :: (Ord v) => M.Map k v -> k
+minimumKey   = fst . minimumBy (\x y -> compare (snd x) (snd y)) . M.toList 
+
+distance     :: [Double] -> [Double] -> [Double]
+distance a b = sqrt . sum $ zipWith (\x y -> (x - y) ^ 2) a b
+
+normalize (n :: Int) = M.map (\(c, s) -> map (`safeDiv` s) c) 
+
+initialCenters :: [a] -> M.HashMap Int [a] -> 
+
+{-@ NNList a      = {v: [a] | ((len v) > 0) }           @-}
+{-@ BoundInt  K   = {v: Int | (0 <= v) && (v < K) }     @-}
+{-@ Point a   N   = {v: [a] | (len v) = N }             @-}
+{-@ Points a  N   = NNList (Point a n)                  @-}
+{-@ Cluster a K N = M.HashMap (BoundInt K) (Point a N)  @-}
+
+{-@ initialCenters  :: k:{k:Int | k > 0} -> [a] -> M.HashMap (BoundInt k) (NNList a) @-}
+initialCenters      :: Int -> [a] -> M.HashMap Int [a]  
+initialCenters k xs = M.fromList $ zip indices partitions 
+  where 
+    clusterSize     = max 1 ((length points + k - 1) `div` k)
+    parts           = partition clusterSize points
+    nParts          = length parts
+    indices         = liquidAssume (nParts <= k) [1..nParts]
+
+{-@ partition        :: {v:Int | v > 0} -> [a] -> [(NNList a)] @-}
+partition n []       = []
+partition n ys@(_:_) = zs : part n zs' 
+  where 
+    zs               = take n ys
+    zs'              = drop n ys
+
+kmeansStep :: n:Int -> [Point Double n] -> M.Map k (Point Double n) -> M.Map k (Point Double n) 
+kmeansStep (n :: Int) centers = M.fromList . mapReduce newCenter mergeCluster
+  where
+    recenter x              = [(nearest centers x, (x, 1))]
+    merge (c1, s1) (c2, s2) = (zipWith (+) c1 c2, s1 + s2)
+
+           
+kmeans n k xs  = initialCenters k xs
+
+-- kgroupBy :: k:Int -> (a -> BoundInt k) -> [a] -> {v: [(NNList a)] | (len v) <= k }
+\end{code}
+
+
+
+-- let rec ffor i j f = 
+--   if i < j then (
+--     f i; 
+--     ffor (i+1) j f
+--   )
+-- 
+-- let min_index a =
+--   let min = ref 0 in
+--   ffor 0 (Array.length a) (fun i ->
+--     if a.(i) < a.(!min) then            (* ARRAY BOUNDS *)
+--       min := i
+--   );
+--   !min
+-- 
+-- let nearest dist ctra x  =
+--   let da = Array.map (dist x) ctra in
+--   (min_index da, (x, 1))
+-- 
+-- let centroid plus p1 p2 = 
+--   let (x1, size1) = p1 in
+--   let (x2, size2) = p2 in 
+--   (plus x1 x2, size1 + size2)
+-- 
+-- let update_centers div a ixs =
+--   List.iter (fun (i, (x, size)) -> a.(i) <- div x size) ixs
+--             (* ARRAY BOUNDS, DIV BY ZERO *)
+-- 
+-- let kmeans n dist plus div (points : 'a list) (centera : 'a array) =
+--   assert (Array.length centera > 0); 
+--   ffor 0 n begin fun _ ->
+--     let point_centers   = map      (nearest dist centera) points      in
+--     let center_clusters = group    point_centers                      in 
+--     let new_centers     = reduce   (centroid plus) center_clusters    in
+--     update_centers div centera new_centers
+--   end  
+
+
+\begin{code}
+
+{-# LANGUAGE ScopedTypeVariables, TypeSynonymInstances, FlexibleInstances #-}
+
+module Data.KMeans (kmeans, kmeansGen) where
+
+import Data.List (sort, span, minimumBy)
+import Data.Function (on)
+import Data.Ord (comparing)
+import Language.Haskell.Liquid.Prelude (liquidAssert, liquidError)
+
+{-@ groupBy :: (a -> a -> Bool) 
+            -> [a] 
+            -> [{v:[a] | len(v) > 0}] 
+  @-}
+
+groupBy           :: (a -> a -> Bool) -> [a] -> [[a]]
+groupBy _  []     =  []
+groupBy eq (x:xs) =  (x:ys) : groupBy eq zs
+                     where (ys,zs) = span (eq x) xs
+
+{-@ type Vec a N      = { v : [a] | (len v) = N } @-}
+
+{-@ type Matrix a N M = Vec (Vec a N) M           @-}
+
+{-@ type PosInt       = {v:Int | v > 0}           @-}
+
+
+{-@ transpose :: n:Int -> m:PosInt -> Matrix a n m -> Matrix a m n @-}
+transpose     :: Int -> Int -> [[a]] -> [[a]]
+
+transpose 0 _ _              = []
+transpose n m ((x:xs) : xss) = (x : map head xss) : transpose (n - 1) m (xs : map tail xss)
+-- transpose n m ((x:xs) : xss) = (x : [h | (h:_) <- xss]) : transpose (xs : [ t | (_:t) <- xss])
+transpose n m ([] : _)       = liquidError "transpose1" 
+transpose n m []             = liquidError "transpose2"
+
+
+data WrapType b a = WrapType {getVect :: b, getVal :: a}
+
+instance Eq (WrapType [Double] a) where
+   (==) = (==) `on` getVect
+
+instance Ord (WrapType [Double] a) where
+    compare = comparing getVect
+
+-- dist ::  [Double] -> [Double] -> Double 
+dist a b = sqrt . sum $ zipWith (\x y -> (x - y) ^ 2) a b      -- zipWith dimensions
+
+safeDiv     :: (Fractional a) => a -> Int -> a
+safeDiv n 0 = liquidError "divide by zero"
+safeDiv n d = n / (fromIntegral d)
+
+
+centroid n points = map ((`safeDiv` m) . sum) points'              -- divide By Zero
+  where 
+    m             = length points 
+    points'       = transpose n m (map getVect points)
+
+
+recluster n clusters = recluster' n centroids points 
+  where 
+    points         = concat clusters 
+    centroids      = indexList $ map (centroid n) clusters
+    centeredPoints = [(closest n centroids (getVect p), p) | p <- points]
+    clusters'      = map (map snd)
+
+
+recluster' n centroids points = map (map snd) $ groupBy ((==) `on` fst) reclustered
+    where reclustered = sort [(closest n centroids (getVect p), p) | p <- points]
+
+
+closest :: Int -> [(Int, [Double])] -> [Double] -> Int
+closest (n :: Int) centroids point = minimumKey distances 
+  where 
+    distances = [(i, dist point ci) | (i, ci) <- icentroids ]
+
+minimumKey :: (Ord v) => [(k, v)] -> k
+minimumKey kvs = minimumBy (\x y -> compare (snd x) (snd y)) kvs
+
+indexList :: [a] -> [(Int, a)]
+indexList xs         = zip [1..(length xs)] xs
+
+
+
+
+
+{-@ part        :: n:{v:Int | v > 0} -> [a] -> [{v:[a] | len(v) > 0}] @-}
+part n []       = []
+part n ys@(_:_) = zs : part n zs' 
+                  where zs  = take n ys
+                        zs' = drop n ys
+
+-- | Recluster points
+kmeans'' n clusters
+  | clusters == clusters' = clusters
+  | otherwise             = kmeans'' n clusters'
+  where clusters'         = recluster n clusters
+
+kmeans' n k points = kmeans'' n $ part l points
+    where l = max 1 ((length points + k - 1) `div` k)
+
+-- | Cluster points in a Euclidian space, represented as lists of Doubles, into at most k clusters.
+-- The initial clusters are chosen arbitrarily.
+{-@ kmeans :: n:Int 
+           -> k:Int 
+           -> points:[(Vec Double n)] 
+           -> [[(Vec Double n)]] 
+  @-}
+kmeans :: Int -> Int -> [[Double]] -> [[[Double]]]
+kmeans n = kmeansGen n id
+
+-- | A generalized kmeans function. This function operates not on points, but an arbitrary type 
+--   which may be projected into a Euclidian space. Since the projection may be chosen freely, 
+-- this allows for weighting dimensions to different degrees, etc.
+
+{-@ kmeansGen :: n: Int -> f:(a -> (Vec Double n)) -> k:Int -> points:[a] -> [[a]] @-}
+kmeansGen :: Int -> (a -> [Double]) -> Int -> [a] -> [[a]]
+kmeansGen n f k points = map (map getVal) . kmeans' n k . map (\x -> WrapType (f x) x) $ points
+
+
+\end{code}
+
+
+
+Conclusions
+-----------
+
+1. How to do *K-Means Clustering* !
+
+2. Track precise length properties with **measures**
+
+3. Circumvent limitations of SMT with a touch of **dynamic** checking using **assumes**
+
+
+[vecbounds]:  /blog/2013/01/05/bounding-vectors.lhs/ 
+[ghclist]:    https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/GHC/List.lhs#L125
+[foldl1]:     http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#foldl1
+[safeList]:   /blog/2013/01/31/safely-catching-a-list-by-its-tail.lhs/ 
+
+
+
diff --git a/docs/blog/todo/lets-talk-about-sets.lhs.markdown b/docs/blog/todo/lets-talk-about-sets.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/lets-talk-about-sets.lhs.markdown
@@ -0,0 +1,671 @@
+---
+layout: post
+title: "Lets Talk About Sets"
+date: 2013-01-05 16:12
+comments: true
+external-url:
+categories: basic, measures, sets
+author: Ranjit Jhala
+published: false 
+---
+
+In the posts so far, we've seen how LiquidHaskell allows you to use SMT 
+solvers to specify and verify *numeric* invariants -- denominators 
+that are non-zero, integer indices that are within the range of an 
+array, vectors that have the right number of dimensions and so on.
+
+However, SMT solvers are not limited to numbers, and in fact, support
+rather expressive logics. In the next couple of posts, lets see how 
+LiquidHaskell uses SMT to talk about **sets of values**, for example, 
+the contents of a list, and to specify and verify properties about 
+those sets.
+
+
+<pre><span class=hs-linenum>24: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>ListSets</span> <span class='hs-keyword'>where</span>
+</pre>
+
+Talking about Sets (In Logic)
+=============================
+
+First, we need a way to talk about sets in the refinement logic. We could
+roll our own special Haskell type, but why not just use the `Set a` type
+from `Data.Set`.
+
+
+<pre><span class=hs-linenum>35: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Set</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>filter</span><span class='hs-layout'>,</span> <span class='hs-varid'>split</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>36: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span>  <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span><span class='hs-layout'>,</span> <span class='hs-varid'>filter</span><span class='hs-layout'>)</span>
+</pre>
+
+The above, also instructs LiquidHaskell to import in the various 
+specifications defined for the `Data.Set` module that we have *predefined* 
+in [Data/Set.spec][setspec] 
+
+Lets look at the specifications.
+
+ The `embed` directive tells LiquidHaskell to model the **Haskell** 
+<pre><span class=hs-linenum>46: </span><span class='hs-keyword'>type</span> <span class='hs-varid'>constructor</span> <span class='hs-varop'>`Set`</span> <span class='hs-varid'>with</span> <span class='hs-varid'>the</span> <span class='hs-varop'>**</span><span class='hs-conid'>SMT</span><span class='hs-varop'>**</span> <span class='hs-keyword'>type</span> <span class='hs-varid'>constructor</span> <span class='hs-varop'>`Set_Set`</span><span class='hs-varop'>.</span>
+<span class=hs-linenum>47: </span>
+<span class=hs-linenum>48: </span><span class='hs-keyword'>module</span> <span class='hs-varid'>spec</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Set</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>49: </span>
+<span class=hs-linenum>50: </span><span class='hs-definition'>embed</span> <span class='hs-conid'>Set</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>Set_Set</span>
+</pre>
+
+ First, we define the logical operators (i.e. `measure`s) 
+<pre><span class=hs-linenum>54: </span><span class='hs-definition'>measure</span> <span class='hs-conid'>Set_sng</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>                    <span class='hs-comment'>-- ^ singleton</span>
+<span class=hs-linenum>55: </span><span class='hs-definition'>measure</span> <span class='hs-conid'>Set_cup</span>  <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>   <span class='hs-comment'>-- ^ union</span>
+<span class=hs-linenum>56: </span><span class='hs-definition'>measure</span> <span class='hs-conid'>Set_cap</span>  <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>   <span class='hs-comment'>-- ^ intersection</span>
+<span class=hs-linenum>57: </span><span class='hs-definition'>measure</span> <span class='hs-conid'>Set_dif</span>  <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>   <span class='hs-comment'>-- ^ difference </span>
+</pre>
+
+ Next, we define predicates on `Set`s 
+<pre><span class=hs-linenum>61: </span><span class='hs-definition'>measure</span> <span class='hs-conid'>Set_emp</span>  <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>                 <span class='hs-comment'>-- ^ emptiness</span>
+<span class=hs-linenum>62: </span><span class='hs-definition'>measure</span> <span class='hs-conid'>Set_mem</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>            <span class='hs-comment'>-- ^ membership</span>
+<span class=hs-linenum>63: </span><span class='hs-definition'>measure</span> <span class='hs-conid'>Set_sub</span>  <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>      <span class='hs-comment'>-- ^ inclusion </span>
+</pre>
+
+
+Interpreted Operations
+----------------------
+
+The above operators are *interpreted* by the SMT solver. That is, just 
+like the SMT solver *"knows that"* 
+
+    2 + 2 == 4
+
+the SMT solver *"knows that"* 
+
+    (Set_sng 1) == (Set_cap (Set_sng 1) (Set_cup (Set_sng 2) (Set_sng 1)))
+
+This is because, the above formulas belong to a decidable Theory of Sets
+which can be reduced to McCarthy's more general [Theory of Arrays][mccarthy]. 
+See [this recent paper][z3cal] if you want to learn more about how modern SMT 
+solvers *"know"* the above equality holds...
+
+Talking about Sets (In Code)
+============================
+
+Of course, the above operators exist purely in the realm of the 
+refinement logic, beyond the grasp of the programmer.
+
+To bring them down (or up, or left or right) within reach of Haskell code, 
+we can simply *assume* that the various public functions in `Data.Set` do 
+the *Right Thing* i.e. produce values that reflect the logical set operations:
+
+ First, the functions that create `Set` values
+<pre><span class=hs-linenum>95: </span><span class='hs-definition'>empty</span>     <span class='hs-keyglyph'>::</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_emp</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>96: </span><span class='hs-definition'>singleton</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_sng</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+</pre>
+
+ Next, the functions that operate on elements and `Set` values
+<pre><span class=hs-linenum>100: </span><span class='hs-definition'>insert</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_cup</span> <span class='hs-varid'>xs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_sng</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>101: </span><span class='hs-definition'>delete</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_dif</span> <span class='hs-varid'>xs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_sng</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+</pre>
+
+ Then, the binary `Set` operators
+<pre><span class=hs-linenum>105: </span><span class='hs-definition'>union</span>        <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_cup</span> <span class='hs-varid'>xs</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>106: </span><span class='hs-definition'>intersection</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_cap</span> <span class='hs-varid'>xs</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>107: </span><span class='hs-definition'>difference</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_dif</span> <span class='hs-varid'>xs</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+</pre>
+
+ And finally, the predicates on `Set` values:
+<pre><span class=hs-linenum>111: </span><span class='hs-definition'>isSubsetOf</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-conid'>Prop</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-varop'>&lt;=&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_sub</span> <span class='hs-varid'>xs</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>112: </span><span class='hs-definition'>member</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-conid'>Prop</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-varop'>&lt;=&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_mem</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+</pre>
+
+**Note:** Oh quite. We shouldn't and needn't really *assume*, but should and
+will *guarantee* that the functions from `Data.Set` implement the above types. 
+But thats a story for another day...
+
+Proving Theorems With LiquidHaskell
+===================================
+
+OK, lets take our refined operators from `Data.Set` out for a spin!
+One pleasant consequence of being able to precisely type the operators 
+from `Data.Set` is that we have a pleasant interface for using the SMT
+solver to *prove theorems* about sets, while remaining firmly rooted in
+Haskell. 
+
+First, lets write a simple function that asserts that its input is `True`
+
+
+<pre><span class=hs-linenum>131: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>boolAssert</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>{v:</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>| (Prop v)}</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Bool</span> <span class='hs-keyword'>| (Prop v)}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>132: </span><a class=annot href="#"><span class=annottext>{VV : (GHC.Types.Bool) | (? Prop([VV]))}
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV]))}</span><span class='hs-definition'>boolAssert</span></a> <span class='hs-conid'>True</span>   <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : (GHC.Types.Bool) | (? Prop([VV])),(VV = True)}</span><span class='hs-conid'>True</span></a>
+<span class=hs-linenum>133: </span><span class='hs-definition'>boolAssert</span> <span class='hs-conid'>False</span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>[(GHC.Types.Char)] -&gt; {VV : (GHC.Types.Bool) | false}</span><span class='hs-varid'>error</span></a> <a class=annot href="#"><span class=annottext>{VV : [(GHC.Types.Char)] | (len([VV]) &gt;= 0)}</span><span class='hs-str'>"boolAssert: False? Never!"</span></a>
+</pre>
+
+Now, we can use `boolAssert` to write some simple properties. (Yes, these do
+indeed look like QuickCheck properties -- but here, instead of generating
+tests and executing the code, the type system is proving to us that the
+properties will *always* evaluate to `True`) 
+
+Lets check that `intersection` is commutative ...
+
+
+<pre><span class=hs-linenum>144: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>prop_cap_comm</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>145: </span><span class='hs-definition'>prop_cap_comm</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
+<span class=hs-linenum>146: </span><a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; (Data.Set.Base.Set (GHC.Types.Int)) -&gt; (GHC.Types.Bool)</span><span class='hs-definition'>prop_cap_comm</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>y</span></a> 
+<span class=hs-linenum>147: </span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : (GHC.Types.Bool) | (? Prop([VV]))}
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV]))}</span><span class='hs-varid'>boolAssert</span></a> 
+<span class=hs-linenum>148: </span>  <a class=annot href="#"><span class=annottext>({VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}
+ -&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)})
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}</span><span class='hs-varop'>$</span></a> <a class=annot href="#"><span class=annottext>(GHC.Types.Bool)</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cap([xs;
+                                                              ys]))}</span><span class='hs-varop'>`intersection`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = y)}</span><span class='hs-varid'>y</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>GHC.Classes.Eq (Data.Set.Base.Set GHC.Types.Int)</span><span class='hs-varop'>==</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cap([xs;
+                                                              ys]))}</span><span class='hs-varop'>`intersection`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a><span class='hs-layout'>)</span>
+</pre>
+
+that `union` is associative ...
+
+
+<pre><span class=hs-linenum>154: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>prop_cup_assoc</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>155: </span><span class='hs-definition'>prop_cup_assoc</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
+<span class=hs-linenum>156: </span><a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; (Data.Set.Base.Set (GHC.Types.Int))
+-&gt; (Data.Set.Base.Set (GHC.Types.Int))
+-&gt; (GHC.Types.Bool)</span><span class='hs-definition'>prop_cup_assoc</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>z</span></a> 
+<span class=hs-linenum>157: </span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : (GHC.Types.Bool) | (? Prop([VV]))}
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV]))}</span><span class='hs-varid'>boolAssert</span></a> 
+<span class=hs-linenum>158: </span>  <a class=annot href="#"><span class=annottext>({VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}
+ -&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)})
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}</span><span class='hs-varop'>$</span></a> <a class=annot href="#"><span class=annottext>(GHC.Types.Bool)</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cup([xs;
+                                                              ys]))}</span><span class='hs-varop'>`union`</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cup([xs;
+                                                              ys]))}</span><span class='hs-varop'>`union`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = z)}</span><span class='hs-varid'>z</span></a><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>x:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; y:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (GHC.Types.Bool) | ((? Prop([VV])) &lt;=&gt; (x = y))}</span><span class='hs-varop'>==</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cup([xs;
+                                                              ys]))}</span><span class='hs-varop'>`union`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = y)}</span><span class='hs-varid'>y</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cup([xs;
+                                                              ys]))}</span><span class='hs-varop'>`union`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = z)}</span><span class='hs-varid'>z</span></a>
+</pre>
+
+and that `union` distributes over `intersection`.
+
+
+<pre><span class=hs-linenum>164: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>prop_cap_dist</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>165: </span><span class='hs-definition'>prop_cap_dist</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
+<span class=hs-linenum>166: </span><a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; (Data.Set.Base.Set (GHC.Types.Int))
+-&gt; (Data.Set.Base.Set (GHC.Types.Int))
+-&gt; (GHC.Types.Bool)</span><span class='hs-definition'>prop_cap_dist</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>z</span></a> 
+<span class=hs-linenum>167: </span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : (GHC.Types.Bool) | (? Prop([VV]))}
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV]))}</span><span class='hs-varid'>boolAssert</span></a> 
+<span class=hs-linenum>168: </span>  <a class=annot href="#"><span class=annottext>({VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}
+ -&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)})
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}</span><span class='hs-varop'>$</span></a>  <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cap([xs;
+                                                              ys]))}</span><span class='hs-varop'>`intersection`</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cup([xs;
+                                                              ys]))}</span><span class='hs-varop'>`union`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = z)}</span><span class='hs-varid'>z</span></a><span class='hs-layout'>)</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>169: </span>  <a class=annot href="#"><span class=annottext>x:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; y:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (GHC.Types.Bool) | ((? Prop([VV])) &lt;=&gt; (x = y))}</span><span class='hs-varop'>==</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cap([xs;
+                                                              ys]))}</span><span class='hs-varop'>`intersection`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = y)}</span><span class='hs-varid'>y</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cup([xs;
+                                                              ys]))}</span><span class='hs-varop'>`union`</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cap([xs;
+                                                              ys]))}</span><span class='hs-varop'>`intersection`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = z)}</span><span class='hs-varid'>z</span></a><span class='hs-layout'>)</span> 
+</pre>
+  
+Of course, while we're at it, lets make sure LiquidHaskell 
+doesn't prove anything thats *not* true ...
+
+
+<pre><span class=hs-linenum>176: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>prop_cup_dif_bad</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>177: </span><span class='hs-definition'>prop_cup_dif_bad</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Set</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
+<span class=hs-linenum>178: </span><a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; (Data.Set.Base.Set (GHC.Types.Int)) -&gt; (GHC.Types.Bool)</span><span class='hs-definition'>prop_cup_dif_bad</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-varid'>y</span></a>
+<span class=hs-linenum>179: </span>   <span class='hs-keyglyph'>=</span> <span class=hs-error><a class=annot href="#"><span class=annottext>{VV : (GHC.Types.Bool) | (? Prop([VV]))}
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV]))}</span><span class='hs-varid'>boolAssert</span></a></span> 
+<span class=hs-linenum>180: </span>   <a class=annot href="#"><span class=annottext>((GHC.Types.Bool)
+ -&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)})
+-&gt; (GHC.Types.Bool)
+-&gt; {VV : (GHC.Types.Bool) | (? Prop([VV])),(VV != False)}</span><span class='hs-varop'>$</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; y:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (GHC.Types.Bool) | ((? Prop([VV])) &lt;=&gt; (x = y))}</span><span class='hs-varop'>==</span></a> <a class=annot href="#"><span class=annottext>(Data.Set.Base.Set (GHC.Types.Int))</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_cup([xs;
+                                                              ys]))}</span><span class='hs-varop'>`union`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = y)}</span><span class='hs-varid'>y</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>xs:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; ys:(Data.Set.Base.Set (GHC.Types.Int))
+-&gt; {VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = Set_dif([xs;
+                                                              ys]))}</span><span class='hs-varop'>`difference`</span></a> <a class=annot href="#"><span class=annottext>{VV : (Data.Set.Base.Set (GHC.Types.Int)) | (VV = y)}</span><span class='hs-varid'>y</span></a>
+</pre>
+
+Hmm. You do know why the above doesn't hold, right? It would be nice to
+get a *counterexample* wouldn't it. Well, for the moment, there is
+QuickCheck!
+
+Thus, the refined types offer a nice interface for interacting with the SMT
+solver in order to prove theorems in LiquidHaskell. (BTW, The [SBV project][sbv]
+describes another approach for using SMT solvers from Haskell, without the 
+indirection of refinement types.)
+
+While the above is a nice warm up exercise to understanding how
+LiquidHaskell reasons about sets, our overall goal is not to prove 
+theorems about set operators, but instead to specify and verify 
+properties of programs. 
+
+
+The Set of Values in a List
+===========================
+
+Lets see how we might reason about sets of values in regular Haskell programs. 
+
+Lets begin with Lists, the jack-of-all-data-types. Now, instead of just
+talking about the **number of** elements in a list, we can write a measure
+that describes the **set of** elements in a list:
+
+ A measure for the elements of a list, from [Data/Set.spec][setspec]
+<pre><span class=hs-linenum>208: </span>
+<span class=hs-linenum>209: </span><span class='hs-definition'>measure</span> <span class='hs-varid'>listElts</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>210: </span><span class='hs-definition'>listElts</span> <span class='hs-layout'>(</span><span class='hs-conid'>[]</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varop'>?</span> <span class='hs-conid'>Set_emp</span><span class='hs-layout'>(</span><span class='hs-varid'>v</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>211: </span><span class='hs-definition'>listElts</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_cup</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_sng</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>listElts</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
+</pre>
+
+That is, `(elts xs)` describes the set of elements contained in a list `xs`.
+
+Next, to make the specifications concise, lets define a few predicate aliases:
+
+
+<pre><span class=hs-linenum>219: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>predicate</span> <span class='hs-conid'>SameElts</span>  <span class='hs-conid'>X</span> <span class='hs-conid'>Y</span>   <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>listElts</span> <span class='hs-conid'>X</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>listElts</span> <span class='hs-conid'>Y</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>                        <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>220: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>predicate</span> <span class='hs-conid'>SubElts</span>   <span class='hs-conid'>X</span> <span class='hs-conid'>Y</span>   <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_sub</span> <span class='hs-layout'>(</span><span class='hs-varid'>listElts</span> <span class='hs-conid'>X</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>listElts</span> <span class='hs-conid'>Y</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>                   <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>221: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>predicate</span> <span class='hs-conid'>UnionElts</span> <span class='hs-conid'>X</span> <span class='hs-conid'>Y</span> <span class='hs-conid'>Z</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>listElts</span> <span class='hs-conid'>X</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Set_cup</span> <span class='hs-layout'>(</span><span class='hs-varid'>listElts</span> <span class='hs-conid'>Y</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>listElts</span> <span class='hs-conid'>Z</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+A Trivial Identity
+------------------
+
+OK, now lets write some code to check that the `elts` measure is sensible!
+
+
+<pre><span class=hs-linenum>230: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>listId</span>    <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span><span class='hs-keyword'>| (SameElts v xs)}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>231: </span><a class=annot href="#"><span class=annottext>forall a.
+x1:[a]
+-&gt; {VV : [a] | (len([VV]) = len([x1])),
+               (listElts([VV]) = Set_cup([listElts([x1]); listElts([x1])])),
+               (listElts([VV]) = listElts([x1])),
+               (listElts([x1]) = Set_cup([listElts([x1]); listElts([VV])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-definition'>listId</span></a> <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+{VV : [{VV : a | false}]&lt;p&gt; | (? Set_emp([listElts([VV])])),
+                              (len([VV]) = 0)}</span><span class='hs-conid'>[]</span></a>
+<span class=hs-linenum>232: </span><span class='hs-definition'>listId</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+x1:[a]
+-&gt; {VV : [a] | (len([VV]) = len([x1])),
+               (listElts([VV]) = Set_cup([listElts([x1]); listElts([x1])])),
+               (listElts([VV]) = listElts([x1])),
+               (listElts([x1]) = Set_cup([listElts([x1]); listElts([VV])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>listId</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = xs),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+</pre>
+
+That is, LiquidHaskell checks that the set of elements of the output list
+is the same as those in the input.
+
+A Less Trivial Identity
+-----------------------
+
+Next, lets write a function to `reverse` a list. Of course, we'd like to
+verify that `reverse` doesn't leave any elements behind; that is that the 
+output has the same set of values as the input list. This is somewhat more 
+interesting because of the *tail recursive* helper `go`. Do you understand 
+the type that is inferred for it? (Put your mouse over `go` to see the 
+inferred type.)
+
+
+<pre><span class=hs-linenum>249: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>reverse</span>       <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span><span class='hs-keyword'>| (SameElts v xs)}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>250: </span><a class=annot href="#"><span class=annottext>forall a. xs:[a] -&gt; {VV : [a] | (listElts([VV]) = listElts([xs]))}</span><span class='hs-definition'>reverse</span></a>           <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{VV : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | (len([VV]) = 0)}
+-&gt; x2:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([x2])])),
+               (listElts([VV]) = Set_cup([listElts([x2]); listElts([x1])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>go</span></a> <a class=annot href="#"><span class=annottext>{VV : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | (? Set_emp([listElts([VV])])),
+                                           (len([VV]) = 0),
+                                           (len([VV]) &gt;= 0)}</span><span class='hs-conid'>[]</span></a> 
+<span class=hs-linenum>251: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>252: </span>    <a class=annot href="#"><span class=annottext>acc:{VV : [a] | (len([VV]) &gt;= 0)}
+-&gt; x1:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([acc]);
+                                          listElts([x1])])),
+               (listElts([VV]) = Set_cup([listElts([x1]); listElts([acc])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>go</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (len([VV]) &gt;= 0)}</span><span class='hs-varid'>acc</span></a> <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = acc),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>acc</span></a>
+<span class=hs-linenum>253: </span>    <span class='hs-varid'>go</span> <span class='hs-varid'>acc</span> <span class='hs-layout'>(</span><span class='hs-varid'>y</span><span class='hs-conop'>:</span><span class='hs-varid'>ys</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>acc:{VV : [a] | (len([VV]) &gt;= 0)}
+-&gt; x1:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([acc]);
+                                          listElts([x1])])),
+               (listElts([VV]) = Set_cup([listElts([x1]); listElts([acc])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>go</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV = y)}</span><span class='hs-varid'>y</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{VV : [a] | (VV = acc),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>acc</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = ys),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a>
+</pre>
+
+Appending Lists
+---------------
+
+Next, here's good old `append`, but now with a specification that states
+that the output indeed includes the elements from both the input lists.
+
+
+<pre><span class=hs-linenum>263: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>append</span>       <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyword'>| (UnionElts v xs ys) }</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>264: </span><a class=annot href="#"><span class=annottext>forall a.
+x1:[a]
+-&gt; ys:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([ys])])),
+               (listElts([VV]) = Set_cup([listElts([ys]); listElts([x1])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-definition'>append</span></a> <span class='hs-conid'>[]</span>     <a class=annot href="#"><span class=annottext>[a]</span><span class='hs-varid'>ys</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = ys),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a>
+<span class=hs-linenum>265: </span><span class='hs-definition'>append</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+x1:[a]
+-&gt; ys:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([ys])])),
+               (listElts([VV]) = Set_cup([listElts([ys]); listElts([x1])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>append</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = xs),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = ys),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a>
+</pre>
+
+Filtering Lists
+---------------
+
+Lets round off the list trilogy, with `filter`. Here, we can verify
+that it returns a **subset of** the values of the input list.
+
+
+<pre><span class=hs-linenum>275: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>filter</span>      <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span><span class='hs-keyword'>| (SubElts v xs)}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>276: </span>
+<span class=hs-linenum>277: </span><a class=annot href="#"><span class=annottext>forall a.
+(a -&gt; (GHC.Types.Bool))
+-&gt; x2:[a]
+-&gt; {VV : [a] | (? Set_sub([listElts([VV]); listElts([x2])])),
+               (listElts([x2]) = Set_cup([listElts([x2]); listElts([VV])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-definition'>filter</span></a> <a class=annot href="#"><span class=annottext>a -&gt; (GHC.Types.Bool)</span><span class='hs-varid'>f</span></a> <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+{VV : [{VV : a | false}]&lt;p&gt; | (? Set_emp([listElts([VV])])),
+                              (len([VV]) = 0)}</span><span class='hs-conid'>[]</span></a>
+<span class=hs-linenum>278: </span><span class='hs-definition'>filter</span> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>279: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>a -&gt; (GHC.Types.Bool)</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a>         <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(a -&gt; (GHC.Types.Bool))
+-&gt; x2:[a]
+-&gt; {VV : [a] | (? Set_sub([listElts([VV]); listElts([x2])])),
+               (listElts([x2]) = Set_cup([listElts([x2]); listElts([VV])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>filter</span></a> <a class=annot href="#"><span class=annottext>a -&gt; (GHC.Types.Bool)</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = xs),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a> 
+<span class=hs-linenum>280: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>   <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a.
+(a -&gt; (GHC.Types.Bool))
+-&gt; x2:[a]
+-&gt; {VV : [a] | (? Set_sub([listElts([VV]); listElts([x2])])),
+               (listElts([x2]) = Set_cup([listElts([x2]); listElts([VV])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>filter</span></a> <a class=annot href="#"><span class=annottext>a -&gt; (GHC.Types.Bool)</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = xs),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+</pre>
+
+Merge Sort
+==========
+
+Lets conclude this entry with one larger example: `mergeSort`. 
+We'd like to verify that, well, the list that is returned 
+contains the same set of elements as the input list. 
+
+And so we will!
+
+But first, lets remind ourselves of how `mergeSort` works
+
+1. `split` the input list into two halves, 
+2. `sort`  each half, recursively, 
+3. `merge` the sorted halves to obtain the sorted list.
+
+
+Split
+-----
+
+We can `split` a list into two, roughly equal parts like so:
+
+
+<pre><span class=hs-linenum>305: </span><a class=annot href="#"><span class=annottext>forall a.
+x1:[a]
+-&gt; ({VV : [a] | (? Set_sub([listElts([VV]); listElts([x1])])),
+                (listElts([x1]) = Set_cup([listElts([x1]); listElts([VV])])),
+                (len([VV]) &gt;= 0)} , {VV : [a] | (? Set_sub([listElts([VV]);
+                                                            listElts([x1])])),
+                                                (listElts([x1]) = Set_cup([listElts([x1]);
+                                                                           listElts([VV])])),
+                                                (len([VV]) &gt;= 0)})&lt;\x1 VV -&gt; (? Set_sub([listElts([VV]);
+                                                                                         listElts([x1])])),
+                                                                             (listElts([x1]) = Set_cup([listElts([x1]);
+                                                                                                        listElts([VV])])),
+                                                                             (listElts([x1]) = Set_cup([listElts([x1]);
+                                                                                                        listElts([VV])])),
+                                                                             (len([VV]) &gt;= 0)&gt;</span><span class='hs-definition'>split</span></a> <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a b &lt;p2 :: a -&gt; b -&gt; Bool&gt;. x1:a -&gt; b&lt;p2 x1&gt; -&gt; (a , b)&lt;p2&gt;</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{VV : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | (? Set_emp([listElts([VV])])),
+                                           (len([VV]) = 0),
+                                           (len([VV]) &gt;= 0)}</span><span class='hs-conid'>[]</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{VV : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | (? Set_emp([listElts([VV])])),
+                                           (len([VV]) = 0),
+                                           (len([VV]) &gt;= 0)}</span><span class='hs-conid'>[]</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>306: </span><span class='hs-definition'>split</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a b &lt;p2 :: a -&gt; b -&gt; Bool&gt;. x1:a -&gt; b&lt;p2 x1&gt; -&gt; (a , b)&lt;p2&gt;</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{VV : [a] | (? Set_sub([listElts([VV]); listElts([xs])])),
+            (VV = zs),
+            (VV = zs),
+            (len([VV]) = len([zs])),
+            (listElts([VV]) = Set_cup([listElts([zs]); listElts([zs])])),
+            (listElts([VV]) = listElts([zs])),
+            (listElts([xs]) = Set_cup([listElts([xs]); listElts([VV])])),
+            (listElts([xs]) = Set_cup([listElts([ys]); listElts([VV])])),
+            (listElts([xs]) = Set_cup([listElts([ys]); listElts([VV])])),
+            (listElts([zs]) = Set_cup([listElts([zs]); listElts([VV])])),
+            (len([VV]) &gt;= 0)}</span><span class='hs-varid'>zs</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (? Set_sub([listElts([VV]); listElts([xs])])),
+            (VV = ys),
+            (VV = ys),
+            (len([VV]) = len([ys])),
+            (listElts([VV]) = Set_cup([listElts([ys]); listElts([ys])])),
+            (listElts([VV]) = listElts([ys])),
+            (listElts([xs]) = Set_cup([listElts([xs]); listElts([VV])])),
+            (listElts([xs]) = Set_cup([listElts([zs]); listElts([VV])])),
+            (listElts([ys]) = Set_cup([listElts([ys]); listElts([VV])])),
+            (len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>307: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>308: </span>    <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : [a] | (? Set_sub([listElts([VV]); listElts([xs])])),
+            (VV = ys),
+            (len([VV]) = len([ys])),
+            (listElts([VV]) = Set_cup([listElts([ys]); listElts([ys])])),
+            (listElts([VV]) = listElts([ys])),
+            (listElts([xs]) = Set_cup([listElts([xs]); listElts([VV])])),
+            (listElts([xs]) = Set_cup([listElts([zs]); listElts([VV])])),
+            (listElts([ys]) = Set_cup([listElts([ys]); listElts([VV])])),
+            (len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (? Set_sub([listElts([VV]); listElts([xs])])),
+            (VV = zs),
+            (len([VV]) = len([zs])),
+            (listElts([VV]) = Set_cup([listElts([zs]); listElts([zs])])),
+            (listElts([VV]) = listElts([zs])),
+            (listElts([xs]) = Set_cup([listElts([xs]); listElts([VV])])),
+            (listElts([xs]) = Set_cup([listElts([ys]); listElts([VV])])),
+            (listElts([xs]) = Set_cup([listElts([ys]); listElts([VV])])),
+            (listElts([zs]) = Set_cup([listElts([zs]); listElts([VV])])),
+            (len([VV]) &gt;= 0)}</span><span class='hs-varid'>zs</span></a><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a.
+x1:[a]
+-&gt; ({VV : [a] | (? Set_sub([listElts([VV]); listElts([x1])])),
+                (listElts([x1]) = Set_cup([listElts([x1]); listElts([VV])])),
+                (len([VV]) &gt;= 0)} , {VV : [a] | (? Set_sub([listElts([VV]);
+                                                            listElts([x1])])),
+                                                (listElts([x1]) = Set_cup([listElts([x1]);
+                                                                           listElts([VV])])),
+                                                (len([VV]) &gt;= 0)})&lt;\x1 VV -&gt; (? Set_sub([listElts([VV]);
+                                                                                         listElts([x1])])),
+                                                                             (listElts([x1]) = Set_cup([listElts([x1]);
+                                                                                                        listElts([VV])])),
+                                                                             (listElts([x1]) = Set_cup([listElts([x1]);
+                                                                                                        listElts([VV])])),
+                                                                             (len([VV]) &gt;= 0)&gt;</span><span class='hs-varid'>split</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = xs),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+</pre>
+
+LiquidHaskell verifies that the relevant property of `split` is
+
+
+<pre><span class=hs-linenum>314: </span><span class='hs-keyword'>{-@</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>ys</span> <span class='hs-varid'>zs</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>UnionElts</span> <span class='hs-varid'>xs</span> <span class='hs-varid'>ys</span> <span class='hs-varid'>zs</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+The funny syntax with angle brackets simply says that the output is a 
+a *pair* `(ys, zs)` whose union is the list of elements of the input.
+
+(**Aside** yes, this is indeed a dependent tuple; we will revisit tuples
+later to understand whats going on with the odd syntax.)
+
+Merge
+-----
+
+Dually, we `merge` two (sorted) lists like so:
+
+
+<pre><span class=hs-linenum>329: </span><a class=annot href="#"><span class=annottext>forall a.
+(GHC.Classes.Ord a) =&gt;
+xs:[a]
+-&gt; x1:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([xs])])),
+               (listElts([VV]) = Set_cup([listElts([xs]); listElts([x1])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-definition'>merge</span></a> <a class=annot href="#"><span class=annottext>[a]</span><span class='hs-varid'>xs</span></a> <span class='hs-conid'>[]</span>         <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = xs),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+<span class=hs-linenum>330: </span><span class='hs-definition'>merge</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>ys</span>         <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a>
+<span class=hs-linenum>331: </span><span class='hs-definition'>merge</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>yozz</span><span class='hs-conop'>:</span><span class='hs-varid'>ys</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>332: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x:a
+-&gt; y:a -&gt; {VV : (GHC.Types.Bool) | ((? Prop([VV])) &lt;=&gt; (x &lt;= y))}</span><span class='hs-varop'>&lt;=</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV = yozz)}</span><span class='hs-varid'>yozz</span></a>       <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(GHC.Classes.Ord a) =&gt;
+xs:[a]
+-&gt; x1:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([xs])])),
+               (listElts([VV]) = Set_cup([listElts([xs]); listElts([x1])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>merge</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = xs),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV = yozz)}</span><span class='hs-varid'>yozz</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{VV : [a] | (VV = ys),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>333: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>       <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV = yozz)}</span><span class='hs-varid'>yozz</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(GHC.Classes.Ord a) =&gt;
+xs:[a]
+-&gt; x1:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([xs])])),
+               (listElts([VV]) = Set_cup([listElts([xs]); listElts([x1])])),
+               (len([VV]) &gt;= 0)}</span><span class='hs-varid'>merge</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+y:a
+-&gt; ys:[a&lt;p y&gt;]&lt;p&gt;
+-&gt; {VV : [a]&lt;p&gt; | (len([VV]) = (1 + len([ys]))),
+                  (listElts([VV]) = Set_cup([Set_sng([y]); listElts([ys])]))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{VV : [a] | (VV = xs),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = ys),(len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a>
+</pre>
+
+As you might expect, the elements of the returned list are the union of the
+elements of the input, or as LiquidHaskell might say,
+
+
+<pre><span class=hs-linenum>340: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>merge</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>y</span><span class='hs-conop'>:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyword'>| (UnionElts v x y)}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+Sort
+----
+
+Finally, we put all the pieces together by
+
+
+<pre><span class=hs-linenum>349: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>mergeSort</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyword'>| (SameElts v xs)}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>350: </span><a class=annot href="#"><span class=annottext>forall a.
+(GHC.Classes.Ord a) =&gt;
+x1:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([x1])])),
+               (listElts([VV]) = listElts([x1])),
+               (listElts([x1]) = Set_cup([listElts([x1]); listElts([VV])]))}</span><span class='hs-definition'>mergeSort</span></a> <span class='hs-conid'>[]</span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: a -&gt; a -&gt; Bool&gt;.
+{VV : [{VV : a | false}]&lt;p&gt; | (? Set_emp([listElts([VV])])),
+                              (len([VV]) = 0)}</span><span class='hs-conid'>[]</span></a>
+<span class=hs-linenum>351: </span><span class='hs-definition'>mergeSort</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>x</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | (? Set_emp([listElts([VV])])),
+                                           (len([VV]) = 0),
+                                           (len([VV]) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{VV : a | (VV = x)}</span><span class='hs-varid'>x</span></a><span class='hs-keyglyph'>]</span>
+<span class=hs-linenum>352: </span><span class='hs-definition'>mergeSort</span> <span class='hs-varid'>xs</span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x:[a]
+-&gt; y:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x]);
+                                          listElts([y])]))}</span><span class='hs-varid'>merge</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>forall a.
+(GHC.Classes.Ord a) =&gt;
+x1:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([x1])])),
+               (listElts([VV]) = listElts([x1])),
+               (listElts([x1]) = Set_cup([listElts([x1]); listElts([VV])]))}</span><span class='hs-varid'>mergeSort</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = ys),
+            (VV = ys),
+            (len([VV]) = len([ys])),
+            (listElts([VV]) = Set_cup([listElts([ys]); listElts([ys])])),
+            (listElts([VV]) = listElts([ys])),
+            (listElts([ys]) = Set_cup([listElts([ys]); listElts([VV])])),
+            (len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>forall a.
+(GHC.Classes.Ord a) =&gt;
+x1:[a]
+-&gt; {VV : [a] | (listElts([VV]) = Set_cup([listElts([x1]);
+                                          listElts([x1])])),
+               (listElts([VV]) = listElts([x1])),
+               (listElts([x1]) = Set_cup([listElts([x1]); listElts([VV])]))}</span><span class='hs-varid'>mergeSort</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = zs),
+            (VV = zs),
+            (len([VV]) = len([zs])),
+            (listElts([VV]) = Set_cup([listElts([zs]); listElts([zs])])),
+            (listElts([VV]) = listElts([zs])),
+            (listElts([zs]) = Set_cup([listElts([zs]); listElts([VV])])),
+            (len([VV]) &gt;= 0)}</span><span class='hs-varid'>zs</span></a><span class='hs-layout'>)</span> 
+<span class=hs-linenum>353: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>354: </span>    <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : [a] | (VV = ys),
+            (len([VV]) = len([ys])),
+            (listElts([VV]) = Set_cup([listElts([ys]); listElts([ys])])),
+            (listElts([VV]) = listElts([ys])),
+            (listElts([ys]) = Set_cup([listElts([ys]); listElts([VV])])),
+            (len([VV]) &gt;= 0)}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV = zs),
+            (len([VV]) = len([zs])),
+            (listElts([VV]) = Set_cup([listElts([zs]); listElts([zs])])),
+            (listElts([VV]) = listElts([zs])),
+            (listElts([zs]) = Set_cup([listElts([zs]); listElts([VV])])),
+            (len([VV]) &gt;= 0)}</span><span class='hs-varid'>zs</span></a><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>xs:[a]
+-&gt; ([a] , [a])&lt;\ys VV -&gt; (listElts([xs]) = Set_cup([listElts([ys]);
+                                                    listElts([VV])]))&gt;</span><span class='hs-varid'>split</span></a> <a class=annot href="#"><span class=annottext>{VV : [a] | (len([VV]) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+</pre>
+
+The type given to `mergeSort`guarantees that the set of elements in the 
+output list is indeed the same as in the input list. Of course, it says 
+nothing about whether the list is *actually sorted*. 
+
+Well, Rome wasn't built in a day...
+
+[sbv]:      https://github.com/LeventErkok/sbv
+[setspec]:  https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Data/Set.spec
+[mccarthy]: http://www-formal.stanford.edu/jmc/towards.ps
+[z3cal]:    http://research.microsoft.com/en-us/um/people/leonardo/fmcad09.pdf
diff --git a/docs/blog/todo/red-black-intro.lhs b/docs/blog/todo/red-black-intro.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/red-black-intro.lhs
@@ -0,0 +1,111 @@
+---
+layout: post
+title: "Composing Specifications: Red Black Trees" 
+date: 2014-04-05 16:12
+author: Ranjit Jhala
+published: false 
+comments: true
+external-url:
+categories: measures, abstract-refinements, red-black 
+---
+
+TODO: **Conjoining Specifications** lamport. 
+TODO: composing, and, for example, 
+TODO: red-black trees.
+
+[Red Black trees][RBTwiki] trees are a classic, cold-war era, 
+data structure used to efficiently represent sets, using trees
+whose nodes are labeled by the set's elements, and additionally, 
+are colored *red* or *black*. 
+
+The key to efficiency is that the the trees be *balanced*. 
+
+Of course, the easiest way to do this is to just add a *height* 
+label and check that the difference of heights at each node is 
+bounded (cf. [AVL trees][AVLTwiki]). But, back in the olden 
+days, every bit counted -- the super cunning thing about 
+Red-Black Trees is that they ensure balancedness, at the 
+throwaway price of a *single bit* per node.
+
+The catch is that the invariants are devilishly tricky.
+
+<!-- more -->
+
+1. **Order:** Each node's value is between those in its left and right subtrees,
+2. **Color:** Each red node's children are colored black,
+3. **Height:** Each root-to-leaf path has the same number of black nodes.
+
+There are ways to encode various subsets of these using 
+GADTs and such, but, like [Appel][RBTappel], I find the 
+encodings rather too clever as they require a variety 
+of different types and constructors to capture each 
+invariant. 
+
+One advantage of refinements is we fix the data type, 
+and can then *pick and choose* which invariants we want
+to verify, and *compose* them, quite trivially, via
+conjunction.
+
+Red Black Trees
+---------------
+
+Lets start with the basic type describing trees.
+
+\begin{code}
+data RBTree a = Leaf 
+              | Node Color a !(RBTree a) !(RBTree a)
+              deriving (Show)
+\end{code}
+
+A tree is either a `Leaf` (an empty set) or a `Node c x l r` where:
+
+* `x` is the value at the node, 
+* `l` and `r` are the left and right subtrees, and
+* `c` is either `B` (black) or `R` (red). 
+
+\begin{code}
+data Color    = B -- ^ Black
+              | R -- ^ Red
+              deriving (Eq,Show)
+\end{code}
+
+Intuitively, the set denoted by a tree is the set of values at 
+the nodes of the tree.
+
+Over the next few posts, we will develop an implementation 
+([based off this][coqRBT]) of a set library using the `RBTree` 
+datatype. In particular, we will implement the API:
+
+\begin{code} <div/>
+empty  :: RBTree a
+member :: a -> RBTree a -> Bool
+insert :: a -> RBTree a -> RBTree a
+delete :: a -> RBTree a -> RBTree a
+toList :: RBTree a -> [a] 
+\end{code}
+
+and will use LiquidHaskell to *directly* and *compositionally* 
+specify and enforce the various invariants.
+
+Continue to:
+
+* [Order][rbtOrder]
+
+Coming soon:
+
+* Color
+* Height
+* Compose
+
+[rbtOrder]   : /blog/2014/04/07/red-black-order.lhs/ 
+
+<!--
+
+* [Color][rbtColor]
+* [Height][rbtHeight]
+* [Compose][rbtAll]
+
+[rbtColor]   : /blog/2014/04/14/red-black-color.lhs/ 
+[rbtHeight]  : /blog/2014/04/21/red-black-height.lhs/ 
+[rbtCompose] : /blog/2014/04/28/red-black-compose.lhs/
+-->
diff --git a/docs/blog/todo/red-black-order.lhs b/docs/blog/todo/red-black-order.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/red-black-order.lhs
@@ -0,0 +1,254 @@
+---
+layout: post
+title: "Red-Black Trees: Order"
+date: 2014-04-05 16:12
+author: Ranjit Jhala
+published: false 
+comments: true
+external-url:
+categories: measures, abstract-refinements 
+demo: RBTree-ord.hs
+---
+
+A data structure that implements a *set* interface, must 
+provide an efficient way to determine *membership*, i.e. 
+a function 
+
+\begin{code}
+member :: a -> RBTree a -> Bool
+\end{code}
+
+where `elem x xs` returns `True` iff `x` is in the set denoted by `xs`.
+
+Red Black trees are use 
+
+To enable effici
+
+Abstract Refinements vs. Indices
+--------------------------------
+
+Most formal accounts of Red Black trees eschew the order 
+invariant as it is rather cumbersome to encode using GADTs
+and indexed-types -- one must index the structure with lower
+and upper bounds, and appropriately adjust these bounds at 
+rotations. 
+
+
+TODO: **Conjoining Specifications** lamport. 
+TODO: composing, and, for example, 
+TODO: red-black trees.
+
+[Red Black trees][RBTwiki] trees are a classic, cold-war era, 
+data structure used to efficiently represent sets, using trees
+whose nodes are labeled by the set's elements, and additionally, 
+are colored *red* or *black*. 
+
+The key to efficiency is that the the trees be *balanced*. 
+
+Of course, the easiest way to do this is to just add a *height* 
+label and check that the difference of heights at each node is 
+bounded (cf. [AVL trees][AVLTwiki]). But, back in the olden 
+days, every bit counted -- the super cunning thing about 
+Red-Black Trees is that they ensure balancedness, at the 
+throwaway price of a *single bit* per node.
+
+The catch is that the invariants are devilishly tricky.
+
+<!-- more -->
+
+1. **Order:** Each node's value is between those in its left and right subtrees,
+2. **Color:** Each red node's children are colored black,
+3. **Height:** Each root-to-leaf path has the same number of black nodes.
+
+There are ways to encode various subsets of these using 
+GADTs and such, but, like [Appel][RBTappel], I find the 
+encodings rather too clever as they require a variety 
+of different types and constructors to capture each 
+invariant. 
+
+One advantage of refinements is we fix the data type, 
+and can then *pick and choose* which invariants we want
+to verify, and *compose* them, quite trivially, via
+conjunction.
+
+Continue to:
+
+* [Order][rbtOrder]
+* [Color][rbtColor]
+* [Height][rbtHeight]
+* [Composition][rbtAll]
+
+[rbtOrder]   : /blog/2014/04/07/red-black-order.lhs/ 
+[rbtColor]   : /blog/2014/04/14/red-black-color.lhs/ 
+[rbtHeight]  : /blog/2014/04/21/red-black-height.lhs/ 
+[rbtCompose] : /blog/2014/04/28/red-black-compose.lhs/
+
+
+Red-Black Trees
+---------------
+
+Abstract Refinements
+--------------------
+
+Ordered Trees
+-------------
+
+
+Over the next several posts, lets see how to develop an
+RBTree library, using LiquidHaskell to directly and 
+compositionally specify and enforce the above invariants.
+
+
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination"   @-}
+module Foo (add, remove, deleteMin, deleteMin') where
+import Language.Haskell.Liquid.Prelude
+\end{code}
+
+</div>
+
+ADD
+
+\begin{code}
+data Color    = B -- ^ Black
+              | R -- ^ Red
+              deriving (Eq,Show)
+\end{code}
+
+\begin{code}
+data RBTree a = Leaf 
+              | Node Color a !(RBTree a) !(RBTree a)
+              deriving (Show)
+\end{code}
+
+---------------------------------------------------------------------------
+-- | Add an element -------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ add :: (Ord a) => a -> ORBT a -> ORBT a @-}
+add x s = makeBlack (ins x s)
+
+{-@ ins :: (Ord a) => a -> ORBT a -> ORBT a @-}
+ins kx Leaf             = Node R kx Leaf Leaf
+ins kx s@(Node B x l r) = case compare kx x of
+                            LT -> let t = lbal x (ins kx l) r in t 
+                            GT -> let t = rbal x l (ins kx r) in t 
+                            EQ -> s
+ins kx s@(Node R x l r) = case compare kx x of
+                            LT -> Node R x (ins kx l) r
+                            GT -> Node R x l (ins kx r)
+                            EQ -> s
+
+---------------------------------------------------------------------------
+-- | Delete an element ----------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ remove :: (Ord a) => a -> ORBT a -> ORBT a @-}
+remove x t = makeBlack (del x t)
+
+{-@ del              :: (Ord a) => a -> ORBT a -> ORBT a @-}
+del x Leaf           = Leaf
+del x (Node _ y a b) = case compare x y of
+   EQ -> append y a b 
+   LT -> case a of
+           Leaf         -> Node R y Leaf b
+           Node B _ _ _ -> lbalS y (del x a) b
+           _            -> let t = Node R y (del x a) b in t 
+   GT -> case b of
+           Leaf         -> Node R y a Leaf 
+           Node B _ _ _ -> rbalS y a (del x b)
+           _            -> Node R y a (del x b)
+
+{-@ append  :: y:a -> ORBT {v:a | v < y} -> ORBT {v:a | y < v} -> ORBT a @-}
+append :: a -> RBTree a -> RBTree a -> RBTree a
+
+append _ Leaf r                               
+  = r
+
+append _ l Leaf                               
+  = l
+
+append piv (Node R lx ll lr) (Node R rx rl rr)  
+  = case append piv lr rl of 
+      Node R x lr' rl' -> Node R x (Node R lx ll lr') (Node R rx rl' rr)
+      lrl              -> Node R lx ll (Node R rx lrl rr)
+
+append piv (Node B lx ll lr) (Node B rx rl rr)  
+  = case append piv lr rl of 
+      Node R x lr' rl' -> Node R x (Node B lx ll lr') (Node B rx rl' rr)
+      lrl              -> lbalS lx ll (Node B rx lrl rr)
+
+append piv l@(Node B _ _ _) (Node R rx rl rr)   
+  = Node R rx (append piv l rl) rr
+
+append piv l@(Node R lx ll lr) r@(Node B _ _ _) 
+  = Node R lx ll (append piv lr r)
+
+---------------------------------------------------------------------------
+-- | Delete Minimum Element -----------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ deleteMin  :: ORBT a -> ORBT a @-}
+deleteMin (Leaf)         = Leaf
+deleteMin (Node _ x l r) = makeBlack t
+  where 
+    (_, t)               = deleteMin' x l r
+
+
+{-@ deleteMin' :: k:a -> ORBT {v:a | v < k} -> ORBT {v:a | k < v} -> (a, ORBT a) @-}
+deleteMin' k Leaf r              = (k, r)
+deleteMin' x (Node R lx ll lr) r = (k, Node R x l' r)   where (k, l') = deleteMin' lx ll lr 
+deleteMin' x (Node B lx ll lr) r = (k, lbalS x l' r )   where (k, l') = deleteMin' lx ll lr 
+
+---------------------------------------------------------------------------
+-- | Rotations ------------------------------------------------------------
+---------------------------------------------------------------------------
+
+lbalS k (Node R x a b) r              = Node R k (Node B x a b) r
+lbalS k l (Node B y a b)              = let t = rbal k l (Node R y a b) in t 
+lbalS k l (Node R z (Node B y a b) c) = Node R y (Node B k l a) (rbal z b (makeRed c))
+lbalS k l r                           = error "nein" 
+
+rbalS k l (Node R y b c)              = Node R k l (Node B y b c)
+rbalS k (Node B x a b) r              = let t = lbal k (Node R x a b) r in t 
+rbalS k (Node R x a (Node B y b c)) r = Node R y (lbal x (makeRed a) b) (Node B k c r)
+rbalS k l r                           = error "nein"
+
+lbal k (Node R y (Node R x a b) c) r  = Node R y (Node B x a b) (Node B k c r)
+lbal k (Node R x a (Node R y b c)) r  = Node R y (Node B x a b) (Node B k c r)
+lbal k l r                            = Node B k l r
+
+rbal x a (Node R y b (Node R z c d))  = Node R y (Node B x a b) (Node B z c d)
+rbal x a (Node R z (Node R y b c) d)  = Node R y (Node B x a b) (Node B z c d)
+rbal x l r                            = Node B x l r
+
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+
+makeRed (Node _ x l r)   = Node R x l r
+makeRed Leaf             = error "nein" 
+
+makeBlack Leaf           = Leaf
+makeBlack (Node _ x l r) = Node B x l r
+
+---------------------------------------------------------------------------
+-- | Specifications -------------------------------------------------------
+---------------------------------------------------------------------------
+
+-- | Ordered Red-Black Trees
+
+{-@ type ORBT a = RBTree <{\root v -> v < root }, {\root v -> v > root}> a @-}
+
+-- | Binary Search Ordering
+
+{-@ data RBTree a <l :: a -> a -> Prop, r :: a -> a -> Prop>
+            = Leaf
+            | Node (c    :: Color)
+                   (key  :: a)
+                   (left :: RBTree <l, r> (a <l key>))
+                   (left :: RBTree <l, r> (a <r key>))
+  @-}
diff --git a/docs/blog/todo/telling-lies-old.lhs b/docs/blog/todo/telling-lies-old.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/telling-lies-old.lhs
@@ -0,0 +1,122 @@
+---
+layout: post
+title: "LiquidHaskell Caught Telling Lies!"
+date: 2013-11-19 16:12
+comments: true
+external-url:
+categories: termination
+author: Niki Vazou
+published: false
+demo: TellingLies.hs
+---
+
+If you used liquidHaskell lately, you may have noticed some type errors that
+just make no sense.
+Well, that is not a bug, but a ... **termination checker** failing to prove that
+your function terminates.
+
+LiquidHaskell, *by default*, performs a termination check while verifying your
+code.
+Of course the tool would be useless if it required all your functions
+to terminate.
+Instead, it just requires that non-terminating functions return unrefined
+results.
+We will shortly explain when and how one can turn off termination checking while preserve
+sound type checking.
+To do so, we should start by explaining why termination is requied. 
+
+<!-- more -->
+
+\begin{code}
+module TellingLies where
+
+import Prelude  hiding (repeat)
+import Language.Haskell.Liquid.Prelude (liquidAssert)
+\end{code}
+
+Why is Termination Analysis Required
+-------------------------------------
+
+Consider a no-terminating function:
+
+\begin{code}
+{-@ foo :: Int -> {v:Int | false} @-}
+foo     :: Int -> Int
+foo n   = foo n
+\end{code}
+
+According to the *partial correctness property*
+the type signature for `foo` means that any
+value `foo` returns will satisfy the result refinement
+`false`. 
+Since `foo` never returns, 
+it can return *none* value, thus it trivially satisfies its
+type.
+
+Now, in an environment where `false` (i.e., `foo`'s result)
+exists, liquidHaskell can prove anything, 
+even the contradiction `0==1`:
+
+\begin{code}
+prop = liquidAssert ((\_ -> 0==1) (foo 0))
+\end{code}
+
+This is totally valid under *eager* evaluation, where
+to execute the assertion one should first compute the argument
+`foo 0` which never returns.
+But, it is not valid under haskell's *lazy* semantics
+where execution ignores the unused argument, and fails.
+
+From the above discussion we see that partial correctness is not enough to
+verify Haskell's lazy code.
+To restore soundness we require *total correctness*, or
+that each function terminates.
+This explains why termination checking is set as default to liquidHaskell (as is
+in many other verifiers, like Coq or Agda.)
+
+Turning off Termination Checking
+--------------------------------
+
+Of course, you cannot prove termination of functions like `repeat`
+
+\begin{code}
+{-@ repeat :: a -> [a] @-}
+repeat     :: a -> [a]
+repeat a   = a : repeat a
+\end{code}
+
+Instead, you can mark `repeat` as `Lazy` to disable termination for these
+functions:
+\begin{code}
+{-@ Lazy repeat @-}
+\end{code}
+
+But, be careful!
+By marking a function as `Lazy` *you* also guarantee that *the result type
+cannot contain inconsistencies*.
+In our previous example, liquidHaskell typechecked the unsafe `prop`, just
+because we marked `foo` (who's return type contains inconsistency) as `Lazy`
+\begin{code}
+{-@ Lazy foo @-}
+\end{code}
+
+Even though it is hard to decide if a type can contain inconsistencies,
+trivially *unrefined types* (or types refined to `true`) cannot ever be resolved
+to `false`.
+In other words, it is always safe to mark as `Lazy` functions with unrefined
+result.
+
+\begin{code}Finally, you have the option to totally disable termination checking, using the `no-termination` flag:
+{-@ LIQUID "--no-termination" @-}
+\end{code}
+
+
+Prevent liquidHaskell from Telling Lies
+---------------------------------------
+
+In this post, we saw why termination is required for sound type checking and when
+it is safe to deactivate it.
+But still, we didn't discuss how to prevent the tool from telling lies, i.e., how
+to actually prove termination.
+Turns out that liquidHaskell is powerful enough to prove
+termination on a great number of functions, but this is a topic of another post.
diff --git a/docs/blog/todo/termination.lhs b/docs/blog/todo/termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/termination.lhs
@@ -0,0 +1,288 @@
+---
+layout: post
+title: "Termination Checking"
+date: 2013-11-18 16:12
+comments: true
+external-url:
+categories: termination
+author: Niki Vazou
+published: false
+demo: Termination.hs
+---
+
+If you used liquidHaskell lately, you may have noticed some type errors that
+just make no sense.
+Well, that is not a bug, but a ... **termination checker** failing to prove that
+your function terminates.
+
+In this post, we present how you can use liquidHaskell to prove termination on
+simple recursive functions and explain why termination is required for sound
+type checking.
+Of course liquidHaskell would be useless if it required that all your functions
+do terminate.
+Instead, it just requires that non-terminating functions return unrefined
+results.
+We will shortly explain how one can turn off termination checking while preserve
+sound type checking.
+
+<!-- more -->
+
+\begin{code}
+module Termination where
+
+import Prelude hiding (sum, (!!), repeat)
+import Data.List      (lookup)
+import Data.Maybe     (fromJust)
+
+import Language.Haskell.Liquid.Prelude (liquidAssert)
+\end{code}
+
+Termination Check with Refinement Types
+---------------------------------------
+
+Consider a `Vec`tor that maps `Int`egers to `Val`ues:
+
+\begin{code}
+type Val   = Int
+data Vec   = V [(Int, Val)]
+
+(!!)       :: Vec -> Int -> Val
+(V a) !! i = case i `lookup` a of {Just v -> v; _ -> 0}
+\end{code}
+
+Let `sum a i` add the `i` first elements of the vector `a`:
+
+\begin{code}
+sum     :: Vec -> Int -> Val
+sum a 0 = 0
+sum a i = (a !! (i-1)) + sum a (i-1)
+\end{code}
+
+Does `sum` terminate?
+We observe that if `i` is not `0` then `sum i` will call `sum (i-1)`, otherwise
+it will return.
+This reasoning suffices to convince ourselves that `sum i` terminates for every
+natural number `i`.
+Formally, we shown that `sum` terminates because a *well-founded metric* (i.e., the
+natural number `i`) is decreasing at each iteration.
+Thus, to ensure termination it suffices to restrict `i` on Natural numbers,
+which we can do with a liquid-type signature.
+\begin{code}
+{-@ sum :: Vec -> Nat -> Val @-}
+\end{code}
+
+LiquidHaskell will apply the same reasoning to prove `sum`
+terminates:
+Conventionally, to typecheck `sum` we would check the body assuming an
+environment
+
+`a:Vec`, `i:Nat`, `sum:Vec -> Nat -> Val`
+
+Instead, we *weaken* the environment to 
+
+`a:Vec`, `i:Nat`, `sum:Vec -> {v:Nat| v < i} -> Val`
+
+Now, the type of `sum` stipulates that it *only* be recursively called with
+`Nat` (so well-founded) values that are *strictly less than* the current parameter `i`. 
+Since its body typechecks in this environment, `sum` terminates for
+every `i` on `Nat`s.
+
+Choosing the correct argument
+-----------------------------
+
+We saw that liquidHaskell can happily check that a Natural number is decreasing
+at each iteration; but it uses a na&#239;ve heuristic to choose which one. 
+For this post we can assume that it always chooses *the first* Integer. 
+
+So, a tail-recursive implementation of `sum`:
+\begin{code}
+{-@ sum' :: Vec -> Val -> Nat -> Val @-}
+sum' :: Vec -> Val -> Int -> Val
+sum' a acc 0 = acc + a!!0 
+sum' a acc i = sum' a (acc + a!!i) (i-1)
+\end{code}
+
+will fail, as liquidHaskell wants to prove that the `acc`umulator is the `Nat`ural
+number that
+decreases at each iteration.
+
+\begin{code}The remedy is simple. We can direct liquidHaskell to the correct argument `i` using a `Decrease` annotation: 
+{-@ Decrease sum' 3 @-}
+\end{code}
+which directs liquidHaskell to check whether the *third*
+argument (i.e., `i`) is decreasing.
+With this hint, liquidHaskell will happily verify that `sum'` is indeed a
+terminating function.
+
+Lexicographic Termination
+-------------------------
+
+Lets complicate the things a little bit.
+To do so, lets compute the `sum` of a 2D `Vec`tor:
+
+\begin{code}
+data Vec2D    = V2D [((Int, Int), Val)]
+
+(!!!)         :: Vec2D -> (Int,Int) -> Val
+(V2D a) !!! i = case i `lookup` a of {Just v -> v; _ -> 0}
+\end{code}
+
+Now we write a `sum2D a n m` function that computes the sum of the first 
+`(n+1) (m+1)` elements of `a`
+
+\begin{code}
+{-@ sum2D :: Vec2D -> Nat -> Nat -> Val @-}
+sum2D :: Vec2D -> Int -> Int -> Val
+sum2D a n m = go n m
+  where 
+    {-@ Decrease go 1 2 @-}
+    go 0 0             = 0
+    go i j | j == 0    =  a!!!(i, 0) + go (i-1) m
+           | otherwise =  a!!!(i, j) + go i (j-1)
+\end{code}
+
+Here there is no decreasing argument, 
+if `j>0`, `j` decreases (line `139`), otherwise `i` decreases (line `138`).
+Though, liquidHaskell succeed in verifying that `sum2D` terminates and the reason
+is our `Decrease go 1 2` annotation.
+This annotation informs the tool that the decreasing measure is the
+*lexicographically ordered* pair `[i,j]`. 
+LiquidHaskell will verify that this pair is indeed decreasing: at each
+iteration either `i` decreases (line `138`) or `i` remains the same and `j`
+decreases (line `139`).
+
+\begin{code}An alternative annotation to express the above decreasing measure is:
+       {-@ go :: i:Nat -> j:Nat -> Val / [i, j] @-}
+\end{code}
+where after the type signature for `go` we write the list of lexicographic
+decreasing *expressions*.
+This mechanism, as we shall see, allows us to prove termination in functions
+where the decreasing measure in a *function* of the arguments.
+
+Decreasing expressions
+----------------------
+Back to our `1D` Vector, 
+we now define a function `sumFromTo a lo hi` that sums the elements form `a!!lo`
+to `a!!hi`:
+
+\begin{code}
+{-@ sumFromTo :: Vec -> lo:Nat -> hi:{v:Nat|v>=lo} -> Val @-}
+sumFromTo :: Vec -> Int -> Int ->  Val
+sumFromTo a lo hi = go lo hi
+  where 
+       {-@ go :: lo:Nat -> hi:{v:Nat|v>=lo} -> Val / [hi-lo] @-}
+        go lo hi | lo == hi  =  a!!lo
+                 | otherwise =  a!!lo + go (lo+1) hi
+\end{code}
+
+No argument is decreasing in this function, 
+but still it does terminate, as at each iteration `lo` is increased and
+execution will terminate when `lo` reaches `hi`.
+Here the decreasing measure is the expression `hi-lo`.
+LiquidHaskell has no way to generate such a measure, but,
+if the user generates it, i.e., by annotating `go`'s signature,
+liquidHaskell will happily check that `lo-hi` is indeed a well-founded measure (as it is
+a natural number) that decreases at each iteration.
+
+
+Powered with decreasing expressions and the `Decrease` hint,
+we can prove termination on a great number of functions 
+ranging from 
+ones defined on recursive data structures
+to mutual recursive ones. 
+Of course, we can never prove termination on non-terminating functions that
+naturally exist on haskell source code.
+So, we postpone 
+proving termination on more interesting functions
+and instead lets see how and when you can safely turn termination check off.
+
+Why is Termination Analysis Required
+-------------------------------------
+
+Consider a no-terminating function:
+
+\begin{code}
+{-@ foo :: Int -> {v:Int | false} @-}
+foo     :: Int -> Int
+foo n   = foo n
+\end{code}
+
+According to the *partial correctness property*
+the type signature for `foo` means that any
+value `foo` returns will satisfy the result refinement
+`false`. 
+Since `foo` never returns, 
+it can return *none* value, thus it trivially satisfies its
+type.
+
+Now, in an environment where `false` (i.e., `foo`'s result)
+exists, liquidHaskell can prove anything, 
+even the contradiction `0==1`:
+
+\begin{code}
+prop = liquidAssert ((\_ -> 0==1) (foo 0))
+\end{code}
+
+This is totally valid under *eager* evaluation, where
+to execute the assertion one should first compute the argument
+`foo 0` which never returns.
+But, it is not valid under haskell's *lazy* semantics
+where execution ignores the unused argument, and fails.
+
+From the above discussion we see that partial correctness is not enough to
+verify Haskell's lazy code.
+To restore soundness we require *total correctness*, or
+that each function terminates.
+This explains why termination checking is set as default to liquidHaskell (as is
+in many other verifiers, like Coq or Agda.)
+
+Turning off Termination Checking
+--------------------------------
+
+Of course, you cannot prove termination of functions like `repeat`
+
+\begin{code}
+{-@ repeat :: a -> [a] @-}
+repeat     :: a -> [a]
+repeat a   = a : repeat a
+\end{code}
+
+Instead, you can mark `repeat` as `Lazy` to disable termination for these
+functions:
+\begin{code}
+{-@ Lazy repeat @-}
+\end{code}
+
+But, be careful!
+By marking a function as `Lazy` *you* also guarantee that *the result type
+cannot contain inconsistencies*.
+In our previous example, liquidHaskell typechecked the unsafe `prop`, just
+because we marked `foo` (who's return type contains inconsistency) as `Lazy`
+\begin{code}
+{-@ Lazy foo @-}
+\end{code}
+
+Even though it is hard to decide if a type can contain inconsistencies,
+trivially *unrefined types* (or types refined to `true`) cannot ever be resolved
+to `false`.
+In other words, it is always safe to mark as `Lazy` functions with unrefined
+result.
+
+\begin{code} Finally, you have the option to totally disable termination checking, using the `no-termination` flag:
+{-@ LIQUID "--no-termination" @-}
+\end{code}
+
+Conclusion
+----------
+
+In this post, 
+
+- We saw how to use liquidHaskell to prove termination of simple recursive
+  functions, and
+
+- We learned why termination is required for sound type checking and when
+  it is safe to deactivate it.
+
+Termination checking may sound a big demand,
+but soon we will see that liquidHaskell is powerful enough to prove
+termination on a great number of functions
diff --git a/docs/blog/todo/text-layout.png b/docs/blog/todo/text-layout.png
new file mode 100644
Binary files /dev/null and b/docs/blog/todo/text-layout.png differ
diff --git a/docs/blog/todo/text-lifecycle.png b/docs/blog/todo/text-lifecycle.png
new file mode 100644
Binary files /dev/null and b/docs/blog/todo/text-lifecycle.png differ
diff --git a/docs/blog/todo/verifying-efficient-sorting-algorithms.lhs b/docs/blog/todo/verifying-efficient-sorting-algorithms.lhs
new file mode 100644
--- /dev/null
+++ b/docs/blog/todo/verifying-efficient-sorting-algorithms.lhs
@@ -0,0 +1,185 @@
+---
+layout: post
+title: "Verifing Efficient Sorting Algorithms"
+date: 2013-02-15 16:12
+comments: true
+external-url:
+categories: abstract-refinements
+author: Niki Vazou
+published: false
+---
+
+
+In this example, we will see how abstract refinements can be used to verify
+complex sorting algorithms, like the ones implemented in `Data.List`.
+
+\begin{code}
+module GhcSort (sort, sort1, sort2) where
+\end{code}
+
+Once again, we defined the type of sorted lists as:
+
+\begin{code}
+{-@ type SList a = [a]<{v: a | (v >= fld)}> @-}
+\end{code}
+
+and we aim to prove that all sorting functions return a list if this type.
+
+QuickSort
+---------
+
+Prelude used to implement the below variant of quicksort, as its sorting algorithm.
+
+First, we define `qsort`:
+\begin{code}
+qsort :: (Ord a) =>  a -> [a] -> [a] -> [a]
+qsort _ []     r = r
+qsort _ [x]    r = x:r
+qsort w (x:xs) r = qpart w x xs [] [] r
+\end{code}
+
+
+In `qsort w ys r`, `r` is a sorted list with values greater than `w` and `ys` is a non-sorted list with values lower or equal to `w`.
+If there is at most one element in `ys`, `qsort` returns the sorted list `ys++r`.
+Otherwise, `ys=(x:xs)`, and to short `ys`, `qsort` choses as _pivot element_ the `x` and calls `qpart`:
+
+\begin{code}
+qpart :: (Ord a) => a -> a -> [a] -> [a] -> [a] -> [a] -> [a]
+qpart w x [] rlt rge r =
+    -- rlt and rge are in reverse order and must be sorted with an
+    -- anti-stable sorting
+    rqsort x rlt (x:rqsort w rge r)
+qpart w x (y:ys) rlt rge r =
+    case compare x y of
+        GT -> qpart w x ys (y:rlt) rge r
+        _  -> qpart w x ys rlt (y:rge) r
+\end{code}
+
+In `qpart w x xs rlt rge r`, `r` is a sorted list with values greater than `w`, all other argument lists are not sorted and their values are less or equal to `w`. Moreover, `rge` (`rlt`) has values greater or equal (less) than the pivot element `x`.
+`qpart` splits `xs` values between `rlt` and `rge` and when there are no more values in `xs` it calls `qsort` on these two lists to recursively sort them.
+But, since `qpart` reverses the order of equal values, it actually calls `rqsort` that behaves similar to `qsort`, apart from reversing once more the order of equal values: 
+
+\begin{code}
+-- rqsort is as qsort but anti-stable, i.e. reverses equal elements
+rqsort :: (Ord a) => a -> [a] -> [a] -> [a]
+rqsort _ []     r = r
+rqsort _ [x]    r = x:r
+rqsort w (x:xs) r = rqpart w x xs [] [] r
+
+rqpart :: (Ord a) => a -> a -> [a] -> [a] -> [a] -> [a] -> [a]
+rqpart w x [] rle rgt r =
+    qsort x rle (x:qsort w rgt r)
+rqpart w x (y:ys) rle rgt r =
+    case compare y x of
+        GT -> rqpart w x ys rle (y:rgt) r
+        _  -> rqpart w x ys (y:rle) rgt r
+\end{code}
+
+Finally, to sort a list `ls` we have to call `qsort` with an empty initially sorted list. Also, we have to provide a `w` such that all elements in `ls` are less or equal to `w`. So, we have the sorting function:
+
+\begin{code}
+{-@ sort1 :: (Ord a) => w:a -> ls:[{v:a|v<=w}] -> SList a @-}
+sort1 :: (Ord a) => a -> [a] -> [a]
+sort1 w ls = qsort w ls []
+\end{code}
+
+We note that the `w` that appears in all functions is a ``ghost'' variable that we added so we can prove the correctness of the function. In other words, `w` is not actually used by the functions, but it is needed so that we can prove that always any value in the sorted list `r` is greater than any value in the other lists.
+
+
+
+Mergesort
+---------
+In 2002, Ian Lynagh proposed that GHC should use a sorting algorithm with nlogn worst case performance, so he proposed proposed the below mergesort function:
+
+
+\begin{code}
+mergesort :: (Ord a) => [a] -> [a]
+mergesort = mergesort' . map wrap
+
+mergesort' :: (Ord a) => [[a]] -> [a]
+mergesort' [] = []
+mergesort' [xs] = xs
+mergesort' xss = mergesort' (merge_pairs xss)
+
+merge_pairs :: (Ord a) => [[a]] -> [[a]]
+merge_pairs [] = []
+merge_pairs [xs] = [xs]
+merge_pairs (xs:ys:xss) = merge xs ys : merge_pairs xss
+
+merge :: (Ord a) => [a] -> [a] -> [a]
+merge [] ys = ys
+merge xs [] = xs
+merge (x:xs) (y:ys)
+ = case x `compare` y of
+        GT -> y : merge (x:xs)   ys
+        _  -> x : merge    xs (y:ys)
+
+wrap :: a -> [a]
+wrap x = [x]
+\end{code}
+
+This is a usual merge sort function: Initially each element of the list is wrapped in an one-element list. So, a list of sorted lists in constructed and applied to `mergesort'`. `mergesort'` is always called on list of sorted lists, so if its argument has zero or one elements it trivially returns a sorted list, otherwise it merges all consequtive pairs, with `merge_pairs`, and recursivelly calls itself. In the same way, `merge_pairs` either returns a trivially sorted list, or it merges two consequtive lists and recursivelly calls itself on the rest. Finally, two sorted lists are merged by `merge` in the expected way.
+
+
+Without any code modifications, our system can prove that all invariants are kept, and ultimately `mergesort` returns a sorted list:
+
+\begin{code}
+{-@ sort2 :: (Ord a) => [a] -> SList a @-}
+sort2 :: (Ord a) => [a] -> [a]
+sort2 = mergesort
+\end{code}
+
+
+Official GHC Sort
+-----------------
+In 2009 `mergesort` was replaced by the bellow function, which is similar to "A smooth applicative merge sort", as proposed in 1982 by Richard O'Keefe:
+
+First we define `descending a as bs`, that has the invariant tha all values in `as` are greater than `a` and returns a list whose first element is the greatest descending prefix list in `bs`, reversed. 
+
+\begin{code}
+descending a as (b:bs)
+  | a `compare` b == GT = descending b (a:as) bs
+descending a as bs      = (a:as): sequences bs
+\end{code}
+
+Then we define `ascending a as bs`, that has the invariant tha all arguments of `as` are greater than or equal to `a` and returns a list whose first element is the greatest ascending prefix list in `bs`. To avoid reversing this sublist, `as` is not a list, but a function that every time stores the beggining of the lists and expects its ending.
+
+\begin{code}  
+ascending a as (b:bs)
+  | a `compare` b /= GT = ascending b (\ys -> as (a:ys)) bs
+ascending a as bs       = as [a]: sequences bs
+\end{code}
+
+Since, an arbitrary list can be split in consecutive ascending or descending sublists we define the function `sequences ls` that recursively uses `ascending` and `descending` to split `ls` in these sublists.
+
+\begin{code}
+sequences (a:b:xs)
+  | a `compare` b == GT = descending b [a]  xs
+  | otherwise           = ascending  b (a:) xs
+sequences [x] = [[x]]
+sequences []  = [[]]
+\end{code}
+
+Then, we define a `mergeAll` function that merges sorted lists: 
+
+\begin{code}
+mergeAll [x] = x
+mergeAll xs  = mergeAll (mergePairs xs)
+
+mergePairs (a:b:xs) = merge a b: mergePairs xs
+mergePairs [x]      = [x]
+mergePairs []       = []
+\end{code}
+
+Finally, we define the sorting function that applies `mergeAll` to the result of `sequences` applied in the initial list.
+
+\begin{code}
+{-@ sort :: (Ord a) => [a] -> SList a @-}
+sort :: (Ord a) => [a] -> [a]
+sort = mergeAll . sequences
+\end{code}
+
+Our system can again prove that all the above invariants hold, and `sort` produces a sorted list.
+
+We have to note that the initial ghc functions take comparing function as an argument. But to prove sortedness, we have to transfer the information we get from comparison to the type system. So we actually modified all the above code, by inlining the `compare` function instead of passing it as an argument.
+
diff --git a/docs/language/Makefile b/docs/language/Makefile
new file mode 100644
--- /dev/null
+++ b/docs/language/Makefile
@@ -0,0 +1,55 @@
+TARGET= main
+
+TECH=main
+URL=nvazou@goto.ucsd.edu:~/public_html/lazytechreport.pdf
+
+STY = liquidHaskell.sty commands.sty
+TEX = main.tex language.tex typeInference.tex 
+BIB = sw.bib
+CLS = sigplanconf.cls
+SRCFILES = Makefile ${TEX} ${STY} ${CLS}
+
+
+all: ${TEX}
+	pdflatex main
+	bibtex main
+	pdflatex main
+	bibtex main
+	pdflatex main
+
+tech: ${SRCFILES}
+	cp $(SHOWPROOFS) $(PROOFCNF)
+	pdflatex ${TECH}
+	bibtex ${TECH}
+	pdflatex ${TECH}
+	bibtex ${TECH}
+	pdflatex ${TECH}
+	cp $(HIDEPROOFS) $(PROOFCNF)
+
+
+uploadtech: ${TECH}.pdf
+	scp ${TECH}.pdf ${URL}
+withproofs:
+	cp $(SHOWPROOFS) $(PROOFCNF)
+
+noproofs:
+	cp $(HIDEPROOFS) $(PROOFCNF)
+
+clean:
+	$(RM) *.log *.aux *.ps *.dvi *.bbl *.blg *.bak *.fdb_latexmk *.out *~ proofs/*.log
+
+reallyclean: clean
+	$(RM) *.ps *.pdf
+
+distclean: reallyclean
+
+pdfshow: $(TARGET).pdf
+	xpdf $(TARGET).pdf
+
+acroshow: $(TARGET).pdf
+	acroread $(TARGET).pdf
+
+pack: reallyclean
+	tar cvfz liquidHaskell_tex.tar.gz ${SRCFILES}
+
+PHONY : ps all clean reallyclean distclean
diff --git a/docs/language/commands.sty b/docs/language/commands.sty
new file mode 100644
--- /dev/null
+++ b/docs/language/commands.sty
@@ -0,0 +1,41 @@
+\usepackage[usenames,dvipsnames]{xcolor}
+
+%% \def\mynote#1{{\sf $\clubsuit$ #1$\clubsuit$}}
+%% \def\RJ#1{\textcolor{Red}{\sf RJ:$\clubsuit$ #1$\clubsuit$}}
+%% \def\NV#1{\textcolor{Plum}{\sf NV:$\clubsuit$ #1$\clubsuit$}}
+\def\NV#1{\textcolor{Green}{\sf NV:$\clubsuit$ #1$\clubsuit$}}
+%% \def\ES#1{\textcolor{Blue}{\sf ES:$\clubsuit$ #1$\clubsuit$}}
+
+
+\def\myex#1{\smallskip\noindent{\emphbf{Example: {#1}.}}}
+\newcommand\spara[1]{\smallskip\noindent\textbf{\emph{#1}}\xspace}
+\newcommand\mypara[1]{\spara{#1}}
+%\def\mypara#1{\smallskip\noindent\textbf{#1.}\ }
+
+
+
+\newcommand\etc{\textit{etc.}\xspace}
+\newcommand\eg{\textit{e.g.}\xspace}
+\newcommand\ie{\textit{i.e.}\xspace}
+\newcommand\ala{\textit{a la}\xspace}
+\newcommand\etal{\textit{et al.}\xspace}
+
+\def\emphbf#1{\textbf{\emph{#1}}}
+\def\spmid{\ \mid \ }
+
+\def\colon{\ensuremath{\text{:}}}
+
+\newcommand{\relDescription}[1]{\ensuremath{\textrm{\textbf{#1}}}}
+\newcommand{\judgementHead}[2]{\ensuremath{\relDescription{#1}\hfill\fbox{#2}}}
+\newcommand{\judgementHeadNameOnly}[1]{\ensuremath{\relDescription{#1}\hfill}}
+
+\newenvironment{sitemize}{\begin{list}
+   {$\bullet$}
+   {\setlength{\topsep}{0pt}
+    \setlength{\itemsep}{0pt}
+    \setlength{\leftmargin}{15pt}
+    }
+  }
+  {\end{list}}
+
+
diff --git a/docs/language/haskellListings.tex b/docs/language/haskellListings.tex
new file mode 100644
--- /dev/null
+++ b/docs/language/haskellListings.tex
@@ -0,0 +1,113 @@
+\usepackage{listings}
+
+% uncomment next line to restore colors
+% \def\withcolor{}
+
+\ifdefined\withcolor
+	\definecolor{haskellblue}{rgb}{0.0, 0.0, 1.0}
+	\definecolor{haskellblue}{rgb}{1.0, 0.0, 0.0}
+	\definecolor{gray_ulisses}{gray}{0.55}
+	\definecolor{castanho_ulisses}{rgb}{0.71,0.33,0.14}
+	\definecolor{preto_ulisses}{rgb}{0.41,0.20,0.04}
+	\definecolor{green_ulisses}{rgb}{0.0,0.4,0.0}
+\else
+	\definecolor{haskellblue}{gray}{0.1}
+	\definecolor{haskellred}{gray}{0.1}
+	\definecolor{gray_ulisses}{gray}{0.1}
+	\definecolor{castanho_ulisses}{gray}{0.1}
+	\definecolor{preto_ulisses}{gray}{0.1}
+	\definecolor{green_ulisses}{gray}{0.1}
+\fi
+
+
+\def\codesize{\normalsize}
+
+\lstdefinelanguage{HaskellUlisses} {
+	basicstyle=\ttfamily\codesize,
+	sensitive=true,
+	morecomment=[l][\color{gray_ulisses}\ttfamily\codesize]{--},
+	%% morecomment=[s][\color{gray_ulisses}\ttfamily\codesize]{\{-}{-\}},
+	morestring=[b]",
+	stringstyle=\color{haskellred},
+	showstringspaces=false,
+	numberstyle=\codesize,
+	numberblanklines=true,
+	showspaces=false,
+	breaklines=true,
+	showtabs=false,
+	emph=
+	{[1]
+		FilePath,IOError,abs,acos,acosh,all,and,any,appendFile,approxRational,asTypeOf,asin,
+		asinh,atan,atan2,atanh,basicIORun,break,catch,ceiling,chr,compare,concat,concatMap,
+		const,cos,cosh,curry,cycle,decodeFloat,denominator,digitToInt,div,divMod,drop,
+		dropWhile,either,elem,encodeFloat,enumFrom,enumFromThen,enumFromThenTo,enumFromTo,
+		error,even,exp,exponent,fail,filter,flip,floatDigits,floatRadix,floatRange,floor,
+		fmap,foldl,foldl1,foldr,foldr1,fromDouble,fromEnum,fromInt,fromInteger,
+		fromRational,fst,gcd,getChar,getContents,getLine,head,id,inRange,index,init,intToDigit,
+		interact,ioError,isAlpha,isAlphaNum,isAscii,isControl,isDenormalized,isDigit,isHexDigit,
+		isIEEE,isInfinite,isLower,isNaN,isNegativeZero,isOctDigit,isPrint,isSpace,isUpper,iterate,
+		last,lcm,length,lex,lexDigits,lexLitChar,lines,log,logBase,lookup,map,mapM,mapM_,max,
+		maxBound,maximum,maybe,min,minBound,minimum,mod,negate,not,notElem,numerator,odd,
+		or,pi,pred,primExitWith,print,product,properFraction,putChar,putStr,putStrLn,quot,
+		quotRem,range,rangeSize,read,readDec,readFile,readFloat,readHex,readIO,readInt,readList,readLitChar,
+		readLn,readOct,readParen,readSigned,reads,readsPrec,realToFrac,recip,rem,repeat,replicate,
+		reverse,round,scaleFloat,scanl,scanl1,scanr,scanr1,seq,sequence,sequence_,show,showChar,showInt,
+		showList,showLitChar,showParen,showSigned,showString,shows,showsPrec,significand,signum,sin,
+		sinh,snd,span,splitAt,sqrt,subtract,succ,sum,tail,take,takeWhile,tan,tanh,threadToIOResult,toEnum,
+		toInt,toInteger,toLower,toRational,toUpper,truncate,uncurry,undefined,unlines,until,unwords,unzip,
+		unzip3,userError,words,writeFile,zip,zip3,zipWith,zipWith3,listArray,doParse,for,initTo,
+        maxEvens,create,get,set,initialize,idVec,fastFib,fibMemo,
+        insert,union,split,size,fromList,initUpto,trim,quickSort,insertSort,append,upperCase,
+        copy, group, doDownLoop, mapAccumR, peekByteOff,
+        pokeByteOff,spanByte, 
+        good, bad, foo, explode, 
+        fib, ack, 
+        tLen,
+        memcpy,writeChar,unsafeWrite,unsafeFreeze,
+        singleton
+	},
+	emphstyle={[1]\color{haskellblue}},
+	emph=
+	{[2]
+		Bool,Char,Double,Either,Float,IO,Integer,Int,Maybe,Ordering,Rational,Ratio,ReadS,ShowS,String,
+		Word8,Nat,NonZero,Nat64,Text,ByteString,ByteStringSZ,ByteStringN,
+        Ptr,ForeignPtr,CSize
+        InPacket,Tree,Prop,TreeEq,TreeLt,Vec,
+        NullTerm,IncrList,DecrList,UniqList,BST,MinHeap,MaxHeap,
+        PtrN,ByteStringN,ByteStringEq,VO,ByteStringsEq,ByteStringNE
+	},
+	emphstyle={[2]\color{castanho_ulisses}},
+	emph=
+	{[3]
+		case,class,data,deriving,do,else,if,import,in,infixl,infixr,instance,let,
+		module,measure,predicate,of,primitive,then,refinement,type,where
+	},
+	emphstyle={[3]\color{preto_ulisses}\textbf},
+	emph=
+	{[4]
+		quot,rem,div,mod,elem,notElem,seq
+	},
+	emphstyle={[4]\color{castanho_ulisses}\textbf},
+	emph=
+	{[5]
+		PS,Tip,Node,EQ,False,GT,Just,LT,Left,Nothing,Right,True,Show,Eq,Ord,Num
+	},
+	emphstyle={[5]\color{green_ulisses}}
+}
+
+%%%ORIG
+%%%\lstnewenvironment{code}
+%%%{\textbf{Haskell Code} \hspace{1cm} \hrulefill \lstset{language=HaskellUlisses}}
+%%%{\hrule\smallskip}
+
+%V1
+%\lstnewenvironment{code}
+%{\smallskip \lstset{language=HaskellUlisses}}
+%{\smallskip}
+
+\lstnewenvironment{code}
+{\lstset{language=HaskellUlisses}}
+{}
+
+\lstMakeShortInline[language=HaskellUlisses]@
+
diff --git a/docs/language/language.tex b/docs/language/language.tex
new file mode 100644
--- /dev/null
+++ b/docs/language/language.tex
@@ -0,0 +1,82 @@
+
+
+
+\begin{figure}[t!]
+\centering
+$$
+\begin{array}{rrcl}
+\emphbf{Basic Types} \quad
+  & b 
+  & ::=
+  & \alpha
+  \spmid \tfun{x}{\tau}{\tau}
+  \spmid \tcon{C}{\bar{\tau}}{\bar{\ref}}
+  \spmid \tapp{\tau}{\tau}
+  \\[0.05in]
+
+\emphbf{Types} \quad
+  & \tau 
+  & ::=
+  & \tref{v}{b}{\ref}
+  \spmid \tcl{Cl}{\bar{\tau}}
+  \\[0.05in]
+
+\emphbf{Abstract Refinements} \quad
+  & \pi
+  & ::=
+  & \forall \left\langle p \colon \tau \right\rangle . \pi 
+  \spmid \tau
+  \\[0.05in]
+
+\emphbf{Type Schemata} \quad
+  & \sigma
+  & ::=
+  & \tall{\alpha}{\sigma} 
+  \spmid \pi
+  \\[0.05in]
+
+\emphbf{Refinements} \quad
+  & \ref
+  & ::=
+  & (\aref,\cref)
+  \\[0.05in]
+
+\emphbf{Abstract Refinements} \quad
+  & \aref
+  & ::= 
+  &  [] \spmid p\ \bar{e}, \aref
+  \\[0.05in]
+
+\emphbf{Concrete Refinements} \quad
+  & \cref
+  & ::=
+  &  k \sub{x}{e}
+  \spmid \pr
+  \spmid \cref \land \cref
+  \\[0.05in]
+
+\emphbf{Predicates} \quad
+  & \pr
+  & ::=
+  &  \ptrue \spmid \pfalse 
+  \spmid \pand{\bar{\pr}}
+  \spmid \por{\bar{\pr}}
+  \spmid \pnot{\pr}
+  \spmid \pimp{\pr}{\pr}
+  \spmid \piff{\pr}{\pr}
+  \\ && \spmid &  e 
+  \spmid e \left[= \mid \neq \mid > \mid < \mid \geq \mid \leq \right] e
+  \\[0.05in]
+
+\emphbf{Expressions} \quad
+  & e
+  & ::=
+  &  c \spmid n \spmid x \spmid \eapp{c}{\bar{e}} \spmid \eif{\pr}{e}{e} 
+  \spmid e \left[+ \mid - \mid * \mid / \mid \% \right] e 
+
+
+  \end{array}
+$$
+\caption{Syntax of \corelan}
+\label{fig:syntax}
+\end{figure}
diff --git a/docs/language/liquidHaskell.sty b/docs/language/liquidHaskell.sty
new file mode 100644
--- /dev/null
+++ b/docs/language/liquidHaskell.sty
@@ -0,0 +1,199 @@
+\newcommand{\C}{\textsc{C}\xspace}
+\newcommand{\toolname}{\textsc{LiquidHaskell}\xspace}
+%\newcommand{\bytestring}{\textsc{bytestring}\xspace}
+%\newcommand{\libtext}{\textsc{text}\xspace}
+\newcommand{\bytestring}{\texttt{Bytestring}\xspace}
+\newcommand{\libtext}{\texttt{Text}\xspace}
+
+%% 
+
+\newcommand{\CRASH}{\ensuremath{\mathtt{crash}}\xspace}
+\newcommand{\defeq}{\ \doteq\ }
+\providecommand{\dbrkts}[1]{[\![#1]\!]}
+%\newcommand\embed[1]{\dbrkts{#1}}
+\newcommand\embed[1]{\dbrkts{#1}}
+\newcommand\R{\ensuremath{\mathsf{Fin}\xspace}}
+\newcommand\FORCE[1]{#1 \in \R}
+\newcommand\NOFORCE[1]{#1 \not \in \R}
+
+\newcommand\corelan{$\lambda_\downarrow$\xspace}
+\newcommand\ttbind[2]{\ensuremath{\mathtt{#1}:\mathtt{#2}}}
+\newcommand\tbind[2]{{#1} \colon {#2}}
+\newcommand\ttref[1]{\ensuremath{\mathtt{\{#1\}}}}
+\newcommand\ttreft[3]{\ttref{\tbind{#1}{#2}\mid {#3}}}
+
+\newcommand\subt[2]{\ensuremath{#1 \preceq #2}}
+\newcommand\subtref[2]{\subt{\ttref{#1}}{\ttref{#2}}}
+
+\newcommand\hastypet[3]{\ensuremath{#1 \vdash \tbind{#2}{#3}}}
+\newcommand\hastype[3]{\ensuremath{#1 \vdash #2 : #3}}
+
+\newcommand\issubtype[3]{\ensuremath{#1 \vdash #2 \preceq #3}}
+\newcommand\iswellformed[2]{\ensuremath{#1 \vdash #2}}
+\newcommand\wellformedsub[2]{\ensuremath{#1 \models #2}}
+\newcommand\ismodeled[2]{\ensuremath{#1 \models #2}}
+\newcommand\wfmodels[2]{\ismodeled{#1}{#2}}
+
+\newcommand\stepsym{\hookrightarrow}
+\newcommand\stepv{\stepsym_v}
+\newcommand\stepn{\stepsym_n}
+\newcommand\stepo{\stepsym_o}
+
+\newcommand\eval[2]{\evalR{\stepsym}{#1}{#2}}
+\newcommand\evalR[3]{\ensuremath{#2 #1 #3}}
+\newcommand\evalGen[4]{\evalR{\stepsym_{#3}^{#4}}{#1}{#2}}
+
+\newcommand\evalv[2]{\evalGen{#1}{#2}{v}{}}
+\newcommand\evaln[2]{\evalGen{#1}{#2}{n}{}}
+\newcommand\evalo[2]{\evalGen{#1}{#2}{o}{}}
+\newcommand\evalvs[2]{\evalGen{#1}{#2}{v}{*}}
+\newcommand\evalns[2]{\evalGen{#1}{#2}{n}{*}}
+\newcommand\evalos[2]{\evalGen{#1}{#2}{o}{*}}
+
+% termination eval
+\newcommand\evalt[3]{\evalGen{#1}{#2}{o}{#3}}
+\newcommand\evalts[2]{\evalGen{#1}{#2}{o}{*}}
+
+
+
+
+
+
+\newcommand\sub[2]{\ensuremath{\left[#2/#1\right]}}
+%\newcommand\sub[2]{\ensuremath{\left[#1 \mapsto #2\right]}}
+\newcommand{\SUBST}[3]{{#1}\sub{#2}{#3}}
+
+\newcommand\shape{\ensuremath{\text{shape}}\xspace}
+\newcommand\termincon[1]{\ensuremath\textcolor{Red}{#1}}
+
+%TT
+\newcommand\Env{\Gamma}
+
+\newcommand\ttack{\mathtt{ack}}
+
+\newcommand\tttLen{\mathtt{tLen}}
+\newcommand\ttsz{\mathtt{sz}}
+\newcommand\ttt{\mathtt{t}}
+\newcommand\tttp{\mathtt{t'}}
+\newcommand\ttb{\mathtt{b}}
+\newcommand\tta{\mathtt{a}}
+\newcommand\ttm{\mathtt{m}}
+\newcommand\ttmp{\mathtt{m'}}
+\newcommand\ttnp{\mathtt{n'}}
+\newcommand\ttn{\mathtt{n}}
+\newcommand\ttp{\mathtt{p}}
+\newcommand\ttv{\mathtt{v}}
+\newcommand\ttx{\mathtt{x}}
+\newcommand\tty{\mathtt{y}}
+\newcommand\ttz{\mathtt{z}}
+\newcommand\tte{\mathtt{e}}
+\newcommand\ttf{\mathtt{e}}
+\newcommand\ttg{\mathtt{e}}
+\newcommand\ttInt{\mathtt{Int}}
+\newcommand\ttNonzero{\mathtt{NonZero}}
+\newcommand\ttNat{\mathtt{Nat}}
+\newcommand\ttfib{\mathtt{fib}}
+
+% MISC 
+
+\newcommand\smtvalid[1]{\ensuremath{\mathsf{SmtValid}(#1)}}
+\newcommand\strict{\ensuremath{\mathsf{Trivial}}}
+\newcommand\constty[1]{\ensuremath{\mathsf{Ty}(#1)}}
+\newcommand\serious{serious\xspace}
+\newcommand\trivial{trivial\xspace}
+
+
+% Expressions
+\newcommand\efun[3]{\ensuremath{\lambda #1. #3}}
+\newcommand\eapp[2]{\ensuremath{#1 \ #2}}
+\newcommand\eif[3]{\ensuremath{\mathtt{if}\ #1\ \mathtt{then}\ #2\ \mathtt{else}\ #3}}
+\newcommand\elet[3]{\ensuremath{\mathtt{let}\ #1 = #2\ \mathtt{in}\ #3}}
+\newcommand\erec[3]{\ensuremath{\mu #1.\lambda #2. #3}}
+\newcommand\etabs[2]{\ensuremath{\left[\Lambda #1\right] #2}}
+\newcommand\etapp[2]{\ensuremath{#1 \left[ #2 \right]}}
+\newcommand\etrue{\ensuremath{\mathtt{true}}\xspace}
+\newcommand\efalse{\ensuremath{\mathtt{false}}\xspace}
+\newcommand\eletsub[2]{\ensuremath{#1 #2}}
+
+%Labels
+\newcommand\ltop{\ensuremath{\downarrow}\xspace}
+\newcommand\lbot{\ensuremath{\uparrow}\xspace}
+
+% Types
+\newcommand\tbool{\ensuremath{\mathtt{bool}}\xspace}
+\newcommand\tint{\ensuremath{\mathtt{nat}}\xspace}
+\newcommand\tref[4]{\ensuremath{\{ \tbind{#1}{#2^{#3}} \mid #4 \}}}
+\newcommand\tfun[3]{\ensuremath{\tbind{#1}{#2} \rightarrow #3}}
+\newcommand\tabs[2]{\ensuremath{\forall #1 . #2}}
+
+%Rule Names
+\newcommand\rulename[1]{\textsc{#1}\xspace}
+\newcommand{\rtsub}{\rulename{T-Sub}}
+\newcommand{\rtvara}{\rulename{T-Var-Base}}
+\newcommand{\rtvarb}{\rulename{T-Var}}
+\newcommand{\rtconst}{\rulename{T-Con}}
+\newcommand{\rtfun}{\rulename{T-Fun}}
+\newcommand{\rtapp}{\rulename{T-App}}
+\newcommand{\rtappa}{\rulename{T-App-$\lbot$}}
+\newcommand{\rtappb}{\rulename{T-App-$\ltop$}}
+\newcommand{\rtif}{\rulename{T-If}}
+\newcommand{\rtlet}{\rulename{T-Let}}
+\newcommand{\rtgen}{\rulename{T-Gen}}
+\newcommand{\rtinst}{\rulename{T-Inst}}
+\newcommand{\rtrec}{\rulename{T-Rec}}
+\newcommand{\rtrecs}{\rulename{T-Rec-$\lbot$}}
+\newcommand{\rtrect}{\rulename{T-Rec-$\ltop$}}
+%% \newcommand{\rtrecs}{\rulename{TR-Ser}}
+%% \newcommand{\rtrect}{\rulename{TR-Tr}}
+
+\newcommand{\rsbasetop}{\rulename{$\preceq$-Base-$\ltop$}}
+\newcommand{\rsbasebot}{\rulename{$\preceq$-Base-$\lbot$}}
+\newcommand{\rsvar}{\rulename{$\preceq$-Var}}
+\newcommand{\rsfun}{\rulename{$\preceq$-Fun}}
+\newcommand{\rspoly}{\rulename{$\preceq$-Poly}}
+
+\newcommand{\rwbasetop}{\rulename{WF-Base-$\ltop$}}
+\newcommand{\rwbasebot}{\rulename{WF-Base-$\lbot$}}
+\newcommand{\rwbase}{\NV{TODO}}
+\newcommand{\rwvar}{\rulename{WF-Var}}
+\newcommand{\rwfun}{\rulename{WF-Fun}}
+\newcommand{\rwpoly}{\rulename{WF-Poly}}
+
+\newcommand{\rwsempty}{\rulename{WS-Empty}}
+\newcommand{\rwsext}{\rulename{WS-Ext}}
+\newcommand{\rwsgxt}{\rulename{WS-Gxt}}
+
+
+\newcommand{\reapp}{\rulename{E-AppL}}
+\newcommand{\reappb}{\rulename{E-App}}
+\newcommand{\reappc}{\rulename{E-AppT}}
+\newcommand{\reappd}{\rulename{E-AppTB}}
+\newcommand{\reconsta}{\rulename{E-ConstA}}
+\newcommand{\reconstb}{\rulename{E-Con}}
+\newcommand{\reif}{\rulename{E-If}}
+\newcommand{\reiftrue}{\rulename{E-If-True}}
+\newcommand{\reiffalse}{\rulename{E-If-False}}
+\newcommand{\rereca}{\rulename{E-Rec}}
+\newcommand{\rerecb}{\NV{UNIFIED}}
+\newcommand{\rerecc}{\rulename{E-RecC}}
+\newcommand{\reinst}{\NV{TODO}}
+\newcommand{\reinsta}{\rulename{E-InstA}}
+\newcommand{\reinstb}{\rulename{E-InstB}}
+\newcommand{\reinstc}{\rulename{E-InstC}}
+\newcommand{\releta}{\rulename{E-Let}}
+\newcommand{\reletb}{\rulename{E-LetX}}
+\newcommand{\recntx}{\rulename{E-Com}}
+\newcommand{\reletc}{\rulename{E-LetTB}}
+
+%%%%%%%% TABLE
+
+\newcommand\bfModule{\textbf{Module}\xspace}
+\newcommand\bfAnnot{\textbf{Annot}\xspace}
+\newcommand\bfQualif{\textbf{Qualif}\xspace}
+\newcommand\bfLOC{\textbf{LOC}\xspace}
+\newcommand\bfSpecs{\textbf{Specs}\xspace}
+\newcommand\bfLetRec{\textbf{Rec}\xspace}
+\newcommand\bfMutRec{\textbf{Mut}\xspace}
+\newcommand\bfHint{\textbf{Hint}\xspace}
+\newcommand\bfWitness{\textbf{Wit}\xspace}
+
diff --git a/docs/language/main.pdf b/docs/language/main.pdf
new file mode 100644
Binary files /dev/null and b/docs/language/main.pdf differ
diff --git a/docs/language/main.tex b/docs/language/main.tex
new file mode 100644
--- /dev/null
+++ b/docs/language/main.tex
@@ -0,0 +1,110 @@
+\documentclass[10pt,a4paper]{article}
+
+%\documentclass{llncs}
+%\documentclass[nocopyrightspace]{sigplanconf}
+%%% \usepackage[top=1.5cm,bottom=1.5cm,left=2.3cm,right=2cm]{geometry}
+
+\pagestyle{plain}
+\usepackage{times}
+%\usepackage[nocompress]{cite} % AR: comment this out if you wish hyperrefs 
+\usepackage{hyperref}
+
+\usepackage{amsmath,amssymb, latexsym}
+
+\usepackage{amsmath}
+\usepackage{amsthm}
+
+\newtheorem{lemma}{Lemma}
+\newtheorem{theorem}{Theorem}
+\newtheorem*{theorem*}{Theorem}
+\newtheorem{definition}{Definition}
+\newtheorem*{lemma*}{Lemma}
+
+\usepackage{amsfonts}
+\usepackage{amssymb}
+
+\usepackage{commands}
+\usepackage{liquidHaskell}
+\usepackage[inference]{semantic}
+
+\usepackage{enumerate}
+\def\url{}
+\usepackage{xspace}
+\usepackage{epsfig}
+\usepackage{booktabs}
+\usepackage{listings}
+\usepackage{comment}
+\usepackage{ifthen}
+
+\newcommand{\isTechReport}{false} % true or false
+\newcommand{\includeProof}[1]{
+  \ifthenelse{\equal{\isTechReport}{true}}{
+    #1
+  }{
+  }
+}
+
+%%%%%\usepackage{fancyvrb}
+%%%%%\DefineVerbatimEnvironment{code}{Verbatim}{fontsize=\small}
+%%%%%\DefineVerbatimEnvironment{example}{Verbatim}{fontsize=\small}
+%%%%%\newcommand{\ignore}[1]{}
+
+% command to end a proof or definition:
+%\def\qed{\rule{0.4em}{1.4ex}}
+\def\qed{\hfill$\Box$}
+
+% space at the beginning of an environment:
+\def\@envspa{\hspace{0.3em}}
+\def\@sa{\hspace{-0.2em}}
+\def\@sb{\hspace{0.5em}}
+\def\@sc{\hspace{-0.1em}}
+
+\def\sk{\smallskip}		% space before and after theorems
+
+\newtheorem{notation}{Notation}{\itshape}{}
+\newtheorem{invariant}{Invariant}
+\newtheorem*{hypothesis}{Hypothesis}
+
+\input{haskellListings}
+
+
+\begin{document}
+%% BEGIN MOVE 
+% these are mostly redefined commands, move them to commands
+
+\renewcommand\tref[3]{\ensuremath{\{#1 : #2 \mid #3 \}}}
+\renewcommand\tfun[3]{\ensuremath{#1 : #2 \rightarrow #3}}
+\newcommand\tcon[3]{\ensuremath{#1 \ #2 \ #3}}
+\newcommand\tapp[2]{\ensuremath{#1 \ #2}}
+\newcommand\tall[2]{\ensuremath{ \forall #1 .  #2}}
+\newcommand\tcl[2]{\ensuremath{#1 \ #2}}
+\renewcommand\ref{r}
+\newcommand\pr{pr}
+\newcommand\aref{ar}
+\newcommand\cref{cr}
+
+\newcommand\ptrue{\ensuremath{true}}
+\newcommand\pfalse{\ensuremath{false}}
+\newcommand\pand[1]{\ensuremath{\bigwedge \ #1}}
+\newcommand\por[1]{\ensuremath{\bigvee \ #1}}
+\newcommand\pnot[1]{\ensuremath{\lnot #1}}
+\newcommand\pimp[2]{\ensuremath{#1 \Rightarrow #2}}
+\newcommand\piff[2]{\ensuremath{#1 \Leftrightarrow #2}}
+
+\renewcommand\eapp[2]{\ensuremath{#1 \ #2}}
+\renewcommand\eif[3]{\ensuremath{if \ #1 \ then \ #2 \ else \ #3}}
+\renewcommand\corelan{\texttt{liquidHaskell}}
+
+%% END MOVE
+
+% \maketitle
+
+\input{language}
+\input{typeInference}
+
+% {
+% \bibliographystyle{plain}
+% \bibliography{sw}
+% }
+
+\end{document}
diff --git a/docs/language/typeInference.tex b/docs/language/typeInference.tex
new file mode 100644
--- /dev/null
+++ b/docs/language/typeInference.tex
@@ -0,0 +1,325 @@
+\renewcommand\hastype[4]{\ensuremath{#1 \vdash #2 \uparrow #3 ; #4}}
+\newcommand\checktype[4]{\ensuremath{#1 \vdash #2 \downarrow #3 ; #4}}
+\newcommand\hastypealt[5]{\ensuremath{#1 ; #2 \downarrow #3 \colon #4 ; #5}}
+\newcommand\ty[1]{\ensuremath{ty(#1)}}
+
+\NV{TODO : \\
+1. Add termination checker.}
+
+\section*{Constraint Generation (without the termination checker)}
+
+\hfill\textbf{Type synthesis}\qquad\mbox{\hastype{\Gamma}{e}{\sigma}{C}}
+
+
+$$
+\inference{
+	(x, \tref{v}{b}{e}) \in \Gamma
+}{
+	\hastype{\Gamma}{x}{\tref{v}{b}{e \land x = v}}{\emptyset}
+}
+\qquad
+\inference{
+	(x, \sigma \in \Gamma) &&
+	\sigma \neq \tref{v}{b}{e}
+}{
+	\hastype{\Gamma}{x}{\sigma}{\emptyset}
+}
+$$
+
+$$
+\inference{
+}{
+	\hastype{\Gamma}{c}{\tref{v}{\ty{c}}{v = c}}{\emptyset}
+}
+$$
+
+\newcommand\wfc[2]{\ensuremath{\texttt{WfC}\ #1 \ #2}}
+\newcommand\subc[3]{\ensuremath{\texttt{SubC}\ #1 \ #2\ #3}}
+\newcommand\freshty[1]{\ensuremath{freshTy(#1)}}
+\newcommand\truety[1]{\ensuremath{trueTy(#1)}}
+\newcommand\truetyExpr[1]{\ensuremath{trueTyExpr(#1)}}
+\newcommand\isGenericty[2]{\ensuremath{isGeneric(#1, #2)}}
+\newcommand\freshPredsty[1]{\ensuremath{freshPreds(\Gamma, #1)}}
+\newcommand\varTemplate[1]{\ensuremath{varTemplate(#1)}}
+\newcommand\dataconty[2]{\ensuremath{dataConTy(#1, #2)}}
+
+$$
+\inference{
+	\hastype{\Gamma}{e}{\tall{\alpha}{\sigma}}{C} \\
+	\tau' = if\ \isGenericty{\alpha}{\sigma}\ then\ \freshty{\tau}\ else\ \truety{\tau}
+}{
+	\hastype{\Gamma}{\etapp{e}{\tau}}{\sigma\sub{\alpha}{\tau'}}{(\wfc{\Gamma}{\tau'}, C)}
+}
+$$
+
+$$
+\inference{
+	\hastype{\Gamma}{e_1}{\tau_1}{C_1} &&
+	\checktype{\Gamma}{e_2}{\tau_x}{C_2} &&\\
+	(\tau_1', C_p) = \freshPredsty{\tau_1} &&
+	\tfun{x}{\tau_x}{\tau} = \tau_1'
+}{
+	\hastype{\Gamma}{\eapp{e_1}{e_2}}{\tau\sub{x}{e_2}}
+			{(C_1, C_2, C_p)}
+}
+$$
+
+
+$$
+\inference{
+	\hastype{\Gamma}{e}{\sigma}{C}
+}{
+	\hastype{\Gamma}{\etabs{\alpha}{e}}{\tall{\alpha}{\sigma}}{C}
+}
+$$
+
+$$
+\inference{
+	\hastype{\Gamma, x : \tau_x}{e}{\tau}{C} &&
+	t_x = freshty(varType\ x)
+}{
+	\hastype{\Gamma}{(\efun{x}{}{e})}{(\tfun{x}{\tau_x}{\tau})}{(\wfc{\Gamma}{\tau_x}, C)}
+}
+$$
+
+$$
+\inference{
+	\hastype{\Gamma}{e}{\sigma}{C}
+}{
+	\hastype{\Gamma}{Tick\ t\ e}{\sigma}{C}
+}
+$$
+
+$$
+\inference{
+}{
+	\hastype{\Gamma}{Cast\ e\ c}{\truetyExpr{Cast\ e\ c}}{\emptyset}
+}
+$$
+
+$$
+\inference{
+}{
+	\hastype{\Gamma}{Coercion\ c}{\truetyExpr{Coercion\ c}}{\emptyset}
+}
+$$
+
+$$
+\inference{
+	\sigma = \freshty{e} &&
+	\checktype{\Gamma}{\elet{{x_i}}{e_{x_i}}{e}}{\sigma}{C}
+}{
+	\hastype{\Gamma}{\elet{{x_i}}{e_{x_i}}{e}}{\sigma}{(\wfc \Gamma \sigma, C)}
+}
+$$
+
+$$
+\inference{
+	\sigma = \freshty{e} &&
+	\checktype{\Gamma}{Case\ e\ x\ alt_i}{\sigma}{C}
+}{
+	\hastype{\Gamma}{Case\ e\ x\ alt_i}{\sigma}{(\wfc \Gamma \sigma, C)}
+}
+$$
+
+
+
+\hfill\textbf{Type checking}\qquad\mbox{\checktype{\Gamma}{e}{\sigma}{C}}
+
+
+
+
+%% This rule allows more general types for let binds.
+%% Eg. (tests/pos/meas1.hs)
+%% goo x = [x] :: a -> {v:[a] | ((null v) <=> false)} -- by default
+%% this rule also allows 
+%% goo :: a -> {v:[a] | ((len v) > 0)}
+
+\newcommand\userType[1]{\ensuremath{userType(#1)}}
+
+$$
+\inference{
+	\tau_x  = userTypes(x) &&
+	\checktype{\Gamma}{e_x}{\tau_x}{C_x} \\&&
+	\checktype{\Gamma, x\colon\tau_x}{e}{\sigma}{C}
+}{
+	\checktype{\Gamma}{\elet{x}{e_x}{e}}{\sigma}{(C_x,C)}
+}
+$$
+
+$$
+\inference{
+	x \notin userTypes &&
+	\hastype{\Gamma}{e_x}{\tau_x}{C_x} \\&&
+	\checktype{\Gamma, x\colon\tau_x}{e}{\sigma}{C}
+}{
+	\checktype{\Gamma}{\elet{x}{e_x}{e}}{\sigma}{(C_x,C)}
+}
+$$
+
+$$
+\inference{
+	\checktype{\Gamma, \overline{{x_i} : \tau_{x_i}}}{e}{\sigma}{C} &&\\
+	(C_{x_i}, \tau_{x_i}) = \varTemplate{x_i} &&
+	\checktype{\Gamma, \overline{{x_i} : \tau_{x_i}}}{e_{x_i}}{\tau_{x_i}}{C_{x_i}'}
+}{
+	\hastype{\Gamma}{\elet{{x_i}}{e_{x_i}}{e}}{\sigma}{(C_{x_i}, C_{x_i}', C)}
+}
+$$
+
+$$
+\inference{
+	\hastype{\Gamma}{e}{\tau_x}{C_x} &&
+	\hastypealt{(\Gamma, x:\tau_x)}{x}{alt_i}{\sigma}{C_i}
+}{
+	\checktype{\Gamma}{Case\ e\ x\ alt_i}{\sigma}{(C_x, C_i)}
+}
+$$
+
+$$
+\inference{
+	\checktype{\Gamma}{e}{\sigma\sub{\alpha'}{\alpha}}{C}
+}{
+	\checktype{\Gamma}{\etabs{\alpha}{e}}{\tall{\alpha'}{\sigma}}{C}
+}
+$$
+
+$$
+\inference{
+	\checktype{\Gamma, x : \tau_y}{e}{\tau\sub{y}{x}}{C}
+}{
+	\checktype{\Gamma}{\efun{x}{\tau}{e}}{(\tfun{y}{\tau_y}{\tau})}{C}
+}
+$$
+
+$$
+\inference{
+	\checktype{\Gamma}{e}{\sigma}{C}
+}{
+	\checktype{\Gamma}{Tick\ t\ e}{\sigma}{C}
+}
+$$
+
+$$
+\inference{
+	\sigma' = \truety{Cast\ c\ e}
+}{
+	\checktype{\Gamma}{Cast\ c\ e}{\sigma}{(C, \subc{\Gamma}{\sigma'}{\sigma})}
+}
+$$
+
+$$
+\inference{
+	\checktype{\Gamma, p \colon \tau}
+	{e}{\sigma}{C} %% here replacePredsWithRefs is used
+}{
+	\checktype{\Gamma}{e}
+	{\forall \left\langle p \colon \tau \right\rangle . \sigma}{C}
+}
+$$
+
+$$
+\inference{
+	\hastype{\Gamma}{e}{\sigma'}{C} &&
+	(\sigma'', C_p) = \freshPredsty{\sigma'}
+}{
+	\checktype{\Gamma}{e}{\sigma}
+	{(C, C_p, \subc{\Gamma}{\sigma''}{\sigma})}
+}
+$$
+
+
+\hfill\mbox{\hastypealt{\Gamma}{x}{alt}{\sigma}{C}}
+$$
+\inference{
+	(x,\tau_x^0) \in \Gamma  && \tau_x^0 = \tref{v}{C\ {t_C}_l\ {r_C}_j }{r}  &&
+	\ty{C} = \forall \alpha_l p_j . y_1\colon t_1 \rightarrow \dots y_n \colon t_n \rightarrow t &&\\
+	\theta = \sub{\alpha_l}{{t_C}_l}\sub{p_j}{{r_C}_j}\sub{y_i}{x_i} &&\\
+	\tau_{x_i} = \theta t_i && \tau_x = \theta t \land \tau_x^0 \land \dataconty{C}{x_i} &&\\
+	\checktype{\Gamma, x\colon \tau_x, x_i \colon \tau_{x_i}}{e}{\sigma}{C}
+}{
+	\hastypealt{\Gamma}{x}{(C, x_i, e)}{\sigma}{C}
+}
+$$
+
+
+% FUNCTIONS
+\section*{Helper Functions}
+\hfill\isGenericty{\alpha}{\sigma} -- not constrained by class predicates
+$$\isGenericty{\alpha}{\sigma} \Leftrightarrow \alpha \notin ClassConstraints(\sigma)$$ 
+
+\begin{align*}
+classConstraints(\tall{\alpha}{\sigma}) &= classConstraints(\sigma)\\ 
+classConstraints(\tall{p}{\sigma}) &= classConstraints(\sigma)\\ 
+classConstraints(C \alpha_i \rightarrow \tau) &= \alpha_i \cup classConstraints(\tau) 
+\end{align*}
+
+\hfill\freshty{\sigma} { -- type with liquid variables for all refinements}\\
+
+\newcommand\freshref{\ensuremath{fref}} %([], k_i)}}
+\newcommand\trueref{\ensuremath{tref}}  %([], true)}}
+$$
+\begin{array}{lcl}
+\freshty{\tref{v}{\alpha}{r}} &=& \tref{v}{\alpha}{\freshref}\\
+\freshty{\tref{v}{\tfun{x}{\tau_x}{\tau}}{r}} &=& \tref{v}{\tfun{x}{\freshty{\tau_x}}{\freshty{\tau}}}{\trueref}\\
+\freshty{\tref{v}{\tcon{C}{\overline{\tau}}{\overline{\ref}}}{r}} 
+	&=& \tref{v}{\tcon{C}{\overline{\freshty{\tau}}}{\overline{\freshref}}}{\freshref}\\
+\freshty{\tref{v}{\tapp{\tau_1}{\tau_2}}{r}} &=& \tref{v}{\tapp{\freshty{\tau_1}}{\freshty{\tau_2}}}{\trueref}\\
+\freshty{\tcl{Cl}{\bar{\tau}}} &=& \tcl{Cl}{\bar{\tau}}\\
+\freshty{\tall{\alpha}{\sigma}} &=& \tall{\alpha}{\freshty{\sigma}}\\
+\freshty{\forall \left\langle p \colon \tau \right\rangle . \sigma} 
+	&=& {\forall \left\langle p \colon \tau \right\rangle . \freshty{\sigma}}
+\end{array}
+$$
+where $fref = {([], k_i)}$, $tref = {([], true)}$
+
+\hfill\truety{\sigma} { -- type with true for all refinements}\\
+$$
+\begin{array}{lcl}
+\truety{\tref{v}{\alpha}{r}} 
+	&=& \tref{v}{\alpha}{\trueref}\\
+\truety{\tref{v}{\tfun{x}{\tau_x}{\tau}}{r}} 
+	&=& \tref{v}{\tfun{x}{\truety{\tau_x}}{\truety{\tau}}}{\trueref}\\
+\truety{\tref{v}{\tcon{C}{\overline{\tau}}{\overline{\ref}}}{r}} 
+	&=& \tref{v}{\tcon{C}{\overline{\truety{\tau}}}{\overline{\trueref}}}{\trueref}\\
+\truety{\tref{v}{\tapp{\tau_1}{\tau_2}}{r}} 
+	&=& \tref{v}{\tapp{\truety{\tau_1}}{\truety{\tau_2}}}{\trueref}\\
+\truety{\tcl{Cl}{\bar{\tau}}} &=& \tcl{Cl}{\bar{\tau}}\\
+\truety{\tall{\alpha}{\sigma}} &=& \tall{\alpha}{\truety{\sigma}}\\
+\truety{\forall \left\langle p \colon \tau \right\rangle . \sigma} 
+	&=& {\forall \left\langle p \colon \tau \right\rangle . \truety{\sigma}}
+\end{array}
+$$
+
+
+\hfill \freshPredsty{\sigma}  -- replace predicate occurrences with liquid variables
+$$
+\begin{array}{lclll}
+\freshPredsty{\tall{\alpha}{\sigma}}  
+	&=& (\tall{\alpha}{\sigma'}, C) & where& (\sigma', C) = \freshPredsty{\sigma}\\
+\freshPredsty{\forall \left\langle p \colon \tau \right\rangle .\sigma}  
+	&=& (\sigma'\sub{p}{k_i}, (C,\wfc{\Gamma'}{k_i})) & where& (\sigma', C) = \freshPredsty{\sigma}\\ 
+	&&&&  x_1\colon\tau_1 \rightarrow \dots x_n \colon\tau_n \rightarrow Prop= \tau\\
+	&&&&  \Gamma' = \Gamma, x_1\colon\tau_1 \rightarrow \dots x_{n-1} \colon\tau_{n-1}\\
+\freshPredsty{\tau}  
+	&=& (\tau, \emptyset) && \\
+\end{array}
+$$
+
+\begin{align*}
+%\isGenericty{\alpha}{\sigma} & \text{ -- not constrained by class predicates}\\
+%\freshty{\sigma} & \text{ -- type with liquid variables for all refinements}\\
+%\truety{\sigma} & \text{ -- type with true for all refinements}\\
+\truetyExpr{e} & \text{ -- type of expression with true for all refinements}\\
+\varTemplate{x} & \text{ -- type for variable x, user specified type or a fresh type}\\
+\end{align*}
+
+\begin{align*}
+\dataconty{C}{x_i} = 
+\left\lbrace \begin{array}{l l}
+Prop\ v & C = True\\
+\lnot (Prop\ v) & C = False\\
+v = x_1 & C = I\# \\
+v= C x_i & \text{otherwise}
+\end{array}\right.
+\end{align*}
diff --git a/docs/slides/BOS14/Makefile b/docs/slides/BOS14/Makefile
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/Makefile
@@ -0,0 +1,95 @@
+####################################################################
+SERVERHOME=nvazou@goto.ucsd.edu:~/public_html/liquidtutorial/
+RJSERVER=rjhala@goto.ucsd.edu:~/public_html/liquid/haskell/plpv/lhs/
+## LOCAL
+## MATHJAX=file:///Users/rjhala/research/MathJax
+## REMOTE 
+## MATHJAX=https://c328740.ssl.cf1.rackcdn.com/mathjax/latest
+## MATHJAX=https://c328740.ssl.cf1.rackcdn.com/mathjax/latest
+MATHJAX=http://cdn.mathjax.org/mathjax/latest
+
+####################################################################
+
+STRIPCODE=./MkCode.hs
+
+REVEAL=pandoc \
+	   --from=markdown\
+	   --to=html5                           \
+	   --standalone                         \
+	   --mathjax \
+	   --section-divs                       \
+	   --template=_support/template.reveal  \
+	   --variable reveal=../_support/reveal.js \
+	   --variable mathjax=$(MATHJAX)
+
+FREVEAL=pandoc \
+ 	   --from=markdown+lhs\
+	   --to=html5                           \
+	   --standalone                         \
+	   --mathjax \
+	   --section-divs                       \
+	   --template=_support/template.reveal  \
+	   --variable reveal=../_support/reveal.js
+
+PANDOC=pandoc --columns=80  -s --mathjax --slide-level=2
+SLIDY=$(PANDOC) -t slidy
+DZSLIDES=$(PANDOC) --highlight-style tango --css=slides.css -w dzslides
+HANDOUT=$(PANDOC) --highlight-style tango --css=text.css -w html5
+WEBTEX=$(PANDOC) -s --webtex -i -t slidy
+BEAMER=pandoc -t beamer
+LIQUID=liquid --short-names 
+
+mdObjects   := $(patsubst %.lhs,%.lhs.markdown,$(wildcard lhs/*.lhs))
+htmlObjects := $(patsubst %.lhs,%.lhs.slides.html,$(wildcard lhs/*.lhs))
+pdfObjects  := $(patsubst %.lhs,%.lhs.slides.pdf,$(wildcard lhs/*.lhs))
+fhtmlObjects := $(patsubst %.lhs,%.fast.html,$(wildcard lhs/*.lhs))
+
+####################################################################
+
+
+all: slides 
+
+fast: $(fhtmlObjects)
+
+one: $(mdObjects)
+	$(REVEAL) lhs/.liquid/00_Index.lhs.markdown > lhs/index.html
+
+tut: $(mdObjects)
+	$(REVEAL) lhs/.liquid/*.markdown > lhs/tutorial.html 
+
+slides: $(htmlObjects)
+
+pdfslides: $(pdfObjects)
+
+lhs/.liquid/%.lhs.markdown: lhs/%.lhs
+	-$(LIQUID) $?
+
+
+lhs/%.fast: lhs/%.lhs
+	$(STRIPCODE) $? > $@ 
+
+lhs/%.fast.html: lhs/%.fast
+	$(FREVEAL) $? -o $@ 
+
+lhs/%.lhs.slides.html: lhs/.liquid/%.lhs.markdown
+	$(REVEAL) $? -o $@ 
+
+lhs/%.lhs.slides.pdf: lhs/.liquid/%.lhs.markdown
+	$(BEAMER) $? -o $@
+
+
+copy:
+	cp lhs/*lhs.html html/
+	cp lhs/*lhs.slides.html html/
+	cp css/*.css html/
+	cp -r fonts html/
+	cp index.html html/
+	cp Benchmarks.html html/
+
+clean:
+	cd lhs/ && ../cleanup && cd ../
+#	cd html/ && rm -rf * && cd ../
+#	cp index.html html/
+
+upload: 
+	scp -r html/* $(SERVERHOME)
diff --git a/docs/slides/BOS14/README.md b/docs/slides/BOS14/README.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/README.md
@@ -0,0 +1,262 @@
+Todo
+----
+
++ CREATE 00_Motivation_Bugs.lhs **TUFTS**
+  + sequence, BUGs, 1984, etc.
+
++ UPDATE 11_Evaluation.lhs **TUFTS,BOS** 
+  + Add bits about "comments" ---> "types"
+  + Nicer GRAPHS
+  
++ CREATE HARDWIRED-RED-BLACK-BST.lhs **TUFTS**
+  + INV 1: COLOR
+  + INV 2: HEIGHT
+  + INV 3: ORDER
+
++ CREATE 03_Memory.lhs **TUFTS, BOS**
+  + and associated demo file, from eseidel's BS demo.
+
++ UPDATE 09_Laziness.lhs **BOS**
+  + Use math fonts
+  
++ CHECK 10_Termination.lhs **BOS**
+  + link to Termination.hs demo
+  
+Comparison with DT
+------------------
+
+-- Grisly HS+DT proof
+https://github.com/jstolarek/dep-typed-wbl-heaps-hs/blob/master/src/TwoPassMerge/CombinedProofs.hs#L68
+
+-- HS (no proof)
+https://github.com/jstolarek/dep-typed-wbl-heaps-hs/blob/master/src/TwoPassMerge/NoProofs.hs#L96
+
+-- HS+LH proof
+https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/pos/WBL.hs#L129
+
+
+BOS-Haskell Plan
+----------------
+
+[35] PART I "refinement types"
+
+* [5]  00_Motivation: "Go Wrong"
+
+* [15] 01_SimpleRefinements (upto VC, Abs) but no Kvar
+    + Demo : hs/000_Refinements.hs
+	+ Demo : hs/001_Refinements.hs
+	
+* [15] 02_Measures
+    + Demo : hs/01_Elements.hs
+
+[20] PART II "case studies"
+
+* [5]  lhs/02_RedBlack.lhs	
+* [15] lhs/13_Memory.lhs
+
+
+[25] PART III "haskell"
+
+* [10] lhs/09_Laziness.lhs
+* [10] lhs/10_Termination.lhs
+* [3]  lhs/11_Evaluation.lhs 
+* [2]  lhs/12_Conclusion.lhs
+
+[20] PART IV "abstract refinements"
+
+* [5]  04_Abstract Refinements.lhs
+    + Demo : 02_AbstractRefinements.hs (listMax)
+
+* [7] Demo Inductive
+    + Demo:  02_AbstractRefinements.hs (ifoldr, append, filter)
+	  
+* [8] Demo Recursive
+	+ Demo:  02_AbstractRefinements.hs (insertSort, ifoldr-insertSort)
+	+ Demo:  04_Streams.hs (repeat, take)
+
+? [10] Demo Indexed
+	+ Demo: KMP.hs
+
+Tufts Plan
+----------
+
+* [7]  00_Motivation_Long
+        + Bugs
+		+ Well typed Program Go Wrong
+		
+* [10]  01_SimpleRefinements
+        + upto VC, Abs
+
+* [10] 02_Measures 
+        + Demo    : 00_Refinements.hs
+        + Demo    : 01_Elements.hs
+
+* [5]  02_RedBlack 
+		+ Complex : RED-BLACK Trees
+
+* [5] 03_Memory_short?
+		+ Upto just the low-level API?
+		
+* [5]  11_Evaluation.lhs 
+		+ Add bits about "comments" ---> "types"
+		
+* [2]  12_Conclusion.lhs
+
+
+
+Brown Plan
+----------
+
+* [5]  00_Motivation: "Go Wrong"
+
+* [5]  01_SimpleRefinements (upto VC, Abs, but no Kvar)
+
+* [10] 02_Measures [TODO: cut RED-BLACK]
+    + Demo : 00_Refinements.hs
+    + Demo : 01_Elements.hs
+
+* [5]  04_Abstract Refinements
+    + Demo : 02_AbstractRefinements.hs (listMax)
+	
+* [5]  06_Inductive
+	+ Describe: [TODO: CUT ?foldn] foldr
+    + Demo:  02_AbstractRefinements.hs (foldr, append, filter)
+
+* [5]  08_Recursive
+	+ Describe: list-ord
+	+ Demo:  02_AbstractRefinements.hs (insertSort, ifoldr-insertSort)
+	+ Show:  GhcListSort.hs 
+	+ Describe: tree-ord
+	+ Demo:     Stream
+ 
+* [3]  11_Evaluation.lhs 
+
+* [2]  12_Conclusion.lhs
+
+
+
+Harvard Plan
+------------
+
+* [5] 00_Motivation: "Go Wrong"
+
+* [5] 01_SimpleRefinements (upto VC, Abs, but no Kvar)
+
+* [10] 02_Measures [TODO: cut RED-BLACK]
+    + Demo : 00_Refinements.hs (upto "wtAverage")
+    + Demo : 01_Elements.hs
+
+* [5] 04_Abstract Refinements
+    + Demo : 02_AbstractRefinements.hs (listMax)
+	
+* [5] 06_Inductive
+	+ Describe: [TODO: CUT ?foldn] foldr
+    + Demo:  02_AbstractRefinements.hs (foldr, append, filter)
+
+* [5] 08_Recursive
+	+ Describe: list-ord
+	+ Demo:  02_AbstractRefinements.hs (insertSort, ifoldr-insertSort)
+
+	+ Show:  GhcListSort.hs 
+	+ Describe: tree-ord
+	+ [TODO: CUT] Demo:     RBTree-Ord
+	+ Demo:     Stream
+
+* [TODO: CUT] [5] 07_Array
+  [TODO: CUT] 	+ Describe: Array
+  [TODO: CUT] 	+ Demo:     KMP
+  
+* [3] 11_Evaluation.lhs 
+
+* [2] 12_Conclusion.lhs
+
+Bytestring Details
+------------------
+
+-- | A variety of 'head' for non-empty ByteStrings. 'unsafeHead' omits
+-- the check for the empty case, which is good for performance, but
+-- there is an obligation on the programmer to provide a proof that the
+-- ByteString is non-empty.
+{-@ unsafeHead :: ByteStringNE -> Char @-}
+unsafeHead :: ByteString -> Char
+unsafeHead  = w2c . B.unsafeHead
+{-# INLINE unsafeHead #-}
+
+
+type ByteStringNE = {v:ByteString | 0 < bLength v}
+
+
+-- | Unsafe 'ByteString' index (subscript) operator, starting from 0, returning a 'Word8'
+-- This omits the bounds check, which means there is an accompanying
+-- obligation on the programmer to ensure the bounds are checked in some
+-- other way.
+
+{-@ type OkIdx B = {v:Nat | v < bLength B} @-}
+
+{-@ unsafeIndex :: b:ByteString -> OkIdx b -> Word8 @-}
+unsafeIndex :: ByteString -> Int -> Word8
+unsafeIndex (PS x s l) i = assert (i >= 0 && i < l) $
+    inlinePerformIO $ withForeignPtr x $ \p -> peekByteOff p (s+i)
+
+
+Low-Level Memory
+----------------
+
+1. "Haskell HeartBleed" (using BS)
+
+2. Memory API (calls out to C)
+	+ mallocForeignPtrBytes
+	+ withForeignPtr 
+	+ peek
+	+ poke
+	+ plusPtr
+
+   First with types, then with Refined Types.
+
+3. Examples
+    + okPtr
+	+ badPtr (replace 3 with 6)
+
+4. `ByteString`
+   + invariant 
+   + goodBS1, goodBS2
+   + badBS1, badBS2
+
+5. `create`
+   + good call
+   + bad call
+   
+6. `pack`
+7. `unpack`
+8. `unsafeTake`
+9. `heartBleed` redux.
+
+`peekByteOff p i == peek (p `plusPtr` i)`
+
+\begin{code}
+module BSCrash where
+
+import Data.ByteString.Char8  as C
+import Data.ByteString        as B
+import Data.ByteString.Unsafe as U
+
+heartBleed s n = s'
+  where 
+    b          = C.pack s         -- "Ranjit"
+    b'         = U.unsafeTake n b -- 20
+    s'         = C.unpack b'
+
+-- > let ex = "Ranjit Loves Burritos"
+    
+-- > heartBleed ex 1
+--   "R"
+    
+-- > heartBleed ex 6
+-- > "Ranjit"
+
+-- > heartBleed ex 10
+-- > "Ranjit Lov"
+    
+-- > heartBleed ex 30
+-- > "Ranjit Loves Burritos\NUL\NUL\NUL\201\&1j\DC3\SOH\NUL"
+\end{code}
diff --git a/docs/slides/BOS14/_support/liquid.css b/docs/slides/BOS14/_support/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/liquid.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/BOS14/_support/liquidhaskell.css b/docs/slides/BOS14/_support/liquidhaskell.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/liquidhaskell.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/BOS14/_support/reveal.js/.travis.yml b/docs/slides/BOS14/_support/reveal.js/.travis.yml
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - 0.8
+before_script:
+  - npm install -g grunt-cli
diff --git a/docs/slides/BOS14/_support/reveal.js/Gruntfile.js b/docs/slides/BOS14/_support/reveal.js/Gruntfile.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/Gruntfile.js
@@ -0,0 +1,137 @@
+/* global module:false */
+module.exports = function(grunt) {
+	var port = grunt.option('port') || 8000;
+	// Project configuration
+	grunt.initConfig({
+		pkg: grunt.file.readJSON('package.json'),
+		meta: {
+			banner:
+				'/*!\n' +
+				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
+				' * http://lab.hakim.se/reveal-js\n' +
+				' * MIT licensed\n' +
+				' *\n' +
+				' * Copyright (C) 2014 Hakim El Hattab, http://hakim.se\n' +
+				' */'
+		},
+
+		qunit: {
+			files: [ 'test/*.html' ]
+		},
+
+		uglify: {
+			options: {
+				banner: '<%= meta.banner %>\n'
+			},
+			build: {
+				src: 'js/reveal.js',
+				dest: 'js/reveal.min.js'
+			}
+		},
+
+		cssmin: {
+			compress: {
+				files: {
+					'css/reveal.min.css': [ 'css/reveal.css' ]
+				}
+			}
+		},
+
+		sass: {
+			main: {
+				files: {
+					'css/theme/default.css': 'css/theme/source/default.scss',
+					'css/theme/beige.css': 'css/theme/source/beige.scss',
+					'css/theme/night.css': 'css/theme/source/night.scss',
+					'css/theme/serif.css': 'css/theme/source/serif.scss',
+					'css/theme/simple.css': 'css/theme/source/simple.scss',
+					'css/theme/sky.css': 'css/theme/source/sky.scss',
+					'css/theme/moon.css': 'css/theme/source/moon.scss',
+					'css/theme/solarized.css': 'css/theme/source/solarized.scss',
+					'css/theme/blood.css': 'css/theme/source/blood.scss'
+				}
+			}
+		},
+
+		jshint: {
+			options: {
+				curly: false,
+				eqeqeq: true,
+				immed: true,
+				latedef: true,
+				newcap: true,
+				noarg: true,
+				sub: true,
+				undef: true,
+				eqnull: true,
+				browser: true,
+				expr: true,
+				globals: {
+					head: false,
+					module: false,
+					console: false,
+					unescape: false
+				}
+			},
+			files: [ 'Gruntfile.js', 'js/reveal.js' ]
+		},
+
+		connect: {
+			server: {
+				options: {
+					port: port,
+					base: '.'
+				}
+			}
+		},
+
+		zip: {
+			'reveal-js-presentation.zip': [
+				'index.html',
+				'css/**',
+				'js/**',
+				'lib/**',
+				'images/**',
+				'plugin/**'
+			]
+		},
+
+		watch: {
+			main: {
+				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
+				tasks: 'default'
+			},
+			theme: {
+				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
+				tasks: 'themes'
+			}
+		}
+
+	});
+
+	// Dependencies
+	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
+	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
+	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
+	grunt.loadNpmTasks( 'grunt-contrib-watch' );
+	grunt.loadNpmTasks( 'grunt-contrib-sass' );
+	grunt.loadNpmTasks( 'grunt-contrib-connect' );
+	grunt.loadNpmTasks( 'grunt-zip' );
+
+	// Default task
+	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );
+
+	// Theme task
+	grunt.registerTask( 'themes', [ 'sass' ] );
+
+	// Package presentation to archive
+	grunt.registerTask( 'package', [ 'default', 'zip' ] );
+
+	// Serve presentation locally
+	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );
+
+	// Run tests
+	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );
+
+};
diff --git a/docs/slides/BOS14/_support/reveal.js/LICENSE b/docs/slides/BOS14/_support/reveal.js/LICENSE
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/docs/slides/BOS14/_support/reveal.js/README.md b/docs/slides/BOS14/_support/reveal.js/README.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/README.md
@@ -0,0 +1,933 @@
+# reveal.js [![Build Status](https://travis-ci.org/hakimel/reveal.js.png?branch=master)](https://travis-ci.org/hakimel/reveal.js)
+
+A framework for easily creating beautiful presentations using HTML. [Check out the live demo](http://lab.hakim.se/reveal-js/).
+
+reveal.js comes with a broad range of features including [nested slides](https://github.com/hakimel/reveal.js#markup), [markdown contents](https://github.com/hakimel/reveal.js#markdown), [PDF export](https://github.com/hakimel/reveal.js#pdf-export), [speaker notes](https://github.com/hakimel/reveal.js#speaker-notes) and a [JavaScript API](https://github.com/hakimel/reveal.js#api). It's best viewed in a browser with support for CSS 3D transforms but [fallbacks](https://github.com/hakimel/reveal.js/wiki/Browser-Support) are available to make sure your presentation can still be viewed elsewhere.
+
+
+#### More reading:
+- [Installation](#installation): Step-by-step instructions for getting reveal.js running on your computer.
+- [Changelog](https://github.com/hakimel/reveal.js/releases): Up-to-date version history.
+- [Examples](https://github.com/hakimel/reveal.js/wiki/Example-Presentations): Presentations created with reveal.js, add your own!
+- [Browser Support](https://github.com/hakimel/reveal.js/wiki/Browser-Support): Explanation of browser support and fallbacks.
+
+## Online Editor
+
+Presentations are written using HTML or markdown but there's also an online editor for those of you who prefer a graphical interface. Give it a try at [http://slid.es](http://slid.es).
+
+
+## Instructions
+
+### Markup
+
+Markup hierarchy needs to be ``<div class="reveal"> <div class="slides"> <section>`` where the ``<section>`` represents one slide and can be repeated indefinitely. If you place multiple ``<section>``'s inside of another ``<section>`` they will be shown as vertical slides. The first of the vertical slides is the "root" of the others (at the top), and it will be included in the horizontal sequence. For example:
+
+```html
+<div class="reveal">
+	<div class="slides">
+		<section>Single Horizontal Slide</section>
+		<section>
+			<section>Vertical Slide 1</section>
+			<section>Vertical Slide 2</section>
+		</section>
+	</div>
+</div>
+```
+
+### Markdown
+
+It's possible to write your slides using Markdown. To enable Markdown, add the ```data-markdown``` attribute to your ```<section>``` elements and wrap the contents in a ```<script type="text/template">``` like the example below.
+
+This is based on [data-markdown](https://gist.github.com/1343518) from [Paul Irish](https://github.com/paulirish) modified to use [marked](https://github.com/chjj/marked) to support [Github Flavoured Markdown](https://help.github.com/articles/github-flavored-markdown). Sensitive to indentation (avoid mixing tabs and spaces) and line breaks (avoid consecutive breaks).
+
+```html
+<section data-markdown>
+	<script type="text/template">
+		## Page title
+
+		A paragraph with some text and a [link](http://hakim.se).
+	</script>
+</section>
+```
+
+#### External Markdown
+
+You can write your content as a separate file and have reveal.js load it at runtime. Note the separator arguments which determine how slides are delimited in the external file. The ```data-charset``` attribute is optional and specifies which charset to use when loading the external file.
+
+When used locally, this feature requires that reveal.js [runs from a local web server](#full-setup).
+
+```html
+<section data-markdown="example.md"  
+         data-separator="^\n\n\n"  
+         data-vertical="^\n\n"  
+         data-notes="^Note:"  
+         data-charset="iso-8859-15">
+</section>
+```
+
+#### Element Attributes
+
+Special syntax (in html comment) is available for adding attributes to Markdown elements. This is useful for fragments, amongst other things.
+
+```html
+<section data-markdown>
+	<script type="text/template">
+		- Item 1 <!-- .element: class="fragment" data-fragment-index="2" -->
+		- Item 2 <!-- .element: class="fragment" data-fragment-index="1" -->
+	</script>
+</section>
+```
+
+#### Slide Attributes
+
+Special syntax (in html comment) is available for adding attributes to the slide `<section>` elements generated by your Markdown.
+
+```html
+<section data-markdown>
+	<script type="text/template">
+	<!-- .slide: data-background="#ff0000" -->
+		Markdown content
+	</script>
+</section>
+```
+
+
+### Configuration
+
+At the end of your page you need to initialize reveal by running the following code. Note that all config values are optional and will default as specified below.
+
+```javascript
+Reveal.initialize({
+
+	// Display controls in the bottom right corner
+	controls: true,
+
+	// Display a presentation progress bar
+	progress: true,
+
+	// Display the page number of the current slide
+	slideNumber: false,
+
+	// Push each slide change to the browser history
+	history: false,
+
+	// Enable keyboard shortcuts for navigation
+	keyboard: true,
+
+	// Enable the slide overview mode
+	overview: true,
+
+	// Vertical centering of slides
+	center: true,
+
+	// Enables touch navigation on devices with touch input
+	touch: true,
+
+	// Loop the presentation
+	loop: false,
+
+	// Change the presentation direction to be RTL
+	rtl: false,
+
+	// Turns fragments on and off globally
+	fragments: true,
+
+	// Flags if the presentation is running in an embedded mode,
+	// i.e. contained within a limited portion of the screen
+	embedded: false,
+
+	// Number of milliseconds between automatically proceeding to the
+	// next slide, disabled when set to 0, this value can be overwritten
+	// by using a data-autoslide attribute on your slides
+	autoSlide: 0,
+
+	// Stop auto-sliding after user input
+	autoSlideStoppable: true,
+
+	// Enable slide navigation via mouse wheel
+	mouseWheel: false,
+
+	// Hides the address bar on mobile devices
+	hideAddressBar: true,
+
+	// Opens links in an iframe preview overlay
+	previewLinks: false,
+
+	// Transition style
+	transition: 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+	// Transition speed
+	transitionSpeed: 'default', // default/fast/slow
+
+	// Transition style for full page slide backgrounds
+	backgroundTransition: 'default', // default/none/slide/concave/convex/zoom
+
+	// Number of slides away from the current that are visible
+	viewDistance: 3,
+
+	// Parallax background image
+	parallaxBackgroundImage: '', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
+
+	// Parallax background size
+	parallaxBackgroundSize: '' // CSS syntax, e.g. "2100px 900px"
+
+
+});
+```
+
+Note that the new default vertical centering option will break compatibility with slides that were using transitions with backgrounds (`cube` and `page`). To restore the previous behavior, set `center` to `false`.
+
+
+The configuration can be updated after initialization using the ```configure``` method:
+
+```javascript
+// Turn autoSlide off
+Reveal.configure({ autoSlide: 0 });
+
+// Start auto-sliding every 5s
+Reveal.configure({ autoSlide: 5000 });
+```
+
+
+### Dependencies
+
+Reveal.js doesn't _rely_ on any third party scripts to work but a few optional libraries are included by default. These libraries are loaded as dependencies in the order they appear, for example:
+
+```javascript
+Reveal.initialize({
+	dependencies: [
+		// Cross-browser shim that fully implements classList - https://github.com/eligrey/classList.js/
+		{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
+
+		// Interpret Markdown in <section> elements
+		{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+		{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+
+		// Syntax highlight for <code> elements
+		{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+
+		// Zoom in and out with Alt+click
+		{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
+
+		// Speaker notes
+		{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
+
+		// Remote control your reveal.js presentation using a touch device
+		{ src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } },
+
+		// MathJax
+		{ src: 'plugin/math/math.js', async: true }
+	]
+});
+```
+
+You can add your own extensions using the same syntax. The following properties are available for each dependency object:
+- **src**: Path to the script to load
+- **async**: [optional] Flags if the script should load after reveal.js has started, defaults to false
+- **callback**: [optional] Function to execute when the script has loaded
+- **condition**: [optional] Function which must return true for the script to be loaded
+
+
+### Presentation Size
+
+All presentations have a normal size, that is the resolution at which they are authored. The framework will automatically scale presentations uniformly based on this size to ensure that everything fits on any given display or viewport.
+
+See below for a list of configuration options related to sizing, including default values:
+
+```javascript
+Reveal.initialize({
+
+	...
+
+	// The "normal" size of the presentation, aspect ratio will be preserved
+	// when the presentation is scaled to fit different resolutions. Can be
+	// specified using percentage units.
+	width: 960,
+	height: 700,
+
+	// Factor of the display size that should remain empty around the content
+	margin: 0.1,
+
+	// Bounds for smallest/largest possible scale to apply to content
+	minScale: 0.2,
+	maxScale: 1.0
+
+});
+```
+
+
+### Auto-sliding
+
+Presentations can be configure to progress through slides automatically, without any user input. To enable this you will need to tell the framework how many milliseconds it should wait between slides:
+
+```javascript
+// Slide every five seconds
+Reveal.configure({
+  autoSlide: 5000
+});
+```
+
+When this is turned on a control element will appear that enables users to pause and resume auto-sliding. Sliding is also paused automatically as soon as the user starts navigating. You can disable these controls by specifying ```autoSlideStoppable: false``` in your reveal.js config.
+
+You can also override the slide duration for individual slides by using the ```data-autoslide``` attribute on individual sections:
+
+```html
+<section data-autoslide="10000">This will remain on screen for 10 seconds</section>
+```
+
+
+### Keyboard Bindings
+
+If you're unhappy with any of the default keyboard bindings you can override them using the ```keyboard``` config option:
+
+```javascript
+Reveal.configure({
+  keyboard: {
+    13: 'next', // go to the next slide when the ENTER key is pressed
+    27: function() {}, // do something custom when ESC is pressed
+    32: null // don't do anything when SPACE is pressed (i.e. disable a reveal.js default binding)
+  }
+});
+```
+
+
+### API
+
+The ``Reveal`` class provides a JavaScript API for controlling navigation and reading state:
+
+```javascript
+// Navigation
+Reveal.slide( indexh, indexv, indexf );
+Reveal.left();
+Reveal.right();
+Reveal.up();
+Reveal.down();
+Reveal.prev();
+Reveal.next();
+Reveal.prevFragment();
+Reveal.nextFragment();
+Reveal.toggleOverview();
+Reveal.togglePause();
+
+// Retrieves the previous and current slide elements
+Reveal.getPreviousSlide();
+Reveal.getCurrentSlide();
+
+Reveal.getIndices(); // { h: 0, v: 0 } }
+
+// State checks
+Reveal.isFirstSlide();
+Reveal.isLastSlide();
+Reveal.isOverview();
+Reveal.isPaused();
+```
+
+### Ready Event
+
+The 'ready' event is fired when reveal.js has loaded all (synchronous) dependencies and is ready to start navigating.
+
+```javascript
+Reveal.addEventListener( 'ready', function( event ) {
+	// event.currentSlide, event.indexh, event.indexv
+} );
+```
+
+### Slide Changed Event
+
+An 'slidechanged' event is fired each time the slide is changed (regardless of state). The event object holds the index values of the current slide as well as a reference to the previous and current slide HTML nodes.
+
+Some libraries, like MathJax (see [#226](https://github.com/hakimel/reveal.js/issues/226#issuecomment-10261609)), get confused by the transforms and display states of slides. Often times, this can be fixed by calling their update or render function from this callback.
+
+```javascript
+Reveal.addEventListener( 'slidechanged', function( event ) {
+	// event.previousSlide, event.currentSlide, event.indexh, event.indexv
+} );
+```
+
+
+### States
+
+If you set ``data-state="somestate"`` on a slide ``<section>``, "somestate" will be applied as a class on the document element when that slide is opened. This allows you to apply broad style changes to the page based on the active slide.
+
+Furthermore you can also listen to these changes in state via JavaScript:
+
+```javascript
+Reveal.addEventListener( 'somestate', function() {
+	// TODO: Sprinkle magic
+}, false );
+```
+
+### Slide Backgrounds
+
+Slides are contained within a limited portion of the screen by default to allow them to fit any display and scale uniformly. You can apply full page background colors or images by applying a ```data-background``` attribute to your ```<section>``` elements. Below are a few examples.
+
+```html
+<section data-background="#ff0000">
+	<h2>All CSS color formats are supported, like rgba() or hsl().</h2>
+</section>
+<section data-background="http://example.com/image.png">
+	<h2>This slide will have a full-size background image.</h2>
+</section>
+<section data-background="http://example.com/image.png" data-background-size="100px" data-background-repeat="repeat">
+	<h2>This background image will be sized to 100px and repeated.</h2>
+</section>
+```
+
+Backgrounds transition using a fade animation by default. This can be changed to a linear sliding transition by passing ```backgroundTransition: 'slide'``` to the ```Reveal.initialize()``` call. Alternatively you can set ```data-background-transition``` on any section with a background to override that specific transition.
+
+
+### Parallax Background
+
+If you want to use a parallax scrolling background, set the two following config properties when initializing reveal.js (the third one is optional).
+
+```javascript
+Reveal.initialize({
+
+	// Parallax background image
+	parallaxBackgroundImage: '', // e.g. "https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg"
+
+	// Parallax background size
+	parallaxBackgroundSize: '', // CSS syntax, e.g. "2100px 900px" - currently only pixels are supported (don't use % or auto)
+
+	// This slide transition gives best results:
+	transition: linear
+
+});
+```
+
+Make sure that the background size is much bigger than screen size to allow for some scrolling. [View example](http://lab.hakim.se/reveal-js/?parallaxBackgroundImage=https%3A%2F%2Fs3.amazonaws.com%2Fhakim-static%2Freveal-js%2Freveal-parallax-1.jpg&parallaxBackgroundSize=2100px%20900px).
+
+
+
+### Slide Transitions
+The global presentation transition is set using the ```transition``` config value. You can override the global transition for a specific slide by using the ```data-transition``` attribute:
+
+```html
+<section data-transition="zoom">
+	<h2>This slide will override the presentation transition and zoom!</h2>
+</section>
+
+<section data-transition-speed="fast">
+	<h2>Choose from three transition speeds: default, fast or slow!</h2>
+</section>
+```
+
+Note that this does not work with the page and cube transitions.
+
+
+### Internal links
+
+It's easy to link between slides. The first example below targets the index of another slide whereas the second targets a slide with an ID attribute (```<section id="some-slide">```):
+
+```html
+<a href="#/2/2">Link</a>
+<a href="#/some-slide">Link</a>
+```
+
+You can also add relative navigation links, similar to the built in reveal.js controls, by appending one of the following classes on any element. Note that each element is automatically given an ```enabled``` class when it's a valid navigation route based on the current slide.
+
+```html
+<a href="#" class="navigate-left">
+<a href="#" class="navigate-right">
+<a href="#" class="navigate-up">
+<a href="#" class="navigate-down">
+<a href="#" class="navigate-prev"> <!-- Previous vertical or horizontal slide -->
+<a href="#" class="navigate-next"> <!-- Next vertical or horizontal slide -->
+```
+
+
+### Fragments
+Fragments are used to highlight individual elements on a slide. Every element with the class ```fragment``` will be stepped through before moving on to the next slide. Here's an example: http://lab.hakim.se/reveal-js/#/fragments
+
+The default fragment style is to start out invisible and fade in. This style can be changed by appending a different class to the fragment:
+
+```html
+<section>
+	<p class="fragment grow">grow</p>
+	<p class="fragment shrink">shrink</p>
+	<p class="fragment roll-in">roll-in</p>
+	<p class="fragment fade-out">fade-out</p>
+	<p class="fragment current-visible">visible only once</p>
+	<p class="fragment highlight-current-blue">blue only once</p>
+	<p class="fragment highlight-red">highlight-red</p>
+	<p class="fragment highlight-green">highlight-green</p>
+	<p class="fragment highlight-blue">highlight-blue</p>
+</section>
+```
+
+Multiple fragments can be applied to the same element sequentially by wrapping it, this will fade in the text on the first step and fade it back out on the second.
+
+```html
+<section>
+	<span class="fragment fade-in">
+		<span class="fragment fade-out">I'll fade in, then out</span>
+	</span>
+</section>
+```
+
+The display order of fragments can be controlled using the ```data-fragment-index``` attribute.
+
+```html
+<section>
+	<p class="fragment" data-fragment-index="3">Appears last</p>
+	<p class="fragment" data-fragment-index="1">Appears first</p>
+	<p class="fragment" data-fragment-index="2">Appears second</p>
+</section>
+```
+
+### Fragment events
+
+When a slide fragment is either shown or hidden reveal.js will dispatch an event.
+
+Some libraries, like MathJax (see #505), get confused by the initially hidden fragment elements. Often times this can be fixed by calling their update or render function from this callback.
+
+```javascript
+Reveal.addEventListener( 'fragmentshown', function( event ) {
+	// event.fragment = the fragment DOM element
+} );
+Reveal.addEventListener( 'fragmenthidden', function( event ) {
+	// event.fragment = the fragment DOM element
+} );
+```
+
+### Code syntax highlighting
+
+By default, Reveal is configured with [highlight.js](http://softwaremaniacs.org/soft/highlight/en/) for code syntax highlighting. Below is an example with clojure code that will be syntax highlighted. When the `data-trim` attribute is present surrounding whitespace is automatically removed.
+
+```html
+<section>
+	<pre><code data-trim>
+(def lazy-fib
+  (concat
+   [0 1]
+   ((fn rfib [a b]
+        (lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
+	</code></pre>
+</section>
+```
+
+### Slide number
+If you would like to display the page number of the current slide you can do so using the ```slideNumber``` configuration value.
+
+```javascript
+Reveal.configure({ slideNumber: true });
+```
+
+
+### Overview mode
+
+Press "Esc" or "o" keys to toggle the overview mode on and off. While you're in this mode, you can still navigate between slides,
+as if you were at 1,000 feet above your presentation. The overview mode comes with a few API hooks:
+
+```javascript
+Reveal.addEventListener( 'overviewshown', function( event ) { /* ... */ } );
+Reveal.addEventListener( 'overviewhidden', function( event ) { /* ... */ } );
+
+// Toggle the overview mode programmatically
+Reveal.toggleOverview();
+```
+
+### Fullscreen mode
+Just press »F« on your keyboard to show your presentation in fullscreen mode. Press the »ESC« key to exit fullscreen mode.
+
+
+### Embedded media
+Embedded HTML5 `<video>`/`<audio>` and YouTube iframes are automatically paused when you navigate away from a slide. This can be disabled by decorating your element with a `data-ignore` attribute.
+
+Add `data-autoplay` to your media element if you want it to automatically start playing when the slide is shown:
+
+```html
+<video data-autoplay src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
+```
+
+Additionally the framework automatically pushes two [post messages](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) to all iframes, ```slide:start``` when the slide containing the iframe is made visible and ```slide:stop``` when it is hidden.
+
+
+### Stretching elements
+Sometimes it's desirable to have an element, like an image or video, stretch to consume as much space as possible within a given slide. This can be done by adding the ```.stretch``` class to an element as seen below:
+
+```html
+<section>
+	<h2>This video will use up the remaining space on the slide</h2>
+    <video class="stretch" src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
+</section>
+```
+
+Limitations:
+- Only direct descendants of a slide section can be stretched
+- Only one descendant per slide section can be stretched
+
+
+## PDF Export
+
+Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome).
+Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-13872948.
+
+1. Open your presentation with [css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css) included on the page. The default index HTML lets you add *print-pdf* anywhere in the query to include the stylesheet, for example: [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf).
+2. Open the in-browser print dialog (CMD+P).
+3. Change the **Destination** setting to **Save as PDF**.
+4. Change the **Layout** to **Landscape**.
+5. Change the **Margins** to **None**.
+6. Click **Save**.
+
+![Chrome Print Settings](https://s3.amazonaws.com/hakim-static/reveal-js/pdf-print-settings.png)
+
+## Theming
+
+The framework comes with a few different themes included:
+
+- default: Gray background, white text, blue links
+- beige: Beige background, dark text, brown links
+- sky: Blue background, thin white text, blue links
+- night: Black background, thick white text, orange links
+- serif: Cappuccino background, gray text, brown links
+- simple: White background, black text, blue links
+- solarized: Cream-colored background, dark green text, blue links
+
+Each theme is available as a separate stylesheet. To change theme you will need to replace **default** below with your desired theme name in index.html:
+
+```html
+<link rel="stylesheet" href="css/theme/default.css" id="theme">
+```
+
+If you want to add a theme of your own see the instructions here: [/css/theme/README.md](https://github.com/hakimel/reveal.js/blob/master/css/theme/README.md).
+
+
+## Speaker Notes
+
+reveal.js comes with a speaker notes plugin which can be used to present per-slide notes in a separate browser window. The notes window also gives you a preview of the next upcoming slide so it may be helpful even if you haven't written any notes. Press the 's' key on your keyboard to open the notes window.
+
+Notes are defined by appending an ```<aside>``` element to a slide as seen below. You can add the ```data-markdown``` attribute to the aside element if you prefer writing notes using Markdown.
+
+When used locally, this feature requires that reveal.js [runs from a local web server](#full-setup).
+
+```html
+<section>
+	<h2>Some Slide</h2>
+
+	<aside class="notes">
+		Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
+	</aside>
+</section>
+```
+
+If you're using the external Markdown plugin, you can add notes with the help of a special delimiter:
+
+```html
+<section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n" data-notes="^Note:"></section>
+
+# Title
+## Sub-title
+
+Here is some content...
+
+Note:
+This will only display in the notes window.
+```
+
+## Server Side Speaker Notes
+
+In some cases it can be desirable to run notes on a separate device from the one you're presenting on. The Node.js-based notes plugin lets you do this using the same note definitions as its client side counterpart. Include the required scripts by adding the following dependencies:
+
+```javascript
+Reveal.initialize({
+	...
+
+	dependencies: [
+		{ src: 'socket.io/socket.io.js', async: true },
+		{ src: 'plugin/notes-server/client.js', async: true }
+	]
+});
+```
+
+Then:
+
+1. Install [Node.js](http://nodejs.org/)
+2. Run ```npm install```
+3. Run ```node plugin/notes-server```
+
+
+## Multiplexing
+
+The multiplex plugin allows your audience to view the slides of the presentation you are controlling on their own phone, tablet or laptop. As the master presentation navigates the slides, all client presentations will update in real time. See a demo at [http://revealjs.jit.su/](http://revealjs.jit.su).
+
+The multiplex plugin needs the following 3 things to operate:
+
+1. Master presentation that has control
+2. Client presentations that follow the master
+3. Socket.io server to broadcast events from the master to the clients
+
+More details:
+
+#### Master presentation
+Served from a static file server accessible (preferably) only to the presenter. This need only be on your (the presenter's) computer. (It's safer to run the master presentation from your own computer, so if the venue's Internet goes down it doesn't stop the show.) An example would be to execute the following commands in the directory of your master presentation: 
+
+1. ```npm install node-static```
+2. ```static```
+
+If you want to use the speaker notes plugin with your master presentation then make sure you have the speaker notes plugin configured correctly along with the configuration shown below, then execute ```node plugin/notes-server``` in the directory of your master presentation. The configuration below will cause it to connect to the socket.io server as a master, as well as launch your speaker-notes/static-file server.
+
+You can then access your master presentation at ```http://localhost:1947```
+
+Example configuration:
+```javascript
+Reveal.initialize({
+	// other options...
+
+	multiplex: {
+		// Example values. To generate your own, see the socket.io server instructions.
+		secret: '13652805320794272084', // Obtained from the socket.io server. Gives this (the master) control of the presentation
+		id: '1ea875674b17ca76', // Obtained from socket.io server
+		url: 'revealjs.jit.su:80' // Location of socket.io server
+	},
+
+	// Don't forget to add the dependencies
+	dependencies: [
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: 'plugin/multiplex/master.js', async: true },
+
+		// and if you want speaker notes
+		{ src: 'plugin/notes-server/client.js', async: true }
+
+		// other dependencies...
+	]
+});
+```
+
+#### Client presentation
+Served from a publicly accessible static file server. Examples include: GitHub Pages, Amazon S3, Dreamhost, Akamai, etc. The more reliable, the better. Your audience can then access the client presentation via ```http://example.com/path/to/presentation/client/index.html```, with the configuration below causing them to connect to the socket.io server as clients.
+
+Example configuration:
+```javascript
+Reveal.initialize({
+	// other options...
+
+	multiplex: {
+		// Example values. To generate your own, see the socket.io server instructions.
+		secret: null, // null so the clients do not have control of the master presentation
+		id: '1ea875674b17ca76', // id, obtained from socket.io server
+		url: 'revealjs.jit.su:80' // Location of socket.io server
+	},
+
+	// Don't forget to add the dependencies
+	dependencies: [
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: 'plugin/multiplex/client.js', async: true }
+
+		// other dependencies...
+	]
+});
+```
+
+#### Socket.io server
+Server that receives the slideChanged events from the master presentation and broadcasts them out to the connected client presentations. This needs to be publicly accessible. You can run your own socket.io server with the commands:
+
+1. ```npm install```
+2. ```node plugin/multiplex```
+
+Or you use the socket.io server at [http://revealjs.jit.su](http://revealjs.jit.su).
+
+You'll need to generate a unique secret and token pair for your master and client presentations. To do so, visit ```http://example.com/token```, where ```http://example.com``` is the location of your socket.io server. Or if you're going to use the socket.io server at [http://revealjs.jit.su](http://revealjs.jit.su), visit [http://revealjs.jit.su/token](http://revealjs.jit.su/token).
+
+You are very welcome to point your presentations at the Socket.io server running at [http://revealjs.jit.su](http://revealjs.jit.su), but availability and stability are not guaranteed. For anything mission critical I recommend you run your own server. It is simple to deploy to nodejitsu, heroku, your own environment, etc.
+
+##### socket.io server as file static server
+
+The socket.io server can play the role of static file server for your client presentation, as in the example at [http://revealjs.jit.su](http://revealjs.jit.su). (Open [http://revealjs.jit.su](http://revealjs.jit.su) in two browsers. Navigate through the slides on one, and the other will update to match.) 
+
+Example configuration:
+```javascript
+Reveal.initialize({
+	// other options...
+
+	multiplex: {
+		// Example values. To generate your own, see the socket.io server instructions.
+		secret: null, // null so the clients do not have control of the master presentation
+		id: '1ea875674b17ca76', // id, obtained from socket.io server
+		url: 'example.com:80' // Location of your socket.io server
+	},
+
+	// Don't forget to add the dependencies
+	dependencies: [
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: 'plugin/multiplex/client.js', async: true }
+
+		// other dependencies...
+	]
+```
+
+It can also play the role of static file server for your master presentation and client presentations at the same time (as long as you don't want to use speaker notes). (Open [http://revealjs.jit.su](http://revealjs.jit.su) in two browsers. Navigate through the slides on one, and the other will update to match. Navigate through the slides on the second, and the first will update to match.) This is probably not desirable, because you don't want your audience to mess with your slides while you're presenting. ;)
+
+Example configuration:
+```javascript
+Reveal.initialize({
+	// other options...
+
+	multiplex: {
+		// Example values. To generate your own, see the socket.io server instructions.
+		secret: '13652805320794272084', // Obtained from the socket.io server. Gives this (the master) control of the presentation
+		id: '1ea875674b17ca76', // Obtained from socket.io server
+		url: 'example.com:80' // Location of your socket.io server
+	},
+
+	// Don't forget to add the dependencies
+	dependencies: [
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: 'plugin/multiplex/master.js', async: true },
+		{ src: 'plugin/multiplex/client.js', async: true }
+
+		// other dependencies...
+	]
+});
+```
+
+## Leap Motion
+The Leap Motion plugin lets you utilize your [Leap Motion](https://www.leapmotion.com/) device to control basic navigation of your presentation. The gestures currently supported are:
+
+##### 1 to 2 fingers
+Pointer &mdash; Point to anything on screen. Move your finger past the device to expand the pointer.
+
+##### 1 hand + 3 or more fingers (left/right/up/down)
+Navigate through your slides. See config options to invert movements.
+
+##### 2 hands upwards
+Toggle the overview mode. Do it a second time to exit the overview.
+
+#### Config Options
+You can edit the following options:
+
+| Property          | Default           | Description
+| ----------------- |:-----------------:| :-------------
+| autoCenter        | true              | Center the pointer based on where you put your finger into the leap motions detection field.
+| gestureDelay      | 500               | How long to delay between gestures in milliseconds.
+| naturalSwipe      | true              | Swipe as though you were touching a touch screen. Set to false to invert.
+| pointerColor      | #00aaff           | The color of the pointer.
+| pointerOpacity    | 0.7               | The opacity of the pointer.
+| pointerSize       | 15                | The minimum height and width of the pointer.
+| pointerTolerance  | 120               | Bigger = slower pointer.
+
+
+Example configuration:
+```js
+Reveal.initialize({
+
+	// other options...
+
+	leap: {
+		naturalSwipe   : false,    // Invert swipe gestures
+		pointerOpacity : 0.5,      // Set pointer opacity to 0.5
+		pointerColor   : '#d80000' // Red pointer
+	},
+
+	dependencies: [
+		{ src: 'plugin/leap/leap.js', async: true }
+	]
+
+});
+```
+
+## MathJax
+
+If you want to display math equations in your presentation you can easily do so by including this plugin. The plugin is a very thin wrapper around the [MathJax](http://www.mathjax.org/) library. To use it you'll need to include it as a reveal.js dependency, [find our more about dependencies here](#dependencies).
+
+The plugin defaults to using [LaTeX](http://en.wikipedia.org/wiki/LaTeX) but that can be adjusted through the ```math``` configuration object. Note that MathJax is loaded from a remote server. If you want to use it offline you'll need to download a copy of the library and adjust the ```mathjax``` configuration value. 
+
+Below is an example of how the plugin can be configured. If you don't intend to change these values you do not need to include the ```math``` config object at all.
+
+```js
+Reveal.initialize({
+
+	// other options ...
+
+	math: {
+		mathjax: 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
+		config: 'TeX-AMS_HTML-full'  // See http://docs.mathjax.org/en/latest/config-files.html
+	},
+	
+	dependencies: [
+		{ src: 'plugin/math/math.js', async: true }
+	]
+
+});
+```
+
+Read MathJax's documentation if you need [HTTPS delivery](http://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn) or serving of [specific versions](http://docs.mathjax.org/en/latest/configuration.html#loading-mathjax-from-the-cdn) for stability.
+
+
+## Installation
+
+The **basic setup** is for authoring presentations only. The **full setup** gives you access to all reveal.js features and plugins such as speaker notes as well as the development tasks needed to make changes to the source.
+
+### Basic setup
+
+The core of reveal.js is very easy to install. You'll simply need to download a copy of this repository and open the index.html file directly in your browser.
+
+1. Download the latest version of reveal.js from <https://github.com/hakimel/reveal.js/releases>
+
+2. Unzip and replace the example contents in index.html with your own
+
+3. Open index.html in a browser to view it
+
+
+### Full setup
+
+Some reveal.js features, like external markdown and speaker notes, require that presentations run from a local web server. The following instructions will set up such a server as well as all of the development tasks needed to make edits to the reveal.js source code.
+
+1. Install [Node.js](http://nodejs.org/)
+
+2. Install [Grunt](http://gruntjs.com/getting-started#installing-the-cli)
+
+4. Clone the reveal.js repository
+   ```sh
+   $ git clone https://github.com/hakimel/reveal.js.git
+   ```
+
+5. Navigate to the reveal.js folder
+   ```sh
+   $ cd reveal.js
+   ```
+
+6. Install dependencies
+   ```sh
+   $ npm install
+   ```
+
+7. Serve the presentation and monitor source files for changes
+   ```sh
+   $ grunt serve
+   ```
+
+8. Open <http://localhost:8000> to view your presentation
+
+   You can change the port by using `grunt serve --port 8001`.
+
+
+### Folder Structure
+- **css/** Core styles without which the project does not function
+- **js/** Like above but for JavaScript
+- **plugin/** Components that have been developed as extensions to reveal.js
+- **lib/** All other third party assets (JavaScript, CSS, fonts)
+
+
+### Contributing
+
+Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**. If you are reporting a bug make sure to include information about which browser and operating system you are using as well as the necessary steps to reproduce the issue.
+
+If you have personal support questions use [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
+
+
+#### Pull requests
+
+- Should follow the coding style of the file you work in, most importantly:
+  - Tabs to indent
+  - Single-quoted strings
+- Should be made towards the **dev branch**
+- Should be submitted from a feature/topic branch (not your master)
+- Should not include the minified **reveal.min.js** file
+
+
+## License
+
+MIT licensed
+
+Copyright (C) 2014 Hakim El Hattab, http://hakim.se
diff --git a/docs/slides/BOS14/_support/reveal.js/css/print/paper.css b/docs/slides/BOS14/_support/reveal.js/css/print/paper.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/print/paper.css
@@ -0,0 +1,176 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+body {
+	background: #fff;
+	font-size: 13pt;
+	width: auto;
+	height: auto;
+	border: 0;
+	margin: 0 5%;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+}
+html {
+	background: #fff;
+	width: auto;
+	height: auto;
+	overflow: visible;
+}
+
+/* SECTION 2: Remove any elements not needed in print.
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow,
+.controls,
+.reveal .progress,
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display: none !important;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div, a {
+	font-size: 16pt!important;
+	font-family: Georgia, "Times New Roman", Times, serif !important;
+	color: #000;
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Differentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	color: #000!important;
+	height: auto;
+	line-height: normal;
+	font-family: Georgia, "Times New Roman", Times, serif !important;
+	text-shadow: 0 0 0 #000 !important;
+	text-align: left;
+	letter-spacing: normal;
+}
+/* Need to reduce the size of the fonts for printing */
+h1 { font-size: 26pt !important;  }
+h2 { font-size: 22pt !important; }
+h3 { font-size: 20pt !important; }
+h4 { font-size: 20pt !important; font-variant: small-caps; }
+h5 { font-size: 19pt !important; }
+h6 { font-size: 18pt !important; font-style: italic; }
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link,
+a:visited {
+	color: #000 !important;
+	font-weight: bold;
+	text-decoration: underline;
+}
+/*
+.reveal a:link:after,
+.reveal a:visited:after {
+	content: " (" attr(href) ") ";
+	color: #222 !important;
+	font-size: 90%;
+}
+*/
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+	text-align: left !important;
+}
+.reveal .slides {
+	position: static;
+	width: auto;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin-left: auto;
+	margin-top: auto;
+	padding: auto;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides>section,
+.reveal .slides>section>section {
+
+	visibility: visible !important;
+	position: static !important;
+	width: 90% !important;
+	height: auto !important;
+	display: block !important;
+	overflow: visible !important;
+
+	left: 0% !important;
+	top: 0% !important;
+	margin-left: 0px !important;
+	margin-top: 0px !important;
+	padding: 20px 0px !important;
+
+	opacity: 1 !important;
+
+	-webkit-transform-style: flat !important;
+	   -moz-transform-style: flat !important;
+	    -ms-transform-style: flat !important;
+	        transform-style: flat !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section {
+	page-break-after: always !important;
+	display: block !important;
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+	visibility: visible !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section:last-of-type {
+	page-break-after: avoid !important;
+}
+.reveal section img {
+	display: block;
+	margin: 15px 0px;
+	background: rgba(255,255,255,1);
+	border: 1px solid #666;
+	box-shadow: none;
+}
diff --git a/docs/slides/BOS14/_support/reveal.js/css/print/pdf.css b/docs/slides/BOS14/_support/reveal.js/css/print/pdf.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/print/pdf.css
@@ -0,0 +1,190 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+
+* {
+	-webkit-print-color-adjust: exact;
+}
+
+body {
+	font-size: 18pt;
+	width: 297mm;
+	height: 229mm;
+	margin: 0 auto !important;
+	border: 0;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+}
+
+html {
+	width: 100%;
+	height: 100%;
+	overflow: visible;
+}
+
+@page {
+	size: letter landscape;
+	margin: 0;
+}
+
+/* SECTION 2: Remove any elements not needed in print.
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow,
+.controls,
+.reveal .progress,
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display: none !important;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div {
+	font-size: 18pt;
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Differentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	text-shadow: 0 0 0 #000 !important;
+}
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link,
+a:visited {
+	font-weight: normal;
+	text-decoration: underline;
+}
+
+.reveal pre code {
+	overflow: hidden !important;
+	font-family: monospace !important;
+}
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+}
+.reveal {
+	width: auto !important;
+	height: auto !important;
+	overflow: hidden !important;
+}
+.reveal .slides {
+	position: static;
+	width: 100%;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin: 0 !important;
+	padding: 0 !important;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides section {
+
+	page-break-after: always !important;
+
+	visibility: visible !important;
+	position: relative !important;
+	width: 100% !important;
+	height: 229mm !important;
+	min-height: 229mm !important;
+	display: block !important;
+	overflow: hidden !important;
+
+	left: 0 !important;
+	top: 0 !important;
+	margin: 0 !important;
+	padding: 2cm 2cm 0 2cm !important;
+	box-sizing: border-box !important;
+
+	opacity: 1 !important;
+
+	-webkit-transform-style: flat !important;
+	   -moz-transform-style: flat !important;
+	    -ms-transform-style: flat !important;
+	        transform-style: flat !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section.stack {
+	margin: 0 !important;
+	padding: 0 !important;
+	page-break-after: avoid !important;
+	height: auto !important;
+	min-height: auto !important;
+}
+.reveal .absolute-element {
+	margin-left: 2.2cm;
+	margin-top: 1.8cm;
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+	visibility: visible !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section .slide-background {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	z-index: 0;
+}
+.reveal section>* {
+	position: relative;
+	z-index: 1;
+}
+.reveal img {
+	box-shadow: none;
+}
+.reveal .roll {
+	overflow: visible;
+	line-height: 1em;
+}
+.reveal small a {
+	font-size: 16pt !important;
+}
diff --git a/docs/slides/BOS14/_support/reveal.js/css/reveal.css b/docs/slides/BOS14/_support/reveal.js/css/reveal.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/reveal.css
@@ -0,0 +1,1882 @@
+@charset "UTF-8";
+
+/*!
+ * reveal.js
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+ */
+
+
+/*********************************************
+ * RESET STYLES
+ *********************************************/
+
+html, body, .reveal div, .reveal span, .reveal applet, .reveal object, .reveal iframe,
+.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6, .reveal p, .reveal blockquote, .reveal pre,
+.reveal a, .reveal abbr, .reveal acronym, .reveal address, .reveal big, .reveal cite, .reveal code,
+.reveal del, .reveal dfn, .reveal em, .reveal img, .reveal ins, .reveal kbd, .reveal q, .reveal s, .reveal samp,
+.reveal small, .reveal strike, .reveal strong, .reveal sub, .reveal sup, .reveal tt, .reveal var,
+.reveal b, .reveal u, .reveal i, .reveal center,
+.reveal dl, .reveal dt, .reveal dd, .reveal ol, .reveal ul, .reveal li,
+.reveal fieldset, .reveal form, .reveal label, .reveal legend,
+.reveal table, .reveal caption, .reveal tbody, .reveal tfoot, .reveal thead, .reveal tr, .reveal th, .reveal td,
+.reveal article, .reveal aside, .reveal canvas, .reveal details, .reveal embed,
+.reveal figure, .reveal figcaption, .reveal footer, .reveal header, .reveal hgroup,
+.reveal menu, .reveal nav, .reveal output, .reveal ruby, .reveal section, .reveal summary,
+.reveal time, .reveal mark, .reveal audio, video {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font-size: 100%;
+	font: inherit;
+	vertical-align: baseline;
+}
+
+.reveal article, .reveal aside, .reveal details, .reveal figcaption, .reveal figure,
+.reveal footer, .reveal header, .reveal hgroup, .reveal menu, .reveal nav, .reveal section {
+	display: block;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+html,
+body {
+	width: 100%;
+	height: 100%;
+	overflow: hidden;
+}
+
+body {
+	position: relative;
+	line-height: 1;
+}
+
+::selection {
+	background: #FF5E99;
+	color: #fff;
+	text-shadow: none;
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+	-webkit-hyphens: auto;
+	   -moz-hyphens: auto;
+	        hyphens: auto;
+
+	word-wrap: break-word;
+	line-height: 1;
+}
+
+.reveal h1 { font-size: 3.77em; }
+.reveal h2 { font-size: 1.85em;	}
+.reveal h3 { font-size: 1.55em;	}
+.reveal h4 { font-size: 1em;	}
+
+
+/*********************************************
+ * VIEW FRAGMENTS
+ *********************************************/
+
+.reveal .slides section .fragment {
+	opacity: 0;
+
+	-webkit-transition: all .2s ease;
+	   -moz-transition: all .2s ease;
+	    -ms-transition: all .2s ease;
+	     -o-transition: all .2s ease;
+	        transition: all .2s ease;
+}
+	.reveal .slides section .fragment.visible {
+		opacity: 1;
+	}
+
+.reveal .slides section .fragment.grow {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.grow.visible {
+		-webkit-transform: scale( 1.3 );
+		   -moz-transform: scale( 1.3 );
+		    -ms-transform: scale( 1.3 );
+		     -o-transform: scale( 1.3 );
+		        transform: scale( 1.3 );
+	}
+
+.reveal .slides section .fragment.shrink {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.shrink.visible {
+		-webkit-transform: scale( 0.7 );
+		   -moz-transform: scale( 0.7 );
+		    -ms-transform: scale( 0.7 );
+		     -o-transform: scale( 0.7 );
+		        transform: scale( 0.7 );
+	}
+
+.reveal .slides section .fragment.zoom-in {
+	opacity: 0;
+
+	-webkit-transform: scale( 0.1 );
+	   -moz-transform: scale( 0.1 );
+	    -ms-transform: scale( 0.1 );
+	     -o-transform: scale( 0.1 );
+	        transform: scale( 0.1 );
+}
+
+	.reveal .slides section .fragment.zoom-in.visible {
+		opacity: 1;
+
+		-webkit-transform: scale( 1 );
+		   -moz-transform: scale( 1 );
+		    -ms-transform: scale( 1 );
+		     -o-transform: scale( 1 );
+		        transform: scale( 1 );
+	}
+
+.reveal .slides section .fragment.roll-in {
+	opacity: 0;
+
+	-webkit-transform: rotateX( 90deg );
+	   -moz-transform: rotateX( 90deg );
+	    -ms-transform: rotateX( 90deg );
+	     -o-transform: rotateX( 90deg );
+	        transform: rotateX( 90deg );
+}
+	.reveal .slides section .fragment.roll-in.visible {
+		opacity: 1;
+
+		-webkit-transform: rotateX( 0 );
+		   -moz-transform: rotateX( 0 );
+		    -ms-transform: rotateX( 0 );
+		     -o-transform: rotateX( 0 );
+		        transform: rotateX( 0 );
+	}
+
+.reveal .slides section .fragment.fade-out {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.fade-out.visible {
+		opacity: 0;
+	}
+
+.reveal .slides section .fragment.semi-fade-out {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.semi-fade-out.visible {
+		opacity: 0.5;
+	}
+
+.reveal .slides section .fragment.current-visible {
+	opacity:0;
+}
+
+.reveal .slides section .fragment.current-visible.current-fragment {
+	opacity:1;
+}
+
+.reveal .slides section .fragment.highlight-red,
+.reveal .slides section .fragment.highlight-current-red,
+.reveal .slides section .fragment.highlight-green,
+.reveal .slides section .fragment.highlight-current-green,
+.reveal .slides section .fragment.highlight-blue,
+.reveal .slides section .fragment.highlight-current-blue {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.highlight-red.visible {
+		color: #ff2c2d
+	}
+	.reveal .slides section .fragment.highlight-green.visible {
+		color: #17ff2e;
+	}
+	.reveal .slides section .fragment.highlight-blue.visible {
+		color: #1b91ff;
+	}
+
+.reveal .slides section .fragment.highlight-current-red.current-fragment {
+	color: #ff2c2d
+}
+.reveal .slides section .fragment.highlight-current-green.current-fragment {
+	color: #17ff2e;
+}
+.reveal .slides section .fragment.highlight-current-blue.current-fragment {
+	color: #1b91ff;
+}
+
+
+/*********************************************
+ * DEFAULT ELEMENT STYLES
+ *********************************************/
+
+/* Fixes issue in Chrome where italic fonts did not appear when printing to PDF */
+.reveal:after {
+  content: '';
+  font-style: italic;
+}
+
+.reveal iframe {
+	z-index: 1;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+	max-width: 95%;
+	max-height: 95%;
+}
+
+/** Prevents layering issues in certain browser/transition combinations */
+.reveal a {
+	position: relative;
+}
+
+.reveal strong,
+.reveal b {
+	font-weight: bold;
+}
+
+.reveal em,
+.reveal i {
+	font-style: italic;
+}
+
+.reveal ol,
+.reveal ul {
+	display: inline-block;
+
+	text-align: left;
+	margin: 0 0 0 1em;
+}
+
+.reveal ol {
+	list-style-type: decimal;
+}
+
+.reveal ul {
+	list-style-type: disc;
+}
+
+.reveal ul ul {
+	list-style-type: square;
+}
+
+.reveal ul ul ul {
+	list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+	display: block;
+	margin-left: 40px;
+}
+
+.reveal p {
+	margin-bottom: 10px;
+	line-height: 1.2em;
+}
+
+.reveal q,
+.reveal blockquote {
+	quotes: none;
+}
+
+.reveal blockquote {
+	display: block;
+	position: relative;
+	width: 70%;
+	margin: 5px auto;
+	padding: 5px;
+
+	font-style: italic;
+	background: rgba(255, 255, 255, 0.05);
+	box-shadow: 0px 0px 2px rgba(0,0,0,0.2);
+}
+	.reveal blockquote p:first-child,
+	.reveal blockquote p:last-child {
+		display: inline-block;
+	}
+
+.reveal q {
+	font-style: italic;
+}
+
+.reveal pre {
+	display: block;
+	position: relative;
+	width: 90%;
+	margin: 10px auto;
+
+	text-align: left;
+	font-size: 0.81em;
+	font-family: monospace;
+	line-height: 1.2em;
+
+	word-wrap: break-word;
+
+	box-shadow: 0px 0px 6px rgba(0,0,0,0.3);
+}
+.reveal code {
+	font-family: monospace;
+	font-size: 0.81em;
+}
+.reveal pre code {
+	padding: 5px;
+	overflow: auto;
+	max-height: 400px;
+	word-wrap: normal;
+}
+.reveal pre.stretch code {
+	height: 100%;
+	max-height: 100%;
+
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+
+.reveal table th,
+.reveal table td {
+	text-align: left;
+	padding-right: .3em;
+}
+
+.reveal table th {
+	font-weight: bold;
+}
+
+.reveal sup {
+	vertical-align: super;
+}
+.reveal sub {
+	vertical-align: sub;
+}
+
+.reveal small {
+	display: inline-block;
+	font-size: 0.6em;
+	line-height: 1.2em;
+	vertical-align: top;
+}
+
+.reveal small * {
+	vertical-align: top;
+}
+
+.reveal .stretch {
+	max-width: none;
+	max-height: none;
+}
+
+
+/*********************************************
+ * CONTROLS
+ *********************************************/
+
+.reveal .controls {
+	display: none;
+	position: fixed;
+	width: 110px;
+	height: 110px;
+	z-index: 30;
+	right: 10px;
+	bottom: 10px;
+}
+
+.reveal .controls div {
+	position: absolute;
+	opacity: 0.05;
+	width: 0;
+	height: 0;
+	border: 12px solid transparent;
+
+	-moz-transform: scale(.9999);
+
+	-webkit-transition: all 0.2s ease;
+	   -moz-transition: all 0.2s ease;
+	    -ms-transition: all 0.2s ease;
+	     -o-transition: all 0.2s ease;
+	        transition: all 0.2s ease;
+}
+
+.reveal .controls div.enabled {
+	opacity: 0.7;
+	cursor: pointer;
+}
+
+.reveal .controls div.enabled:active {
+	margin-top: 1px;
+}
+
+	.reveal .controls div.navigate-left {
+		top: 42px;
+
+		border-right-width: 22px;
+		border-right-color: #eee;
+	}
+		.reveal .controls div.navigate-left.fragmented {
+			opacity: 0.3;
+		}
+
+	.reveal .controls div.navigate-right {
+		left: 74px;
+		top: 42px;
+
+		border-left-width: 22px;
+		border-left-color: #eee;
+	}
+		.reveal .controls div.navigate-right.fragmented {
+			opacity: 0.3;
+		}
+
+	.reveal .controls div.navigate-up {
+		left: 42px;
+
+		border-bottom-width: 22px;
+		border-bottom-color: #eee;
+	}
+		.reveal .controls div.navigate-up.fragmented {
+			opacity: 0.3;
+		}
+
+	.reveal .controls div.navigate-down {
+		left: 42px;
+		top: 74px;
+
+		border-top-width: 22px;
+		border-top-color: #eee;
+	}
+		.reveal .controls div.navigate-down.fragmented {
+			opacity: 0.3;
+		}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	position: fixed;
+	display: none;
+	height: 3px;
+	width: 100%;
+	bottom: 0;
+	left: 0;
+	z-index: 10;
+}
+	.reveal .progress:after {
+		content: '';
+		display: 'block';
+		position: absolute;
+		height: 20px;
+		width: 100%;
+		top: -20px;
+	}
+	.reveal .progress span {
+		display: block;
+		height: 100%;
+		width: 0px;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+
+.reveal .slide-number {
+	position: fixed;
+	display: block;
+	right: 15px;
+	bottom: 15px;
+	opacity: 0.5;
+	z-index: 31;
+	font-size: 12px;
+}
+
+/*********************************************
+ * SLIDES
+ *********************************************/
+
+.reveal {
+	position: relative;
+	width: 100%;
+	height: 100%;
+
+	-ms-touch-action: none;
+}
+
+.reveal .slides {
+	position: absolute;
+    max-width: 1024px;
+	width: 120%;
+	height: 100%;
+	left: 50%;
+	top: 50%;
+
+	overflow: visible;
+	z-index: 1;
+	text-align: center;
+
+	-webkit-transition: -webkit-perspective .4s ease;
+	   -moz-transition: -moz-perspective .4s ease;
+	    -ms-transition: -ms-perspective .4s ease;
+	     -o-transition: -o-perspective .4s ease;
+	        transition: perspective .4s ease;
+
+	-webkit-perspective: 600px;
+	   -moz-perspective: 600px;
+	    -ms-perspective: 600px;
+	        perspective: 600px;
+
+	-webkit-perspective-origin: 0px -100px;
+	   -moz-perspective-origin: 0px -100px;
+	    -ms-perspective-origin: 0px -100px;
+	        perspective-origin: 0px -100px;
+}
+
+.reveal .slides>section {
+	-ms-perspective: 600px;
+}
+
+.reveal .slides>section,
+.reveal .slides>section>section {
+	display: none;
+	position: absolute;
+	width: 100%;
+	padding: 20px 0px;
+
+	z-index: 10;
+	line-height: 1.2em;
+	font-weight: inherit;
+
+	-webkit-transform-style: preserve-3d;
+	   -moz-transform-style: preserve-3d;
+	    -ms-transform-style: preserve-3d;
+	        transform-style: preserve-3d;
+
+	-webkit-transition: -webkit-transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						-webkit-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	   -moz-transition: -moz-transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						-moz-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	    -ms-transition: -ms-transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						-ms-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	     -o-transition: -o-transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						-o-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	        transition: transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+}
+
+/* Global transition speed settings */
+.reveal[data-transition-speed="fast"] .slides section {
+	-webkit-transition-duration: 400ms;
+	   -moz-transition-duration: 400ms;
+	    -ms-transition-duration: 400ms;
+	        transition-duration: 400ms;
+}
+.reveal[data-transition-speed="slow"] .slides section {
+	-webkit-transition-duration: 1200ms;
+	   -moz-transition-duration: 1200ms;
+	    -ms-transition-duration: 1200ms;
+	        transition-duration: 1200ms;
+}
+
+/* Slide-specific transition speed overrides */
+.reveal .slides section[data-transition-speed="fast"] {
+	-webkit-transition-duration: 400ms;
+	   -moz-transition-duration: 400ms;
+	    -ms-transition-duration: 400ms;
+	        transition-duration: 400ms;
+}
+.reveal .slides section[data-transition-speed="slow"] {
+	-webkit-transition-duration: 1200ms;
+	   -moz-transition-duration: 1200ms;
+	    -ms-transition-duration: 1200ms;
+	        transition-duration: 1200ms;
+}
+
+.reveal .slides>section {
+	left: -50%;
+	top: -50%;
+}
+
+.reveal .slides>section.stack {
+	padding-top: 0;
+	padding-bottom: 0;
+}
+
+.reveal .slides>section.present,
+.reveal .slides>section>section.present {
+	display: block;
+	z-index: 11;
+	opacity: 1;
+}
+
+.reveal.center,
+.reveal.center .slides,
+.reveal.center .slides section {
+	min-height: auto !important;
+}
+
+/* Don't allow interaction with invisible slides */
+.reveal .slides>section.future,
+.reveal .slides>section>section.future,
+.reveal .slides>section.past,
+.reveal .slides>section>section.past {
+	pointer-events: none;
+}
+
+.reveal.overview .slides>section,
+.reveal.overview .slides>section>section {
+	pointer-events: auto;
+}
+
+
+
+/*********************************************
+ * DEFAULT TRANSITION
+ *********************************************/
+
+.reveal .slides>section[data-transition=default].past,
+.reveal .slides>section.past {
+	display: block;
+	opacity: 0;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+}
+.reveal .slides>section[data-transition=default].future,
+.reveal .slides>section.future {
+	display: block;
+	opacity: 0;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+}
+
+.reveal .slides>section>section[data-transition=default].past,
+.reveal .slides>section>section.past {
+	display: block;
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0);
+	   -moz-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0);
+	    -ms-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0);
+	        transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0);
+}
+.reveal .slides>section>section[data-transition=default].future,
+.reveal .slides>section>section.future {
+	display: block;
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
+	   -moz-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
+	    -ms-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
+	        transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
+}
+
+
+/*********************************************
+ * CONCAVE TRANSITION
+ *********************************************/
+
+.reveal .slides>section[data-transition=concave].past,
+.reveal.concave  .slides>section.past {
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+}
+.reveal .slides>section[data-transition=concave].future,
+.reveal.concave .slides>section.future {
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+}
+
+.reveal .slides>section>section[data-transition=concave].past,
+.reveal.concave .slides>section>section.past {
+	-webkit-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	   -moz-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	    -ms-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	        transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+}
+.reveal .slides>section>section[data-transition=concave].future,
+.reveal.concave .slides>section>section.future {
+	-webkit-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	   -moz-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	    -ms-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	        transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+}
+
+
+/*********************************************
+ * ZOOM TRANSITION
+ *********************************************/
+
+.reveal .slides>section[data-transition=zoom],
+.reveal.zoom .slides>section {
+	-webkit-transition-timing-function: ease;
+	   -moz-transition-timing-function: ease;
+	    -ms-transition-timing-function: ease;
+	     -o-transition-timing-function: ease;
+	        transition-timing-function: ease;
+}
+
+.reveal .slides>section[data-transition=zoom].past,
+.reveal.zoom .slides>section.past {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(16);
+	   -moz-transform: scale(16);
+	    -ms-transform: scale(16);
+	     -o-transform: scale(16);
+	        transform: scale(16);
+}
+.reveal .slides>section[data-transition=zoom].future,
+.reveal.zoom .slides>section.future {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(0.2);
+	   -moz-transform: scale(0.2);
+	    -ms-transform: scale(0.2);
+	     -o-transform: scale(0.2);
+	        transform: scale(0.2);
+}
+
+.reveal .slides>section>section[data-transition=zoom].past,
+.reveal.zoom .slides>section>section.past {
+	-webkit-transform: translate(0, -150%);
+	   -moz-transform: translate(0, -150%);
+	    -ms-transform: translate(0, -150%);
+	     -o-transform: translate(0, -150%);
+	        transform: translate(0, -150%);
+}
+.reveal .slides>section>section[data-transition=zoom].future,
+.reveal.zoom .slides>section>section.future {
+	-webkit-transform: translate(0, 150%);
+	   -moz-transform: translate(0, 150%);
+	    -ms-transform: translate(0, 150%);
+	     -o-transform: translate(0, 150%);
+	        transform: translate(0, 150%);
+}
+
+
+/*********************************************
+ * LINEAR TRANSITION
+ *********************************************/
+
+.reveal.linear section {
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	    -ms-backface-visibility: hidden;
+	        backface-visibility: hidden;
+}
+
+.reveal .slides>section[data-transition=linear].past,
+.reveal.linear .slides>section.past {
+	-webkit-transform: translate(-150%, 0);
+	   -moz-transform: translate(-150%, 0);
+	    -ms-transform: translate(-150%, 0);
+	     -o-transform: translate(-150%, 0);
+	        transform: translate(-150%, 0);
+}
+.reveal .slides>section[data-transition=linear].future,
+.reveal.linear .slides>section.future {
+	-webkit-transform: translate(150%, 0);
+	   -moz-transform: translate(150%, 0);
+	    -ms-transform: translate(150%, 0);
+	     -o-transform: translate(150%, 0);
+	        transform: translate(150%, 0);
+}
+
+.reveal .slides>section>section[data-transition=linear].past,
+.reveal.linear .slides>section>section.past {
+	-webkit-transform: translate(0, -150%);
+	   -moz-transform: translate(0, -150%);
+	    -ms-transform: translate(0, -150%);
+	     -o-transform: translate(0, -150%);
+	        transform: translate(0, -150%);
+}
+.reveal .slides>section>section[data-transition=linear].future,
+.reveal.linear .slides>section>section.future {
+	-webkit-transform: translate(0, 150%);
+	   -moz-transform: translate(0, 150%);
+	    -ms-transform: translate(0, 150%);
+	     -o-transform: translate(0, 150%);
+	        transform: translate(0, 150%);
+}
+
+
+/*********************************************
+ * CUBE TRANSITION
+ *********************************************/
+
+.reveal.cube .slides {
+	-webkit-perspective: 1300px;
+	   -moz-perspective: 1300px;
+	    -ms-perspective: 1300px;
+	        perspective: 1300px;
+}
+
+.reveal.cube .slides section {
+	padding: 30px;
+	min-height: 700px;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	    -ms-backface-visibility: hidden;
+	        backface-visibility: hidden;
+
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+	.reveal.center.cube .slides section {
+		min-height: auto;
+	}
+	.reveal.cube .slides section:not(.stack):before {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+		background: rgba(0,0,0,0.1);
+		border-radius: 4px;
+
+		-webkit-transform: translateZ( -20px );
+		   -moz-transform: translateZ( -20px );
+		    -ms-transform: translateZ( -20px );
+		     -o-transform: translateZ( -20px );
+		        transform: translateZ( -20px );
+	}
+	.reveal.cube .slides section:not(.stack):after {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 90%;
+		height: 30px;
+		left: 5%;
+		bottom: 0;
+		background: none;
+		z-index: 1;
+
+		border-radius: 4px;
+		box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ(-90px) rotateX( 65deg );
+		   -moz-transform: translateZ(-90px) rotateX( 65deg );
+		    -ms-transform: translateZ(-90px) rotateX( 65deg );
+		     -o-transform: translateZ(-90px) rotateX( 65deg );
+		        transform: translateZ(-90px) rotateX( 65deg );
+	}
+
+.reveal.cube .slides>section.stack {
+	padding: 0;
+	background: none;
+}
+
+.reveal.cube .slides>section.past {
+	-webkit-transform-origin: 100% 0%;
+	   -moz-transform-origin: 100% 0%;
+	    -ms-transform-origin: 100% 0%;
+	        transform-origin: 100% 0%;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+}
+
+.reveal.cube .slides>section.future {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg);
+}
+
+.reveal.cube .slides>section>section.past {
+	-webkit-transform-origin: 0% 100%;
+	   -moz-transform-origin: 0% 100%;
+	    -ms-transform-origin: 0% 100%;
+	        transform-origin: 0% 100%;
+
+	-webkit-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	   -moz-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	    -ms-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	        transform: translate3d(0, -100%, 0) rotateX(90deg);
+}
+
+.reveal.cube .slides>section>section.future {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	   -moz-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	    -ms-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	        transform: translate3d(0, 100%, 0) rotateX(-90deg);
+}
+
+
+/*********************************************
+ * PAGE TRANSITION
+ *********************************************/
+
+.reveal.page .slides {
+	-webkit-perspective-origin: 0% 50%;
+	   -moz-perspective-origin: 0% 50%;
+	    -ms-perspective-origin: 0% 50%;
+	        perspective-origin: 0% 50%;
+
+	-webkit-perspective: 3000px;
+	   -moz-perspective: 3000px;
+	    -ms-perspective: 3000px;
+	        perspective: 3000px;
+}
+
+.reveal.page .slides section {
+	padding: 30px;
+	min-height: 700px;
+
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+	.reveal.page .slides section.past {
+		z-index: 12;
+	}
+	.reveal.page .slides section:not(.stack):before {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+		background: rgba(0,0,0,0.1);
+
+		-webkit-transform: translateZ( -20px );
+		   -moz-transform: translateZ( -20px );
+		    -ms-transform: translateZ( -20px );
+		     -o-transform: translateZ( -20px );
+		        transform: translateZ( -20px );
+	}
+	.reveal.page .slides section:not(.stack):after {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 90%;
+		height: 30px;
+		left: 5%;
+		bottom: 0;
+		background: none;
+		z-index: 1;
+
+		border-radius: 4px;
+		box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ(-90px) rotateX( 65deg );
+	}
+
+.reveal.page .slides>section.stack {
+	padding: 0;
+	background: none;
+}
+
+.reveal.page .slides>section.past {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	   -moz-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	    -ms-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	        transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+}
+
+.reveal.page .slides>section.future {
+	-webkit-transform-origin: 100% 0%;
+	   -moz-transform-origin: 100% 0%;
+	    -ms-transform-origin: 100% 0%;
+	        transform-origin: 100% 0%;
+
+	-webkit-transform: translate3d(0, 0, 0);
+	   -moz-transform: translate3d(0, 0, 0);
+	    -ms-transform: translate3d(0, 0, 0);
+	        transform: translate3d(0, 0, 0);
+}
+
+.reveal.page .slides>section>section.past {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	   -moz-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	    -ms-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	        transform: translate3d(0, -40%, 0) rotateX(80deg);
+}
+
+.reveal.page .slides>section>section.future {
+	-webkit-transform-origin: 0% 100%;
+	   -moz-transform-origin: 0% 100%;
+	    -ms-transform-origin: 0% 100%;
+	        transform-origin: 0% 100%;
+
+	-webkit-transform: translate3d(0, 0, 0);
+	   -moz-transform: translate3d(0, 0, 0);
+	    -ms-transform: translate3d(0, 0, 0);
+	        transform: translate3d(0, 0, 0);
+}
+
+
+/*********************************************
+ * FADE TRANSITION
+ *********************************************/
+
+.reveal .slides section[data-transition=fade],
+.reveal.fade .slides section,
+.reveal.fade .slides>section>section {
+    -webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	     -o-transform: none;
+	        transform: none;
+
+	-webkit-transition: opacity 0.5s;
+	   -moz-transition: opacity 0.5s;
+	    -ms-transition: opacity 0.5s;
+	     -o-transition: opacity 0.5s;
+	        transition: opacity 0.5s;
+}
+
+
+.reveal.fade.overview .slides section,
+.reveal.fade.overview .slides>section>section,
+.reveal.fade.overview-deactivating .slides section,
+.reveal.fade.overview-deactivating .slides>section>section {
+	-webkit-transition: none;
+	   -moz-transition: none;
+	    -ms-transition: none;
+	     -o-transition: none;
+	        transition: none;
+}
+
+
+/*********************************************
+ * NO TRANSITION
+ *********************************************/
+
+.reveal .slides section[data-transition=none],
+.reveal.none .slides section {
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	     -o-transform: none;
+	        transform: none;
+
+	-webkit-transition: none;
+	   -moz-transition: none;
+	    -ms-transition: none;
+	     -o-transition: none;
+	        transition: none;
+}
+
+
+/*********************************************
+ * OVERVIEW
+ *********************************************/
+
+.reveal.overview .slides {
+	-webkit-perspective-origin: 0% 0%;
+	   -moz-perspective-origin: 0% 0%;
+	    -ms-perspective-origin: 0% 0%;
+	        perspective-origin: 0% 0%;
+
+	-webkit-perspective: 700px;
+	   -moz-perspective: 700px;
+	    -ms-perspective: 700px;
+	        perspective: 700px;
+}
+
+.reveal.overview .slides section {
+	height: 600px;
+	top: -300px !important;
+	overflow: hidden;
+	opacity: 1 !important;
+	visibility: visible !important;
+	cursor: pointer;
+	background: rgba(0,0,0,0.1);
+}
+.reveal.overview .slides section .fragment {
+	opacity: 1;
+}
+.reveal.overview .slides section:after,
+.reveal.overview .slides section:before {
+	display: none !important;
+}
+.reveal.overview .slides section>section {
+	opacity: 1;
+	cursor: pointer;
+}
+	.reveal.overview .slides section:hover {
+		background: rgba(0,0,0,0.3);
+	}
+	.reveal.overview .slides section.present {
+		background: rgba(0,0,0,0.3);
+	}
+.reveal.overview .slides>section.stack {
+	padding: 0;
+	top: 0 !important;
+	background: none;
+	overflow: visible;
+}
+
+
+/*********************************************
+ * PAUSED MODE
+ *********************************************/
+
+.reveal .pause-overlay {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	background: black;
+	visibility: hidden;
+	opacity: 0;
+	z-index: 100;
+
+	-webkit-transition: all 1s ease;
+	   -moz-transition: all 1s ease;
+	    -ms-transition: all 1s ease;
+	     -o-transition: all 1s ease;
+	        transition: all 1s ease;
+}
+.reveal.paused .pause-overlay {
+	visibility: visible;
+	opacity: 1;
+}
+
+
+/*********************************************
+ * FALLBACK
+ *********************************************/
+
+.no-transforms {
+	overflow-y: auto;
+}
+
+.no-transforms .reveal .slides {
+	position: relative;
+	width: 80%;
+	height: auto !important;
+	top: 0;
+	left: 50%;
+	margin: 0;
+	text-align: center;
+}
+
+.no-transforms .reveal .controls,
+.no-transforms .reveal .progress {
+	display: none !important;
+}
+
+.no-transforms .reveal .slides section {
+	display: block !important;
+	opacity: 1 !important;
+	position: relative !important;
+	height: auto;
+	min-height: auto;
+	top: 0;
+	left: -50%;
+	margin: 70px 0;
+
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	     -o-transform: none;
+	        transform: none;
+}
+
+.no-transforms .reveal .slides section section {
+	left: 0;
+}
+
+.reveal .no-transition,
+.reveal .no-transition * {
+	-webkit-transition: none !important;
+	   -moz-transition: none !important;
+	    -ms-transition: none !important;
+	     -o-transition: none !important;
+	        transition: none !important;
+}
+
+
+/*********************************************
+ * BACKGROUND STATES [DEPRECATED]
+ *********************************************/
+
+.reveal .state-background {
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	background: rgba( 0, 0, 0, 0 );
+
+	-webkit-transition: background 800ms ease;
+	   -moz-transition: background 800ms ease;
+	    -ms-transition: background 800ms ease;
+	     -o-transition: background 800ms ease;
+	        transition: background 800ms ease;
+}
+.alert .reveal .state-background {
+	background: rgba( 200, 50, 30, 0.6 );
+}
+.soothe .reveal .state-background {
+	background: rgba( 50, 200, 90, 0.4 );
+}
+.blackout .reveal .state-background {
+	background: rgba( 0, 0, 0, 0.6 );
+}
+.whiteout .reveal .state-background {
+	background: rgba( 255, 255, 255, 0.6 );
+}
+.cobalt .reveal .state-background {
+	background: rgba( 22, 152, 213, 0.6 );
+}
+.mint .reveal .state-background {
+	background: rgba( 22, 213, 75, 0.6 );
+}
+.submerge .reveal .state-background {
+	background: rgba( 12, 25, 77, 0.6);
+}
+.lila .reveal .state-background {
+	background: rgba( 180, 50, 140, 0.6 );
+}
+.sunset .reveal .state-background {
+	background: rgba( 255, 122, 0, 0.6 );
+}
+
+
+/*********************************************
+ * PER-SLIDE BACKGROUNDS
+ *********************************************/
+
+.reveal>.backgrounds {
+	position: absolute;
+	width: 100%;
+	height: 100%;
+
+	-webkit-perspective: 600px;
+	   -moz-perspective: 600px;
+	    -ms-perspective: 600px;
+	        perspective: 600px;
+}
+	.reveal .slide-background {
+		position: absolute;
+		width: 100%;
+		height: 100%;
+		opacity: 0;
+		visibility: hidden;
+
+		background-color: rgba( 0, 0, 0, 0 );
+		background-position: 50% 50%;
+		background-repeat: no-repeat;
+		background-size: cover;
+
+		-webkit-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+	.reveal .slide-background.present {
+		opacity: 1;
+		visibility: visible;
+	}
+
+	.print-pdf .reveal .slide-background {
+		opacity: 1 !important;
+		visibility: visible !important;
+	}
+
+/* Immediate transition style */
+.reveal[data-background-transition=none]>.backgrounds .slide-background,
+.reveal>.backgrounds .slide-background[data-background-transition=none] {
+	-webkit-transition: none;
+	   -moz-transition: none;
+	    -ms-transition: none;
+	     -o-transition: none;
+	        transition: none;
+}
+
+/* 2D slide */
+.reveal[data-background-transition=slide]>.backgrounds .slide-background,
+.reveal>.backgrounds .slide-background[data-background-transition=slide] {
+	opacity: 1;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	    -ms-backface-visibility: hidden;
+	        backface-visibility: hidden;
+}
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background.past,
+	.reveal>.backgrounds .slide-background.past[data-background-transition=slide] {
+		-webkit-transform: translate(-100%, 0);
+		   -moz-transform: translate(-100%, 0);
+		    -ms-transform: translate(-100%, 0);
+		     -o-transform: translate(-100%, 0);
+		        transform: translate(-100%, 0);
+	}
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background.future,
+	.reveal>.backgrounds .slide-background.future[data-background-transition=slide] {
+		-webkit-transform: translate(100%, 0);
+		   -moz-transform: translate(100%, 0);
+		    -ms-transform: translate(100%, 0);
+		     -o-transform: translate(100%, 0);
+		        transform: translate(100%, 0);
+	}
+
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past,
+	.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide] {
+		-webkit-transform: translate(0, -100%);
+		   -moz-transform: translate(0, -100%);
+		    -ms-transform: translate(0, -100%);
+		     -o-transform: translate(0, -100%);
+		        transform: translate(0, -100%);
+	}
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future,
+	.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide] {
+		-webkit-transform: translate(0, 100%);
+		   -moz-transform: translate(0, 100%);
+		    -ms-transform: translate(0, 100%);
+		     -o-transform: translate(0, 100%);
+		        transform: translate(0, 100%);
+	}
+
+
+/* Convex */
+.reveal[data-background-transition=convex]>.backgrounds .slide-background.past,
+.reveal>.backgrounds .slide-background.past[data-background-transition=convex] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+}
+.reveal[data-background-transition=convex]>.backgrounds .slide-background.future,
+.reveal>.backgrounds .slide-background.future[data-background-transition=convex] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+}
+
+.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past,
+.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
+	   -moz-transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
+	    -ms-transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
+	        transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
+}
+.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future,
+.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
+	   -moz-transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
+	    -ms-transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
+	        transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
+}
+
+
+/* Concave */
+.reveal[data-background-transition=concave]>.backgrounds .slide-background.past,
+.reveal>.backgrounds .slide-background.past[data-background-transition=concave] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+}
+.reveal[data-background-transition=concave]>.backgrounds .slide-background.future,
+.reveal>.backgrounds .slide-background.future[data-background-transition=concave] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+}
+
+.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past,
+.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
+	   -moz-transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
+	    -ms-transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
+	        transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
+}
+.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future,
+.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
+	   -moz-transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
+	    -ms-transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
+	        transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
+}
+
+/* Zoom */
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background,
+.reveal>.backgrounds .slide-background[data-background-transition=zoom] {
+	-webkit-transition-timing-function: ease;
+	   -moz-transition-timing-function: ease;
+	    -ms-transition-timing-function: ease;
+	     -o-transition-timing-function: ease;
+	        transition-timing-function: ease;
+}
+
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past,
+.reveal>.backgrounds .slide-background.past[data-background-transition=zoom] {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(16);
+	   -moz-transform: scale(16);
+	    -ms-transform: scale(16);
+	     -o-transform: scale(16);
+	        transform: scale(16);
+}
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future,
+.reveal>.backgrounds .slide-background.future[data-background-transition=zoom] {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(0.2);
+	   -moz-transform: scale(0.2);
+	    -ms-transform: scale(0.2);
+	     -o-transform: scale(0.2);
+	        transform: scale(0.2);
+}
+
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past,
+.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom] {
+	opacity: 0;
+		visibility: hidden;
+
+		-webkit-transform: scale(16);
+		   -moz-transform: scale(16);
+		    -ms-transform: scale(16);
+		     -o-transform: scale(16);
+		        transform: scale(16);
+}
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future,
+.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom] {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(0.2);
+	   -moz-transform: scale(0.2);
+	    -ms-transform: scale(0.2);
+	     -o-transform: scale(0.2);
+	        transform: scale(0.2);
+}
+
+
+/* Global transition speed settings */
+.reveal[data-transition-speed="fast"]>.backgrounds .slide-background {
+	-webkit-transition-duration: 400ms;
+	   -moz-transition-duration: 400ms;
+	    -ms-transition-duration: 400ms;
+	        transition-duration: 400ms;
+}
+.reveal[data-transition-speed="slow"]>.backgrounds .slide-background {
+	-webkit-transition-duration: 1200ms;
+	   -moz-transition-duration: 1200ms;
+	    -ms-transition-duration: 1200ms;
+	        transition-duration: 1200ms;
+}
+
+
+/*********************************************
+ * RTL SUPPORT
+ *********************************************/
+
+.reveal.rtl .slides,
+.reveal.rtl .slides h1,
+.reveal.rtl .slides h2,
+.reveal.rtl .slides h3,
+.reveal.rtl .slides h4,
+.reveal.rtl .slides h5,
+.reveal.rtl .slides h6 {
+	direction: rtl;
+	font-family: sans-serif;
+}
+
+.reveal.rtl pre,
+.reveal.rtl code {
+	direction: ltr;
+}
+
+.reveal.rtl ol,
+.reveal.rtl ul {
+	text-align: right;
+}
+
+.reveal.rtl .progress span {
+	float: right
+}
+
+/*********************************************
+ * PARALLAX BACKGROUND
+ *********************************************/
+
+.reveal.has-parallax-background .backgrounds {
+	-webkit-transition: all 0.8s ease;
+	   -moz-transition: all 0.8s ease;
+	    -ms-transition: all 0.8s ease;
+	        transition: all 0.8s ease;
+}
+
+/* Global transition speed settings */
+.reveal.has-parallax-background[data-transition-speed="fast"] .backgrounds {
+	-webkit-transition-duration: 400ms;
+	   -moz-transition-duration: 400ms;
+	    -ms-transition-duration: 400ms;
+	        transition-duration: 400ms;
+}
+.reveal.has-parallax-background[data-transition-speed="slow"] .backgrounds {
+	-webkit-transition-duration: 1200ms;
+	   -moz-transition-duration: 1200ms;
+	    -ms-transition-duration: 1200ms;
+	        transition-duration: 1200ms;
+}
+
+
+/*********************************************
+ * LINK PREVIEW OVERLAY
+ *********************************************/
+
+ .reveal .preview-link-overlay {
+ 	position: absolute;
+ 	top: 0;
+ 	left: 0;
+ 	width: 100%;
+ 	height: 100%;
+ 	z-index: 1000;
+ 	background: rgba( 0, 0, 0, 0.9 );
+ 	opacity: 0;
+ 	visibility: hidden;
+
+ 	-webkit-transition: all 0.3s ease;
+ 	   -moz-transition: all 0.3s ease;
+ 	    -ms-transition: all 0.3s ease;
+ 	        transition: all 0.3s ease;
+ }
+ 	.reveal .preview-link-overlay.visible {
+ 		opacity: 1;
+ 		visibility: visible;
+ 	}
+
+ 	.reveal .preview-link-overlay .spinner {
+ 		position: absolute;
+ 		display: block;
+ 		top: 50%;
+ 		left: 50%;
+ 		width: 32px;
+ 		height: 32px;
+ 		margin: -16px 0 0 -16px;
+ 		z-index: 10;
+ 		background-image: url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D);
+
+ 		visibility: visible;
+ 		opacity: 0.6;
+
+ 		-webkit-transition: all 0.3s ease;
+ 		   -moz-transition: all 0.3s ease;
+ 		    -ms-transition: all 0.3s ease;
+ 		        transition: all 0.3s ease;
+ 	}
+
+ 	.reveal .preview-link-overlay header {
+ 		position: absolute;
+ 		left: 0;
+ 		top: 0;
+ 		width: 100%;
+ 		height: 40px;
+ 		z-index: 2;
+ 		border-bottom: 1px solid #222;
+ 	}
+ 		.reveal .preview-link-overlay header a {
+ 			display: inline-block;
+ 			width: 40px;
+ 			height: 40px;
+ 			padding: 0 10px;
+ 			float: right;
+ 			opacity: 0.6;
+
+ 			box-sizing: border-box;
+ 		}
+ 			.reveal .preview-link-overlay header a:hover {
+ 				opacity: 1;
+ 			}
+ 			.reveal .preview-link-overlay header a .icon {
+ 				display: inline-block;
+ 				width: 20px;
+ 				height: 20px;
+
+ 				background-position: 50% 50%;
+ 				background-size: 100%;
+ 				background-repeat: no-repeat;
+ 			}
+ 			.reveal .preview-link-overlay header a.close .icon {
+ 				background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC);
+ 			}
+ 			.reveal .preview-link-overlay header a.external .icon {
+ 				background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==);
+ 			}
+
+ 	.reveal .preview-link-overlay .viewport {
+ 		position: absolute;
+ 		top: 40px;
+ 		right: 0;
+ 		bottom: 0;
+ 		left: 0;
+ 	}
+
+ 	.reveal .preview-link-overlay .viewport iframe {
+ 		width: 100%;
+ 		height: 100%;
+ 		max-width: 100%;
+ 		max-height: 100%;
+ 		border: 0;
+
+ 		opacity: 0;
+ 		visibility: hidden;
+
+ 		-webkit-transition: all 0.3s ease;
+ 		   -moz-transition: all 0.3s ease;
+ 		    -ms-transition: all 0.3s ease;
+ 		        transition: all 0.3s ease;
+ 	}
+
+ 	.reveal .preview-link-overlay.loaded .viewport iframe {
+ 		opacity: 1;
+ 		visibility: visible;
+ 	}
+
+ 	.reveal .preview-link-overlay.loaded .spinner {
+ 		opacity: 0;
+ 		visibility: hidden;
+
+ 		-webkit-transform: scale(0.2);
+ 		   -moz-transform: scale(0.2);
+ 		    -ms-transform: scale(0.2);
+ 		        transform: scale(0.2);
+ 	}
+
+
+
+/*********************************************
+ * PLAYBACK COMPONENT
+ *********************************************/
+
+.reveal .playback {
+	position: fixed;
+	left: 15px;
+	bottom: 15px;
+	z-index: 30;
+	cursor: pointer;
+
+	-webkit-transition: all 400ms ease;
+	   -moz-transition: all 400ms ease;
+	    -ms-transition: all 400ms ease;
+	        transition: all 400ms ease;
+}
+
+.reveal.overview .playback {
+	opacity: 0;
+	visibility: hidden;
+}
+
+
+/*********************************************
+ * ROLLING LINKS
+ *********************************************/
+
+.reveal .roll {
+	display: inline-block;
+	line-height: 1.2;
+	overflow: hidden;
+
+	vertical-align: top;
+
+	-webkit-perspective: 400px;
+	   -moz-perspective: 400px;
+	    -ms-perspective: 400px;
+	        perspective: 400px;
+
+	-webkit-perspective-origin: 50% 50%;
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+	.reveal .roll:hover {
+		background: none;
+		text-shadow: none;
+	}
+.reveal .roll span {
+	display: block;
+	position: relative;
+	padding: 0 2px;
+
+	pointer-events: none;
+
+	-webkit-transition: all 400ms ease;
+	   -moz-transition: all 400ms ease;
+	    -ms-transition: all 400ms ease;
+	        transition: all 400ms ease;
+
+	-webkit-transform-origin: 50% 0%;
+	   -moz-transform-origin: 50% 0%;
+	    -ms-transform-origin: 50% 0%;
+	        transform-origin: 50% 0%;
+
+	-webkit-transform-style: preserve-3d;
+	   -moz-transform-style: preserve-3d;
+	    -ms-transform-style: preserve-3d;
+	        transform-style: preserve-3d;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	        backface-visibility: hidden;
+}
+	.reveal .roll:hover span {
+	    background: rgba(0,0,0,0.5);
+
+	    -webkit-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	       -moz-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	        -ms-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	            transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	}
+.reveal .roll span:after {
+	content: attr(data-title);
+
+	display: block;
+	position: absolute;
+	left: 0;
+	top: 0;
+	padding: 0 2px;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	        backface-visibility: hidden;
+
+	-webkit-transform-origin: 50% 0%;
+	   -moz-transform-origin: 50% 0%;
+	    -ms-transform-origin: 50% 0%;
+	        transform-origin: 50% 0%;
+
+	-webkit-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	   -moz-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	    -ms-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	        transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+}
+
+
+/*********************************************
+ * SPEAKER NOTES
+ *********************************************/
+
+.reveal aside.notes {
+	display: none;
+}
+
+
+/*********************************************
+ * ZOOM PLUGIN
+ *********************************************/
+
+.zoomed .reveal *,
+.zoomed .reveal *:before,
+.zoomed .reveal *:after {
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+
+	-webkit-backface-visibility: visible !important;
+	   -moz-backface-visibility: visible !important;
+	    -ms-backface-visibility: visible !important;
+	        backface-visibility: visible !important;
+}
+
+.zoomed .reveal .progress,
+.zoomed .reveal .controls {
+	opacity: 0;
+}
+
+.zoomed .reveal .roll span {
+	background: none;
+}
+
+.zoomed .reveal .roll span:after {
+	visibility: hidden;
+}
+
+
diff --git a/docs/slides/BOS14/_support/reveal.js/css/reveal.min.css b/docs/slides/BOS14/_support/reveal.js/css/reveal.min.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/reveal.min.css
@@ -0,0 +1,7 @@
+@charset "UTF-8";/*!
+ * reveal.js
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+ */ html,body,.reveal div,.reveal span,.reveal applet,.reveal object,.reveal iframe,.reveal h1,.reveal h2,.reveal h3,.reveal h4,.reveal h5,.reveal h6,.reveal p,.reveal blockquote,.reveal pre,.reveal a,.reveal abbr,.reveal acronym,.reveal address,.reveal big,.reveal cite,.reveal code,.reveal del,.reveal dfn,.reveal em,.reveal img,.reveal ins,.reveal kbd,.reveal q,.reveal s,.reveal samp,.reveal small,.reveal strike,.reveal strong,.reveal sub,.reveal sup,.reveal tt,.reveal var,.reveal b,.reveal u,.reveal i,.reveal center,.reveal dl,.reveal dt,.reveal dd,.reveal ol,.reveal ul,.reveal li,.reveal fieldset,.reveal form,.reveal label,.reveal legend,.reveal table,.reveal caption,.reveal tbody,.reveal tfoot,.reveal thead,.reveal tr,.reveal th,.reveal td,.reveal article,.reveal aside,.reveal canvas,.reveal details,.reveal embed,.reveal figure,.reveal figcaption,.reveal footer,.reveal header,.reveal hgroup,.reveal menu,.reveal nav,.reveal output,.reveal ruby,.reveal section,.reveal summary,.reveal time,.reveal mark,.reveal audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}.reveal article,.reveal aside,.reveal details,.reveal figcaption,.reveal figure,.reveal footer,.reveal header,.reveal hgroup,.reveal menu,.reveal nav,.reveal section{display:block}html,body{width:100%;height:100%;overflow:hidden}body{position:relative;line-height:1}::selection{background:#FF5E99;color:#fff;text-shadow:none}.reveal h1,.reveal h2,.reveal h3,.reveal h4,.reveal h5,.reveal h6{-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto;word-wrap:break-word;line-height:1}.reveal h1{font-size:3.77em}.reveal h2{font-size:2.11em}.reveal h3{font-size:1.55em}.reveal h4{font-size:1em}.reveal .slides section .fragment{opacity:0;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-ms-transition:all .2s ease;-o-transition:all .2s ease;transition:all .2s ease}.reveal .slides section .fragment.visible{opacity:1}.reveal .slides section .fragment.grow{opacity:1}.reveal .slides section .fragment.grow.visible{-webkit-transform:scale(1.3);-moz-transform:scale(1.3);-ms-transform:scale(1.3);-o-transform:scale(1.3);transform:scale(1.3)}.reveal .slides section .fragment.shrink{opacity:1}.reveal .slides section .fragment.shrink.visible{-webkit-transform:scale(0.7);-moz-transform:scale(0.7);-ms-transform:scale(0.7);-o-transform:scale(0.7);transform:scale(0.7)}.reveal .slides section .fragment.zoom-in{opacity:0;-webkit-transform:scale(0.1);-moz-transform:scale(0.1);-ms-transform:scale(0.1);-o-transform:scale(0.1);transform:scale(0.1)}.reveal .slides section .fragment.zoom-in.visible{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}.reveal .slides section .fragment.roll-in{opacity:0;-webkit-transform:rotateX(90deg);-moz-transform:rotateX(90deg);-ms-transform:rotateX(90deg);-o-transform:rotateX(90deg);transform:rotateX(90deg)}.reveal .slides section .fragment.roll-in.visible{opacity:1;-webkit-transform:rotateX(0);-moz-transform:rotateX(0);-ms-transform:rotateX(0);-o-transform:rotateX(0);transform:rotateX(0)}.reveal .slides section .fragment.fade-out{opacity:1}.reveal .slides section .fragment.fade-out.visible{opacity:0}.reveal .slides section .fragment.semi-fade-out{opacity:1}.reveal .slides section .fragment.semi-fade-out.visible{opacity:.5}.reveal .slides section .fragment.current-visible{opacity:0}.reveal .slides section .fragment.current-visible.current-fragment{opacity:1}.reveal .slides section .fragment.highlight-red,.reveal .slides section .fragment.highlight-current-red,.reveal .slides section .fragment.highlight-green,.reveal .slides section .fragment.highlight-current-green,.reveal .slides section .fragment.highlight-blue,.reveal .slides section .fragment.highlight-current-blue{opacity:1}.reveal .slides section .fragment.highlight-red.visible{color:#ff2c2d}.reveal .slides section .fragment.highlight-green.visible{color:#17ff2e}.reveal .slides section .fragment.highlight-blue.visible{color:#1b91ff}.reveal .slides section .fragment.highlight-current-red.current-fragment{color:#ff2c2d}.reveal .slides section .fragment.highlight-current-green.current-fragment{color:#17ff2e}.reveal .slides section .fragment.highlight-current-blue.current-fragment{color:#1b91ff}.reveal:after{content:'';font-style:italic}.reveal iframe{z-index:1}.reveal img,.reveal video,.reveal iframe{max-width:95%;max-height:95%}.reveal a{position:relative}.reveal strong,.reveal b{font-weight:700}.reveal em,.reveal i{font-style:italic}.reveal ol,.reveal ul{display:inline-block;text-align:left;margin:0 0 0 1em}.reveal ol{list-style-type:decimal}.reveal ul{list-style-type:disc}.reveal ul ul{list-style-type:square}.reveal ul ul ul{list-style-type:circle}.reveal ul ul,.reveal ul ol,.reveal ol ol,.reveal ol ul{display:block;margin-left:40px}.reveal p{margin-bottom:10px;line-height:1.2em}.reveal q,.reveal blockquote{quotes:none}.reveal blockquote{display:block;position:relative;width:70%;margin:5px auto;padding:5px;font-style:italic;background:rgba(255,255,255,.05);box-shadow:0 0 2px rgba(0,0,0,.2)}.reveal blockquote p:first-child,.reveal blockquote p:last-child{display:inline-block}.reveal q{font-style:italic}.reveal pre{display:block;position:relative;width:90%;margin:15px auto;text-align:left;font-size:.55em;font-family:monospace;line-height:1.2em;word-wrap:break-word;box-shadow:0 0 6px rgba(0,0,0,.3)}.reveal code{font-family:monospace}.reveal pre code{padding:5px;overflow:auto;max-height:400px;word-wrap:normal}.reveal pre.stretch code{height:100%;max-height:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.reveal table th,.reveal table td{text-align:left;padding-right:.3em}.reveal table th{font-weight:700}.reveal sup{vertical-align:super}.reveal sub{vertical-align:sub}.reveal small{display:inline-block;font-size:.6em;line-height:1.2em;vertical-align:top}.reveal small *{vertical-align:top}.reveal .stretch{max-width:none;max-height:none}.reveal .controls{display:none;position:fixed;width:110px;height:110px;z-index:30;right:10px;bottom:10px}.reveal .controls div{position:absolute;opacity:.05;width:0;height:0;border:12px solid transparent;-moz-transform:scale(.9999);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-ms-transition:all .2s ease;-o-transition:all .2s ease;transition:all .2s ease}.reveal .controls div.enabled{opacity:.7;cursor:pointer}.reveal .controls div.enabled:active{margin-top:1px}.reveal .controls div.navigate-left{top:42px;border-right-width:22px;border-right-color:#eee}.reveal .controls div.navigate-left.fragmented{opacity:.3}.reveal .controls div.navigate-right{left:74px;top:42px;border-left-width:22px;border-left-color:#eee}.reveal .controls div.navigate-right.fragmented{opacity:.3}.reveal .controls div.navigate-up{left:42px;border-bottom-width:22px;border-bottom-color:#eee}.reveal .controls div.navigate-up.fragmented{opacity:.3}.reveal .controls div.navigate-down{left:42px;top:74px;border-top-width:22px;border-top-color:#eee}.reveal .controls div.navigate-down.fragmented{opacity:.3}.reveal .progress{position:fixed;display:none;height:3px;width:100%;bottom:0;left:0;z-index:10}.reveal .progress:after{content:'';display:'block';position:absolute;height:20px;width:100%;top:-20px}.reveal .progress span{display:block;height:100%;width:0;-webkit-transition:width 800ms cubic-bezier(0.26,.86,.44,.985);-moz-transition:width 800ms cubic-bezier(0.26,.86,.44,.985);-ms-transition:width 800ms cubic-bezier(0.26,.86,.44,.985);-o-transition:width 800ms cubic-bezier(0.26,.86,.44,.985);transition:width 800ms cubic-bezier(0.26,.86,.44,.985)}.reveal .slide-number{position:fixed;display:block;right:15px;bottom:15px;opacity:.5;z-index:31;font-size:12px}.reveal{position:relative;width:100%;height:100%;-ms-touch-action:none}.reveal .slides{position:absolute;width:100%;height:100%;left:50%;top:50%;overflow:visible;z-index:1;text-align:center;-webkit-transition:-webkit-perspective .4s ease;-moz-transition:-moz-perspective .4s ease;-ms-transition:-ms-perspective .4s ease;-o-transition:-o-perspective .4s ease;transition:perspective .4s ease;-webkit-perspective:600px;-moz-perspective:600px;-ms-perspective:600px;perspective:600px;-webkit-perspective-origin:0 -100px;-moz-perspective-origin:0 -100px;-ms-perspective-origin:0 -100px;perspective-origin:0 -100px}.reveal .slides>section{-ms-perspective:600px}.reveal .slides>section,.reveal .slides>section>section{display:none;position:absolute;width:100%;padding:20px 0;z-index:10;line-height:1.2em;font-weight:inherit;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transition:-webkit-transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),-webkit-transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985);-moz-transition:-moz-transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),-moz-transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985);-ms-transition:-ms-transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),-ms-transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985);-o-transition:-o-transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),-o-transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985);transition:transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985)}.reveal[data-transition-speed=fast] .slides section{-webkit-transition-duration:400ms;-moz-transition-duration:400ms;-ms-transition-duration:400ms;transition-duration:400ms}.reveal[data-transition-speed=slow] .slides section{-webkit-transition-duration:1200ms;-moz-transition-duration:1200ms;-ms-transition-duration:1200ms;transition-duration:1200ms}.reveal .slides section[data-transition-speed=fast]{-webkit-transition-duration:400ms;-moz-transition-duration:400ms;-ms-transition-duration:400ms;transition-duration:400ms}.reveal .slides section[data-transition-speed=slow]{-webkit-transition-duration:1200ms;-moz-transition-duration:1200ms;-ms-transition-duration:1200ms;transition-duration:1200ms}.reveal .slides>section{left:-50%;top:-50%}.reveal .slides>section.stack{padding-top:0;padding-bottom:0}.reveal .slides>section.present,.reveal .slides>section>section.present{display:block;z-index:11;opacity:1}.reveal.center,.reveal.center .slides,.reveal.center .slides section{min-height:auto!important}.reveal .slides>section.future,.reveal .slides>section>section.future,.reveal .slides>section.past,.reveal .slides>section>section.past{pointer-events:none}.reveal.overview .slides>section,.reveal.overview .slides>section>section{pointer-events:auto}.reveal .slides>section[data-transition=default].past,.reveal .slides>section.past{display:block;opacity:0;-webkit-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);-moz-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=default].future,.reveal .slides>section.future{display:block;opacity:0;-webkit-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);-moz-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=default].past,.reveal .slides>section>section.past{display:block;opacity:0;-webkit-transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0);-moz-transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0);-ms-transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0);transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0)}.reveal .slides>section>section[data-transition=default].future,.reveal .slides>section>section.future{display:block;opacity:0;-webkit-transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0);-moz-transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0);-ms-transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0);transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0)}.reveal .slides>section[data-transition=concave].past,.reveal.concave .slides>section.past{-webkit-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);-moz-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=concave].future,.reveal.concave .slides>section.future{-webkit-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);-moz-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=concave].past,.reveal.concave .slides>section>section.past{-webkit-transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0);-moz-transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0);-ms-transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0);transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0)}.reveal .slides>section>section[data-transition=concave].future,.reveal.concave .slides>section>section.future{-webkit-transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0);-moz-transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0);-ms-transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0);transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0)}.reveal .slides>section[data-transition=zoom],.reveal.zoom .slides>section{-webkit-transition-timing-function:ease;-moz-transition-timing-function:ease;-ms-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.reveal .slides>section[data-transition=zoom].past,.reveal.zoom .slides>section.past{opacity:0;visibility:hidden;-webkit-transform:scale(16);-moz-transform:scale(16);-ms-transform:scale(16);-o-transform:scale(16);transform:scale(16)}.reveal .slides>section[data-transition=zoom].future,.reveal.zoom .slides>section.future{opacity:0;visibility:hidden;-webkit-transform:scale(0.2);-moz-transform:scale(0.2);-ms-transform:scale(0.2);-o-transform:scale(0.2);transform:scale(0.2)}.reveal .slides>section>section[data-transition=zoom].past,.reveal.zoom .slides>section>section.past{-webkit-transform:translate(0,-150%);-moz-transform:translate(0,-150%);-ms-transform:translate(0,-150%);-o-transform:translate(0,-150%);transform:translate(0,-150%)}.reveal .slides>section>section[data-transition=zoom].future,.reveal.zoom .slides>section>section.future{-webkit-transform:translate(0,150%);-moz-transform:translate(0,150%);-ms-transform:translate(0,150%);-o-transform:translate(0,150%);transform:translate(0,150%)}.reveal.linear section{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.reveal .slides>section[data-transition=linear].past,.reveal.linear .slides>section.past{-webkit-transform:translate(-150%,0);-moz-transform:translate(-150%,0);-ms-transform:translate(-150%,0);-o-transform:translate(-150%,0);transform:translate(-150%,0)}.reveal .slides>section[data-transition=linear].future,.reveal.linear .slides>section.future{-webkit-transform:translate(150%,0);-moz-transform:translate(150%,0);-ms-transform:translate(150%,0);-o-transform:translate(150%,0);transform:translate(150%,0)}.reveal .slides>section>section[data-transition=linear].past,.reveal.linear .slides>section>section.past{-webkit-transform:translate(0,-150%);-moz-transform:translate(0,-150%);-ms-transform:translate(0,-150%);-o-transform:translate(0,-150%);transform:translate(0,-150%)}.reveal .slides>section>section[data-transition=linear].future,.reveal.linear .slides>section>section.future{-webkit-transform:translate(0,150%);-moz-transform:translate(0,150%);-ms-transform:translate(0,150%);-o-transform:translate(0,150%);transform:translate(0,150%)}.reveal.cube .slides{-webkit-perspective:1300px;-moz-perspective:1300px;-ms-perspective:1300px;perspective:1300px}.reveal.cube .slides section{padding:30px;min-height:700px;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.reveal.center.cube .slides section{min-height:auto}.reveal.cube .slides section:not(.stack):before{content:'';position:absolute;display:block;width:100%;height:100%;left:0;top:0;background:rgba(0,0,0,.1);border-radius:4px;-webkit-transform:translateZ(-20px);-moz-transform:translateZ(-20px);-ms-transform:translateZ(-20px);-o-transform:translateZ(-20px);transform:translateZ(-20px)}.reveal.cube .slides section:not(.stack):after{content:'';position:absolute;display:block;width:90%;height:30px;left:5%;bottom:0;background:0;z-index:1;border-radius:4px;box-shadow:0 95px 25px rgba(0,0,0,.2);-webkit-transform:translateZ(-90px) rotateX(65deg);-moz-transform:translateZ(-90px) rotateX(65deg);-ms-transform:translateZ(-90px) rotateX(65deg);-o-transform:translateZ(-90px) rotateX(65deg);transform:translateZ(-90px) rotateX(65deg)}.reveal.cube .slides>section.stack{padding:0;background:0}.reveal.cube .slides>section.past{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0;-webkit-transform:translate3d(-100%,0,0) rotateY(-90deg);-moz-transform:translate3d(-100%,0,0) rotateY(-90deg);-ms-transform:translate3d(-100%,0,0) rotateY(-90deg);transform:translate3d(-100%,0,0) rotateY(-90deg)}.reveal.cube .slides>section.future{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translate3d(100%,0,0) rotateY(90deg);-moz-transform:translate3d(100%,0,0) rotateY(90deg);-ms-transform:translate3d(100%,0,0) rotateY(90deg);transform:translate3d(100%,0,0) rotateY(90deg)}.reveal.cube .slides>section>section.past{-webkit-transform-origin:0 100%;-moz-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:translate3d(0,-100%,0) rotateX(90deg);-moz-transform:translate3d(0,-100%,0) rotateX(90deg);-ms-transform:translate3d(0,-100%,0) rotateX(90deg);transform:translate3d(0,-100%,0) rotateX(90deg)}.reveal.cube .slides>section>section.future{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translate3d(0,100%,0) rotateX(-90deg);-moz-transform:translate3d(0,100%,0) rotateX(-90deg);-ms-transform:translate3d(0,100%,0) rotateX(-90deg);transform:translate3d(0,100%,0) rotateX(-90deg)}.reveal.page .slides{-webkit-perspective-origin:0 50%;-moz-perspective-origin:0 50%;-ms-perspective-origin:0 50%;perspective-origin:0 50%;-webkit-perspective:3000px;-moz-perspective:3000px;-ms-perspective:3000px;perspective:3000px}.reveal.page .slides section{padding:30px;min-height:700px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.reveal.page .slides section.past{z-index:12}.reveal.page .slides section:not(.stack):before{content:'';position:absolute;display:block;width:100%;height:100%;left:0;top:0;background:rgba(0,0,0,.1);-webkit-transform:translateZ(-20px);-moz-transform:translateZ(-20px);-ms-transform:translateZ(-20px);-o-transform:translateZ(-20px);transform:translateZ(-20px)}.reveal.page .slides section:not(.stack):after{content:'';position:absolute;display:block;width:90%;height:30px;left:5%;bottom:0;background:0;z-index:1;border-radius:4px;box-shadow:0 95px 25px rgba(0,0,0,.2);-webkit-transform:translateZ(-90px) rotateX(65deg)}.reveal.page .slides>section.stack{padding:0;background:0}.reveal.page .slides>section.past{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translate3d(-40%,0,0) rotateY(-80deg);-moz-transform:translate3d(-40%,0,0) rotateY(-80deg);-ms-transform:translate3d(-40%,0,0) rotateY(-80deg);transform:translate3d(-40%,0,0) rotateY(-80deg)}.reveal.page .slides>section.future{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.reveal.page .slides>section>section.past{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translate3d(0,-40%,0) rotateX(80deg);-moz-transform:translate3d(0,-40%,0) rotateX(80deg);-ms-transform:translate3d(0,-40%,0) rotateX(80deg);transform:translate3d(0,-40%,0) rotateX(80deg)}.reveal.page .slides>section>section.future{-webkit-transform-origin:0 100%;-moz-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.reveal .slides section[data-transition=fade],.reveal.fade .slides section,.reveal.fade .slides>section>section{-webkit-transform:none;-moz-transform:none;-ms-transform:none;-o-transform:none;transform:none;-webkit-transition:opacity .5s;-moz-transition:opacity .5s;-ms-transition:opacity .5s;-o-transition:opacity .5s;transition:opacity .5s}.reveal.fade.overview .slides section,.reveal.fade.overview .slides>section>section,.reveal.fade.overview-deactivating .slides section,.reveal.fade.overview-deactivating .slides>section>section{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.reveal .slides section[data-transition=none],.reveal.none .slides section{-webkit-transform:none;-moz-transform:none;-ms-transform:none;-o-transform:none;transform:none;-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.reveal.overview .slides{-webkit-perspective-origin:0 0;-moz-perspective-origin:0 0;-ms-perspective-origin:0 0;perspective-origin:0 0;-webkit-perspective:700px;-moz-perspective:700px;-ms-perspective:700px;perspective:700px}.reveal.overview .slides section{height:600px;top:-300px!important;overflow:hidden;opacity:1!important;visibility:visible!important;cursor:pointer;background:rgba(0,0,0,.1)}.reveal.overview .slides section .fragment{opacity:1}.reveal.overview .slides section:after,.reveal.overview .slides section:before{display:none!important}.reveal.overview .slides section>section{opacity:1;cursor:pointer}.reveal.overview .slides section:hover{background:rgba(0,0,0,.3)}.reveal.overview .slides section.present{background:rgba(0,0,0,.3)}.reveal.overview .slides>section.stack{padding:0;top:0!important;background:0;overflow:visible}.reveal .pause-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#000;visibility:hidden;opacity:0;z-index:100;-webkit-transition:all 1s ease;-moz-transition:all 1s ease;-ms-transition:all 1s ease;-o-transition:all 1s ease;transition:all 1s ease}.reveal.paused .pause-overlay{visibility:visible;opacity:1}.no-transforms{overflow-y:auto}.no-transforms .reveal .slides{position:relative;width:80%;height:auto!important;top:0;left:50%;margin:0;text-align:center}.no-transforms .reveal .controls,.no-transforms .reveal .progress{display:none!important}.no-transforms .reveal .slides section{display:block!important;opacity:1!important;position:relative!important;height:auto;min-height:auto;top:0;left:-50%;margin:70px 0;-webkit-transform:none;-moz-transform:none;-ms-transform:none;-o-transform:none;transform:none}.no-transforms .reveal .slides section section{left:0}.reveal .no-transition,.reveal .no-transition *{-webkit-transition:none!important;-moz-transition:none!important;-ms-transition:none!important;-o-transition:none!important;transition:none!important}.reveal .state-background{position:absolute;width:100%;height:100%;background:rgba(0,0,0,0);-webkit-transition:background 800ms ease;-moz-transition:background 800ms ease;-ms-transition:background 800ms ease;-o-transition:background 800ms ease;transition:background 800ms ease}.alert .reveal .state-background{background:rgba(200,50,30,.6)}.soothe .reveal .state-background{background:rgba(50,200,90,.4)}.blackout .reveal .state-background{background:rgba(0,0,0,.6)}.whiteout .reveal .state-background{background:rgba(255,255,255,.6)}.cobalt .reveal .state-background{background:rgba(22,152,213,.6)}.mint .reveal .state-background{background:rgba(22,213,75,.6)}.submerge .reveal .state-background{background:rgba(12,25,77,.6)}.lila .reveal .state-background{background:rgba(180,50,140,.6)}.sunset .reveal .state-background{background:rgba(255,122,0,.6)}.reveal>.backgrounds{position:absolute;width:100%;height:100%;-webkit-perspective:600px;-moz-perspective:600px;-ms-perspective:600px;perspective:600px}.reveal .slide-background{position:absolute;width:100%;height:100%;opacity:0;visibility:hidden;background-color:rgba(0,0,0,0);background-position:50% 50%;background-repeat:no-repeat;background-size:cover;-webkit-transition:all 800ms cubic-bezier(0.26,.86,.44,.985);-moz-transition:all 800ms cubic-bezier(0.26,.86,.44,.985);-ms-transition:all 800ms cubic-bezier(0.26,.86,.44,.985);-o-transition:all 800ms cubic-bezier(0.26,.86,.44,.985);transition:all 800ms cubic-bezier(0.26,.86,.44,.985)}.reveal .slide-background.present{opacity:1;visibility:visible}.print-pdf .reveal .slide-background{opacity:1!important;visibility:visible!important}.reveal[data-background-transition=none]>.backgrounds .slide-background,.reveal>.backgrounds .slide-background[data-background-transition=none]{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.reveal[data-background-transition=slide]>.backgrounds .slide-background,.reveal>.backgrounds .slide-background[data-background-transition=slide]{opacity:1;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.reveal[data-background-transition=slide]>.backgrounds .slide-background.past,.reveal>.backgrounds .slide-background.past[data-background-transition=slide]{-webkit-transform:translate(-100%,0);-moz-transform:translate(-100%,0);-ms-transform:translate(-100%,0);-o-transform:translate(-100%,0);transform:translate(-100%,0)}.reveal[data-background-transition=slide]>.backgrounds .slide-background.future,.reveal>.backgrounds .slide-background.future[data-background-transition=slide]{-webkit-transform:translate(100%,0);-moz-transform:translate(100%,0);-ms-transform:translate(100%,0);-o-transform:translate(100%,0);transform:translate(100%,0)}.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past,.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide]{-webkit-transform:translate(0,-100%);-moz-transform:translate(0,-100%);-ms-transform:translate(0,-100%);-o-transform:translate(0,-100%);transform:translate(0,-100%)}.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future,.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide]{-webkit-transform:translate(0,100%);-moz-transform:translate(0,100%);-ms-transform:translate(0,100%);-o-transform:translate(0,100%);transform:translate(0,100%)}.reveal[data-background-transition=convex]>.backgrounds .slide-background.past,.reveal>.backgrounds .slide-background.past[data-background-transition=convex]{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);-moz-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal[data-background-transition=convex]>.backgrounds .slide-background.future,.reveal>.backgrounds .slide-background.future[data-background-transition=convex]{opacity:0;-webkit-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);-moz-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past,.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex]{opacity:0;-webkit-transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0);-moz-transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0);transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0)}.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future,.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex]{opacity:0;-webkit-transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0);-moz-transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0);transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0)}.reveal[data-background-transition=concave]>.backgrounds .slide-background.past,.reveal>.backgrounds .slide-background.past[data-background-transition=concave]{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);-moz-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0)}.reveal[data-background-transition=concave]>.backgrounds .slide-background.future,.reveal>.backgrounds .slide-background.future[data-background-transition=concave]{opacity:0;-webkit-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);-moz-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0)}.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past,.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave]{opacity:0;-webkit-transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0);-moz-transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0);transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0)}.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future,.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave]{opacity:0;-webkit-transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0);-moz-transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0);transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0)}.reveal[data-background-transition=zoom]>.backgrounds .slide-background,.reveal>.backgrounds .slide-background[data-background-transition=zoom]{-webkit-transition-timing-function:ease;-moz-transition-timing-function:ease;-ms-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past,.reveal>.backgrounds .slide-background.past[data-background-transition=zoom]{opacity:0;visibility:hidden;-webkit-transform:scale(16);-moz-transform:scale(16);-ms-transform:scale(16);-o-transform:scale(16);transform:scale(16)}.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future,.reveal>.backgrounds .slide-background.future[data-background-transition=zoom]{opacity:0;visibility:hidden;-webkit-transform:scale(0.2);-moz-transform:scale(0.2);-ms-transform:scale(0.2);-o-transform:scale(0.2);transform:scale(0.2)}.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past,.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom]{opacity:0;visibility:hidden;-webkit-transform:scale(16);-moz-transform:scale(16);-ms-transform:scale(16);-o-transform:scale(16);transform:scale(16)}.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future,.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom]{opacity:0;visibility:hidden;-webkit-transform:scale(0.2);-moz-transform:scale(0.2);-ms-transform:scale(0.2);-o-transform:scale(0.2);transform:scale(0.2)}.reveal[data-transition-speed=fast]>.backgrounds .slide-background{-webkit-transition-duration:400ms;-moz-transition-duration:400ms;-ms-transition-duration:400ms;transition-duration:400ms}.reveal[data-transition-speed=slow]>.backgrounds .slide-background{-webkit-transition-duration:1200ms;-moz-transition-duration:1200ms;-ms-transition-duration:1200ms;transition-duration:1200ms}.reveal.rtl .slides,.reveal.rtl .slides h1,.reveal.rtl .slides h2,.reveal.rtl .slides h3,.reveal.rtl .slides h4,.reveal.rtl .slides h5,.reveal.rtl .slides h6{direction:rtl;font-family:sans-serif}.reveal.rtl pre,.reveal.rtl code{direction:ltr}.reveal.rtl ol,.reveal.rtl ul{text-align:right}.reveal.rtl .progress span{float:right}.reveal.has-parallax-background .backgrounds{-webkit-transition:all .8s ease;-moz-transition:all .8s ease;-ms-transition:all .8s ease;transition:all .8s ease}.reveal.has-parallax-background[data-transition-speed=fast] .backgrounds{-webkit-transition-duration:400ms;-moz-transition-duration:400ms;-ms-transition-duration:400ms;transition-duration:400ms}.reveal.has-parallax-background[data-transition-speed=slow] .backgrounds{-webkit-transition-duration:1200ms;-moz-transition-duration:1200ms;-ms-transition-duration:1200ms;transition-duration:1200ms}.reveal .preview-link-overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1000;background:rgba(0,0,0,.9);opacity:0;visibility:hidden;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;transition:all .3s ease}.reveal .preview-link-overlay.visible{opacity:1;visibility:visible}.reveal .preview-link-overlay .spinner{position:absolute;display:block;top:50%;left:50%;width:32px;height:32px;margin:-16px 0 0 -16px;z-index:10;background-image:url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D);visibility:visible;opacity:.6;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;transition:all .3s ease}.reveal .preview-link-overlay header{position:absolute;left:0;top:0;width:100%;height:40px;z-index:2;border-bottom:1px solid #222}.reveal .preview-link-overlay header a{display:inline-block;width:40px;height:40px;padding:0 10px;float:right;opacity:.6;box-sizing:border-box}.reveal .preview-link-overlay header a:hover{opacity:1}.reveal .preview-link-overlay header a .icon{display:inline-block;width:20px;height:20px;background-position:50% 50%;background-size:100%;background-repeat:no-repeat}.reveal .preview-link-overlay header a.close .icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC)}.reveal .preview-link-overlay header a.external .icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==)}.reveal .preview-link-overlay .viewport{position:absolute;top:40px;right:0;bottom:0;left:0}.reveal .preview-link-overlay .viewport iframe{width:100%;height:100%;max-width:100%;max-height:100%;border:0;opacity:0;visibility:hidden;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;transition:all .3s ease}.reveal .preview-link-overlay.loaded .viewport iframe{opacity:1;visibility:visible}.reveal .preview-link-overlay.loaded .spinner{opacity:0;visibility:hidden;-webkit-transform:scale(0.2);-moz-transform:scale(0.2);-ms-transform:scale(0.2);transform:scale(0.2)}.reveal .playback{position:fixed;left:15px;bottom:15px;z-index:30;cursor:pointer;-webkit-transition:all 400ms ease;-moz-transition:all 400ms ease;-ms-transition:all 400ms ease;transition:all 400ms ease}.reveal.overview .playback{opacity:0;visibility:hidden}.reveal .roll{display:inline-block;line-height:1.2;overflow:hidden;vertical-align:top;-webkit-perspective:400px;-moz-perspective:400px;-ms-perspective:400px;perspective:400px;-webkit-perspective-origin:50% 50%;-moz-perspective-origin:50% 50%;-ms-perspective-origin:50% 50%;perspective-origin:50% 50%}.reveal .roll:hover{background:0;text-shadow:none}.reveal .roll span{display:block;position:relative;padding:0 2px;pointer-events:none;-webkit-transition:all 400ms ease;-moz-transition:all 400ms ease;-ms-transition:all 400ms ease;transition:all 400ms ease;-webkit-transform-origin:50% 0;-moz-transform-origin:50% 0;-ms-transform-origin:50% 0;transform-origin:50% 0;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden}.reveal .roll:hover span{background:rgba(0,0,0,.5);-webkit-transform:translate3d(0px,0,-45px) rotateX(90deg);-moz-transform:translate3d(0px,0,-45px) rotateX(90deg);-ms-transform:translate3d(0px,0,-45px) rotateX(90deg);transform:translate3d(0px,0,-45px) rotateX(90deg)}.reveal .roll span:after{content:attr(data-title);display:block;position:absolute;left:0;top:0;padding:0 2px;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:50% 0;-moz-transform-origin:50% 0;-ms-transform-origin:50% 0;transform-origin:50% 0;-webkit-transform:translate3d(0px,110%,0) rotateX(-90deg);-moz-transform:translate3d(0px,110%,0) rotateX(-90deg);-ms-transform:translate3d(0px,110%,0) rotateX(-90deg);transform:translate3d(0px,110%,0) rotateX(-90deg)}.reveal aside.notes{display:none}.zoomed .reveal *,.zoomed .reveal :before,.zoomed .reveal :after{-webkit-transform:none!important;-moz-transform:none!important;-ms-transform:none!important;transform:none!important;-webkit-backface-visibility:visible!important;-moz-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important}.zoomed .reveal .progress,.zoomed .reveal .controls{opacity:0}.zoomed .reveal .roll span{background:0}.zoomed .reveal .roll span:after{visibility:hidden}
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/README.md b/docs/slides/BOS14/_support/reveal.js/css/theme/README.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/README.md
@@ -0,0 +1,25 @@
+## Dependencies
+
+Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceding: https://github.com/hakimel/reveal.js#full-setup
+
+You also need to install Ruby and then Sass (with `gem install sass`).
+
+## Creating a Theme
+
+To create your own theme, start by duplicating any ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source) and adding it to the compilation list in the [Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js).
+
+Each theme file does four things in the following order:
+
+1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)**
+Shared utility functions.
+
+2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)**
+Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3.
+
+3. **Override**
+This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding full selectors with hardcoded styles.
+
+4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)**
+The template theme file which will generate final CSS output based on the currently defined variables.
+
+When you are done, run `grunt themes` to compile the Sass file to CSS and you are ready to use your new theme.
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/beige.css b/docs/slides/BOS14/_support/reveal.js/css/theme/beige.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/beige.css
@@ -0,0 +1,148 @@
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Beige theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f7f2d3;
+  background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
+  background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background-color: #f7f3de; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #333333; }
+
+::selection {
+  color: white;
+  background: rgba(79, 64, 28, 0.99);
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #333333;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #8b743d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #c0a86e;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #564826; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #333333;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #8b743d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #8b743d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #8b743d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #8b743d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #8b743d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #c0a86e; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #c0a86e; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #c0a86e; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #c0a86e; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #8b743d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #8b743d; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/blood.css b/docs/slides/BOS14/_support/reveal.js/css/theme/blood.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/blood.css
@@ -0,0 +1,175 @@
+@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
+/**
+ * Blood theme for reveal.js
+ * Author: Walther http://github.com/Walther
+ *
+ * Designed to be used with highlight.js theme
+ * "monokai_sublime.css" available from
+ * https://github.com/isagalaev/highlight.js/
+ *
+ * For other themes, change $codeBackground accordingly.
+ *
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #222222;
+  background: -moz-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #626262), color-stop(100%, #222222));
+  background: -webkit-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background: -o-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background: -ms-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background: radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background-color: #2b2b2b; }
+
+.reveal {
+  font-family: Ubuntu, "sans-serif";
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #eeeeee; }
+
+::selection {
+  color: white;
+  background: #aa2233;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eeeeee;
+  font-family: Ubuntu, "sans-serif";
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: 2px 2px 2px #222222; }
+
+.reveal h1 {
+  text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #aa2233;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #dd5566;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #6a1520; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #eeeeee;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #aa2233;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #aa2233; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #aa2233; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #aa2233; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #aa2233; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #dd5566; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #dd5566; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #dd5566; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #dd5566; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #aa2233;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #aa2233; }
+
+.reveal p {
+  font-weight: 300;
+  text-shadow: 1px 1px #222222; }
+
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  font-weight: 700; }
+
+.reveal a:not(.image),
+.reveal a:not(.image):hover {
+  text-shadow: 2px 2px 2px #000; }
+
+.reveal small a:not(.image),
+.reveal small a:not(.image):hover {
+  text-shadow: 1px 1px 1px #000; }
+
+.reveal p code {
+  background-color: #23241f;
+  display: inline-block;
+  border-radius: 7px; }
+
+.reveal small code {
+  vertical-align: baseline; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/default.css b/docs/slides/BOS14/_support/reveal.js/css/theme/default.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/default.css
@@ -0,0 +1,148 @@
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Default theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #1c1e20;
+  background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
+  background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background-color: #2b2b2b; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #eeeeee; }
+
+::selection {
+  color: white;
+  background: #ff5e99;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eeeeee;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+.reveal h1 {
+  text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #13daec;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #71e9f4;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #0d99a5; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #eeeeee;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #13daec;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #13daec; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #13daec; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #13daec; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #13daec; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #71e9f4; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #71e9f4; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #71e9f4; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #71e9f4; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #13daec;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #13daec; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/moon.css b/docs/slides/BOS14/_support/reveal.js/css/theme/moon.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/moon.css
@@ -0,0 +1,148 @@
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Solarized Dark theme for reveal.js.
+ * Author: Achim Staebler
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal; }
+
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+  color-profile: sRGB;
+  rendering-intent: auto; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #002b36;
+  background-color: #002b36; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #93a1a1; }
+
+::selection {
+  color: white;
+  background: #d33682;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eee8d5;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #268bd2;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #78b9e6;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #1a6091; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #93a1a1;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #268bd2;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #268bd2; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #268bd2; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #268bd2; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #268bd2; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #78b9e6; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #78b9e6; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #78b9e6; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #78b9e6; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #268bd2;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #268bd2; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/night.css b/docs/slides/BOS14/_support/reveal.js/css/theme/night.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/night.css
@@ -0,0 +1,136 @@
+@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
+/**
+ * Black theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #111111;
+  background-color: #111111; }
+
+.reveal {
+  font-family: "Open Sans", sans-serif;
+  font-size: 30px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #eeeeee; }
+
+::selection {
+  color: white;
+  background: #e7ad52;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eeeeee;
+  font-family: "Montserrat", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: -0.03em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #e7ad52;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #f3d7ac;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #d08a1d; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #eeeeee;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #e7ad52;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #e7ad52; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #e7ad52; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #e7ad52; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #e7ad52; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #f3d7ac; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #f3d7ac; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #f3d7ac; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #f3d7ac; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #e7ad52;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #e7ad52; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/seminar.css b/docs/slides/BOS14/_support/reveal.js/css/theme/seminar.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/seminar.css
@@ -0,0 +1,200 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb; }
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+.reveal a {
+  color: #8b7c69;
+  text-decoration: none;
+}
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 40px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	// :color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.05em 0.05em 0.25em blue;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+/*
+.reveal a:not(.image) {
+  line-height: 1.3em; }
+
+
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c; }
+
+*/
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #51483d; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/seminar.orig.css b/docs/slides/BOS14/_support/reveal.js/css/theme/seminar.orig.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/seminar.orig.css
@@ -0,0 +1,301 @@
+/**
+ * The default theme for reveal.js presentations.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.ttf') format('truetype');
+	font-weight: normal;
+	font-style: normal;
+}
+
+@font-face {
+		font-family: 'PTSansNarrow';
+        src: url('../../lib/font/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+@font-face {
+		font-family: 'OpenSans';
+        src: url('../../lib/font/OpenSans-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'OpenSans', Times, 'Times New Roman', serif;
+	font-size: 36;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #eee;
+
+	background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM1NTVhNWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMWMxZTIwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+	background-color: #2b2b2b;
+	background: -moz-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%, rgba(28,30,32,1) 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(85,90,95,1)), color-stop(100%,rgba(28,30,32,1)));
+	background: -webkit-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -o-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+}
+
+
+/*********************************************
+ * main.css OVERIDES
+ *********************************************/
+
+
+/*--DW-- uncomment below to undo globally centered text from main.css*/
+
+/*.reveal .slides {
+	text-align: left;
+}
+
+.reveal li {
+	padding-bottom: 0.7em;
+	line-height: 1em;
+}
+.reveal ul ul {
+	padding-left: 8%;
+	padding-top: 0.7em;
+	font-size: 85%;
+}*/
+
+/*--DW--
+* override list width to make multiline list items
+* a bit more manageable
+*/
+.reveal ul {
+	max-width: 80%;
+}
+
+.reveal li {
+	padding-bottom: 0.3em;
+}
+
+/*--DW-- uncenter pararagraph blocks*/
+.reveal .slides p {
+	text-align: left
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2 {
+	margin: 0 0 20px 0;
+	color: #eee;
+	font-family: 'League Gothic', Impact, sans-serif;
+	line-height: 0.9em;
+	letter-spacing: 0.02em;
+	
+	text-align: center;
+	text-transform: uppercase;
+	text-shadow: 0px 1px 0px rgba(0,0,0,1);
+}
+
+.reveal h2 {
+	font-family: 'PTSansNarrow';
+	font-size: 130%;
+}
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+
+
+/*********************************************
+ * BLOCKQUOTES
+ *********************************************/
+
+/*--DW--*/
+.reveal blockquote
+{   background: rgba(255,255,255, .2);
+    font-size: 75%;
+    text-align: justify;
+    width: 70%;
+    padding: 0.5em 5% 0.2em;
+    margin: 0 10%;
+    border: 2px solid rgba(255, 255, 255, .1);
+    -webkit-box-shadow: .1em .1em .5em black inset;
+    -moz-box-shadow: .1em .1em .5em black inset;
+    box-shadow: .1em .1em .5em black inset;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: hsl(185, 85%, 50%);
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+.reveal a:not(.image):hover {
+	color: hsl(185, 85%, 70%);
+	
+	text-shadow: none;
+	border: none;
+	border-radius: 2px;
+}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: hsl(185, 60%, 35%);
+}
+
+
+/*********************************************
+ * IMAGES AND FIGURES
+ *********************************************/
+
+/*--DW-- added figures; changed img styling*/
+/*pandoc*/
+.reveal figure {
+	margin-left: auto;
+	margin-right: auto;
+}
+
+/*pandoc*/
+.reveal figcaption {
+	text-align: center;
+	font-size: 75%;
+	font-style: italic;
+}
+.reveal section img,
+.reveal section embed {
+/*	width: 80%;
+	height: 80%;
+*/	display: block;
+	margin-left: auto;
+	margin-right: auto;
+	padding: 15px;
+	background: rgba(255,255,255, .75);
+    border: 2px solid rgba(255, 255, 255, .1);
+    -webkit-box-shadow: .1em .1em .5em black inset;
+       -moz-box-shadow: .1em .1em .5em black inset;
+            box-shadow: .1em .1em .5em black inset;
+
+/*--DW-- original image box styling*/
+/*
+-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+
+-webkit-transition: all .2s linear;
+   -moz-transition: all .2s linear;
+    -ms-transition: all .2s linear;
+     -o-transition: all .2s linear;
+        transition: all .2s linear;
+*/
+}
+
+.reveal a:hover img {
+	background: rgba(255,255,255,0.2);
+	border-color: #13DAEC;
+	
+	-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		/*color: hsl(185, 85%, 70%);*/
+		color: rgba(138, 201, 85, 0.60);
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		/*background: hsl(185, 85%, 50%);*/
+		background: rgba(138, 201, 85, 0.60);
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/serif.css b/docs/slides/BOS14/_support/reveal.js/css/theme/serif.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/serif.css
@@ -0,0 +1,138 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+.reveal a:not(.image) {
+  line-height: 1.3em; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb; }
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #51483d; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/simple.css b/docs/slides/BOS14/_support/reveal.js/css/theme/simple.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/simple.css
@@ -0,0 +1,138 @@
+@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is darkblue.
+ *
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: white;
+  background-color: white; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+::selection {
+  color: white;
+  background: rgba(0, 0, 0, 0.99);
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: black;
+  font-family: "News Cycle", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: darkblue;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #0000f1;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #00003f; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: darkblue;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: darkblue; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: darkblue; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: darkblue; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: darkblue; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #0000f1; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #0000f1; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #0000f1; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #0000f1; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: darkblue;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: darkblue; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/sky.css b/docs/slides/BOS14/_support/reveal.js/css/theme/sky.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/sky.css
@@ -0,0 +1,145 @@
+@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+/**
+ * Sky theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+.reveal a:not(.image) {
+  line-height: 1.3em; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #add9e4;
+  background: -moz-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #f7fbfc), color-stop(100%, #add9e4));
+  background: -webkit-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -o-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -ms-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background-color: #f7fbfc; }
+
+.reveal {
+  font-family: "Open Sans", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #333333; }
+
+::selection {
+  color: white;
+  background: #134674;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #333333;
+  font-family: "Quicksand", sans-serif;
+  line-height: 0.9em;
+  letter-spacing: -0.08em;
+  text-transform: uppercase;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #3b759e;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #74a7cb;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #264c66; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #333333;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #3b759e;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #3b759e; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #3b759e; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #3b759e; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #3b759e; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #74a7cb; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #74a7cb; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #74a7cb; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #74a7cb; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #3b759e;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #3b759e; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/solarized.css b/docs/slides/BOS14/_support/reveal.js/css/theme/solarized.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/solarized.css
@@ -0,0 +1,148 @@
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Solarized Light theme for reveal.js.
+ * Author: Achim Staebler
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal; }
+
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+  color-profile: sRGB;
+  rendering-intent: auto; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #fdf6e3;
+  background-color: #fdf6e3; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #657b83; }
+
+::selection {
+  color: white;
+  background: #d33682;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #586e75;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #268bd2;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #78b9e6;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #1a6091; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #657b83;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #268bd2;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #268bd2; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #268bd2; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #268bd2; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #268bd2; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #78b9e6; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #78b9e6; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #78b9e6; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #78b9e6; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #268bd2;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #268bd2; }
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/beige.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/beige.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/beige.scss
@@ -0,0 +1,50 @@
+/**
+ * Beige theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainColor: #333;
+$headingColor: #333;
+$headingTextShadow: none;
+$backgroundColor: #f7f3de;
+$linkColor: #8b743d;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
+$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/blood.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/blood.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/blood.scss
@@ -0,0 +1,91 @@
+/**
+ * Blood theme for reveal.js
+ * Author: Walther http://github.com/Walther
+ *
+ * Designed to be used with highlight.js theme
+ * "monokai_sublime.css" available from
+ * https://github.com/isagalaev/highlight.js/
+ *
+ * For other themes, change $codeBackground accordingly.
+ *
+ */
+
+ // Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+// Include theme-specific fonts
+
+@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
+
+// Colors used in the theme
+$blood: #a23;
+$coal: #222;
+$codeBackground: #23241f;
+
+// Main text
+$mainFont: Ubuntu, 'sans-serif';
+$mainFontSize: 36px;
+$mainColor: #eee;
+
+// Headings
+$headingFont: Ubuntu, 'sans-serif';
+$headingTextShadow: 2px 2px 2px $coal;
+
+// h1 shadow, borrowed humbly from 
+// (c) Default theme by Hakim El Hattab
+$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
+
+// Links
+$linkColor: $blood;
+$linkColorHover: lighten( $linkColor, 20% );
+
+// Text selection
+$selectionBackgroundColor: $blood;
+$selectionColor: #fff;
+
+// Background generator
+@mixin bodyBackground() {
+    @include radial-gradient( $coal, lighten( $coal, 25% ) );
+}
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
+
+// some overrides after theme template import
+
+.reveal p {
+    font-weight: 300;
+    text-shadow: 1px 1px $coal;
+}
+
+.reveal h1, 
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+    font-weight: 700;
+}
+
+.reveal a:not(.image),
+.reveal a:not(.image):hover {
+    text-shadow: 2px 2px 2px #000;
+}
+
+.reveal small a:not(.image),
+.reveal small a:not(.image):hover {
+    text-shadow: 1px 1px 1px #000;
+}
+
+.reveal p code {
+    background-color: $codeBackground;
+    display: inline-block;
+    border-radius: 7px;
+}
+
+.reveal small code {
+    vertical-align: baseline;
+}
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/default.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/default.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/default.scss
@@ -0,0 +1,42 @@
+/**
+ * Default theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+// Override theme settings (see ../template/settings.scss)
+$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/moon.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/moon.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/moon.scss
@@ -0,0 +1,68 @@
+/**
+ * Solarized Dark theme for reveal.js.
+ * Author: Achim Staebler
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+	color-profile: sRGB;
+	rendering-intent: auto;
+}
+
+// Solarized colors
+$base03:    #002b36;
+$base02:    #073642;
+$base01:    #586e75;
+$base00:    #657b83;
+$base0:     #839496;
+$base1:     #93a1a1;
+$base2:     #eee8d5;
+$base3:     #fdf6e3;
+$yellow:    #b58900;
+$orange:    #cb4b16;
+$red:       #dc322f;
+$magenta:   #d33682;
+$violet:    #6c71c4;
+$blue:      #268bd2;
+$cyan:      #2aa198;
+$green:     #859900;
+
+// Override theme settings (see ../template/settings.scss)
+$mainColor: $base1;
+$headingColor: $base2;
+$headingTextShadow: none;
+$backgroundColor: $base03;
+$linkColor: $blue;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: $magenta;
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/night.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/night.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/night.scss
@@ -0,0 +1,35 @@
+/**
+ * Black theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+// Include theme-specific fonts
+@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$backgroundColor: #111;
+
+$mainFont: 'Open Sans', sans-serif;
+$linkColor: #e7ad52;
+$linkColorHover: lighten( $linkColor, 20% );
+$headingFont: 'Montserrat', Impact, sans-serif;
+$headingTextShadow: none;
+$headingLetterSpacing: -0.03em;
+$headingTextTransform: none;
+$selectionBackgroundColor: #e7ad52;
+$mainFontSize: 30px;
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/serif.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/serif.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/serif.scss
@@ -0,0 +1,35 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+$mainColor: #000;
+$headingFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+$headingColor: #383D3D;
+$headingTextShadow: none;
+$headingTextTransform: none;
+$backgroundColor: #F0F1EB;
+$linkColor: #51483D;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: #26351C;
+
+.reveal a:not(.image) {
+  line-height: 1.3em;
+}
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/simple.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/simple.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/simple.scss
@@ -0,0 +1,38 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is darkblue.
+ *
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Lato', sans-serif;
+$mainColor: #000;
+$headingFont: 'News Cycle', Impact, sans-serif;
+$headingColor: #000;
+$headingTextShadow: none;
+$headingTextTransform: none;
+$backgroundColor: #fff;
+$linkColor: #00008B;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/sky.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/sky.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/sky.scss
@@ -0,0 +1,46 @@
+/**
+ * Sky theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Open Sans', sans-serif;
+$mainColor: #333;
+$headingFont: 'Quicksand', sans-serif;
+$headingColor: #333;
+$headingLetterSpacing: -0.08em;
+$headingTextShadow: none;
+$backgroundColor: #f7fbfc;
+$linkColor: #3b759e;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: #134674;
+
+// Fix links so they are not cut off
+.reveal a:not(.image) {
+	line-height: 1.3em;
+}
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( #add9e4, #f7fbfc );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/source/solarized.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/source/solarized.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/source/solarized.scss
@@ -0,0 +1,74 @@
+/**
+ * Solarized Light theme for reveal.js.
+ * Author: Achim Staebler
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+	color-profile: sRGB;
+	rendering-intent: auto;
+}
+
+// Solarized colors
+$base03:    #002b36;
+$base02:    #073642;
+$base01:    #586e75;
+$base00:    #657b83;
+$base0:     #839496;
+$base1:     #93a1a1;
+$base2:     #eee8d5;
+$base3:     #fdf6e3;
+$yellow:    #b58900;
+$orange:    #cb4b16;
+$red:       #dc322f;
+$magenta:   #d33682;
+$violet:    #6c71c4;
+$blue:      #268bd2;
+$cyan:      #2aa198;
+$green:     #859900;
+
+// Override theme settings (see ../template/settings.scss)
+$mainColor: $base00;
+$headingColor: $base01;
+$headingTextShadow: none;
+$backgroundColor: $base3;
+$linkColor: $blue;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: $magenta;
+
+// Background generator
+// @mixin bodyBackground() {
+// 	@include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
+// }
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/template/mixins.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/template/mixins.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/template/mixins.scss
@@ -0,0 +1,29 @@
+@mixin vertical-gradient( $top, $bottom ) {
+	background: $top;
+	background: -moz-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -webkit-gradient( linear, left top, left bottom, color-stop(0%,$top), color-stop(100%,$bottom) );
+	background: -webkit-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -o-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -ms-linear-gradient( top, $top 0%, $bottom 100% );
+	background: linear-gradient( top, $top 0%, $bottom 100% );
+}
+
+@mixin horizontal-gradient( $top, $bottom ) {
+	background: $top;
+	background: -moz-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -webkit-gradient( linear, left top, right top, color-stop(0%,$top), color-stop(100%,$bottom) );
+	background: -webkit-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -o-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -ms-linear-gradient( left, $top 0%, $bottom 100% );
+	background: linear-gradient( left, $top 0%, $bottom 100% );
+}
+
+@mixin radial-gradient( $outer, $inner, $type: circle ) {
+	background: $outer;
+	background: -moz-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -webkit-gradient( radial, center center, 0px, center center, 100%, color-stop(0%,$inner), color-stop(100%,$outer) );
+	background: -webkit-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -o-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -ms-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+}
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/template/settings.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/template/settings.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/template/settings.scss
@@ -0,0 +1,34 @@
+// Base settings for all themes that can optionally be
+// overridden by the super-theme
+
+// Background of the presentation
+$backgroundColor: #2b2b2b;
+
+// Primary/body text
+$mainFont: 'Lato', sans-serif;
+$mainFontSize: 36px;
+$mainColor: #eee;
+
+// Headings
+$headingMargin: 0 0 20px 0;
+$headingFont: 'League Gothic', Impact, sans-serif;
+$headingColor: #eee;
+$headingLineHeight: 0.9em;
+$headingLetterSpacing: 0.02em;
+$headingTextTransform: uppercase;
+$headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2);
+$heading1TextShadow: $headingTextShadow;
+
+// Links and actions
+$linkColor: #13DAEC;
+$linkColorHover: lighten( $linkColor, 20% );
+
+// Text selection
+$selectionBackgroundColor: #FF5E99;
+$selectionColor: #fff;
+
+// Generates the presentation background, can be overridden
+// to return a background image or gradient
+@mixin bodyBackground() {
+	background: $backgroundColor;
+}
diff --git a/docs/slides/BOS14/_support/reveal.js/css/theme/template/theme.scss b/docs/slides/BOS14/_support/reveal.js/css/theme/template/theme.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/css/theme/template/theme.scss
@@ -0,0 +1,170 @@
+// Base theme template for reveal.js
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	@include bodyBackground();
+	background-color: $backgroundColor;
+}
+
+.reveal {
+	font-family: $mainFont;
+	font-size: $mainFontSize;
+	font-weight: normal;
+	letter-spacing: -0.02em;
+	color: $mainColor;
+}
+
+::selection {
+	color: $selectionColor;
+	background: $selectionBackgroundColor;
+	text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+	margin: $headingMargin;
+	color: $headingColor;
+
+	font-family: $headingFont;
+	line-height: $headingLineHeight;
+	letter-spacing: $headingLetterSpacing;
+
+	text-transform: $headingTextTransform;
+	text-shadow: $headingTextShadow;
+}
+
+.reveal h1 {
+	text-shadow: $heading1TextShadow;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: $linkColor;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		color: $linkColorHover;
+
+		text-shadow: none;
+		border: none;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: darken( $linkColor, 15% );
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 15px 0px;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid $mainColor;
+
+	box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: $linkColor;
+
+		box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+	border-right-color: $linkColor;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+	border-left-color: $linkColor;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+	border-bottom-color: $linkColor;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+	border-top-color: $linkColor;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+	border-right-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+	border-left-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+	border-bottom-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+	border-top-color: $linkColorHover;
+}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: $linkColor;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: $linkColor;
+}
+
+
diff --git a/docs/slides/BOS14/_support/reveal.js/index.html b/docs/slides/BOS14/_support/reveal.js/index.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/index.html
@@ -0,0 +1,394 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - The HTML Presentation Framework</title>
+
+		<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
+		<meta name="author" content="Hakim El Hattab">
+
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="css/reveal.min.css">
+		<link rel="stylesheet" href="css/theme/default.css" id="theme">
+
+		<!-- For syntax highlighting -->
+		<link rel="stylesheet" href="lib/css/zenburn.css">
+
+		<!-- If the query includes 'print-pdf', include the PDF print sheet -->
+		<script>
+			if( window.location.search.match( /print-pdf/gi ) ) {
+				var link = document.createElement( 'link' );
+				link.rel = 'stylesheet';
+				link.type = 'text/css';
+				link.href = 'css/print/pdf.css';
+				document.getElementsByTagName( 'head' )[0].appendChild( link );
+			}
+		</script>
+
+		<!--[if lt IE 9]>
+		<script src="lib/js/html5shiv.js"></script>
+		<![endif]-->
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<!-- Any section element inside of this container is displayed as a slide -->
+			<div class="slides">
+				<section>
+					<h1>Reveal.js</h1>
+					<h3>HTML Presentations Made Easy</h3>
+					<p>
+						<small>Created by <a href="http://hakim.se">Hakim El Hattab</a> / <a href="http://twitter.com/hakimel">@hakimel</a></small>
+					</p>
+				</section>
+
+				<section>
+					<h2>Heads Up</h2>
+					<p>
+						reveal.js is a framework for easily creating beautiful presentations using HTML. You'll need a browser with
+						support for CSS 3D transforms to see it in its full glory.
+					</p>
+
+					<aside class="notes">
+						Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
+					</aside>
+				</section>
+
+				<!-- Example of nested vertical slides -->
+				<section>
+					<section>
+						<h2>Vertical Slides</h2>
+						<p>
+							Slides can be nested inside of other slides,
+							try pressing <a href="#" class="navigate-down">down</a>.
+						</p>
+						<a href="#" class="image navigate-down">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
+						</a>
+					</section>
+					<section>
+						<h2>Basement Level 1</h2>
+						<p>Press down or up to navigate.</p>
+					</section>
+					<section>
+						<h2>Basement Level 2</h2>
+						<p>Cornify</p>
+						<a class="test" href="http://cornify.com">
+							<img width="280" height="326" src="https://s3.amazonaws.com/hakim-static/reveal-js/cornify.gif" alt="Unicorn">
+						</a>
+					</section>
+					<section>
+						<h2>Basement Level 3</h2>
+						<p>That's it, time to go back up.</p>
+						<a href="#/2" class="image">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="-webkit-transform: rotate(180deg);">
+						</a>
+					</section>
+				</section>
+
+				<section>
+					<h2>Slides</h2>
+					<p>
+						Not a coder? No problem. There's a fully-featured visual editor for authoring these, try it out at <a href="http://slid.es" target="_blank">http://slid.es</a>.
+					</p>
+				</section>
+
+				<section>
+					<h2>Point of View</h2>
+					<p>
+						Press <strong>ESC</strong> to enter the slide overview.
+					</p>
+					<p>
+						Hold down alt and click on any element to zoom in on it using <a href="http://lab.hakim.se/zoom-js">zoom.js</a>. Alt + click anywhere to zoom back out.
+					</p>
+				</section>
+
+				<section>
+					<h2>Works in Mobile Safari</h2>
+					<p>
+						Try it out! You can swipe through the slides and pinch your way to the overview.
+					</p>
+				</section>
+
+				<section>
+					<h2>Marvelous Unordered List</h2>
+					<ul>
+						<li>No order here</li>
+						<li>Or here</li>
+						<li>Or here</li>
+						<li>Or here</li>
+					</ul>
+				</section>
+
+				<section>
+					<h2>Fantastic Ordered List</h2>
+					<ol>
+						<li>One is smaller than...</li>
+						<li>Two is smaller than...</li>
+						<li>Three!</li>
+					</ol>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						## Markdown support
+
+						For those of you who like that sort of thing. Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
+
+						```
+						<section data-markdown>
+						  ## Markdown support
+
+						  For those of you who like that sort of thing.
+						  Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
+						</section>
+						```
+					</script>
+				</section>
+
+				<section id="transitions">
+					<h2>Transition Styles</h2>
+					<p>
+						You can select from different transitions, like: <br>
+						<a href="?transition=cube#/transitions">Cube</a> -
+						<a href="?transition=page#/transitions">Page</a> -
+						<a href="?transition=concave#/transitions">Concave</a> -
+						<a href="?transition=zoom#/transitions">Zoom</a> -
+						<a href="?transition=linear#/transitions">Linear</a> -
+						<a href="?transition=fade#/transitions">Fade</a> -
+						<a href="?transition=none#/transitions">None</a> -
+						<a href="?#/transitions">Default</a>
+					</p>
+				</section>
+
+				<section id="themes">
+					<h2>Themes</h2>
+					<p>
+						Reveal.js comes with a few themes built in: <br>
+						<a href="?#/themes">Default</a> -
+						<a href="?theme=sky#/themes">Sky</a> -
+						<a href="?theme=beige#/themes">Beige</a> -
+						<a href="?theme=simple#/themes">Simple</a> -
+						<a href="?theme=serif#/themes">Serif</a> -
+						<a href="?theme=night#/themes">Night</a> <br>
+						<a href="?theme=moon#/themes">Moon</a> -
+						<a href="?theme=solarized#/themes">Solarized</a>
+					</p>
+					<p>
+						<small>
+							* Theme demos are loaded after the presentation which leads to flicker. In production you should load your theme in the <code>&lt;head&gt;</code> using a <code>&lt;link&gt;</code>.
+						</small>
+					</p>
+				</section>
+
+				<section>
+					<h2>Global State</h2>
+					<p>
+						Set <code>data-state="something"</code> on a slide and <code>"something"</code>
+						will be added as a class to the document element when the slide is open. This lets you
+						apply broader style changes, like switching the background.
+					</p>
+				</section>
+
+				<section data-state="customevent">
+					<h2>Custom Events</h2>
+					<p>
+						Additionally custom events can be triggered on a per slide basis by binding to the <code>data-state</code> name.
+					</p>
+					<pre><code data-trim contenteditable style="font-size: 18px; margin-top: 20px;">
+Reveal.addEventListener( 'customevent', function() {
+	console.log( '"customevent" has fired' );
+} );
+					</code></pre>
+				</section>
+
+				<section>
+					<section data-background="#007777">
+						<h2>Slide Backgrounds</h2>
+						<p>
+							Set <code>data-background="#007777"</code> on a slide to change the full page background to the given color. All CSS color formats are supported.
+						</p>
+						<a href="#" class="image navigate-down">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
+						</a>
+					</section>
+					<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png">
+						<h2>Image Backgrounds</h2>
+						<pre><code>&lt;section data-background="image.png"&gt;</code></pre>
+					</section>
+					<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" data-background-repeat="repeat" data-background-size="100px">
+						<h2>Repeated Image Backgrounds</h2>
+						<pre><code style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre>
+					</section>
+				</section>
+
+				<section data-transition="linear" data-background="#4d7e65" data-background-transition="slide">
+					<h2>Background Transitions</h2>
+					<p>
+						Pass reveal.js the <code>backgroundTransition: 'slide'</code> config argument to make backgrounds slide rather than fade.
+					</p>
+				</section>
+
+				<section data-transition="linear" data-background="#8c4738" data-background-transition="slide">
+					<h2>Background Transition Override</h2>
+					<p>
+						You can override background transitions per slide by using <code>data-background-transition="slide"</code>.
+					</p>
+				</section>
+
+				<section>
+					<h2>Clever Quotes</h2>
+					<p>
+						These guys come in two forms, inline: <q cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
+						&ldquo;The nice thing about standards is that there are so many to choose from&rdquo;</q> and block:
+					</p>
+					<blockquote cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
+						&ldquo;For years there has been a theory that millions of monkeys typing at random on millions of typewriters would
+						reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.&rdquo;
+					</blockquote>
+				</section>
+
+				<section>
+					<h2>Pretty Code</h2>
+					<pre><code data-trim contenteditable>
+function linkify( selector ) {
+  if( supports3DTransforms ) {
+
+    var nodes = document.querySelectorAll( selector );
+
+    for( var i = 0, len = nodes.length; i &lt; len; i++ ) {
+      var node = nodes[i];
+
+      if( !node.className ) {
+        node.className += ' roll';
+      }
+    }
+  }
+}
+					</code></pre>
+					<p>Courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p>
+				</section>
+
+				<section>
+					<h2>Intergalactic Interconnections</h2>
+					<p>
+						You can link between slides internally,
+						<a href="#/2/3">like this</a>.
+					</p>
+				</section>
+
+				<section>
+					<section id="fragments">
+						<h2>Fragmented Views</h2>
+						<p>Hit the next arrow...</p>
+						<p class="fragment">... to step through ...</p>
+						<ol>
+							<li class="fragment"><code>any type</code></li>
+							<li class="fragment"><em>of view</em></li>
+							<li class="fragment"><strong>fragments</strong></li>
+						</ol>
+
+						<aside class="notes">
+							This slide has fragments which are also stepped through in the notes window.
+						</aside>
+					</section>
+					<section>
+						<h2>Fragment Styles</h2>
+						<p>There's a few styles of fragments, like:</p>
+						<p class="fragment grow">grow</p>
+						<p class="fragment shrink">shrink</p>
+						<p class="fragment roll-in">roll-in</p>
+						<p class="fragment fade-out">fade-out</p>
+						<p class="fragment highlight-red">highlight-red</p>
+						<p class="fragment highlight-green">highlight-green</p>
+						<p class="fragment highlight-blue">highlight-blue</p>
+						<p class="fragment current-visible">current-visible</p>
+						<p class="fragment highlight-current-blue">highlight-current-blue</p>
+					</section>
+				</section>
+
+				<section>
+					<h2>Spectacular image!</h2>
+					<a class="image" href="http://lab.hakim.se/meny/" target="_blank">
+						<img width="320" height="299" src="http://s3.amazonaws.com/hakim-static/portfolio/images/meny.png" alt="Meny">
+					</a>
+				</section>
+
+				<section>
+					<h2>Export to PDF</h2>
+					<p>Presentations can be <a href="https://github.com/hakimel/reveal.js#pdf-export">exported to PDF</a>, below is an example that's been uploaded to SlideShare.</p>
+					<iframe id="slideshare" src="http://www.slideshare.net/slideshow/embed_code/13872948" width="455" height="356" style="margin:0;overflow:hidden;border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen> </iframe>
+					<script>
+						document.getElementById('slideshare').attributeName = 'allowfullscreen';
+					</script>
+				</section>
+
+				<section>
+					<h2>Take a Moment</h2>
+					<p>
+						Press b or period on your keyboard to enter the 'paused' mode. This mode is helpful when you want to take distracting slides off the screen
+						during a presentation.
+					</p>
+				</section>
+
+				<section>
+					<h2>Stellar Links</h2>
+					<ul>
+						<li><a href="http://slid.es">Try the online editor</a></li>
+						<li><a href="https://github.com/hakimel/reveal.js">Source code on GitHub</a></li>
+						<li><a href="http://twitter.com/hakimel">Follow me on Twitter</a></li>
+					</ul>
+				</section>
+
+				<section>
+					<h1>THE END</h1>
+					<h3>BY Hakim El Hattab / hakim.se</h3>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="lib/js/head.min.js"></script>
+		<script src="js/reveal.min.js"></script>
+
+		<script>
+
+			// Full list of configuration options available here:
+			// https://github.com/hakimel/reveal.js#configuration
+			Reveal.initialize({
+				controls: true,
+				progress: true,
+				history: true,
+				center: true,
+
+				theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
+				transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+				// Parallax scrolling
+				// parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg',
+				// parallaxBackgroundSize: '2100px 900px',
+
+				// Optional libraries used to extend on reveal.js
+				dependencies: [
+					{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
+					{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+					{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
+					{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
+				]
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/js/reveal.js b/docs/slides/BOS14/_support/reveal.js/js/reveal.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/js/reveal.js
@@ -0,0 +1,3382 @@
+/*!
+ * reveal.js
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+ */
+var Reveal = (function(){
+
+	'use strict';
+
+	var SLIDES_SELECTOR = '.reveal .slides section',
+		HORIZONTAL_SLIDES_SELECTOR = '.reveal .slides>section',
+		VERTICAL_SLIDES_SELECTOR = '.reveal .slides>section.present>section',
+		HOME_SLIDE_SELECTOR = '.reveal .slides>section:first-of-type',
+
+		// Configurations defaults, can be overridden at initialization time
+		config = {
+
+			// The "normal" size of the presentation, aspect ratio will be preserved
+			// when the presentation is scaled to fit different resolutions
+			width: 960,
+			height: 700,
+
+			// Factor of the display size that should remain empty around the content
+			margin: 0.1,
+
+			// Bounds for smallest/largest possible scale to apply to content
+			minScale: 0.2,
+			maxScale: 1.0,
+
+			// Display controls in the bottom right corner
+			controls: true,
+
+			// Display a presentation progress bar
+			progress: true,
+
+			// Display the page number of the current slide
+			slideNumber: false,
+
+			// Push each slide change to the browser history
+			history: false,
+
+			// Enable keyboard shortcuts for navigation
+			keyboard: true,
+
+			// Enable the slide overview mode
+			overview: true,
+
+			// Vertical centering of slides
+			center: true,
+
+			// Enables touch navigation on devices with touch input
+			touch: true,
+
+			// Loop the presentation
+			loop: false,
+
+			// Change the presentation direction to be RTL
+			rtl: false,
+
+			// Turns fragments on and off globally
+			fragments: true,
+
+			// Flags if the presentation is running in an embedded mode,
+			// i.e. contained within a limited portion of the screen
+			embedded: false,
+
+			// Number of milliseconds between automatically proceeding to the
+			// next slide, disabled when set to 0, this value can be overwritten
+			// by using a data-autoslide attribute on your slides
+			autoSlide: 0,
+
+			// Stop auto-sliding after user input
+			autoSlideStoppable: true,
+
+			// Enable slide navigation via mouse wheel
+			mouseWheel: false,
+
+			// Apply a 3D roll to links on hover
+			rollingLinks: false,
+
+			// Hides the address bar on mobile devices
+			hideAddressBar: true,
+
+			// Opens links in an iframe preview overlay
+			previewLinks: false,
+
+			// Focuses body when page changes visiblity to ensure keyboard shortcuts work
+			focusBodyOnPageVisiblityChange: true,
+
+			// Theme (see /css/theme)
+			theme: null,
+
+			// Transition style
+			transition: 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+			// Transition speed
+			transitionSpeed: 'default', // default/fast/slow
+
+			// Transition style for full page slide backgrounds
+			backgroundTransition: 'default', // default/linear/none
+
+			// Parallax background image
+			parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg"
+
+			// Parallax background size
+			parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px"
+
+			// Number of slides away from the current that are visible
+			viewDistance: 3,
+
+			// Script dependencies to load
+			dependencies: []
+
+		},
+
+		// Flags if reveal.js is loaded (has dispatched the 'ready' event)
+		loaded = false,
+
+		// The horizontal and vertical index of the currently active slide
+		indexh,
+		indexv,
+
+		// The previous and current slide HTML elements
+		previousSlide,
+		currentSlide,
+
+		previousBackground,
+
+		// Slides may hold a data-state attribute which we pick up and apply
+		// as a class to the body. This list contains the combined state of
+		// all current slides.
+		state = [],
+
+		// The current scale of the presentation (see width/height config)
+		scale = 1,
+
+		// Cached references to DOM elements
+		dom = {},
+
+		// Features supported by the browser, see #checkCapabilities()
+		features = {},
+
+		// Client is a mobile device, see #checkCapabilities()
+		isMobileDevice,
+
+		// Throttles mouse wheel navigation
+		lastMouseWheelStep = 0,
+
+		// Delays updates to the URL due to a Chrome thumbnailer bug
+		writeURLTimeout = 0,
+
+		// A delay used to activate the overview mode
+		activateOverviewTimeout = 0,
+
+		// A delay used to deactivate the overview mode
+		deactivateOverviewTimeout = 0,
+
+		// Flags if the interaction event listeners are bound
+		eventsAreBound = false,
+
+		// The current auto-slide duration
+		autoSlide = 0,
+
+		// Auto slide properties
+		autoSlidePlayer,
+		autoSlideTimeout = 0,
+		autoSlideStartTime = -1,
+		autoSlidePaused = false,
+
+		// Holds information about the currently ongoing touch input
+		touch = {
+			startX: 0,
+			startY: 0,
+			startSpan: 0,
+			startCount: 0,
+			captured: false,
+			threshold: 40
+		};
+
+	/**
+	 * Starts up the presentation if the client is capable.
+	 */
+	function initialize( options ) {
+
+		checkCapabilities();
+
+		if( !features.transforms2d && !features.transforms3d ) {
+			document.body.setAttribute( 'class', 'no-transforms' );
+
+			// If the browser doesn't support core features we won't be
+			// using JavaScript to control the presentation
+			return;
+		}
+
+		// Force a layout when the whole page, incl fonts, has loaded
+		window.addEventListener( 'load', layout, false );
+
+		var query = Reveal.getQueryHash();
+
+		// Do not accept new dependencies via query config to avoid
+		// the potential of malicious script injection
+		if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];
+
+		// Copy options over to our config object
+		extend( config, options );
+		extend( config, query );
+
+		// Hide the address bar in mobile browsers
+		hideAddressBar();
+
+		// Loads the dependencies and continues to #start() once done
+		load();
+
+	}
+
+	/**
+	 * Inspect the client to see what it's capable of, this
+	 * should only happens once per runtime.
+	 */
+	function checkCapabilities() {
+
+		features.transforms3d = 'WebkitPerspective' in document.body.style ||
+								'MozPerspective' in document.body.style ||
+								'msPerspective' in document.body.style ||
+								'OPerspective' in document.body.style ||
+								'perspective' in document.body.style;
+
+		features.transforms2d = 'WebkitTransform' in document.body.style ||
+								'MozTransform' in document.body.style ||
+								'msTransform' in document.body.style ||
+								'OTransform' in document.body.style ||
+								'transform' in document.body.style;
+
+		features.requestAnimationFrameMethod = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
+		features.requestAnimationFrame = typeof features.requestAnimationFrameMethod === 'function';
+
+		features.canvas = !!document.createElement( 'canvas' ).getContext;
+
+		isMobileDevice = navigator.userAgent.match( /(iphone|ipod|android)/gi );
+
+	}
+
+
+    /**
+     * Loads the dependencies of reveal.js. Dependencies are
+     * defined via the configuration option 'dependencies'
+     * and will be loaded prior to starting/binding reveal.js.
+     * Some dependencies may have an 'async' flag, if so they
+     * will load after reveal.js has been started up.
+     */
+	function load() {
+
+		var scripts = [],
+			scriptsAsync = [],
+			scriptsToPreload = 0;
+
+		// Called once synchronous scripts finish loading
+		function proceed() {
+			if( scriptsAsync.length ) {
+				// Load asynchronous scripts
+				head.js.apply( null, scriptsAsync );
+			}
+
+			start();
+		}
+
+		function loadScript( s ) {
+			head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], function() {
+				// Extension may contain callback functions
+				if( typeof s.callback === 'function' ) {
+					s.callback.apply( this );
+				}
+
+				if( --scriptsToPreload === 0 ) {
+					proceed();
+				}
+			});
+		}
+
+		for( var i = 0, len = config.dependencies.length; i < len; i++ ) {
+			var s = config.dependencies[i];
+
+			// Load if there's no condition or the condition is truthy
+			if( !s.condition || s.condition() ) {
+				if( s.async ) {
+					scriptsAsync.push( s.src );
+				}
+				else {
+					scripts.push( s.src );
+				}
+
+				loadScript( s );
+			}
+		}
+
+		if( scripts.length ) {
+			scriptsToPreload = scripts.length;
+
+			// Load synchronous scripts
+			head.js.apply( null, scripts );
+		}
+		else {
+			proceed();
+		}
+
+	}
+
+	/**
+	 * Starts up reveal.js by binding input events and navigating
+	 * to the current URL deeplink if there is one.
+	 */
+	function start() {
+
+		// Make sure we've got all the DOM elements we need
+		setupDOM();
+
+		// Resets all vertical slides so that only the first is visible
+		resetVerticalSlides();
+
+		// Updates the presentation to match the current configuration values
+		configure();
+
+		// Read the initial hash
+		readURL();
+
+		// Update all backgrounds
+		updateBackground( true );
+
+		// Notify listeners that the presentation is ready but use a 1ms
+		// timeout to ensure it's not fired synchronously after #initialize()
+		setTimeout( function() {
+			// Enable transitions now that we're loaded
+			dom.slides.classList.remove( 'no-transition' );
+
+			loaded = true;
+
+			dispatchEvent( 'ready', {
+				'indexh': indexh,
+				'indexv': indexv,
+				'currentSlide': currentSlide
+			} );
+		}, 1 );
+
+	}
+
+	/**
+	 * Finds and stores references to DOM elements which are
+	 * required by the presentation. If a required element is
+	 * not found, it is created.
+	 */
+	function setupDOM() {
+
+		// Cache references to key DOM elements
+		dom.theme = document.querySelector( '#theme' );
+		dom.wrapper = document.querySelector( '.reveal' );
+		dom.slides = document.querySelector( '.reveal .slides' );
+
+		// Prevent transitions while we're loading
+		dom.slides.classList.add( 'no-transition' );
+
+		// Background element
+		dom.background = createSingletonNode( dom.wrapper, 'div', 'backgrounds', null );
+
+		// Progress bar
+		dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '<span></span>' );
+		dom.progressbar = dom.progress.querySelector( 'span' );
+
+		// Arrow controls
+		createSingletonNode( dom.wrapper, 'aside', 'controls',
+			'<div class="navigate-left"></div>' +
+			'<div class="navigate-right"></div>' +
+			'<div class="navigate-up"></div>' +
+			'<div class="navigate-down"></div>' );
+
+		// Slide number
+		dom.slideNumber = createSingletonNode( dom.wrapper, 'div', 'slide-number', '' );
+
+		// State background element [DEPRECATED]
+		createSingletonNode( dom.wrapper, 'div', 'state-background', null );
+
+		// Overlay graphic which is displayed during the paused mode
+		createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null );
+
+		// Cache references to elements
+		dom.controls = document.querySelector( '.reveal .controls' );
+
+		// There can be multiple instances of controls throughout the page
+		dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) );
+		dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) );
+		dom.controlsUp = toArray( document.querySelectorAll( '.navigate-up' ) );
+		dom.controlsDown = toArray( document.querySelectorAll( '.navigate-down' ) );
+		dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) );
+		dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) );
+
+	}
+
+	/**
+	 * Creates an HTML element and returns a reference to it.
+	 * If the element already exists the existing instance will
+	 * be returned.
+	 */
+	function createSingletonNode( container, tagname, classname, innerHTML ) {
+
+		var node = container.querySelector( '.' + classname );
+		if( !node ) {
+			node = document.createElement( tagname );
+			node.classList.add( classname );
+			if( innerHTML !== null ) {
+				node.innerHTML = innerHTML;
+			}
+			container.appendChild( node );
+		}
+		return node;
+
+	}
+
+	/**
+	 * Creates the slide background elements and appends them
+	 * to the background container. One element is created per
+	 * slide no matter if the given slide has visible background.
+	 */
+	function createBackgrounds() {
+
+		if( isPrintingPDF() ) {
+			document.body.classList.add( 'print-pdf' );
+		}
+
+		// Clear prior backgrounds
+		dom.background.innerHTML = '';
+		dom.background.classList.add( 'no-transition' );
+
+		// Helper method for creating a background element for the
+		// given slide
+		function _createBackground( slide, container ) {
+
+			var data = {
+				background: slide.getAttribute( 'data-background' ),
+				backgroundSize: slide.getAttribute( 'data-background-size' ),
+				backgroundImage: slide.getAttribute( 'data-background-image' ),
+				backgroundColor: slide.getAttribute( 'data-background-color' ),
+				backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
+				backgroundPosition: slide.getAttribute( 'data-background-position' ),
+				backgroundTransition: slide.getAttribute( 'data-background-transition' )
+			};
+
+			var element = document.createElement( 'div' );
+			element.className = 'slide-background';
+
+			if( data.background ) {
+				// Auto-wrap image urls in url(...)
+				if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
+					element.style.backgroundImage = 'url('+ data.background +')';
+				}
+				else {
+					element.style.background = data.background;
+				}
+			}
+
+			if( data.background || data.backgroundColor || data.backgroundImage ) {
+				element.setAttribute( 'data-background-hash', data.background + data.backgroundSize + data.backgroundImage + data.backgroundColor + data.backgroundRepeat + data.backgroundPosition + data.backgroundTransition );
+			}
+
+			// Additional and optional background properties
+			if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize;
+			if( data.backgroundImage ) element.style.backgroundImage = 'url("' + data.backgroundImage + '")';
+			if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
+			if( data.backgroundRepeat ) element.style.backgroundRepeat = data.backgroundRepeat;
+			if( data.backgroundPosition ) element.style.backgroundPosition = data.backgroundPosition;
+			if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
+
+			container.appendChild( element );
+
+			return element;
+
+		}
+
+		// Iterate over all horizontal slides
+		toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( slideh ) {
+
+			var backgroundStack;
+
+			if( isPrintingPDF() ) {
+				backgroundStack = _createBackground( slideh, slideh );
+			}
+			else {
+				backgroundStack = _createBackground( slideh, dom.background );
+			}
+
+			// Iterate over all vertical slides
+			toArray( slideh.querySelectorAll( 'section' ) ).forEach( function( slidev ) {
+
+				if( isPrintingPDF() ) {
+					_createBackground( slidev, slidev );
+				}
+				else {
+					_createBackground( slidev, backgroundStack );
+				}
+
+			} );
+
+		} );
+
+		// Add parallax background if specified
+		if( config.parallaxBackgroundImage ) {
+
+			dom.background.style.backgroundImage = 'url("' + config.parallaxBackgroundImage + '")';
+			dom.background.style.backgroundSize = config.parallaxBackgroundSize;
+
+			// Make sure the below properties are set on the element - these properties are
+			// needed for proper transitions to be set on the element via CSS. To remove
+			// annoying background slide-in effect when the presentation starts, apply
+			// these properties after short time delay
+			setTimeout( function() {
+				dom.wrapper.classList.add( 'has-parallax-background' );
+			}, 1 );
+
+		}
+		else {
+
+			dom.background.style.backgroundImage = '';
+			dom.wrapper.classList.remove( 'has-parallax-background' );
+
+		}
+
+	}
+
+	/**
+	 * Applies the configuration settings from the config
+	 * object. May be called multiple times.
+	 */
+	function configure( options ) {
+
+		var numberOfSlides = document.querySelectorAll( SLIDES_SELECTOR ).length;
+
+		dom.wrapper.classList.remove( config.transition );
+
+		// New config options may be passed when this method
+		// is invoked through the API after initialization
+		if( typeof options === 'object' ) extend( config, options );
+
+		// Force linear transition based on browser capabilities
+		if( features.transforms3d === false ) config.transition = 'linear';
+
+		dom.wrapper.classList.add( config.transition );
+
+		dom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed );
+		dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );
+
+		dom.controls.style.display = config.controls ? 'block' : 'none';
+		dom.progress.style.display = config.progress ? 'block' : 'none';
+
+		if( config.rtl ) {
+			dom.wrapper.classList.add( 'rtl' );
+		}
+		else {
+			dom.wrapper.classList.remove( 'rtl' );
+		}
+
+		if( config.center ) {
+			dom.wrapper.classList.add( 'center' );
+		}
+		else {
+			dom.wrapper.classList.remove( 'center' );
+		}
+
+		if( config.mouseWheel ) {
+			document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
+			document.addEventListener( 'mousewheel', onDocumentMouseScroll, false );
+		}
+		else {
+			document.removeEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
+			document.removeEventListener( 'mousewheel', onDocumentMouseScroll, false );
+		}
+
+		// Rolling 3D links
+		if( config.rollingLinks ) {
+			enableRollingLinks();
+		}
+		else {
+			disableRollingLinks();
+		}
+
+		// Iframe link previews
+		if( config.previewLinks ) {
+			enablePreviewLinks();
+		}
+		else {
+			disablePreviewLinks();
+			enablePreviewLinks( '[data-preview-link]' );
+		}
+
+		// Auto-slide playback controls
+		if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable && features.canvas && features.requestAnimationFrame ) {
+			autoSlidePlayer = new Playback( dom.wrapper, function() {
+				return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );
+			} );
+
+			autoSlidePlayer.on( 'click', onAutoSlidePlayerClick );
+			autoSlidePaused = false;
+		}
+		else if( autoSlidePlayer ) {
+			autoSlidePlayer.destroy();
+			autoSlidePlayer = null;
+		}
+
+		// Load the theme in the config, if it's not already loaded
+		if( config.theme && dom.theme ) {
+			var themeURL = dom.theme.getAttribute( 'href' );
+			var themeFinder = /[^\/]*?(?=\.css)/;
+			var themeName = themeURL.match(themeFinder)[0];
+
+			if(  config.theme !== themeName ) {
+				themeURL = themeURL.replace(themeFinder, config.theme);
+				dom.theme.setAttribute( 'href', themeURL );
+			}
+		}
+
+		sync();
+
+	}
+
+	/**
+	 * Binds all event listeners.
+	 */
+	function addEventListeners() {
+
+		eventsAreBound = true;
+
+		window.addEventListener( 'hashchange', onWindowHashChange, false );
+		window.addEventListener( 'resize', onWindowResize, false );
+
+		if( config.touch ) {
+			dom.wrapper.addEventListener( 'touchstart', onTouchStart, false );
+			dom.wrapper.addEventListener( 'touchmove', onTouchMove, false );
+			dom.wrapper.addEventListener( 'touchend', onTouchEnd, false );
+
+			// Support pointer-style touch interaction as well
+			if( window.navigator.msPointerEnabled ) {
+				dom.wrapper.addEventListener( 'MSPointerDown', onPointerDown, false );
+				dom.wrapper.addEventListener( 'MSPointerMove', onPointerMove, false );
+				dom.wrapper.addEventListener( 'MSPointerUp', onPointerUp, false );
+			}
+		}
+
+		if( config.keyboard ) {
+			document.addEventListener( 'keydown', onDocumentKeyDown, false );
+		}
+
+		if( config.progress && dom.progress ) {
+			dom.progress.addEventListener( 'click', onProgressClicked, false );
+		}
+
+		if( config.focusBodyOnPageVisiblityChange ) {
+			var visibilityChange;
+
+			if( 'hidden' in document ) {
+				visibilityChange = 'visibilitychange';
+			}
+			else if( 'msHidden' in document ) {
+				visibilityChange = 'msvisibilitychange';
+			}
+			else if( 'webkitHidden' in document ) {
+				visibilityChange = 'webkitvisibilitychange';
+			}
+
+			if( visibilityChange ) {
+				document.addEventListener( visibilityChange, onPageVisibilityChange, false );
+			}
+		}
+
+		[ 'touchstart', 'click' ].forEach( function( eventName ) {
+			dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } );
+			dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } );
+			dom.controlsUp.forEach( function( el ) { el.addEventListener( eventName, onNavigateUpClicked, false ); } );
+			dom.controlsDown.forEach( function( el ) { el.addEventListener( eventName, onNavigateDownClicked, false ); } );
+			dom.controlsPrev.forEach( function( el ) { el.addEventListener( eventName, onNavigatePrevClicked, false ); } );
+			dom.controlsNext.forEach( function( el ) { el.addEventListener( eventName, onNavigateNextClicked, false ); } );
+		} );
+
+	}
+
+	/**
+	 * Unbinds all event listeners.
+	 */
+	function removeEventListeners() {
+
+		eventsAreBound = false;
+
+		document.removeEventListener( 'keydown', onDocumentKeyDown, false );
+		window.removeEventListener( 'hashchange', onWindowHashChange, false );
+		window.removeEventListener( 'resize', onWindowResize, false );
+
+		dom.wrapper.removeEventListener( 'touchstart', onTouchStart, false );
+		dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false );
+		dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false );
+
+		if( window.navigator.msPointerEnabled ) {
+			dom.wrapper.removeEventListener( 'MSPointerDown', onPointerDown, false );
+			dom.wrapper.removeEventListener( 'MSPointerMove', onPointerMove, false );
+			dom.wrapper.removeEventListener( 'MSPointerUp', onPointerUp, false );
+		}
+
+		if ( config.progress && dom.progress ) {
+			dom.progress.removeEventListener( 'click', onProgressClicked, false );
+		}
+
+		[ 'touchstart', 'click' ].forEach( function( eventName ) {
+			dom.controlsLeft.forEach( function( el ) { el.removeEventListener( eventName, onNavigateLeftClicked, false ); } );
+			dom.controlsRight.forEach( function( el ) { el.removeEventListener( eventName, onNavigateRightClicked, false ); } );
+			dom.controlsUp.forEach( function( el ) { el.removeEventListener( eventName, onNavigateUpClicked, false ); } );
+			dom.controlsDown.forEach( function( el ) { el.removeEventListener( eventName, onNavigateDownClicked, false ); } );
+			dom.controlsPrev.forEach( function( el ) { el.removeEventListener( eventName, onNavigatePrevClicked, false ); } );
+			dom.controlsNext.forEach( function( el ) { el.removeEventListener( eventName, onNavigateNextClicked, false ); } );
+		} );
+
+	}
+
+	/**
+	 * Extend object a with the properties of object b.
+	 * If there's a conflict, object b takes precedence.
+	 */
+	function extend( a, b ) {
+
+		for( var i in b ) {
+			a[ i ] = b[ i ];
+		}
+
+	}
+
+	/**
+	 * Converts the target object to an array.
+	 */
+	function toArray( o ) {
+
+		return Array.prototype.slice.call( o );
+
+	}
+
+	/**
+	 * Measures the distance in pixels between point a
+	 * and point b.
+	 *
+	 * @param {Object} a point with x/y properties
+	 * @param {Object} b point with x/y properties
+	 */
+	function distanceBetween( a, b ) {
+
+		var dx = a.x - b.x,
+			dy = a.y - b.y;
+
+		return Math.sqrt( dx*dx + dy*dy );
+
+	}
+
+	/**
+	 * Applies a CSS transform to the target element.
+	 */
+	function transformElement( element, transform ) {
+
+		element.style.WebkitTransform = transform;
+		element.style.MozTransform = transform;
+		element.style.msTransform = transform;
+		element.style.OTransform = transform;
+		element.style.transform = transform;
+
+	}
+
+	/**
+	 * Retrieves the height of the given element by looking
+	 * at the position and height of its immediate children.
+	 */
+	function getAbsoluteHeight( element ) {
+
+		var height = 0;
+
+		if( element ) {
+			var absoluteChildren = 0;
+
+			toArray( element.childNodes ).forEach( function( child ) {
+
+				if( typeof child.offsetTop === 'number' && child.style ) {
+					// Count # of abs children
+					if( child.style.position === 'absolute' ) {
+						absoluteChildren += 1;
+					}
+
+					height = Math.max( height, child.offsetTop + child.offsetHeight );
+				}
+
+			} );
+
+			// If there are no absolute children, use offsetHeight
+			if( absoluteChildren === 0 ) {
+				height = element.offsetHeight;
+			}
+
+		}
+
+		return height;
+
+	}
+
+	/**
+	 * Returns the remaining height within the parent of the
+	 * target element after subtracting the height of all
+	 * siblings.
+	 *
+	 * remaining height = [parent height] - [ siblings height]
+	 */
+	function getRemainingHeight( element, height ) {
+
+		height = height || 0;
+
+		if( element ) {
+			var parent = element.parentNode;
+			var siblings = parent.childNodes;
+
+			// Subtract the height of each sibling
+			toArray( siblings ).forEach( function( sibling ) {
+
+				if( typeof sibling.offsetHeight === 'number' && sibling !== element ) {
+
+					var styles = window.getComputedStyle( sibling ),
+						marginTop = parseInt( styles.marginTop, 10 ),
+						marginBottom = parseInt( styles.marginBottom, 10 );
+
+					height -= sibling.offsetHeight + marginTop + marginBottom;
+
+				}
+
+			} );
+
+			var elementStyles = window.getComputedStyle( element );
+
+			// Subtract the margins of the target element
+			height -= parseInt( elementStyles.marginTop, 10 ) +
+						parseInt( elementStyles.marginBottom, 10 );
+
+		}
+
+		return height;
+
+	}
+
+	/**
+	 * Checks if this instance is being used to print a PDF.
+	 */
+	function isPrintingPDF() {
+
+		return ( /print-pdf/gi ).test( window.location.search );
+
+	}
+
+	/**
+	 * Hides the address bar if we're on a mobile device.
+	 */
+	function hideAddressBar() {
+
+		if( config.hideAddressBar && isMobileDevice ) {
+			// Events that should trigger the address bar to hide
+			window.addEventListener( 'load', removeAddressBar, false );
+			window.addEventListener( 'orientationchange', removeAddressBar, false );
+		}
+
+	}
+
+	/**
+	 * Causes the address bar to hide on mobile devices,
+	 * more vertical space ftw.
+	 */
+	function removeAddressBar() {
+
+		setTimeout( function() {
+			window.scrollTo( 0, 1 );
+		}, 10 );
+
+	}
+
+	/**
+	 * Dispatches an event of the specified type from the
+	 * reveal DOM element.
+	 */
+	function dispatchEvent( type, properties ) {
+
+		var event = document.createEvent( "HTMLEvents", 1, 2 );
+		event.initEvent( type, true, true );
+		extend( event, properties );
+		dom.wrapper.dispatchEvent( event );
+
+	}
+
+	/**
+	 * Wrap all links in 3D goodness.
+	 */
+	function enableRollingLinks() {
+
+		if( features.transforms3d && !( 'msPerspective' in document.body.style ) ) {
+			var anchors = document.querySelectorAll( SLIDES_SELECTOR + ' a:not(.image)' );
+
+			for( var i = 0, len = anchors.length; i < len; i++ ) {
+				var anchor = anchors[i];
+
+				if( anchor.textContent && !anchor.querySelector( '*' ) && ( !anchor.className || !anchor.classList.contains( anchor, 'roll' ) ) ) {
+					var span = document.createElement('span');
+					span.setAttribute('data-title', anchor.text);
+					span.innerHTML = anchor.innerHTML;
+
+					anchor.classList.add( 'roll' );
+					anchor.innerHTML = '';
+					anchor.appendChild(span);
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * Unwrap all 3D links.
+	 */
+	function disableRollingLinks() {
+
+		var anchors = document.querySelectorAll( SLIDES_SELECTOR + ' a.roll' );
+
+		for( var i = 0, len = anchors.length; i < len; i++ ) {
+			var anchor = anchors[i];
+			var span = anchor.querySelector( 'span' );
+
+			if( span ) {
+				anchor.classList.remove( 'roll' );
+				anchor.innerHTML = span.innerHTML;
+			}
+		}
+
+	}
+
+	/**
+	 * Bind preview frame links.
+	 */
+	function enablePreviewLinks( selector ) {
+
+		var anchors = toArray( document.querySelectorAll( selector ? selector : 'a' ) );
+
+		anchors.forEach( function( element ) {
+			if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) {
+				element.addEventListener( 'click', onPreviewLinkClicked, false );
+			}
+		} );
+
+	}
+
+	/**
+	 * Unbind preview frame links.
+	 */
+	function disablePreviewLinks() {
+
+		var anchors = toArray( document.querySelectorAll( 'a' ) );
+
+		anchors.forEach( function( element ) {
+			if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) {
+				element.removeEventListener( 'click', onPreviewLinkClicked, false );
+			}
+		} );
+
+	}
+
+	/**
+	 * Opens a preview window for the target URL.
+	 */
+	function openPreview( url ) {
+
+		closePreview();
+
+		dom.preview = document.createElement( 'div' );
+		dom.preview.classList.add( 'preview-link-overlay' );
+		dom.wrapper.appendChild( dom.preview );
+
+		dom.preview.innerHTML = [
+			'<header>',
+				'<a class="close" href="#"><span class="icon"></span></a>',
+				'<a class="external" href="'+ url +'" target="_blank"><span class="icon"></span></a>',
+			'</header>',
+			'<div class="spinner"></div>',
+			'<div class="viewport">',
+				'<iframe src="'+ url +'"></iframe>',
+			'</div>'
+		].join('');
+
+		dom.preview.querySelector( 'iframe' ).addEventListener( 'load', function( event ) {
+			dom.preview.classList.add( 'loaded' );
+		}, false );
+
+		dom.preview.querySelector( '.close' ).addEventListener( 'click', function( event ) {
+			closePreview();
+			event.preventDefault();
+		}, false );
+
+		dom.preview.querySelector( '.external' ).addEventListener( 'click', function( event ) {
+			closePreview();
+		}, false );
+
+		setTimeout( function() {
+			dom.preview.classList.add( 'visible' );
+		}, 1 );
+
+	}
+
+	/**
+	 * Closes the iframe preview window.
+	 */
+	function closePreview() {
+
+		if( dom.preview ) {
+			dom.preview.setAttribute( 'src', '' );
+			dom.preview.parentNode.removeChild( dom.preview );
+			dom.preview = null;
+		}
+
+	}
+
+	/**
+	 * Applies JavaScript-controlled layout rules to the
+	 * presentation.
+	 */
+	function layout() {
+
+		if( dom.wrapper && !isPrintingPDF() ) {
+
+			// Available space to scale within
+			var availableWidth = dom.wrapper.offsetWidth,
+				availableHeight = dom.wrapper.offsetHeight;
+
+			// Reduce available space by margin
+			availableWidth -= ( availableHeight * config.margin );
+			availableHeight -= ( availableHeight * config.margin );
+
+			// Dimensions of the content
+			var slideWidth = config.width,
+				slideHeight = config.height,
+				slidePadding = 20; // TODO Dig this out of DOM
+
+			// Layout the contents of the slides
+			layoutSlideContents( config.width, config.height, slidePadding );
+
+			// Slide width may be a percentage of available width
+			if( typeof slideWidth === 'string' && /%$/.test( slideWidth ) ) {
+				slideWidth = parseInt( slideWidth, 10 ) / 100 * availableWidth;
+			}
+
+			// Slide height may be a percentage of available height
+			if( typeof slideHeight === 'string' && /%$/.test( slideHeight ) ) {
+				slideHeight = parseInt( slideHeight, 10 ) / 100 * availableHeight;
+			}
+
+			dom.slides.style.width = slideWidth + 'px';
+			dom.slides.style.height = slideHeight + 'px';
+
+			// Determine scale of content to fit within available space
+			scale = Math.min( availableWidth / slideWidth, availableHeight / slideHeight );
+
+			// Respect max/min scale settings
+			scale = Math.max( scale, config.minScale );
+			scale = Math.min( scale, config.maxScale );
+
+			// Prefer applying scale via zoom since Chrome blurs scaled content
+			// with nested transforms
+			if( typeof dom.slides.style.zoom !== 'undefined' && !navigator.userAgent.match( /(iphone|ipod|ipad|android)/gi ) ) {
+				dom.slides.style.zoom = scale;
+			}
+			// Apply scale transform as a fallback
+			else {
+				transformElement( dom.slides, 'translate(-50%, -50%) scale('+ scale +') translate(50%, 50%)' );
+			}
+
+			// Select all slides, vertical and horizontal
+			var slides = toArray( document.querySelectorAll( SLIDES_SELECTOR ) );
+
+			for( var i = 0, len = slides.length; i < len; i++ ) {
+				var slide = slides[ i ];
+
+				// Don't bother updating invisible slides
+				if( slide.style.display === 'none' ) {
+					continue;
+				}
+
+				if( config.center || slide.classList.contains( 'center' ) ) {
+					// Vertical stacks are not centred since their section
+					// children will be
+					if( slide.classList.contains( 'stack' ) ) {
+						slide.style.top = 0;
+					}
+					else {
+						slide.style.top = Math.max( - ( getAbsoluteHeight( slide ) / 2 ) - slidePadding, -slideHeight / 2 ) + 'px';
+					}
+				}
+				else {
+					slide.style.top = '';
+				}
+
+			}
+
+			updateProgress();
+			updateParallax();
+
+		}
+
+	}
+
+	/**
+	 * Applies layout logic to the contents of all slides in
+	 * the presentation.
+	 */
+	function layoutSlideContents( width, height, padding ) {
+
+		// Handle sizing of elements with the 'stretch' class
+		toArray( dom.slides.querySelectorAll( 'section > .stretch' ) ).forEach( function( element ) {
+
+			// Determine how much vertical space we can use
+			var remainingHeight = getRemainingHeight( element, ( height - ( padding * 2 ) ) );
+
+			// Consider the aspect ratio of media elements
+			if( /(img|video)/gi.test( element.nodeName ) ) {
+				var nw = element.naturalWidth || element.videoWidth,
+					nh = element.naturalHeight || element.videoHeight;
+
+				var es = Math.min( width / nw, remainingHeight / nh );
+
+				element.style.width = ( nw * es ) + 'px';
+				element.style.height = ( nh * es ) + 'px';
+
+			}
+			else {
+				element.style.width = width + 'px';
+				element.style.height = remainingHeight + 'px';
+			}
+
+		} );
+
+	}
+
+	/**
+	 * Stores the vertical index of a stack so that the same
+	 * vertical slide can be selected when navigating to and
+	 * from the stack.
+	 *
+	 * @param {HTMLElement} stack The vertical stack element
+	 * @param {int} v Index to memorize
+	 */
+	function setPreviousVerticalIndex( stack, v ) {
+
+		if( typeof stack === 'object' && typeof stack.setAttribute === 'function' ) {
+			stack.setAttribute( 'data-previous-indexv', v || 0 );
+		}
+
+	}
+
+	/**
+	 * Retrieves the vertical index which was stored using
+	 * #setPreviousVerticalIndex() or 0 if no previous index
+	 * exists.
+	 *
+	 * @param {HTMLElement} stack The vertical stack element
+	 */
+	function getPreviousVerticalIndex( stack ) {
+
+		if( typeof stack === 'object' && typeof stack.setAttribute === 'function' && stack.classList.contains( 'stack' ) ) {
+			// Prefer manually defined start-indexv
+			var attributeName = stack.hasAttribute( 'data-start-indexv' ) ? 'data-start-indexv' : 'data-previous-indexv';
+
+			return parseInt( stack.getAttribute( attributeName ) || 0, 10 );
+		}
+
+		return 0;
+
+	}
+
+	/**
+	 * Displays the overview of slides (quick nav) by
+	 * scaling down and arranging all slide elements.
+	 *
+	 * Experimental feature, might be dropped if perf
+	 * can't be improved.
+	 */
+	function activateOverview() {
+
+		// Only proceed if enabled in config
+		if( config.overview ) {
+
+			// Don't auto-slide while in overview mode
+			cancelAutoSlide();
+
+			var wasActive = dom.wrapper.classList.contains( 'overview' );
+
+			// Vary the depth of the overview based on screen size
+			var depth = window.innerWidth < 400 ? 1000 : 2500;
+
+			dom.wrapper.classList.add( 'overview' );
+			dom.wrapper.classList.remove( 'overview-deactivating' );
+
+			clearTimeout( activateOverviewTimeout );
+			clearTimeout( deactivateOverviewTimeout );
+
+			// Not the pretties solution, but need to let the overview
+			// class apply first so that slides are measured accurately
+			// before we can position them
+			activateOverviewTimeout = setTimeout( function() {
+
+				var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+
+				for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
+					var hslide = horizontalSlides[i],
+						hoffset = config.rtl ? -105 : 105;
+
+					hslide.setAttribute( 'data-index-h', i );
+
+					// Apply CSS transform
+					transformElement( hslide, 'translateZ(-'+ depth +'px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)' );
+
+					if( hslide.classList.contains( 'stack' ) ) {
+
+						var verticalSlides = hslide.querySelectorAll( 'section' );
+
+						for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
+							var verticalIndex = i === indexh ? indexv : getPreviousVerticalIndex( hslide );
+
+							var vslide = verticalSlides[j];
+
+							vslide.setAttribute( 'data-index-h', i );
+							vslide.setAttribute( 'data-index-v', j );
+
+							// Apply CSS transform
+							transformElement( vslide, 'translate(0%, ' + ( ( j - verticalIndex ) * 105 ) + '%)' );
+
+							// Navigate to this slide on click
+							vslide.addEventListener( 'click', onOverviewSlideClicked, true );
+						}
+
+					}
+					else {
+
+						// Navigate to this slide on click
+						hslide.addEventListener( 'click', onOverviewSlideClicked, true );
+
+					}
+				}
+
+				updateSlidesVisibility();
+
+				layout();
+
+				if( !wasActive ) {
+					// Notify observers of the overview showing
+					dispatchEvent( 'overviewshown', {
+						'indexh': indexh,
+						'indexv': indexv,
+						'currentSlide': currentSlide
+					} );
+				}
+
+			}, 10 );
+
+		}
+
+	}
+
+	/**
+	 * Exits the slide overview and enters the currently
+	 * active slide.
+	 */
+	function deactivateOverview() {
+
+		// Only proceed if enabled in config
+		if( config.overview ) {
+
+			clearTimeout( activateOverviewTimeout );
+			clearTimeout( deactivateOverviewTimeout );
+
+			dom.wrapper.classList.remove( 'overview' );
+
+			// Temporarily add a class so that transitions can do different things
+			// depending on whether they are exiting/entering overview, or just
+			// moving from slide to slide
+			dom.wrapper.classList.add( 'overview-deactivating' );
+
+			deactivateOverviewTimeout = setTimeout( function () {
+				dom.wrapper.classList.remove( 'overview-deactivating' );
+			}, 1 );
+
+			// Select all slides
+			toArray( document.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) {
+				// Resets all transforms to use the external styles
+				transformElement( slide, '' );
+
+				slide.removeEventListener( 'click', onOverviewSlideClicked, true );
+			} );
+
+			slide( indexh, indexv );
+
+			cueAutoSlide();
+
+			// Notify observers of the overview hiding
+			dispatchEvent( 'overviewhidden', {
+				'indexh': indexh,
+				'indexv': indexv,
+				'currentSlide': currentSlide
+			} );
+
+		}
+	}
+
+	/**
+	 * Toggles the slide overview mode on and off.
+	 *
+	 * @param {Boolean} override Optional flag which overrides the
+	 * toggle logic and forcibly sets the desired state. True means
+	 * overview is open, false means it's closed.
+	 */
+	function toggleOverview( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? activateOverview() : deactivateOverview();
+		}
+		else {
+			isOverview() ? deactivateOverview() : activateOverview();
+		}
+
+	}
+
+	/**
+	 * Checks if the overview is currently active.
+	 *
+	 * @return {Boolean} true if the overview is active,
+	 * false otherwise
+	 */
+	function isOverview() {
+
+		return dom.wrapper.classList.contains( 'overview' );
+
+	}
+
+	/**
+	 * Checks if the current or specified slide is vertical
+	 * (nested within another slide).
+	 *
+	 * @param {HTMLElement} slide [optional] The slide to check
+	 * orientation of
+	 */
+	function isVerticalSlide( slide ) {
+
+		// Prefer slide argument, otherwise use current slide
+		slide = slide ? slide : currentSlide;
+
+		return slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i );
+
+	}
+
+	/**
+	 * Handling the fullscreen functionality via the fullscreen API
+	 *
+	 * @see http://fullscreen.spec.whatwg.org/
+	 * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode
+	 */
+	function enterFullscreen() {
+
+		var element = document.body;
+
+		// Check which implementation is available
+		var requestMethod = element.requestFullScreen ||
+							element.webkitRequestFullscreen ||
+							element.webkitRequestFullScreen ||
+							element.mozRequestFullScreen ||
+							element.msRequestFullScreen;
+
+		if( requestMethod ) {
+			requestMethod.apply( element );
+		}
+
+	}
+
+	/**
+	 * Enters the paused mode which fades everything on screen to
+	 * black.
+	 */
+	function pause() {
+
+		var wasPaused = dom.wrapper.classList.contains( 'paused' );
+
+		cancelAutoSlide();
+		dom.wrapper.classList.add( 'paused' );
+
+		if( wasPaused === false ) {
+			dispatchEvent( 'paused' );
+		}
+
+	}
+
+	/**
+	 * Exits from the paused mode.
+	 */
+	function resume() {
+
+		var wasPaused = dom.wrapper.classList.contains( 'paused' );
+		dom.wrapper.classList.remove( 'paused' );
+
+		cueAutoSlide();
+
+		if( wasPaused ) {
+			dispatchEvent( 'resumed' );
+		}
+
+	}
+
+	/**
+	 * Toggles the paused mode on and off.
+	 */
+	function togglePause() {
+
+		if( isPaused() ) {
+			resume();
+		}
+		else {
+			pause();
+		}
+
+	}
+
+	/**
+	 * Checks if we are currently in the paused mode.
+	 */
+	function isPaused() {
+
+		return dom.wrapper.classList.contains( 'paused' );
+
+	}
+
+	/**
+	 * Steps from the current point in the presentation to the
+	 * slide which matches the specified horizontal and vertical
+	 * indices.
+	 *
+	 * @param {int} h Horizontal index of the target slide
+	 * @param {int} v Vertical index of the target slide
+	 * @param {int} f Optional index of a fragment within the
+	 * target slide to activate
+	 * @param {int} o Optional origin for use in multimaster environments
+	 */
+	function slide( h, v, f, o ) {
+
+		// Remember where we were at before
+		previousSlide = currentSlide;
+
+		// Query all horizontal slides in the deck
+		var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+
+		// If no vertical index is specified and the upcoming slide is a
+		// stack, resume at its previous vertical index
+		if( v === undefined ) {
+			v = getPreviousVerticalIndex( horizontalSlides[ h ] );
+		}
+
+		// If we were on a vertical stack, remember what vertical index
+		// it was on so we can resume at the same position when returning
+		if( previousSlide && previousSlide.parentNode && previousSlide.parentNode.classList.contains( 'stack' ) ) {
+			setPreviousVerticalIndex( previousSlide.parentNode, indexv );
+		}
+
+		// Remember the state before this slide
+		var stateBefore = state.concat();
+
+		// Reset the state array
+		state.length = 0;
+
+		var indexhBefore = indexh || 0,
+			indexvBefore = indexv || 0;
+
+		// Activate and transition to the new slide
+		indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
+		indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
+
+		// Update the visibility of slides now that the indices have changed
+		updateSlidesVisibility();
+
+		layout();
+
+		// Apply the new state
+		stateLoop: for( var i = 0, len = state.length; i < len; i++ ) {
+			// Check if this state existed on the previous slide. If it
+			// did, we will avoid adding it repeatedly
+			for( var j = 0; j < stateBefore.length; j++ ) {
+				if( stateBefore[j] === state[i] ) {
+					stateBefore.splice( j, 1 );
+					continue stateLoop;
+				}
+			}
+
+			document.documentElement.classList.add( state[i] );
+
+			// Dispatch custom event matching the state's name
+			dispatchEvent( state[i] );
+		}
+
+		// Clean up the remains of the previous state
+		while( stateBefore.length ) {
+			document.documentElement.classList.remove( stateBefore.pop() );
+		}
+
+		// If the overview is active, re-activate it to update positions
+		if( isOverview() ) {
+			activateOverview();
+		}
+
+		// Find the current horizontal slide and any possible vertical slides
+		// within it
+		var currentHorizontalSlide = horizontalSlides[ indexh ],
+			currentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' );
+
+		// Store references to the previous and current slides
+		currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;
+
+		// Show fragment, if specified
+		if( typeof f !== 'undefined' ) {
+			navigateFragment( f );
+		}
+
+		// Dispatch an event if the slide changed
+		var slideChanged = ( indexh !== indexhBefore || indexv !== indexvBefore );
+		if( slideChanged ) {
+			dispatchEvent( 'slidechanged', {
+				'indexh': indexh,
+				'indexv': indexv,
+				'previousSlide': previousSlide,
+				'currentSlide': currentSlide,
+				'origin': o
+			} );
+		}
+		else {
+			// Ensure that the previous slide is never the same as the current
+			previousSlide = null;
+		}
+
+		// Solves an edge case where the previous slide maintains the
+		// 'present' class when navigating between adjacent vertical
+		// stacks
+		if( previousSlide ) {
+			previousSlide.classList.remove( 'present' );
+
+			// Reset all slides upon navigate to home
+			// Issue: #285
+			if ( document.querySelector( HOME_SLIDE_SELECTOR ).classList.contains( 'present' ) ) {
+				// Launch async task
+				setTimeout( function () {
+					var slides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.stack') ), i;
+					for( i in slides ) {
+						if( slides[i] ) {
+							// Reset stack
+							setPreviousVerticalIndex( slides[i], 0 );
+						}
+					}
+				}, 0 );
+			}
+		}
+
+		// Handle embedded content
+		if( slideChanged ) {
+			stopEmbeddedContent( previousSlide );
+			startEmbeddedContent( currentSlide );
+		}
+
+		updateControls();
+		updateProgress();
+		updateBackground();
+		updateParallax();
+		updateSlideNumber();
+
+		// Update the URL hash
+		writeURL();
+
+		cueAutoSlide();
+
+	}
+
+	/**
+	 * Syncs the presentation with the current DOM. Useful
+	 * when new slides or control elements are added or when
+	 * the configuration has changed.
+	 */
+	function sync() {
+
+		// Subscribe to input
+		removeEventListeners();
+		addEventListeners();
+
+		// Force a layout to make sure the current config is accounted for
+		layout();
+
+		// Reflect the current autoSlide value
+		autoSlide = config.autoSlide;
+
+		// Start auto-sliding if it's enabled
+		cueAutoSlide();
+
+		// Re-create the slide backgrounds
+		createBackgrounds();
+
+		sortAllFragments();
+
+		updateControls();
+		updateProgress();
+		updateBackground( true );
+		updateSlideNumber();
+
+	}
+
+	/**
+	 * Resets all vertical slides so that only the first
+	 * is visible.
+	 */
+	function resetVerticalSlides() {
+
+		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+		horizontalSlides.forEach( function( horizontalSlide ) {
+
+			var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
+			verticalSlides.forEach( function( verticalSlide, y ) {
+
+				if( y > 0 ) {
+					verticalSlide.classList.remove( 'present' );
+					verticalSlide.classList.remove( 'past' );
+					verticalSlide.classList.add( 'future' );
+				}
+
+			} );
+
+		} );
+
+	}
+
+	/**
+	 * Sorts and formats all of fragments in the
+	 * presentation.
+	 */
+	function sortAllFragments() {
+
+		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+		horizontalSlides.forEach( function( horizontalSlide ) {
+
+			var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
+			verticalSlides.forEach( function( verticalSlide, y ) {
+
+				sortFragments( verticalSlide.querySelectorAll( '.fragment' ) );
+
+			} );
+
+			if( verticalSlides.length === 0 ) sortFragments( horizontalSlide.querySelectorAll( '.fragment' ) );
+
+		} );
+
+	}
+
+	/**
+	 * Updates one dimension of slides by showing the slide
+	 * with the specified index.
+	 *
+	 * @param {String} selector A CSS selector that will fetch
+	 * the group of slides we are working with
+	 * @param {Number} index The index of the slide that should be
+	 * shown
+	 *
+	 * @return {Number} The index of the slide that is now shown,
+	 * might differ from the passed in index if it was out of
+	 * bounds.
+	 */
+	function updateSlides( selector, index ) {
+
+		// Select all slides and convert the NodeList result to
+		// an array
+		var slides = toArray( document.querySelectorAll( selector ) ),
+			slidesLength = slides.length;
+
+		if( slidesLength ) {
+
+			// Should the index loop?
+			if( config.loop ) {
+				index %= slidesLength;
+
+				if( index < 0 ) {
+					index = slidesLength + index;
+				}
+			}
+
+			// Enforce max and minimum index bounds
+			index = Math.max( Math.min( index, slidesLength - 1 ), 0 );
+
+			for( var i = 0; i < slidesLength; i++ ) {
+				var element = slides[i];
+
+				var reverse = config.rtl && !isVerticalSlide( element );
+
+				element.classList.remove( 'past' );
+				element.classList.remove( 'present' );
+				element.classList.remove( 'future' );
+
+				// http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute
+				element.setAttribute( 'hidden', '' );
+
+				if( i < index ) {
+					// Any element previous to index is given the 'past' class
+					element.classList.add( reverse ? 'future' : 'past' );
+
+					var pastFragments = toArray( element.querySelectorAll( '.fragment' ) );
+
+					// Show all fragments on prior slides
+					while( pastFragments.length ) {
+						var pastFragment = pastFragments.pop();
+						pastFragment.classList.add( 'visible' );
+						pastFragment.classList.remove( 'current-fragment' );
+					}
+				}
+				else if( i > index ) {
+					// Any element subsequent to index is given the 'future' class
+					element.classList.add( reverse ? 'past' : 'future' );
+
+					var futureFragments = toArray( element.querySelectorAll( '.fragment.visible' ) );
+
+					// No fragments in future slides should be visible ahead of time
+					while( futureFragments.length ) {
+						var futureFragment = futureFragments.pop();
+						futureFragment.classList.remove( 'visible' );
+						futureFragment.classList.remove( 'current-fragment' );
+					}
+				}
+
+				// If this element contains vertical slides
+				if( element.querySelector( 'section' ) ) {
+					element.classList.add( 'stack' );
+				}
+			}
+
+			// Mark the current slide as present
+			slides[index].classList.add( 'present' );
+			slides[index].removeAttribute( 'hidden' );
+
+			// If this slide has a state associated with it, add it
+			// onto the current state of the deck
+			var slideState = slides[index].getAttribute( 'data-state' );
+			if( slideState ) {
+				state = state.concat( slideState.split( ' ' ) );
+			}
+
+		}
+		else {
+			// Since there are no slides we can't be anywhere beyond the
+			// zeroth index
+			index = 0;
+		}
+
+		return index;
+
+	}
+
+	/**
+	 * Optimization method; hide all slides that are far away
+	 * from the present slide.
+	 */
+	function updateSlidesVisibility() {
+
+		// Select all slides and convert the NodeList result to
+		// an array
+		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ),
+			horizontalSlidesLength = horizontalSlides.length,
+			distanceX,
+			distanceY;
+
+		if( horizontalSlidesLength ) {
+
+			// The number of steps away from the present slide that will
+			// be visible
+			var viewDistance = isOverview() ? 10 : config.viewDistance;
+
+			// Limit view distance on weaker devices
+			if( isMobileDevice ) {
+				viewDistance = isOverview() ? 6 : 1;
+			}
+
+			for( var x = 0; x < horizontalSlidesLength; x++ ) {
+				var horizontalSlide = horizontalSlides[x];
+
+				var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ),
+					verticalSlidesLength = verticalSlides.length;
+
+				// Loops so that it measures 1 between the first and last slides
+				distanceX = Math.abs( ( indexh - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;
+
+				// Show the horizontal slide if it's within the view distance
+				horizontalSlide.style.display = distanceX > viewDistance ? 'none' : 'block';
+
+				if( verticalSlidesLength ) {
+
+					var oy = getPreviousVerticalIndex( horizontalSlide );
+
+					for( var y = 0; y < verticalSlidesLength; y++ ) {
+						var verticalSlide = verticalSlides[y];
+
+						distanceY = x === indexh ? Math.abs( indexv - y ) : Math.abs( y - oy );
+
+						verticalSlide.style.display = ( distanceX + distanceY ) > viewDistance ? 'none' : 'block';
+					}
+
+				}
+			}
+
+		}
+
+	}
+
+	/**
+	 * Updates the progress bar to reflect the current slide.
+	 */
+	function updateProgress() {
+
+		// Update progress if enabled
+		if( config.progress && dom.progress ) {
+
+			var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+
+			// The number of past and total slides
+			var totalCount = document.querySelectorAll( SLIDES_SELECTOR + ':not(.stack)' ).length;
+			var pastCount = 0;
+
+			// Step through all slides and count the past ones
+			mainLoop: for( var i = 0; i < horizontalSlides.length; i++ ) {
+
+				var horizontalSlide = horizontalSlides[i];
+				var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
+
+				for( var j = 0; j < verticalSlides.length; j++ ) {
+
+					// Stop as soon as we arrive at the present
+					if( verticalSlides[j].classList.contains( 'present' ) ) {
+						break mainLoop;
+					}
+
+					pastCount++;
+
+				}
+
+				// Stop as soon as we arrive at the present
+				if( horizontalSlide.classList.contains( 'present' ) ) {
+					break;
+				}
+
+				// Don't count the wrapping section for vertical slides
+				if( horizontalSlide.classList.contains( 'stack' ) === false ) {
+					pastCount++;
+				}
+
+			}
+
+			dom.progressbar.style.width = ( pastCount / ( totalCount - 1 ) ) * window.innerWidth + 'px';
+
+		}
+
+	}
+
+	/**
+	 * Updates the slide number div to reflect the current slide.
+	 */
+	function updateSlideNumber() {
+
+		// Update slide number if enabled
+		if( config.slideNumber && dom.slideNumber) {
+
+			// Display the number of the page using 'indexh - indexv' format
+			var indexString = indexh;
+			if( indexv > 0 ) {
+				indexString += ' - ' + indexv;
+			}
+
+			dom.slideNumber.innerHTML = indexString;
+		}
+
+	}
+
+	/**
+	 * Updates the state of all control/navigation arrows.
+	 */
+	function updateControls() {
+
+		var routes = availableRoutes();
+		var fragments = availableFragments();
+
+		// Remove the 'enabled' class from all directions
+		dom.controlsLeft.concat( dom.controlsRight )
+						.concat( dom.controlsUp )
+						.concat( dom.controlsDown )
+						.concat( dom.controlsPrev )
+						.concat( dom.controlsNext ).forEach( function( node ) {
+			node.classList.remove( 'enabled' );
+			node.classList.remove( 'fragmented' );
+		} );
+
+		// Add the 'enabled' class to the available routes
+		if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' );	} );
+		if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); } );
+		if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' );	} );
+		if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); } );
+
+		// Prev/next buttons
+		if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); } );
+		if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); } );
+
+		// Highlight fragment directions
+		if( currentSlide ) {
+
+			// Always apply fragment decorator to prev/next buttons
+			if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+			if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+
+			// Apply fragment decorators to directional buttons based on
+			// what slide axis they are in
+			if( isVerticalSlide( currentSlide ) ) {
+				if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+				if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+			}
+			else {
+				if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+				if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+			}
+
+		}
+
+	}
+
+	/**
+	 * Updates the background elements to reflect the current
+	 * slide.
+	 *
+	 * @param {Boolean} includeAll If true, the backgrounds of
+	 * all vertical slides (not just the present) will be updated.
+	 */
+	function updateBackground( includeAll ) {
+
+		var currentBackground = null;
+
+		// Reverse past/future classes when in RTL mode
+		var horizontalPast = config.rtl ? 'future' : 'past',
+			horizontalFuture = config.rtl ? 'past' : 'future';
+
+		// Update the classes of all backgrounds to match the
+		// states of their slides (past/present/future)
+		toArray( dom.background.childNodes ).forEach( function( backgroundh, h ) {
+
+			if( h < indexh ) {
+				backgroundh.className = 'slide-background ' + horizontalPast;
+			}
+			else if ( h > indexh ) {
+				backgroundh.className = 'slide-background ' + horizontalFuture;
+			}
+			else {
+				backgroundh.className = 'slide-background present';
+
+				// Store a reference to the current background element
+				currentBackground = backgroundh;
+			}
+
+			if( includeAll || h === indexh ) {
+				toArray( backgroundh.childNodes ).forEach( function( backgroundv, v ) {
+
+					if( v < indexv ) {
+						backgroundv.className = 'slide-background past';
+					}
+					else if ( v > indexv ) {
+						backgroundv.className = 'slide-background future';
+					}
+					else {
+						backgroundv.className = 'slide-background present';
+
+						// Only if this is the present horizontal and vertical slide
+						if( h === indexh ) currentBackground = backgroundv;
+					}
+
+				} );
+			}
+
+		} );
+
+		// Don't transition between identical backgrounds. This
+		// prevents unwanted flicker.
+		if( currentBackground ) {
+			var previousBackgroundHash = previousBackground ? previousBackground.getAttribute( 'data-background-hash' ) : null;
+			var currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
+			if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== previousBackground ) {
+				dom.background.classList.add( 'no-transition' );
+			}
+
+			previousBackground = currentBackground;
+		}
+
+		// Allow the first background to apply without transition
+		setTimeout( function() {
+			dom.background.classList.remove( 'no-transition' );
+		}, 1 );
+
+	}
+
+	/**
+	 * Updates the position of the parallax background based
+	 * on the current slide index.
+	 */
+	function updateParallax() {
+
+		if( config.parallaxBackgroundImage ) {
+
+			var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
+				verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
+
+			var backgroundSize = dom.background.style.backgroundSize.split( ' ' ),
+				backgroundWidth, backgroundHeight;
+
+			if( backgroundSize.length === 1 ) {
+				backgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );
+			}
+			else {
+				backgroundWidth = parseInt( backgroundSize[0], 10 );
+				backgroundHeight = parseInt( backgroundSize[1], 10 );
+			}
+
+			var slideWidth = dom.background.offsetWidth;
+			var horizontalSlideCount = horizontalSlides.length;
+			var horizontalOffset = -( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) * indexh;
+
+			var slideHeight = dom.background.offsetHeight;
+			var verticalSlideCount = verticalSlides.length;
+			var verticalOffset = verticalSlideCount > 0 ? -( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 ) * indexv : 0;
+
+			dom.background.style.backgroundPosition = horizontalOffset + 'px ' + verticalOffset + 'px';
+
+		}
+
+	}
+
+	/**
+	 * Determine what available routes there are for navigation.
+	 *
+	 * @return {Object} containing four booleans: left/right/up/down
+	 */
+	function availableRoutes() {
+
+		var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
+			verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
+
+		var routes = {
+			left: indexh > 0 || config.loop,
+			right: indexh < horizontalSlides.length - 1 || config.loop,
+			up: indexv > 0,
+			down: indexv < verticalSlides.length - 1
+		};
+
+		// reverse horizontal controls for rtl
+		if( config.rtl ) {
+			var left = routes.left;
+			routes.left = routes.right;
+			routes.right = left;
+		}
+
+		return routes;
+
+	}
+
+	/**
+	 * Returns an object describing the available fragment
+	 * directions.
+	 *
+	 * @return {Object} two boolean properties: prev/next
+	 */
+	function availableFragments() {
+
+		if( currentSlide && config.fragments ) {
+			var fragments = currentSlide.querySelectorAll( '.fragment' );
+			var hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.visible)' );
+
+			return {
+				prev: fragments.length - hiddenFragments.length > 0,
+				next: !!hiddenFragments.length
+			};
+		}
+		else {
+			return { prev: false, next: false };
+		}
+
+	}
+
+	/**
+	 * Start playback of any embedded content inside of
+	 * the targeted slide.
+	 */
+	function startEmbeddedContent( slide ) {
+
+		if( slide && !isSpeakerNotes() ) {
+			// HTML5 media elements
+			toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
+				if( el.hasAttribute( 'data-autoplay' ) ) {
+					el.play();
+				}
+			} );
+
+			// iframe embeds
+			toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
+				el.contentWindow.postMessage( 'slide:start', '*' );
+			});
+
+			// YouTube embeds
+			toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
+				if( el.hasAttribute( 'data-autoplay' ) ) {
+					el.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
+				}
+			});
+		}
+
+	}
+
+	/**
+	 * Stop playback of any embedded content inside of
+	 * the targeted slide.
+	 */
+	function stopEmbeddedContent( slide ) {
+
+		if( slide ) {
+			// HTML5 media elements
+			toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
+				if( !el.hasAttribute( 'data-ignore' ) ) {
+					el.pause();
+				}
+			} );
+
+			// iframe embeds
+			toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
+				el.contentWindow.postMessage( 'slide:stop', '*' );
+			});
+
+			// YouTube embeds
+			toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
+				if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
+					el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
+				}
+			});
+		}
+
+	}
+
+	/**
+	 * Checks if this presentation is running inside of the
+	 * speaker notes window.
+	 */
+	function isSpeakerNotes() {
+
+		return !!window.location.search.match( /receiver/gi );
+
+	}
+
+	/**
+	 * Reads the current URL (hash) and navigates accordingly.
+	 */
+	function readURL() {
+
+		var hash = window.location.hash;
+
+		// Attempt to parse the hash as either an index or name
+		var bits = hash.slice( 2 ).split( '/' ),
+			name = hash.replace( /#|\//gi, '' );
+
+		// If the first bit is invalid and there is a name we can
+		// assume that this is a named link
+		if( isNaN( parseInt( bits[0], 10 ) ) && name.length ) {
+			// Find the slide with the specified name
+			var element = document.querySelector( '#' + name );
+
+			if( element ) {
+				// Find the position of the named slide and navigate to it
+				var indices = Reveal.getIndices( element );
+				slide( indices.h, indices.v );
+			}
+			// If the slide doesn't exist, navigate to the current slide
+			else {
+				slide( indexh || 0, indexv || 0 );
+			}
+		}
+		else {
+			// Read the index components of the hash
+			var h = parseInt( bits[0], 10 ) || 0,
+				v = parseInt( bits[1], 10 ) || 0;
+
+			if( h !== indexh || v !== indexv ) {
+				slide( h, v );
+			}
+		}
+
+	}
+
+	/**
+	 * Updates the page URL (hash) to reflect the current
+	 * state.
+	 *
+	 * @param {Number} delay The time in ms to wait before
+	 * writing the hash
+	 */
+	function writeURL( delay ) {
+
+		if( config.history ) {
+
+			// Make sure there's never more than one timeout running
+			clearTimeout( writeURLTimeout );
+
+			// If a delay is specified, timeout this call
+			if( typeof delay === 'number' ) {
+				writeURLTimeout = setTimeout( writeURL, delay );
+			}
+			else {
+				var url = '/';
+
+				// If the current slide has an ID, use that as a named link
+				if( currentSlide && typeof currentSlide.getAttribute( 'id' ) === 'string' ) {
+					url = '/' + currentSlide.getAttribute( 'id' );
+				}
+				// Otherwise use the /h/v index
+				else {
+					if( indexh > 0 || indexv > 0 ) url += indexh;
+					if( indexv > 0 ) url += '/' + indexv;
+				}
+
+				window.location.hash = url;
+			}
+		}
+
+	}
+
+	/**
+	 * Retrieves the h/v location of the current, or specified,
+	 * slide.
+	 *
+	 * @param {HTMLElement} slide If specified, the returned
+	 * index will be for this slide rather than the currently
+	 * active one
+	 *
+	 * @return {Object} { h: <int>, v: <int>, f: <int> }
+	 */
+	function getIndices( slide ) {
+
+		// By default, return the current indices
+		var h = indexh,
+			v = indexv,
+			f;
+
+		// If a slide is specified, return the indices of that slide
+		if( slide ) {
+			var isVertical = isVerticalSlide( slide );
+			var slideh = isVertical ? slide.parentNode : slide;
+
+			// Select all horizontal slides
+			var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+
+			// Now that we know which the horizontal slide is, get its index
+			h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
+
+			// If this is a vertical slide, grab the vertical index
+			if( isVertical ) {
+				v = Math.max( toArray( slide.parentNode.querySelectorAll( 'section' ) ).indexOf( slide ), 0 );
+			}
+		}
+
+		if( !slide && currentSlide ) {
+			var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;
+			if( hasFragments ) {
+				var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );
+				f = visibleFragments.length - 1;
+			}
+		}
+
+		return { h: h, v: v, f: f };
+
+	}
+
+	/**
+	 * Return a sorted fragments list, ordered by an increasing
+	 * "data-fragment-index" attribute.
+	 *
+	 * Fragments will be revealed in the order that they are returned by
+	 * this function, so you can use the index attributes to control the
+	 * order of fragment appearance.
+	 *
+	 * To maintain a sensible default fragment order, fragments are presumed
+	 * to be passed in document order. This function adds a "fragment-index"
+	 * attribute to each node if such an attribute is not already present,
+	 * and sets that attribute to an integer value which is the position of
+	 * the fragment within the fragments list.
+	 */
+	function sortFragments( fragments ) {
+
+		fragments = toArray( fragments );
+
+		var ordered = [],
+			unordered = [],
+			sorted = [];
+
+		// Group ordered and unordered elements
+		fragments.forEach( function( fragment, i ) {
+			if( fragment.hasAttribute( 'data-fragment-index' ) ) {
+				var index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );
+
+				if( !ordered[index] ) {
+					ordered[index] = [];
+				}
+
+				ordered[index].push( fragment );
+			}
+			else {
+				unordered.push( [ fragment ] );
+			}
+		} );
+
+		// Append fragments without explicit indices in their
+		// DOM order
+		ordered = ordered.concat( unordered );
+
+		// Manually count the index up per group to ensure there
+		// are no gaps
+		var index = 0;
+
+		// Push all fragments in their sorted order to an array,
+		// this flattens the groups
+		ordered.forEach( function( group ) {
+			group.forEach( function( fragment ) {
+				sorted.push( fragment );
+				fragment.setAttribute( 'data-fragment-index', index );
+			} );
+
+			index ++;
+		} );
+
+		return sorted;
+
+	}
+
+	/**
+	 * Navigate to the specified slide fragment.
+	 *
+	 * @param {Number} index The index of the fragment that
+	 * should be shown, -1 means all are invisible
+	 * @param {Number} offset Integer offset to apply to the
+	 * fragment index
+	 *
+	 * @return {Boolean} true if a change was made in any
+	 * fragments visibility as part of this call
+	 */
+	function navigateFragment( index, offset ) {
+
+		if( currentSlide && config.fragments ) {
+
+			var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) );
+			if( fragments.length ) {
+
+				// If no index is specified, find the current
+				if( typeof index !== 'number' ) {
+					var lastVisibleFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
+
+					if( lastVisibleFragment ) {
+						index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
+					}
+					else {
+						index = -1;
+					}
+				}
+
+				// If an offset is specified, apply it to the index
+				if( typeof offset === 'number' ) {
+					index += offset;
+				}
+
+				var fragmentsShown = [],
+					fragmentsHidden = [];
+
+				toArray( fragments ).forEach( function( element, i ) {
+
+					if( element.hasAttribute( 'data-fragment-index' ) ) {
+						i = parseInt( element.getAttribute( 'data-fragment-index' ), 10 );
+					}
+
+					// Visible fragments
+					if( i <= index ) {
+						if( !element.classList.contains( 'visible' ) ) fragmentsShown.push( element );
+						element.classList.add( 'visible' );
+						element.classList.remove( 'current-fragment' );
+
+						if( i === index ) {
+							element.classList.add( 'current-fragment' );
+						}
+					}
+					// Hidden fragments
+					else {
+						if( element.classList.contains( 'visible' ) ) fragmentsHidden.push( element );
+						element.classList.remove( 'visible' );
+						element.classList.remove( 'current-fragment' );
+					}
+
+
+				} );
+
+				if( fragmentsHidden.length ) {
+					dispatchEvent( 'fragmenthidden', { fragment: fragmentsHidden[0], fragments: fragmentsHidden } );
+				}
+
+				if( fragmentsShown.length ) {
+					dispatchEvent( 'fragmentshown', { fragment: fragmentsShown[0], fragments: fragmentsShown } );
+				}
+
+				updateControls();
+
+				return !!( fragmentsShown.length || fragmentsHidden.length );
+
+			}
+
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Navigate to the next slide fragment.
+	 *
+	 * @return {Boolean} true if there was a next fragment,
+	 * false otherwise
+	 */
+	function nextFragment() {
+
+		return navigateFragment( null, 1 );
+
+	}
+
+	/**
+	 * Navigate to the previous slide fragment.
+	 *
+	 * @return {Boolean} true if there was a previous fragment,
+	 * false otherwise
+	 */
+	function previousFragment() {
+
+		return navigateFragment( null, -1 );
+
+	}
+
+	/**
+	 * Cues a new automated slide if enabled in the config.
+	 */
+	function cueAutoSlide() {
+
+		cancelAutoSlide();
+
+		if( currentSlide ) {
+
+			var parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;
+			var slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );
+
+			// Pick value in the following priority order:
+			// 1. Current slide's data-autoslide
+			// 2. Parent slide's data-autoslide
+			// 3. Global autoSlide setting
+			if( slideAutoSlide ) {
+				autoSlide = parseInt( slideAutoSlide, 10 );
+			}
+			else if( parentAutoSlide ) {
+				autoSlide = parseInt( parentAutoSlide, 10 );
+			}
+			else {
+				autoSlide = config.autoSlide;
+			}
+
+			// If there are media elements with data-autoplay,
+			// automatically set the autoSlide duration to the
+			// length of that media
+			toArray( currentSlide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
+				if( el.hasAttribute( 'data-autoplay' ) ) {
+					if( autoSlide && el.duration * 1000 > autoSlide ) {
+						autoSlide = ( el.duration * 1000 ) + 1000;
+					}
+				}
+			} );
+
+			// Cue the next auto-slide if:
+			// - There is an autoSlide value
+			// - Auto-sliding isn't paused by the user
+			// - The presentation isn't paused
+			// - The overview isn't active
+			// - The presentation isn't over
+			if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || config.loop === true ) ) {
+				autoSlideTimeout = setTimeout( navigateNext, autoSlide );
+				autoSlideStartTime = Date.now();
+			}
+
+			if( autoSlidePlayer ) {
+				autoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );
+			}
+
+		}
+
+	}
+
+	/**
+	 * Cancels any ongoing request to auto-slide.
+	 */
+	function cancelAutoSlide() {
+
+		clearTimeout( autoSlideTimeout );
+		autoSlideTimeout = -1;
+
+	}
+
+	function pauseAutoSlide() {
+
+		autoSlidePaused = true;
+		clearTimeout( autoSlideTimeout );
+
+		if( autoSlidePlayer ) {
+			autoSlidePlayer.setPlaying( false );
+		}
+
+	}
+
+	function resumeAutoSlide() {
+
+		autoSlidePaused = false;
+		cueAutoSlide();
+
+	}
+
+	function navigateLeft() {
+
+		// Reverse for RTL
+		if( config.rtl ) {
+			if( ( isOverview() || nextFragment() === false ) && availableRoutes().left ) {
+				slide( indexh + 1 );
+			}
+		}
+		// Normal navigation
+		else if( ( isOverview() || previousFragment() === false ) && availableRoutes().left ) {
+			slide( indexh - 1 );
+		}
+
+	}
+
+	function navigateRight() {
+
+		// Reverse for RTL
+		if( config.rtl ) {
+			if( ( isOverview() || previousFragment() === false ) && availableRoutes().right ) {
+				slide( indexh - 1 );
+			}
+		}
+		// Normal navigation
+		else if( ( isOverview() || nextFragment() === false ) && availableRoutes().right ) {
+			slide( indexh + 1 );
+		}
+
+	}
+
+	function navigateUp() {
+
+		// Prioritize hiding fragments
+		if( ( isOverview() || previousFragment() === false ) && availableRoutes().up ) {
+			slide( indexh, indexv - 1 );
+		}
+
+	}
+
+	function navigateDown() {
+
+		// Prioritize revealing fragments
+		if( ( isOverview() || nextFragment() === false ) && availableRoutes().down ) {
+			slide( indexh, indexv + 1 );
+		}
+
+	}
+
+	/**
+	 * Navigates backwards, prioritized in the following order:
+	 * 1) Previous fragment
+	 * 2) Previous vertical slide
+	 * 3) Previous horizontal slide
+	 */
+	function navigatePrev() {
+
+		// Prioritize revealing fragments
+		if( previousFragment() === false ) {
+			if( availableRoutes().up ) {
+				navigateUp();
+			}
+			else {
+				// Fetch the previous horizontal slide, if there is one
+				var previousSlide = document.querySelector( HORIZONTAL_SLIDES_SELECTOR + '.past:nth-child(' + indexh + ')' );
+
+				if( previousSlide ) {
+					var v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined;
+					var h = indexh - 1;
+					slide( h, v );
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * Same as #navigatePrev() but navigates forwards.
+	 */
+	function navigateNext() {
+
+		// Prioritize revealing fragments
+		if( nextFragment() === false ) {
+			availableRoutes().down ? navigateDown() : navigateRight();
+		}
+
+		// If auto-sliding is enabled we need to cue up
+		// another timeout
+		cueAutoSlide();
+
+	}
+
+
+	// --------------------------------------------------------------------//
+	// ----------------------------- EVENTS -------------------------------//
+	// --------------------------------------------------------------------//
+
+	/**
+	 * Called by all event handlers that are based on user
+	 * input.
+	 */
+	function onUserInput( event ) {
+
+		if( config.autoSlideStoppable ) {
+			pauseAutoSlide();
+		}
+
+	}
+
+	/**
+	 * Handler for the document level 'keydown' event.
+	 */
+	function onDocumentKeyDown( event ) {
+
+		onUserInput( event );
+
+		// Check if there's a focused element that could be using
+		// the keyboard
+		var activeElement = document.activeElement;
+		var hasFocus = !!( document.activeElement && ( document.activeElement.type || document.activeElement.href || document.activeElement.contentEditable !== 'inherit' ) );
+
+		// Disregard the event if there's a focused element or a
+		// keyboard modifier key is present
+		if( hasFocus || (event.shiftKey && event.keyCode !== 32) || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		// While paused only allow "unpausing" keyboard events (b and .)
+		if( isPaused() && [66,190,191].indexOf( event.keyCode ) === -1 ) {
+			return false;
+		}
+
+		var triggered = false;
+
+		// 1. User defined key bindings
+		if( typeof config.keyboard === 'object' ) {
+
+			for( var key in config.keyboard ) {
+
+				// Check if this binding matches the pressed key
+				if( parseInt( key, 10 ) === event.keyCode ) {
+
+					var value = config.keyboard[ key ];
+
+					// Callback function
+					if( typeof value === 'function' ) {
+						value.apply( null, [ event ] );
+					}
+					// String shortcuts to reveal.js API
+					else if( typeof value === 'string' && typeof Reveal[ value ] === 'function' ) {
+						Reveal[ value ].call();
+					}
+
+					triggered = true;
+
+				}
+
+			}
+
+		}
+
+		// 2. System defined key bindings
+		if( triggered === false ) {
+
+			// Assume true and try to prove false
+			triggered = true;
+
+			switch( event.keyCode ) {
+				// p, page up
+				case 80: case 33: navigatePrev(); break;
+				// n, page down
+				case 78: case 34: navigateNext(); break;
+				// h, left
+				case 72: case 37: navigateLeft(); break;
+				// l, right
+				case 76: case 39: navigateRight(); break;
+				// k, up
+				case 75: case 38: navigateUp(); break;
+				// j, down
+				case 74: case 40: navigateDown(); break;
+				// home
+				case 36: slide( 0 ); break;
+				// end
+				case 35: slide( Number.MAX_VALUE ); break;
+				// space
+				case 32: isOverview() ? deactivateOverview() : event.shiftKey ? navigatePrev() : navigateNext(); break;
+				// return
+				case 13: isOverview() ? deactivateOverview() : triggered = false; break;
+				// b, period, Logitech presenter tools "black screen" button
+				case 66: case 190: case 191: togglePause(); break;
+				// f
+				case 70: enterFullscreen(); break;
+				default:
+					triggered = false;
+			}
+
+		}
+
+		// If the input resulted in a triggered action we should prevent
+		// the browsers default behavior
+		if( triggered ) {
+			event.preventDefault();
+		}
+		// ESC or O key
+		else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && features.transforms3d ) {
+			if( dom.preview ) {
+				closePreview();
+			}
+			else {
+				toggleOverview();
+			}
+
+			event.preventDefault();
+		}
+
+		// If auto-sliding is enabled we need to cue up
+		// another timeout
+		cueAutoSlide();
+
+	}
+
+	/**
+	 * Handler for the 'touchstart' event, enables support for
+	 * swipe and pinch gestures.
+	 */
+	function onTouchStart( event ) {
+
+		touch.startX = event.touches[0].clientX;
+		touch.startY = event.touches[0].clientY;
+		touch.startCount = event.touches.length;
+
+		// If there's two touches we need to memorize the distance
+		// between those two points to detect pinching
+		if( event.touches.length === 2 && config.overview ) {
+			touch.startSpan = distanceBetween( {
+				x: event.touches[1].clientX,
+				y: event.touches[1].clientY
+			}, {
+				x: touch.startX,
+				y: touch.startY
+			} );
+		}
+
+	}
+
+	/**
+	 * Handler for the 'touchmove' event.
+	 */
+	function onTouchMove( event ) {
+
+		// Each touch should only trigger one action
+		if( !touch.captured ) {
+			onUserInput( event );
+
+			var currentX = event.touches[0].clientX;
+			var currentY = event.touches[0].clientY;
+
+			// If the touch started with two points and still has
+			// two active touches; test for the pinch gesture
+			if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) {
+
+				// The current distance in pixels between the two touch points
+				var currentSpan = distanceBetween( {
+					x: event.touches[1].clientX,
+					y: event.touches[1].clientY
+				}, {
+					x: touch.startX,
+					y: touch.startY
+				} );
+
+				// If the span is larger than the desire amount we've got
+				// ourselves a pinch
+				if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
+					touch.captured = true;
+
+					if( currentSpan < touch.startSpan ) {
+						activateOverview();
+					}
+					else {
+						deactivateOverview();
+					}
+				}
+
+				event.preventDefault();
+
+			}
+			// There was only one touch point, look for a swipe
+			else if( event.touches.length === 1 && touch.startCount !== 2 ) {
+
+				var deltaX = currentX - touch.startX,
+					deltaY = currentY - touch.startY;
+
+				if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					touch.captured = true;
+					navigateLeft();
+				}
+				else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					touch.captured = true;
+					navigateRight();
+				}
+				else if( deltaY > touch.threshold ) {
+					touch.captured = true;
+					navigateUp();
+				}
+				else if( deltaY < -touch.threshold ) {
+					touch.captured = true;
+					navigateDown();
+				}
+
+				// If we're embedded, only block touch events if they have
+				// triggered an action
+				if( config.embedded ) {
+					if( touch.captured || isVerticalSlide( currentSlide ) ) {
+						event.preventDefault();
+					}
+				}
+				// Not embedded? Block them all to avoid needless tossing
+				// around of the viewport in iOS
+				else {
+					event.preventDefault();
+				}
+
+			}
+		}
+		// There's a bug with swiping on some Android devices unless
+		// the default action is always prevented
+		else if( navigator.userAgent.match( /android/gi ) ) {
+			event.preventDefault();
+		}
+
+	}
+
+	/**
+	 * Handler for the 'touchend' event.
+	 */
+	function onTouchEnd( event ) {
+
+		touch.captured = false;
+
+	}
+
+	/**
+	 * Convert pointer down to touch start.
+	 */
+	function onPointerDown( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			onTouchStart( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer move to touch move.
+	 */
+	function onPointerMove( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			onTouchMove( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer up to touch end.
+	 */
+	function onPointerUp( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			onTouchEnd( event );
+		}
+
+	}
+
+	/**
+	 * Handles mouse wheel scrolling, throttled to avoid skipping
+	 * multiple slides.
+	 */
+	function onDocumentMouseScroll( event ) {
+
+		if( Date.now() - lastMouseWheelStep > 600 ) {
+
+			lastMouseWheelStep = Date.now();
+
+			var delta = event.detail || -event.wheelDelta;
+			if( delta > 0 ) {
+				navigateNext();
+			}
+			else {
+				navigatePrev();
+			}
+
+		}
+
+	}
+
+	/**
+	 * Clicking on the progress bar results in a navigation to the
+	 * closest approximate horizontal slide using this equation:
+	 *
+	 * ( clickX / presentationWidth ) * numberOfSlides
+	 */
+	function onProgressClicked( event ) {
+
+		onUserInput( event );
+
+		event.preventDefault();
+
+		var slidesTotal = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).length;
+		var slideIndex = Math.floor( ( event.clientX / dom.wrapper.offsetWidth ) * slidesTotal );
+
+		slide( slideIndex );
+
+	}
+
+	/**
+	 * Event handler for navigation control buttons.
+	 */
+	function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); navigateLeft(); }
+	function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); navigateRight(); }
+	function onNavigateUpClicked( event ) { event.preventDefault(); onUserInput(); navigateUp(); }
+	function onNavigateDownClicked( event ) { event.preventDefault(); onUserInput(); navigateDown(); }
+	function onNavigatePrevClicked( event ) { event.preventDefault(); onUserInput(); navigatePrev(); }
+	function onNavigateNextClicked( event ) { event.preventDefault(); onUserInput(); navigateNext(); }
+
+	/**
+	 * Handler for the window level 'hashchange' event.
+	 */
+	function onWindowHashChange( event ) {
+
+		readURL();
+
+	}
+
+	/**
+	 * Handler for the window level 'resize' event.
+	 */
+	function onWindowResize( event ) {
+
+		layout();
+
+	}
+
+	/**
+	 * Handle for the window level 'visibilitychange' event.
+	 */
+	function onPageVisibilityChange( event ) {
+
+		var isHidden =  document.webkitHidden ||
+						document.msHidden ||
+						document.hidden;
+
+		// If, after clicking a link or similar and we're coming back,
+		// focus the document.body to ensure we can use keyboard shortcuts
+		if( isHidden === false && document.activeElement !== document.body ) {
+			document.activeElement.blur();
+			document.body.focus();
+		}
+
+	}
+
+	/**
+	 * Invoked when a slide is and we're in the overview.
+	 */
+	function onOverviewSlideClicked( event ) {
+
+		// TODO There's a bug here where the event listeners are not
+		// removed after deactivating the overview.
+		if( eventsAreBound && isOverview() ) {
+			event.preventDefault();
+
+			var element = event.target;
+
+			while( element && !element.nodeName.match( /section/gi ) ) {
+				element = element.parentNode;
+			}
+
+			if( element && !element.classList.contains( 'disabled' ) ) {
+
+				deactivateOverview();
+
+				if( element.nodeName.match( /section/gi ) ) {
+					var h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),
+						v = parseInt( element.getAttribute( 'data-index-v' ), 10 );
+
+					slide( h, v );
+				}
+
+			}
+		}
+
+	}
+
+	/**
+	 * Handles clicks on links that are set to preview in the
+	 * iframe overlay.
+	 */
+	function onPreviewLinkClicked( event ) {
+
+		var url = event.target.getAttribute( 'href' );
+		if( url ) {
+			openPreview( url );
+			event.preventDefault();
+		}
+
+	}
+
+	/**
+	 * Handles click on the auto-sliding controls element.
+	 */
+	function onAutoSlidePlayerClick( event ) {
+
+		// Replay
+		if( Reveal.isLastSlide() && config.loop === false ) {
+			slide( 0, 0 );
+			resumeAutoSlide();
+		}
+		// Resume
+		else if( autoSlidePaused ) {
+			resumeAutoSlide();
+		}
+		// Pause
+		else {
+			pauseAutoSlide();
+		}
+
+	}
+
+
+	// --------------------------------------------------------------------//
+	// ------------------------ PLAYBACK COMPONENT ------------------------//
+	// --------------------------------------------------------------------//
+
+
+	/**
+	 * Constructor for the playback component, which displays
+	 * play/pause/progress controls.
+	 *
+	 * @param {HTMLElement} container The component will append
+	 * itself to this
+	 * @param {Function} progressCheck A method which will be
+	 * called frequently to get the current progress on a range
+	 * of 0-1
+	 */
+	function Playback( container, progressCheck ) {
+
+		// Cosmetics
+		this.diameter = 50;
+		this.thickness = 3;
+
+		// Flags if we are currently playing
+		this.playing = false;
+
+		// Current progress on a 0-1 range
+		this.progress = 0;
+
+		// Used to loop the animation smoothly
+		this.progressOffset = 1;
+
+		this.container = container;
+		this.progressCheck = progressCheck;
+
+		this.canvas = document.createElement( 'canvas' );
+		this.canvas.className = 'playback';
+		this.canvas.width = this.diameter;
+		this.canvas.height = this.diameter;
+		this.context = this.canvas.getContext( '2d' );
+
+		this.container.appendChild( this.canvas );
+
+		this.render();
+
+	}
+
+	Playback.prototype.setPlaying = function( value ) {
+
+		var wasPlaying = this.playing;
+
+		this.playing = value;
+
+		// Start repainting if we weren't already
+		if( !wasPlaying && this.playing ) {
+			this.animate();
+		}
+		else {
+			this.render();
+		}
+
+	};
+
+	Playback.prototype.animate = function() {
+
+		var progressBefore = this.progress;
+
+		this.progress = this.progressCheck();
+
+		// When we loop, offset the progress so that it eases
+		// smoothly rather than immediately resetting
+		if( progressBefore > 0.8 && this.progress < 0.2 ) {
+			this.progressOffset = this.progress;
+		}
+
+		this.render();
+
+		if( this.playing ) {
+			features.requestAnimationFrameMethod.call( window, this.animate.bind( this ) );
+		}
+
+	};
+
+	/**
+	 * Renders the current progress and playback state.
+	 */
+	Playback.prototype.render = function() {
+
+		var progress = this.playing ? this.progress : 0,
+			radius = ( this.diameter / 2 ) - this.thickness,
+			x = this.diameter / 2,
+			y = this.diameter / 2,
+			iconSize = 14;
+
+		// Ease towards 1
+		this.progressOffset += ( 1 - this.progressOffset ) * 0.1;
+
+		var endAngle = ( - Math.PI / 2 ) + ( progress * ( Math.PI * 2 ) );
+		var startAngle = ( - Math.PI / 2 ) + ( this.progressOffset * ( Math.PI * 2 ) );
+
+		this.context.save();
+		this.context.clearRect( 0, 0, this.diameter, this.diameter );
+
+		// Solid background color
+		this.context.beginPath();
+		this.context.arc( x, y, radius + 2, 0, Math.PI * 2, false );
+		this.context.fillStyle = 'rgba( 0, 0, 0, 0.4 )';
+		this.context.fill();
+
+		// Draw progress track
+		this.context.beginPath();
+		this.context.arc( x, y, radius, 0, Math.PI * 2, false );
+		this.context.lineWidth = this.thickness;
+		this.context.strokeStyle = '#666';
+		this.context.stroke();
+
+		if( this.playing ) {
+			// Draw progress on top of track
+			this.context.beginPath();
+			this.context.arc( x, y, radius, startAngle, endAngle, false );
+			this.context.lineWidth = this.thickness;
+			this.context.strokeStyle = '#fff';
+			this.context.stroke();
+		}
+
+		this.context.translate( x - ( iconSize / 2 ), y - ( iconSize / 2 ) );
+
+		// Draw play/pause icons
+		if( this.playing ) {
+			this.context.fillStyle = '#fff';
+			this.context.fillRect( 0, 0, iconSize / 2 - 2, iconSize );
+			this.context.fillRect( iconSize / 2 + 2, 0, iconSize / 2 - 2, iconSize );
+		}
+		else {
+			this.context.beginPath();
+			this.context.translate( 2, 0 );
+			this.context.moveTo( 0, 0 );
+			this.context.lineTo( iconSize - 2, iconSize / 2 );
+			this.context.lineTo( 0, iconSize );
+			this.context.fillStyle = '#fff';
+			this.context.fill();
+		}
+
+		this.context.restore();
+
+	};
+
+	Playback.prototype.on = function( type, listener ) {
+		this.canvas.addEventListener( type, listener, false );
+	};
+
+	Playback.prototype.off = function( type, listener ) {
+		this.canvas.removeEventListener( type, listener, false );
+	};
+
+	Playback.prototype.destroy = function() {
+
+		this.playing = false;
+
+		if( this.canvas.parentNode ) {
+			this.container.removeChild( this.canvas );
+		}
+
+	};
+
+
+	// --------------------------------------------------------------------//
+	// ------------------------------- API --------------------------------//
+	// --------------------------------------------------------------------//
+
+
+	return {
+		initialize: initialize,
+		configure: configure,
+		sync: sync,
+
+		// Navigation methods
+		slide: slide,
+		left: navigateLeft,
+		right: navigateRight,
+		up: navigateUp,
+		down: navigateDown,
+		prev: navigatePrev,
+		next: navigateNext,
+
+		// Fragment methods
+		navigateFragment: navigateFragment,
+		prevFragment: previousFragment,
+		nextFragment: nextFragment,
+
+		// Deprecated aliases
+		navigateTo: slide,
+		navigateLeft: navigateLeft,
+		navigateRight: navigateRight,
+		navigateUp: navigateUp,
+		navigateDown: navigateDown,
+		navigatePrev: navigatePrev,
+		navigateNext: navigateNext,
+
+		// Forces an update in slide layout
+		layout: layout,
+
+		// Returns an object with the available routes as booleans (left/right/top/bottom)
+		availableRoutes: availableRoutes,
+
+		// Returns an object with the available fragments as booleans (prev/next)
+		availableFragments: availableFragments,
+
+		// Toggles the overview mode on/off
+		toggleOverview: toggleOverview,
+
+		// Toggles the "black screen" mode on/off
+		togglePause: togglePause,
+
+		// State checks
+		isOverview: isOverview,
+		isPaused: isPaused,
+
+		// Adds or removes all internal event listeners (such as keyboard)
+		addEventListeners: addEventListeners,
+		removeEventListeners: removeEventListeners,
+
+		// Returns the indices of the current, or specified, slide
+		getIndices: getIndices,
+
+		// Returns the slide at the specified index, y is optional
+		getSlide: function( x, y ) {
+			var horizontalSlide = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR )[ x ];
+			var verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' );
+
+			if( typeof y !== 'undefined' ) {
+				return verticalSlides ? verticalSlides[ y ] : undefined;
+			}
+
+			return horizontalSlide;
+		},
+
+		// Returns the previous slide element, may be null
+		getPreviousSlide: function() {
+			return previousSlide;
+		},
+
+		// Returns the current slide element
+		getCurrentSlide: function() {
+			return currentSlide;
+		},
+
+		// Returns the current scale of the presentation content
+		getScale: function() {
+			return scale;
+		},
+
+		// Returns the current configuration object
+		getConfig: function() {
+			return config;
+		},
+
+		// Helper method, retrieves query string as a key/value hash
+		getQueryHash: function() {
+			var query = {};
+
+			location.search.replace( /[A-Z0-9]+?=([\w\.%-]*)/gi, function(a) {
+				query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
+			} );
+
+			// Basic deserialization
+			for( var i in query ) {
+				var value = query[ i ];
+
+				query[ i ] = unescape( value );
+
+				if( value === 'null' ) query[ i ] = null;
+				else if( value === 'true' ) query[ i ] = true;
+				else if( value === 'false' ) query[ i ] = false;
+				else if( value.match( /^\d+$/ ) ) query[ i ] = parseFloat( value );
+			}
+
+			return query;
+		},
+
+		// Returns true if we're currently on the first slide
+		isFirstSlide: function() {
+			return document.querySelector( SLIDES_SELECTOR + '.past' ) == null ? true : false;
+		},
+
+		// Returns true if we're currently on the last slide
+		isLastSlide: function() {
+			if( currentSlide ) {
+				// Does this slide has next a sibling?
+				if( currentSlide.nextElementSibling ) return false;
+
+				// If it's vertical, does its parent have a next sibling?
+				if( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false;
+
+				return true;
+			}
+
+			return false;
+		},
+
+		// Checks if reveal.js has been loaded and is ready for use
+		isReady: function() {
+			return loaded;
+		},
+
+		// Forward event binding to the reveal DOM element
+		addEventListener: function( type, listener, useCapture ) {
+			if( 'addEventListener' in window ) {
+				( dom.wrapper || document.querySelector( '.reveal' ) ).addEventListener( type, listener, useCapture );
+			}
+		},
+		removeEventListener: function( type, listener, useCapture ) {
+			if( 'addEventListener' in window ) {
+				( dom.wrapper || document.querySelector( '.reveal' ) ).removeEventListener( type, listener, useCapture );
+			}
+		}
+	};
+
+})();
diff --git a/docs/slides/BOS14/_support/reveal.js/js/reveal.min.js b/docs/slides/BOS14/_support/reveal.js/js/reveal.min.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/js/reveal.min.js
@@ -0,0 +1,9 @@
+/*!
+ * reveal.js 2.6.1 (2014-03-13, 09:22)
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+ */
+var Reveal=function(){"use strict";function a(a){if(b(),!ec.transforms2d&&!ec.transforms3d)return document.body.setAttribute("class","no-transforms"),void 0;window.addEventListener("load",A,!1);var d=Reveal.getQueryHash();"undefined"!=typeof d.dependencies&&delete d.dependencies,k(_b,a),k(_b,d),r(),c()}function b(){ec.transforms3d="WebkitPerspective"in document.body.style||"MozPerspective"in document.body.style||"msPerspective"in document.body.style||"OPerspective"in document.body.style||"perspective"in document.body.style,ec.transforms2d="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style,ec.requestAnimationFrameMethod=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame,ec.requestAnimationFrame="function"==typeof ec.requestAnimationFrameMethod,ec.canvas=!!document.createElement("canvas").getContext,Vb=navigator.userAgent.match(/(iphone|ipod|android)/gi)}function c(){function a(){e.length&&head.js.apply(null,e),d()}function b(b){head.ready(b.src.match(/([\w\d_\-]*)\.?js$|[^\\\/]*$/i)[0],function(){"function"==typeof b.callback&&b.callback.apply(this),0===--f&&a()})}for(var c=[],e=[],f=0,g=0,h=_b.dependencies.length;h>g;g++){var i=_b.dependencies[g];(!i.condition||i.condition())&&(i.async?e.push(i.src):c.push(i.src),b(i))}c.length?(f=c.length,head.js.apply(null,c)):a()}function d(){e(),Q(),h(),cb(),X(!0),setTimeout(function(){dc.slides.classList.remove("no-transition"),ac=!0,t("ready",{indexh:Qb,indexv:Rb,currentSlide:Tb})},1)}function e(){dc.theme=document.querySelector("#theme"),dc.wrapper=document.querySelector(".reveal"),dc.slides=document.querySelector(".reveal .slides"),dc.slides.classList.add("no-transition"),dc.background=f(dc.wrapper,"div","backgrounds",null),dc.progress=f(dc.wrapper,"div","progress","<span></span>"),dc.progressbar=dc.progress.querySelector("span"),f(dc.wrapper,"aside","controls",'<div class="navigate-left"></div><div class="navigate-right"></div><div class="navigate-up"></div><div class="navigate-down"></div>'),dc.slideNumber=f(dc.wrapper,"div","slide-number",""),f(dc.wrapper,"div","state-background",null),f(dc.wrapper,"div","pause-overlay",null),dc.controls=document.querySelector(".reveal .controls"),dc.controlsLeft=l(document.querySelectorAll(".navigate-left")),dc.controlsRight=l(document.querySelectorAll(".navigate-right")),dc.controlsUp=l(document.querySelectorAll(".navigate-up")),dc.controlsDown=l(document.querySelectorAll(".navigate-down")),dc.controlsPrev=l(document.querySelectorAll(".navigate-prev")),dc.controlsNext=l(document.querySelectorAll(".navigate-next"))}function f(a,b,c,d){var e=a.querySelector("."+c);return e||(e=document.createElement(b),e.classList.add(c),null!==d&&(e.innerHTML=d),a.appendChild(e)),e}function g(){function a(a,b){var c={background:a.getAttribute("data-background"),backgroundSize:a.getAttribute("data-background-size"),backgroundImage:a.getAttribute("data-background-image"),backgroundColor:a.getAttribute("data-background-color"),backgroundRepeat:a.getAttribute("data-background-repeat"),backgroundPosition:a.getAttribute("data-background-position"),backgroundTransition:a.getAttribute("data-background-transition")},d=document.createElement("div");return d.className="slide-background",c.background&&(/^(http|file|\/\/)/gi.test(c.background)||/\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test(c.background)?d.style.backgroundImage="url("+c.background+")":d.style.background=c.background),(c.background||c.backgroundColor||c.backgroundImage)&&d.setAttribute("data-background-hash",c.background+c.backgroundSize+c.backgroundImage+c.backgroundColor+c.backgroundRepeat+c.backgroundPosition+c.backgroundTransition),c.backgroundSize&&(d.style.backgroundSize=c.backgroundSize),c.backgroundImage&&(d.style.backgroundImage='url("'+c.backgroundImage+'")'),c.backgroundColor&&(d.style.backgroundColor=c.backgroundColor),c.backgroundRepeat&&(d.style.backgroundRepeat=c.backgroundRepeat),c.backgroundPosition&&(d.style.backgroundPosition=c.backgroundPosition),c.backgroundTransition&&d.setAttribute("data-background-transition",c.backgroundTransition),b.appendChild(d),d}q()&&document.body.classList.add("print-pdf"),dc.background.innerHTML="",dc.background.classList.add("no-transition"),l(document.querySelectorAll(Yb)).forEach(function(b){var c;c=q()?a(b,b):a(b,dc.background),l(b.querySelectorAll("section")).forEach(function(b){q()?a(b,b):a(b,c)})}),_b.parallaxBackgroundImage?(dc.background.style.backgroundImage='url("'+_b.parallaxBackgroundImage+'")',dc.background.style.backgroundSize=_b.parallaxBackgroundSize,setTimeout(function(){dc.wrapper.classList.add("has-parallax-background")},1)):(dc.background.style.backgroundImage="",dc.wrapper.classList.remove("has-parallax-background"))}function h(a){var b=document.querySelectorAll(Xb).length;if(dc.wrapper.classList.remove(_b.transition),"object"==typeof a&&k(_b,a),ec.transforms3d===!1&&(_b.transition="linear"),dc.wrapper.classList.add(_b.transition),dc.wrapper.setAttribute("data-transition-speed",_b.transitionSpeed),dc.wrapper.setAttribute("data-background-transition",_b.backgroundTransition),dc.controls.style.display=_b.controls?"block":"none",dc.progress.style.display=_b.progress?"block":"none",_b.rtl?dc.wrapper.classList.add("rtl"):dc.wrapper.classList.remove("rtl"),_b.center?dc.wrapper.classList.add("center"):dc.wrapper.classList.remove("center"),_b.mouseWheel?(document.addEventListener("DOMMouseScroll",Bb,!1),document.addEventListener("mousewheel",Bb,!1)):(document.removeEventListener("DOMMouseScroll",Bb,!1),document.removeEventListener("mousewheel",Bb,!1)),_b.rollingLinks?u():v(),_b.previewLinks?w():(x(),w("[data-preview-link]")),b>1&&_b.autoSlide&&_b.autoSlideStoppable&&ec.canvas&&ec.requestAnimationFrame?(Wb=new Pb(dc.wrapper,function(){return Math.min(Math.max((Date.now()-mc)/kc,0),1)}),Wb.on("click",Ob),nc=!1):Wb&&(Wb.destroy(),Wb=null),_b.theme&&dc.theme){var c=dc.theme.getAttribute("href"),d=/[^\/]*?(?=\.css)/,e=c.match(d)[0];_b.theme!==e&&(c=c.replace(d,_b.theme),dc.theme.setAttribute("href",c))}P()}function i(){if(jc=!0,window.addEventListener("hashchange",Jb,!1),window.addEventListener("resize",Kb,!1),_b.touch&&(dc.wrapper.addEventListener("touchstart",vb,!1),dc.wrapper.addEventListener("touchmove",wb,!1),dc.wrapper.addEventListener("touchend",xb,!1),window.navigator.msPointerEnabled&&(dc.wrapper.addEventListener("MSPointerDown",yb,!1),dc.wrapper.addEventListener("MSPointerMove",zb,!1),dc.wrapper.addEventListener("MSPointerUp",Ab,!1))),_b.keyboard&&document.addEventListener("keydown",ub,!1),_b.progress&&dc.progress&&dc.progress.addEventListener("click",Cb,!1),_b.focusBodyOnPageVisiblityChange){var a;"hidden"in document?a="visibilitychange":"msHidden"in document?a="msvisibilitychange":"webkitHidden"in document&&(a="webkitvisibilitychange"),a&&document.addEventListener(a,Lb,!1)}["touchstart","click"].forEach(function(a){dc.controlsLeft.forEach(function(b){b.addEventListener(a,Db,!1)}),dc.controlsRight.forEach(function(b){b.addEventListener(a,Eb,!1)}),dc.controlsUp.forEach(function(b){b.addEventListener(a,Fb,!1)}),dc.controlsDown.forEach(function(b){b.addEventListener(a,Gb,!1)}),dc.controlsPrev.forEach(function(b){b.addEventListener(a,Hb,!1)}),dc.controlsNext.forEach(function(b){b.addEventListener(a,Ib,!1)})})}function j(){jc=!1,document.removeEventListener("keydown",ub,!1),window.removeEventListener("hashchange",Jb,!1),window.removeEventListener("resize",Kb,!1),dc.wrapper.removeEventListener("touchstart",vb,!1),dc.wrapper.removeEventListener("touchmove",wb,!1),dc.wrapper.removeEventListener("touchend",xb,!1),window.navigator.msPointerEnabled&&(dc.wrapper.removeEventListener("MSPointerDown",yb,!1),dc.wrapper.removeEventListener("MSPointerMove",zb,!1),dc.wrapper.removeEventListener("MSPointerUp",Ab,!1)),_b.progress&&dc.progress&&dc.progress.removeEventListener("click",Cb,!1),["touchstart","click"].forEach(function(a){dc.controlsLeft.forEach(function(b){b.removeEventListener(a,Db,!1)}),dc.controlsRight.forEach(function(b){b.removeEventListener(a,Eb,!1)}),dc.controlsUp.forEach(function(b){b.removeEventListener(a,Fb,!1)}),dc.controlsDown.forEach(function(b){b.removeEventListener(a,Gb,!1)}),dc.controlsPrev.forEach(function(b){b.removeEventListener(a,Hb,!1)}),dc.controlsNext.forEach(function(b){b.removeEventListener(a,Ib,!1)})})}function k(a,b){for(var c in b)a[c]=b[c]}function l(a){return Array.prototype.slice.call(a)}function m(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)}function n(a,b){a.style.WebkitTransform=b,a.style.MozTransform=b,a.style.msTransform=b,a.style.OTransform=b,a.style.transform=b}function o(a){var b=0;if(a){var c=0;l(a.childNodes).forEach(function(a){"number"==typeof a.offsetTop&&a.style&&("absolute"===a.style.position&&(c+=1),b=Math.max(b,a.offsetTop+a.offsetHeight))}),0===c&&(b=a.offsetHeight)}return b}function p(a,b){if(b=b||0,a){var c=a.parentNode,d=c.childNodes;l(d).forEach(function(c){if("number"==typeof c.offsetHeight&&c!==a){var d=window.getComputedStyle(c),e=parseInt(d.marginTop,10),f=parseInt(d.marginBottom,10);b-=c.offsetHeight+e+f}});var e=window.getComputedStyle(a);b-=parseInt(e.marginTop,10)+parseInt(e.marginBottom,10)}return b}function q(){return/print-pdf/gi.test(window.location.search)}function r(){_b.hideAddressBar&&Vb&&(window.addEventListener("load",s,!1),window.addEventListener("orientationchange",s,!1))}function s(){setTimeout(function(){window.scrollTo(0,1)},10)}function t(a,b){var c=document.createEvent("HTMLEvents",1,2);c.initEvent(a,!0,!0),k(c,b),dc.wrapper.dispatchEvent(c)}function u(){if(ec.transforms3d&&!("msPerspective"in document.body.style))for(var a=document.querySelectorAll(Xb+" a:not(.image)"),b=0,c=a.length;c>b;b++){var d=a[b];if(!(!d.textContent||d.querySelector("*")||d.className&&d.classList.contains(d,"roll"))){var e=document.createElement("span");e.setAttribute("data-title",d.text),e.innerHTML=d.innerHTML,d.classList.add("roll"),d.innerHTML="",d.appendChild(e)}}}function v(){for(var a=document.querySelectorAll(Xb+" a.roll"),b=0,c=a.length;c>b;b++){var d=a[b],e=d.querySelector("span");e&&(d.classList.remove("roll"),d.innerHTML=e.innerHTML)}}function w(a){var b=l(document.querySelectorAll(a?a:"a"));b.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.addEventListener("click",Nb,!1)})}function x(){var a=l(document.querySelectorAll("a"));a.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.removeEventListener("click",Nb,!1)})}function y(a){z(),dc.preview=document.createElement("div"),dc.preview.classList.add("preview-link-overlay"),dc.wrapper.appendChild(dc.preview),dc.preview.innerHTML=["<header>",'<a class="close" href="#"><span class="icon"></span></a>','<a class="external" href="'+a+'" target="_blank"><span class="icon"></span></a>',"</header>",'<div class="spinner"></div>','<div class="viewport">','<iframe src="'+a+'"></iframe>',"</div>"].join(""),dc.preview.querySelector("iframe").addEventListener("load",function(){dc.preview.classList.add("loaded")},!1),dc.preview.querySelector(".close").addEventListener("click",function(a){z(),a.preventDefault()},!1),dc.preview.querySelector(".external").addEventListener("click",function(){z()},!1),setTimeout(function(){dc.preview.classList.add("visible")},1)}function z(){dc.preview&&(dc.preview.setAttribute("src",""),dc.preview.parentNode.removeChild(dc.preview),dc.preview=null)}function A(){if(dc.wrapper&&!q()){var a=dc.wrapper.offsetWidth,b=dc.wrapper.offsetHeight;a-=b*_b.margin,b-=b*_b.margin;var c=_b.width,d=_b.height,e=20;B(_b.width,_b.height,e),"string"==typeof c&&/%$/.test(c)&&(c=parseInt(c,10)/100*a),"string"==typeof d&&/%$/.test(d)&&(d=parseInt(d,10)/100*b),dc.slides.style.width=c+"px",dc.slides.style.height=d+"px",cc=Math.min(a/c,b/d),cc=Math.max(cc,_b.minScale),cc=Math.min(cc,_b.maxScale),"undefined"==typeof dc.slides.style.zoom||navigator.userAgent.match(/(iphone|ipod|ipad|android)/gi)?n(dc.slides,"translate(-50%, -50%) scale("+cc+") translate(50%, 50%)"):dc.slides.style.zoom=cc;for(var f=l(document.querySelectorAll(Xb)),g=0,h=f.length;h>g;g++){var i=f[g];"none"!==i.style.display&&(i.style.top=_b.center||i.classList.contains("center")?i.classList.contains("stack")?0:Math.max(-(o(i)/2)-e,-d/2)+"px":"")}U(),Y()}}function B(a,b,c){l(dc.slides.querySelectorAll("section > .stretch")).forEach(function(d){var e=p(d,b-2*c);if(/(img|video)/gi.test(d.nodeName)){var f=d.naturalWidth||d.videoWidth,g=d.naturalHeight||d.videoHeight,h=Math.min(a/f,e/g);d.style.width=f*h+"px",d.style.height=g*h+"px"}else d.style.width=a+"px",d.style.height=e+"px"})}function C(a,b){"object"==typeof a&&"function"==typeof a.setAttribute&&a.setAttribute("data-previous-indexv",b||0)}function D(a){if("object"==typeof a&&"function"==typeof a.setAttribute&&a.classList.contains("stack")){var b=a.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(a.getAttribute(b)||0,10)}return 0}function E(){if(_b.overview){kb();var a=dc.wrapper.classList.contains("overview"),b=window.innerWidth<400?1e3:2500;dc.wrapper.classList.add("overview"),dc.wrapper.classList.remove("overview-deactivating"),clearTimeout(hc),clearTimeout(ic),hc=setTimeout(function(){for(var c=document.querySelectorAll(Yb),d=0,e=c.length;e>d;d++){var f=c[d],g=_b.rtl?-105:105;if(f.setAttribute("data-index-h",d),n(f,"translateZ(-"+b+"px) translate("+(d-Qb)*g+"%, 0%)"),f.classList.contains("stack"))for(var h=f.querySelectorAll("section"),i=0,j=h.length;j>i;i++){var k=d===Qb?Rb:D(f),l=h[i];l.setAttribute("data-index-h",d),l.setAttribute("data-index-v",i),n(l,"translate(0%, "+105*(i-k)+"%)"),l.addEventListener("click",Mb,!0)}else f.addEventListener("click",Mb,!0)}T(),A(),a||t("overviewshown",{indexh:Qb,indexv:Rb,currentSlide:Tb})},10)}}function F(){_b.overview&&(clearTimeout(hc),clearTimeout(ic),dc.wrapper.classList.remove("overview"),dc.wrapper.classList.add("overview-deactivating"),ic=setTimeout(function(){dc.wrapper.classList.remove("overview-deactivating")},1),l(document.querySelectorAll(Xb)).forEach(function(a){n(a,""),a.removeEventListener("click",Mb,!0)}),O(Qb,Rb),jb(),t("overviewhidden",{indexh:Qb,indexv:Rb,currentSlide:Tb}))}function G(a){"boolean"==typeof a?a?E():F():H()?F():E()}function H(){return dc.wrapper.classList.contains("overview")}function I(a){return a=a?a:Tb,a&&a.parentNode&&!!a.parentNode.nodeName.match(/section/i)}function J(){var a=document.body,b=a.requestFullScreen||a.webkitRequestFullscreen||a.webkitRequestFullScreen||a.mozRequestFullScreen||a.msRequestFullScreen;b&&b.apply(a)}function K(){var a=dc.wrapper.classList.contains("paused");kb(),dc.wrapper.classList.add("paused"),a===!1&&t("paused")}function L(){var a=dc.wrapper.classList.contains("paused");dc.wrapper.classList.remove("paused"),jb(),a&&t("resumed")}function M(){N()?L():K()}function N(){return dc.wrapper.classList.contains("paused")}function O(a,b,c,d){Sb=Tb;var e=document.querySelectorAll(Yb);void 0===b&&(b=D(e[a])),Sb&&Sb.parentNode&&Sb.parentNode.classList.contains("stack")&&C(Sb.parentNode,Rb);var f=bc.concat();bc.length=0;var g=Qb||0,h=Rb||0;Qb=S(Yb,void 0===a?Qb:a),Rb=S(Zb,void 0===b?Rb:b),T(),A();a:for(var i=0,j=bc.length;j>i;i++){for(var k=0;k<f.length;k++)if(f[k]===bc[i]){f.splice(k,1);continue a}document.documentElement.classList.add(bc[i]),t(bc[i])}for(;f.length;)document.documentElement.classList.remove(f.pop());H()&&E();var m=e[Qb],n=m.querySelectorAll("section");Tb=n[Rb]||m,"undefined"!=typeof c&&gb(c);var o=Qb!==g||Rb!==h;o?t("slidechanged",{indexh:Qb,indexv:Rb,previousSlide:Sb,currentSlide:Tb,origin:d}):Sb=null,Sb&&(Sb.classList.remove("present"),document.querySelector($b).classList.contains("present")&&setTimeout(function(){var a,b=l(document.querySelectorAll(Yb+".stack"));for(a in b)b[a]&&C(b[a],0)},0)),o&&(ab(Sb),_(Tb)),W(),U(),X(),Y(),V(),db(),jb()}function P(){j(),i(),A(),kc=_b.autoSlide,jb(),g(),R(),W(),U(),X(!0),V()}function Q(){var a=l(document.querySelectorAll(Yb));a.forEach(function(a){var b=l(a.querySelectorAll("section"));b.forEach(function(a,b){b>0&&(a.classList.remove("present"),a.classList.remove("past"),a.classList.add("future"))})})}function R(){var a=l(document.querySelectorAll(Yb));a.forEach(function(a){var b=l(a.querySelectorAll("section"));b.forEach(function(a){fb(a.querySelectorAll(".fragment"))}),0===b.length&&fb(a.querySelectorAll(".fragment"))})}function S(a,b){var c=l(document.querySelectorAll(a)),d=c.length;if(d){_b.loop&&(b%=d,0>b&&(b=d+b)),b=Math.max(Math.min(b,d-1),0);for(var e=0;d>e;e++){var f=c[e],g=_b.rtl&&!I(f);if(f.classList.remove("past"),f.classList.remove("present"),f.classList.remove("future"),f.setAttribute("hidden",""),b>e){f.classList.add(g?"future":"past");for(var h=l(f.querySelectorAll(".fragment"));h.length;){var i=h.pop();i.classList.add("visible"),i.classList.remove("current-fragment")}}else if(e>b){f.classList.add(g?"past":"future");for(var j=l(f.querySelectorAll(".fragment.visible"));j.length;){var k=j.pop();k.classList.remove("visible"),k.classList.remove("current-fragment")}}f.querySelector("section")&&f.classList.add("stack")}c[b].classList.add("present"),c[b].removeAttribute("hidden");var m=c[b].getAttribute("data-state");m&&(bc=bc.concat(m.split(" ")))}else b=0;return b}function T(){var a,b,c=l(document.querySelectorAll(Yb)),d=c.length;if(d){var e=H()?10:_b.viewDistance;Vb&&(e=H()?6:1);for(var f=0;d>f;f++){var g=c[f],h=l(g.querySelectorAll("section")),i=h.length;if(a=Math.abs((Qb-f)%(d-e))||0,g.style.display=a>e?"none":"block",i)for(var j=D(g),k=0;i>k;k++){var m=h[k];b=f===Qb?Math.abs(Rb-k):Math.abs(k-j),m.style.display=a+b>e?"none":"block"}}}}function U(){if(_b.progress&&dc.progress){var a=l(document.querySelectorAll(Yb)),b=document.querySelectorAll(Xb+":not(.stack)").length,c=0;a:for(var d=0;d<a.length;d++){for(var e=a[d],f=l(e.querySelectorAll("section")),g=0;g<f.length;g++){if(f[g].classList.contains("present"))break a;c++}if(e.classList.contains("present"))break;e.classList.contains("stack")===!1&&c++}dc.progressbar.style.width=c/(b-1)*window.innerWidth+"px"}}function V(){if(_b.slideNumber&&dc.slideNumber){var a=Qb;Rb>0&&(a+=" - "+Rb),dc.slideNumber.innerHTML=a}}function W(){var a=Z(),b=$();dc.controlsLeft.concat(dc.controlsRight).concat(dc.controlsUp).concat(dc.controlsDown).concat(dc.controlsPrev).concat(dc.controlsNext).forEach(function(a){a.classList.remove("enabled"),a.classList.remove("fragmented")}),a.left&&dc.controlsLeft.forEach(function(a){a.classList.add("enabled")}),a.right&&dc.controlsRight.forEach(function(a){a.classList.add("enabled")}),a.up&&dc.controlsUp.forEach(function(a){a.classList.add("enabled")}),a.down&&dc.controlsDown.forEach(function(a){a.classList.add("enabled")}),(a.left||a.up)&&dc.controlsPrev.forEach(function(a){a.classList.add("enabled")}),(a.right||a.down)&&dc.controlsNext.forEach(function(a){a.classList.add("enabled")}),Tb&&(b.prev&&dc.controlsPrev.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsNext.forEach(function(a){a.classList.add("fragmented","enabled")}),I(Tb)?(b.prev&&dc.controlsUp.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsDown.forEach(function(a){a.classList.add("fragmented","enabled")})):(b.prev&&dc.controlsLeft.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsRight.forEach(function(a){a.classList.add("fragmented","enabled")})))}function X(a){var b=null,c=_b.rtl?"future":"past",d=_b.rtl?"past":"future";if(l(dc.background.childNodes).forEach(function(e,f){Qb>f?e.className="slide-background "+c:f>Qb?e.className="slide-background "+d:(e.className="slide-background present",b=e),(a||f===Qb)&&l(e.childNodes).forEach(function(a,c){Rb>c?a.className="slide-background past":c>Rb?a.className="slide-background future":(a.className="slide-background present",f===Qb&&(b=a))})}),b){var e=Ub?Ub.getAttribute("data-background-hash"):null,f=b.getAttribute("data-background-hash");f&&f===e&&b!==Ub&&dc.background.classList.add("no-transition"),Ub=b}setTimeout(function(){dc.background.classList.remove("no-transition")},1)}function Y(){if(_b.parallaxBackgroundImage){var a,b,c=document.querySelectorAll(Yb),d=document.querySelectorAll(Zb),e=dc.background.style.backgroundSize.split(" ");1===e.length?a=b=parseInt(e[0],10):(a=parseInt(e[0],10),b=parseInt(e[1],10));var f=dc.background.offsetWidth,g=c.length,h=-(a-f)/(g-1)*Qb,i=dc.background.offsetHeight,j=d.length,k=j>0?-(b-i)/(j-1)*Rb:0;dc.background.style.backgroundPosition=h+"px "+k+"px"}}function Z(){var a=document.querySelectorAll(Yb),b=document.querySelectorAll(Zb),c={left:Qb>0||_b.loop,right:Qb<a.length-1||_b.loop,up:Rb>0,down:Rb<b.length-1};if(_b.rtl){var d=c.left;c.left=c.right,c.right=d}return c}function $(){if(Tb&&_b.fragments){var a=Tb.querySelectorAll(".fragment"),b=Tb.querySelectorAll(".fragment:not(.visible)");return{prev:a.length-b.length>0,next:!!b.length}}return{prev:!1,next:!1}}function _(a){a&&!bb()&&(l(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&a.play()}),l(a.querySelectorAll("iframe")).forEach(function(a){a.contentWindow.postMessage("slide:start","*")}),l(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-autoplay")&&a.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*")}))}function ab(a){a&&(l(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-ignore")||a.pause()}),l(a.querySelectorAll("iframe")).forEach(function(a){a.contentWindow.postMessage("slide:stop","*")}),l(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-ignore")||"function"!=typeof a.contentWindow.postMessage||a.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")}))}function bb(){return!!window.location.search.match(/receiver/gi)}function cb(){var a=window.location.hash,b=a.slice(2).split("/"),c=a.replace(/#|\//gi,"");if(isNaN(parseInt(b[0],10))&&c.length){var d=document.querySelector("#"+c);if(d){var e=Reveal.getIndices(d);O(e.h,e.v)}else O(Qb||0,Rb||0)}else{var f=parseInt(b[0],10)||0,g=parseInt(b[1],10)||0;(f!==Qb||g!==Rb)&&O(f,g)}}function db(a){if(_b.history)if(clearTimeout(gc),"number"==typeof a)gc=setTimeout(db,a);else{var b="/";Tb&&"string"==typeof Tb.getAttribute("id")?b="/"+Tb.getAttribute("id"):((Qb>0||Rb>0)&&(b+=Qb),Rb>0&&(b+="/"+Rb)),window.location.hash=b}}function eb(a){var b,c=Qb,d=Rb;if(a){var e=I(a),f=e?a.parentNode:a,g=l(document.querySelectorAll(Yb));c=Math.max(g.indexOf(f),0),e&&(d=Math.max(l(a.parentNode.querySelectorAll("section")).indexOf(a),0))}if(!a&&Tb){var h=Tb.querySelectorAll(".fragment").length>0;if(h){var i=Tb.querySelectorAll(".fragment.visible");b=i.length-1}}return{h:c,v:d,f:b}}function fb(a){a=l(a);var b=[],c=[],d=[];a.forEach(function(a){if(a.hasAttribute("data-fragment-index")){var d=parseInt(a.getAttribute("data-fragment-index"),10);b[d]||(b[d]=[]),b[d].push(a)}else c.push([a])}),b=b.concat(c);var e=0;return b.forEach(function(a){a.forEach(function(a){d.push(a),a.setAttribute("data-fragment-index",e)}),e++}),d}function gb(a,b){if(Tb&&_b.fragments){var c=fb(Tb.querySelectorAll(".fragment"));if(c.length){if("number"!=typeof a){var d=fb(Tb.querySelectorAll(".fragment.visible")).pop();a=d?parseInt(d.getAttribute("data-fragment-index")||0,10):-1}"number"==typeof b&&(a+=b);var e=[],f=[];return l(c).forEach(function(b,c){b.hasAttribute("data-fragment-index")&&(c=parseInt(b.getAttribute("data-fragment-index"),10)),a>=c?(b.classList.contains("visible")||e.push(b),b.classList.add("visible"),b.classList.remove("current-fragment"),c===a&&b.classList.add("current-fragment")):(b.classList.contains("visible")&&f.push(b),b.classList.remove("visible"),b.classList.remove("current-fragment"))}),f.length&&t("fragmenthidden",{fragment:f[0],fragments:f}),e.length&&t("fragmentshown",{fragment:e[0],fragments:e}),W(),!(!e.length&&!f.length)}}return!1}function hb(){return gb(null,1)}function ib(){return gb(null,-1)}function jb(){if(kb(),Tb){var a=Tb.parentNode?Tb.parentNode.getAttribute("data-autoslide"):null,b=Tb.getAttribute("data-autoslide");kc=b?parseInt(b,10):a?parseInt(a,10):_b.autoSlide,l(Tb.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&kc&&1e3*a.duration>kc&&(kc=1e3*a.duration+1e3)}),!kc||nc||N()||H()||Reveal.isLastSlide()&&_b.loop!==!0||(lc=setTimeout(sb,kc),mc=Date.now()),Wb&&Wb.setPlaying(-1!==lc)}}function kb(){clearTimeout(lc),lc=-1}function lb(){nc=!0,clearTimeout(lc),Wb&&Wb.setPlaying(!1)}function mb(){nc=!1,jb()}function nb(){_b.rtl?(H()||hb()===!1)&&Z().left&&O(Qb+1):(H()||ib()===!1)&&Z().left&&O(Qb-1)}function ob(){_b.rtl?(H()||ib()===!1)&&Z().right&&O(Qb-1):(H()||hb()===!1)&&Z().right&&O(Qb+1)}function pb(){(H()||ib()===!1)&&Z().up&&O(Qb,Rb-1)}function qb(){(H()||hb()===!1)&&Z().down&&O(Qb,Rb+1)}function rb(){if(ib()===!1)if(Z().up)pb();else{var a=document.querySelector(Yb+".past:nth-child("+Qb+")");if(a){var b=a.querySelectorAll("section").length-1||void 0,c=Qb-1;O(c,b)}}}function sb(){hb()===!1&&(Z().down?qb():ob()),jb()}function tb(){_b.autoSlideStoppable&&lb()}function ub(a){tb(a),document.activeElement;var b=!(!document.activeElement||!document.activeElement.type&&!document.activeElement.href&&"inherit"===document.activeElement.contentEditable);if(!(b||a.shiftKey&&32!==a.keyCode||a.altKey||a.ctrlKey||a.metaKey)){if(N()&&-1===[66,190,191].indexOf(a.keyCode))return!1;var c=!1;if("object"==typeof _b.keyboard)for(var d in _b.keyboard)if(parseInt(d,10)===a.keyCode){var e=_b.keyboard[d];"function"==typeof e?e.apply(null,[a]):"string"==typeof e&&"function"==typeof Reveal[e]&&Reveal[e].call(),c=!0}if(c===!1)switch(c=!0,a.keyCode){case 80:case 33:rb();break;case 78:case 34:sb();break;case 72:case 37:nb();break;case 76:case 39:ob();break;case 75:case 38:pb();break;case 74:case 40:qb();break;case 36:O(0);break;case 35:O(Number.MAX_VALUE);break;case 32:H()?F():a.shiftKey?rb():sb();break;case 13:H()?F():c=!1;break;case 66:case 190:case 191:M();break;case 70:J();break;default:c=!1}c?a.preventDefault():27!==a.keyCode&&79!==a.keyCode||!ec.transforms3d||(dc.preview?z():G(),a.preventDefault()),jb()}}function vb(a){oc.startX=a.touches[0].clientX,oc.startY=a.touches[0].clientY,oc.startCount=a.touches.length,2===a.touches.length&&_b.overview&&(oc.startSpan=m({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:oc.startX,y:oc.startY}))}function wb(a){if(oc.captured)navigator.userAgent.match(/android/gi)&&a.preventDefault();else{tb(a);var b=a.touches[0].clientX,c=a.touches[0].clientY;if(2===a.touches.length&&2===oc.startCount&&_b.overview){var d=m({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:oc.startX,y:oc.startY});Math.abs(oc.startSpan-d)>oc.threshold&&(oc.captured=!0,d<oc.startSpan?E():F()),a.preventDefault()}else if(1===a.touches.length&&2!==oc.startCount){var e=b-oc.startX,f=c-oc.startY;e>oc.threshold&&Math.abs(e)>Math.abs(f)?(oc.captured=!0,nb()):e<-oc.threshold&&Math.abs(e)>Math.abs(f)?(oc.captured=!0,ob()):f>oc.threshold?(oc.captured=!0,pb()):f<-oc.threshold&&(oc.captured=!0,qb()),_b.embedded?(oc.captured||I(Tb))&&a.preventDefault():a.preventDefault()}}}function xb(){oc.captured=!1}function yb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],vb(a))}function zb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],wb(a))}function Ab(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],xb(a))}function Bb(a){if(Date.now()-fc>600){fc=Date.now();var b=a.detail||-a.wheelDelta;b>0?sb():rb()}}function Cb(a){tb(a),a.preventDefault();var b=l(document.querySelectorAll(Yb)).length,c=Math.floor(a.clientX/dc.wrapper.offsetWidth*b);O(c)}function Db(a){a.preventDefault(),tb(),nb()}function Eb(a){a.preventDefault(),tb(),ob()}function Fb(a){a.preventDefault(),tb(),pb()}function Gb(a){a.preventDefault(),tb(),qb()}function Hb(a){a.preventDefault(),tb(),rb()}function Ib(a){a.preventDefault(),tb(),sb()}function Jb(){cb()}function Kb(){A()}function Lb(){var a=document.webkitHidden||document.msHidden||document.hidden;a===!1&&document.activeElement!==document.body&&(document.activeElement.blur(),document.body.focus())}function Mb(a){if(jc&&H()){a.preventDefault();for(var b=a.target;b&&!b.nodeName.match(/section/gi);)b=b.parentNode;if(b&&!b.classList.contains("disabled")&&(F(),b.nodeName.match(/section/gi))){var c=parseInt(b.getAttribute("data-index-h"),10),d=parseInt(b.getAttribute("data-index-v"),10);O(c,d)}}}function Nb(a){var b=a.target.getAttribute("href");b&&(y(b),a.preventDefault())}function Ob(){Reveal.isLastSlide()&&_b.loop===!1?(O(0,0),mb()):nc?mb():lb()}function Pb(a,b){this.diameter=50,this.thickness=3,this.playing=!1,this.progress=0,this.progressOffset=1,this.container=a,this.progressCheck=b,this.canvas=document.createElement("canvas"),this.canvas.className="playback",this.canvas.width=this.diameter,this.canvas.height=this.diameter,this.context=this.canvas.getContext("2d"),this.container.appendChild(this.canvas),this.render()}var Qb,Rb,Sb,Tb,Ub,Vb,Wb,Xb=".reveal .slides section",Yb=".reveal .slides>section",Zb=".reveal .slides>section.present>section",$b=".reveal .slides>section:first-of-type",_b={width:960,height:700,margin:.1,minScale:.2,maxScale:1,controls:!0,progress:!0,slideNumber:!1,history:!1,keyboard:!0,overview:!0,center:!0,touch:!0,loop:!1,rtl:!1,fragments:!0,embedded:!1,autoSlide:0,autoSlideStoppable:!0,mouseWheel:!1,rollingLinks:!1,hideAddressBar:!0,previewLinks:!1,focusBodyOnPageVisiblityChange:!0,theme:null,transition:"default",transitionSpeed:"default",backgroundTransition:"default",parallaxBackgroundImage:"",parallaxBackgroundSize:"",viewDistance:3,dependencies:[]},ac=!1,bc=[],cc=1,dc={},ec={},fc=0,gc=0,hc=0,ic=0,jc=!1,kc=0,lc=0,mc=-1,nc=!1,oc={startX:0,startY:0,startSpan:0,startCount:0,captured:!1,threshold:40};return Pb.prototype.setPlaying=function(a){var b=this.playing;this.playing=a,!b&&this.playing?this.animate():this.render()},Pb.prototype.animate=function(){var a=this.progress;this.progress=this.progressCheck(),a>.8&&this.progress<.2&&(this.progressOffset=this.progress),this.render(),this.playing&&ec.requestAnimationFrameMethod.call(window,this.animate.bind(this))},Pb.prototype.render=function(){var a=this.playing?this.progress:0,b=this.diameter/2-this.thickness,c=this.diameter/2,d=this.diameter/2,e=14;this.progressOffset+=.1*(1-this.progressOffset);var f=-Math.PI/2+a*2*Math.PI,g=-Math.PI/2+this.progressOffset*2*Math.PI;this.context.save(),this.context.clearRect(0,0,this.diameter,this.diameter),this.context.beginPath(),this.context.arc(c,d,b+2,0,2*Math.PI,!1),this.context.fillStyle="rgba( 0, 0, 0, 0.4 )",this.context.fill(),this.context.beginPath(),this.context.arc(c,d,b,0,2*Math.PI,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#666",this.context.stroke(),this.playing&&(this.context.beginPath(),this.context.arc(c,d,b,g,f,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#fff",this.context.stroke()),this.context.translate(c-e/2,d-e/2),this.playing?(this.context.fillStyle="#fff",this.context.fillRect(0,0,e/2-2,e),this.context.fillRect(e/2+2,0,e/2-2,e)):(this.context.beginPath(),this.context.translate(2,0),this.context.moveTo(0,0),this.context.lineTo(e-2,e/2),this.context.lineTo(0,e),this.context.fillStyle="#fff",this.context.fill()),this.context.restore()},Pb.prototype.on=function(a,b){this.canvas.addEventListener(a,b,!1)},Pb.prototype.off=function(a,b){this.canvas.removeEventListener(a,b,!1)},Pb.prototype.destroy=function(){this.playing=!1,this.canvas.parentNode&&this.container.removeChild(this.canvas)},{initialize:a,configure:h,sync:P,slide:O,left:nb,right:ob,up:pb,down:qb,prev:rb,next:sb,navigateFragment:gb,prevFragment:ib,nextFragment:hb,navigateTo:O,navigateLeft:nb,navigateRight:ob,navigateUp:pb,navigateDown:qb,navigatePrev:rb,navigateNext:sb,layout:A,availableRoutes:Z,availableFragments:$,toggleOverview:G,togglePause:M,isOverview:H,isPaused:N,addEventListeners:i,removeEventListeners:j,getIndices:eb,getSlide:function(a,b){var c=document.querySelectorAll(Yb)[a],d=c&&c.querySelectorAll("section");
+return"undefined"!=typeof b?d?d[b]:void 0:c},getPreviousSlide:function(){return Sb},getCurrentSlide:function(){return Tb},getScale:function(){return cc},getConfig:function(){return _b},getQueryHash:function(){var a={};location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi,function(b){a[b.split("=").shift()]=b.split("=").pop()});for(var b in a){var c=a[b];a[b]=unescape(c),"null"===c?a[b]=null:"true"===c?a[b]=!0:"false"===c?a[b]=!1:c.match(/^\d+$/)&&(a[b]=parseFloat(c))}return a},isFirstSlide:function(){return null==document.querySelector(Xb+".past")?!0:!1},isLastSlide:function(){return Tb?Tb.nextElementSibling?!1:I(Tb)&&Tb.parentNode.nextElementSibling?!1:!0:!1},isReady:function(){return ac},addEventListener:function(a,b,c){"addEventListener"in window&&(dc.wrapper||document.querySelector(".reveal")).addEventListener(a,b,c)},removeEventListener:function(a,b,c){"addEventListener"in window&&(dc.wrapper||document.querySelector(".reveal")).removeEventListener(a,b,c)}}}();
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/css/zenburn.css b/docs/slides/BOS14/_support/reveal.js/lib/css/zenburn.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/lib/css/zenburn.css
@@ -0,0 +1,114 @@
+/*
+
+Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
+based on dark.css by Ivan Sagalaev
+
+*/
+
+pre code {
+  display: block; padding: 0.5em;
+  background: #3F3F3F;
+  color: #DCDCDC;
+}
+
+pre .keyword,
+pre .tag,
+pre .css .class,
+pre .css .id,
+pre .lisp .title,
+pre .nginx .title,
+pre .request,
+pre .status,
+pre .clojure .attribute {
+  color: #E3CEAB;
+}
+
+pre .django .template_tag,
+pre .django .variable,
+pre .django .filter .argument {
+  color: #DCDCDC;
+}
+
+pre .number,
+pre .date {
+  color: #8CD0D3;
+}
+
+pre .dos .envvar,
+pre .dos .stream,
+pre .variable,
+pre .apache .sqbracket {
+  color: #EFDCBC;
+}
+
+pre .dos .flow,
+pre .diff .change,
+pre .python .exception,
+pre .python .built_in,
+pre .literal,
+pre .tex .special {
+  color: #EFEFAF;
+}
+
+pre .diff .chunk,
+pre .subst {
+  color: #8F8F8F;
+}
+
+pre .dos .keyword,
+pre .python .decorator,
+pre .title,
+pre .haskell .type,
+pre .diff .header,
+pre .ruby .class .parent,
+pre .apache .tag,
+pre .nginx .built_in,
+pre .tex .command,
+pre .prompt {
+    color: #efef8f;
+}
+
+pre .dos .winutils,
+pre .ruby .symbol,
+pre .ruby .symbol .string,
+pre .ruby .string {
+  color: #DCA3A3;
+}
+
+pre .diff .deletion,
+pre .string,
+pre .tag .value,
+pre .preprocessor,
+pre .built_in,
+pre .sql .aggregate,
+pre .javadoc,
+pre .smalltalk .class,
+pre .smalltalk .localvars,
+pre .smalltalk .array,
+pre .css .rules .value,
+pre .attr_selector,
+pre .pseudo,
+pre .apache .cbracket,
+pre .tex .formula {
+  color: #CC9393;
+}
+
+pre .shebang,
+pre .diff .addition,
+pre .comment,
+pre .java .annotation,
+pre .template_comment,
+pre .pi,
+pre .doctype {
+  color: #7F9F7F;
+}
+
+pre .coffeescript .javascript,
+pre .javascript .xml,
+pre .tex .formula,
+pre .xml .javascript,
+pre .xml .vbscript,
+pre .xml .css,
+pre .xml .cdata {
+  opacity: 0.5;
+}
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.eot b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.eot
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.eot differ
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.svg b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.svg
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.svg
@@ -0,0 +1,230 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="LeagueGothicRegular" horiz-adv-x="724" >
+<font-face units-per-em="2048" ascent="1505" descent="-543" />
+<missing-glyph horiz-adv-x="315" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="2048" />
+<glyph unicode="&#xd;" horiz-adv-x="682" />
+<glyph unicode=" "  horiz-adv-x="315" />
+<glyph unicode="&#x09;" horiz-adv-x="315" />
+<glyph unicode="&#xa0;" horiz-adv-x="315" />
+<glyph unicode="!" horiz-adv-x="387" d="M74 1505h239l-55 -1099h-129zM86 0v227h215v-227h-215z" />
+<glyph unicode="&#x22;" horiz-adv-x="329" d="M57 1505h215l-30 -551h-154z" />
+<glyph unicode="#" horiz-adv-x="1232" d="M49 438l27 195h198l37 258h-196l26 194h197l57 420h197l-57 -420h260l57 420h197l-58 -420h193l-27 -194h-192l-37 -258h190l-26 -195h-191l-59 -438h-197l60 438h-261l-59 -438h-197l60 438h-199zM471 633h260l37 258h-260z" />
+<glyph unicode="$" horiz-adv-x="692" d="M37 358l192 13q12 -186 129 -187q88 0 93 185q0 74 -61 175q-21 36 -34 53l-40 55q-28 38 -65.5 90t-70.5 101.5t-70.5 141.5t-37.5 170q4 293 215 342v131h123v-125q201 -23 235 -282l-192 -25q-14 129 -93 125q-80 -2 -84 -162q0 -102 94 -227l41 -59q30 -42 37 -52 t33 -48l37 -52q41 -57 68 -109l26 -55q43 -94 43 -186q-4 -338 -245 -369v-217h-123v221q-236 41 -250 352z" />
+<glyph unicode="%" horiz-adv-x="1001" d="M55 911v437q0 110 82 156q33 18 90.5 18t97.5 -44t44 -87l4 -43v-437q0 -107 -81 -157q-32 -19 -77 -19q-129 0 -156 135zM158 0l553 1505h131l-547 -1505h-137zM178 911q-4 -55 37 -55q16 0 25.5 14.5t9.5 26.5v451q2 55 -35 55q-18 0 -27.5 -13.5t-9.5 -27.5v-451z M631 158v436q0 108 81 156q33 20 79 20q125 0 153 -135l4 -41v-436q0 -110 -80 -156q-32 -18 -90.5 -18t-98.5 43t-44 88zM754 158q-4 -57 37 -58q37 0 34 58v436q2 55 -34 55q-18 0 -27.5 -13t-9.5 -28v-450z" />
+<glyph unicode="&#x26;" horiz-adv-x="854" d="M49 304q0 126 44 225.5t126 222.5q-106 225 -106 442v18q0 94 47 180q70 130 223 130q203 0 252 -215q14 -61 12 -113q0 -162 -205 -434q76 -174 148 -285q33 96 47 211l176 -33q-16 -213 -92 -358q55 -63 92 -76v-235q-23 0 -86 37.5t-123 101.5q-123 -139 -252 -139 t-216 97t-87 223zM263 325.5q1 -65.5 28.5 -107.5t78.5 -42t117 86q-88 139 -174 295q-18 -30 -34.5 -98t-15.5 -133.5zM305 1194q0 -111 55 -246q101 156 101 252q-2 2 0 15.5t-2 36t-11 42.5q-19 52 -61.5 52t-62 -38t-19.5 -75v-39z" />
+<glyph unicode="'" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="(" horiz-adv-x="561" d="M66 645q0 143 29.5 292.5t73.5 261.5q92 235 159 343l30 47l162 -84q-38 -53 -86.5 -148t-82.5 -189.5t-61.5 -238t-27.5 -284.5t26.5 -282.5t64.5 -240.5q80 -207 141 -296l26 -39l-162 -84q-41 61 -96 173t-94 217.5t-70.5 257t-31.5 294.5z" />
+<glyph unicode=")" horiz-adv-x="561" d="M41 -213q36 50 85.5 147t83.5 190t61.5 236.5t27.5 284.5t-26.5 282.5t-64.5 240.5q-78 205 -140 298l-27 39l162 84q41 -61 96 -173.5t94 -217t71 -257.5t32 -296t-30 -292.5t-74 -260.5q-92 -233 -159 -342l-30 -47z" />
+<glyph unicode="*" horiz-adv-x="677" d="M74 1251l43 148l164 -70l-19 176h154l-19 -176l164 70l43 -148l-172 -34l115 -138l-131 -80l-78 152l-76 -152l-131 80l115 138z" />
+<glyph unicode="+" horiz-adv-x="1060" d="M74 649v172h370v346h172v-346h371v-172h-371v-346h-172v346h-370z" />
+<glyph unicode="," horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="-" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="." horiz-adv-x="321" d="M53 0v227h215v-227h-215z" />
+<glyph unicode="/" horiz-adv-x="720" d="M8 -147l543 1652h162l-537 -1652h-168z" />
+<glyph unicode="0" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="1" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="2" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="3" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="4" horiz-adv-x="684" d="M25 328v194l323 983h221v-983h103v-194h-103v-328h-202v328h-342zM213 522h154v516h-13z" />
+<glyph unicode="5" horiz-adv-x="704" d="M74 438h221v-59q0 -115 14.5 -159t52 -44t53 45t15.5 156v336q0 111 -70 110q-33 0 -59.5 -40t-26.5 -70h-186v792h535v-219h-344v-313q74 55 127 51q78 0 133 -40t77 -100q35 -98 35 -171v-336q0 -393 -289 -393q-78 0 -133 29.5t-84.5 71.5t-46.5 109q-24 98 -24 244z " />
+<glyph unicode="6" horiz-adv-x="700" d="M66 309v856q0 356 288.5 356.5t288.5 -356.5v-94h-221q0 162 -11.5 210t-53.5 48t-56 -37t-14 -127v-268q59 37 124.5 37t119 -36t75.5 -93q37 -92 37 -189v-307q0 -90 -42 -187q-26 -61 -89 -99.5t-157.5 -38.5t-158 38.5t-88.5 99.5q-42 98 -42 187zM287 244 q0 -20 17.5 -44t49 -24t50 24.5t18.5 43.5v450q0 18 -18.5 43t-49 25t-48 -20.5t-19.5 -41.5v-456z" />
+<glyph unicode="7" horiz-adv-x="589" d="M8 1286v219h557v-221l-221 -1284h-229l225 1286h-332z" />
+<glyph unicode="8" horiz-adv-x="696" d="M53 322v176q0 188 115 297q-102 102 -102 276v127q0 213 147 293q57 31 135 31t135.5 -31t84 -71t42.5 -93q21 -66 21 -129v-127q0 -174 -103 -276q115 -109 115 -297v-176q0 -222 -153 -306q-60 -32 -142 -32t-141.5 32.5t-88 73.5t-44.5 96q-21 69 -21 136zM269 422 q1 -139 16.5 -187.5t57.5 -48.5t59.5 30t21.5 71t4 158t-13.5 174t-66.5 57t-66.5 -57.5t-12.5 -196.5zM284 1116q-1 -123 11 -173t53 -50t53.5 50t12.5 170t-12.5 167t-51.5 47t-52 -44t-14 -167z" />
+<glyph unicode="9" horiz-adv-x="700" d="M57 340v94h222q0 -162 11 -210t53 -48t56.5 37t14.5 127v283q-59 -37 -125 -37t-119 35.5t-76 92.5q-37 96 -37 189v293q0 87 43 188q25 60 88.5 99t157.5 39t157.5 -39t88.5 -99q43 -101 43 -188v-856q0 -356 -289 -356t-289 356zM279 825q0 -18 18 -42.5t49 -24.5 t48.5 20.5t19.5 40.5v443q0 20 -17.5 43.5t-49.5 23.5t-50 -24.5t-18 -42.5v-437z" />
+<glyph unicode=":" horiz-adv-x="362" d="M74 0v227h215v-227h-215zM74 893v227h215v-227h-215z" />
+<glyph unicode=";" horiz-adv-x="362" d="M74 0v227h215v-227l-113 -266h-102l71 266h-71zM74 893v227h215v-227h-215z" />
+<glyph unicode="&#x3c;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="=" horiz-adv-x="1058" d="M74 477v172h911v-172h-911zM74 864v172h911v-172h-911z" />
+<glyph unicode="&#x3e;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="?" horiz-adv-x="645" d="M25 1260q24 67 78 131q105 128 235 122q82 -2 138 -33.5t82 -81.5q46 -88 46 -170.5t-80 -219.5l-57 -96q-18 -32 -42 -106.5t-24 -143.5v-256h-190v256q0 102 24.5 195t48 140t65.5 118t50 105t-9 67.5t-60 34.5t-78 -48t-49 -98zM199 0h215v227h-215v-227z" />
+<glyph unicode="@" horiz-adv-x="872" d="M66 303v889q0 97 73 200q39 56 117 93t184.5 37t184 -37t116.5 -93q74 -105 74 -200v-793h-164l-20 56q-14 -28 -46 -48t-67 -20q-145 0 -145 172v485q0 170 145 170q71 0 113 -67v45q0 51 -45 104.5t-145.5 53.5t-145.5 -53.5t-45 -104.5v-889q0 -53 44 -103t153.5 -50 t160.5 63l152 -86q-109 -143 -320 -143q-106 0 -184 35.5t-117 90.5q-73 102 -73 193zM535 573q0 -53 48 -53t48 53v455q0 53 -48 53t-48 -53v-455z" />
+<glyph unicode="A" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="B" horiz-adv-x="745" d="M82 0v1505h194q205 0 304.5 -91t99.5 -308q0 -106 -29.5 -175t-107.5 -136q14 -5 47 -38.5t54 -71.5q52 -97 52 -259q0 -414 -342 -426h-272zM303 219q74 0 109 31q55 56 55 211t-63 195q-42 26 -93 26h-8v-463zM303 885q87 0 119 39q45 55 45 138t-14.5 124t-30.5 60.5 t-45 28.5q-35 11 -74 11v-401z" />
+<glyph unicode="C" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175z" />
+<glyph unicode="D" horiz-adv-x="761" d="M82 0v1505h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174zM303 221q117 0 140.5 78t23.5 399v111q0 322 -23.5 398.5t-140.5 76.5v-1063z" />
+<glyph unicode="E" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506z" />
+<glyph unicode="F" horiz-adv-x="616" d="M82 0v1505h526v-227h-305v-395h205v-228h-205v-655h-221z" />
+<glyph unicode="G" horiz-adv-x="737" d="M67 271.5q0 26.5 1 37.5v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-231h-221v231q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-905q0 -46 19.5 -78.5t54 -32.5t53 28t18.5 54l2 29v272h-88v187h309v-750h-131l-26 72 q-70 -88 -172 -88q-203 0 -250 213q-11 48 -11 74.5z" />
+<glyph unicode="H" horiz-adv-x="778" d="M82 0v1505h221v-622h172v622h221v-1505h-221v655h-172v-655h-221z" />
+<glyph unicode="I" horiz-adv-x="385" d="M82 0v1505h221v-1505h-221z" />
+<glyph unicode="J" horiz-adv-x="423" d="M12 -14v217q4 0 12.5 -1t29 2t35.5 12t28.5 34.5t13.5 62.5v1192h221v-1226q0 -137 -74 -216q-74 -78 -223 -78h-4q-19 0 -39 1z" />
+<glyph unicode="K" horiz-adv-x="768" d="M82 0v1505h221v-526h8l195 526h215l-203 -495l230 -1010h-216l-153 655l-6 31h-6l-64 -154v-532h-221z" />
+<glyph unicode="L" horiz-adv-x="604" d="M82 0v1505h221v-1300h293v-205h-514z" />
+<glyph unicode="M" horiz-adv-x="991" d="M82 0v1505h270l131 -688l11 -80h4l10 80l131 688h270v-1505h-204v1010h-13l-149 -1010h-94l-142 946l-8 64h-12v-1010h-205z" />
+<glyph unicode="N" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203z" />
+<glyph unicode="O" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="P" horiz-adv-x="720" d="M82 0v1505h221q166 0 277.5 -105.5t111.5 -345t-111.5 -346t-277.5 -106.5v-602h-221zM303 827q102 0 134 45.5t32 175.5t-33 181t-133 51v-453z" />
+<glyph unicode="Q" horiz-adv-x="729" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -94 -45 -182q33 -43 88 -53v-189q-160 0 -227 117q-55 -18 -125 -18t-130 33.5t-88 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887 q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="R" horiz-adv-x="739" d="M82 0v1505h221q377 0 377 -434q0 -258 -123 -342l141 -729h-221l-115 635h-59v-635h-221zM303 840q117 0 149 98q15 49 15 125t-15.5 125t-45.5 68q-44 30 -103 30v-446z" />
+<glyph unicode="S" horiz-adv-x="702" d="M37 422l217 20q0 -256 104 -256q90 0 91 166q0 59 -32 117.5t-45 79.5l-54 79q-40 58 -77 113t-73.5 117t-68 148.5t-31.5 162.5q0 139 71.5 245t216.5 108h10q88 0 152 -36t94 -100q54 -120 54 -264l-217 -20q0 217 -89 217q-75 -2 -75 -146q0 -59 23 -105 q32 -66 58 -104l197 -296q31 -49 67 -139.5t36 -166.5q0 -378 -306 -378h-2q-229 0 -290 188q-31 99 -31 250z" />
+<glyph unicode="T" horiz-adv-x="647" d="M4 1278v227h639v-227h-209v-1278h-221v1278h-209z" />
+<glyph unicode="U" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175z" />
+<glyph unicode="V" horiz-adv-x="716" d="M18 1505h215l111 -827l8 -64h13l118 891h215l-229 -1505h-221z" />
+<glyph unicode="W" horiz-adv-x="1036" d="M25 1505h204l88 -782l5 -49h16l100 831h160l100 -831h17l92 831h205l-203 -1505h-172l-115 801h-8l-115 -801h-172z" />
+<glyph unicode="X" horiz-adv-x="737" d="M16 0l244 791l-240 714h218l120 -381l7 -18h8l127 399h217l-240 -714l244 -791h-217l-127 449l-4 18h-8l-132 -467h-217z" />
+<glyph unicode="Y" horiz-adv-x="700" d="M14 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641z" />
+<glyph unicode="Z" horiz-adv-x="626" d="M20 0v238l347 1048h-297v219h536v-219l-352 -1067h352v-219h-586z" />
+<glyph unicode="[" horiz-adv-x="538" d="M82 -213v1718h399v-196h-202v-1325h202v-197h-399z" />
+<glyph unicode="\" horiz-adv-x="792" d="M8 1692h162l614 -1872h-168z" />
+<glyph unicode="]" horiz-adv-x="538" d="M57 -16h203v1325h-203v196h400v-1718h-400v197z" />
+<glyph unicode="^" horiz-adv-x="1101" d="M53 809l381 696h234l381 -696h-199l-299 543l-299 -543h-199z" />
+<glyph unicode="_" horiz-adv-x="1210" d="M74 -154h1063v-172h-1063v172z" />
+<glyph unicode="`" horiz-adv-x="1024" d="M293 1489h215l106 -184h-159z" />
+<glyph unicode="a" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="b" horiz-adv-x="686" d="M82 0v1505h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-74h-207zM289 246q0 -29 19.5 -48.5t42 -19.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -21.5t-19.5 -46.5v-628z" />
+<glyph unicode="c" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331z" />
+<glyph unicode="d" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v458h207v-1505h-207v74q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 19.5t19.5 48.5v628q0 25 -19.5 46.5t-42 21.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="e" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="f" horiz-adv-x="475" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-65 0 -65 -175v-5v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="g" horiz-adv-x="700" d="M12 -184q0 94 162 170q-125 35 -125 149q0 45 40 93t89 75q-51 35 -80.5 95.5t-34.5 105.5l-4 43v305q0 35 16.5 91t41 94t79 69t126.5 31q135 0 206 -103q102 102 170 103v-185q-72 0 -120 -24l10 -70v-317q0 -37 -17.5 -90.5t-42 -90t-79 -66.5t-104.5 -30t-62 2 q-29 -25 -29 -46t11 -33.5t42 -20.5t45.5 -10t65.5 -10.5t95 -21.5t89 -41q96 -60 96 -205t-103 -212q-100 -65 -250 -65h-9q-156 2 -240 50t-84 165zM213 -150q0 -77 132 -77h3q59 0 108.5 19t49.5 54t-20.5 52.5t-90.5 29.5l-106 21q-76 -43 -76 -99zM262 509 q0 -17 15.5 -45t44.5 -28q63 6 63 101v307q-2 0 0 10q1 3 1 7q0 8 -3 19q-4 15 -9 30q-11 36 -46 36t-50.5 -25.5t-15.5 -52.5v-359z" />
+<glyph unicode="h" horiz-adv-x="690" d="M82 0v1505h207v-479l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="i" horiz-adv-x="370" d="M82 0v1120h207v-1120h-207zM82 1298v207h207v-207h-207z" />
+<glyph unicode="j" horiz-adv-x="364" d="M-45 -182q29 -8 57 -8q64 0 64 142v1168h207v-1149q0 -186 -51 -266q-23 -35 -71 -62.5t-115 -27.5t-91 12v191zM76 1298v207h207v-207h-207z" />
+<glyph unicode="k" horiz-adv-x="641" d="M82 0v1505h207v-714h10l113 329h186l-149 -364l188 -756h-199l-102 453l-4 16h-10l-33 -82v-387h-207z" />
+<glyph unicode="l" horiz-adv-x="370" d="M82 0v1505h207v-1505h-207z" />
+<glyph unicode="m" horiz-adv-x="1021" d="M82 0v1120h207v-94q2 0 33 30q80 81 139 81q100 0 139 -125q125 125 194.5 125t109.5 -69t40 -150v-918h-194v887q-1 49 -56 49q-41 0 -78 -53v-883h-194v887q0 49 -55 49q-41 0 -78 -53v-883h-207z" />
+<glyph unicode="n" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="o" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="p" horiz-adv-x="686" d="M82 -385v1505h207v-73q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="q" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v73h207v-1505h-207v459q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 21.5t19.5 46.5v628q0 29 -19.5 48.5t-42 19.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="r" horiz-adv-x="503" d="M82 0v1120h207v-125q8 41 58.5 91.5t148.5 50.5v-230q-34 11 -77 11t-86.5 -39t-43.5 -101v-778h-207z" />
+<glyph unicode="s" horiz-adv-x="630" d="M37 326h192q0 -170 97 -170q71 0 71 131q0 78 -129 202q-68 66 -98.5 99t-64 101.5t-33.5 134t12 114.5t39 95q59 100 201 104h11q161 0 211 -105q42 -86 42 -198h-193q0 131 -67 131q-63 -2 -64 -131q0 -33 23.5 -73t45 -62.5t66.5 -65.5q190 -182 191 -342 q0 -123 -64.5 -215t-199.5 -92q-197 0 -260 170q-29 76 -29 172z" />
+<glyph unicode="t" horiz-adv-x="501" d="M20 934v186h105v277h207v-277h141v-186h-141v-557q0 -184 65 -184l76 8v-203q-45 -14 -112 -14t-114.5 28.5t-70 64.5t-34.5 96q-17 79 -17 187v574h-105z" />
+<glyph unicode="u" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5z" />
+<glyph unicode="v" horiz-adv-x="602" d="M16 1120h201l68 -649l8 -72h16l76 721h201l-183 -1120h-204z" />
+<glyph unicode="w" horiz-adv-x="905" d="M20 1120h189l65 -585l9 -64h12l96 649h123l86 -585l10 -64h13l73 649h189l-166 -1120h-172l-80 535l-10 63h-8l-91 -598h-172z" />
+<glyph unicode="x" horiz-adv-x="618" d="M16 0l193 578l-176 542h194l74 -262l6 -31h4l6 31l74 262h195l-176 -542l192 -578h-201l-84 283l-6 30h-4l-6 -30l-84 -283h-201z" />
+<glyph unicode="y" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5z" />
+<glyph unicode="z" horiz-adv-x="532" d="M12 0v168l285 764h-240v188h459v-168l-285 -764h285v-188h-504z" />
+<glyph unicode="{" horiz-adv-x="688" d="M61 453v163q72 0 102 49.5t30 90.5v397q0 223 96 298t342 71v-172q-135 2 -188.5 -38t-53.5 -159v-397q0 -143 -127 -221q127 -82 127 -222v-397q0 -119 53.5 -159t188.5 -38v-172q-246 -4 -342 71t-96 298v397q0 57 -41 97.5t-91 42.5z" />
+<glyph unicode="|" horiz-adv-x="356" d="M82 -512v2204h192v-2204h-192z" />
+<glyph unicode="}" horiz-adv-x="688" d="M57 -281q135 -2 188.5 38t53.5 159v397q0 139 127 222q-127 78 -127 221v397q0 119 -53 159t-189 38v172q246 4 342.5 -71t96.5 -298v-397q0 -63 41 -101.5t90 -38.5v-163q-72 -4 -101.5 -52.5t-29.5 -87.5v-397q0 -223 -96.5 -298t-342.5 -71v172z" />
+<glyph unicode="~" horiz-adv-x="1280" d="M113 1352q35 106 115 200q34 41 94.5 74t121 33t116.5 -18.5t82 -33t83 -51.5q106 -72 174 -71q109 0 178 153l13 29l135 -57q-63 -189 -206 -276q-56 -34 -120 -34q-121 0 -272 101q-115 74 -178.5 74t-113.5 -45.5t-69 -90.5l-18 -45z" />
+<glyph unicode="&#xa1;" horiz-adv-x="387" d="M74 -385l55 1100h129l55 -1100h-239zM86 893v227h215v-227h-215z" />
+<glyph unicode="&#xa2;" horiz-adv-x="636" d="M66 508v489q0 297 208 328v242h123v-244q98 -16 144.5 -88t46.5 -227v-88h-189v135q0 90 -72.5 90t-72.5 -90v-604q0 -90 72 -91q74 0 73 91v155h189v-108q0 -156 -46 -228.5t-145 -89.5v-303h-123v301q-209 31 -208 330z" />
+<glyph unicode="&#xa3;" horiz-adv-x="817" d="M4 63q8 20 23.5 53.5t70 91.5t117.5 68q37 111 37 189t-31 184h-188v137h147l-6 21q-78 254 -78 333t15.5 140t48.5 116q72 122 231 126q190 4 267 -126q65 -108 65 -276h-213q0 201 -115 197q-47 -2 -68.5 -51t-21.5 -139.5t70 -315.5l6 -25h211v-137h-174 q25 -100 24.5 -189t-57.5 -204q16 -8 44 -24q59 -35 89 -35q74 4 82 190l188 -22q-12 -182 -81.5 -281.5t-169.5 -99.5q-51 0 -143.5 51t-127.5 51t-63.5 -25.5t-40.5 -52.5l-12 -24z" />
+<glyph unicode="&#xa5;" horiz-adv-x="720" d="M25 1505h217l110 -481l6 -14h4l7 14l110 481h217l-196 -753h147v-138h-176v-137h176v-137h-176v-340h-221v340h-176v137h176v137h-176v138h147z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1024" d="M272 1305v200h191v-200h-191zM561 1305v200h191v-200h-191z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM627 487v531q0 122 97 174q40 22 95 22 q147 0 182 -147l7 -49v-125h-138v142q0 11 -12 28.5t-37 17.5q-47 -2 -49 -63v-531q0 -63 49 -63q53 2 49 63v125h138v-125q0 -68 -40 -127q-18 -26 -57 -47.5t-108.5 -21.5t-117.5 49t-54 98z" />
+<glyph unicode="&#xaa;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xad;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#xae;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM625 313v879h196q231 0 232 -258 q0 -76 -16.5 -125t-71.5 -96l106 -400h-151l-95 365h-55v-365h-145zM770 805h45q43 0 65.5 21.5t27.5 45t5 61.5t-5 62.5t-27.5 46t-65.5 21.5h-45v-258z" />
+<glyph unicode="&#xaf;" horiz-adv-x="1024" d="M313 1315v162h398v-162h-398z" />
+<glyph unicode="&#xb2;" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="&#xb3;" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="&#xb4;" horiz-adv-x="1024" d="M410 1305l106 184h215l-162 -184h-159z" />
+<glyph unicode="&#xb7;" horiz-adv-x="215" d="M0 649v228h215v-228h-215z" />
+<glyph unicode="&#xb8;" horiz-adv-x="1024" d="M426 -111h172v-141l-45 -133h-104l40 133h-63v141z" />
+<glyph unicode="&#xb9;" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="&#xba;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="&#xbf;" horiz-adv-x="645" d="M41 -106q0 82 80 219l57 95q18 32 42 106.5t24 144.5v256h190v-256q0 -102 -24.5 -195.5t-48 -140.5t-65.5 -118t-50 -104.5t9 -67.5t60 -35t78 48.5t49 98.5l179 -84q-24 -66 -78 -132q-104 -126 -236 -122q-163 4 -220 115q-46 90 -46 172zM231 893v227h215v-227h-215z " />
+<glyph unicode="&#xc0;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM141 1823h215l107 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc1;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM293 1638l106 185h215l-161 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc2;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM133 1638l141 185h220l141 -185h-189l-63 72l-61 -72h-189zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc3;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM184 1632v152q49 39 95.5 39t104.5 -18.5t100.5 -19.5t97.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-98 19.5t-102 -33zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc4;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM143 1638v201h191v-201h-191zM307 541h152l-64 475l-6 39h-12zM432 1638v201h191v-201h-191z" />
+<glyph unicode="&#xc5;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM231 1761.5q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM307 541h152l-64 475l-6 39h-12zM309 1761.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50 t-23.5 50t-52.5 21.5t-52.5 -21.5t-23.5 -50z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1099" d="M16 0l420 1505h623v-227h-285v-395h205v-242h-205v-414h285v-227h-506v307h-227l-90 -307h-220zM393 541h160v514h-10z" />
+<glyph unicode="&#xc7;" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM268 -111v-141h64l-41 -133h104l45 133v141h-172z" />
+<glyph unicode="&#xc8;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM111 1823h215l106 -185h-160z" />
+<glyph unicode="&#xc9;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM236 1638l106 185h215l-162 -185h-159z" />
+<glyph unicode="&#xca;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM84 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xcb;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM94 1638v201h191v-201h-191zM383 1638v201h190v-201h-190z" />
+<glyph unicode="&#xcc;" horiz-adv-x="401" d="M-6 1823h215l106 -185h-159zM98 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcd;" horiz-adv-x="401" d="M82 0v1505h221v-1505h-221zM86 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xce;" horiz-adv-x="370" d="M-66 1638l142 185h219l141 -185h-188l-64 72l-61 -72h-189zM74 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcf;" horiz-adv-x="372" d="M-53 1638v201h190v-201h-190zM76 0v1505h221v-1505h-221zM236 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd0;" horiz-adv-x="761" d="M20 655v228h62v622h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174v655h-62zM303 221q117 0 141.5 81t22.5 452q2 371 -22.5 450.5t-141.5 79.5v-401h84v-228h-84v-434z " />
+<glyph unicode="&#xd1;" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203zM207 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39t-102.5 19.5t-100 19.5t-99.5 -33z" />
+<glyph unicode="&#xd2;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM121 1823h215l106 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd3;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM285 1638l106 185h215l-162 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5 t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd4;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM113 1638l141 185h219l141 -185h-188l-64 72l-61 -72h-188zM289 309q0 -46 19.5 -78 t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd5;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM164 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39 t-102.5 19.5t-100 19.5t-99.5 -33zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd6;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM123 1638v201h190v-201h-190zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887zM412 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd8;" d="M59 -20l47 157q-36 74 -36 148l-2 24v887q0 42 17 106t45 107t88.5 78t148 35t153.5 -43l15 47h122l-45 -150q43 -84 43 -155l2 -25v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-150.5 -34.5t-153 43l-15 -47h-129zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v488zM289 727l147 479q-8 100 -74 101q-35 0 -53 -28t-18 -54l-2 -29v-469z" />
+<glyph unicode="&#xd9;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM145 1823h215l107 -185h-160z" />
+<glyph unicode="&#xda;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM307 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xdb;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM125 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xdc;" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175zM135 1638v201h191v-201h-191zM424 1638v201h190v-201h-190z" />
+<glyph unicode="&#xdd;" horiz-adv-x="704" d="M16 1505l226 -864v-641h221v641l225 864h-217l-111 -481l-6 -14h-4l-6 14l-111 481h-217zM254 1638l106 185h215l-161 -185h-160z" />
+<glyph unicode="&#xde;" d="M82 0v1505h219v-241h2q166 0 277.5 -105.5t111.5 -345.5t-111.5 -346.5t-277.5 -106.5v-360h-221zM303 586q102 0 134 45t32 175t-33 181t-133 51v-452z" />
+<glyph unicode="&#xdf;" horiz-adv-x="733" d="M66 0v1235q0 123 70.5 205t206.5 82t204.5 -81t68.5 -197t-88 -181q152 -88 152 -488q0 -362 -87 -475q-46 -59 -102.5 -79.5t-144.5 -20.5v193q45 0 70 25q57 57 57 357q0 316 -57 377q-25 27 -70 27v141q35 0 60.5 33t25.5 84q0 100 -86 100q-74 0 -74 -102v-1235h-206 z" />
+<glyph unicode="&#xe0;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1489h215 l107 -184h-160zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe1;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xe2;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM90 1305 l141 184h220l141 -184h-189l-63 71l-61 -71h-189zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe3;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM143 1305v151 q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe4;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1305v200 h191v-200h-191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM391 1305v200h191v-200h-191z" />
+<glyph unicode="&#xe5;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM188 1421.5 q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM266 1421.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50t-23.5 50t-52.5 21.5t-52.5 -21.5 t-23.5 -50z" />
+<glyph unicode="&#xe6;" horiz-adv-x="989" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t197.5 88q84 0 152 -52q66 51 162 52q199 0 251 -197q14 -51 15 -92v-326h-342v-256q0 -60 38 -88q17 -12 38 -12q70 10 73 113v122h193v-129 q0 -37 -16.5 -93t-41 -95t-80 -69.5t-130.5 -30.5q-158 0 -226 131q-102 -131 -221 -131q-59 0 -112.5 60t-53.5 191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM588 684h149v158q0 48 -19.5 81t-53 33t-53 -28.5t-21.5 -57.5l-2 -28v-158z " />
+<glyph unicode="&#xe7;" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331zM238 -111v-141h63l-41 -133h105l45 133v141h-172z " />
+<glyph unicode="&#xe8;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM102 1489h215l107 -184 h-160zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xe9;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xea;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM80 1305l141 184h219 l142 -184h-189l-63 71l-62 -71h-188zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xeb;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM90 1305v200h191v-200 h-191zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xec;" horiz-adv-x="370" d="M-33 1489h215l107 -184h-160zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xed;" horiz-adv-x="370" d="M82 0h207v1120h-207v-1120zM82 1305l106 184h215l-161 -184h-160z" />
+<glyph unicode="&#xee;" horiz-adv-x="370" d="M-66 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xef;" horiz-adv-x="372" d="M-53 1305v200h190v-200h-190zM82 0v1120h207v-1120h-207zM236 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf0;" horiz-adv-x="673" d="M76 279v579q0 279 172 279q63 0 155 -78q-12 109 -51 203l-82 -72l-55 63l100 88l-45 66l109 100q25 -27 53 -61l94 82l56 -66l-101 -88q125 -201 125 -446v-656q0 -102 -56 -188q-26 -39 -80 -69.5t-129 -30.5t-130 30.5t-80 73.5q-53 91 -53 160zM270 267.5 q-2 -11.5 2 -29t10 -34.5q16 -38 58 -38q70 10 72 113v563q-2 0 0 11t-2 28.5t-10 34.5q-16 40 -60 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf1;" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207zM147 1305v151q49 39 95.5 39t105 -18.5t97 -19.5t100.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#xf2;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM98 1489h215l107 -184h-160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf3;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5 t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM260 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xf4;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM78 1305l141 184h219l142 -184h-189l-63 71l-62 -71h-188zM258 267.5q-2 -11.5 2 -29 t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf5;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM131 1305v151q49 39 95.5 39t104.5 -18.5t98.5 -19.5t98.5 32v-152q-51 -39 -95 -39 t-102 19.5t-101 19.5t-99 -32zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf6;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM90 1305v200h191v-200h-191zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf8;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t118 32t117.5 -19l21 80h75l-30 -121q88 -84 94 -229v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-120.5 -30.5t-112 16l-20 -78h-80l31 121q-41 39 -64.5 97.5t-25.5 97.5zM258 436l125 486q-18 35 -55 34q-68 -10 -70 -114 v-406zM274 197q17 -31 54 -31q70 10 71 113v403z" />
+<glyph unicode="&#xf9;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM113 1489h215l106 -184h-160z" />
+<glyph unicode="&#xfa;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM274 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfb;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM94 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189z" />
+<glyph unicode="&#xfc;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM106 1305v200h191v-200h-191zM395 1305v200h191v-200h-191z" />
+<glyph unicode="&#xfd;" horiz-adv-x="634" d="M25 1120l190 -1153q0 -68 -36 -123t-97 -61l-49 4v-184q70 -4 92 -4q115 0 192.5 95t94.5 222l198 1204h-202l-82 -688l-4 -57h-9l-4 57l-82 688h-202zM231 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfe;" horiz-adv-x="686" d="M82 -385v1890h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="&#xff;" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5zM78 1305v200h190v-200h-190zM367 1305v200h190v-200h-190z" />
+<glyph unicode="&#x152;" horiz-adv-x="983" d="M68 309v887q0 41 17 101.5t45 100.5t88.5 73.5t143.5 33.5h580v-227h-285v-395h205v-242h-205v-414h285v-227h-580q-84 0 -144 31.5t-88 78.5q-55 91 -60 169zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v901q-6 96 -74 97q-35 0 -53 -28t-18 -54l-2 -29 v-887z" />
+<glyph unicode="&#x153;" horiz-adv-x="995" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t145.5 32t156 -60q66 59 170 60q199 0 252 -197q14 -51 14 -92v-326h-342v-250q0 -46 22.5 -76t53.5 -30q70 10 73 113v122h193v-129q0 -37 -16.5 -93t-41 -95t-80 -69.5t-146 -30.5t-154.5 57q-68 -57 -156 -57t-143.5 30.5 t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM594 684h149v158q0 48 -19 81t-58 33t-55.5 -37.5t-16.5 -70.5v-164z" />
+<glyph unicode="&#x178;" horiz-adv-x="704" d="M16 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641zM113 1638v201h190v-201h-190zM401 1638v201h191v-201h-191z" />
+<glyph unicode="&#x2c6;" horiz-adv-x="1021" d="M260 1305l141 184h220l141 -184h-189l-63 71l-61 -71h-189z" />
+<glyph unicode="&#x2dc;" horiz-adv-x="1024" d="M313 1305v151q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#x2000;" horiz-adv-x="952" />
+<glyph unicode="&#x2001;" horiz-adv-x="1905" />
+<glyph unicode="&#x2002;" horiz-adv-x="952" />
+<glyph unicode="&#x2003;" horiz-adv-x="1905" />
+<glyph unicode="&#x2004;" horiz-adv-x="635" />
+<glyph unicode="&#x2005;" horiz-adv-x="476" />
+<glyph unicode="&#x2006;" horiz-adv-x="317" />
+<glyph unicode="&#x2007;" horiz-adv-x="317" />
+<glyph unicode="&#x2008;" horiz-adv-x="238" />
+<glyph unicode="&#x2009;" horiz-adv-x="381" />
+<glyph unicode="&#x200a;" horiz-adv-x="105" />
+<glyph unicode="&#x2010;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2011;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2012;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2013;" horiz-adv-x="806" d="M74 649v195h659v-195h-659z" />
+<glyph unicode="&#x2014;" horiz-adv-x="972" d="M74 649v195h825v-195h-825z" />
+<glyph unicode="&#x2018;" horiz-adv-x="309" d="M49 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x2019;" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="&#x201a;" horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="&#x201c;" horiz-adv-x="624" d="M53 1012v227l113 266h102l-71 -266h71v-227h-215zM356 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x201d;" horiz-adv-x="624" d="M53 1012l72 266h-72v227h215v-227l-112 -266h-103zM356 1012l72 266h-72v227h215v-227l-112 -266h-103z" />
+<glyph unicode="&#x201e;" horiz-adv-x="624" d="M53 0v227h215v-227l-112 -266h-103l72 266h-72zM356 0v227h215v-227l-112 -266h-103l72 266h-72z" />
+<glyph unicode="&#x2022;" horiz-adv-x="663" d="M82 815q0 104 72.5 177t177 73t177.5 -72.5t73 -177t-73 -177.5t-177 -73t-177 73t-73 177z" />
+<glyph unicode="&#x2026;" horiz-adv-x="964" d="M53 0v227h215v-227h-215zM375 0v227h215v-227h-215zM696 0v227h215v-227h-215z" />
+<glyph unicode="&#x202f;" horiz-adv-x="381" />
+<glyph unicode="&#x2039;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="&#x203a;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="&#x205f;" horiz-adv-x="476" />
+<glyph unicode="&#x20ac;" horiz-adv-x="813" d="M53 547v137h107v137h-107v137h107v238q0 42 17.5 106t45 107t88 78t144.5 35t144 -34t88 -81q53 -90 61 -178l2 -33v-84h-207v84q-2 0 0 11.5t-3 27.5t-12 33q-18 39 -69 39q-70 -10 -78 -111v-238h233v-137h-233v-137h233v-137h-233v-238q0 -43 21.5 -76.5t59.5 -33.5 t58.5 27.5t20.5 56.5l2 26v84h207v-84q0 -38 -17.5 -104t-45.5 -109t-88 -77.5t-144 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175l-2 35v238h-107z" />
+<glyph unicode="&#x2122;" horiz-adv-x="937" d="M74 1401v104h321v-104h-104v-580h-113v580h-104zM440 821v684h138l67 -319h6l68 319h137v-684h-104v449l-78 -449h-51l-80 449v-449h-103z" />
+<glyph unicode="&#xe000;" horiz-adv-x="1120" d="M0 0v1120h1120v-1120h-1120z" />
+<glyph unicode="&#xfb01;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2v-184q-41 12 -91 12t-69.5 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h358v-1120h-207v934h-151v-934h-207v934h-105z" />
+<glyph unicode="&#xfb02;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2h164v-1505h-207v1329q-37 4 -67.5 4t-50 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="&#xfb03;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1120h207v-1120h-207zM1032 1298v207h207v-207h-207z" />
+<glyph unicode="&#xfb04;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1505h207v-1505h-207z" />
+</font>
+</defs></svg> 
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.ttf b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.ttf differ
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.woff b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.woff
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic-webfont.woff differ
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic_license b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic_license
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/lib/font/league_gothic_license
@@ -0,0 +1,2 @@
+SIL Open Font License (OFL)
+http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/js/classList.js b/docs/slides/BOS14/_support/reveal.js/lib/js/classList.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/lib/js/classList.js
@@ -0,0 +1,2 @@
+/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
+if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.className),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.className=this.toString()}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(o){o+="";if(g(this,o)===-1){this.push(o);this._updateClassName()}};e.remove=function(p){p+="";var o=g(this,p);if(o!==-1){this.splice(o,1);this._updateClassName()}};e.toggle=function(o){o+="";if(g(this,o)===-1){this.add(o)}else{this.remove(o)}};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/js/head.min.js b/docs/slides/BOS14/_support/reveal.js/lib/js/head.min.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/lib/js/head.min.js
@@ -0,0 +1,8 @@
+/**
+    Head JS     The only script in your <HEAD>
+    Copyright   Tero Piirainen (tipiirai)
+    License     MIT / http://bit.ly/mit-license
+    Version     0.96
+
+    http://headjs.com
+*/(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c<a.length;c++)b.call(a,a[c],c)}}function r(a){var b;if(typeof a=="object")for(var c in a)a[c]&&(b={name:c,url:a[c]});else b={name:q(a),url:a};var d=h[b.name];if(d&&d.url===b.url)return d;h[b.name]=b;return b}function q(a){var b=a.split("/"),c=b[b.length-1],d=c.indexOf("?");return d!=-1?c.substring(0,d):c}function p(a){a._done||(a(),a._done=1)}var b=a.documentElement,c,d,e=[],f=[],g={},h={},i=a.createElement("script").async===!0||"MozAppearance"in a.documentElement.style||window.opera,j=window.head_conf&&head_conf.head||"head",k=window[j]=window[j]||function(){k.ready.apply(null,arguments)},l=1,m=2,n=3,o=4;i?k.js=function(){var a=arguments,b=a[a.length-1],c={};t(b)||(b=null),s(a,function(d,e){d!=b&&(d=r(d),c[d.name]=d,x(d,b&&e==a.length-2?function(){u(c)&&p(b)}:null))});return k}:k.js=function(){var a=arguments,b=[].slice.call(a,1),d=b[0];if(!c){f.push(function(){k.js.apply(null,a)});return k}d?(s(b,function(a){t(a)||w(r(a))}),x(r(a[0]),t(d)?d:function(){k.js.apply(null,b)})):x(r(a[0]));return k},k.ready=function(b,c){if(b==a){d?p(c):e.push(c);return k}t(b)&&(c=b,b="ALL");if(typeof b!="string"||!t(c))return k;var f=h[b];if(f&&f.state==o||b=="ALL"&&u()&&d){p(c);return k}var i=g[b];i?i.push(c):i=g[b]=[c];return k},k.ready(a,function(){u()&&s(g.ALL,function(a){p(a)}),k.feature&&k.feature("domloaded",!0)});if(window.addEventListener)a.addEventListener("DOMContentLoaded",z,!1),window.addEventListener("load",z,!1);else if(window.attachEvent){a.attachEvent("onreadystatechange",function(){a.readyState==="complete"&&z()});var A=1;try{A=window.frameElement}catch(B){}!A&&b.doScroll&&function(){try{b.doScroll("left"),z()}catch(a){setTimeout(arguments.callee,1);return}}(),window.attachEvent("onload",z)}!a.readyState&&a.addEventListener&&(a.readyState="loading",a.addEventListener("DOMContentLoaded",handler=function(){a.removeEventListener("DOMContentLoaded",handler,!1),a.readyState="complete"},!1)),setTimeout(function(){c=!0,s(f,function(a){a()})},300)})(document)
diff --git a/docs/slides/BOS14/_support/reveal.js/lib/js/html5shiv.js b/docs/slides/BOS14/_support/reveal.js/lib/js/html5shiv.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/lib/js/html5shiv.js
@@ -0,0 +1,7 @@
+document.createElement('header');
+document.createElement('nav');
+document.createElement('section');
+document.createElement('article');
+document.createElement('aside');
+document.createElement('footer');
+document.createElement('hgroup');
diff --git a/docs/slides/BOS14/_support/reveal.js/package.json b/docs/slides/BOS14/_support/reveal.js/package.json
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/package.json
@@ -0,0 +1,46 @@
+{
+  "name": "reveal.js",
+  "version": "2.6.2",
+  "description": "The HTML Presentation Framework",
+  "homepage": "http://lab.hakim.se/reveal-js",
+  "subdomain": "revealjs",
+  "scripts": {
+    "test": "grunt test",
+    "start": ""
+  },
+  "author": {
+    "name": "Hakim El Hattab",
+    "email": "hakim.elhattab@gmail.com",
+    "web": "http://hakim.se"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/hakimel/reveal.js.git"
+  },
+  "engines": {
+    "node": "~0.8.0"
+  },
+  "dependencies": {
+    "underscore": "~1.5.1",
+    "express": "~2.5.9",
+    "mustache": "~0.7.2",
+    "socket.io": "~0.9.13"
+  },
+  "devDependencies": {
+    "grunt-contrib-qunit": "~0.2.2",
+    "grunt-contrib-jshint": "~0.6.4",
+    "grunt-contrib-cssmin": "~0.4.1",
+    "grunt-contrib-uglify": "~0.2.4",
+    "grunt-contrib-watch": "~0.5.3",
+    "grunt-contrib-sass": "~0.5.0",
+    "grunt-contrib-connect": "~0.4.1",
+    "grunt-zip": "~0.7.0",
+    "grunt": "~0.4.0"
+  },
+  "licenses": [
+    {
+      "type": "MIT",
+      "url": "https://github.com/hakimel/reveal.js/blob/master/LICENSE"
+    }
+  ]
+}
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/highlight/highlight.js b/docs/slides/BOS14/_support/reveal.js/plugin/highlight/highlight.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/highlight/highlight.js
@@ -0,0 +1,32 @@
+// START CUSTOM REVEAL.JS INTEGRATION
+(function() {
+	if( typeof window.addEventListener === 'function' ) {
+		var hljs_nodes = document.querySelectorAll( 'pre code' );
+
+		for( var i = 0, len = hljs_nodes.length; i < len; i++ ) {
+			var element = hljs_nodes[i];
+
+			// trim whitespace if data-trim attribute is present
+			if( element.hasAttribute( 'data-trim' ) && typeof element.innerHTML.trim === 'function' ) {
+				element.innerHTML = element.innerHTML.trim();
+			}
+
+			// Now escape html unless prevented by author
+			if( ! element.hasAttribute( 'data-noescape' )) {
+				element.innerHTML = element.innerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;");
+			}
+
+			// re-highlight when focus is lost (for edited code)
+			element.addEventListener( 'focusout', function( event ) {
+				hljs.highlightBlock( event.currentTarget );
+			}, false );
+		}
+	}
+})();
+// END CUSTOM REVEAL.JS INTEGRATION
+
+// highlight.js build includes support for:
+// All languages in master + fsharp
+
+
+var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName=="CODE"){return o}if(!(o.nodeType==3&&o.nodeValue.match(/\s+/))){break}}}function h(p,o){return Array.prototype.map.call(p.childNodes,function(q){if(q.nodeType==3){return o?q.nodeValue.replace(/\n/g,""):q.nodeValue}if(q.nodeName=="BR"){return"\n"}return h(q,o)}).join("")}function a(q){var p=(q.className+" "+(q.parentNode?q.parentNode.className:"")).split(/\s+/);p=p.map(function(r){return r.replace(/^language-/,"")});for(var o=0;o<p.length;o++){if(e[p[o]]||p[o]=="no-highlight"){return p[o]}}}function c(q){var o=[];(function p(r,s){for(var t=r.firstChild;t;t=t.nextSibling){if(t.nodeType==3){s+=t.nodeValue.length}else{if(t.nodeName=="BR"){s+=1}else{if(t.nodeType==1){o.push({event:"start",offset:s,node:t});s=p(t,s);o.push({event:"stop",offset:s,node:t})}}}}return s})(q,0);return o}function j(x,v,w){var p=0;var y="";var r=[];function t(){if(x.length&&v.length){if(x[0].offset!=v[0].offset){return(x[0].offset<v[0].offset)?x:v}else{return v[0].event=="start"?x:v}}else{return x.length?x:v}}function s(A){function z(B){return" "+B.nodeName+'="'+l(B.value)+'"'}return"<"+A.nodeName+Array.prototype.map.call(A.attributes,z).join("")+">"}while(x.length||v.length){var u=t().splice(0,1)[0];y+=l(w.substr(p,u.offset-p));p=u.offset;if(u.event=="start"){y+=s(u.node);r.push(u.node)}else{if(u.event=="stop"){var o,q=r.length;do{q--;o=r[q];y+=("</"+o.nodeName.toLowerCase()+">")}while(o!=u.node);r.splice(q,1);while(q<r.length){y+=s(r[q]);q++}}}}return y+l(w.substr(p))}function f(r){function o(s){return(s&&s.source)||s}function p(t,s){return RegExp(o(t),"m"+(r.cI?"i":"")+(s?"g":""))}function q(z,x){if(z.compiled){return}z.compiled=true;var u=[];if(z.k){var s={};function A(B,t){t.split(" ").forEach(function(C){var D=C.split("|");s[D[0]]=[B,D[1]?Number(D[1]):1];u.push(D[0])})}z.lR=p(z.l||hljs.IR+"(?!\\.)",true);if(typeof z.k=="string"){A("keyword",z.k)}else{for(var y in z.k){if(!z.k.hasOwnProperty(y)){continue}A(y,z.k[y])}}z.k=s}if(x){if(z.bWK){z.b="\\b("+u.join("|")+")\\b(?!\\.)\\s*"}z.bR=p(z.b?z.b:"\\B|\\b");if(!z.e&&!z.eW){z.e="\\B|\\b"}if(z.e){z.eR=p(z.e)}z.tE=o(z.e)||"";if(z.eW&&x.tE){z.tE+=(z.e?"|":"")+x.tE}}if(z.i){z.iR=p(z.i)}if(z.r===undefined){z.r=1}if(!z.c){z.c=[]}for(var w=0;w<z.c.length;w++){if(z.c[w]=="self"){z.c[w]=z}q(z.c[w],z)}if(z.starts){q(z.starts,x)}var v=[];for(var w=0;w<z.c.length;w++){v.push(o(z.c[w].b))}if(z.tE){v.push(o(z.tE))}if(z.i){v.push(o(z.i))}z.t=v.length?p(v.join("|"),true):{exec:function(t){return null}}}q(r)}function d(E,F,C){function o(r,N){for(var M=0;M<N.c.length;M++){var L=N.c[M].bR.exec(r);if(L&&L.index==0){return N.c[M]}}}function s(L,r){if(L.e&&L.eR.test(r)){return L}if(L.eW){return s(L.parent,r)}}function t(r,L){return !C&&L.i&&L.iR.test(r)}function y(M,r){var L=G.cI?r[0].toLowerCase():r[0];return M.k.hasOwnProperty(L)&&M.k[L]}function H(){var L=l(w);if(!A.k){return L}var r="";var O=0;A.lR.lastIndex=0;var M=A.lR.exec(L);while(M){r+=L.substr(O,M.index-O);var N=y(A,M);if(N){v+=N[1];r+='<span class="'+N[0]+'">'+M[0]+"</span>"}else{r+=M[0]}O=A.lR.lastIndex;M=A.lR.exec(L)}return r+L.substr(O)}function z(){if(A.sL&&!e[A.sL]){return l(w)}var r=A.sL?d(A.sL,w):g(w);if(A.r>0){v+=r.keyword_count;B+=r.r}return'<span class="'+r.language+'">'+r.value+"</span>"}function K(){return A.sL!==undefined?z():H()}function J(M,r){var L=M.cN?'<span class="'+M.cN+'">':"";if(M.rB){x+=L;w=""}else{if(M.eB){x+=l(r)+L;w=""}else{x+=L;w=r}}A=Object.create(M,{parent:{value:A}})}function D(L,r){w+=L;if(r===undefined){x+=K();return 0}var N=o(r,A);if(N){x+=K();J(N,r);return N.rB?0:r.length}var O=s(A,r);if(O){var M=A;if(!(M.rE||M.eE)){w+=r}x+=K();do{if(A.cN){x+="</span>"}B+=A.r;A=A.parent}while(A!=O.parent);if(M.eE){x+=l(r)}w="";if(O.starts){J(O.starts,"")}return M.rE?0:r.length}if(t(r,A)){throw new Error('Illegal lexem "'+r+'" for mode "'+(A.cN||"<unnamed>")+'"')}w+=r;return r.length||1}var G=e[E];f(G);var A=G;var w="";var B=0;var v=0;var x="";try{var u,q,p=0;while(true){A.t.lastIndex=p;u=A.t.exec(F);if(!u){break}q=D(F.substr(p,u.index-p),u[0]);p=u.index+q}D(F.substr(p));return{r:B,keyword_count:v,value:x,language:E}}catch(I){if(I.message.indexOf("Illegal")!=-1){return{r:0,keyword_count:0,value:l(F)}}else{throw I}}}function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p in e){if(!e.hasOwnProperty(p)){continue}var r=d(p,s,false);r.language=p;if(r.keyword_count+r.r>q.keyword_count+q.r){q=r}if(r.keyword_count+r.r>o.keyword_count+o.r){q=o;o=r}}if(q.language){o.second_best=q}return o}function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\t)+)/gm,function(r,v,u,t){return v.replace(/\t/g,p)})}if(o){q=q.replace(/\n/g,"<br>")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}var w=t?d(t,v,true):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match("(\\s|^)(language-)?"+t+"(\\s|$)")){s=s?(s+" "+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagName("pre"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener("DOMContentLoaded",n,false);window.addEventListener("load",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES["1c"]=function(b){var f="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*";var c="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт";var e="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку  стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон";var a={cN:"dquote",b:'""'};var d={cN:"string",b:'"',e:'"|$',c:[a],r:0};var g={cN:"string",b:"\\|",e:'"|$',c:[a]};return{cI:true,l:f,k:{keyword:c,built_in:e},c:[b.CLCM,b.NM,d,g,{cN:"function",b:"(процедура|функция)",e:"$",l:f,k:"процедура функция",c:[{cN:"title",b:f},{cN:"tail",eW:true,c:[{cN:"params",b:"\\(",e:"\\)",l:f,k:"знач",c:[d,g]},{cN:"export",b:"экспорт",eW:true,l:f,k:"экспорт",c:[b.CLCM]}]},b.CLCM]},{cN:"preprocessor",b:"#",e:"$"},{cN:"date",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}}(hljs);hljs.LANGUAGES.actionscript=function(a){var d="[a-zA-Z_$][a-zA-Z0-9_$]*";var c="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";var e={cN:"rest_arg",b:"[.]{3}",e:d,r:10};var b={cN:"title",b:d};return{k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{cN:"package",bWK:true,e:"{",k:"package",c:[b]},{cN:"class",bWK:true,e:"{",k:"class interface",c:[{bWK:true,k:"extends implements"},b]},{cN:"preprocessor",bWK:true,e:";",k:"import include"},{cN:"function",bWK:true,e:"[{;]",k:"function",i:"\\S",c:[b,{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,e]},{cN:"type",b:":",e:c,r:10}]}]}}(hljs);hljs.LANGUAGES.apache=function(a){var b={cN:"number",b:"[\\$%]\\d+"};return{cI:true,k:{keyword:"acceptfilter acceptmutex acceptpathinfo accessfilename action addalt addaltbyencoding addaltbytype addcharset adddefaultcharset adddescription addencoding addhandler addicon addiconbyencoding addiconbytype addinputfilter addlanguage addmoduleinfo addoutputfilter addoutputfilterbytype addtype alias aliasmatch allow allowconnect allowencodedslashes allowoverride anonymous anonymous_logemail anonymous_mustgiveemail anonymous_nouserid anonymous_verifyemail authbasicauthoritative authbasicprovider authdbduserpwquery authdbduserrealmquery authdbmgroupfile authdbmtype authdbmuserfile authdefaultauthoritative authdigestalgorithm authdigestdomain authdigestnccheck authdigestnonceformat authdigestnoncelifetime authdigestprovider authdigestqop authdigestshmemsize authgroupfile authldapbinddn authldapbindpassword authldapcharsetconfig authldapcomparednonserver authldapdereferencealiases authldapgroupattribute authldapgroupattributeisdn authldapremoteuserattribute authldapremoteuserisdn authldapurl authname authnprovideralias authtype authuserfile authzdbmauthoritative authzdbmtype authzdefaultauthoritative authzgroupfileauthoritative authzldapauthoritative authzownerauthoritative authzuserauthoritative balancermember browsermatch browsermatchnocase bufferedlogs cachedefaultexpire cachedirlength cachedirlevels cachedisable cacheenable cachefile cacheignorecachecontrol cacheignoreheaders cacheignorenolastmod cacheignorequerystring cachelastmodifiedfactor cachemaxexpire cachemaxfilesize cacheminfilesize cachenegotiateddocs cacheroot cachestorenostore cachestoreprivate cgimapextension charsetdefault charsetoptions charsetsourceenc checkcaseonly checkspelling chrootdir contentdigest cookiedomain cookieexpires cookielog cookiename cookiestyle cookietracking coredumpdirectory customlog dav davdepthinfinity davgenericlockdb davlockdb davmintimeout dbdexptime dbdkeep dbdmax dbdmin dbdparams dbdpersist dbdpreparesql dbdriver defaulticon defaultlanguage defaulttype deflatebuffersize deflatecompressionlevel deflatefilternote deflatememlevel deflatewindowsize deny directoryindex directorymatch directoryslash documentroot dumpioinput dumpiologlevel dumpiooutput enableexceptionhook enablemmap enablesendfile errordocument errorlog example expiresactive expiresbytype expiresdefault extendedstatus extfilterdefine extfilteroptions fileetag filterchain filterdeclare filterprotocol filterprovider filtertrace forcelanguagepriority forcetype forensiclog gracefulshutdowntimeout group header headername hostnamelookups identitycheck identitychecktimeout imapbase imapdefault imapmenu include indexheadinsert indexignore indexoptions indexorderdefault indexstylesheet isapiappendlogtoerrors isapiappendlogtoquery isapicachefile isapifakeasync isapilognotsupported isapireadaheadbuffer keepalive keepalivetimeout languagepriority ldapcacheentries ldapcachettl ldapconnectiontimeout ldapopcacheentries ldapopcachettl ldapsharedcachefile ldapsharedcachesize ldaptrustedclientcert ldaptrustedglobalcert ldaptrustedmode ldapverifyservercert limitinternalrecursion limitrequestbody limitrequestfields limitrequestfieldsize limitrequestline limitxmlrequestbody listen listenbacklog loadfile loadmodule lockfile logformat loglevel maxclients maxkeepaliverequests maxmemfree maxrequestsperchild maxrequestsperthread maxspareservers maxsparethreads maxthreads mcachemaxobjectcount mcachemaxobjectsize mcachemaxstreamingbuffer mcacheminobjectsize mcacheremovalalgorithm mcachesize metadir metafiles metasuffix mimemagicfile minspareservers minsparethreads mmapfile mod_gzip_on mod_gzip_add_header_count mod_gzip_keep_workfiles mod_gzip_dechunk mod_gzip_min_http mod_gzip_minimum_file_size mod_gzip_maximum_file_size mod_gzip_maximum_inmem_size mod_gzip_temp_dir mod_gzip_item_include mod_gzip_item_exclude mod_gzip_command_version mod_gzip_can_negotiate mod_gzip_handle_methods mod_gzip_static_suffix mod_gzip_send_vary mod_gzip_update_static modmimeusepathinfo multiviewsmatch namevirtualhost noproxy nwssltrustedcerts nwsslupgradeable options order passenv pidfile protocolecho proxybadheader proxyblock proxydomain proxyerroroverride proxyftpdircharset proxyiobuffersize proxymaxforwards proxypass proxypassinterpolateenv proxypassmatch proxypassreverse proxypassreversecookiedomain proxypassreversecookiepath proxypreservehost proxyreceivebuffersize proxyremote proxyremotematch proxyrequests proxyset proxystatus proxytimeout proxyvia readmename receivebuffersize redirect redirectmatch redirectpermanent redirecttemp removecharset removeencoding removehandler removeinputfilter removelanguage removeoutputfilter removetype requestheader require rewritebase rewritecond rewriteengine rewritelock rewritelog rewriteloglevel rewritemap rewriteoptions rewriterule rlimitcpu rlimitmem rlimitnproc satisfy scoreboardfile script scriptalias scriptaliasmatch scriptinterpretersource scriptlog scriptlogbuffer scriptloglength scriptsock securelisten seerequesttail sendbuffersize serveradmin serveralias serverlimit servername serverpath serverroot serversignature servertokens setenv setenvif setenvifnocase sethandler setinputfilter setoutputfilter ssienableaccess ssiendtag ssierrormsg ssistarttag ssitimeformat ssiundefinedecho sslcacertificatefile sslcacertificatepath sslcadnrequestfile sslcadnrequestpath sslcarevocationfile sslcarevocationpath sslcertificatechainfile sslcertificatefile sslcertificatekeyfile sslciphersuite sslcryptodevice sslengine sslhonorciperorder sslmutex ssloptions sslpassphrasedialog sslprotocol sslproxycacertificatefile sslproxycacertificatepath sslproxycarevocationfile sslproxycarevocationpath sslproxyciphersuite sslproxyengine sslproxymachinecertificatefile sslproxymachinecertificatepath sslproxyprotocol sslproxyverify sslproxyverifydepth sslrandomseed sslrequire sslrequiressl sslsessioncache sslsessioncachetimeout sslusername sslverifyclient sslverifydepth startservers startthreads substitute suexecusergroup threadlimit threadsperchild threadstacksize timeout traceenable transferlog typesconfig unsetenv usecanonicalname usecanonicalphysicalport user userdir virtualdocumentroot virtualdocumentrootip virtualscriptalias virtualscriptaliasip win32disableacceptex xbithack",literal:"on off"},c:[a.HCM,{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",b]},b,{cN:"tag",b:"</?",e:">"},a.QSM]}}(hljs);hljs.LANGUAGES.applescript=function(a){var b=a.inherit(a.QSM,{i:""});var e={cN:"title",b:a.UIR};var d={cN:"params",b:"\\(",e:"\\)",c:["self",a.CNM,b]};var c=[{cN:"comment",b:"--",e:"$",},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",{b:"--",e:"$"}]},a.HCM];return{k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[b,a.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bWK:true,k:"on",i:"[${=;\\n]",c:[e,d]}].concat(c),i:"//"}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);hljs.LANGUAGES.asciidoc=function(a){return{c:[{cN:"comment",b:"^/{4,}\\n",e:"\\n/{4,}$",r:10},{cN:"comment",b:"^//",e:"$",r:0},{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"header",b:"^(={1,5}) .+?( \\1)?$",r:10},{cN:"header",b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$",r:10},{cN:"attribute",b:"^:.+?:",e:"\\s",eE:true,r:10},{cN:"attribute",b:"^\\[.+?\\]$",r:0},{cN:"blockquote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"label",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{cN:"horizontal_rule",b:"^'{4,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:true,c:[{b:"(link|image:?):",r:0},{cN:"link_url",b:"\\w",e:"[^\\[]+",r:0},{cN:"link_label",b:"\\[",e:"\\]",eB:true,eE:true,r:0}],r:10}]}}(hljs);hljs.LANGUAGES.avrasm=function(a){return{cI:true,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf"},c:[a.CBLCLM,{cN:"comment",b:";",e:"$"},a.CNM,a.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"label",b:"^[A-Za-z0-9_.$]+:"},{cN:"preprocessor",b:"#",e:"$"},{cN:"preprocessor",b:"\\.[a-zA-Z]+"},{cN:"localvars",b:"@[0-9]+"}]}}(hljs);hljs.LANGUAGES.axapta=function(a){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"{",i:":",k:"class interface",c:[{cN:"inheritance",bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]}]}}(hljs);hljs.LANGUAGES.bash=function(a){var c={cN:"variable",b:/\$[\w\d#@][\w\d_]*/};var b={cN:"variable",b:/\$\{(.*?)\}/};var e={cN:"string",b:/"/,e:/"/,c:[a.BE,c,b,{cN:"variable",b:/\$\(/,e:/\)/,c:a.BE}],r:0};var d={cN:"string",b:/'/,e:/'/,r:0};return{l:/-?[a-z]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[{cN:"title",b:/\w[\w\d_]*/}],r:0},a.HCM,a.NM,e,d,c,b]}}(hljs);hljs.LANGUAGES.brainfuck=function(a){return{c:[{cN:"comment",b:"[^\\[\\]\\.,\\+\\-<> \r\n]",eE:true,e:"[\\[\\]\\.,\\+\\-<> \r\n]",r:0},{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]"},{cN:"literal",b:"[\\+\\-]"}]}}(hljs);hljs.LANGUAGES.clojure=function(l){var e={built_in:"def cond apply if-not if-let if not not= = &lt; < > &lt;= <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for doseq dosync dotimes and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import intern refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! import use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if throw printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time ns assert re-find re-groups rand-int rand mod locking assert-valid-fdecl alias namespace resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! memfn to-array future future-call into-array aset gen-class reduce merge map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"};var f="[a-zA-Z_0-9\\!\\.\\?\\-\\+\\*\\/\\<\\=\\>\\&\\#\\$';]+";var a="[\\s:\\(\\{]+\\d+(\\.\\d+)?";var d={cN:"number",b:a,r:0};var j={cN:"string",b:'"',e:'"',c:[l.BE],r:0};var o={cN:"comment",b:";",e:"$",r:0};var n={cN:"collection",b:"[\\[\\{]",e:"[\\]\\}]"};var c={cN:"comment",b:"\\^"+f};var b={cN:"comment",b:"\\^\\{",e:"\\}"};var h={cN:"attribute",b:"[:]"+f};var m={cN:"list",b:"\\(",e:"\\)"};var g={eW:true,k:{literal:"true false nil"},r:0};var i={k:e,l:f,cN:"title",b:f,starts:g};m.c=[{cN:"comment",b:"comment"},i];g.c=[m,j,c,b,o,h,n,d];n.c=[m,j,c,o,h,n,d];return{i:"\\S",c:[o,m]}}(hljs);hljs.LANGUAGES.cmake=function(a){return{cI:true,k:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file",c:[{cN:"envvar",b:"\\${",e:"}"},a.HCM,a.QSM,a.NM]}}(hljs);hljs.LANGUAGES.coffeescript=function(c){var b={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module exports global window document"};var a="[A-Za-z$_][0-9A-Za-z$_]*";var f={cN:"title",b:a};var e={cN:"subst",b:"#\\{",e:"}",k:b,};var d=[c.BNM,c.inherit(c.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",b:"'''",e:"'''",c:[c.BE]},{cN:"string",b:"'",e:"'",c:[c.BE],r:0},{cN:"string",b:'"""',e:'"""',c:[c.BE,e]},{cN:"string",b:'"',e:'"',c:[c.BE,e],r:0},{cN:"regexp",b:"///",e:"///",c:[c.HCM]},{cN:"regexp",b:"//[gim]*",r:0},{cN:"regexp",b:"/\\S(\\\\.|[^\\n])*?/[gim]*(?=\\s|\\W|$)"},{cN:"property",b:"@"+a},{b:"`",e:"`",eB:true,eE:true,sL:"javascript"}];e.c=d;return{k:b,c:d.concat([{cN:"comment",b:"###",e:"###"},c.HCM,{cN:"function",b:"("+a+"\\s*=\\s*)?(\\(.*\\))?\\s*[-=]>",e:"[-=]>",rB:true,c:[f,{cN:"params",b:"\\(",rB:true,c:[{b:/\(/,e:/\)/,k:b,c:["self"].concat(d)}]}]},{cN:"class",bWK:true,k:"class",e:"$",i:"[:\\[\\]]",c:[{bWK:true,k:"extends",eW:true,i:":",c:[f]},f]},{cN:"attribute",b:a+":",e:":",rB:true,eE:true}])}}(hljs);hljs.LANGUAGES.cpp=function(a){var b={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long throw volatile static protected bool template mutable if public friend do return goto auto void enum else break new extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'\\\\?.",e:"'",i:"."},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},a.CNM,{cN:"preprocessor",b:"#",e:"$",c:[{b:"<",e:">",i:"\\n"},a.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,r:10,c:["self"]}]}}(hljs);hljs.LANGUAGES.cs=function(a){return{k:"abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async await ascending descending from get group into join let orderby partial select set value var where yield",c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"}]},a.CLCM,a.CBLCLM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},a.ASM,a.QSM,a.CNM]}}(hljs);hljs.LANGUAGES.css=function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.NM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}}(hljs);hljs.LANGUAGES.d=function(x){var b={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"};var c="(0|[1-9][\\d_]*)",q="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",h="0[bB][01_]+",v="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",y="0[xX]"+v,p="([eE][+-]?"+q+")",o="("+q+"(\\.\\d*|"+p+")|\\d+\\."+q+q+"|\\."+c+p+"?)",k="(0[xX]("+v+"\\."+v+"|\\.?"+v+")[pP][+-]?"+q+")",l="("+c+"|"+h+"|"+y+")",n="("+k+"|"+o+")";var z="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};";var m={cN:"number",b:"\\b"+l+"(L|u|U|Lu|LU|uL|UL)?",r:0};var j={cN:"number",b:"\\b("+n+"([fF]|L|i|[fF]i|Li)?|"+l+"(i|[fF]i|Li))",r:0};var s={cN:"string",b:"'("+z+"|.)",e:"'",i:"."};var r={b:z,r:0};var w={cN:"string",b:'"',c:[r],e:'"[cwd]?',r:0};var f={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5};var u={cN:"string",b:"`",e:"`[cwd]?"};var i={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10};var t={cN:"string",b:'q"\\{',e:'\\}"'};var e={cN:"shebang",b:"^#!",e:"$",r:5};var g={cN:"preprocessor",b:"#(line)",e:"$",r:5};var d={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"};var a={cN:"comment",b:"\\/\\+",c:["self"],e:"\\+\\/",r:10};return{l:x.UIR,k:b,c:[x.CLCM,x.CBLCLM,a,i,w,f,u,t,j,m,s,e,g,d]}}(hljs);hljs.LANGUAGES.delphi=function(b){var f="and safecall cdecl then string exports library not pascal set virtual file in array label packed end. index while const raise for to implementation with except overload destructor downto finally program exit unit inherited override if type until function do begin repeat goto nil far initialization object else var uses external resourcestring interface end finalization class asm mod case on shr shl of register xorwrite threadvar try record near stored constructor stdcall inline div out or procedure";var e="safecall stdcall pascal stored const implementation finalization except to finally program inherited override then exports string read not mod shr try div shl set library message packed index for near overload label downto exit public goto interface asm on of constructor or private array unit raise destructor var type until function else external with case default record while protected property procedure published and cdecl do threadvar file in if end virtual write far out begin repeat nil initialization object uses resourcestring class register xorwrite inline static";var a={cN:"comment",b:"{",e:"}",r:0};var g={cN:"comment",b:"\\(\\*",e:"\\*\\)",r:10};var c={cN:"string",b:"'",e:"'",c:[{b:"''"}],r:0};var d={cN:"string",b:"(#\\d+)+"};var h={cN:"function",bWK:true,e:"[:;]",k:"function constructor|10 destructor|10 procedure|10",c:[{cN:"title",b:b.IR},{cN:"params",b:"\\(",e:"\\)",k:f,c:[c,d]},a,g]};return{cI:true,k:f,i:'("|\\$[G-Zg-z]|\\/\\*|</)',c:[a,g,b.CLCM,c,d,b.NM,h,{cN:"class",b:"=\\bclass\\b",e:"end;",k:e,c:[c,d,a,g,b.CLCM,h]}]}}(hljs);hljs.LANGUAGES.diff=function(a){return{c:[{cN:"chunk",b:"^\\@\\@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +\\@\\@$",r:10},{cN:"chunk",b:"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$",r:10},{cN:"chunk",b:"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$",r:10},{cN:"header",b:"Index: ",e:"$"},{cN:"header",b:"=====",e:"=====$"},{cN:"header",b:"^\\-\\-\\-",e:"$"},{cN:"header",b:"^\\*{3} ",e:"$"},{cN:"header",b:"^\\+\\+\\+",e:"$"},{cN:"header",b:"\\*{5}",e:"\\*{5}$"},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}(hljs);hljs.LANGUAGES.django=function(c){function e(h,g){return(g==undefined||(!h.cN&&g.cN=="tag")||h.cN=="value")}function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}if(e(l,k)){m=b.concat(m)}if(m.length){g.c=m}}return g}var d={cN:"filter",b:"\\|[A-Za-z]+\\:?",k:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone",c:[{cN:"argument",b:'"',e:'"'}]};var b=[{cN:"template_comment",b:"{%\\s*comment\\s*%}",e:"{%\\s*endcomment\\s*%}"},{cN:"template_comment",b:"{#",e:"#}"},{cN:"template_tag",b:"{%",e:"%}",k:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor in ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup by as ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim",c:[d]},{cN:"variable",b:"{{",e:"}}",c:[d]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.dos=function(a){return{cI:true,k:{flow:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",keyword:"shift cd dir echo setlocal endlocal set pause copy",stream:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux",winutils:"ping net ipconfig taskkill xcopy ren del"},c:[{cN:"envvar",b:"%%[^ ]"},{cN:"envvar",b:"%[^ ]+?%"},{cN:"envvar",b:"![^ ]+?!"},{cN:"number",b:"\\b\\d+",r:0},{cN:"comment",b:"@?rem",e:"$"}]}}(hljs);hljs.LANGUAGES["erlang-repl"]=function(a){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},{cN:"comment",b:"%",e:"$"},{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a.ASM,a.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}}(hljs);hljs.LANGUAGES.erlang=function(i){var c="[a-z'][a-zA-Z0-9_']*";var o="("+c+":"+c+"|"+c+")";var f={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun let not of orelse|10 query receive rem try when xor",literal:"false true"};var l={cN:"comment",b:"%",e:"$",r:0};var e={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0};var g={b:"fun\\s+"+c+"/\\d+"};var n={b:o+"\\(",e:"\\)",rB:true,r:0,c:[{cN:"function_name",b:o,r:0},{b:"\\(",e:"\\)",eW:true,rE:true,r:0}]};var h={cN:"tuple",b:"{",e:"}",r:0};var a={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0};var m={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0};var b={b:"#",e:"}",i:".",r:0,rB:true,c:[{cN:"record_name",b:"#"+i.UIR,r:0},{b:"{",eW:true,r:0}]};var k={k:f,b:"(fun|receive|if|try|case)",e:"end"};k.c=[l,g,i.inherit(i.ASM,{cN:""}),k,n,i.QSM,e,h,a,m,b];var j=[l,g,k,n,i.QSM,e,h,a,m,b];n.c[1].c=j;h.c=j;b.c[1].c=j;var d={cN:"params",b:"\\(",e:"\\)",c:j};return{k:f,i:"(</|\\*=|\\+=|-=|/=|/\\*|\\*/|\\(\\*|\\*\\))",c:[{cN:"function",b:"^"+c+"\\s*\\(",e:"->",rB:true,i:"\\(|#|//|/\\*|\\\\|:",c:[d,{cN:"title",b:c}],starts:{e:";|\\.",k:f,c:j}},l,{cN:"pp",b:"^-",e:"\\.",r:0,eE:true,rB:true,l:"-"+i.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior",c:[d]},e,i.QSM,b,a,m,h]}}(hljs);hljs.LANGUAGES.fsharp=function(a){var b="'[a-zA-Z0-9_]+";return{k:"yield! return! let! do!abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun|10 function global if in inherit inline interface internal lazy let match member module mutable|10 namespace new null of open or override private public rec|10 return sig static struct then to true try type upcast use val void when while with yield",c:[{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},{cN:"comment",b:"//",e:"$",rB:true},{cN:"comment",b:"\\(\\*",e:"\\*\\)"},{cN:"class",bWK:true,e:"\\(|=|$",k:"type",c:[{cN:"title",b:a.UIR}]},{cN:"annotation",b:"\\[<",e:">\\]",r:10},{cN:"typeparam",b:"<",e:">",c:[{cN:"title",b:b}]},a.CLCM,a.CBLCLM,a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),a.CNM]}}(hljs);hljs.LANGUAGES.glsl=function(a){return{k:{keyword:"atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly",built_in:"gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffsetgl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse",literal:"true false"},i:'"',c:[a.CLCM,a.CBLCLM,a.CNM,{cN:"preprocessor",b:"#",e:"$"}]}}(hljs);hljs.LANGUAGES.go=function(a){var b={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer",constant:"true false iota nil",typename:"bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"string",b:"`",e:"`"},{cN:"number",b:"[^a-zA-Z_0-9](\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?",r:0},a.CNM]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.haml=function(a){return{cI:true,c:[{cN:"doctype",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},{cN:"comment",b:"^\\s*(-#|/).*$",r:0},{b:"^\\s*-(?!#)",starts:{e:"\\n",sL:"ruby"},r:0},{cN:"tag",b:"^\\s*%",c:[{cN:"title",b:"\\w+",r:0},{cN:"value",b:"[#\\.]\\w+",r:0},{b:"{\\s*",e:"\\s*}",eE:true,c:[{b:":\\w+\\s*=>",e:",\\s+",rB:true,eW:true,r:0,c:[{cN:"symbol",b:":\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0},{b:"\\(\\s*",e:"\\s*\\)",eE:true,c:[{b:"\\w+\\s*=",e:"\\s+",rB:true,eW:true,r:0,c:[{cN:"attribute",b:"\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0}],r:10},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"},r:0}]}}(hljs);hljs.LANGUAGES.handlebars=function(c){function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}m=d.concat(m);if(m.length){g.c=m}}return g}var b="each in with if else unless bindattr action collection debugger log outlet template unbound view yield";var e={cN:"variable",b:"[a-zA-Z.]+",k:b};var d=[{cN:"expression",b:"{{",e:"}}",c:[{cN:"begin-block",b:"#[a-zA-Z .]+",k:b},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z .]+",k:b},{cN:"variable",b:"[a-zA-Z.]+",k:b}]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.haskell=function(a){var d={cN:"type",b:"\\b[A-Z][\\w']*",r:0};var c={cN:"container",b:"\\(",e:"\\)",i:'"',c:[{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},{cN:"title",b:"[_a-z][\\w']*"}]};var b={cN:"container",b:"{",e:"}",c:c.c};return{k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance not as foreign ccall safe unsafe",c:[{cN:"comment",b:"--",e:"$"},{cN:"preprocessor",b:"{-#",e:"#-}"},{cN:"comment",c:["self"],b:"{-",e:"-}"},{cN:"string",b:"\\s+'",e:"'",c:[a.BE],r:0},a.QSM,{cN:"import",b:"\\bimport",e:"$",k:"import qualified as hiding",c:[c],i:"\\W\\.|;"},{cN:"module",b:"\\bmodule",e:"where",k:"module where",c:[c],i:"\\W\\.|;"},{cN:"class",b:"\\b(class|instance)",e:"where",k:"class where instance",c:[d]},{cN:"typedef",b:"\\b(data|(new)?type)",e:"$",k:"data type newtype deriving",c:[d,c,b]},a.CNM,{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},d,{cN:"title",b:"^[_a-z][\\w']*"},{b:"->|<-"}]}}(hljs);hljs.LANGUAGES.http=function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}}(hljs);hljs.LANGUAGES.ini=function(a){return{cI:true,i:"[^\\s]",c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:"on off true false yes no",c:[a.QSM,a.NM],r:0}]}]}}(hljs);hljs.LANGUAGES.java=function(a){return{k:"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,{cN:"class",bWK:true,e:"{",k:"class interface",eE:true,i:":",c:[{bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]},a.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}}(hljs);hljs.LANGUAGES.javascript=function(a){return{k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const",literal:"true false null undefined NaN Infinity"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,a.REGEXP_MODE,{b:/</,e:/>;/,sL:"xml"}],r:0},{cN:"function",bWK:true,e:/{/,k:"function",c:[{cN:"title",b:/[A-Za-z$_][0-9A-Za-z$_]*/},{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBLCLM],i:/["'\(]/}],i:/\[|%/}]}}(hljs);hljs.LANGUAGES.json=function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}}(hljs);hljs.LANGUAGES.lasso=function(b){var a="[a-zA-Z_][a-zA-Z0-9_.]*|&[lg]t;";var c="<\\?(lasso(script)?|=)";return{cI:true,l:a,k:{literal:"true false none minimal full all infinity nan and or not bw ew cn lt lte gt gte eq neq ft rx nrx",built_in:"array date decimal duration integer map pair string tag xml null list queue set stack staticarray local var variable data global self inherited void",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require skip split_thread sum take thread to trait type where with yield"},c:[{cN:"preprocessor",b:"\\]|\\?>",r:0,starts:{cN:"markup",e:"\\[|"+c,rE:true}},{cN:"preprocessor",b:"\\[noprocess\\]",starts:{cN:"markup",e:"\\[/noprocess\\]",rE:true}},{cN:"preprocessor",b:"\\[no_square_brackets|\\[/noprocess|"+c},{cN:"preprocessor",b:"\\[",r:0},{cN:"shebang",b:"^#!.+lasso9\\b",r:10},b.CLCM,{cN:"javadoc",b:"/\\*\\*!",e:"\\*/"},b.CBLCLM,b.CNM,b.inherit(b.ASM,{i:null}),b.inherit(b.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{cN:"variable",b:"#\\d+|[#$]"+a},{cN:"tag",b:"::",e:a},{cN:"attribute",b:"\\.\\.\\.|-"+b.UIR},{cN:"class",bWK:true,k:"define",eE:true,e:"\\(|=>",c:[{cN:"title",b:b.UIR+"=?"}]}]}}(hljs);hljs.LANGUAGES.lisp=function(i){var l="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*";var m="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?";var k={cN:"shebang",b:"^#!",e:"$"};var a={cN:"literal",b:"\\b(t{1}|nil)\\b"};var d=[{cN:"number",b:m},{cN:"number",b:"#b[0-1]+(/[0-1]+)?"},{cN:"number",b:"#o[0-7]+(/[0-7]+)?"},{cN:"number",b:"#x[0-9a-f]+(/[0-9a-f]+)?"},{cN:"number",b:"#c\\("+m+" +"+m,e:"\\)"}];var h={cN:"string",b:'"',e:'"',c:[i.BE],r:0};var n={cN:"comment",b:";",e:"$"};var g={cN:"variable",b:"\\*",e:"\\*"};var o={cN:"keyword",b:"[:&]"+l};var b={b:"\\(",e:"\\)",c:["self",a,h].concat(d)};var e={cN:"quoted",b:"['`]\\(",e:"\\)",c:d.concat([h,g,o,b])};var c={cN:"quoted",b:"\\(quote ",e:"\\)",k:{title:"quote"},c:d.concat([h,g,o,b])};var j={cN:"list",b:"\\(",e:"\\)"};var f={eW:true,r:0};j.c=[{cN:"title",b:l},f];f.c=[e,c,j,a].concat(d).concat([h,n,g,o]);return{i:"[^\\s]",c:d.concat([k,a,h,n,e,c,j])}}(hljs);hljs.LANGUAGES.lua=function(b){var a="\\[=*\\[";var e="\\]=*\\]";var c={b:a,e:e,c:["self"]};var d=[{cN:"comment",b:"--(?!"+a+")",e:"$"},{cN:"comment",b:"--"+a,e:e,c:[c],r:10}];return{l:b.UIR,k:{keyword:"and break do else elseif end false for if in local nil not or repeat return then true until while",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},c:d.concat([{cN:"function",bWK:true,e:"\\)",k:"function",c:[{cN:"title",b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"},{cN:"params",b:"\\(",eW:true,c:d}].concat(d)},b.CNM,b.ASM,b.QSM,{cN:"string",b:a,e:e,c:[c],r:10}])}}(hljs);hljs.LANGUAGES.markdown=function(a){return{c:[{cN:"header",b:"^#{1,3}",e:"$"},{cN:"header",b:"^.+?\\n[=-]{2,}$"},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",b:"\\*.+?\\*"},{cN:"emphasis",b:"_.+?_",r:0},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",b:"`.+?`"},{cN:"code",b:"^    ",e:"$",r:0},{cN:"horizontal_rule",b:"^-{3,}",e:"$"},{b:"\\[.+?\\]\\(.+?\\)",rB:true,c:[{cN:"link_label",b:"\\[.+\\]"},{cN:"link_url",b:"\\(",e:"\\)",eB:true,eE:true}]}]}}(hljs);hljs.LANGUAGES.matlab=function(a){var b=[a.CNM,{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0}];return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bWK:true,e:"$",k:"function",c:[{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)"},{cN:"params",b:"\\[",e:"\\]"}]},{cN:"transposed_variable",b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:""},{cN:"matrix",b:"\\[",e:"\\]'*[\\.']*",c:b},{cN:"cell",b:"\\{",e:"\\}'*[\\.']*",c:b},{cN:"comment",b:"\\%",e:"$"}].concat(b)}}(hljs);hljs.LANGUAGES.mel=function(a){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:"</",c:[a.CNM,a.ASM,a.QSM,{cN:"string",b:"`",e:"`",c:[a.BE]},{cN:"variable",b:"\\$\\d",r:5},{cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+|[^\\s\\w{]|{\\w+}|\\w+)"},a.CLCM,a.CBLCLM]}}(hljs);hljs.LANGUAGES.mizar=function(a){return{k:["environ vocabularies notations constructors definitions registrations theorems schemes requirements","begin end definition registration cluster existence pred func defpred deffunc theorem proof","let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from","be being by means equals implies iff redefine define now not or attr is mode suppose per cases set","thesis contradiction scheme reserve struct","correctness compatibility coherence symmetry assymetry reflexivity irreflexivity","connectedness uniqueness commutativity idempotence involutiveness projectivity"].join(" "),c:[{cN:"comment",b:"::",e:"$"}]}}(hljs);hljs.LANGUAGES.nginx=function(b){var c=[{cN:"variable",b:"\\$\\d+"},{cN:"variable",b:"\\${",e:"}"},{cN:"variable",b:"[\\$\\@]"+b.UIR}];var a={eW:true,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[b.HCM,{cN:"string",b:'"',e:'"',c:[b.BE].concat(c),r:0},{cN:"string",b:"'",e:"'",c:[b.BE].concat(c),r:0},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:true,eE:true},{cN:"regexp",b:"\\s\\^",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"~\\*?\\s+",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"\\*(\\.[a-z\\-]+)+",c:[b.BE].concat(c)},{cN:"regexp",b:"([a-z\\-]+\\.)+\\*",c:[b.BE].concat(c)},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0}].concat(c)};return{c:[b.HCM,{b:b.UIR+"\\s",e:";|{",rB:true,c:[{cN:"title",b:b.UIR,starts:a}],r:0}],i:"[^\\s\\}]"}}(hljs);hljs.LANGUAGES.objectivec=function(a){var b={keyword:"int float while private char catch export sizeof typedef const struct for union unsigned long volatile static protected bool mutable if public do return goto void enum else break extern asm case short default double throw register explicit signed typename try this switch continue wchar_t inline readonly assign property self synchronized end synthesize id optional required nonatomic super unichar finally dynamic IBOutlet IBAction selector strong weak readonly",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection UIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.CNM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"preprocessor",b:"#import",e:"$",c:[{cN:"title",b:'"',e:'"'},{cN:"title",b:"<",e:">"}]},{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"({|$)",k:"interface class protocol implementation",c:[{cN:"id",b:a.UIR}]},{cN:"variable",b:"\\."+a.UIR,r:0}]}}(hljs);hljs.LANGUAGES.parser3=function(a){return{sL:"xml",r:0,c:[{cN:"comment",b:"^#",e:"$"},{cN:"comment",b:"\\^rem{",e:"}",r:10,c:[{b:"{",e:"}",c:["self"]}]},{cN:"preprocessor",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},a.CNM]}}(hljs);hljs.LANGUAGES.perl=function(e){var a="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when";var d={cN:"subst",b:"[$@]\\{",e:"\\}",k:a,r:10};var b={cN:"variable",b:"\\$\\d"};var i={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var f=[e.BE,d,b,i];var h={b:"->",c:[{b:e.IR},{b:"{",e:"}"}]};var g={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5};var c=[b,i,e.HCM,g,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:true},h,{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:f,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:f,r:5},{cN:"string",b:"'",e:"'",c:[e.BE],r:0},{cN:"string",b:'"',e:'"',c:f,r:0},{cN:"string",b:"`",e:"`",c:[e.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"("+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,g,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bWK:true,e:"(\\s*\\(.*?\\))?[;{]",k:"sub",r:5},{cN:"operator",b:"-\\w\\b",r:0}];d.c=c;h.c[1].c=c;return{k:a,c:c}}(hljs);hljs.LANGUAGES.php=function(a){var e={cN:"variable",b:"\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"};var b=[a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),{cN:"string",b:'b"',e:'"',c:[a.BE]},{cN:"string",b:"b'",e:"'",c:[a.BE]}];var c=[a.BNM,a.CNM];var d={cN:"title",b:a.UIR};return{cI:true,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return implements parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception php_user_filter default die require __FUNCTION__ enddeclare final try this switch continue endfor endif declare unset true false namespace trait goto instanceof insteadof __DIR__ __NAMESPACE__ __halt_compiler",c:[a.CLCM,a.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"}]},{cN:"comment",eB:true,b:"__halt_compiler.+?;",eW:true},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[a.BE]},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"},e,{cN:"function",bWK:true,e:"{",k:"function",i:"\\$|\\[|%",c:[d,{cN:"params",b:"\\(",e:"\\)",c:["self",e,a.CBLCLM].concat(b).concat(c)}]},{cN:"class",bWK:true,e:"{",k:"class",i:"[:\\(\\$]",c:[{bWK:true,eW:true,k:"extends",c:[d]},d]},{b:"=>"}].concat(b).concat(c)}}(hljs);hljs.LANGUAGES.profile=function(a){return{c:[a.CNM,{cN:"built_in",b:"{",e:"}$",eB:true,eE:true,c:[a.ASM,a.QSM],r:0},{cN:"filename",b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:true},{cN:"header",b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{cN:"summary",b:"function calls",e:"$",c:[a.CNM],r:10},a.ASM,a.QSM,{cN:"function",b:"\\(",e:"\\)$",c:[{cN:"title",b:a.UIR,r:0}],r:0}]}}(hljs);hljs.LANGUAGES.python=function(a){var f={cN:"prompt",b:/^(>>>|\.\.\.) /};var c=[{cN:"string",b:/(u|b)?r?'''/,e:/'''/,c:[f],r:10},{cN:"string",b:/(u|b)?r?"""/,e:/"""/,c:[f],r:10},{cN:"string",b:/(u|r|ur)'/,e:/'/,c:[a.BE],r:10},{cN:"string",b:/(u|r|ur)"/,e:/"/,c:[a.BE],r:10},{cN:"string",b:/(b|br)'/,e:/'/,c:[a.BE]},{cN:"string",b:/(b|br)"/,e:/"/,c:[a.BE]}].concat([a.ASM,a.QSM]);var e={cN:"title",b:a.UIR};var d={cN:"params",b:/\(/,e:/\)/,c:["self",a.CNM,f].concat(c)};var b={bWK:true,e:/:/,i:/[${=;\n]/,c:[e,d],r:10};return{k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10",built_in:"None True False Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:c.concat([f,a.HCM,a.inherit(b,{cN:"function",k:"def"}),a.inherit(b,{cN:"class",k:"class"}),a.CNM,{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}])}}(hljs);hljs.LANGUAGES.r=function(a){var b="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[a.HCM,{b:b,l:b,k:{keyword:"function if in break next repeat else for return switch while try tryCatch|10 stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...|10",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",b:'"',e:'"',c:[a.BE],r:0},{cN:"string",b:"'",e:"'",c:[a.BE],r:0}]}}(hljs);hljs.LANGUAGES.rib=function(a){return{k:"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd",i:"</",c:[a.HCM,a.CNM,a.ASM,a.QSM]}}(hljs);hljs.LANGUAGES.rsl=function(a){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,a.ASM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"shader",bWK:true,e:"\\(",k:"surface displacement light volume imager"},{cN:"shading",bWK:true,e:"\\(",k:"illuminate illuminance gather"}]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.ruleslanguage=function(a){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEMASK|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN DELETE SAVE SAVE_UPDATE CLEAR DETERMINANT LABEL REPORT REVENUE ABORT CALL DONE LEAVE EACH IN LIST NOVALUE FROM TOTAL CHARGE BLOCK AND OR CSV_FILE BILL_PERIOD RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM ABORT WARN NUMDAYS RATE_CODE READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}}(hljs);hljs.LANGUAGES.rust=function(b){var d={cN:"title",b:b.UIR};var c={cN:"number",b:"\\b(0[xb][A-Za-z0-9_]+|[0-9_]+(\\.[0-9_]+)?([uif](8|16|32|64)?)?)",r:0};var a="assert bool break char check claim comm const cont copy dir do drop else enum extern export f32 f64 fail false float fn for i16 i32 i64 i8 if impl int let log loop match mod move mut priv pub pure ref return self static str struct task true trait type u16 u32 u64 u8 uint unsafe use vec while";return{k:a,i:"</",c:[b.CLCM,b.CBLCLM,b.inherit(b.QSM,{i:null}),b.ASM,c,{cN:"function",bWK:true,e:"(\\(|<)",k:"fn",c:[d]},{cN:"preprocessor",b:"#\\[",e:"\\]"},{bWK:true,e:"(=|<)",k:"type",c:[d],i:"\\S"},{bWK:true,e:"({|<)",k:"trait enum",c:[d],i:"\\S"}]}}(hljs);hljs.LANGUAGES.scala=function(a){var c={cN:"annotation",b:"@[A-Za-z]+"};var b={cN:"string",b:'u?r?"""',e:'"""',r:10};return{k:"type yield lazy override def with val var false true sealed abstract private trait object null if for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,b,{cN:"class",b:"((case )?class |object |trait )",e:"({|$)",i:":",k:"case class trait object",c:[{bWK:true,k:"extends with",r:10},{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,b,c]}]},a.CNM,c]}}(hljs);hljs.LANGUAGES.scss=function(a){var c="[a-zA-Z-][a-zA-Z0-9_-]*";var d={cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};var b={cN:"hexcolor",b:"#[0-9A-Fa-f]+"};var e={cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[d,b,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"important",b:"!important"}]}};return{cI:true,i:"[=/|']",c:[a.CLCM,a.CBLCLM,{cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]},{cN:"id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{cN:"pseudo",b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{cN:"pseudo",b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{cN:"value",b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{cN:"value",b:":",e:";",c:[b,a.NM,a.QSM,a.ASM,{cN:"important",b:"!important"}]},{cN:"at_rule",b:"@",e:"[{;]",k:"mixin include for extend charset import media page font-face namespace",c:[d,a.QSM,a.ASM,b,a.NM,{cN:"preprocessor",b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}}(hljs);hljs.LANGUAGES.smalltalk=function(a){var b="[a-z][a-zA-Z0-9_]*";var d={cN:"char",b:"\\$.{1}"};var c={cN:"symbol",b:"#"+a.UIR};return{k:"self super nil true false thisContext",c:[{cN:"comment",b:'"',e:'"',r:0},a.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:b+":"},a.CNM,c,d,{cN:"localvars",b:"\\|\\s*"+b+"(\\s+"+b+")*\\s*\\|"},{cN:"array",b:"\\#\\(",e:"\\)",c:[a.ASM,d,a.CNM,c]}]}}(hljs);hljs.LANGUAGES.sql=function(a){return{cI:true,c:[{cN:"operator",b:"(begin|end|start|commit|rollback|savepoint|lock|alter|create|drop|rename|call|delete|do|handler|insert|load|replace|select|truncate|update|set|show|pragma|grant)\\b(?!:)",e:";",eW:true,k:{keyword:"all partial global month current_timestamp using go revoke smallint indicator end-exec disconnect zone with character assertion to add current_user usage input local alter match collate real then rollback get read timestamp session_user not integer bit unique day minute desc insert execute like ilike|2 level decimal drop continue isolation found where constraints domain right national some module transaction relative second connect escape close system_user for deferred section cast current sqlstate allocate intersect deallocate numeric public preserve full goto initially asc no key output collation group by union session both last language constraint column of space foreign deferrable prior connection unknown action commit view or first into float year primary cascaded except restrict set references names table outer open select size are rows from prepare distinct leading create only next inner authorization schema corresponding option declare precision immediate else timezone_minute external varying translation true case exception join hour default double scroll value cursor descriptor values dec fetch procedure delete and false int is describe char as at in varchar null trailing any absolute current_time end grant privileges when cross check write current_date pad begin temporary exec time update catalog user sql date on identity timezone_hour natural whenever interval work order cascade diagnostics nchar having left call do handler load replace truncate start lock show pragma exists number trigger if before after each row",aggregate:"count sum min max avg"},c:[{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0},{cN:"string",b:'"',e:'"',c:[a.BE,{b:'""'}],r:0},{cN:"string",b:"`",e:"`",c:[a.BE]},a.CNM]},a.CBLCLM,{cN:"comment",b:"--",e:"$"}]}}(hljs);hljs.LANGUAGES.tex=function(a){var d={cN:"command",b:"\\\\[a-zA-Zа-яА-я]+[\\*]?"};var c={cN:"command",b:"\\\\[^a-zA-Zа-яА-я0-9]"};var b={cN:"special",b:"[{}\\[\\]\\&#~]",r:0};return{c:[{b:"\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",rB:true,c:[d,c,{cN:"number",b:" *=",e:"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",eB:true}],r:10},d,c,b,{cN:"formula",b:"\\$\\$",e:"\\$\\$",c:[d,c,b],r:0},{cN:"formula",b:"\\$",e:"\\$",c:[d,c,b],r:0},{cN:"comment",b:"%",e:"$",r:0}]}}(hljs);hljs.LANGUAGES.vala=function(a){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object",literal:"false true null"},c:[{cN:"class",bWK:true,e:"{",k:"class interface delegate namespace",i:"[^,:\\n\\s\\.]",c:[{cN:"title",b:a.UIR}]},a.CLCM,a.CBLCLM,{cN:"string",b:'"""',e:'"""',r:5},a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"^#",e:"$",r:2},{cN:"constant",b:" [A-Z_]+ ",r:0}]}}(hljs);hljs.LANGUAGES.vbnet=function(a){return{cI:true,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"(//|endif|gosub|variant|wend)",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"'''|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"},]},a.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end region externalsource"},]}}(hljs);hljs.LANGUAGES.vbscript=function(a){return{cI:true,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$"},a.CNM]}}(hljs);hljs.LANGUAGES.vhdl=function(a){return{cI:true,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",typename:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[a.CBLCLM,{cN:"comment",b:"--",e:"$"},a.QSM,a.CNM,{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[a.BE]},{cN:"attribute",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[a.BE]}]}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/leap/leap.js b/docs/slides/BOS14/_support/reveal.js/plugin/leap/leap.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/leap/leap.js
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2013, Leap Motion, Inc.
+ * 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 HOLDER 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.
+ *
+ * Version 0.2.0 - http://js.leapmotion.com/0.2.0/leap.min.js
+ * Grab latest versions from http://js.leapmotion.com/
+ */
+
+!function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i}({1:[function(require,module,exports){var chooseProtocol=require("./protocol").chooseProtocol,EventEmitter=require("events").EventEmitter,_=require("underscore");var BaseConnection=module.exports=function(opts){this.opts=_.defaults(opts||{},{host:"127.0.0.1",enableGestures:false,port:6437,enableHeartbeat:true,heartbeatInterval:100,requestProtocolVersion:3});this.host=opts.host;this.port=opts.port;this.on("ready",function(){this.enableGestures(this.opts.enableGestures);if(this.opts.enableHeartbeat)this.startHeartbeat()});this.on("disconnect",function(){if(this.opts.enableHeartbeat)this.stopHeartbeat()});this.heartbeatTimer=null};BaseConnection.prototype.getUrl=function(){return"ws://"+this.host+":"+this.port+"/v"+this.opts.requestProtocolVersion+".json"};BaseConnection.prototype.sendHeartbeat=function(){if(this.protocol){this.setHeartbeatState(true);this.protocol.sendHeartbeat(this)}};BaseConnection.prototype.handleOpen=function(){this.emit("connect")};BaseConnection.prototype.enableGestures=function(enabled){this.gesturesEnabled=enabled?true:false;this.send(this.protocol.encode({enableGestures:this.gesturesEnabled}))};BaseConnection.prototype.handleClose=function(){this.disconnect();this.startReconnection()};BaseConnection.prototype.startReconnection=function(){var connection=this;setTimeout(function(){connection.connect()},1e3)};BaseConnection.prototype.disconnect=function(){if(!this.socket)return;this.socket.close();delete this.socket;delete this.protocol;this.emit("disconnect")};BaseConnection.prototype.handleData=function(data){var message=JSON.parse(data);var messageEvent;if(this.protocol===undefined){messageEvent=this.protocol=chooseProtocol(message);this.emit("ready")}else{messageEvent=this.protocol(message)}this.emit(messageEvent.type,messageEvent)};BaseConnection.prototype.connect=function(){if(this.socket)return;this.socket=this.setupSocket();return true};BaseConnection.prototype.send=function(data){this.socket.send(data)};BaseConnection.prototype.stopHeartbeat=function(){if(!this.heartbeatTimer)return;clearInterval(this.heartbeatTimer);delete this.heartbeatTimer;this.setHeartbeatState(false)};BaseConnection.prototype.setHeartbeatState=function(state){if(this.heartbeatState===state)return;this.heartbeatState=state;this.emit(this.heartbeatState?"focus":"blur")};_.extend(BaseConnection.prototype,EventEmitter.prototype)},{"./protocol":12,events:17,underscore:20}],2:[function(require,module,exports){var CircularBuffer=module.exports=function(size){this.pos=0;this._buf=[];this.size=size};CircularBuffer.prototype.get=function(i){if(i==undefined)i=0;if(i>=this.size)return undefined;if(i>=this._buf.length)return undefined;return this._buf[(this.pos-i-1)%this.size]};CircularBuffer.prototype.push=function(o){this._buf[this.pos%this.size]=o;return this.pos++}},{}],3:[function(require,module,exports){var Connection=module.exports=require("./base_connection");Connection.prototype.setupSocket=function(){var connection=this;var socket=new WebSocket(this.getUrl());socket.onopen=function(){connection.handleOpen()};socket.onmessage=function(message){connection.handleData(message.data)};socket.onclose=function(){connection.handleClose()};return socket};Connection.prototype.startHeartbeat=function(){if(!this.protocol.sendHeartbeat||this.heartbeatTimer)return;var connection=this;var propertyName=null;if(typeof document.hidden!=="undefined"){propertyName="hidden"}else if(typeof document.mozHidden!=="undefined"){propertyName="mozHidden"}else if(typeof document.msHidden!=="undefined"){propertyName="msHidden"}else if(typeof document.webkitHidden!=="undefined"){propertyName="webkitHidden"}else{propertyName=undefined}var windowVisible=true;var focusListener=window.addEventListener("focus",function(e){windowVisible=true});var blurListener=window.addEventListener("blur",function(e){windowVisible=false});this.on("disconnect",function(){if(connection.heartbeatTimer){clearTimeout(connection.heartbeatTimer);delete connection.heartbeatTimer}window.removeEventListener(focusListener);window.removeEventListener(blurListener)});this.heartbeatTimer=setInterval(function(){var isVisible=propertyName===undefined?true:document[propertyName]===false;if(isVisible&&windowVisible){connection.sendHeartbeat()}else{connection.setHeartbeatState(false)}},this.opts.heartbeatInterval)}},{"./base_connection":1}],4:[function(require,module,exports){!function(process){var Frame=require("./frame"),CircularBuffer=require("./circular_buffer"),Pipeline=require("./pipeline"),EventEmitter=require("events").EventEmitter,gestureListener=require("./gesture").gestureListener,_=require("underscore");var Controller=module.exports=function(opts){var inNode=typeof process!=="undefined"&&process.title==="node";opts=_.defaults(opts||{},{inNode:inNode});this.inNode=opts.inNode;opts=_.defaults(opts||{},{frameEventName:this.useAnimationLoop()?"animationFrame":"deviceFrame",supressAnimationLoop:false});this.supressAnimationLoop=opts.supressAnimationLoop;this.frameEventName=opts.frameEventName;this.history=new CircularBuffer(200);this.lastFrame=Frame.Invalid;this.lastValidFrame=Frame.Invalid;this.lastConnectionFrame=Frame.Invalid;this.accumulatedGestures=[];if(opts.connectionType===undefined){this.connectionType=this.inBrowser()?require("./connection"):require("./node_connection")}else{this.connectionType=opts.connectionType}this.connection=new this.connectionType(opts);this.setupConnectionEvents()};Controller.prototype.gesture=function(type,cb){var creator=gestureListener(this,type);if(cb!==undefined){creator.stop(cb)}return creator};Controller.prototype.inBrowser=function(){return!this.inNode};Controller.prototype.useAnimationLoop=function(){return this.inBrowser()&&typeof chrome==="undefined"};Controller.prototype.connect=function(){var controller=this;if(this.connection.connect()&&this.inBrowser()&&!controller.supressAnimationLoop){var callback=function(){controller.emit("animationFrame",controller.lastConnectionFrame);window.requestAnimFrame(callback)};window.requestAnimFrame(callback)}};Controller.prototype.disconnect=function(){this.connection.disconnect()};Controller.prototype.frame=function(num){return this.history.get(num)||Frame.Invalid};Controller.prototype.loop=function(callback){switch(callback.length){case 1:this.on(this.frameEventName,callback);break;case 2:var controller=this;var scheduler=null;var immediateRunnerCallback=function(frame){callback(frame,function(){if(controller.lastFrame!=frame){immediateRunnerCallback(controller.lastFrame)}else{controller.once(controller.frameEventName,immediateRunnerCallback)}})};this.once(this.frameEventName,immediateRunnerCallback);break}this.connect()};Controller.prototype.addStep=function(step){if(!this.pipeline)this.pipeline=new Pipeline(this);this.pipeline.addStep(step)};Controller.prototype.processFrame=function(frame){if(frame.gestures){this.accumulatedGestures=this.accumulatedGestures.concat(frame.gestures)}if(this.pipeline){frame=this.pipeline.run(frame);if(!frame)frame=Frame.Invalid}this.lastConnectionFrame=frame;this.emit("deviceFrame",frame)};Controller.prototype.processFinishedFrame=function(frame){this.lastFrame=frame;if(frame.valid){this.lastValidFrame=frame}frame.controller=this;frame.historyIdx=this.history.push(frame);if(frame.gestures){frame.gestures=this.accumulatedGestures;this.accumulatedGestures=[];for(var gestureIdx=0;gestureIdx!=frame.gestures.length;gestureIdx++){this.emit("gesture",frame.gestures[gestureIdx],frame)}}this.emit("frame",frame)};Controller.prototype.setupConnectionEvents=function(){var controller=this;this.connection.on("frame",function(frame){controller.processFrame(frame)});this.on(this.frameEventName,function(frame){controller.processFinishedFrame(frame)});this.connection.on("disconnect",function(){controller.emit("disconnect")});this.connection.on("ready",function(){controller.emit("ready")});this.connection.on("connect",function(){controller.emit("connect")});this.connection.on("focus",function(){controller.emit("focus")});this.connection.on("blur",function(){controller.emit("blur")});this.connection.on("protocol",function(protocol){controller.emit("protocol",protocol)});this.connection.on("deviceConnect",function(evt){controller.emit(evt.state?"deviceConnected":"deviceDisconnected")})};_.extend(Controller.prototype,EventEmitter.prototype)}(require("__browserify_process"))},{"./circular_buffer":2,"./connection":3,"./frame":5,"./gesture":6,"./node_connection":16,"./pipeline":10,__browserify_process:18,events:17,underscore:20}],5:[function(require,module,exports){var Hand=require("./hand"),Pointable=require("./pointable"),createGesture=require("./gesture").createGesture,glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,InteractionBox=require("./interaction_box"),_=require("underscore");var Frame=module.exports=function(data){this.valid=true;this.id=data.id;this.timestamp=data.timestamp;this.hands=[];this.handsMap={};this.pointables=[];this.tools=[];this.fingers=[];if(data.interactionBox){this.interactionBox=new InteractionBox(data.interactionBox)}this.gestures=[];this.pointablesMap={};this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.data=data;this.type="frame";this.currentFrameRate=data.currentFrameRate;var handMap={};for(var handIdx=0,handCount=data.hands.length;handIdx!=handCount;handIdx++){var hand=new Hand(data.hands[handIdx]);hand.frame=this;this.hands.push(hand);this.handsMap[hand.id]=hand;handMap[hand.id]=handIdx}for(var pointableIdx=0,pointableCount=data.pointables.length;pointableIdx!=pointableCount;pointableIdx++){var pointable=new Pointable(data.pointables[pointableIdx]);pointable.frame=this;this.pointables.push(pointable);this.pointablesMap[pointable.id]=pointable;(pointable.tool?this.tools:this.fingers).push(pointable);if(pointable.handId!==undefined&&handMap.hasOwnProperty(pointable.handId)){var hand=this.hands[handMap[pointable.handId]];hand.pointables.push(pointable);(pointable.tool?hand.tools:hand.fingers).push(pointable)}}if(data.gestures){for(var gestureIdx=0,gestureCount=data.gestures.length;gestureIdx!=gestureCount;gestureIdx++){this.gestures.push(createGesture(data.gestures[gestureIdx]))}}};Frame.prototype.tool=function(id){var pointable=this.pointable(id);return pointable.tool?pointable:Pointable.Invalid};Frame.prototype.pointable=function(id){return this.pointablesMap[id]||Pointable.Invalid};Frame.prototype.finger=function(id){var pointable=this.pointable(id);return!pointable.tool?pointable:Pointable.Invalid};Frame.prototype.hand=function(id){return this.handsMap[id]||Hand.Invalid};Frame.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Frame.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceFrame._rotation[5],this._rotation[2]-sinceFrame._rotation[6],this._rotation[3]-sinceFrame._rotation[1]])};Frame.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);return mat3.multiply(mat3.create(),sinceFrame._rotation,transpose)};Frame.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;return Math.exp(this._scaleFactor-sinceFrame._scaleFactor)};Frame.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.subtract(vec3.create(),this._translation,sinceFrame._translation)};Frame.prototype.toString=function(){var str="Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")";if(this.gestures)str+=" | Gesture count:("+this.gestures.length+")";str+=" ]";return str};Frame.prototype.dump=function(){var out="";out+="Frame Info:<br/>";out+=this.toString();out+="<br/><br/>Hands:<br/>";for(var handIdx=0,handCount=this.hands.length;handIdx!=handCount;handIdx++){out+="  "+this.hands[handIdx].toString()+"<br/>"}out+="<br/><br/>Pointables:<br/>";for(var pointableIdx=0,pointableCount=this.pointables.length;pointableIdx!=pointableCount;pointableIdx++){out+="  "+this.pointables[pointableIdx].toString()+"<br/>"}if(this.gestures){out+="<br/><br/>Gestures:<br/>";for(var gestureIdx=0,gestureCount=this.gestures.length;gestureIdx!=gestureCount;gestureIdx++){out+="  "+this.gestures[gestureIdx].toString()+"<br/>"}}out+="<br/><br/>Raw JSON:<br/>";out+=JSON.stringify(this.data);return out};Frame.Invalid={valid:false,hands:[],fingers:[],tools:[],gestures:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},hand:function(){return Hand.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"gl-matrix":19,underscore:20}],6:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3,EventEmitter=require("events").EventEmitter,_=require("underscore");var createGesture=exports.createGesture=function(data){var gesture;switch(data.type){case"circle":gesture=new CircleGesture(data);break;case"swipe":gesture=new SwipeGesture(data);break;case"screenTap":gesture=new ScreenTapGesture(data);break;case"keyTap":gesture=new KeyTapGesture(data);break;default:throw"unkown gesture type"}gesture.id=data.id;gesture.handIds=data.handIds;gesture.pointableIds=data.pointableIds;gesture.duration=data.duration;gesture.state=data.state;gesture.type=data.type;return gesture};var gestureListener=exports.gestureListener=function(controller,type){var handlers={};var gestureMap={};var gestureCreator=function(){var candidateGesture=gestureMap[gesture.id];if(candidateGesture!==undefined)gesture.update(gesture,frame);if(gesture.state=="start"||gesture.state=="stop"){if(type==gesture.type&&gestureMap[gesture.id]===undefined){gestureMap[gesture.id]=new Gesture(gesture,frame);gesture.update(gesture,frame)}if(gesture.state=="stop"){delete gestureMap[gesture.id]}}};controller.on("gesture",function(gesture,frame){if(gesture.type==type){if(gesture.state=="start"||gesture.state=="stop"){if(gestureMap[gesture.id]===undefined){var gestureTracker=new Gesture(gesture,frame);gestureMap[gesture.id]=gestureTracker;_.each(handlers,function(cb,name){gestureTracker.on(name,cb)})}}gestureMap[gesture.id].update(gesture,frame);if(gesture.state=="stop"){delete gestureMap[gesture.id]}}});var builder={start:function(cb){handlers["start"]=cb;return builder},stop:function(cb){handlers["stop"]=cb;return builder},complete:function(cb){handlers["stop"]=cb;return builder},update:function(cb){handlers["update"]=cb;return builder}};return builder};var Gesture=exports.Gesture=function(gesture,frame){this.gestures=[gesture];this.frames=[frame]};Gesture.prototype.update=function(gesture,frame){this.gestures.push(gesture);this.frames.push(frame);this.emit(gesture.state,this)};_.extend(Gesture.prototype,EventEmitter.prototype);var CircleGesture=function(data){this.center=data.center;this.normal=data.normal;this.progress=data.progress;this.radius=data.radius};CircleGesture.prototype.toString=function(){return"CircleGesture ["+JSON.stringify(this)+"]"};var SwipeGesture=function(data){this.startPosition=data.startPosition;this.position=data.position;this.direction=data.direction;this.speed=data.speed};SwipeGesture.prototype.toString=function(){return"SwipeGesture ["+JSON.stringify(this)+"]"};var ScreenTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};ScreenTapGesture.prototype.toString=function(){return"ScreenTapGesture ["+JSON.stringify(this)+"]"};var KeyTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};KeyTapGesture.prototype.toString=function(){return"KeyTapGesture ["+JSON.stringify(this)+"]"}},{events:17,"gl-matrix":19,underscore:20}],7:[function(require,module,exports){var Pointable=require("./pointable"),glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,_=require("underscore");var Hand=module.exports=function(data){this.id=data.id;this.palmPosition=data.palmPosition;this.direction=data.direction;this.palmVelocity=data.palmVelocity;this.palmNormal=data.palmNormal;this.sphereCenter=data.sphereCenter;this.sphereRadius=data.sphereRadius;this.valid=true;this.pointables=[];this.fingers=[];this.tools=[];this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.timeVisible=data.timeVisible;this.stabilizedPalmPosition=data.stabilizedPalmPosition};Hand.prototype.finger=function(id){var finger=this.frame.finger(id);return finger&&finger.handId==this.id?finger:Pointable.Invalid};Hand.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Hand.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceHand._rotation[5],this._rotation[2]-sinceHand._rotation[6],this._rotation[3]-sinceHand._rotation[1]])};Hand.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);var m=mat3.multiply(mat3.create(),sinceHand._rotation,transpose);return m};Hand.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 1;return Math.exp(this._scaleFactor-sinceHand._scaleFactor)};Hand.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return[this._translation[0]-sinceHand._translation[0],this._translation[1]-sinceHand._translation[1],this._translation[2]-sinceHand._translation[2]]};Hand.prototype.toString=function(){return"Hand [ id: "+this.id+" | palm velocity:"+this.palmVelocity+" | sphere center:"+this.sphereCenter+" ] "};Hand.Invalid={valid:false,fingers:[],tools:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./pointable":11,"gl-matrix":19,underscore:20}],8:[function(require,module,exports){!function(){module.exports={Controller:require("./controller"),Frame:require("./frame"),Gesture:require("./gesture"),Hand:require("./hand"),Pointable:require("./pointable"),InteractionBox:require("./interaction_box"),Connection:require("./connection"),CircularBuffer:require("./circular_buffer"),UI:require("./ui"),glMatrix:require("gl-matrix"),mat3:require("gl-matrix").mat3,vec3:require("gl-matrix").vec3,loopController:undefined,loop:function(opts,callback){if(callback===undefined){callback=opts;opts={}}if(!this.loopController)this.loopController=new this.Controller(opts);this.loopController.loop(callback)}}}()},{"./circular_buffer":2,"./connection":3,"./controller":4,"./frame":5,"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"./ui":13,"gl-matrix":19}],9:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var InteractionBox=module.exports=function(data){this.valid=true;this.center=data.center;this.size=data.size;this.width=data.size[0];this.height=data.size[1];this.depth=data.size[2]};InteractionBox.prototype.denormalizePoint=function(normalizedPosition){return vec3.fromValues((normalizedPosition[0]-.5)*this.size[0]+this.center[0],(normalizedPosition[1]-.5)*this.size[1]+this.center[1],(normalizedPosition[2]-.5)*this.size[2]+this.center[2])};InteractionBox.prototype.normalizePoint=function(position,clamp){var vec=vec3.fromValues((position[0]-this.center[0])/this.size[0]+.5,(position[1]-this.center[1])/this.size[1]+.5,(position[2]-this.center[2])/this.size[2]+.5);if(clamp){vec[0]=Math.min(Math.max(vec[0],0),1);vec[1]=Math.min(Math.max(vec[1],0),1);vec[2]=Math.min(Math.max(vec[2],0),1)}return vec};InteractionBox.prototype.toString=function(){return"InteractionBox [ width:"+this.width+" | height:"+this.height+" | depth:"+this.depth+" ]"};InteractionBox.Invalid={valid:false}},{"gl-matrix":19}],10:[function(require,module,exports){var Pipeline=module.exports=function(){this.steps=[]};Pipeline.prototype.addStep=function(step){this.steps.push(step)};Pipeline.prototype.run=function(frame){var stepsLength=this.steps.length;for(var i=0;i!=stepsLength;i++){if(!frame)break;frame=this.steps[i](frame)}return frame}},{}],11:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var Pointable=module.exports=function(data){this.valid=true;this.id=data.id;this.handId=data.handId;this.length=data.length;this.tool=data.tool;this.width=data.width;this.direction=data.direction;this.stabilizedTipPosition=data.stabilizedTipPosition;this.tipPosition=data.tipPosition;this.tipVelocity=data.tipVelocity;this.touchZone=data.touchZone;this.touchDistance=data.touchDistance;this.timeVisible=data.timeVisible};Pointable.prototype.toString=function(){if(this.tool==true){return"Pointable [ id:"+this.id+" "+this.length+"mmx | with:"+this.width+"mm | direction:"+this.direction+" ]"}else{return"Pointable [ id:"+this.id+" "+this.length+"mmx | direction: "+this.direction+" ]"}};Pointable.Invalid={valid:false}},{"gl-matrix":19}],12:[function(require,module,exports){var Frame=require("./frame");var Event=function(data){this.type=data.type;this.state=data.state};var chooseProtocol=exports.chooseProtocol=function(header){var protocol;switch(header.version){case 1:protocol=JSONProtocol(1,function(data){return new Frame(data)});break;case 2:protocol=JSONProtocol(2,function(data){return new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;case 3:protocol=JSONProtocol(3,function(data){return data.event?new Event(data.event):new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;default:throw"unrecognized version"}return protocol};var JSONProtocol=function(version,cb){var protocol=cb;protocol.encode=function(message){return JSON.stringify(message)};protocol.version=version;protocol.versionLong="Version "+version;protocol.type="protocol";return protocol}},{"./frame":5}],13:[function(require,module,exports){exports.UI={Region:require("./ui/region"),Cursor:require("./ui/cursor")}},{"./ui/cursor":14,"./ui/region":15}],14:[function(require,module,exports){var Cursor=module.exports=function(){return function(frame){var pointable=frame.pointables.sort(function(a,b){return a.z-b.z})[0];if(pointable&&pointable.valid){frame.cursorPosition=pointable.tipPosition}return frame}}},{}],15:[function(require,module,exports){var EventEmitter=require("events").EventEmitter,_=require("underscore");var Region=module.exports=function(start,end){this.start=new Vector(start);this.end=new Vector(end);this.enteredFrame=null};Region.prototype.hasPointables=function(frame){for(var i=0;i!=frame.pointables.length;i++){var position=frame.pointables[i].tipPosition;if(position.x>=this.start.x&&position.x<=this.end.x&&position.y>=this.start.y&&position.y<=this.end.y&&position.z>=this.start.z&&position.z<=this.end.z){return true}}return false};Region.prototype.listener=function(opts){var region=this;if(opts&&opts.nearThreshold)this.setupNearRegion(opts.nearThreshold);return function(frame){return region.updatePosition(frame)}};Region.prototype.clipper=function(){var region=this;return function(frame){region.updatePosition(frame);return region.enteredFrame?frame:null}};Region.prototype.setupNearRegion=function(distance){var nearRegion=this.nearRegion=new Region([this.start.x-distance,this.start.y-distance,this.start.z-distance],[this.end.x+distance,this.end.y+distance,this.end.z+distance]);var region=this;nearRegion.on("enter",function(frame){region.emit("near",frame)});nearRegion.on("exit",function(frame){region.emit("far",frame)});region.on("exit",function(frame){region.emit("near",frame)})};Region.prototype.updatePosition=function(frame){if(this.nearRegion)this.nearRegion.updatePosition(frame);if(this.hasPointables(frame)&&this.enteredFrame==null){this.enteredFrame=frame;this.emit("enter",this.enteredFrame)}else if(!this.hasPointables(frame)&&this.enteredFrame!=null){this.enteredFrame=null;this.emit("exit",this.enteredFrame)}return frame};Region.prototype.normalize=function(position){return new Vector([(position.x-this.start.x)/(this.end.x-this.start.x),(position.y-this.start.y)/(this.end.y-this.start.y),(position.z-this.start.z)/(this.end.z-this.start.z)])};Region.prototype.mapToXY=function(position,width,height){var normalized=this.normalize(position);var x=normalized.x,y=normalized.y;if(x>1)x=1;else if(x<-1)x=-1;if(y>1)y=1;else if(y<-1)y=-1;return[(x+1)/2*width,(1-y)/2*height,normalized.z]};_.extend(Region.prototype,EventEmitter.prototype)},{events:17,underscore:20}],16:[function(require,module,exports){},{}],17:[function(require,module,exports){!function(process){if(!process.EventEmitter)process.EventEmitter=function(){};var EventEmitter=exports.EventEmitter=process.EventEmitter;var isArray=typeof Array.isArray==="function"?Array.isArray:function(xs){return Object.prototype.toString.call(xs)==="[object Array]"};function indexOf(xs,x){if(xs.indexOf)return xs.indexOf(x);for(var i=0;i<xs.length;i++){if(x===xs[i])return i}return-1}var defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!this._events)this._events={};this._events.maxListeners=n};EventEmitter.prototype.emit=function(type){if(type==="error"){if(!this._events||!this._events.error||isArray(this._events.error)&&!this._events.error.length){if(arguments[1]instanceof Error){throw arguments[1]}else{throw new Error("Uncaught, unspecified 'error' event.")}return false}}if(!this._events)return false;var handler=this._events[type];if(!handler)return false;if(typeof handler=="function"){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:var args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}return true}else if(isArray(handler)){var args=Array.prototype.slice.call(arguments,1);var listeners=handler.slice();for(var i=0,l=listeners.length;i<l;i++){listeners[i].apply(this,args)}return true}else{return false}};EventEmitter.prototype.addListener=function(type,listener){if("function"!==typeof listener){throw new Error("addListener only takes instances of Function")}if(!this._events)this._events={};this.emit("newListener",type,listener);if(!this._events[type]){this._events[type]=listener}else if(isArray(this._events[type])){if(!this._events[type].warned){var m;if(this._events.maxListeners!==undefined){m=this._events.maxListeners}else{m=defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);console.trace()}}this._events[type].push(listener)}else{this._events[type]=[this._events[type],listener]}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){var self=this;self.on(type,function g(){self.removeListener(type,g);listener.apply(this,arguments)});return this};EventEmitter.prototype.removeListener=function(type,listener){if("function"!==typeof listener){throw new Error("removeListener only takes instances of Function")}if(!this._events||!this._events[type])return this;var list=this._events[type];if(isArray(list)){var i=indexOf(list,listener);if(i<0)return this;list.splice(i,1);if(list.length==0)delete this._events[type]}else if(this._events[type]===listener){delete this._events[type]}return this};EventEmitter.prototype.removeAllListeners=function(type){if(arguments.length===0){this._events={};return this}if(type&&this._events&&this._events[type])this._events[type]=null;return this};EventEmitter.prototype.listeners=function(type){if(!this._events)this._events={};if(!this._events[type])this._events[type]=[];if(!isArray(this._events[type])){this._events[type]=[this._events[type]]}return this._events[type]}}(require("__browserify_process"))},{__browserify_process:18}],18:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){if(ev.source===window&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}],19:[function(require,module,exports){!function(){!function(){"use strict";var shim={};if(typeof exports==="undefined"){if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){shim.exports={};define(function(){return shim.exports})}else{shim.exports=window}}else{shim.exports=exports}!function(exports){var vec2={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec2.create=function(){return new Float32Array(2)};vec2.clone=function(a){var out=new Float32Array(2);out[0]=a[0];out[1]=a[1];return out};vec2.fromValues=function(x,y){var out=new Float32Array(2);out[0]=x;out[1]=y;return out};vec2.copy=function(out,a){out[0]=a[0];out[1]=a[1];return out};vec2.set=function(out,x,y){out[0]=x;out[1]=y;return out};vec2.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];return out};vec2.sub=vec2.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];return out};vec2.mul=vec2.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];return out};vec2.div=vec2.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];return out};vec2.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);
+out[1]=Math.min(a[1],b[1]);return out};vec2.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);return out};vec2.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;return out};vec2.dist=vec2.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return Math.sqrt(x*x+y*y)};vec2.sqrDist=vec2.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return x*x+y*y};vec2.len=vec2.length=function(a){var x=a[0],y=a[1];return Math.sqrt(x*x+y*y)};vec2.sqrLen=vec2.squaredLength=function(a){var x=a[0],y=a[1];return x*x+y*y};vec2.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];return out};vec2.normalize=function(out,a){var x=a[0],y=a[1];var len=x*x+y*y;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len}return out};vec2.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]};vec2.cross=function(out,a,b){var z=a[0]*b[1]-a[1]*b[0];out[0]=out[1]=0;out[2]=z;return out};vec2.lerp=function(out,a,b,t){var ax=a[0],ay=a[1];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);return out};vec2.transformMat2=function(out,a,m){var x=a[0],y=a[1];out[0]=x*m[0]+y*m[1];out[1]=x*m[2]+y*m[3];return out};vec2.forEach=function(){var vec=new Float32Array(2);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=2}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1]}return a}}();vec2.str=function(a){return"vec2("+a[0]+", "+a[1]+")"};if(typeof exports!=="undefined"){exports.vec2=vec2}var vec3={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec3.create=function(){return new Float32Array(3)};vec3.clone=function(a){var out=new Float32Array(3);out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.fromValues=function(x,y,z){var out=new Float32Array(3);out[0]=x;out[1]=y;out[2]=z;return out};vec3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.set=function(out,x,y,z){out[0]=x;out[1]=y;out[2]=z;return out};vec3.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];return out};vec3.sub=vec3.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];return out};vec3.mul=vec3.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];return out};vec3.div=vec3.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];return out};vec3.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);return out};vec3.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);return out};vec3.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;return out};vec3.dist=vec3.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrDist=vec3.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return x*x+y*y+z*z};vec3.len=vec3.length=function(a){var x=a[0],y=a[1],z=a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrLen=vec3.squaredLength=function(a){var x=a[0],y=a[1],z=a[2];return x*x+y*y+z*z};vec3.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];return out};vec3.normalize=function(out,a){var x=a[0],y=a[1],z=a[2];var len=x*x+y*y+z*z;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len}return out};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};vec3.cross=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2];out[0]=ay*bz-az*by;out[1]=az*bx-ax*bz;out[2]=ax*by-ay*bx;return out};vec3.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);return out};vec3.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12];out[1]=m[1]*x+m[5]*y+m[9]*z+m[13];out[2]=m[2]*x+m[6]*y+m[10]*z+m[14];return out};vec3.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec3.forEach=function(){var vec=new Float32Array(3);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=3}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2]}return a}}();vec3.str=function(a){return"vec3("+a[0]+", "+a[1]+", "+a[2]+")"};if(typeof exports!=="undefined"){exports.vec3=vec3}var vec4={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec4.create=function(){return new Float32Array(4)};vec4.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.fromValues=function(x,y,z,w){var out=new Float32Array(4);out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.set=function(out,x,y,z,w){out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];out[3]=a[3]+b[3];return out};vec4.sub=vec4.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];out[3]=a[3]-b[3];return out};vec4.mul=vec4.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];out[3]=a[3]*b[3];return out};vec4.div=vec4.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];out[3]=a[3]/b[3];return out};vec4.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);out[3]=Math.min(a[3],b[3]);return out};vec4.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);out[3]=Math.max(a[3],b[3]);return out};vec4.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;out[3]=a[3]*b;return out};vec4.dist=vec4.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrDist=vec4.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return x*x+y*y+z*z+w*w};vec4.len=vec4.length=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrLen=vec4.squaredLength=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return x*x+y*y+z*z+w*w};vec4.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=-a[3];return out};vec4.normalize=function(out,a){var x=a[0],y=a[1],z=a[2],w=a[3];var len=x*x+y*y+z*z+w*w;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len;out[3]=a[3]*len}return out};vec4.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]};vec4.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);out[3]=aw+t*(b[3]-aw);return out};vec4.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2],w=a[3];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12]*w;out[1]=m[1]*x+m[5]*y+m[9]*z+m[13]*w;out[2]=m[2]*x+m[6]*y+m[10]*z+m[14]*w;out[3]=m[3]*x+m[7]*y+m[11]*z+m[15]*w;return out};vec4.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec4.forEach=function(){var vec=new Float32Array(4);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=4}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];vec[3]=a[i+3];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2];a[i+3]=vec[3]}return a}}();vec4.str=function(a){return"vec4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.vec4=vec4}var mat2={};var mat2Identity=new Float32Array([1,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat2.create=function(){return new Float32Array(mat2Identity)};mat2.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=1;return out};mat2.transpose=function(out,a){if(out===a){var a1=a[1];out[1]=a[2];out[2]=a1}else{out[0]=a[0];out[1]=a[2];out[2]=a[1];out[3]=a[3]}return out};mat2.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],det=a0*a3-a2*a1;if(!det){return null}det=1/det;out[0]=a3*det;out[1]=-a1*det;out[2]=-a2*det;out[3]=a0*det;return out};mat2.adjoint=function(out,a){var a0=a[0];out[0]=a[3];out[1]=-a[1];out[2]=-a[2];out[3]=a0;return out};mat2.determinant=function(a){return a[0]*a[3]-a[2]*a[1]};mat2.mul=mat2.multiply=function(out,a,b){var a0=a[0],a1=a[1],a2=a[2],a3=a[3];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=a0*b0+a1*b2;out[1]=a0*b1+a1*b3;out[2]=a2*b0+a3*b2;out[3]=a2*b1+a3*b3;return out};mat2.rotate=function(out,a,rad){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],s=Math.sin(rad),c=Math.cos(rad);out[0]=a0*c+a1*s;out[1]=a0*-s+a1*c;out[2]=a2*c+a3*s;out[3]=a2*-s+a3*c;return out};mat2.scale=function(out,a,v){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],v0=v[0],v1=v[1];out[0]=a0*v0;out[1]=a1*v1;out[2]=a2*v0;out[3]=a3*v1;return out};mat2.str=function(a){return"mat2("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.mat2=mat2}var mat3={};var mat3Identity=new Float32Array([1,0,0,0,1,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat3.create=function(){return new Float32Array(mat3Identity)};mat3.clone=function(a){var out=new Float32Array(9);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=1;out[5]=0;out[6]=0;out[7]=0;out[8]=1;return out};mat3.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a12=a[5];out[1]=a[3];out[2]=a[6];out[3]=a01;out[5]=a[7];out[6]=a02;out[7]=a12}else{out[0]=a[0];out[1]=a[3];out[2]=a[6];out[3]=a[1];out[4]=a[4];out[5]=a[7];out[6]=a[2];out[7]=a[5];out[8]=a[8]}return out};mat3.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b01=a22*a11-a12*a21,b11=-a22*a10+a12*a20,b21=a21*a10-a11*a20,det=a00*b01+a01*b11+a02*b21;if(!det){return null}det=1/det;out[0]=b01*det;out[1]=(-a22*a01+a02*a21)*det;out[2]=(a12*a01-a02*a11)*det;out[3]=b11*det;out[4]=(a22*a00-a02*a20)*det;out[5]=(-a12*a00+a02*a10)*det;out[6]=b21*det;out[7]=(-a21*a00+a01*a20)*det;out[8]=(a11*a00-a01*a10)*det;return out};mat3.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];out[0]=a11*a22-a12*a21;out[1]=a02*a21-a01*a22;out[2]=a01*a12-a02*a11;out[3]=a12*a20-a10*a22;out[4]=a00*a22-a02*a20;out[5]=a02*a10-a00*a12;out[6]=a10*a21-a11*a20;out[7]=a01*a20-a00*a21;out[8]=a00*a11-a01*a10;return out};mat3.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];return a00*(a22*a11-a12*a21)+a01*(-a22*a10+a12*a20)+a02*(a21*a10-a11*a20)};mat3.mul=mat3.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b00=b[0],b01=b[1],b02=b[2],b10=b[3],b11=b[4],b12=b[5],b20=b[6],b21=b[7],b22=b[8];out[0]=b00*a00+b01*a10+b02*a20;out[1]=b00*a01+b01*a11+b02*a21;out[2]=b00*a02+b01*a12+b02*a22;out[3]=b10*a00+b11*a10+b12*a20;out[4]=b10*a01+b11*a11+b12*a21;out[5]=b10*a02+b11*a12+b12*a22;out[6]=b20*a00+b21*a10+b22*a20;out[7]=b20*a01+b21*a11+b22*a21;out[8]=b20*a02+b21*a12+b22*a22;return out};mat3.str=function(a){return"mat3("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+")"};if(typeof exports!=="undefined"){exports.mat3=mat3}var mat4={};var mat4Identity=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat4.create=function(){return new Float32Array(mat4Identity)};mat4.clone=function(a){var out=new Float32Array(16);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=1;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=1;out[11]=0;out[12]=0;out[13]=0;out[14]=0;out[15]=1;return out};mat4.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a03=a[3],a12=a[6],a13=a[7],a23=a[11];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a01;out[6]=a[9];out[7]=a[13];out[8]=a02;out[9]=a12;out[11]=a[14];out[12]=a03;out[13]=a13;out[14]=a23}else{out[0]=a[0];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a[1];out[5]=a[5];out[6]=a[9];out[7]=a[13];out[8]=a[2];out[9]=a[6];out[10]=a[10];out[11]=a[14];out[12]=a[3];out[13]=a[7];out[14]=a[11];out[15]=a[15]}return out};mat4.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32,det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;if(!det){return null}det=1/det;out[0]=(a11*b11-a12*b10+a13*b09)*det;out[1]=(a02*b10-a01*b11-a03*b09)*det;out[2]=(a31*b05-a32*b04+a33*b03)*det;out[3]=(a22*b04-a21*b05-a23*b03)*det;out[4]=(a12*b08-a10*b11-a13*b07)*det;out[5]=(a00*b11-a02*b08+a03*b07)*det;out[6]=(a32*b02-a30*b05-a33*b01)*det;out[7]=(a20*b05-a22*b02+a23*b01)*det;out[8]=(a10*b10-a11*b08+a13*b06)*det;out[9]=(a01*b08-a00*b10-a03*b06)*det;out[10]=(a30*b04-a31*b02+a33*b00)*det;out[11]=(a21*b02-a20*b04-a23*b00)*det;out[12]=(a11*b07-a10*b09-a12*b06)*det;out[13]=(a00*b09-a01*b07+a02*b06)*det;out[14]=(a31*b01-a30*b03-a32*b00)*det;out[15]=(a20*b03-a21*b01+a22*b00)*det;return out};mat4.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];out[0]=a11*(a22*a33-a23*a32)-a21*(a12*a33-a13*a32)+a31*(a12*a23-a13*a22);out[1]=-(a01*(a22*a33-a23*a32)-a21*(a02*a33-a03*a32)+a31*(a02*a23-a03*a22));out[2]=a01*(a12*a33-a13*a32)-a11*(a02*a33-a03*a32)+a31*(a02*a13-a03*a12);out[3]=-(a01*(a12*a23-a13*a22)-a11*(a02*a23-a03*a22)+a21*(a02*a13-a03*a12));out[4]=-(a10*(a22*a33-a23*a32)-a20*(a12*a33-a13*a32)+a30*(a12*a23-a13*a22));out[5]=a00*(a22*a33-a23*a32)-a20*(a02*a33-a03*a32)+a30*(a02*a23-a03*a22);out[6]=-(a00*(a12*a33-a13*a32)-a10*(a02*a33-a03*a32)+a30*(a02*a13-a03*a12));out[7]=a00*(a12*a23-a13*a22)-a10*(a02*a23-a03*a22)+a20*(a02*a13-a03*a12);out[8]=a10*(a21*a33-a23*a31)-a20*(a11*a33-a13*a31)+a30*(a11*a23-a13*a21);out[9]=-(a00*(a21*a33-a23*a31)-a20*(a01*a33-a03*a31)+a30*(a01*a23-a03*a21));out[10]=a00*(a11*a33-a13*a31)-a10*(a01*a33-a03*a31)+a30*(a01*a13-a03*a11);out[11]=-(a00*(a11*a23-a13*a21)-a10*(a01*a23-a03*a21)+a20*(a01*a13-a03*a11));out[12]=-(a10*(a21*a32-a22*a31)-a20*(a11*a32-a12*a31)+a30*(a11*a22-a12*a21));out[13]=a00*(a21*a32-a22*a31)-a20*(a01*a32-a02*a31)+a30*(a01*a22-a02*a21);out[14]=-(a00*(a11*a32-a12*a31)-a10*(a01*a32-a02*a31)+a30*(a01*a12-a02*a11));out[15]=a00*(a11*a22-a12*a21)-a10*(a01*a22-a02*a21)+a20*(a01*a12-a02*a11);return out};mat4.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32;return b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06};mat4.mul=mat4.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=b0*a00+b1*a10+b2*a20+b3*a30;out[1]=b0*a01+b1*a11+b2*a21+b3*a31;out[2]=b0*a02+b1*a12+b2*a22+b3*a32;out[3]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[4];b1=b[5];b2=b[6];b3=b[7];out[4]=b0*a00+b1*a10+b2*a20+b3*a30;out[5]=b0*a01+b1*a11+b2*a21+b3*a31;out[6]=b0*a02+b1*a12+b2*a22+b3*a32;out[7]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[8];b1=b[9];b2=b[10];b3=b[11];out[8]=b0*a00+b1*a10+b2*a20+b3*a30;out[9]=b0*a01+b1*a11+b2*a21+b3*a31;out[10]=b0*a02+b1*a12+b2*a22+b3*a32;out[11]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[12];b1=b[13];b2=b[14];b3=b[15];out[12]=b0*a00+b1*a10+b2*a20+b3*a30;out[13]=b0*a01+b1*a11+b2*a21+b3*a31;out[14]=b0*a02+b1*a12+b2*a22+b3*a32;out[15]=b0*a03+b1*a13+b2*a23+b3*a33;return out};mat4.translate=function(out,a,v){var x=v[0],y=v[1],z=v[2],a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23;if(a===out){out[12]=a[0]*x+a[4]*y+a[8]*z+a[12];out[13]=a[1]*x+a[5]*y+a[9]*z+a[13];out[14]=a[2]*x+a[6]*y+a[10]*z+a[14];out[15]=a[3]*x+a[7]*y+a[11]*z+a[15]}else{a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];out[0]=a00;out[1]=a01;out[2]=a02;out[3]=a03;out[4]=a10;out[5]=a11;out[6]=a12;out[7]=a13;out[8]=a20;out[9]=a21;out[10]=a22;out[11]=a23;out[12]=a00*x+a10*y+a20*z+a[12];out[13]=a01*x+a11*y+a21*z+a[13];out[14]=a02*x+a12*y+a22*z+a[14];out[15]=a03*x+a13*y+a23*z+a[15]}return out};mat4.scale=function(out,a,v){var x=v[0],y=v[1],z=v[2];out[0]=a[0]*x;out[1]=a[1]*x;out[2]=a[2]*x;out[3]=a[3]*x;out[4]=a[4]*y;out[5]=a[5]*y;out[6]=a[6]*y;out[7]=a[7]*y;out[8]=a[8]*z;out[9]=a[9]*z;out[10]=a[10]*z;out[11]=a[11]*z;out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.rotate=function(out,a,rad,axis){var x=axis[0],y=axis[1],z=axis[2],len=Math.sqrt(x*x+y*y+z*z),s,c,t,a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23,b00,b01,b02,b10,b11,b12,b20,b21,b22;if(Math.abs(len)<GLMAT_EPSILON){return null}len=1/len;x*=len;y*=len;z*=len;s=Math.sin(rad);c=Math.cos(rad);t=1-c;a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];b00=x*x*t+c;b01=y*x*t+z*s;b02=z*x*t-y*s;b10=x*y*t-z*s;b11=y*y*t+c;b12=z*y*t+x*s;b20=x*z*t+y*s;b21=y*z*t-x*s;b22=z*z*t+c;out[0]=a00*b00+a10*b01+a20*b02;out[1]=a01*b00+a11*b01+a21*b02;out[2]=a02*b00+a12*b01+a22*b02;out[3]=a03*b00+a13*b01+a23*b02;out[4]=a00*b10+a10*b11+a20*b12;out[5]=a01*b10+a11*b11+a21*b12;out[6]=a02*b10+a12*b11+a22*b12;out[7]=a03*b10+a13*b11+a23*b12;out[8]=a00*b20+a10*b21+a20*b22;out[9]=a01*b20+a11*b21+a21*b22;out[10]=a02*b20+a12*b21+a22*b22;out[11]=a03*b20+a13*b21+a23*b22;if(a!==out){out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}return out};mat4.rotateX=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[4]=a10*c+a20*s;out[5]=a11*c+a21*s;out[6]=a12*c+a22*s;out[7]=a13*c+a23*s;out[8]=a20*c-a10*s;out[9]=a21*c-a11*s;out[10]=a22*c-a12*s;out[11]=a23*c-a13*s;return out};mat4.rotateY=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c-a20*s;out[1]=a01*c-a21*s;out[2]=a02*c-a22*s;out[3]=a03*c-a23*s;out[8]=a00*s+a20*c;out[9]=a01*s+a21*c;out[10]=a02*s+a22*c;out[11]=a03*s+a23*c;return out};mat4.rotateZ=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7];if(a!==out){out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c+a10*s;out[1]=a01*c+a11*s;out[2]=a02*c+a12*s;out[3]=a03*c+a13*s;out[4]=a10*c-a00*s;out[5]=a11*c-a01*s;out[6]=a12*c-a02*s;out[7]=a13*c-a03*s;return out};mat4.fromRotationTranslation=function(out,q,v){var x=q[0],y=q[1],z=q[2],w=q[3],x2=x+x,y2=y+y,z2=z+z,xx=x*x2,xy=x*y2,xz=x*z2,yy=y*y2,yz=y*z2,zz=z*z2,wx=w*x2,wy=w*y2,wz=w*z2;out[0]=1-(yy+zz);out[1]=xy+wz;out[2]=xz-wy;out[3]=0;out[4]=xy-wz;out[5]=1-(xx+zz);out[6]=yz+wx;out[7]=0;out[8]=xz+wy;out[9]=yz-wx;out[10]=1-(xx+yy);out[11]=0;out[12]=v[0];out[13]=v[1];out[14]=v[2];out[15]=1;return out};mat4.frustum=function(out,left,right,bottom,top,near,far){var rl=1/(right-left),tb=1/(top-bottom),nf=1/(near-far);out[0]=near*2*rl;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=near*2*tb;out[6]=0;out[7]=0;out[8]=(right+left)*rl;out[9]=(top+bottom)*tb;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=far*near*2*nf;out[15]=0;return out};mat4.perspective=function(out,fovy,aspect,near,far){var f=1/Math.tan(fovy/2),nf=1/(near-far);out[0]=f/aspect;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=f;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=2*far*near*nf;out[15]=0;return out};mat4.ortho=function(out,left,right,bottom,top,near,far){var lr=1/(left-right),bt=1/(bottom-top),nf=1/(near-far);out[0]=-2*lr;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=-2*bt;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=2*nf;out[11]=0;out[12]=(left+right)*lr;out[13]=(top+bottom)*bt;out[14]=(far+near)*nf;out[15]=1;return out};mat4.lookAt=function(out,eye,center,up){var x0,x1,x2,y0,y1,y2,z0,z1,z2,len,eyex=eye[0],eyey=eye[1],eyez=eye[2],upx=up[0],upy=up[1],upz=up[2],centerx=center[0],centery=center[1],centerz=center[2];if(Math.abs(eyex-centerx)<GLMAT_EPSILON&&Math.abs(eyey-centery)<GLMAT_EPSILON&&Math.abs(eyez-centerz)<GLMAT_EPSILON){return mat4.identity(out)}z0=eyex-centerx;z1=eyey-centery;z2=eyez-centerz;len=1/Math.sqrt(z0*z0+z1*z1+z2*z2);z0*=len;z1*=len;z2*=len;x0=upy*z2-upz*z1;x1=upz*z0-upx*z2;x2=upx*z1-upy*z0;len=Math.sqrt(x0*x0+x1*x1+x2*x2);if(!len){x0=0;x1=0;x2=0}else{len=1/len;x0*=len;x1*=len;x2*=len}y0=z1*x2-z2*x1;y1=z2*x0-z0*x2;y2=z0*x1-z1*x0;len=Math.sqrt(y0*y0+y1*y1+y2*y2);if(!len){y0=0;y1=0;y2=0}else{len=1/len;y0*=len;y1*=len;y2*=len}out[0]=x0;out[1]=y0;out[2]=z0;out[3]=0;out[4]=x1;out[5]=y1;out[6]=z1;out[7]=0;out[8]=x2;out[9]=y2;out[10]=z2;out[11]=0;out[12]=-(x0*eyex+x1*eyey+x2*eyez);out[13]=-(y0*eyex+y1*eyey+y2*eyez);out[14]=-(z0*eyex+z1*eyey+z2*eyez);out[15]=1;return out};mat4.str=function(a){return"mat4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+")"};if(typeof exports!=="undefined"){exports.mat4=mat4}var quat={};var quatIdentity=new Float32Array([0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}quat.create=function(){return new Float32Array(quatIdentity)};quat.clone=vec4.clone;quat.fromValues=vec4.fromValues;quat.copy=vec4.copy;quat.set=vec4.set;quat.identity=function(out){out[0]=0;out[1]=0;out[2]=0;out[3]=1;return out};quat.setAxisAngle=function(out,axis,rad){rad=rad*.5;var s=Math.sin(rad);out[0]=s*axis[0];out[1]=s*axis[1];out[2]=s*axis[2];out[3]=Math.cos(rad);return out};quat.add=vec4.add;quat.mul=quat.multiply=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=b[3];out[0]=ax*bw+aw*bx+ay*bz-az*by;out[1]=ay*bw+aw*by+az*bx-ax*bz;out[2]=az*bw+aw*bz+ax*by-ay*bx;out[3]=aw*bw-ax*bx-ay*by-az*bz;return out};quat.scale=vec4.scale;quat.rotateX=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+aw*bx;out[1]=ay*bw+az*bx;out[2]=az*bw-ay*bx;out[3]=aw*bw-ax*bx;return out};quat.rotateY=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],by=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw-az*by;out[1]=ay*bw+aw*by;out[2]=az*bw+ax*by;out[3]=aw*bw-ay*by;return out};quat.rotateZ=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bz=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+ay*bz;out[1]=ay*bw-ax*bz;out[2]=az*bw+aw*bz;out[3]=aw*bw-az*bz;return out};quat.calculateW=function(out,a){var x=a[0],y=a[1],z=a[2];out[0]=x;out[1]=y;out[2]=z;out[3]=-Math.sqrt(Math.abs(1-x*x-y*y-z*z));return out};quat.dot=vec4.dot;quat.lerp=vec4.lerp;quat.slerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=a[3];var cosHalfTheta=ax*bx+ay*by+az*bz+aw*bw,halfTheta,sinHalfTheta,ratioA,ratioB;if(Math.abs(cosHalfTheta)>=1){if(out!==a){out[0]=ax;out[1]=ay;out[2]=az;out[3]=aw}return out}halfTheta=Math.acos(cosHalfTheta);sinHalfTheta=Math.sqrt(1-cosHalfTheta*cosHalfTheta);if(Math.abs(sinHalfTheta)<.001){out[0]=ax*.5+bx*.5;out[1]=ay*.5+by*.5;out[2]=az*.5+bz*.5;out[3]=aw*.5+bw*.5;return out}ratioA=Math.sin((1-t)*halfTheta)/sinHalfTheta;ratioB=Math.sin(t*halfTheta)/sinHalfTheta;out[0]=ax*ratioA+bx*ratioB;out[1]=ay*ratioA+by*ratioB;out[2]=az*ratioA+bz*ratioB;out[3]=aw*ratioA+bw*ratioB;return out};quat.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],dot=a0*a0+a1*a1+a2*a2+a3*a3,invDot=dot?1/dot:0;out[0]=-a0*invDot;out[1]=-a1*invDot;out[2]=-a2*invDot;out[3]=a3*invDot;return out};quat.conjugate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=a[3];return out};quat.len=quat.length=vec4.length;quat.sqrLen=quat.squaredLength=vec4.squaredLength;quat.normalize=vec4.normalize;quat.str=function(a){return"quat("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.quat=quat}}(shim.exports)}()}()},{}],20:[function(require,module,exports){!function(){!function(){var root=this;var previousUnderscore=root._;var breaker={};var ArrayProto=Array.prototype,ObjProto=Object.prototype,FuncProto=Function.prototype;var push=ArrayProto.push,slice=ArrayProto.slice,concat=ArrayProto.concat,toString=ObjProto.toString,hasOwnProperty=ObjProto.hasOwnProperty;var nativeForEach=ArrayProto.forEach,nativeMap=ArrayProto.map,nativeReduce=ArrayProto.reduce,nativeReduceRight=ArrayProto.reduceRight,nativeFilter=ArrayProto.filter,nativeEvery=ArrayProto.every,nativeSome=ArrayProto.some,nativeIndexOf=ArrayProto.indexOf,nativeLastIndexOf=ArrayProto.lastIndexOf,nativeIsArray=Array.isArray,nativeKeys=Object.keys,nativeBind=FuncProto.bind;var _=function(obj){if(obj instanceof _)return obj;if(!(this instanceof _))return new _(obj);this._wrapped=obj};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=_}exports._=_}else{root._=_}_.VERSION="1.4.4";var each=_.each=_.forEach=function(obj,iterator,context){if(obj==null)return;if(nativeForEach&&obj.forEach===nativeForEach){obj.forEach(iterator,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){if(iterator.call(context,obj[i],i,obj)===breaker)return}}else{for(var key in obj){if(_.has(obj,key)){if(iterator.call(context,obj[key],key,obj)===breaker)return}}}};_.map=_.collect=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeMap&&obj.map===nativeMap)return obj.map(iterator,context);each(obj,function(value,index,list){results[results.length]=iterator.call(context,value,index,list)});return results};var reduceError="Reduce of empty array with no initial value";_.reduce=_.foldl=_.inject=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduce&&obj.reduce===nativeReduce){if(context)iterator=_.bind(iterator,context);return initial?obj.reduce(iterator,memo):obj.reduce(iterator)}each(obj,function(value,index,list){if(!initial){memo=value;initial=true}else{memo=iterator.call(context,memo,value,index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.reduceRight=_.foldr=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduceRight&&obj.reduceRight===nativeReduceRight){if(context)iterator=_.bind(iterator,context);return initial?obj.reduceRight(iterator,memo):obj.reduceRight(iterator)}var length=obj.length;if(length!==+length){var keys=_.keys(obj);length=keys.length}each(obj,function(value,index,list){index=keys?keys[--length]:--length;if(!initial){memo=obj[index];initial=true}else{memo=iterator.call(context,memo,obj[index],index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.find=_.detect=function(obj,iterator,context){var result;any(obj,function(value,index,list){if(iterator.call(context,value,index,list)){result=value;return true}});return result};_.filter=_.select=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeFilter&&obj.filter===nativeFilter)return obj.filter(iterator,context);each(obj,function(value,index,list){if(iterator.call(context,value,index,list))results[results.length]=value});return results};_.reject=function(obj,iterator,context){return _.filter(obj,function(value,index,list){return!iterator.call(context,value,index,list)},context)};_.every=_.all=function(obj,iterator,context){iterator||(iterator=_.identity);var result=true;if(obj==null)return result;if(nativeEvery&&obj.every===nativeEvery)return obj.every(iterator,context);each(obj,function(value,index,list){if(!(result=result&&iterator.call(context,value,index,list)))return breaker});return!!result};var any=_.some=_.any=function(obj,iterator,context){iterator||(iterator=_.identity);var result=false;if(obj==null)return result;if(nativeSome&&obj.some===nativeSome)return obj.some(iterator,context);each(obj,function(value,index,list){if(result||(result=iterator.call(context,value,index,list)))return breaker});return!!result};_.contains=_.include=function(obj,target){if(obj==null)return false;if(nativeIndexOf&&obj.indexOf===nativeIndexOf)return obj.indexOf(target)!=-1;return any(obj,function(value){return value===target})};_.invoke=function(obj,method){var args=slice.call(arguments,2);var isFunc=_.isFunction(method);return _.map(obj,function(value){return(isFunc?method:value[method]).apply(value,args)})};_.pluck=function(obj,key){return _.map(obj,function(value){return value[key]})};_.where=function(obj,attrs,first){if(_.isEmpty(attrs))return first?null:[];return _[first?"find":"filter"](obj,function(value){for(var key in attrs){if(attrs[key]!==value[key])return false}return true})};_.findWhere=function(obj,attrs){return _.where(obj,attrs,true)};_.max=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.max.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return-Infinity;var result={computed:-Infinity,value:-Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed>=result.computed&&(result={value:value,computed:computed})});return result.value};_.min=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.min.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return Infinity;var result={computed:Infinity,value:Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed<result.computed&&(result={value:value,computed:computed})});return result.value};_.shuffle=function(obj){var rand;var index=0;var shuffled=[];each(obj,function(value){rand=_.random(index++);shuffled[index-1]=shuffled[rand];shuffled[rand]=value});return shuffled};var lookupIterator=function(value){return _.isFunction(value)?value:function(obj){return obj[value]}};_.sortBy=function(obj,value,context){var iterator=lookupIterator(value);return _.pluck(_.map(obj,function(value,index,list){return{value:value,index:index,criteria:iterator.call(context,value,index,list)}}).sort(function(left,right){var a=left.criteria;
+var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)return-1}return left.index<right.index?-1:1}),"value")};var group=function(obj,value,context,behavior){var result={};var iterator=lookupIterator(value||_.identity);each(obj,function(value,index){var key=iterator.call(context,value,index,obj);behavior(result,key,value)});return result};_.groupBy=function(obj,value,context){return group(obj,value,context,function(result,key,value){(_.has(result,key)?result[key]:result[key]=[]).push(value)})};_.countBy=function(obj,value,context){return group(obj,value,context,function(result,key){if(!_.has(result,key))result[key]=0;result[key]++})};_.sortedIndex=function(array,obj,iterator,context){iterator=iterator==null?_.identity:lookupIterator(iterator);var value=iterator.call(context,obj);var low=0,high=array.length;while(low<high){var mid=low+high>>>1;iterator.call(context,array[mid])<value?low=mid+1:high=mid}return low};_.toArray=function(obj){if(!obj)return[];if(_.isArray(obj))return slice.call(obj);if(obj.length===+obj.length)return _.map(obj,_.identity);return _.values(obj)};_.size=function(obj){if(obj==null)return 0;return obj.length===+obj.length?obj.length:_.keys(obj).length};_.first=_.head=_.take=function(array,n,guard){if(array==null)return void 0;return n!=null&&!guard?slice.call(array,0,n):array[0]};_.initial=function(array,n,guard){return slice.call(array,0,array.length-(n==null||guard?1:n))};_.last=function(array,n,guard){if(array==null)return void 0;if(n!=null&&!guard){return slice.call(array,Math.max(array.length-n,0))}else{return array[array.length-1]}};_.rest=_.tail=_.drop=function(array,n,guard){return slice.call(array,n==null||guard?1:n)};_.compact=function(array){return _.filter(array,_.identity)};var flatten=function(input,shallow,output){each(input,function(value){if(_.isArray(value)){shallow?push.apply(output,value):flatten(value,shallow,output)}else{output.push(value)}});return output};_.flatten=function(array,shallow){return flatten(array,shallow,[])};_.without=function(array){return _.difference(array,slice.call(arguments,1))};_.uniq=_.unique=function(array,isSorted,iterator,context){if(_.isFunction(isSorted)){context=iterator;iterator=isSorted;isSorted=false}var initial=iterator?_.map(array,iterator,context):array;var results=[];var seen=[];each(initial,function(value,index){if(isSorted?!index||seen[seen.length-1]!==value:!_.contains(seen,value)){seen.push(value);results.push(array[index])}});return results};_.union=function(){return _.uniq(concat.apply(ArrayProto,arguments))};_.intersection=function(array){var rest=slice.call(arguments,1);return _.filter(_.uniq(array),function(item){return _.every(rest,function(other){return _.indexOf(other,item)>=0})})};_.difference=function(array){var rest=concat.apply(ArrayProto,slice.call(arguments,1));return _.filter(array,function(value){return!_.contains(rest,value)})};_.zip=function(){var args=slice.call(arguments);var length=_.max(_.pluck(args,"length"));var results=new Array(length);for(var i=0;i<length;i++){results[i]=_.pluck(args,""+i)}return results};_.object=function(list,values){if(list==null)return{};var result={};for(var i=0,l=list.length;i<l;i++){if(values){result[list[i]]=values[i]}else{result[list[i][0]]=list[i][1]}}return result};_.indexOf=function(array,item,isSorted){if(array==null)return-1;var i=0,l=array.length;if(isSorted){if(typeof isSorted=="number"){i=isSorted<0?Math.max(0,l+isSorted):isSorted}else{i=_.sortedIndex(array,item);return array[i]===item?i:-1}}if(nativeIndexOf&&array.indexOf===nativeIndexOf)return array.indexOf(item,isSorted);for(;i<l;i++)if(array[i]===item)return i;return-1};_.lastIndexOf=function(array,item,from){if(array==null)return-1;var hasIndex=from!=null;if(nativeLastIndexOf&&array.lastIndexOf===nativeLastIndexOf){return hasIndex?array.lastIndexOf(item,from):array.lastIndexOf(item)}var i=hasIndex?from:array.length;while(i--)if(array[i]===item)return i;return-1};_.range=function(start,stop,step){if(arguments.length<=1){stop=start||0;start=0}step=arguments[2]||1;var len=Math.max(Math.ceil((stop-start)/step),0);var idx=0;var range=new Array(len);while(idx<len){range[idx++]=start;start+=step}return range};_.bind=function(func,context){if(func.bind===nativeBind&&nativeBind)return nativeBind.apply(func,slice.call(arguments,1));var args=slice.call(arguments,2);return function(){return func.apply(context,args.concat(slice.call(arguments)))}};_.partial=function(func){var args=slice.call(arguments,1);return function(){return func.apply(this,args.concat(slice.call(arguments)))}};_.bindAll=function(obj){var funcs=slice.call(arguments,1);if(funcs.length===0)funcs=_.functions(obj);each(funcs,function(f){obj[f]=_.bind(obj[f],obj)});return obj};_.memoize=function(func,hasher){var memo={};hasher||(hasher=_.identity);return function(){var key=hasher.apply(this,arguments);return _.has(memo,key)?memo[key]:memo[key]=func.apply(this,arguments)}};_.delay=function(func,wait){var args=slice.call(arguments,2);return setTimeout(function(){return func.apply(null,args)},wait)};_.defer=function(func){return _.delay.apply(_,[func,1].concat(slice.call(arguments,1)))};_.throttle=function(func,wait){var context,args,timeout,result;var previous=0;var later=function(){previous=new Date;timeout=null;result=func.apply(context,args)};return function(){var now=new Date;var remaining=wait-(now-previous);context=this;args=arguments;if(remaining<=0){clearTimeout(timeout);timeout=null;previous=now;result=func.apply(context,args)}else if(!timeout){timeout=setTimeout(later,remaining)}return result}};_.debounce=function(func,wait,immediate){var timeout,result;return function(){var context=this,args=arguments;var later=function(){timeout=null;if(!immediate)result=func.apply(context,args)};var callNow=immediate&&!timeout;clearTimeout(timeout);timeout=setTimeout(later,wait);if(callNow)result=func.apply(context,args);return result}};_.once=function(func){var ran=false,memo;return function(){if(ran)return memo;ran=true;memo=func.apply(this,arguments);func=null;return memo}};_.wrap=function(func,wrapper){return function(){var args=[func];push.apply(args,arguments);return wrapper.apply(this,args)}};_.compose=function(){var funcs=arguments;return function(){var args=arguments;for(var i=funcs.length-1;i>=0;i--){args=[funcs[i].apply(this,args)]}return args[0]}};_.after=function(times,func){if(times<=0)return func();return function(){if(--times<1){return func.apply(this,arguments)}}};_.keys=nativeKeys||function(obj){if(obj!==Object(obj))throw new TypeError("Invalid object");var keys=[];for(var key in obj)if(_.has(obj,key))keys[keys.length]=key;return keys};_.values=function(obj){var values=[];for(var key in obj)if(_.has(obj,key))values.push(obj[key]);return values};_.pairs=function(obj){var pairs=[];for(var key in obj)if(_.has(obj,key))pairs.push([key,obj[key]]);return pairs};_.invert=function(obj){var result={};for(var key in obj)if(_.has(obj,key))result[obj[key]]=key;return result};_.functions=_.methods=function(obj){var names=[];for(var key in obj){if(_.isFunction(obj[key]))names.push(key)}return names.sort()};_.extend=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){obj[prop]=source[prop]}}});return obj};_.pick=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));each(keys,function(key){if(key in obj)copy[key]=obj[key]});return copy};_.omit=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));for(var key in obj){if(!_.contains(keys,key))copy[key]=obj[key]}return copy};_.defaults=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){if(obj[prop]==null)obj[prop]=source[prop]}}});return obj};_.clone=function(obj){if(!_.isObject(obj))return obj;return _.isArray(obj)?obj.slice():_.extend({},obj)};_.tap=function(obj,interceptor){interceptor(obj);return obj};var eq=function(a,b,aStack,bStack){if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;if(a instanceof _)a=a._wrapped;if(b instanceof _)b=b._wrapped;var className=toString.call(a);if(className!=toString.call(b))return false;switch(className){case"[object String]":return a==String(b);case"[object Number]":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case"[object Date]":case"[object Boolean]":return+a==+b;case"[object RegExp]":return a.source==b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return false;var length=aStack.length;while(length--){if(aStack[length]==a)return bStack[length]==b}aStack.push(a);bStack.push(b);var size=0,result=true;if(className=="[object Array]"){size=a.length;result=size==b.length;if(result){while(size--){if(!(result=eq(a[size],b[size],aStack,bStack)))break}}}else{var aCtor=a.constructor,bCtor=b.constructor;if(aCtor!==bCtor&&!(_.isFunction(aCtor)&&aCtor instanceof aCtor&&_.isFunction(bCtor)&&bCtor instanceof bCtor)){return false}for(var key in a){if(_.has(a,key)){size++;if(!(result=_.has(b,key)&&eq(a[key],b[key],aStack,bStack)))break}}if(result){for(key in b){if(_.has(b,key)&&!size--)break}result=!size}}aStack.pop();bStack.pop();return result};_.isEqual=function(a,b){return eq(a,b,[],[])};_.isEmpty=function(obj){if(obj==null)return true;if(_.isArray(obj)||_.isString(obj))return obj.length===0;for(var key in obj)if(_.has(obj,key))return false;return true};_.isElement=function(obj){return!!(obj&&obj.nodeType===1)};_.isArray=nativeIsArray||function(obj){return toString.call(obj)=="[object Array]"};_.isObject=function(obj){return obj===Object(obj)};each(["Arguments","Function","String","Number","Date","RegExp"],function(name){_["is"+name]=function(obj){return toString.call(obj)=="[object "+name+"]"}});if(!_.isArguments(arguments)){_.isArguments=function(obj){return!!(obj&&_.has(obj,"callee"))}}if(typeof/./!=="function"){_.isFunction=function(obj){return typeof obj==="function"}}_.isFinite=function(obj){return isFinite(obj)&&!isNaN(parseFloat(obj))};_.isNaN=function(obj){return _.isNumber(obj)&&obj!=+obj};_.isBoolean=function(obj){return obj===true||obj===false||toString.call(obj)=="[object Boolean]"};_.isNull=function(obj){return obj===null};_.isUndefined=function(obj){return obj===void 0};_.has=function(obj,key){return hasOwnProperty.call(obj,key)};_.noConflict=function(){root._=previousUnderscore;return this};_.identity=function(value){return value};_.times=function(n,iterator,context){var accum=Array(n);for(var i=0;i<n;i++)accum[i]=iterator.call(context,i);return accum};_.random=function(min,max){if(max==null){max=min;min=0}return min+Math.floor(Math.random()*(max-min+1))};var entityMap={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};entityMap.unescape=_.invert(entityMap.escape);var entityRegexes={escape:new RegExp("["+_.keys(entityMap.escape).join("")+"]","g"),unescape:new RegExp("("+_.keys(entityMap.unescape).join("|")+")","g")};_.each(["escape","unescape"],function(method){_[method]=function(string){if(string==null)return"";return(""+string).replace(entityRegexes[method],function(match){return entityMap[method][match]})}});_.result=function(object,property){if(object==null)return null;var value=object[property];return _.isFunction(value)?value.call(object):value};_.mixin=function(obj){each(_.functions(obj),function(name){var func=_[name]=obj[name];_.prototype[name]=function(){var args=[this._wrapped];push.apply(args,arguments);return result.call(this,func.apply(_,args))}})};var idCounter=0;_.uniqueId=function(prefix){var id=++idCounter+"";return prefix?prefix+id:id};_.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var noMatch=/(.)^/;var escapes={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"};var escaper=/\\|'|\r|\n|\t|\u2028|\u2029/g;_.template=function(text,data,settings){var render;settings=_.defaults({},settings,_.templateSettings);var matcher=new RegExp([(settings.escape||noMatch).source,(settings.interpolate||noMatch).source,(settings.evaluate||noMatch).source].join("|")+"|$","g");var index=0;var source="__p+='";text.replace(matcher,function(match,escape,interpolate,evaluate,offset){source+=text.slice(index,offset).replace(escaper,function(match){return"\\"+escapes[match]});if(escape){source+="'+\n((__t=("+escape+"))==null?'':_.escape(__t))+\n'"}if(interpolate){source+="'+\n((__t=("+interpolate+"))==null?'':__t)+\n'"}if(evaluate){source+="';\n"+evaluate+"\n__p+='"}index=offset+match.length;return match});source+="';\n";if(!settings.variable)source="with(obj||{}){\n"+source+"}\n";source="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+source+"return __p;\n";try{render=new Function(settings.variable||"obj","_",source)}catch(e){e.source=source;throw e}if(data)return render(data,_);var template=function(data){return render.call(this,data,_)};template.source="function("+(settings.variable||"obj")+"){\n"+source+"}";return template};_.chain=function(obj){return _(obj).chain()};var result=function(obj){return this._chain?_(obj).chain():obj};_.mixin(_);each(["pop","push","reverse","shift","sort","splice","unshift"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){var obj=this._wrapped;method.apply(obj,arguments);if((name=="shift"||name=="splice")&&obj.length===0)delete obj[0];return result.call(this,obj)}});each(["concat","join","slice"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){return result.call(this,method.apply(this._wrapped,arguments))}});_.extend(_.prototype,{chain:function(){this._chain=true;return this},value:function(){return this._wrapped}})}.call(this)}()},{}],21:[function(require,module,exports){window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){window.setTimeout(callback,1e3/60)}}();Leap=require("../lib/index")},{"../lib/index":8}]},{},[21]);
+
+/*
+ * Leap Motion integration for Reveal.js.
+ * James Sun  [sun16]
+ * Rory Hardy [gneatgeek]
+ */
+
+(function () {
+  var body        = document.body,
+      controller  = new Leap.Controller({ enableGestures: true }),
+      lastGesture = 0,
+      leapConfig  = Reveal.getConfig().leap,
+      pointer     = document.createElement( 'div' ),
+      config      = {
+        autoCenter       : true,      // Center pointer around detected position.
+        gestureDelay     : 500,       // How long to delay between gestures.
+        naturalSwipe     : true,      // Swipe as if it were a touch screen.
+        pointerColor     : '#00aaff', // Default color of the pointer.
+        pointerOpacity   : 0.7,       // Default opacity of the pointer.
+        pointerSize      : 15,        // Default minimum height/width of the pointer.
+        pointerTolerance : 120        // Bigger = slower pointer.
+      },
+      entered, enteredPosition, now, size, tipPosition; // Other vars we need later, but don't need to redeclare.
+
+      // Merge user defined settings with defaults
+      if( leapConfig ) {
+        for( key in leapConfig ) {
+          config[key] = leapConfig[key];
+        }
+      }
+
+      pointer.id = 'leap';
+
+      pointer.style.position        = 'absolute';
+      pointer.style.visibility      = 'hidden';
+      pointer.style.zIndex          = 50;
+      pointer.style.opacity         = config.pointerOpacity;
+      pointer.style.backgroundColor = config.pointerColor;
+
+      body.appendChild( pointer );
+
+  // Leap's loop
+  controller.on( 'frame', function ( frame ) {
+    // Timing code to rate limit gesture execution
+    now = new Date().getTime();
+
+    // Pointer: 1 to 2 fingers. Strictly one finger works but may cause innaccuracies.
+    // The innaccuracies were observed on a development model and may not be an issue with consumer models.
+    if( frame.fingers.length > 0 && frame.fingers.length < 3 ) {
+      // Invert direction and multiply by 3 for greater effect.
+      size = -3 * frame.fingers[0].tipPosition[2];
+
+      if( size < config.pointerSize ) {
+        size = config.pointerSize;
+      }
+
+      pointer.style.width        = size     + 'px';
+      pointer.style.height       = size     + 'px';
+      pointer.style.borderRadius = size - 5 + 'px';
+      pointer.style.visibility   = 'visible';
+
+      if( config.autoCenter ) {
+        tipPosition = frame.fingers[0].tipPosition;
+
+        // Check whether the finger has entered the z range of the Leap Motion. Used for the autoCenter option.
+        if( !entered ) {
+          entered         = true;
+          enteredPosition = frame.fingers[0].tipPosition;
+        }
+
+        pointer.style.top =
+          (-1 * (( tipPosition[1] - enteredPosition[1] ) * body.offsetHeight / config.pointerTolerance )) +
+            ( body.offsetHeight / 2 ) + 'px';
+
+        pointer.style.left =
+          (( tipPosition[0] - enteredPosition[0] ) * body.offsetWidth / config.pointerTolerance ) +
+            ( body.offsetWidth / 2 ) + 'px';
+      }
+      else {
+        pointer.style.top  = ( 1 - (( tipPosition[1] - 50) / config.pointerTolerance )) *
+          body.offsetHeight + 'px';
+
+        pointer.style.left = ( tipPosition[0] * body.offsetWidth / config.pointerTolerance ) +
+          ( body.offsetWidth / 2 ) + 'px';
+      }
+    }
+    else {
+      // Hide pointer on exit
+      entered                  = false;
+      pointer.style.visibility = 'hidden';
+    }
+
+    // Gestures
+    if( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) {
+      var gesture = frame.gestures[0];
+
+      // One hand gestures
+      if( frame.hands.length === 1 ) {
+        // Swipe gestures. 3+ fingers.
+        if( frame.fingers.length > 2 && gesture.type === 'swipe' ) {
+          // Define here since some gestures will throw undefined for these.
+          var x = gesture.direction[0],
+              y = gesture.direction[1];
+
+          // Left/right swipe gestures
+          if( Math.abs( x ) > Math.abs( y )) {
+            if( x > 0 ) {
+              config.naturalSwipe ? Reveal.left() : Reveal.right();
+            }
+            else {
+              config.naturalSwipe ? Reveal.right() : Reveal.left();
+            }
+          }
+          // Up/down swipe gestures
+          else {
+            if( y > 0 ) {
+              config.naturalSwipe ? Reveal.down() : Reveal.up();
+            }
+            else {
+              config.naturalSwipe ? Reveal.up() : Reveal.down();
+            }
+          }
+
+          lastGesture = now;
+        }
+      }
+      // Two hand gestures
+      else if( frame.hands.length === 2 ) {
+        // Upward two hand swipe gesture
+        if( gesture.direction[1] > 0 && gesture.type === 'swipe' ) {
+          Reveal.toggleOverview();
+        }
+
+        lastGesture = now;
+      }
+    }
+  });
+
+  controller.connect();
+})();
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/markdown/example.html b/docs/slides/BOS14/_support/reveal.js/plugin/markdown/example.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/markdown/example.html
@@ -0,0 +1,129 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Markdown Demo</title>
+
+		<link rel="stylesheet" href="../../css/reveal.css">
+		<link rel="stylesheet" href="../../css/theme/default.css" id="theme">
+
+        <link rel="stylesheet" href="../../lib/css/zenburn.css">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+                <!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
+                <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section>
+
+                <!-- Slides are separated by three dashes (quick 'n dirty regular expression) -->
+                <section data-markdown data-separator="---">
+                    <script type="text/template">
+                        ## Demo 1
+                        Slide 1
+                        ---
+                        ## Demo 1
+                        Slide 2
+                        ---
+                        ## Demo 1
+                        Slide 3
+                    </script>
+                </section>
+
+                <!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
+                <section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$">
+                    <script type="text/template">
+                        ## Demo 2
+                        Slide 1.1
+
+                        --
+
+                        ## Demo 2
+                        Slide 1.2
+
+                        ---
+
+                        ## Demo 2
+                        Slide 2
+                    </script>
+                </section>
+
+                <!-- No "extra" slides, since there are no separators defined (so they'll become horizontal rulers) -->
+                <section data-markdown>
+                    <script type="text/template">
+                        A
+
+                        ---
+
+                        B
+
+                        ---
+
+                        C
+                    </script>
+                </section>
+
+                <!-- Slide attributes -->
+                <section data-markdown>
+                    <script type="text/template">
+                        <!-- .slide: data-background="#000000" -->
+                        ## Slide attributes
+                    </script>
+                </section>
+
+                <!-- Element attributes -->
+                <section data-markdown>
+                    <script type="text/template">
+                        ## Element attributes
+                        - Item 1 <!-- .element: class="fragment" data-fragment-index="2" -->
+                        - Item 2 <!-- .element: class="fragment" data-fragment-index="1" -->
+                    </script>
+                </section>
+
+                <!-- Code -->
+                <section data-markdown>
+                    <script type="text/template">
+                        ```php
+                        public function foo()
+                        {
+                            $foo = array(
+                                'bar' => 'bar'
+                            )
+                        }
+                        ```
+                    </script>
+                </section>
+
+            </div>
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.js"></script>
+
+		<script>
+
+			Reveal.initialize({
+				controls: true,
+				progress: true,
+				history: true,
+				center: true,
+
+				// Optional libraries used to extend on reveal.js
+				dependencies: [
+					{ src: '../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
+					{ src: 'marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                    { src: 'markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                    { src: '../highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+					{ src: '../notes/notes.js' }
+				]
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/markdown/example.md b/docs/slides/BOS14/_support/reveal.js/plugin/markdown/example.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/markdown/example.md
@@ -0,0 +1,31 @@
+# Markdown Demo
+
+
+
+## External 1.1
+
+Content 1.1
+
+Note: This will only appear in the speaker notes window.
+
+
+## External 1.2
+
+Content 1.2
+
+
+
+## External 2
+
+Content 2.1
+
+
+
+## External 3.1
+
+Content 3.1
+
+
+## External 3.2
+
+Content 3.2
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/markdown/markdown.js b/docs/slides/BOS14/_support/reveal.js/plugin/markdown/markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/markdown/markdown.js
@@ -0,0 +1,392 @@
+/**
+ * The reveal.js markdown plugin. Handles parsing of
+ * markdown inside of presentations as well as loading
+ * of external markdown documents.
+ */
+(function( root, factory ) {
+	if( typeof exports === 'object' ) {
+		module.exports = factory( require( './marked' ) );
+	}
+	else {
+		// Browser globals (root is window)
+		root.RevealMarkdown = factory( root.marked );
+		root.RevealMarkdown.initialize();
+	}
+}( this, function( marked ) {
+
+	if( typeof marked === 'undefined' ) {
+		throw 'The reveal.js Markdown plugin requires marked to be loaded';
+	}
+
+	if( typeof hljs !== 'undefined' ) {
+		marked.setOptions({
+			highlight: function( lang, code ) {
+				return hljs.highlightAuto( lang, code ).value;
+			}
+		});
+	}
+
+	var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$',
+		DEFAULT_NOTES_SEPARATOR = 'note:',
+		DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
+		DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
+
+
+	/**
+	 * Retrieves the markdown contents of a slide section
+	 * element. Normalizes leading tabs/whitespace.
+	 */
+	function getMarkdownFromSlide( section ) {
+
+		var template = section.querySelector( 'script' );
+
+		// strip leading whitespace so it isn't evaluated as code
+		var text = ( template || section ).textContent;
+
+		var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
+			leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
+
+		if( leadingTabs > 0 ) {
+			text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+		}
+		else if( leadingWs > 1 ) {
+			text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+		}
+
+		return text;
+
+	}
+
+	/**
+	 * Given a markdown slide section element, this will
+	 * return all arguments that aren't related to markdown
+	 * parsing. Used to forward any other user-defined arguments
+	 * to the output markdown slide.
+	 */
+	function getForwardedAttributes( section ) {
+
+		var attributes = section.attributes;
+		var result = [];
+
+		for( var i = 0, len = attributes.length; i < len; i++ ) {
+			var name = attributes[i].name,
+				value = attributes[i].value;
+
+			// disregard attributes that are used for markdown loading/parsing
+			if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
+
+			if( value ) {
+				result.push( name + '=' + value );
+			}
+			else {
+				result.push( name );
+			}
+		}
+
+		return result.join( ' ' );
+
+	}
+
+	/**
+	 * Inspects the given options and fills out default
+	 * values for what's not defined.
+	 */
+	function getSlidifyOptions( options ) {
+
+		options = options || {};
+		options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
+		options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
+		options.attributes = options.attributes || '';
+
+		return options;
+
+	}
+
+	/**
+	 * Helper function for constructing a markdown slide.
+	 */
+	function createMarkdownSlide( content, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
+
+		if( notesMatch.length === 2 ) {
+			content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
+		}
+
+		return '<script type="text/template">' + content + '</script>';
+
+	}
+
+	/**
+	 * Parses a data string into multiple slides based
+	 * on the passed in separator arguments.
+	 */
+	function slidify( markdown, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
+			horizontalSeparatorRegex = new RegExp( options.separator );
+
+		var matches,
+			lastIndex = 0,
+			isHorizontal,
+			wasHorizontal = true,
+			content,
+			sectionStack = [];
+
+		// iterate until all blocks between separators are stacked up
+		while( matches = separatorRegex.exec( markdown ) ) {
+			notes = null;
+
+			// determine direction (horizontal by default)
+			isHorizontal = horizontalSeparatorRegex.test( matches[0] );
+
+			if( !isHorizontal && wasHorizontal ) {
+				// create vertical stack
+				sectionStack.push( [] );
+			}
+
+			// pluck slide content from markdown input
+			content = markdown.substring( lastIndex, matches.index );
+
+			if( isHorizontal && wasHorizontal ) {
+				// add to horizontal stack
+				sectionStack.push( content );
+			}
+			else {
+				// add to vertical stack
+				sectionStack[sectionStack.length-1].push( content );
+			}
+
+			lastIndex = separatorRegex.lastIndex;
+			wasHorizontal = isHorizontal;
+		}
+
+		// add the remaining slide
+		( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
+
+		var markdownSections = '';
+
+		// flatten the hierarchical stack, and insert <section data-markdown> tags
+		for( var i = 0, len = sectionStack.length; i < len; i++ ) {
+			// vertical
+			if( sectionStack[i] instanceof Array ) {
+				markdownSections += '<section '+ options.attributes +'>';
+
+				sectionStack[i].forEach( function( child ) {
+					markdownSections += '<section data-markdown>' +  createMarkdownSlide( child, options ) + '</section>';
+				} );
+
+				markdownSections += '</section>';
+			}
+			else {
+				markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
+			}
+		}
+
+		return markdownSections;
+
+	}
+
+	/**
+	 * Parses any current data-markdown slides, splits
+	 * multi-slide markdown into separate sections and
+	 * handles loading of external markdown.
+	 */
+	function processSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]'),
+			section;
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			section = sections[i];
+
+			if( section.getAttribute( 'data-markdown' ).length ) {
+
+				var xhr = new XMLHttpRequest(),
+					url = section.getAttribute( 'data-markdown' );
+
+				datacharset = section.getAttribute( 'data-charset' );
+
+				// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
+				if( datacharset != null && datacharset != '' ) {
+					xhr.overrideMimeType( 'text/html; charset=' + datacharset );
+				}
+
+				xhr.onreadystatechange = function() {
+					if( xhr.readyState === 4 ) {
+						if ( xhr.status >= 200 && xhr.status < 300 ) {
+
+							section.outerHTML = slidify( xhr.responseText, {
+								separator: section.getAttribute( 'data-separator' ),
+								verticalSeparator: section.getAttribute( 'data-vertical' ),
+								notesSeparator: section.getAttribute( 'data-notes' ),
+								attributes: getForwardedAttributes( section )
+							});
+
+						}
+						else {
+
+							section.outerHTML = '<section data-state="alert">' +
+								'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
+								'Check your browser\'s JavaScript console for more details.' +
+								'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
+								'</section>';
+
+						}
+					}
+				};
+
+				xhr.open( 'GET', url, false );
+
+				try {
+					xhr.send();
+				}
+				catch ( e ) {
+					alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
+				}
+
+			}
+			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) {
+
+				section.outerHTML = slidify( getMarkdownFromSlide( section ), {
+					separator: section.getAttribute( 'data-separator' ),
+					verticalSeparator: section.getAttribute( 'data-vertical' ),
+					notesSeparator: section.getAttribute( 'data-notes' ),
+					attributes: getForwardedAttributes( section )
+				});
+
+			}
+			else {
+				section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
+			}
+		}
+
+	}
+
+	/**
+	 * Check if a node value has the attributes pattern.
+	 * If yes, extract it and add that value as one or several attributes
+	 * the the terget element.
+	 *
+	 * You need Cache Killer on Chrome to see the effect on any FOM transformation
+	 * directly on refresh (F5)
+	 * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
+	 */
+	function addAttributeInElement( node, elementTarget, separator ) {
+
+		var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
+		var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
+		var nodeValue = node.nodeValue;
+		if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
+
+			var classes = matches[1];
+			nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
+			node.nodeValue = nodeValue;
+			while( matchesClass = mardownClassRegex.exec( classes ) ) {
+				elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Add attributes to the parent element of a text node,
+	 * or the element of an attribute node.
+	 */
+	function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
+
+		if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
+			previousParentElement = element;
+			for( var i = 0; i < element.childNodes.length; i++ ) {
+				childElement = element.childNodes[i];
+				if ( i > 0 ) {
+					j = i - 1;
+					while ( j >= 0 ) {
+						aPreviousChildElement = element.childNodes[j];
+						if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
+							previousParentElement = aPreviousChildElement;
+							break;
+						}
+						j = j - 1;
+					}
+				}
+				parentSection = section;
+				if( childElement.nodeName ==  "section" ) {
+					parentSection = childElement ;
+					previousParentElement = childElement ;
+				}
+				if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
+					addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
+				}
+			}
+		}
+
+		if ( element.nodeType == Node.COMMENT_NODE ) {
+			if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
+				addAttributeInElement( element, section, separatorSectionAttributes );
+			}
+		}
+	}
+
+	/**
+	 * Converts any current data-markdown slides in the
+	 * DOM to HTML.
+	 */
+	function convertSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]');
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			var section = sections[i];
+
+			// Only parse the same slide once
+			if( !section.getAttribute( 'data-markdown-parsed' ) ) {
+
+				section.setAttribute( 'data-markdown-parsed', true )
+
+				var notes = section.querySelector( 'aside.notes' );
+				var markdown = getMarkdownFromSlide( section );
+
+				section.innerHTML = marked( markdown );
+				addAttributes( 	section, section, null, section.getAttribute( 'data-element-attributes' ) ||
+								section.parentNode.getAttribute( 'data-element-attributes' ) ||
+								DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
+								section.getAttribute( 'data-attributes' ) ||
+								section.parentNode.getAttribute( 'data-attributes' ) ||
+								DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
+
+				// If there were notes, we need to re-add them after
+				// having overwritten the section's HTML
+				if( notes ) {
+					section.appendChild( notes );
+				}
+
+			}
+
+		}
+
+	}
+
+	// API
+	return {
+
+		initialize: function() {
+			processSlides();
+			convertSlides();
+		},
+
+		// TODO: Do these belong in the API?
+		processSlides: processSlides,
+		convertSlides: convertSlides,
+		slidify: slidify
+
+	};
+
+}));
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/markdown/marked.js b/docs/slides/BOS14/_support/reveal.js/plugin/markdown/marked.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/markdown/marked.js
@@ -0,0 +1,37 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){3,} *\n*/,blockquote:/^( *>[^\n]+(\n[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr",/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";block.html=replace(block.html)("comment",/\x3c!--[\s\S]*?--\x3e/)("closed",
+/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1",
+"\\2")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm)if(this.options.tables)this.rules=block.tables;else this.rules=block.gfm}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};
+Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1)this.tokens.push({type:"space"})}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,
+"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,
+"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]="center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].split(/ *\| */);this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=
+src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);
+bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+
+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item[item.length-1]==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:cap[1]==="pre"||cap[1]==="script",text:cap[0]});continue}if(top&&
+(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]=
+"center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */);this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1][cap[1].length-1]==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",
+text:cap[0]});continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^\x3c!--[\s\S]*?--\x3e|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;
+if(!this.links)throw new Error("Tokens array requires a `links` property.");if(this.options.gfm)if(this.options.breaks)this.rules=inline.breaks;else this.rules=inline.gfm;else if(this.options.pedantic)this.rules=inline.pedantic}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);
+out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1][6]===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.url.exec(src)){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.tag.exec(src)){src=src.substring(cap[0].length);
+out+=this.options.sanitize?escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);out+=this.outputLink(cap,{href:cap[2],title:cap[3]});continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0][0];src=cap[0].substring(1)+src;continue}out+=this.outputLink(cap,link);continue}if(cap=this.rules.strong.exec(src)){src=
+src.substring(cap[0].length);out+="<strong>"+this.output(cap[2]||cap[1])+"</strong>";continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+="<em>"+this.output(cap[2]||cap[1])+"</em>";continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+="<code>"+escape(cap[2],true)+"</code>";continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+="<br>";continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+="<del>"+
+this.output(cap[1])+"</del>";continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=escape(cap[0]);continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return out};InlineLexer.prototype.outputLink=function(cap,link){if(cap[0][0]!=="!")return'<a href="'+escape(link.href)+'"'+(link.title?' title="'+escape(link.title)+'"':"")+">"+this.output(cap[1])+"</a>";else return'<img src="'+escape(link.href)+'" alt="'+escape(cap[1])+'"'+(link.title?' title="'+
+escape(link.title)+'"':"")+">"};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/--/g,"\u2014").replace(/'([^']*)'/g,"\u2018$1\u2019").replace(/"([^"]*)"/g,"\u201c$1\u201d").replace(/\.{3}/g,"\u2026")};InlineLexer.prototype.mangle=function(text){var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>0.5)ch="x"+ch.toString(16);out+="&#"+ch+";"}return out};function Parser(options){this.tokens=[];this.token=null;
+this.options=options||marked.defaults}Parser.parse=function(src,options){var parser=new Parser(options);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options);this.tokens=src.reverse();var out="";while(this.next())out+=this.tok();return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;
+while(this.peek().type==="text")body+="\n"+this.next().text;return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case "space":return"";case "hr":return"<hr>\n";case "heading":return"<h"+this.token.depth+">"+this.inline.output(this.token.text)+"</h"+this.token.depth+">\n";case "code":if(this.options.highlight){var code=this.options.highlight(this.token.text,this.token.lang);if(code!=null&&code!==this.token.text){this.token.escaped=true;this.token.text=code}}if(!this.token.escaped)this.token.text=
+escape(this.token.text,true);return"<pre><code"+(this.token.lang?' class="'+this.options.langPrefix+this.token.lang+'"':"")+">"+this.token.text+"</code></pre>\n";case "table":var body="",heading,i,row,cell,j;body+="<thead>\n<tr>\n";for(i=0;i<this.token.header.length;i++){heading=this.inline.output(this.token.header[i]);body+=this.token.align[i]?'<th align="'+this.token.align[i]+'">'+heading+"</th>\n":"<th>"+heading+"</th>\n"}body+="</tr>\n</thead>\n";body+="<tbody>\n";for(i=0;i<this.token.cells.length;i++){row=
+this.token.cells[i];body+="<tr>\n";for(j=0;j<row.length;j++){cell=this.inline.output(row[j]);body+=this.token.align[j]?'<td align="'+this.token.align[j]+'">'+cell+"</td>\n":"<td>"+cell+"</td>\n"}body+="</tr>\n"}body+="</tbody>\n";return"<table>\n"+body+"</table>\n";case "blockquote_start":var body="";while(this.next().type!=="blockquote_end")body+=this.tok();return"<blockquote>\n"+body+"</blockquote>\n";case "list_start":var type=this.token.ordered?"ol":"ul",body="";while(this.next().type!=="list_end")body+=
+this.tok();return"<"+type+">\n"+body+"</"+type+">\n";case "list_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.token.type==="text"?this.parseText():this.tok();return"<li>"+body+"</li>\n";case "loose_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.tok();return"<li>"+body+"</li>\n";case "html":return!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;case "paragraph":return"<p>"+this.inline.output(this.token.text)+
+"</p>\n";case "text":return"<p>"+this.parseText()+"</p>\n"}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=
+1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target)if(Object.prototype.hasOwnProperty.call(target,key))obj[key]=target[key]}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}if(opt)opt=merge({},marked.defaults,opt);var tokens=Lexer.lex(tokens,opt),highlight=opt.highlight,pending=0,l=tokens.length,i=0;if(!highlight||highlight.length<3)return callback(null,Parser.parse(tokens,opt));var done=function(){delete opt.highlight;
+var out=Parser.parse(tokens,opt);opt.highlight=highlight;return callback(null,out)};for(;i<l;i++)(function(token){if(token.type!=="code")return;pending++;return highlight(token.text,token.lang,function(err,code){if(code==null||code===token.text)return--pending||done();token.text=code;token.escaped=true;--pending||done()})})(tokens[i]);return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";
+if((opt||marked.defaults).silent)return"<p>An error occured:</p><pre>"+escape(e.message+"",true)+"</pre>";throw e;}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,smartLists:false,silent:false,highlight:null,langPrefix:""};marked.Parser=Parser;marked.parser=Parser.parse;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;
+marked.parse=marked;if(typeof exports==="object")module.exports=marked;else if(typeof define==="function"&&define.amd)define(function(){return marked});else this.marked=marked}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/math/math.js b/docs/slides/BOS14/_support/reveal.js/plugin/math/math.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/math/math.js
@@ -0,0 +1,64 @@
+/**
+ * A plugin which enables rendering of math equations inside
+ * of reveal.js slides. Essentially a thin wrapper for MathJax.
+ *
+ * @author Hakim El Hattab
+ */
+var RevealMath = window.RevealMath || (function(){
+
+	var options = Reveal.getConfig().math || {};
+	options.mathjax = options.mathjax || 'http://cdn.mathjax.org/mathjax/latest/MathJax.js';
+	options.config = options.config || 'TeX-AMS_HTML-full';
+
+	loadScript( options.mathjax + '?config=' + options.config, function() {
+
+		MathJax.Hub.Config({
+			messageStyle: 'none',
+			tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] },
+			skipStartupTypeset: true
+		});
+
+		// Typeset followed by an immediate reveal.js layout since
+		// the typesetting process could affect slide height
+		MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
+		MathJax.Hub.Queue( Reveal.layout );
+
+		// Reprocess equations in slides when they turn visible
+		Reveal.addEventListener( 'slidechanged', function( event ) {
+
+			MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
+
+		} );
+
+	} );
+
+	function loadScript( url, callback ) {
+
+		var head = document.querySelector( 'head' );
+		var script = document.createElement( 'script' );
+		script.type = 'text/javascript';
+		script.src = url;
+
+		// Wrapper for callback to make sure it only fires once
+		var finish = function() {
+			if( typeof callback === 'function' ) {
+				callback.call();
+				callback = null;
+			}
+		}
+
+		script.onload = finish;
+
+		// IE
+		script.onreadystatechange = function() {
+			if ( this.readyState === 'loaded' ) {
+				finish();
+			}
+		}
+
+		// Normal browsers
+		head.appendChild( script );
+
+	}
+
+})();
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/client.js b/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/client.js
@@ -0,0 +1,13 @@
+(function() {
+	var multiplex = Reveal.getConfig().multiplex;
+	var socketId = multiplex.id;
+	var socket = io.connect(multiplex.url);
+
+	socket.on(multiplex.id, function(data) {
+		// ignore data from sockets that aren't ours
+		if (data.socketId !== socketId) { return; }
+		if( window.location.host === 'localhost:1947' ) return;
+
+		Reveal.slide(data.indexh, data.indexv, data.indexf, 'remote');
+	});
+}());
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/index.js b/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/index.js
@@ -0,0 +1,56 @@
+var express		= require('express');
+var fs			= require('fs');
+var io			= require('socket.io');
+var crypto		= require('crypto');
+
+var app			= express.createServer();
+var staticDir	= express.static;
+
+io				= io.listen(app);
+
+var opts = {
+	port: 1948,
+	baseDir : __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		if (typeof slideData.secret == 'undefined' || slideData.secret == null || slideData.secret === '') return;
+		if (createHash(slideData.secret) === slideData.socketId) {
+			slideData.secret = null;
+			socket.broadcast.emit(slideData.socketId, slideData);
+		};
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/token", function(req,res) {
+	var ts = new Date().getTime();
+	var rand = Math.floor(Math.random()*9999999);
+	var secret = ts.toString() + rand.toString();
+	res.send({secret: secret, socketId: createHash(secret)});
+});
+
+var createHash = function(secret) {
+	var cipher = crypto.createCipher('blowfish', secret);
+	return(cipher.final('hex'));
+};
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset );
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/master.js b/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/master.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/multiplex/master.js
@@ -0,0 +1,51 @@
+(function() {
+	// Don't emit events from inside of notes windows
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var multiplex = Reveal.getConfig().multiplex;
+
+	var socket = io.connect(multiplex.url);
+
+	var notify = function( slideElement, indexh, indexv, origin ) {
+		if( typeof origin === 'undefined' && origin !== 'remote' ) {
+			var nextindexh;
+			var nextindexv;
+
+			var fragmentindex = Reveal.getIndices().f;
+			if (typeof fragmentindex == 'undefined') {
+				fragmentindex = 0;
+			}
+
+			if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+				nextindexh = indexh;
+				nextindexv = indexv + 1;
+			} else {
+				nextindexh = indexh + 1;
+				nextindexv = 0;
+			}
+
+			var slideData = {
+				indexh : indexh,
+				indexv : indexv,
+				indexf : fragmentindex,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				secret: multiplex.secret,
+				socketId : multiplex.id
+			};
+
+			socket.emit('slidechanged', slideData);
+		}
+	}
+
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		notify( event.currentSlide, event.indexh, event.indexv, event.origin );
+	} );
+
+	var fragmentNotify = function( event ) {
+		notify( Reveal.getCurrentSlide(), Reveal.getIndices().h, Reveal.getIndices().v, event.origin );
+	};
+
+	Reveal.addEventListener( 'fragmentshown', fragmentNotify );
+	Reveal.addEventListener( 'fragmenthidden', fragmentNotify );
+}());
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/client.js b/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/client.js
@@ -0,0 +1,57 @@
+(function() {
+	// don't emit events from inside the previews themselves
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var socket = io.connect(window.location.origin);
+	var socketId = Math.random().toString().slice(2);
+	
+	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
+	window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId);
+
+	// Fires when a fragment is shown
+	Reveal.addEventListener( 'fragmentshown', function( event ) {
+		var fragmentData = {
+			fragment : 'next',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when a fragment is hidden
+	Reveal.addEventListener( 'fragmenthidden', function( event ) {
+		var fragmentData = {
+			fragment : 'previous',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when slide is changed
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		var nextindexh;
+		var nextindexv;
+		var slideElement = event.currentSlide;
+
+		if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+			nextindexh = event.indexh;
+			nextindexv = event.indexv + 1;
+		} else {
+			nextindexh = event.indexh + 1;
+			nextindexv = 0;
+		}
+
+		var notes = slideElement.querySelector('aside.notes');
+		var slideData = {
+			notes : notes ? notes.innerHTML : '',
+			indexh : event.indexh,
+			indexv : event.indexv,
+			nextindexh : nextindexh,
+			nextindexv : nextindexv,
+			socketId : socketId,
+			markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false
+
+		};
+
+		socket.emit('slidechanged', slideData);
+	} );
+}());
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/index.js b/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/index.js
@@ -0,0 +1,59 @@
+var express   = require('express');
+var fs        = require('fs');
+var io        = require('socket.io');
+var _         = require('underscore');
+var Mustache  = require('mustache');
+
+var app       = express.createServer();
+var staticDir = express.static;
+
+io            = io.listen(app);
+
+var opts = {
+	port :      1947,
+	baseDir :   __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		socket.broadcast.emit('slidedata', slideData);
+	});
+	socket.on('fragmentchanged', function(fragmentData) {
+		socket.broadcast.emit('fragmentdata', fragmentData);
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/notes/:socketId", function(req, res) {
+
+	fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) {
+		res.send(Mustache.to_html(data.toString(), {
+			socketId : req.params.socketId
+		}));
+	});
+	// fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res);
+});
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
+
+console.log( brown + "reveal.js - Speaker Notes" + reset );
+console.log( "1. Open the slides at " + green + slidesLocation + reset );
+console.log( "2. Click on the link your JS console to go to the notes page" );
+console.log( "3. Advance through your slides and your notes will advance automatically" );
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/notes.html b/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/notes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/notes-server/notes.html
@@ -0,0 +1,142 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+
+		<meta name="viewport" content="width=1150">
+
+		<title>reveal.js - Slide Notes</title>
+
+		<style>
+			body {
+				font-family: Helvetica;
+			}
+
+			#notes {
+				font-size: 24px;
+				width: 640px;
+				margin-top: 5px;
+				clear: left;
+			}
+
+			#wrap-current-slide {
+				width: 640px;
+				height: 512px;
+				float: left;
+				overflow: hidden;
+			}
+
+			#current-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+				    -ms-transform-origin: 0 0;
+				     -o-transform-origin: 0 0;
+				        transform-origin: 0 0;
+
+				-webkit-transform: scale(0.5);
+				   -moz-transform: scale(0.5);
+				    -ms-transform: scale(0.5);
+				     -o-transform: scale(0.5);
+				        transform: scale(0.5);
+			}
+
+			#wrap-next-slide {
+				width: 448px;
+				height: 358px;
+				float: left;
+				margin: 0 0 0 10px;
+				overflow: hidden;
+			}
+
+			#next-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+				    -ms-transform-origin: 0 0;
+				     -o-transform-origin: 0 0;
+				        transform-origin: 0 0;
+
+				-webkit-transform: scale(0.35);
+				   -moz-transform: scale(0.35);
+				    -ms-transform: scale(0.35);
+				     -o-transform: scale(0.35);
+				        transform: scale(0.35);
+			}
+
+			.slides {
+				position: relative;
+				margin-bottom: 10px;
+				border: 1px solid black;
+				border-radius: 2px;
+				background: rgb(28, 30, 32);
+			}
+
+			.slides span {
+				position: absolute;
+				top: 3px;
+				left: 3px;
+				font-weight: bold;
+				font-size: 14px;
+				color: rgba( 255, 255, 255, 0.9 );
+			}
+		</style>
+	</head>
+
+	<body>
+
+		<div id="wrap-current-slide" class="slides">
+			<iframe src="/?receiver" width="1280" height="1024" id="current-slide"></iframe>
+		</div>
+
+		<div id="wrap-next-slide" class="slides">
+			<iframe src="/?receiver" width="640" height="512" id="next-slide"></iframe>
+			<span>UPCOMING:</span>
+		</div>
+		<div id="notes"></div>
+
+		<script src="/socket.io/socket.io.js"></script>
+		<script src="/plugin/markdown/marked.js"></script>
+
+		<script>
+		var socketId = '{{socketId}}';
+		var socket = io.connect(window.location.origin);
+		var notes = document.getElementById('notes');
+		var currentSlide = document.getElementById('current-slide');
+		var nextSlide = document.getElementById('next-slide');
+
+		socket.on('slidedata', function(data) {
+			// ignore data from sockets that aren't ours
+			if (data.socketId !== socketId) { return; }
+
+			if (data.markdown) {
+				notes.innerHTML = marked(data.notes);
+			}
+			else {
+				notes.innerHTML = data.notes;
+			}
+
+			currentSlide.contentWindow.Reveal.slide(data.indexh, data.indexv);
+			nextSlide.contentWindow.Reveal.slide(data.nextindexh, data.nextindexv);
+		});
+		socket.on('fragmentdata', function(data) {
+			// ignore data from sockets that aren't ours
+			if (data.socketId !== socketId) { return; }
+
+			if (data.fragment === 'next') {
+				currentSlide.contentWindow.Reveal.nextFragment();
+			}
+			else if (data.fragment === 'previous') {
+				currentSlide.contentWindow.Reveal.prevFragment();
+			}
+		});
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/notes/notes.html b/docs/slides/BOS14/_support/reveal.js/plugin/notes/notes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/notes/notes.html
@@ -0,0 +1,267 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Slide Notes</title>
+
+		<style>
+			body {
+				font-family: Helvetica;
+			}
+
+			#notes {
+				font-size: 24px;
+				width: 640px;
+				margin-top: 5px;
+				clear: left;
+			}
+
+			#wrap-current-slide {
+				width: 640px;
+				height: 512px;
+				float: left;
+				overflow: hidden;
+			}
+
+			#current-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+					-ms-transform-origin: 0 0;
+					 -o-transform-origin: 0 0;
+						transform-origin: 0 0;
+
+				-webkit-transform: scale(0.5);
+				   -moz-transform: scale(0.5);
+					-ms-transform: scale(0.5);
+					 -o-transform: scale(0.5);
+						transform: scale(0.5);
+			}
+
+			#wrap-next-slide {
+				width: 448px;
+				height: 358px;
+				float: left;
+				margin: 0 0 0 10px;
+				overflow: hidden;
+			}
+
+			#next-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+					-ms-transform-origin: 0 0;
+					 -o-transform-origin: 0 0;
+						transform-origin: 0 0;
+
+				-webkit-transform: scale(0.35);
+				   -moz-transform: scale(0.35);
+					-ms-transform: scale(0.35);
+					 -o-transform: scale(0.35);
+						transform: scale(0.35);
+			}
+
+			.slides {
+				position: relative;
+				margin-bottom: 10px;
+				border: 1px solid black;
+				border-radius: 2px;
+				background: rgb(28, 30, 32);
+			}
+
+			.slides span {
+				position: absolute;
+				top: 3px;
+				left: 3px;
+				font-weight: bold;
+				font-size: 14px;
+				color: rgba( 255, 255, 255, 0.9 );
+			}
+
+			.error {
+				font-weight: bold;
+				color: red;
+				font-size: 1.5em;
+				text-align: center;
+				margin-top: 10%;
+			}
+
+			.error code {
+				font-family: monospace;
+			}
+
+			.time {
+				width: 448px;
+				margin: 30px 0 0 10px;
+				float: left;
+				text-align: center;
+				opacity: 0;
+
+				-webkit-transition: opacity 0.4s;
+				   -moz-transition: opacity 0.4s;
+				     -o-transition: opacity 0.4s;
+				        transition: opacity 0.4s;
+			}
+
+			.elapsed,
+			.clock {
+				color: #333;
+				font-size: 2em;
+				text-align: center;
+				display: inline-block;
+				padding: 0.5em;
+				background-color: #eee;
+				border-radius: 10px;
+			}
+
+			.elapsed h2,
+			.clock h2 {
+				font-size: 0.8em;
+				line-height: 100%;
+				margin: 0;
+				color: #aaa;
+			}
+
+			.elapsed .mute {
+				color: #ddd;
+			}
+
+		</style>
+	</head>
+
+	<body>
+
+		<script>
+			function getNotesURL( controls ) {
+				return window.opener.location.protocol + '//' + window.opener.location.host + window.opener.location.pathname + '?receiver&controls='+ ( controls || 'false' ) +'&progress=false&overview=false' + window.opener.location.hash;
+			}
+			var notesCurrentSlideURL = getNotesURL( true );
+			var notesNextSlideURL = getNotesURL( false );
+		</script>
+
+		<div id="wrap-current-slide" class="slides">
+			<script>document.write( '<iframe width="1280" height="1024" id="current-slide" src="'+ notesCurrentSlideURL +'"></iframe>' );</script>
+		</div>
+
+		<div id="wrap-next-slide" class="slides">
+			<script>document.write( '<iframe width="640" height="512" id="next-slide" src="'+ notesNextSlideURL +'"></iframe>' );</script>
+			<span>UPCOMING:</span>
+		</div>
+
+		<div class="time">
+			<div class="clock">
+				<h2>Time</h2>
+				<span id="clock">0:00:00 AM</span>
+			</div>
+			<div class="elapsed">
+				<h2>Elapsed</h2>
+				<span id="hours">00</span><span id="minutes">:00</span><span id="seconds">:00</span>
+			</div>
+		</div>
+
+		<div id="notes"></div>
+
+		<script src="../../plugin/markdown/marked.js"></script>
+		<script>
+
+			window.addEventListener( 'load', function() {
+
+				if( window.opener && window.opener.location && window.opener.location.href ) {
+
+					var notes = document.getElementById( 'notes' ),
+						currentSlide = document.getElementById( 'current-slide' ),
+						nextSlide = document.getElementById( 'next-slide' ),
+						silenced = false;
+
+					window.addEventListener( 'message', function( event ) {
+						var data = JSON.parse( event.data );
+
+						// No need for updating the notes in case of fragment changes
+						if ( data.notes !== undefined) {
+							if( data.markdown ) {
+								notes.innerHTML = marked( data.notes );
+							}
+							else {
+								notes.innerHTML = data.notes;
+							}
+						}
+
+						silenced = true;
+
+						// Update the note slides
+						currentSlide.contentWindow.Reveal.slide( data.indexh, data.indexv, data.indexf );
+						nextSlide.contentWindow.Reveal.slide( data.nextindexh, data.nextindexv );
+
+						silenced = false;
+
+					}, false );
+
+					var start = new Date(),
+						timeEl = document.querySelector( '.time' ),
+						clockEl = document.getElementById( 'clock' ),
+						hoursEl = document.getElementById( 'hours' ),
+						minutesEl = document.getElementById( 'minutes' ),
+						secondsEl = document.getElementById( 'seconds' );
+
+					setInterval( function() {
+
+						timeEl.style.opacity = 1;
+
+						var diff, hours, minutes, seconds,
+							now = new Date();
+
+						diff = now.getTime() - start.getTime();
+						hours = Math.floor( diff / ( 1000 * 60 * 60 ) );
+						minutes = Math.floor( ( diff / ( 1000 * 60 ) ) % 60 );
+						seconds = Math.floor( ( diff / 1000 ) % 60 );
+
+						clockEl.innerHTML = now.toLocaleTimeString();
+						hoursEl.innerHTML = zeroPadInteger( hours );
+						hoursEl.className = hours > 0 ? "" : "mute";
+						minutesEl.innerHTML = ":" + zeroPadInteger( minutes );
+						minutesEl.className = minutes > 0 ? "" : "mute";
+						secondsEl.innerHTML = ":" + zeroPadInteger( seconds );
+
+					}, 1000 );
+
+					// Broadcasts the state of the notes window to synchronize
+					// the main window
+					function synchronizeMainWindow() {
+
+						if( !silenced ) {
+							var indices = currentSlide.contentWindow.Reveal.getIndices();
+							window.opener.Reveal.slide( indices.h, indices.v, indices.f );
+						}
+
+					}
+
+					// Navigate the main window when the notes slide changes
+					currentSlide.contentWindow.Reveal.addEventListener( 'slidechanged', synchronizeMainWindow );
+					currentSlide.contentWindow.Reveal.addEventListener( 'fragmentshown', synchronizeMainWindow );
+					currentSlide.contentWindow.Reveal.addEventListener( 'fragmenthidden', synchronizeMainWindow );
+
+				}
+				else {
+
+					document.body.innerHTML =  '<p class="error">Unable to access <code>window.opener.location</code>.<br>Make sure the presentation is running on a web server.</p>';
+
+				}
+
+
+			}, false );
+
+			function zeroPadInteger( num ) {
+				var str = "00" + parseInt( num );
+				return str.substring( str.length - 2 );
+			}
+
+		</script>
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/notes/notes.js b/docs/slides/BOS14/_support/reveal.js/plugin/notes/notes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/notes/notes.js
@@ -0,0 +1,78 @@
+/**
+ * Handles opening of and synchronization with the reveal.js
+ * notes window.
+ */
+var RevealNotes = (function() {
+
+	function openNotes() {
+		var jsFileLocation = document.querySelector('script[src$="notes.js"]').src;  // this js file path
+		jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, '');   // the js folder path
+		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' );
+
+		// Fires when slide is changed
+		Reveal.addEventListener( 'slidechanged', post );
+
+		// Fires when a fragment is shown
+		Reveal.addEventListener( 'fragmentshown', post );
+
+		// Fires when a fragment is hidden
+		Reveal.addEventListener( 'fragmenthidden', post );
+
+		/**
+		 * Posts the current slide data to the notes window
+		 */
+		function post() {
+			var slideElement = Reveal.getCurrentSlide(),
+				slideIndices = Reveal.getIndices(),
+				messageData;
+
+			var notes = slideElement.querySelector( 'aside.notes' ),
+				nextindexh,
+				nextindexv;
+
+			if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
+				nextindexh = slideIndices.h;
+				nextindexv = slideIndices.v + 1;
+			} else {
+				nextindexh = slideIndices.h + 1;
+				nextindexv = 0;
+			}
+
+			messageData = {
+				notes : notes ? notes.innerHTML : '',
+				indexh : slideIndices.h,
+				indexv : slideIndices.v,
+				indexf : slideIndices.f,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
+			};
+
+			notesPopup.postMessage( JSON.stringify( messageData ), '*' );
+		}
+
+		// Navigate to the current slide when the notes are loaded
+		notesPopup.addEventListener( 'load', function( event ) {
+			post();
+		}, false );
+	}
+
+	// If the there's a 'notes' query set, open directly
+	if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
+		openNotes();
+	}
+
+	// Open the notes when the 's' key is hit
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openNotes();
+		}
+	}, false );
+
+	return { open: openNotes };
+})();
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/postmessage/example.html b/docs/slides/BOS14/_support/reveal.js/plugin/postmessage/example.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/postmessage/example.html
@@ -0,0 +1,39 @@
+<html>
+	<body>
+
+		<iframe id="reveal" src="../../index.html" style="border: 0;" width="500" height="500"></iframe>
+
+		<div>
+			<input id="back" type="button" value="go back"/>
+			<input id="ahead" type="button" value="go ahead"/>
+			<input id="slideto" type="button" value="slideto 2-2"/>
+		</div>
+
+		<script>
+
+			(function (){
+
+				var back = document.getElementById( 'back' ),
+						ahead = document.getElementById( 'ahead' ),
+						slideto = document.getElementById( 'slideto' ),
+						reveal =  window.frames[0];
+
+					back.addEventListener( 'click', function () {
+						
+					reveal.postMessage( JSON.stringify({method: 'prev', args: []}), '*' );
+				}, false );
+
+				ahead.addEventListener( 'click', function (){
+					reveal.postMessage( JSON.stringify({method: 'next', args: []}), '*' );
+				}, false );
+
+				slideto.addEventListener( 'click', function (){
+					reveal.postMessage( JSON.stringify({method: 'slide', args: [2,2]}), '*' );
+				}, false );
+
+			}());
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/postmessage/postmessage.js b/docs/slides/BOS14/_support/reveal.js/plugin/postmessage/postmessage.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/postmessage/postmessage.js
@@ -0,0 +1,42 @@
+/*
+
+	simple postmessage plugin
+
+	Useful when a reveal slideshow is inside an iframe.
+	It allows to call reveal methods from outside.
+
+	Example:
+		 var reveal =  window.frames[0];
+
+		 // Reveal.prev(); 
+		 reveal.postMessage(JSON.stringify({method: 'prev', args: []}), '*');
+		 // Reveal.next(); 
+		 reveal.postMessage(JSON.stringify({method: 'next', args: []}), '*');
+		 // Reveal.slide(2, 2); 
+		 reveal.postMessage(JSON.stringify({method: 'slide', args: [2,2]}), '*');
+
+	Add to the slideshow:
+
+		dependencies: [
+			...
+			{ src: 'plugin/postmessage/postmessage.js', async: true, condition: function() { return !!document.body.classList; } }
+		]
+
+*/
+
+(function (){
+
+	window.addEventListener( "message", function ( event ) {
+		var data = JSON.parse( event.data ),
+				method = data.method,
+				args = data.args;
+
+		if( typeof Reveal[method] === 'function' ) {
+			Reveal[method].apply( Reveal, data.args );
+		}
+	}, false);
+
+}());
+
+
+
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/print-pdf/print-pdf.js b/docs/slides/BOS14/_support/reveal.js/plugin/print-pdf/print-pdf.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/print-pdf/print-pdf.js
@@ -0,0 +1,44 @@
+/**
+ * phantomjs script for printing presentations to PDF.
+ *
+ * Example:
+ * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf
+ *
+ * By Manuel Bieh (https://github.com/manuelbieh)
+ */
+
+// html2pdf.js
+var page = new WebPage();
+var system = require( 'system' );
+
+page.viewportSize  = {
+	width: 1024,
+	height: 768
+};
+
+page.paperSize = {
+	format: 'letter',
+	orientation: 'landscape',
+	margin: {
+		left: '0',
+		right: '0',
+		top: '0',
+		bottom: '0'
+	}
+};
+
+var revealFile = system.args[1] || 'index.html?print-pdf';
+var slideFile = system.args[2] || 'slides.pdf';
+
+if( slideFile.match( /\.pdf$/gi ) === null ) {
+	slideFile += '.pdf';
+}
+
+console.log( 'Printing PDF...' );
+
+page.open( revealFile, function( status ) {
+	console.log( 'Printed succesfully' );
+	page.render( slideFile );
+	phantom.exit();
+} );
+
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/remotes/remotes.js b/docs/slides/BOS14/_support/reveal.js/plugin/remotes/remotes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/remotes/remotes.js
@@ -0,0 +1,39 @@
+/**
+ * Touch-based remote controller for your presentation courtesy 
+ * of the folks at http://remotes.io
+ */
+
+(function(window){
+
+    /**
+     * Detects if we are dealing with a touch enabled device (with some false positives)
+     * Borrowed from modernizr: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touch.js   
+     */
+    var hasTouch  = (function(){
+        return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
+    })();
+
+    /**
+     * Detects if notes are enable and the current page is opened inside an /iframe
+     * this prevents loading Remotes.io several times
+     */
+    var isNotesAndIframe = (function(){
+        return window.RevealNotes && !(self == top);
+    })();
+
+    if(!hasTouch && !isNotesAndIframe){
+        head.ready( 'remotes.ne.min.js', function() {
+            new Remotes("preview")
+                .on("swipe-left", function(e){ Reveal.right(); })
+                .on("swipe-right", function(e){ Reveal.left(); })
+                .on("swipe-up", function(e){ Reveal.down(); })
+                .on("swipe-down", function(e){ Reveal.up(); })
+                .on("tap", function(e){ Reveal.next(); })
+                .on("zoom-out", function(e){ Reveal.toggleOverview(true); })
+                .on("zoom-in", function(e){ Reveal.toggleOverview(false); })
+            ;
+        } );
+
+        head.js('https://hakim-static.s3.amazonaws.com/reveal-js/remotes.ne.min.js');
+    }
+})(window);
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/search/search.js b/docs/slides/BOS14/_support/reveal.js/plugin/search/search.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/search/search.js
@@ -0,0 +1,196 @@
+/*
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
+ * by navigatating to that slide and highlighting it.
+ *
+ * By Jon Snyder <snyder.jon@gmail.com>, February 2013
+ */
+
+var RevealSearch = (function() {
+
+	var matchedSlides;
+	var currentMatchedIndex;
+	var searchboxDirty;
+	var myHilitor;
+
+// Original JavaScript code by Chirp Internet: www.chirp.com.au
+// Please acknowledge use of this code by including this header.
+// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
+
+function Hilitor(id, tag)
+{
+
+  var targetNode = document.getElementById(id) || document.body;
+  var hiliteTag = tag || "EM";
+  var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
+  var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
+  var wordColor = [];
+  var colorIdx = 0;
+  var matchRegex = "";
+  var matchingSlides = [];
+
+  this.setRegex = function(input)
+  {
+    input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
+    matchRegex = new RegExp("(" + input + ")","i");
+  }
+
+  this.getRegex = function()
+  {
+    return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
+  }
+
+  // recursively apply word highlighting
+  this.hiliteWords = function(node)
+  {
+    if(node == undefined || !node) return;
+    if(!matchRegex) return;
+    if(skipTags.test(node.nodeName)) return;
+
+    if(node.hasChildNodes()) {
+      for(var i=0; i < node.childNodes.length; i++)
+        this.hiliteWords(node.childNodes[i]);
+    }
+    if(node.nodeType == 3) { // NODE_TEXT
+      if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
+      	//find the slide's section element and save it in our list of matching slides
+      	var secnode = node.parentNode;
+      	while (secnode.nodeName != 'SECTION') {
+      		secnode = secnode.parentNode;
+      	}
+      	
+      	var slideIndex = Reveal.getIndices(secnode);
+      	var slidelen = matchingSlides.length;
+      	var alreadyAdded = false;
+      	for (var i=0; i < slidelen; i++) {
+      		if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
+      			alreadyAdded = true;
+      		}
+      	}
+      	if (! alreadyAdded) {
+      		matchingSlides.push(slideIndex);
+      	}
+      	
+        if(!wordColor[regs[0].toLowerCase()]) {
+          wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
+        }
+
+        var match = document.createElement(hiliteTag);
+        match.appendChild(document.createTextNode(regs[0]));
+        match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
+        match.style.fontStyle = "inherit";
+        match.style.color = "#000";
+
+        var after = node.splitText(regs.index);
+        after.nodeValue = after.nodeValue.substring(regs[0].length);
+        node.parentNode.insertBefore(match, after);
+      }
+    }
+  };
+
+  // remove highlighting
+  this.remove = function()
+  {
+    var arr = document.getElementsByTagName(hiliteTag);
+    while(arr.length && (el = arr[0])) {
+      el.parentNode.replaceChild(el.firstChild, el);
+    }
+  };
+
+  // start highlighting at target node
+  this.apply = function(input)
+  {
+    if(input == undefined || !input) return;
+    this.remove();
+    this.setRegex(input);
+    this.hiliteWords(targetNode);
+    return matchingSlides;
+  };
+
+}
+
+	function openSearch() {
+		//ensure the search term input dialog is visible and has focus:
+		var inputbox = document.getElementById("searchinput");
+		inputbox.style.display = "inline";
+		inputbox.focus();
+		inputbox.select();
+	}
+
+	function toggleSearch() {
+		var inputbox = document.getElementById("searchinput");
+		if (inputbox.style.display !== "inline") {
+			openSearch();
+		}
+		else {
+			inputbox.style.display = "none";
+			myHilitor.remove();
+		}
+	}
+
+	function doSearch() {
+		//if there's been a change in the search term, perform a new search:
+		if (searchboxDirty) {
+			var searchstring = document.getElementById("searchinput").value;
+
+			//find the keyword amongst the slides
+			myHilitor = new Hilitor("slidecontent");
+			matchedSlides = myHilitor.apply(searchstring);
+			currentMatchedIndex = 0;
+		}
+
+		//navigate to the next slide that has the keyword, wrapping to the first if necessary
+		if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
+			currentMatchedIndex = 0;
+		}
+		if (matchedSlides.length > currentMatchedIndex) {
+			Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
+			currentMatchedIndex++;
+		}
+	}
+
+	var dom = {};
+	dom.wrapper = document.querySelector( '.reveal' );
+
+	if( !dom.wrapper.querySelector( '.searchbox' ) ) {
+			var searchElement = document.createElement( 'div' );
+			searchElement.id = "searchinputdiv";
+			searchElement.classList.add( 'searchdiv' );
+      searchElement.style.position = 'absolute';
+      searchElement.style.top = '10px';
+      searchElement.style.left = '10px';
+      //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
+			searchElement.innerHTML = '<span><input type="search" id="searchinput" class="searchinput" style="vertical-align: top;"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJiSURBVHjatFZNaxNBGH5md+Mmu92NVdKDRipSAyqCghgQD4L4cRe86UUtAQ+eFCxoa4/25EXBFi8eBE+eRPoDhB6KgiiixdAPCEkx2pjvTXadd9yNsflwuyUDD/O+u8PzzDPvzOwyx3EwyCZhwG3gAkp7MnpjgbopjsltcD4gjuXZZKeAR348MYLYTm3LzOs/y3j3JTfZxgXWXmTuwPHIc4VmoOmv5IrI53+AO2DdHLjkDWQ3GoEEVFXtXQOvkSnPWcyUceviLhwbDYv8/XIVj97kse7TodLvZXxYxrPUHkQ1ufXs3FEdybEIxucySOesoNvUgWU1cP3MkCBfTFdw9fGaAMVmRELq7LBw2Q3/FaAxxWIRpw+ZIr/7IouPqzUBiqmdHAv7EuhRAwf1er2Vy4x1jW3b2d5Jfvu5IPp7l2LYbcgCFFNb+FoJ7oBqEAqFMPNqFcmEgVMJDfMT+1tvN0pNjERlMS6QA5pFOKxiKVPFhakPeL3It+WGJUDxt2wFR+JhzI7v5ctkd8DXOZAkCYYxhO+lKm4+Xfqz/rIixBuNBl7eOYzkQQNzqX249mRl6zUgEcYkaJrGhUwBinVdh6IouPzwE6/DL5w4oLkH8y981aDf+uq6hlKpJESiUdNfDZi7/ehG9K6KfiA3pml0PLcsq+cSMTj2NL9ukc4UOmz7AZ3+crkC4mHujFvXNaMFB3bEr8xPS6p5O+jXxq4VZtaen7/PwzrntjcLUE0iHPS1Ud1cdiEJl/8WivZk0wXd7zWOMkeF8s0CcAmkNrC2nvXZDbbbN73ccYnZoH9bfgswAFzAe9/h3dbKAAAAAElFTkSuQmCC" id="searchbutton" class="searchicon" style="vertical-align: top; margin-top: -1px;"/></span>';
+			dom.wrapper.appendChild( searchElement );
+	}
+
+	document.getElementById("searchbutton").addEventListener( 'click', function(event) {
+		doSearch();
+	}, false );
+
+	document.getElementById("searchinput").addEventListener( 'keyup', function( event ) {
+		switch (event.keyCode) {
+			case 13:
+				event.preventDefault();
+				doSearch();
+				searchboxDirty = false;
+				break;
+			default:
+				searchboxDirty = true;
+		}
+	}, false );
+
+	// Open the search when the 's' key is hit (yes, this conflicts with the notes plugin, disabling for now)
+	/*
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openSearch();
+		}
+	}, false );
+*/
+	return { open: openSearch };
+})();
diff --git a/docs/slides/BOS14/_support/reveal.js/plugin/zoom-js/zoom.js b/docs/slides/BOS14/_support/reveal.js/plugin/zoom-js/zoom.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/plugin/zoom-js/zoom.js
@@ -0,0 +1,258 @@
+// Custom reveal.js integration
+(function(){
+	var isEnabled = true;
+
+	document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) {
+		var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key';
+
+		if( event[ modifier ] && isEnabled ) {
+			event.preventDefault();
+			zoom.to({ element: event.target, pan: false });
+		}
+	} );
+
+	Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
+	Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
+})();
+
+/*!
+ * zoom.js 0.2 (modified version for use with reveal.js)
+ * http://lab.hakim.se/zoom-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var zoom = (function(){
+
+	// The current zoom level (scale)
+	var level = 1;
+
+	// The current mouse position, used for panning
+	var mouseX = 0,
+		mouseY = 0;
+
+	// Timeout before pan is activated
+	var panEngageTimeout = -1,
+		panUpdateInterval = -1;
+
+	var currentOptions = null;
+
+	// Check for transform support so that we can fallback otherwise
+	var supportsTransforms = 	'WebkitTransform' in document.body.style ||
+								'MozTransform' in document.body.style ||
+								'msTransform' in document.body.style ||
+								'OTransform' in document.body.style ||
+								'transform' in document.body.style;
+
+	if( supportsTransforms ) {
+		// The easing that will be applied when we zoom in/out
+		document.body.style.transition = 'transform 0.8s ease';
+		document.body.style.OTransition = '-o-transform 0.8s ease';
+		document.body.style.msTransition = '-ms-transform 0.8s ease';
+		document.body.style.MozTransition = '-moz-transform 0.8s ease';
+		document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
+	}
+
+	// Zoom out if the user hits escape
+	document.addEventListener( 'keyup', function( event ) {
+		if( level !== 1 && event.keyCode === 27 ) {
+			zoom.out();
+		}
+	}, false );
+
+	// Monitor mouse movement for panning
+	document.addEventListener( 'mousemove', function( event ) {
+		if( level !== 1 ) {
+			mouseX = event.clientX;
+			mouseY = event.clientY;
+		}
+	}, false );
+
+	/**
+	 * Applies the CSS required to zoom in, prioritizes use of CSS3
+	 * transforms but falls back on zoom for IE.
+	 *
+	 * @param {Number} pageOffsetX
+	 * @param {Number} pageOffsetY
+	 * @param {Number} elementOffsetX
+	 * @param {Number} elementOffsetY
+	 * @param {Number} scale
+	 */
+	function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) {
+
+		if( supportsTransforms ) {
+			var origin = pageOffsetX +'px '+ pageOffsetY +'px',
+				transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')';
+
+			document.body.style.transformOrigin = origin;
+			document.body.style.OTransformOrigin = origin;
+			document.body.style.msTransformOrigin = origin;
+			document.body.style.MozTransformOrigin = origin;
+			document.body.style.WebkitTransformOrigin = origin;
+
+			document.body.style.transform = transform;
+			document.body.style.OTransform = transform;
+			document.body.style.msTransform = transform;
+			document.body.style.MozTransform = transform;
+			document.body.style.WebkitTransform = transform;
+		}
+		else {
+			// Reset all values
+			if( scale === 1 ) {
+				document.body.style.position = '';
+				document.body.style.left = '';
+				document.body.style.top = '';
+				document.body.style.width = '';
+				document.body.style.height = '';
+				document.body.style.zoom = '';
+			}
+			// Apply scale
+			else {
+				document.body.style.position = 'relative';
+				document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px';
+				document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px';
+				document.body.style.width = ( scale * 100 ) + '%';
+				document.body.style.height = ( scale * 100 ) + '%';
+				document.body.style.zoom = scale;
+			}
+		}
+
+		level = scale;
+
+		if( level !== 1 && document.documentElement.classList ) {
+			document.documentElement.classList.add( 'zoomed' );
+		}
+		else {
+			document.documentElement.classList.remove( 'zoomed' );
+		}
+	}
+
+	/**
+	 * Pan the document when the mosue cursor approaches the edges
+	 * of the window.
+	 */
+	function pan() {
+		var range = 0.12,
+			rangeX = window.innerWidth * range,
+			rangeY = window.innerHeight * range,
+			scrollOffset = getScrollOffset();
+
+		// Up
+		if( mouseY < rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
+		}
+		// Down
+		else if( mouseY > window.innerHeight - rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
+		}
+
+		// Left
+		if( mouseX < rangeX ) {
+			window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
+		}
+		// Right
+		else if( mouseX > window.innerWidth - rangeX ) {
+			window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
+		}
+	}
+
+	function getScrollOffset() {
+		return {
+			x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
+			y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset
+		}
+	}
+
+	return {
+		/**
+		 * Zooms in on either a rectangle or HTML element.
+		 *
+		 * @param {Object} options
+		 *   - element: HTML element to zoom in on
+		 *   OR
+		 *   - x/y: coordinates in non-transformed space to zoom in on
+		 *   - width/height: the portion of the screen to zoom in on
+		 *   - scale: can be used instead of width/height to explicitly set scale
+		 */
+		to: function( options ) {
+			// Due to an implementation limitation we can't zoom in
+			// to another element without zooming out first
+			if( level !== 1 ) {
+				zoom.out();
+			}
+			else {
+				options.x = options.x || 0;
+				options.y = options.y || 0;
+
+				// If an element is set, that takes precedence
+				if( !!options.element ) {
+					// Space around the zoomed in element to leave on screen
+					var padding = 20;
+
+					options.width = options.element.getBoundingClientRect().width + ( padding * 2 );
+					options.height = options.element.getBoundingClientRect().height + ( padding * 2 );
+					options.x = options.element.getBoundingClientRect().left - padding;
+					options.y = options.element.getBoundingClientRect().top - padding;
+				}
+
+				// If width/height values are set, calculate scale from those values
+				if( options.width !== undefined && options.height !== undefined ) {
+					options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
+				}
+
+				if( options.scale > 1 ) {
+					options.x *= options.scale;
+					options.y *= options.scale;
+
+					var scrollOffset = getScrollOffset();
+
+					if( options.element ) {
+						scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2;
+					}
+
+					magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale );
+
+					if( options.pan !== false ) {
+
+						// Wait with engaging panning as it may conflict with the
+						// zoom transition
+						panEngageTimeout = setTimeout( function() {
+							panUpdateInterval = setInterval( pan, 1000 / 60 );
+						}, 800 );
+
+					}
+				}
+
+				currentOptions = options;
+			}
+		},
+
+		/**
+		 * Resets the document zoom state to its default.
+		 */
+		out: function() {
+			clearTimeout( panEngageTimeout );
+			clearInterval( panUpdateInterval );
+
+			var scrollOffset = getScrollOffset();
+
+			if( currentOptions && currentOptions.element ) {
+				scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2;
+			}
+
+			magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 );
+
+			level = 1;
+		},
+
+		// Alias
+		magnify: function( options ) { this.to( options ) },
+		reset: function() { this.out() },
+
+		zoomLevel: function() {
+			return level;
+		}
+	}
+
+})();
+
diff --git a/docs/slides/BOS14/_support/reveal.js/test/examples/assets/image1.png b/docs/slides/BOS14/_support/reveal.js/test/examples/assets/image1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/_support/reveal.js/test/examples/assets/image1.png differ
diff --git a/docs/slides/BOS14/_support/reveal.js/test/examples/assets/image2.png b/docs/slides/BOS14/_support/reveal.js/test/examples/assets/image2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/_support/reveal.js/test/examples/assets/image2.png differ
diff --git a/docs/slides/BOS14/_support/reveal.js/test/examples/barebones.html b/docs/slides/BOS14/_support/reveal.js/test/examples/barebones.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/examples/barebones.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Barebones</title>
+
+		<link rel="stylesheet" href="../../css/reveal.min.css">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+				<section>
+					<h2>Barebones Presentation</h2>
+					<p>This example contains the bare minimum includes and markup required to run a reveal.js presentation.</p>
+				</section>
+
+				<section>
+					<h2>No Theme</h2>
+					<p>There's no theme included, so it will fall back on browser defaults.</p>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../../js/reveal.min.js"></script>
+
+		<script>
+
+			Reveal.initialize();
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/test/examples/embedded-media.html b/docs/slides/BOS14/_support/reveal.js/test/examples/embedded-media.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/examples/embedded-media.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Embedded Media</title>
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/theme/default.css" id="theme">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+				<section>
+					<h2>Embedded Media Test</h2>
+				</section>
+
+				<section>
+					<iframe data-autoplay width="420" height="345" src="http://www.youtube.com/embed/l3RQZ4mcr1c"></iframe>
+				</section>
+
+				<section>
+					<h2>Empty Slide</h2>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.min.js"></script>
+
+		<script>
+
+			Reveal.initialize({
+				transition: 'linear'
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/test/examples/math.html b/docs/slides/BOS14/_support/reveal.js/test/examples/math.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/examples/math.html
@@ -0,0 +1,185 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Math Plugin</title>
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/theme/night.css" id="theme">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+				<section>
+					<h2>reveal.js Math Plugin</h2>
+					<p>A thin wrapper for MathJax</p>
+				</section>
+
+				<section>
+					<h3>The Lorenz Equations</h3>
+
+					\[\begin{aligned}
+					\dot{x} &amp; = \sigma(y-x) \\
+					\dot{y} &amp; = \rho x - y - xz \\
+					\dot{z} &amp; = -\beta z + xy
+					\end{aligned} \]
+				</section>
+
+				<section>
+					<h3>The Cauchy-Schwarz Inequality</h3>
+
+					<script type="math/tex; mode=display">
+						\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
+					</script>
+				</section>
+
+				<section>
+					<h3>A Cross Product Formula</h3>
+
+					\[\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix}
+					\mathbf{i} &amp; \mathbf{j} &amp; \mathbf{k} \\
+					\frac{\partial X}{\partial u} &amp;  \frac{\partial Y}{\partial u} &amp; 0 \\
+					\frac{\partial X}{\partial v} &amp;  \frac{\partial Y}{\partial v} &amp; 0
+					\end{vmatrix}  \]
+				</section>
+
+				<section>
+					<h3>The probability of getting \(k\) heads when flipping \(n\) coins is</h3>
+
+					\[P(E)   = {n \choose k} p^k (1-p)^{ n-k} \]
+				</section>
+
+				<section>
+					<h3>An Identity of Ramanujan</h3>
+
+					\[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} =
+					1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
+					{1+\frac{e^{-8\pi}} {1+\ldots} } } } \]
+				</section>
+
+				<section>
+					<h3>A Rogers-Ramanujan Identity</h3>
+
+					\[  1 +  \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots =
+					\prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}\]
+				</section>
+
+				<section>
+					<h3>Maxwell&#8217;s Equations</h3>
+
+					\[  \begin{aligned}
+					\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\   \nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\
+					\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\
+					\nabla \cdot \vec{\mathbf{B}} &amp; = 0 \end{aligned}
+					\]
+				</section>
+
+				<section>
+					<section>
+						<h3>The Lorenz Equations</h3>
+
+						<div class="fragment">
+							\[\begin{aligned}
+							\dot{x} &amp; = \sigma(y-x) \\
+							\dot{y} &amp; = \rho x - y - xz \\
+							\dot{z} &amp; = -\beta z + xy
+							\end{aligned} \]
+						</div>
+					</section>
+
+					<section>
+						<h3>The Cauchy-Schwarz Inequality</h3>
+
+						<div class="fragment">
+							\[ \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \]
+						</div>
+					</section>
+
+					<section>
+						<h3>A Cross Product Formula</h3>
+
+						<div class="fragment">
+							\[\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix}
+							\mathbf{i} &amp; \mathbf{j} &amp; \mathbf{k} \\
+							\frac{\partial X}{\partial u} &amp;  \frac{\partial Y}{\partial u} &amp; 0 \\
+							\frac{\partial X}{\partial v} &amp;  \frac{\partial Y}{\partial v} &amp; 0
+							\end{vmatrix}  \]
+						</div>
+					</section>
+
+					<section>
+						<h3>The probability of getting \(k\) heads when flipping \(n\) coins is</h3>
+
+						<div class="fragment">
+							\[P(E)   = {n \choose k} p^k (1-p)^{ n-k} \]
+						</div>
+					</section>
+
+					<section>
+						<h3>An Identity of Ramanujan</h3>
+
+						<div class="fragment">
+							\[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} =
+							1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
+							{1+\frac{e^{-8\pi}} {1+\ldots} } } } \]
+						</div>
+					</section>
+
+					<section>
+						<h3>A Rogers-Ramanujan Identity</h3>
+
+						<div class="fragment">
+							\[  1 +  \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots =
+							\prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}\]
+						</div>
+					</section>
+
+					<section>
+						<h3>Maxwell&#8217;s Equations</h3>
+
+						<div class="fragment">
+							\[  \begin{aligned}
+							\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\   \nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\
+							\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\
+							\nabla \cdot \vec{\mathbf{B}} &amp; = 0 \end{aligned}
+							\]
+						</div>
+					</section>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.min.js"></script>
+
+		<script>
+
+			Reveal.initialize({
+				history: true,
+				transition: 'linear',
+
+				math: {
+					// mathjax: 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
+					config: 'TeX-AMS_HTML-full'
+				},
+
+				dependencies: [
+					{ src: '../../lib/js/classList.js' },
+					{ src: '../../plugin/math/math.js', async: true }
+				]
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/test/examples/slide-backgrounds.html b/docs/slides/BOS14/_support/reveal.js/test/examples/slide-backgrounds.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/examples/slide-backgrounds.html
@@ -0,0 +1,122 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Slide Backgrounds</title>
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/theme/serif.css" id="theme">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+				<section data-background="#00ffff">
+					<h2>data-background: #00ffff</h2>
+				</section>
+
+				<section data-background="#bb00bb">
+					<h2>data-background: #bb00bb</h2>
+				</section>
+
+				<section>
+					<section data-background="#ff0000">
+						<h2>data-background: #ff0000</h2>
+					</section>
+					<section data-background="rgba(0, 0, 0, 0.2)">
+						<h2>data-background: rgba(0, 0, 0, 0.2)</h2>
+					</section>
+					<section data-background="salmon">
+						<h2>data-background: salmon</h2>
+					</section>
+				</section>
+
+				<section data-background="rgba(0, 100, 100, 0.2)">
+					<section>
+						<h2>Background applied to stack</h2>
+					</section>
+					<section>
+						<h2>Background applied to stack</h2>
+					</section>
+					<section data-background="rgba(100, 0, 0, 0.2)">
+						<h2>Background applied to slide inside of stack</h2>
+					</section>
+				</section>
+
+				<section data-background-transition="slide" data-background="assets/image1.png" style="background: rgba(255,255,255,0.9)">
+					<h2>Background image</h2>
+				</section>
+
+				<section>
+					<section data-background-transition="slide" data-background="assets/image1.png" style="background: rgba(255,255,255,0.9)">
+						<h2>Background image</h2>
+					</section>
+					<section data-background-transition="slide" data-background="assets/image1.png" style="background: rgba(255,255,255,0.9)">
+						<h2>Background image</h2>
+					</section>
+				</section>
+
+				<section data-background="assets/image2.png" data-background-size="100px" data-background-repeat="repeat" data-background-color="#111" style="background: rgba(255,255,255,0.9)">
+					<h2>Background image</h2>
+					<pre>data-background-size="100px" data-background-repeat="repeat" data-background-color="#111"</pre>
+				</section>
+
+				<section data-background="#888888">
+					<h2>Same background twice (1/2)</h2>
+				</section>
+				<section data-background="#888888">
+					<h2>Same background twice (2/2)</h2>
+				</section>
+
+				<section>
+					<section data-background="#417203">
+						<h2>Same background twice vertical (1/2)</h2>
+					</section>
+					<section data-background="#417203">
+						<h2>Same background twice vertical (2/2)</h2>
+					</section>
+				</section>
+
+				<section data-background="#934f4d">
+					<h2>Same background from horizontal to vertical (1/3)</h2>
+				</section>
+				<section>
+					<section data-background="#934f4d">
+						<h2>Same background from horizontal to vertical (2/3)</h2>
+					</section>
+					<section data-background="#934f4d">
+						<h2>Same background from horizontal to vertical (3/3)</h2>
+					</section>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.min.js"></script>
+
+		<script>
+
+			// Full list of configuration options available here:
+			// https://github.com/hakimel/reveal.js#configuration
+			Reveal.initialize({
+				center: true,
+				// rtl: true,
+
+				transition: 'linear',
+				// transitionSpeed: 'slow',
+				// backgroundTransition: 'slide'
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/test/qunit-1.12.0.css b/docs/slides/BOS14/_support/reveal.js/test/qunit-1.12.0.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/qunit-1.12.0.css
@@ -0,0 +1,244 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+	margin: 0;
+	padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+	padding: 0.5em 0 0.5em 1em;
+
+	color: #8699a4;
+	background-color: #0d3349;
+
+	font-size: 1.5em;
+	line-height: 1em;
+	font-weight: normal;
+
+	border-radius: 5px 5px 0 0;
+	-moz-border-radius: 5px 5px 0 0;
+	-webkit-border-top-right-radius: 5px;
+	-webkit-border-top-left-radius: 5px;
+}
+
+#qunit-header a {
+	text-decoration: none;
+	color: #c2ccd1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+	color: #fff;
+}
+
+#qunit-testrunner-toolbar label {
+	display: inline-block;
+	padding: 0 .5em 0 .1em;
+}
+
+#qunit-banner {
+	height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+	padding: 0.5em 0 0.5em 2em;
+	color: #5E740B;
+	background-color: #eee;
+	overflow: hidden;
+}
+
+#qunit-userAgent {
+	padding: 0.5em 0 0.5em 2.5em;
+	background-color: #2b81af;
+	color: #fff;
+	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+#qunit-modulefilter-container {
+	float: right;
+}
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+	list-style-position: inside;
+}
+
+#qunit-tests li {
+	padding: 0.4em 0.5em 0.4em 2.5em;
+	border-bottom: 1px solid #fff;
+	list-style-position: inside;
+}
+
+#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
+	display: none;
+}
+
+#qunit-tests li strong {
+	cursor: pointer;
+}
+
+#qunit-tests li a {
+	padding: 0.5em;
+	color: #c2ccd1;
+	text-decoration: none;
+}
+#qunit-tests li a:hover,
+#qunit-tests li a:focus {
+	color: #000;
+}
+
+#qunit-tests li .runtime {
+	float: right;
+	font-size: smaller;
+}
+
+.qunit-assert-list {
+	margin-top: 0.5em;
+	padding: 0.5em;
+
+	background-color: #fff;
+
+	border-radius: 5px;
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+}
+
+.qunit-collapsed {
+	display: none;
+}
+
+#qunit-tests table {
+	border-collapse: collapse;
+	margin-top: .2em;
+}
+
+#qunit-tests th {
+	text-align: right;
+	vertical-align: top;
+	padding: 0 .5em 0 0;
+}
+
+#qunit-tests td {
+	vertical-align: top;
+}
+
+#qunit-tests pre {
+	margin: 0;
+	white-space: pre-wrap;
+	word-wrap: break-word;
+}
+
+#qunit-tests del {
+	background-color: #e0f2be;
+	color: #374e0c;
+	text-decoration: none;
+}
+
+#qunit-tests ins {
+	background-color: #ffcaca;
+	color: #500;
+	text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts                       { color: black; }
+#qunit-tests b.passed                       { color: #5E740B; }
+#qunit-tests b.failed                       { color: #710909; }
+
+#qunit-tests li li {
+	padding: 5px;
+	background-color: #fff;
+	border-bottom: none;
+	list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+	color: #3c510c;
+	background-color: #fff;
+	border-left: 10px solid #C6E746;
+}
+
+#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name               { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected           { color: #999999; }
+
+#qunit-banner.qunit-pass                    { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+	color: #710909;
+	background-color: #fff;
+	border-left: 10px solid #EE5757;
+	white-space: pre;
+}
+
+#qunit-tests > li:last-child {
+	border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-webkit-border-bottom-right-radius: 5px;
+	-webkit-border-bottom-left-radius: 5px;
+}
+
+#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name             { color: #000000; }
+
+#qunit-tests .fail .test-actual             { color: #EE5757; }
+#qunit-tests .fail .test-expected           { color: green;   }
+
+#qunit-banner.qunit-fail                    { background-color: #EE5757; }
+
+
+/** Result */
+
+#qunit-testresult {
+	padding: 0.5em 0.5em 0.5em 2.5em;
+
+	color: #2b81af;
+	background-color: #D2E0E6;
+
+	border-bottom: 1px solid white;
+}
+#qunit-testresult .module-name {
+	font-weight: bold;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+	position: absolute;
+	top: -10000px;
+	left: -10000px;
+	width: 1000px;
+	height: 1000px;
+}
diff --git a/docs/slides/BOS14/_support/reveal.js/test/qunit-1.12.0.js b/docs/slides/BOS14/_support/reveal.js/test/qunit-1.12.0.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/qunit-1.12.0.js
@@ -0,0 +1,2212 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * https://jquery.org/license/
+ */
+
+(function( window ) {
+
+var QUnit,
+	assert,
+	config,
+	onErrorFnPrev,
+	testId = 0,
+	fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	// Keep a local reference to Date (GH-283)
+	Date = window.Date,
+	setTimeout = window.setTimeout,
+	defined = {
+		setTimeout: typeof window.setTimeout !== "undefined",
+		sessionStorage: (function() {
+			var x = "qunit-test-string";
+			try {
+				sessionStorage.setItem( x, x );
+				sessionStorage.removeItem( x );
+				return true;
+			} catch( e ) {
+				return false;
+			}
+		}())
+	},
+	/**
+	 * Provides a normalized error string, correcting an issue
+	 * with IE 7 (and prior) where Error.prototype.toString is
+	 * not properly implemented
+	 *
+	 * Based on http://es5.github.com/#x15.11.4.4
+	 *
+	 * @param {String|Error} error
+	 * @return {String} error message
+	 */
+	errorString = function( error ) {
+		var name, message,
+			errorString = error.toString();
+		if ( errorString.substring( 0, 7 ) === "[object" ) {
+			name = error.name ? error.name.toString() : "Error";
+			message = error.message ? error.message.toString() : "";
+			if ( name && message ) {
+				return name + ": " + message;
+			} else if ( name ) {
+				return name;
+			} else if ( message ) {
+				return message;
+			} else {
+				return "Error";
+			}
+		} else {
+			return errorString;
+		}
+	},
+	/**
+	 * Makes a clone of an object using only Array or Object as base,
+	 * and copies over the own enumerable properties.
+	 *
+	 * @param {Object} obj
+	 * @return {Object} New object with only the own properties (recursively).
+	 */
+	objectValues = function( obj ) {
+		// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
+		/*jshint newcap: false */
+		var key, val,
+			vals = QUnit.is( "array", obj ) ? [] : {};
+		for ( key in obj ) {
+			if ( hasOwn.call( obj, key ) ) {
+				val = obj[key];
+				vals[key] = val === Object(val) ? objectValues(val) : val;
+			}
+		}
+		return vals;
+	};
+
+function Test( settings ) {
+	extend( this, settings );
+	this.assertions = [];
+	this.testNumber = ++Test.count;
+}
+
+Test.count = 0;
+
+Test.prototype = {
+	init: function() {
+		var a, b, li,
+			tests = id( "qunit-tests" );
+
+		if ( tests ) {
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml;
+
+			// `a` initialized at top of scope
+			a = document.createElement( "a" );
+			a.innerHTML = "Rerun";
+			a.href = QUnit.url({ testNumber: this.testNumber });
+
+			li = document.createElement( "li" );
+			li.appendChild( b );
+			li.appendChild( a );
+			li.className = "running";
+			li.id = this.id = "qunit-test-output" + testId++;
+
+			tests.appendChild( li );
+		}
+	},
+	setup: function() {
+		if (
+			// Emit moduleStart when we're switching from one module to another
+			this.module !== config.previousModule ||
+				// They could be equal (both undefined) but if the previousModule property doesn't
+				// yet exist it means this is the first test in a suite that isn't wrapped in a
+				// module, in which case we'll just emit a moduleStart event for 'undefined'.
+				// Without this, reporters can get testStart before moduleStart  which is a problem.
+				!hasOwn.call( config, "previousModule" )
+		) {
+			if ( hasOwn.call( config, "previousModule" ) ) {
+				runLoggingCallbacks( "moduleDone", QUnit, {
+					name: config.previousModule,
+					failed: config.moduleStats.bad,
+					passed: config.moduleStats.all - config.moduleStats.bad,
+					total: config.moduleStats.all
+				});
+			}
+			config.previousModule = this.module;
+			config.moduleStats = { all: 0, bad: 0 };
+			runLoggingCallbacks( "moduleStart", QUnit, {
+				name: this.module
+			});
+		}
+
+		config.current = this;
+
+		this.testEnvironment = extend({
+			setup: function() {},
+			teardown: function() {}
+		}, this.moduleTestEnvironment );
+
+		this.started = +new Date();
+		runLoggingCallbacks( "testStart", QUnit, {
+			name: this.testName,
+			module: this.module
+		});
+
+		/*jshint camelcase:false */
+
+
+		/**
+		 * Expose the current test environment.
+		 *
+		 * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
+		 */
+		QUnit.current_testEnvironment = this.testEnvironment;
+
+		/*jshint camelcase:true */
+
+		if ( !config.pollution ) {
+			saveGlobal();
+		}
+		if ( config.notrycatch ) {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+			return;
+		}
+		try {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+		} catch( e ) {
+			QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+		}
+	},
+	run: function() {
+		config.current = this;
+
+		var running = id( "qunit-testresult" );
+
+		if ( running ) {
+			running.innerHTML = "Running: <br/>" + this.nameHtml;
+		}
+
+		if ( this.async ) {
+			QUnit.stop();
+		}
+
+		this.callbackStarted = +new Date();
+
+		if ( config.notrycatch ) {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+			return;
+		}
+
+		try {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+		} catch( e ) {
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+
+			QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
+			// else next test will carry the responsibility
+			saveGlobal();
+
+			// Restart the tests if they're blocking
+			if ( config.blocking ) {
+				QUnit.start();
+			}
+		}
+	},
+	teardown: function() {
+		config.current = this;
+		if ( config.notrycatch ) {
+			if ( typeof this.callbackRuntime === "undefined" ) {
+				this.callbackRuntime = +new Date() - this.callbackStarted;
+			}
+			this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			return;
+		} else {
+			try {
+				this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			} catch( e ) {
+				QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+			}
+		}
+		checkPollution();
+	},
+	finish: function() {
+		config.current = this;
+		if ( config.requireExpects && this.expected === null ) {
+			QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
+		} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
+			QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
+		} else if ( this.expected === null && !this.assertions.length ) {
+			QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
+		}
+
+		var i, assertion, a, b, time, li, ol,
+			test = this,
+			good = 0,
+			bad = 0,
+			tests = id( "qunit-tests" );
+
+		this.runtime = +new Date() - this.started;
+		config.stats.all += this.assertions.length;
+		config.moduleStats.all += this.assertions.length;
+
+		if ( tests ) {
+			ol = document.createElement( "ol" );
+			ol.className = "qunit-assert-list";
+
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				assertion = this.assertions[i];
+
+				li = document.createElement( "li" );
+				li.className = assertion.result ? "pass" : "fail";
+				li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
+				ol.appendChild( li );
+
+				if ( assertion.result ) {
+					good++;
+				} else {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+
+			// store result when possible
+			if ( QUnit.config.reorder && defined.sessionStorage ) {
+				if ( bad ) {
+					sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
+				} else {
+					sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
+				}
+			}
+
+			if ( bad === 0 ) {
+				addClass( ol, "qunit-collapsed" );
+			}
+
+			// `b` initialized at top of scope
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+
+			addEvent(b, "click", function() {
+				var next = b.parentNode.lastChild,
+					collapsed = hasClass( next, "qunit-collapsed" );
+				( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
+			});
+
+			addEvent(b, "dblclick", function( e ) {
+				var target = e && e.target ? e.target : window.event.srcElement;
+				if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
+					target = target.parentNode;
+				}
+				if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
+					window.location = QUnit.url({ testNumber: test.testNumber });
+				}
+			});
+
+			// `time` initialized at top of scope
+			time = document.createElement( "span" );
+			time.className = "runtime";
+			time.innerHTML = this.runtime + " ms";
+
+			// `li` initialized at top of scope
+			li = id( this.id );
+			li.className = bad ? "fail" : "pass";
+			li.removeChild( li.firstChild );
+			a = li.firstChild;
+			li.appendChild( b );
+			li.appendChild( a );
+			li.appendChild( time );
+			li.appendChild( ol );
+
+		} else {
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				if ( !this.assertions[i].result ) {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+		}
+
+		runLoggingCallbacks( "testDone", QUnit, {
+			name: this.testName,
+			module: this.module,
+			failed: bad,
+			passed: this.assertions.length - bad,
+			total: this.assertions.length,
+			duration: this.runtime
+		});
+
+		QUnit.reset();
+
+		config.current = undefined;
+	},
+
+	queue: function() {
+		var bad,
+			test = this;
+
+		synchronize(function() {
+			test.init();
+		});
+		function run() {
+			// each of these can by async
+			synchronize(function() {
+				test.setup();
+			});
+			synchronize(function() {
+				test.run();
+			});
+			synchronize(function() {
+				test.teardown();
+			});
+			synchronize(function() {
+				test.finish();
+			});
+		}
+
+		// `bad` initialized at top of scope
+		// defer when previous test run passed, if storage is available
+		bad = QUnit.config.reorder && defined.sessionStorage &&
+						+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
+
+		if ( bad ) {
+			run();
+		} else {
+			synchronize( run, true );
+		}
+	}
+};
+
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+QUnit = {
+
+	// call on start of module test to prepend name to all tests
+	module: function( name, testEnvironment ) {
+		config.currentModule = name;
+		config.currentModuleTestEnvironment = testEnvironment;
+		config.modules[name] = true;
+	},
+
+	asyncTest: function( testName, expected, callback ) {
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		QUnit.test( testName, expected, callback, true );
+	},
+
+	test: function( testName, expected, callback, async ) {
+		var test,
+			nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
+
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		if ( config.currentModule ) {
+			nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
+		}
+
+		test = new Test({
+			nameHtml: nameHtml,
+			testName: testName,
+			expected: expected,
+			async: async,
+			callback: callback,
+			module: config.currentModule,
+			moduleTestEnvironment: config.currentModuleTestEnvironment,
+			stack: sourceFromStacktrace( 2 )
+		});
+
+		if ( !validTest( test ) ) {
+			return;
+		}
+
+		test.queue();
+	},
+
+	// Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
+	expect: function( asserts ) {
+		if (arguments.length === 1) {
+			config.current.expected = asserts;
+		} else {
+			return config.current.expected;
+		}
+	},
+
+	start: function( count ) {
+		// QUnit hasn't been initialized yet.
+		// Note: RequireJS (et al) may delay onLoad
+		if ( config.semaphore === undefined ) {
+			QUnit.begin(function() {
+				// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+				setTimeout(function() {
+					QUnit.start( count );
+				});
+			});
+			return;
+		}
+
+		config.semaphore -= count || 1;
+		// don't start until equal number of stop-calls
+		if ( config.semaphore > 0 ) {
+			return;
+		}
+		// ignore if start is called more often then stop
+		if ( config.semaphore < 0 ) {
+			config.semaphore = 0;
+			QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
+			return;
+		}
+		// A slight delay, to avoid any current callbacks
+		if ( defined.setTimeout ) {
+			setTimeout(function() {
+				if ( config.semaphore > 0 ) {
+					return;
+				}
+				if ( config.timeout ) {
+					clearTimeout( config.timeout );
+				}
+
+				config.blocking = false;
+				process( true );
+			}, 13);
+		} else {
+			config.blocking = false;
+			process( true );
+		}
+	},
+
+	stop: function( count ) {
+		config.semaphore += count || 1;
+		config.blocking = true;
+
+		if ( config.testTimeout && defined.setTimeout ) {
+			clearTimeout( config.timeout );
+			config.timeout = setTimeout(function() {
+				QUnit.ok( false, "Test timed out" );
+				config.semaphore = 1;
+				QUnit.start();
+			}, config.testTimeout );
+		}
+	}
+};
+
+// `assert` initialized at top of scope
+// Assert helpers
+// All of these must either call QUnit.push() or manually do:
+// - runLoggingCallbacks( "log", .. );
+// - config.current.assertions.push({ .. });
+// We attach it to the QUnit object *after* we expose the public API,
+// otherwise `assert` will become a global variable in browsers (#341).
+assert = {
+	/**
+	 * Asserts rough true-ish result.
+	 * @name ok
+	 * @function
+	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+	 */
+	ok: function( result, msg ) {
+		if ( !config.current ) {
+			throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+		result = !!result;
+		msg = msg || (result ? "okay" : "failed" );
+
+		var source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: msg
+			};
+
+		msg = "<span class='test-message'>" + escapeText( msg ) + "</span>";
+
+		if ( !result ) {
+			source = sourceFromStacktrace( 2 );
+			if ( source ) {
+				details.source = source;
+				msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
+			}
+		}
+		runLoggingCallbacks( "log", QUnit, details );
+		config.current.assertions.push({
+			result: result,
+			message: msg
+		});
+	},
+
+	/**
+	 * Assert that the first two arguments are equal, with an optional message.
+	 * Prints out both actual and expected values.
+	 * @name equal
+	 * @function
+	 * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
+	 */
+	equal: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected == actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notEqual
+	 * @function
+	 */
+	notEqual: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected != actual, actual, expected, message );
+	},
+
+	/**
+	 * @name propEqual
+	 * @function
+	 */
+	propEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notPropEqual
+	 * @function
+	 */
+	notPropEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name deepEqual
+	 * @function
+	 */
+	deepEqual: function( actual, expected, message ) {
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notDeepEqual
+	 * @function
+	 */
+	notDeepEqual: function( actual, expected, message ) {
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name strictEqual
+	 * @function
+	 */
+	strictEqual: function( actual, expected, message ) {
+		QUnit.push( expected === actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notStrictEqual
+	 * @function
+	 */
+	notStrictEqual: function( actual, expected, message ) {
+		QUnit.push( expected !== actual, actual, expected, message );
+	},
+
+	"throws": function( block, expected, message ) {
+		var actual,
+			expectedOutput = expected,
+			ok = false;
+
+		// 'expected' is optional
+		if ( typeof expected === "string" ) {
+			message = expected;
+			expected = null;
+		}
+
+		config.current.ignoreGlobalErrors = true;
+		try {
+			block.call( config.current.testEnvironment );
+		} catch (e) {
+			actual = e;
+		}
+		config.current.ignoreGlobalErrors = false;
+
+		if ( actual ) {
+			// we don't want to validate thrown error
+			if ( !expected ) {
+				ok = true;
+				expectedOutput = null;
+			// expected is a regexp
+			} else if ( QUnit.objectType( expected ) === "regexp" ) {
+				ok = expected.test( errorString( actual ) );
+			// expected is a constructor
+			} else if ( actual instanceof expected ) {
+				ok = true;
+			// expected is a validation function which returns true is validation passed
+			} else if ( expected.call( {}, actual ) === true ) {
+				expectedOutput = null;
+				ok = true;
+			}
+
+			QUnit.push( ok, actual, expectedOutput, message );
+		} else {
+			QUnit.pushFailure( message, null, "No exception was thrown." );
+		}
+	}
+};
+
+/**
+ * @deprecated since 1.8.0
+ * Kept assertion helpers in root for backwards compatibility.
+ */
+extend( QUnit, assert );
+
+/**
+ * @deprecated since 1.9.0
+ * Kept root "raises()" for backwards compatibility.
+ * (Note that we don't introduce assert.raises).
+ */
+QUnit.raises = assert[ "throws" ];
+
+/**
+ * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
+ * Kept to avoid TypeErrors for undefined methods.
+ */
+QUnit.equals = function() {
+	QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
+};
+QUnit.same = function() {
+	QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
+};
+
+// We want access to the constructor's prototype
+(function() {
+	function F() {}
+	F.prototype = QUnit;
+	QUnit = new F();
+	// Make F QUnit's constructor so that we can add to the prototype later
+	QUnit.constructor = F;
+}());
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+	// The queue of tests to run
+	queue: [],
+
+	// block until document ready
+	blocking: true,
+
+	// when enabled, show only failing tests
+	// gets persisted through sessionStorage and can be changed in UI via checkbox
+	hidepassed: false,
+
+	// by default, run previously failed tests first
+	// very useful in combination with "Hide passed tests" checked
+	reorder: true,
+
+	// by default, modify document.title when suite is done
+	altertitle: true,
+
+	// when enabled, all tests must call expect()
+	requireExpects: false,
+
+	// add checkboxes that are persisted in the query-string
+	// when enabled, the id is set to `true` as a `QUnit.config` property
+	urlConfig: [
+		{
+			id: "noglobals",
+			label: "Check for Globals",
+			tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
+		},
+		{
+			id: "notrycatch",
+			label: "No try-catch",
+			tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
+		}
+	],
+
+	// Set of all modules.
+	modules: {},
+
+	// logging callback queues
+	begin: [],
+	done: [],
+	log: [],
+	testStart: [],
+	testDone: [],
+	moduleStart: [],
+	moduleDone: []
+};
+
+// Export global variables, unless an 'exports' object exists,
+// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
+if ( typeof exports === "undefined" ) {
+	extend( window, QUnit.constructor.prototype );
+
+	// Expose QUnit object
+	window.QUnit = QUnit;
+}
+
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+	var i,
+		location = window.location || { search: "", protocol: "file:" },
+		params = location.search.slice( 1 ).split( "&" ),
+		length = params.length,
+		urlParams = {},
+		current;
+
+	if ( params[ 0 ] ) {
+		for ( i = 0; i < length; i++ ) {
+			current = params[ i ].split( "=" );
+			current[ 0 ] = decodeURIComponent( current[ 0 ] );
+			// allow just a key to turn on a flag, e.g., test.html?noglobals
+			current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
+			urlParams[ current[ 0 ] ] = current[ 1 ];
+		}
+	}
+
+	QUnit.urlParams = urlParams;
+
+	// String search anywhere in moduleName+testName
+	config.filter = urlParams.filter;
+
+	// Exact match of the module name
+	config.module = urlParams.module;
+
+	config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
+
+	// Figure out if we're running the tests from a server or not
+	QUnit.isLocal = location.protocol === "file:";
+}());
+
+// Extend QUnit object,
+// these after set here because they should not be exposed as global functions
+extend( QUnit, {
+	assert: assert,
+
+	config: config,
+
+	// Initialize the configuration options
+	init: function() {
+		extend( config, {
+			stats: { all: 0, bad: 0 },
+			moduleStats: { all: 0, bad: 0 },
+			started: +new Date(),
+			updateRate: 1000,
+			blocking: false,
+			autostart: true,
+			autorun: false,
+			filter: "",
+			queue: [],
+			semaphore: 1
+		});
+
+		var tests, banner, result,
+			qunit = id( "qunit" );
+
+		if ( qunit ) {
+			qunit.innerHTML =
+				"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+				"<h2 id='qunit-banner'></h2>" +
+				"<div id='qunit-testrunner-toolbar'></div>" +
+				"<h2 id='qunit-userAgent'></h2>" +
+				"<ol id='qunit-tests'></ol>";
+		}
+
+		tests = id( "qunit-tests" );
+		banner = id( "qunit-banner" );
+		result = id( "qunit-testresult" );
+
+		if ( tests ) {
+			tests.innerHTML = "";
+		}
+
+		if ( banner ) {
+			banner.className = "";
+		}
+
+		if ( result ) {
+			result.parentNode.removeChild( result );
+		}
+
+		if ( tests ) {
+			result = document.createElement( "p" );
+			result.id = "qunit-testresult";
+			result.className = "result";
+			tests.parentNode.insertBefore( result, tests );
+			result.innerHTML = "Running...<br/>&nbsp;";
+		}
+	},
+
+	// Resets the test setup. Useful for tests that modify the DOM.
+	/*
+	DEPRECATED: Use multiple tests instead of resetting inside a test.
+	Use testStart or testDone for custom cleanup.
+	This method will throw an error in 2.0, and will be removed in 2.1
+	*/
+	reset: function() {
+		var fixture = id( "qunit-fixture" );
+		if ( fixture ) {
+			fixture.innerHTML = config.fixture;
+		}
+	},
+
+	// Trigger an event on an element.
+	// @example triggerEvent( document.body, "click" );
+	triggerEvent: function( elem, type, event ) {
+		if ( document.createEvent ) {
+			event = document.createEvent( "MouseEvents" );
+			event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+				0, 0, 0, 0, 0, false, false, false, false, 0, null);
+
+			elem.dispatchEvent( event );
+		} else if ( elem.fireEvent ) {
+			elem.fireEvent( "on" + type );
+		}
+	},
+
+	// Safe object type checking
+	is: function( type, obj ) {
+		return QUnit.objectType( obj ) === type;
+	},
+
+	objectType: function( obj ) {
+		if ( typeof obj === "undefined" ) {
+				return "undefined";
+		// consider: typeof null === object
+		}
+		if ( obj === null ) {
+				return "null";
+		}
+
+		var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+			type = match && match[1] || "";
+
+		switch ( type ) {
+			case "Number":
+				if ( isNaN(obj) ) {
+					return "nan";
+				}
+				return "number";
+			case "String":
+			case "Boolean":
+			case "Array":
+			case "Date":
+			case "RegExp":
+			case "Function":
+				return type.toLowerCase();
+		}
+		if ( typeof obj === "object" ) {
+			return "object";
+		}
+		return undefined;
+	},
+
+	push: function( result, actual, expected, message ) {
+		if ( !config.current ) {
+			throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
+		}
+
+		var output, source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: message,
+				actual: actual,
+				expected: expected
+			};
+
+		message = escapeText( message ) || ( result ? "okay" : "failed" );
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		if ( !result ) {
+			expected = escapeText( QUnit.jsDump.parse(expected) );
+			actual = escapeText( QUnit.jsDump.parse(actual) );
+			output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
+
+			if ( actual !== expected ) {
+				output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
+				output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
+			}
+
+			source = sourceFromStacktrace();
+
+			if ( source ) {
+				details.source = source;
+				output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+			}
+
+			output += "</table>";
+		}
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: !!result,
+			message: output
+		});
+	},
+
+	pushFailure: function( message, source, actual ) {
+		if ( !config.current ) {
+			throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+
+		var output,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: false,
+				message: message
+			};
+
+		message = escapeText( message ) || "error";
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		output += "<table>";
+
+		if ( actual ) {
+			output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
+		}
+
+		if ( source ) {
+			details.source = source;
+			output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+		}
+
+		output += "</table>";
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: false,
+			message: output
+		});
+	},
+
+	url: function( params ) {
+		params = extend( extend( {}, QUnit.urlParams ), params );
+		var key,
+			querystring = "?";
+
+		for ( key in params ) {
+			if ( hasOwn.call( params, key ) ) {
+				querystring += encodeURIComponent( key ) + "=" +
+					encodeURIComponent( params[ key ] ) + "&";
+			}
+		}
+		return window.location.protocol + "//" + window.location.host +
+			window.location.pathname + querystring.slice( 0, -1 );
+	},
+
+	extend: extend,
+	id: id,
+	addEvent: addEvent,
+	addClass: addClass,
+	hasClass: hasClass,
+	removeClass: removeClass
+	// load, equiv, jsDump, diff: Attached later
+});
+
+/**
+ * @deprecated: Created for backwards compatibility with test runner that set the hook function
+ * into QUnit.{hook}, instead of invoking it and passing the hook function.
+ * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
+ * Doing this allows us to tell if the following methods have been overwritten on the actual
+ * QUnit object.
+ */
+extend( QUnit.constructor.prototype, {
+
+	// Logging callbacks; all receive a single argument with the listed properties
+	// run test/logs.html for any related changes
+	begin: registerLoggingCallback( "begin" ),
+
+	// done: { failed, passed, total, runtime }
+	done: registerLoggingCallback( "done" ),
+
+	// log: { result, actual, expected, message }
+	log: registerLoggingCallback( "log" ),
+
+	// testStart: { name }
+	testStart: registerLoggingCallback( "testStart" ),
+
+	// testDone: { name, failed, passed, total, duration }
+	testDone: registerLoggingCallback( "testDone" ),
+
+	// moduleStart: { name }
+	moduleStart: registerLoggingCallback( "moduleStart" ),
+
+	// moduleDone: { name, failed, passed, total }
+	moduleDone: registerLoggingCallback( "moduleDone" )
+});
+
+if ( typeof document === "undefined" || document.readyState === "complete" ) {
+	config.autorun = true;
+}
+
+QUnit.load = function() {
+	runLoggingCallbacks( "begin", QUnit, {} );
+
+	// Initialize the config, saving the execution queue
+	var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
+		urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
+		numModules = 0,
+		moduleNames = [],
+		moduleFilterHtml = "",
+		urlConfigHtml = "",
+		oldconfig = extend( {}, config );
+
+	QUnit.init();
+	extend(config, oldconfig);
+
+	config.blocking = false;
+
+	len = config.urlConfig.length;
+
+	for ( i = 0; i < len; i++ ) {
+		val = config.urlConfig[i];
+		if ( typeof val === "string" ) {
+			val = {
+				id: val,
+				label: val,
+				tooltip: "[no tooltip available]"
+			};
+		}
+		config[ val.id ] = QUnit.urlParams[ val.id ];
+		urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
+			"' name='" + escapeText( val.id ) +
+			"' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
+			" title='" + escapeText( val.tooltip ) +
+			"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
+			"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
+	}
+	for ( i in config.modules ) {
+		if ( config.modules.hasOwnProperty( i ) ) {
+			moduleNames.push(i);
+		}
+	}
+	numModules = moduleNames.length;
+	moduleNames.sort( function( a, b ) {
+		return a.localeCompare( b );
+	});
+	moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+		( config.module === undefined  ? "selected='selected'" : "" ) +
+		">< All Modules ></option>";
+
+
+	for ( i = 0; i < numModules; i++) {
+			moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " +
+				( config.module === moduleNames[i] ? "selected='selected'" : "" ) +
+				">" + escapeText(moduleNames[i]) + "</option>";
+	}
+	moduleFilterHtml += "</select>";
+
+	// `userAgent` initialized at top of scope
+	userAgent = id( "qunit-userAgent" );
+	if ( userAgent ) {
+		userAgent.innerHTML = navigator.userAgent;
+	}
+
+	// `banner` initialized at top of scope
+	banner = id( "qunit-header" );
+	if ( banner ) {
+		banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
+	}
+
+	// `toolbar` initialized at top of scope
+	toolbar = id( "qunit-testrunner-toolbar" );
+	if ( toolbar ) {
+		// `filter` initialized at top of scope
+		filter = document.createElement( "input" );
+		filter.type = "checkbox";
+		filter.id = "qunit-filter-pass";
+
+		addEvent( filter, "click", function() {
+			var tmp,
+				ol = document.getElementById( "qunit-tests" );
+
+			if ( filter.checked ) {
+				ol.className = ol.className + " hidepass";
+			} else {
+				tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
+				ol.className = tmp.replace( / hidepass /, " " );
+			}
+			if ( defined.sessionStorage ) {
+				if (filter.checked) {
+					sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+				} else {
+					sessionStorage.removeItem( "qunit-filter-passed-tests" );
+				}
+			}
+		});
+
+		if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
+			filter.checked = true;
+			// `ol` initialized at top of scope
+			ol = document.getElementById( "qunit-tests" );
+			ol.className = ol.className + " hidepass";
+		}
+		toolbar.appendChild( filter );
+
+		// `label` initialized at top of scope
+		label = document.createElement( "label" );
+		label.setAttribute( "for", "qunit-filter-pass" );
+		label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
+		label.innerHTML = "Hide passed tests";
+		toolbar.appendChild( label );
+
+		urlConfigCheckboxesContainer = document.createElement("span");
+		urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
+		urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
+		// For oldIE support:
+		// * Add handlers to the individual elements instead of the container
+		// * Use "click" instead of "change"
+		// * Fallback from event.target to event.srcElement
+		addEvents( urlConfigCheckboxes, "click", function( event ) {
+			var params = {},
+				target = event.target || event.srcElement;
+			params[ target.name ] = target.checked ? true : undefined;
+			window.location = QUnit.url( params );
+		});
+		toolbar.appendChild( urlConfigCheckboxesContainer );
+
+		if (numModules > 1) {
+			moduleFilter = document.createElement( "span" );
+			moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+			moduleFilter.innerHTML = moduleFilterHtml;
+			addEvent( moduleFilter.lastChild, "change", function() {
+				var selectBox = moduleFilter.getElementsByTagName("select")[0],
+					selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+				window.location = QUnit.url({
+					module: ( selectedModule === "" ) ? undefined : selectedModule,
+					// Remove any existing filters
+					filter: undefined,
+					testNumber: undefined
+				});
+			});
+			toolbar.appendChild(moduleFilter);
+		}
+	}
+
+	// `main` initialized at top of scope
+	main = id( "qunit-fixture" );
+	if ( main ) {
+		config.fixture = main.innerHTML;
+	}
+
+	if ( config.autostart ) {
+		QUnit.start();
+	}
+};
+
+addEvent( window, "load", QUnit.load );
+
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will suppress the default browser handler,
+// returning false will let it run.
+window.onerror = function ( error, filePath, linerNr ) {
+	var ret = false;
+	if ( onErrorFnPrev ) {
+		ret = onErrorFnPrev( error, filePath, linerNr );
+	}
+
+	// Treat return value as window.onerror itself does,
+	// Only do our handling if not suppressed.
+	if ( ret !== true ) {
+		if ( QUnit.config.current ) {
+			if ( QUnit.config.current.ignoreGlobalErrors ) {
+				return true;
+			}
+			QUnit.pushFailure( error, filePath + ":" + linerNr );
+		} else {
+			QUnit.test( "global failure", extend( function() {
+				QUnit.pushFailure( error, filePath + ":" + linerNr );
+			}, { validTest: validTest } ) );
+		}
+		return false;
+	}
+
+	return ret;
+};
+
+function done() {
+	config.autorun = true;
+
+	// Log the last module results
+	if ( config.currentModule ) {
+		runLoggingCallbacks( "moduleDone", QUnit, {
+			name: config.currentModule,
+			failed: config.moduleStats.bad,
+			passed: config.moduleStats.all - config.moduleStats.bad,
+			total: config.moduleStats.all
+		});
+	}
+	delete config.previousModule;
+
+	var i, key,
+		banner = id( "qunit-banner" ),
+		tests = id( "qunit-tests" ),
+		runtime = +new Date() - config.started,
+		passed = config.stats.all - config.stats.bad,
+		html = [
+			"Tests completed in ",
+			runtime,
+			" milliseconds.<br/>",
+			"<span class='passed'>",
+			passed,
+			"</span> assertions of <span class='total'>",
+			config.stats.all,
+			"</span> passed, <span class='failed'>",
+			config.stats.bad,
+			"</span> failed."
+		].join( "" );
+
+	if ( banner ) {
+		banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
+	}
+
+	if ( tests ) {
+		id( "qunit-testresult" ).innerHTML = html;
+	}
+
+	if ( config.altertitle && typeof document !== "undefined" && document.title ) {
+		// show ✖ for good, ✔ for bad suite result in title
+		// use escape sequences in case file gets loaded with non-utf-8-charset
+		document.title = [
+			( config.stats.bad ? "\u2716" : "\u2714" ),
+			document.title.replace( /^[\u2714\u2716] /i, "" )
+		].join( " " );
+	}
+
+	// clear own sessionStorage items if all tests passed
+	if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
+		// `key` & `i` initialized at top of scope
+		for ( i = 0; i < sessionStorage.length; i++ ) {
+			key = sessionStorage.key( i++ );
+			if ( key.indexOf( "qunit-test-" ) === 0 ) {
+				sessionStorage.removeItem( key );
+			}
+		}
+	}
+
+	// scroll back to top to show results
+	if ( window.scrollTo ) {
+		window.scrollTo(0, 0);
+	}
+
+	runLoggingCallbacks( "done", QUnit, {
+		failed: config.stats.bad,
+		passed: passed,
+		total: config.stats.all,
+		runtime: runtime
+	});
+}
+
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+	var include,
+		filter = config.filter && config.filter.toLowerCase(),
+		module = config.module && config.module.toLowerCase(),
+		fullName = (test.module + ": " + test.testName).toLowerCase();
+
+	// Internally-generated tests are always valid
+	if ( test.callback && test.callback.validTest === validTest ) {
+		delete test.callback.validTest;
+		return true;
+	}
+
+	if ( config.testNumber ) {
+		return test.testNumber === config.testNumber;
+	}
+
+	if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
+		return false;
+	}
+
+	if ( !filter ) {
+		return true;
+	}
+
+	include = filter.charAt( 0 ) !== "!";
+	if ( !include ) {
+		filter = filter.slice( 1 );
+	}
+
+	// If the filter matches, we need to honour include
+	if ( fullName.indexOf( filter ) !== -1 ) {
+		return include;
+	}
+
+	// Otherwise, do the opposite
+	return !include;
+}
+
+// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
+// Later Safari and IE10 are supposed to support error.stack as well
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+	offset = offset === undefined ? 3 : offset;
+
+	var stack, include, i;
+
+	if ( e.stacktrace ) {
+		// Opera
+		return e.stacktrace.split( "\n" )[ offset + 3 ];
+	} else if ( e.stack ) {
+		// Firefox, Chrome
+		stack = e.stack.split( "\n" );
+		if (/^error$/i.test( stack[0] ) ) {
+			stack.shift();
+		}
+		if ( fileName ) {
+			include = [];
+			for ( i = offset; i < stack.length; i++ ) {
+				if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+					break;
+				}
+				include.push( stack[ i ] );
+			}
+			if ( include.length ) {
+				return include.join( "\n" );
+			}
+		}
+		return stack[ offset ];
+	} else if ( e.sourceURL ) {
+		// Safari, PhantomJS
+		// hopefully one day Safari provides actual stacktraces
+		// exclude useless self-reference for generated Error objects
+		if ( /qunit.js$/.test( e.sourceURL ) ) {
+			return;
+		}
+		// for actual exceptions, this is useful
+		return e.sourceURL + ":" + e.line;
+	}
+}
+function sourceFromStacktrace( offset ) {
+	try {
+		throw new Error();
+	} catch ( e ) {
+		return extractStacktrace( e, offset );
+	}
+}
+
+/**
+ * Escape text for attribute or text content.
+ */
+function escapeText( s ) {
+	if ( !s ) {
+		return "";
+	}
+	s = s + "";
+	// Both single quotes and double quotes (for attributes)
+	return s.replace( /['"<>&]/g, function( s ) {
+		switch( s ) {
+			case "'":
+				return "&#039;";
+			case "\"":
+				return "&quot;";
+			case "<":
+				return "&lt;";
+			case ">":
+				return "&gt;";
+			case "&":
+				return "&amp;";
+		}
+	});
+}
+
+function synchronize( callback, last ) {
+	config.queue.push( callback );
+
+	if ( config.autorun && !config.blocking ) {
+		process( last );
+	}
+}
+
+function process( last ) {
+	function next() {
+		process( last );
+	}
+	var start = new Date().getTime();
+	config.depth = config.depth ? config.depth + 1 : 1;
+
+	while ( config.queue.length && !config.blocking ) {
+		if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
+			config.queue.shift()();
+		} else {
+			setTimeout( next, 13 );
+			break;
+		}
+	}
+	config.depth--;
+	if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+		done();
+	}
+}
+
+function saveGlobal() {
+	config.pollution = [];
+
+	if ( config.noglobals ) {
+		for ( var key in window ) {
+			if ( hasOwn.call( window, key ) ) {
+				// in Opera sometimes DOM element ids show up here, ignore them
+				if ( /^qunit-test-output/.test( key ) ) {
+					continue;
+				}
+				config.pollution.push( key );
+			}
+		}
+	}
+}
+
+function checkPollution() {
+	var newGlobals,
+		deletedGlobals,
+		old = config.pollution;
+
+	saveGlobal();
+
+	newGlobals = diff( config.pollution, old );
+	if ( newGlobals.length > 0 ) {
+		QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
+	}
+
+	deletedGlobals = diff( old, config.pollution );
+	if ( deletedGlobals.length > 0 ) {
+		QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
+	}
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+	var i, j,
+		result = a.slice();
+
+	for ( i = 0; i < result.length; i++ ) {
+		for ( j = 0; j < b.length; j++ ) {
+			if ( result[i] === b[j] ) {
+				result.splice( i, 1 );
+				i--;
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+function extend( a, b ) {
+	for ( var prop in b ) {
+		if ( hasOwn.call( b, prop ) ) {
+			// Avoid "Member not found" error in IE8 caused by messing with window.constructor
+			if ( !( prop === "constructor" && a === window ) ) {
+				if ( b[ prop ] === undefined ) {
+					delete a[ prop ];
+				} else {
+					a[ prop ] = b[ prop ];
+				}
+			}
+		}
+	}
+
+	return a;
+}
+
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+	// Standards-based browsers
+	if ( elem.addEventListener ) {
+		elem.addEventListener( type, fn, false );
+	// IE
+	} else {
+		elem.attachEvent( "on" + type, fn );
+	}
+}
+
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+	var i = elems.length;
+	while ( i-- ) {
+		addEvent( elems[i], type, fn );
+	}
+}
+
+function hasClass( elem, name ) {
+	return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
+}
+
+function addClass( elem, name ) {
+	if ( !hasClass( elem, name ) ) {
+		elem.className += (elem.className ? " " : "") + name;
+	}
+}
+
+function removeClass( elem, name ) {
+	var set = " " + elem.className + " ";
+	// Class name may appear multiple times
+	while ( set.indexOf(" " + name + " ") > -1 ) {
+		set = set.replace(" " + name + " " , " ");
+	}
+	// If possible, trim it for prettiness, but not necessarily
+	elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
+}
+
+function id( name ) {
+	return !!( typeof document !== "undefined" && document && document.getElementById ) &&
+		document.getElementById( name );
+}
+
+function registerLoggingCallback( key ) {
+	return function( callback ) {
+		config[key].push( callback );
+	};
+}
+
+// Supports deprecated method of completely overwriting logging callbacks
+function runLoggingCallbacks( key, scope, args ) {
+	var i, callbacks;
+	if ( QUnit.hasOwnProperty( key ) ) {
+		QUnit[ key ].call(scope, args );
+	} else {
+		callbacks = config[ key ];
+		for ( i = 0; i < callbacks.length; i++ ) {
+			callbacks[ i ].call( scope, args );
+		}
+	}
+}
+
+// Test for equality any JavaScript type.
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = (function() {
+
+	// Call the o related callback with the given arguments.
+	function bindCallbacks( o, callbacks, args ) {
+		var prop = QUnit.objectType( o );
+		if ( prop ) {
+			if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
+				return callbacks[ prop ].apply( callbacks, args );
+			} else {
+				return callbacks[ prop ]; // or undefined
+			}
+		}
+	}
+
+	// the real equiv function
+	var innerEquiv,
+		// stack to decide between skip/abort functions
+		callers = [],
+		// stack to avoiding loops from circular referencing
+		parents = [],
+		parentsB = [],
+
+		getProto = Object.getPrototypeOf || function ( obj ) {
+			/*jshint camelcase:false */
+			return obj.__proto__;
+		},
+		callbacks = (function () {
+
+			// for string, boolean, number and null
+			function useStrictEquality( b, a ) {
+				/*jshint eqeqeq:false */
+				if ( b instanceof a.constructor || a instanceof b.constructor ) {
+					// to catch short annotation VS 'new' annotation of a
+					// declaration
+					// e.g. var i = 1;
+					// var j = new Number(1);
+					return a == b;
+				} else {
+					return a === b;
+				}
+			}
+
+			return {
+				"string": useStrictEquality,
+				"boolean": useStrictEquality,
+				"number": useStrictEquality,
+				"null": useStrictEquality,
+				"undefined": useStrictEquality,
+
+				"nan": function( b ) {
+					return isNaN( b );
+				},
+
+				"date": function( b, a ) {
+					return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
+				},
+
+				"regexp": function( b, a ) {
+					return QUnit.objectType( b ) === "regexp" &&
+						// the regex itself
+						a.source === b.source &&
+						// and its modifiers
+						a.global === b.global &&
+						// (gmi) ...
+						a.ignoreCase === b.ignoreCase &&
+						a.multiline === b.multiline &&
+						a.sticky === b.sticky;
+				},
+
+				// - skip when the property is a method of an instance (OOP)
+				// - abort otherwise,
+				// initial === would have catch identical references anyway
+				"function": function() {
+					var caller = callers[callers.length - 1];
+					return caller !== Object && typeof caller !== "undefined";
+				},
+
+				"array": function( b, a ) {
+					var i, j, len, loop, aCircular, bCircular;
+
+					// b could be an object literal here
+					if ( QUnit.objectType( b ) !== "array" ) {
+						return false;
+					}
+
+					len = a.length;
+					if ( len !== b.length ) {
+						// safe and faster
+						return false;
+					}
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+					for ( i = 0; i < len; i++ ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									parents.pop();
+									parentsB.pop();
+									return false;
+								}
+							}
+						}
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							parents.pop();
+							parentsB.pop();
+							return false;
+						}
+					}
+					parents.pop();
+					parentsB.pop();
+					return true;
+				},
+
+				"object": function( b, a ) {
+					/*jshint forin:false */
+					var i, j, loop, aCircular, bCircular,
+						// Default to true
+						eq = true,
+						aProperties = [],
+						bProperties = [];
+
+					// comparing constructors is more strict than using
+					// instanceof
+					if ( a.constructor !== b.constructor ) {
+						// Allow objects with no prototype to be equivalent to
+						// objects with Object as their constructor.
+						if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
+							( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
+								return false;
+						}
+					}
+
+					// stack constructor before traversing properties
+					callers.push( a.constructor );
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+
+					// be strict: don't ensure hasOwnProperty and go deep
+					for ( i in a ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									eq = false;
+									break;
+								}
+							}
+						}
+						aProperties.push(i);
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							eq = false;
+							break;
+						}
+					}
+
+					parents.pop();
+					parentsB.pop();
+					callers.pop(); // unstack, we are done
+
+					for ( i in b ) {
+						bProperties.push( i ); // collect b's properties
+					}
+
+					// Ensures identical properties name
+					return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
+				}
+			};
+		}());
+
+	innerEquiv = function() { // can take multiple arguments
+		var args = [].slice.apply( arguments );
+		if ( args.length < 2 ) {
+			return true; // end transition
+		}
+
+		return (function( a, b ) {
+			if ( a === b ) {
+				return true; // catch the most you can
+			} else if ( a === null || b === null || typeof a === "undefined" ||
+					typeof b === "undefined" ||
+					QUnit.objectType(a) !== QUnit.objectType(b) ) {
+				return false; // don't lose time with error prone cases
+			} else {
+				return bindCallbacks(a, callbacks, [ b, a ]);
+			}
+
+			// apply transition with (1..n) arguments
+		}( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) );
+	};
+
+	return innerEquiv;
+}());
+
+/**
+ * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
+ * http://flesler.blogspot.com Licensed under BSD
+ * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
+ *
+ * @projectDescription Advanced and extensible data dumping for Javascript.
+ * @version 1.0.0
+ * @author Ariel Flesler
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
+ */
+QUnit.jsDump = (function() {
+	function quote( str ) {
+		return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
+	}
+	function literal( o ) {
+		return o + "";
+	}
+	function join( pre, arr, post ) {
+		var s = jsDump.separator(),
+			base = jsDump.indent(),
+			inner = jsDump.indent(1);
+		if ( arr.join ) {
+			arr = arr.join( "," + s + inner );
+		}
+		if ( !arr ) {
+			return pre + post;
+		}
+		return [ pre, inner + arr, base + post ].join(s);
+	}
+	function array( arr, stack ) {
+		var i = arr.length, ret = new Array(i);
+		this.up();
+		while ( i-- ) {
+			ret[i] = this.parse( arr[i] , undefined , stack);
+		}
+		this.down();
+		return join( "[", ret, "]" );
+	}
+
+	var reName = /^function (\w+)/,
+		jsDump = {
+			// type is used mostly internally, you can fix a (custom)type in advance
+			parse: function( obj, type, stack ) {
+				stack = stack || [ ];
+				var inStack, res,
+					parser = this.parsers[ type || this.typeOf(obj) ];
+
+				type = typeof parser;
+				inStack = inArray( obj, stack );
+
+				if ( inStack !== -1 ) {
+					return "recursion(" + (inStack - stack.length) + ")";
+				}
+				if ( type === "function" )  {
+					stack.push( obj );
+					res = parser.call( this, obj, stack );
+					stack.pop();
+					return res;
+				}
+				return ( type === "string" ) ? parser : this.parsers.error;
+			},
+			typeOf: function( obj ) {
+				var type;
+				if ( obj === null ) {
+					type = "null";
+				} else if ( typeof obj === "undefined" ) {
+					type = "undefined";
+				} else if ( QUnit.is( "regexp", obj) ) {
+					type = "regexp";
+				} else if ( QUnit.is( "date", obj) ) {
+					type = "date";
+				} else if ( QUnit.is( "function", obj) ) {
+					type = "function";
+				} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
+					type = "window";
+				} else if ( obj.nodeType === 9 ) {
+					type = "document";
+				} else if ( obj.nodeType ) {
+					type = "node";
+				} else if (
+					// native arrays
+					toString.call( obj ) === "[object Array]" ||
+					// NodeList objects
+					( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
+				) {
+					type = "array";
+				} else if ( obj.constructor === Error.prototype.constructor ) {
+					type = "error";
+				} else {
+					type = typeof obj;
+				}
+				return type;
+			},
+			separator: function() {
+				return this.multiline ?	this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
+			},
+			// extra can be a number, shortcut for increasing-calling-decreasing
+			indent: function( extra ) {
+				if ( !this.multiline ) {
+					return "";
+				}
+				var chr = this.indentChar;
+				if ( this.HTML ) {
+					chr = chr.replace( /\t/g, "   " ).replace( / /g, "&nbsp;" );
+				}
+				return new Array( this.depth + ( extra || 0 ) ).join(chr);
+			},
+			up: function( a ) {
+				this.depth += a || 1;
+			},
+			down: function( a ) {
+				this.depth -= a || 1;
+			},
+			setParser: function( name, parser ) {
+				this.parsers[name] = parser;
+			},
+			// The next 3 are exposed so you can use them
+			quote: quote,
+			literal: literal,
+			join: join,
+			//
+			depth: 1,
+			// This is the list of parsers, to modify them, use jsDump.setParser
+			parsers: {
+				window: "[Window]",
+				document: "[Document]",
+				error: function(error) {
+					return "Error(\"" + error.message + "\")";
+				},
+				unknown: "[Unknown]",
+				"null": "null",
+				"undefined": "undefined",
+				"function": function( fn ) {
+					var ret = "function",
+						// functions never have name in IE
+						name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
+
+					if ( name ) {
+						ret += " " + name;
+					}
+					ret += "( ";
+
+					ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
+					return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
+				},
+				array: array,
+				nodelist: array,
+				"arguments": array,
+				object: function( map, stack ) {
+					/*jshint forin:false */
+					var ret = [ ], keys, key, val, i;
+					QUnit.jsDump.up();
+					keys = [];
+					for ( key in map ) {
+						keys.push( key );
+					}
+					keys.sort();
+					for ( i = 0; i < keys.length; i++ ) {
+						key = keys[ i ];
+						val = map[ key ];
+						ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
+					}
+					QUnit.jsDump.down();
+					return join( "{", ret, "}" );
+				},
+				node: function( node ) {
+					var len, i, val,
+						open = QUnit.jsDump.HTML ? "&lt;" : "<",
+						close = QUnit.jsDump.HTML ? "&gt;" : ">",
+						tag = node.nodeName.toLowerCase(),
+						ret = open + tag,
+						attrs = node.attributes;
+
+					if ( attrs ) {
+						for ( i = 0, len = attrs.length; i < len; i++ ) {
+							val = attrs[i].nodeValue;
+							// IE6 includes all attributes in .attributes, even ones not explicitly set.
+							// Those have values like undefined, null, 0, false, "" or "inherit".
+							if ( val && val !== "inherit" ) {
+								ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
+							}
+						}
+					}
+					ret += close;
+
+					// Show content of TextNode or CDATASection
+					if ( node.nodeType === 3 || node.nodeType === 4 ) {
+						ret += node.nodeValue;
+					}
+
+					return ret + open + "/" + tag + close;
+				},
+				// function calls it internally, it's the arguments part of the function
+				functionArgs: function( fn ) {
+					var args,
+						l = fn.length;
+
+					if ( !l ) {
+						return "";
+					}
+
+					args = new Array(l);
+					while ( l-- ) {
+						// 97 is 'a'
+						args[l] = String.fromCharCode(97+l);
+					}
+					return " " + args.join( ", " ) + " ";
+				},
+				// object calls it internally, the key part of an item in a map
+				key: quote,
+				// function calls it internally, it's the content of the function
+				functionCode: "[code]",
+				// node calls it internally, it's an html attribute value
+				attribute: quote,
+				string: quote,
+				date: quote,
+				regexp: literal,
+				number: literal,
+				"boolean": literal
+			},
+			// if true, entities are escaped ( <, >, \t, space and \n )
+			HTML: false,
+			// indentation unit
+			indentChar: "  ",
+			// if true, items in a collection, are separated by a \n, else just a space.
+			multiline: true
+		};
+
+	return jsDump;
+}());
+
+// from jquery.js
+function inArray( elem, array ) {
+	if ( array.indexOf ) {
+		return array.indexOf( elem );
+	}
+
+	for ( var i = 0, length = array.length; i < length; i++ ) {
+		if ( array[ i ] === elem ) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/*
+ * Javascript Diff Algorithm
+ *  By John Resig (http://ejohn.org/)
+ *  Modified by Chu Alan "sprite"
+ *
+ * Released under the MIT license.
+ *
+ * More Info:
+ *  http://ejohn.org/projects/javascript-diff-algorithm/
+ *
+ * Usage: QUnit.diff(expected, actual)
+ *
+ * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
+ */
+QUnit.diff = (function() {
+	/*jshint eqeqeq:false, eqnull:true */
+	function diff( o, n ) {
+		var i,
+			ns = {},
+			os = {};
+
+		for ( i = 0; i < n.length; i++ ) {
+			if ( !hasOwn.call( ns, n[i] ) ) {
+				ns[ n[i] ] = {
+					rows: [],
+					o: null
+				};
+			}
+			ns[ n[i] ].rows.push( i );
+		}
+
+		for ( i = 0; i < o.length; i++ ) {
+			if ( !hasOwn.call( os, o[i] ) ) {
+				os[ o[i] ] = {
+					rows: [],
+					n: null
+				};
+			}
+			os[ o[i] ].rows.push( i );
+		}
+
+		for ( i in ns ) {
+			if ( hasOwn.call( ns, i ) ) {
+				if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
+					n[ ns[i].rows[0] ] = {
+						text: n[ ns[i].rows[0] ],
+						row: os[i].rows[0]
+					};
+					o[ os[i].rows[0] ] = {
+						text: o[ os[i].rows[0] ],
+						row: ns[i].rows[0]
+					};
+				}
+			}
+		}
+
+		for ( i = 0; i < n.length - 1; i++ ) {
+			if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
+						n[ i + 1 ] == o[ n[i].row + 1 ] ) {
+
+				n[ i + 1 ] = {
+					text: n[ i + 1 ],
+					row: n[i].row + 1
+				};
+				o[ n[i].row + 1 ] = {
+					text: o[ n[i].row + 1 ],
+					row: i + 1
+				};
+			}
+		}
+
+		for ( i = n.length - 1; i > 0; i-- ) {
+			if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
+						n[ i - 1 ] == o[ n[i].row - 1 ]) {
+
+				n[ i - 1 ] = {
+					text: n[ i - 1 ],
+					row: n[i].row - 1
+				};
+				o[ n[i].row - 1 ] = {
+					text: o[ n[i].row - 1 ],
+					row: i - 1
+				};
+			}
+		}
+
+		return {
+			o: o,
+			n: n
+		};
+	}
+
+	return function( o, n ) {
+		o = o.replace( /\s+$/, "" );
+		n = n.replace( /\s+$/, "" );
+
+		var i, pre,
+			str = "",
+			out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
+			oSpace = o.match(/\s+/g),
+			nSpace = n.match(/\s+/g);
+
+		if ( oSpace == null ) {
+			oSpace = [ " " ];
+		}
+		else {
+			oSpace.push( " " );
+		}
+
+		if ( nSpace == null ) {
+			nSpace = [ " " ];
+		}
+		else {
+			nSpace.push( " " );
+		}
+
+		if ( out.n.length === 0 ) {
+			for ( i = 0; i < out.o.length; i++ ) {
+				str += "<del>" + out.o[i] + oSpace[i] + "</del>";
+			}
+		}
+		else {
+			if ( out.n[0].text == null ) {
+				for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
+					str += "<del>" + out.o[n] + oSpace[n] + "</del>";
+				}
+			}
+
+			for ( i = 0; i < out.n.length; i++ ) {
+				if (out.n[i].text == null) {
+					str += "<ins>" + out.n[i] + nSpace[i] + "</ins>";
+				}
+				else {
+					// `pre` initialized at top of scope
+					pre = "";
+
+					for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
+						pre += "<del>" + out.o[n] + oSpace[n] + "</del>";
+					}
+					str += " " + out.n[i].text + nSpace[i] + pre;
+				}
+			}
+		}
+
+		return str;
+	};
+}());
+
+// for CommonJS environments, export everything
+if ( typeof exports !== "undefined" ) {
+	extend( exports, QUnit.constructor.prototype );
+}
+
+// get at whatever the global object is, like window in browsers
+}( (function() {return this;}.call()) ));
diff --git a/docs/slides/BOS14/_support/reveal.js/test/test-markdown-element-attributes.html b/docs/slides/BOS14/_support/reveal.js/test/test-markdown-element-attributes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/test-markdown-element-attributes.html
@@ -0,0 +1,134 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test Markdown Element Attributes</title>
+
+		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+
+				<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
+				<section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$" data-element-attributes="{_\s*?([^}]+?)}">>
+					<script type="text/template">
+						## Slide 1.1
+						<!-- {_class="fragment fade-out" data-fragment-index="1"} -->
+
+						--
+
+						## Slide 1.2
+						<!-- {_class="fragment shrink"} -->
+
+						Paragraph 1
+						<!-- {_class="fragment grow"} -->
+
+						Paragraph 2
+						<!-- {_class="fragment grow"} -->
+
+						- list item 1 <!-- {_class="fragment roll-in"} -->
+						- list item 2 <!-- {_class="fragment roll-in"} -->
+						- list item 3 <!-- {_class="fragment roll-in"} -->
+
+
+						---
+
+						## Slide 2
+
+
+						Paragraph 1.2  
+						multi-line <!-- {_class="fragment highlight-red"} -->
+
+						Paragraph 2.2 <!-- {_class="fragment highlight-red"} -->
+
+						Paragraph 2.3 <!-- {_class="fragment highlight-red"} -->
+
+						Paragraph 2.4 <!-- {_class="fragment highlight-red"} -->
+
+						- list item 1 <!-- {_class="fragment highlight-green"} -->
+						- list item 2<!-- {_class="fragment highlight-green"} -->
+						- list item 3<!-- {_class="fragment highlight-green"} -->
+						- list item 4
+						<!-- {_class="fragment highlight-green"} -->
+						- list item 5<!-- {_class="fragment highlight-green"} -->
+
+						Test
+
+						![Example Picture](examples/assets/image2.png)
+						<!-- {_class="reveal stretch"} -->
+
+					</script>
+				</section>
+
+
+
+				<section 	data-markdown data-separator="^\n\n\n"
+									data-vertical="^\n\n"
+									data-notes="^Note:"
+									data-charset="utf-8">
+					<script type="text/template">
+						# Test attributes in Markdown with default separator
+						## Slide 1 Def <!-- .element: class="fragment highlight-red" data-fragment-index="1" -->
+
+
+						## Slide 2 Def
+						<!-- .element: class="fragment highlight-red" -->
+
+					</script>
+				</section>
+
+				<section data-markdown>
+				  <script type="text/template">
+					## Hello world
+					A paragraph
+					<!-- .element: class="fragment highlight-blue" -->
+				  </script>
+				</section>
+
+				<section data-markdown>
+				  <script type="text/template">
+					## Hello world
+
+					Multiple  
+					Line
+					<!-- .element: class="fragment highlight-blue" -->
+				  </script>
+				</section>
+
+				<section data-markdown>
+				  <script type="text/template">
+					## Hello world
+
+					Test<!-- .element: class="fragment highlight-blue" -->
+
+					More Test
+				  </script>
+				</section>
+
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.min.js"></script>
+		<script src="../plugin/markdown/marked.js"></script>
+		<script src="../plugin/markdown/markdown.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test-markdown-element-attributes.js"></script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/test/test-markdown-element-attributes.js b/docs/slides/BOS14/_support/reveal.js/test/test-markdown-element-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/test-markdown-element-attributes.js
@@ -0,0 +1,46 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
+	});
+
+
+	test( 'Attributes on element header in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
+	});
+
+	test( 'Attributes on element paragraphs in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
+	});
+
+	test( 'Attributes on element list items in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.roll-in' ).length, 3, 'found a vertical slide with three list items with class fragment.roll-in' );
+	});
+
+	test( 'Attributes on element paragraphs in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
+	});
+
+	test( 'Attributes on elements in vertical slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
+	});
+
+	test( 'Attributes on elements in single slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/BOS14/_support/reveal.js/test/test-markdown-slide-attributes.html b/docs/slides/BOS14/_support/reveal.js/test/test-markdown-slide-attributes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/test-markdown-slide-attributes.html
@@ -0,0 +1,128 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test Markdown Attributes</title>
+
+		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+
+				<!-- Slides are separated by three lines, vertical slides by two lines, attributes are one any line starting with (spaces and) two dashes -->
+				<section 	data-markdown data-separator="^\n\n\n"
+									data-vertical="^\n\n"
+									data-notes="^Note:"
+									data-attributes="--\s(.*?)$"
+									data-charset="utf-8">
+					<script type="text/template">
+						# Test attributes in Markdown
+						## Slide 1
+
+
+
+						## Slide 2
+						<!-- -- id="slide2" data-transition="zoom" data-background="#A0C66B" -->
+
+
+						## Slide 2.1
+						<!-- -- data-background="#ff0000" data-transition="fade" -->
+
+
+						## Slide 2.2
+						[Link to Slide2](#/slide2)
+
+
+
+						## Slide 3
+						<!-- -- data-transition="zoom" data-background="#C6916B" -->
+
+
+
+						## Slide 4
+					</script>
+				</section>
+
+				<section 	data-markdown data-separator="^\n\n\n"
+									data-vertical="^\n\n"
+									data-notes="^Note:"
+									data-charset="utf-8">
+					<script type="text/template">
+						# Test attributes in Markdown with default separator
+						## Slide 1 Def
+
+
+
+						## Slide 2 Def
+						<!-- .slide: id="slide2def" data-transition="concave" data-background="#A7C66B" -->
+
+
+						## Slide 2.1 Def
+						<!-- .slide: data-background="#f70000" data-transition="page" -->
+
+
+						## Slide 2.2 Def
+						[Link to Slide2](#/slide2def)
+
+
+
+						## Slide 3 Def
+						<!-- .slide: data-transition="concave" data-background="#C7916B" -->
+
+
+
+						## Slide 4
+					</script>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						<!-- .slide: data-background="#ff0000" -->
+						## Hello world
+					</script>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						## Hello world
+						<!-- .slide: data-background="#ff0000" -->
+					</script>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						## Hello world
+
+						Test
+						<!-- .slide: data-background="#ff0000" -->
+
+						More Test
+					</script>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.min.js"></script>
+		<script src="../plugin/markdown/marked.js"></script>
+		<script src="../plugin/markdown/markdown.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test-markdown-slide-attributes.js"></script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/test/test-markdown-slide-attributes.js b/docs/slides/BOS14/_support/reveal.js/test/test-markdown-slide-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/test-markdown-slide-attributes.js
@@ -0,0 +1,47 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' );
+	});
+
+	test( 'Id on slide', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' );
+	});
+
+	test( 'data-background attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-background attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-transition attributes with inline content', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/BOS14/_support/reveal.js/test/test-markdown.html b/docs/slides/BOS14/_support/reveal.js/test/test-markdown.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/test-markdown.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test Markdown</title>
+
+		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+  		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+
+				<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
+				<section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$">
+					<script type="text/template">
+						## Slide 1.1
+
+						--
+
+						## Slide 1.2
+
+						---
+
+						## Slide 2
+					</script>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.min.js"></script>
+		<script src="../plugin/markdown/marked.js"></script>
+		<script src="../plugin/markdown/markdown.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test-markdown.js"></script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/test/test-markdown.js b/docs/slides/BOS14/_support/reveal.js/test/test-markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/test-markdown.js
@@ -0,0 +1,15 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/BOS14/_support/reveal.js/test/test.html b/docs/slides/BOS14/_support/reveal.js/test/test.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/test.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Tests</title>
+
+		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+  		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<section>
+					<h1>1</h1>
+				</section>
+
+				<section>
+					<section>
+						<h1>2.1</h1>
+					</section>
+					<section>
+						<h1>2.2</h1>
+					</section>
+					<section>
+						<h1>2.3</h1>
+					</section>
+				</section>
+
+				<section id="fragment-slides">
+					<section>
+						<h1>3.1</h1>
+						<ul>
+							<li class="fragment">4.1</li>
+							<li class="fragment">4.2</li>
+							<li class="fragment">4.3</li>
+						</ul>
+					</section>
+
+					<section>
+						<h1>3.2</h1>
+						<ul>
+							<li class="fragment" data-fragment-index="0">4.1</li>
+							<li class="fragment" data-fragment-index="0">4.2</li>
+						</ul>
+					</section>
+
+					<section>
+						<h1>3.3</h1>
+						<ul>
+							<li class="fragment" data-fragment-index="1">3.3.1</li>
+							<li class="fragment" data-fragment-index="4">3.3.2</li>
+							<li class="fragment" data-fragment-index="4">3.3.3</li>
+						</ul>
+					</section>
+				</section>
+
+				<section>
+					<h1>4</h1>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.min.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test.js"></script>
+
+	</body>
+</html>
diff --git a/docs/slides/BOS14/_support/reveal.js/test/test.js b/docs/slides/BOS14/_support/reveal.js/test/test.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/reveal.js/test/test.js
@@ -0,0 +1,438 @@
+
+// These tests expect the DOM to contain a presentation
+// with the following slide structure:
+//
+// 1
+// 2 - Three sub-slides
+// 3 - Three fragment elements
+// 3 - Two fragments with same data-fragment-index
+// 4
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	// ---------------------------------------------------------------
+	// DOM TESTS
+
+	QUnit.module( 'DOM' );
+
+	test( 'Initial slides classes', function() {
+		var horizontalSlides = document.querySelectorAll( '.reveal .slides>section' )
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.past' ).length, 0, 'no .past slides' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section.present' ).length, 1, 'one .present slide' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section.future' ).length, horizontalSlides.length - 1, 'remaining horizontal slides are .future' );
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.stack' ).length, 2, 'two .stacks' );
+
+		ok( document.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length > 0, 'vertical slides are given .future' );
+	});
+
+	// ---------------------------------------------------------------
+	// API TESTS
+
+	QUnit.module( 'API' );
+
+	test( 'Reveal.isReady', function() {
+		strictEqual( Reveal.isReady(), true, 'returns true' );
+	});
+
+	test( 'Reveal.isOverview', function() {
+		strictEqual( Reveal.isOverview(), false, 'false by default' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), true, 'true after toggling on' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), false, 'false after toggling off' );
+	});
+
+	test( 'Reveal.isPaused', function() {
+		strictEqual( Reveal.isPaused(), false, 'false by default' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), true, 'true after pausing' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), false, 'false after resuming' );
+	});
+
+	test( 'Reveal.isFirstSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+
+		Reveal.slide( 1, 0 );
+		strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.isLastSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+
+		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
+
+		Reveal.slide( lastSlideIndex, 0 );
+		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( ', 0+ lastSlideIndex +' )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.getIndices', function() {
+		var indices = Reveal.getIndices();
+
+		ok( typeof indices.hasOwnProperty( 'h' ), 'h exists' );
+		ok( typeof indices.hasOwnProperty( 'v' ), 'v exists' );
+		ok( typeof indices.hasOwnProperty( 'f' ), 'f exists' );
+
+		Reveal.slide( 1, 0 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 0, 'h 1, v 0' );
+
+		Reveal.slide( 1, 2 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 2, 'h 1, v 2' );
+
+		Reveal.slide( 0, 0 );
+	});
+
+	test( 'Reveal.getSlide', function() {
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+
+		equal( Reveal.getSlide( 0 ), firstSlide, 'gets correct first slide' );
+
+		strictEqual( Reveal.getSlide( 100 ), undefined, 'returns undefined when slide can\'t be found' );
+	});
+
+	test( 'Reveal.getPreviousSlide/getCurrentSlide', function() {
+		Reveal.slide( 0, 0 );
+		Reveal.slide( 1, 0 );
+
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+		var secondSlide = document.querySelector( '.reveal .slides>section:nth-child(2)>section' );
+
+		equal( Reveal.getPreviousSlide(), firstSlide, 'previous is slide #0' );
+		equal( Reveal.getCurrentSlide(), secondSlide, 'current is slide #1' );
+	});
+
+	test( 'Reveal.getScale', function() {
+		ok( typeof Reveal.getScale() === 'number', 'has scale' );
+	});
+
+	test( 'Reveal.getConfig', function() {
+		ok( typeof Reveal.getConfig() === 'object', 'has config' );
+	});
+
+	test( 'Reveal.configure', function() {
+		strictEqual( Reveal.getConfig().loop, false, '"loop" is false to start with' );
+
+		Reveal.configure({ loop: true });
+		strictEqual( Reveal.getConfig().loop, true, '"loop" has changed to true' );
+
+		Reveal.configure({ loop: false, customTestValue: 1 });
+		strictEqual( Reveal.getConfig().customTestValue, 1, 'supports custom values' );
+	});
+
+	test( 'Reveal.availableRoutes', function() {
+		Reveal.slide( 0, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: false, up: false, down: false, right: true }, 'correct for first slide' );
+
+		Reveal.slide( 1, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: true, up: false, down: true, right: true }, 'correct for vertical slide' );
+	});
+
+	test( 'Reveal.next', function() {
+		Reveal.slide( 0, 0 );
+
+		// Step through vertical child slides
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 1, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } );
+
+		// Step through fragments
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } );
+	});
+
+	test( 'Reveal.next at end', function() {
+		Reveal.slide( 3 );
+
+		// We're at the end, this should have no effect
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+	});
+
+
+	// ---------------------------------------------------------------
+	// FRAGMENT TESTS
+
+	QUnit.module( 'Fragments' );
+
+	test( 'Sliding to fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'Reveal.slide( 2, 0, -1 )' );
+
+		Reveal.slide( 2, 0, 0 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'Reveal.slide( 2, 0, 0 )' );
+
+		Reveal.slide( 2, 0, 2 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'Reveal.slide( 2, 0, 2 )' );
+
+		Reveal.slide( 2, 0, 1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'Reveal.slide( 2, 0, 1 )' );
+	});
+
+	test( 'Hiding all fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' );
+
+		Reveal.slide( 2, 0, -1 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index is -1' );
+	});
+
+	test( 'Current fragment', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 1, 'one current fragment at index 0' );
+
+		Reveal.slide( 1, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
+	});
+
+	test( 'Stepping through fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+
+		// forwards:
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'next() goes to next fragment' );
+
+		Reveal.right();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'right() goes to next fragment' );
+
+		Reveal.down();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'down() goes to next fragment' );
+
+		Reveal.down(); // moves to f #3
+
+		// backwards:
+
+		Reveal.prev();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'prev() goes to prev fragment' );
+
+		Reveal.left();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'left() goes to prev fragment' );
+
+		Reveal.up();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'up() goes to prev fragment' );
+	});
+
+	test( 'Stepping past fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 0, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 3, 'all fragments visible when on future slide' );
+	});
+
+	test( 'Fragment indices', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(2)' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 2, 'both fragments of same index are shown' );
+	});
+
+	test( 'Index generation', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		// These have no indices defined to start with
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' );
+	});
+
+	test( 'Index normalization', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(3)' );
+
+		// These start out as 1-4-4 and should normalize to 0-1-1
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' );
+	});
+
+	asyncTest( 'fragmentshown event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmentshown', _onEvent );
+
+		Reveal.slide( 2, 0 );
+		Reveal.slide( 2, 0 ); // should do nothing
+		Reveal.slide( 2, 0, 0 ); // should do nothing
+		Reveal.next();
+		Reveal.next();
+		Reveal.prev(); // shouldn't fire fragmentshown
+
+		start();
+
+		Reveal.removeEventListener( 'fragmentshown', _onEvent );
+	});
+
+	asyncTest( 'fragmenthidden event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmenthidden', _onEvent );
+
+		Reveal.slide( 2, 0, 2 );
+		Reveal.slide( 2, 0, 2 ); // should do nothing
+		Reveal.prev();
+		Reveal.prev();
+		Reveal.next(); // shouldn't fire fragmenthidden
+
+		start();
+
+		Reveal.removeEventListener( 'fragmenthidden', _onEvent );
+	});
+
+
+	// ---------------------------------------------------------------
+	// CONFIGURATION VALUES
+
+	QUnit.module( 'Configuration' );
+
+	test( 'Controls', function() {
+		var controlsElement = document.querySelector( '.reveal>.controls' );
+
+		Reveal.configure({ controls: false });
+		equal( controlsElement.style.display, 'none', 'controls are hidden' );
+
+		Reveal.configure({ controls: true });
+		equal( controlsElement.style.display, 'block', 'controls are visible' );
+	});
+
+	test( 'Progress', function() {
+		var progressElement = document.querySelector( '.reveal>.progress' );
+
+		Reveal.configure({ progress: false });
+		equal( progressElement.style.display, 'none', 'progress are hidden' );
+
+		Reveal.configure({ progress: true });
+		equal( progressElement.style.display, 'block', 'progress are visible' );
+	});
+
+	test( 'Loop', function() {
+		Reveal.configure({ loop: true });
+
+		Reveal.slide( 0, 0 );
+
+		Reveal.left();
+		notEqual( Reveal.getIndices().h, 0, 'looped from start to end' );
+
+		Reveal.right();
+		equal( Reveal.getIndices().h, 0, 'looped from end to start' );
+
+		Reveal.configure({ loop: false });
+	});
+
+
+	// ---------------------------------------------------------------
+	// EVENT TESTS
+
+	QUnit.module( 'Events' );
+
+	asyncTest( 'slidechanged', function() {
+		expect( 3 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'slidechanged', _onEvent );
+
+		Reveal.slide( 1, 0 ); // should trigger
+		Reveal.slide( 1, 0 ); // should do nothing
+		Reveal.next(); // should trigger
+		Reveal.slide( 3, 0 ); // should trigger
+		Reveal.next(); // should do nothing
+
+		start();
+
+		Reveal.removeEventListener( 'slidechanged', _onEvent );
+
+	});
+
+	asyncTest( 'paused', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'paused', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'paused', _onEvent );
+	});
+
+	asyncTest( 'resumed', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'resumed', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'resumed', _onEvent );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/BOS14/_support/template.reveal b/docs/slides/BOS14/_support/template.reveal
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/_support/template.reveal
@@ -0,0 +1,128 @@
+<!doctype html>  
+<html lang="en">
+	
+<head>
+<meta charset="utf-8">
+
+<title>Liquid Types</title>
+
+<meta name="description" content="Liquid Types IHP 2014">
+<meta name="author" content="Ranjit Jhala">
+
+<meta name="apple-mobile-web-app-capable" content="yes" />
+
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+
+<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
+
+<link rel="stylesheet" href="$reveal$/css/reveal.css">
+<link rel="stylesheet" href="$reveal$/css/theme/seminar.css" id="theme">
+<!-- <link rel="stylesheet" href="$reveal$/css/print/pdf.css"> -->
+<link rel="stylesheet" href="../_support/liquidhaskell.css">
+
+<!-- For syntax highlighting -->
+<link rel="stylesheet" href="$reveal$/lib/css/zenburn.css">
+
+<script>
+	// If the query includes 'print-pdf' we'll use the PDF print sheet
+	document.write( '<link rel="stylesheet" href="$reveal$/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
+</script>
+
+<!--[if lt IE 9]>
+<script src="lib/js/html5shiv.js"></script>
+<![endif]-->
+</head>
+<body>
+
+\(
+\require{color}
+\definecolor{kvcol}{RGB}{203,23,206}
+\definecolor{tycol}{RGB}{5,177,93}
+\definecolor{refcol}{RGB}{18,110,213}
+
+\newcommand{\quals}{\mathbb{Q}}
+\newcommand{\defeq}{\ \doteq\ }
+\newcommand{\subty}{\preceq}
+\newcommand{\True}{\mathit{True}}
+\newcommand{\Int}{\mathtt{Int}}
+\newcommand{\Nat}{\mathtt{Nat}}
+\newcommand{\Zero}{\mathtt{Zero}}
+\newcommand{\foo}[4]{{#1}^{#4} + {#2}^{#4} = {#3}^{#4}}
+\newcommand{\reft}[3]{\{\bindx{#1}{#2} \mid {#3}\}}
+\newcommand{\ereft}[3]{\bindx{#1}{\{#2 \mid #3\}}}
+\newcommand{\bindx}[2]{{#1}\!:\!{#2}}
+\newcommand{\reftx}[2]{\{{#1}\mid{#2}\}}
+\newcommand{\inferrule}[3][]{\frac{#2}{#3}\;{#1}}
+\newcommand{\kvar}[1]{\color{kvcol}{\mathbf{\kappa_{#1}}}}
+\newcommand{\llen}[1]{\mathtt{llen}(#1)}
+\)
+
+<div class="reveal">
+<!-- 
+Used to fade in a background when a specific slide state is reached
+-->
+<div class="state-background"></div>
+
+<!-- Slides
+Any section element inside of this "slides" container is displayed as a slide
+-->
+<div class="slides">
+<!-- Pandoc -->
+$if(title)$
+<section class="titlepage">
+<h1 class="title">$title$</h1>
+$for(author)$
+<h2 class="author">$author$</h2>
+$endfor$
+<h3 class="date">$date$</h3>
+</section>
+$endif$
+$body$
+<!-- End Pandoc -->
+
+</div>
+<!-- End Slides -->
+
+<!-- Presentation progress bar -->
+<div class="progress"><span></span></div>
+</div>
+
+<!-- Initialize reveal.js :: make settings changes here -->
+<script src="$reveal$/lib/js/head.min.js"></script>
+<script src="$reveal$/js/reveal.js"></script>
+
+<!-- ORIGINAL <script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+     -->
+
+<!-- LOCAL 
+<script type="text/javascript" src="file:///Users/rjhala/research/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+-->
+
+<script type="text/javascript" src="$mathjax$/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+
+<script>		
+	// Full list of configuration options available here:
+	// https://github.com/hakimel/reveal.js#configuration
+	Reveal.initialize({
+		controls: true,
+		progress: true,
+		history: true,
+		center: false,
+        rollingLinks: false,
+        theme: Reveal.getQueryHash().theme || 'seminar', // available themes are in /css/theme
+		transition: Reveal.getQueryHash().transition || 'fade', // default/cube/page/concave/linear(2d)
+
+		// Optional libraries used to extend on reveal.js
+		dependencies: [
+			//{ src: '$reveal$/lib/js/highlight.js', async: true, callback: function() { window.hljs.initHighlightingOnLoad(); } },
+			{ src: '$reveal$/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+			{ src: '$reveal$/lib/js/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/lib/js/data-markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/socket.io/socket.io.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+			{ src: '$reveal$/plugin/speakernotes/client.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+		]
+	});
+</script>
+
+</body>
+</html>
diff --git a/docs/slides/BOS14/hs/end/000_Refinements.hs b/docs/slides/BOS14/hs/end/000_Refinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/end/000_Refinements.hs
@@ -0,0 +1,57 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module Refinements where
+
+import Prelude hiding (map, foldr, foldr1)
+
+divide    :: Int -> Int -> Int
+
+
+-----------------------------------------------------------------------
+-- | 1. Simple Refinement Types
+-----------------------------------------------------------------------
+
+{-@ type Nat     = {v:Int | v >= 0} @-}
+{-@ type Pos     = {v:Int | v >  0} @-}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+
+
+{-@ six :: NonZero @-}
+six = 10 :: Int
+
+-----------------------------------------------------------------------
+-- | 2. Function Contracts: Preconditions & Dead Code 
+-----------------------------------------------------------------------
+
+{-@ dead :: {v:_ | false} -> a @-}
+dead msg = error msg
+
+-----------------------------------------------------------------------
+-- | 3. Function Contracts: Safe Division 
+-----------------------------------------------------------------------
+
+abs :: Int -> Int
+abs x | x > 0     = x
+      | otherwise = 0 - x
+
+{-@ divide :: Int -> NonZero -> Int @-}
+divide x 0 = dead "divide-by-zero"
+divide x n = x `div` n
+
+
+
+
+avg2 x y   = divide (x + y)     2
+avg3 x y z = divide (x + y + z) 3
+
+
+-----------------------------------------------------------------------
+-- | But whats the problem here?
+-----------------------------------------------------------------------
+
+avg xs     = divide total n
+  where
+    total  = sum xs
+    n      = length xs
diff --git a/docs/slides/BOS14/hs/end/001_Refinements.hs b/docs/slides/BOS14/hs/end/001_Refinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/end/001_Refinements.hs
@@ -0,0 +1,101 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module Refinements where
+
+import Prelude hiding (map, foldr, foldr1)
+
+divide    :: Int -> Int -> Int
+wtAverage :: List (Int, Int) -> Int
+
+-----------------------------------------------------------------------
+-- | Our first Data Type
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+-----------------------------------------------------------------------
+-- | A few Higher-Order Functions
+-----------------------------------------------------------------------
+
+{-@ map :: _ -> xs:_ -> {v:_ | size v = size xs} @-}
+map f (N)      = N
+map f (C x xs) = C (f x) (map f xs) 
+
+
+foldr                :: (a -> b -> b) -> b -> List a -> b 
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+
+
+-- Uh oh. How shall we fix the error? Lets move on for now...
+
+{-@ foldr1           :: (a -> a -> a) -> {v:List a | size v > 0} -> a @-}   
+foldr1 f (C x xs)    = foldr f x xs
+foldr1 f N           = dead "foldr1"
+
+
+-----------------------------------------------------------------------
+-- | 6. Weighted-Averages 
+-----------------------------------------------------------------------
+
+-- Yikes, a divide-by-zero. How shall we fix it?
+{-@ wtAverage :: {v : List (Pos, Pos) | size v > 0} -> Int @-}
+wtAverage wxs = total `divide` weights
+  where
+    total     = sum $ map (\(w, x) -> w * x) wxs
+    weights   = sum $ map (\(w, _) -> w    ) wxs
+    sum       = foldr1 (+)
+
+
+-- | Exercise: How would you modify the types to get output `Pos` above? 
+
+
+
+
+
+ 
+-----------------------------------------------------------------------
+-- | Measuring the Size of Data
+-----------------------------------------------------------------------
+
+{-@ measure size @-}
+size          :: List a -> Int
+size (C x xs) = 1 + size xs 
+size N        = 0
+
+
+{-@ append :: xs:_ -> ys:_ -> {v: _ | size v = size ys + size xs} @-}
+append N        ys = ys
+append (C x xs) ys = C x (append xs ys)
+
+
+-----------------------------------------------------------------------
+-- | But there are limitations: why does this not work? ...
+-----------------------------------------------------------------------
+
+{-@ append' :: xs:_ -> ys:_ -> {v: _ | size v = size xs + size ys} @-}
+append' xs ys =  foldr C ys xs
+
+
+
+
+-----------------------------------------------------------------------
+-- | Definitions from 000_Refinements.hs
+-----------------------------------------------------------------------
+
+{-@ type Nat     = {v:Int | v >= 0} @-}
+{-@ type Pos     = {v:Int | v >  0} @-}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+
+{-@ dead :: {v:_ | false} -> a @-}
+dead msg = error msg
+
+{-@ divide :: Int -> NonZero -> Int @-}
+divide x 0 = dead "divide-by-zero"
+divide x n = x `div` n
+
+
diff --git a/docs/slides/BOS14/hs/end/01_Elements.hs b/docs/slides/BOS14/hs/end/01_Elements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/end/01_Elements.hs
@@ -0,0 +1,104 @@
+module Elems where
+
+import Prelude hiding (elem)
+
+import Data.Set (Set (..))
+
+
+-----------------------------------------------------------------------------
+-- | 1. Reasoning about the Set of Elements in a List ----------------------- 
+-----------------------------------------------------------------------------
+
+-- | The set of `elems` of a list
+
+
+
+
+
+{-@ measure elems :: [a] -> (Set a)
+    elems ([])    = (Set_empty 0)
+    elems (x:xs)  = (Set_cup (Set_sng x) (elems xs))
+  @-}
+
+
+
+
+-- | A few handy aliases
+
+{-@ predicate EqElts Xs Ys    = elems Xs = elems Ys                      @-}
+{-@ predicate UnElts Xs Ys Zs = elems Xs = Set_cup (elems Ys) (elems Zs) @-}
+
+-- | Reasoning about `append` and `reverse`
+
+{-@ append  :: xs:_ -> ys:_ -> {v:_ | UnElts v xs ys} @-}  
+append [] ys     = ys
+append (x:xs) ys = x : append xs ys 
+
+
+{-@ reverse :: xs:_ -> {v:_ | EqElts v xs} @-}
+reverse xs           = revAcc xs []
+  where 
+   revAcc []     acc = acc
+   revAcc (x:xs) acc = revAcc xs (x:acc)
+
+
+
+-- But, there are limitations...
+   
+{-@ append'  :: xs:_ -> ys:_ -> {v:_ | UnElts v xs ys} @-}  
+append' xs ys = foldr (:) ys xs
+
+
+-----------------------------------------------------------------------------
+-- | 2. Checking for duplicates (xmonad) ------------------------------------ 
+-----------------------------------------------------------------------------
+
+-- | Is a list free of duplicates?
+   
+{-@ measure nodups :: [a] -> Prop
+    nodups ([])   = true
+    nodups (x:xs) = (not (Set_mem x (elems xs)) && nodups xs)
+  @-}
+
+-- | Weeding out duplicates.
+   
+{-@ nub :: xs:_ -> {v:_ | nodups v && EqElts v xs} @-}
+nub xs             = go xs []
+  where
+    go (x:xs) l
+      | x `elem` l = go xs l     
+      | otherwise  = go xs (x:l) 
+    go [] l        = l
+
+
+{-@ elem :: x:_ -> ys:_ -> {v:Bool | Prop v <=> Set_mem x (elems ys)} @-}
+elem x []     = False
+elem x (y:ys) = x == y || elem x ys
+
+-----------------------------------------------------------------------------
+-- | 3. Associative Lookups ------------------------------------------------- 
+-----------------------------------------------------------------------------
+
+-- The dread "key-not-found". How can we fix it?
+{-@ find :: k:_ -> {m:_ | ValidKey k m} -> _ @-}
+find key ((k,v) : kvs)
+  | key == k  = v
+  | otherwise = find key kvs
+find _ []     = die "Key not found! Lookup failed!"
+
+
+{-@ die :: {v:String | false} -> b @-}
+die x = error x
+
+
+----------------------------------------------------------------------------
+----------------------------------------------------------------------------
+----------------------------------------------------------------------------
+
+{-@ predicate ValidKey K M    = Set_mem K (keys M)                       @-}
+
+{-@ measure keys  :: [(a, b)] -> (Set a)
+    keys ([])     = (Set_empty 0)
+    keys (kv:kvs) = (Set_cup (Set_sng (fst kv)) (keys kvs))
+  @-}
+ 
diff --git a/docs/slides/BOS14/hs/end/02_AbstractRefinements.hs b/docs/slides/BOS14/hs/end/02_AbstractRefinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/end/02_AbstractRefinements.hs
@@ -0,0 +1,252 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module AbstractRefinements (
+    listMax
+  , insertSort
+  , insertSort'
+  , insertSort''
+  ) where
+
+import Data.Set hiding (insert, foldr,size,filter, append) 
+import Prelude hiding (map, foldr, filter, append)
+
+listMax     :: [Int] -> Int
+
+
+
+-----------------------------------------------------------------------
+-- | #1. Abstract Refinements 
+-----------------------------------------------------------------------
+
+{-@ listMax :: forall <p :: Int -> Prop>. {v:[Int<p>] | len v > 0} -> Int<p> @-} 
+listMax xs  = foldr1 max xs 
+
+
+-- Lets define a few different subsets of Int
+
+{-@ type Even = {v:Int | v mod 2 == 0}      @-}
+{-@ type Odd  = {v:Int | v mod 2 /= 0}      @-}
+{-@ type RGB  = {v:Int | 0 <= v && v < 256} @-}
+
+
+{-@ xE :: Even @-}
+xE = listMax [0, 200, 4000, 60] 
+
+
+{-@ xO :: Odd @-}
+xO = listMax [1, 21, 4001, 961] 
+
+
+{-@ xR :: RGB @-}
+xR = listMax [1, 21, 41, 61] 
+
+
+
+
+
+
+
+-- > RJ: Return to slides for 06_Inductive
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | #2. Induction, as an Abstract Refinement 
+-----------------------------------------------------------------------
+
+
+{-@ ifoldr :: forall a b <p :: List a -> b -> Prop>. 
+                 (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
+               -> b<p N> 
+               -> ys:List a
+               -> b<p ys>                            @-}
+ifoldr :: (List a -> a -> b -> b) -> b -> List a -> b
+ifoldr f b N        = b
+ifoldr f b (C x xs) = f xs x (ifoldr f b xs)
+
+
+
+
+
+
+
+
+{-@ append :: xs:List a -> ys:List a -> {v:List a | UnElems v xs ys} @-} 
+append xs ys = ifoldr (\_ -> C) ys xs 
+
+
+
+
+
+
+
+{-@ filter :: (a -> Bool) -> xs:List a -> {v:List a | SubElems v xs } @-} 
+filter f xs = ifoldr (id (\_ x ys -> if f x then C x ys else ys)) N xs
+
+
+
+
+
+
+-- > RJ: Return to slides for 08_Recursive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | #3. Abstract Refinement from List's Type 
+-----------------------------------------------------------------------
+
+
+{-@ data List a <p :: a -> a -> Prop> 
+     = N | C {hd :: a, tl :: List<p> (a<p hd>) } @-}
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | #4. Instantiating Abstract Refinements on Lists 
+-----------------------------------------------------------------------
+
+
+{-@ type IncrList a = List <{\x y -> x <= y}> a @-} 
+{-@ type DecrList a = List <{\x y -> x >= y}> a @-} 
+{-@ type DiffList a = List <{\x y -> x /= y}> a @-} 
+
+{-@ ups   :: IncrList Integer @-}
+ups       = 1 `C` 2 `C` 4 `C` N
+
+{-@ downs :: DecrList Integer @-}
+downs     = 100 `C` 20 `C` 4 `C` N
+
+{-@ diffs :: DiffList Integer @-}
+diffs     = 100 `C` 1000 `C` 10 `C` 1 `C`  N
+
+-----------------------------------------------------------------------
+-- | 5. Insertion Sort
+-----------------------------------------------------------------------
+
+{-@ insert         :: x:a -> xs:IncrList a -> {v:IncrList a | AddElt v x xs && size v = 1 + size xs} @-}
+insert x N         = x `C` N
+insert x (C y ys)
+  | x < y          = x `C` y `C` ys
+  | otherwise      = y `C` insert x ys 
+
+{-@ insertSort      :: xs:List a -> IncrList a @-}
+insertSort N        = N
+insertSort (C x xs) = insert x (insertSort xs)
+
+-----------------------------------------------------------------------
+-- | 6. Insertion Sort: using a `foldr` 
+-----------------------------------------------------------------------
+
+{-@ insertSort' :: xs:List a -> IncrList a @-}
+insertSort' xs = foldr insert N xs
+
+
+
+
+
+
+
+-- Or even better... we can use `ifoldr`
+
+{-@ insertSort'' :: xs:List a -> {v:IncrList a | EqSize v xs && EqElem v xs} @-}
+insertSort'' xs = ifoldr (\_ -> insert) N xs
+
+
+
+
+
+
+
+
+-- > RJ: Return to slides for "07_Array"
+
+
+
+
+
+
+              
+-----------------------------------------------------------------------
+-- | Boilerplate definitions from 00_Refinements.hs
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+{-@ measure size @-}
+size          :: List a -> Int
+size (C x xs) = 1 + size xs 
+size N        = 0
+
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+
+{-@ predicate EqSize X Y    = size X  = size Y                         @-}
+{-@ predicate EqElem X Y    = elems X = elems Y                        @-}
+{-@ predicate UnElems X Y Z = elems X = Set_cup (elems Y) (elems Z)    @-}
+{-@ predicate SubElems X Y  = Set_sub (elems X) (elems Y)              @-}
+{-@ predicate AddElt V X Xs = elems V = Set_cup (Set_sng X) (elems Xs) @-}
+
+{-@ measure elems ::List a -> (Set a)
+    elems (N)      = (Set_empty 0)
+    elems (C x xs) = (Set_cup (Set_sng x) (elems xs))
+  @-}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{-@ predicate SubConsElems X Y Ys = Set_sub (elems X) (Set_cup (Set_sng Y) (elems Ys)) @-}
+
+{-@ qual1  :: y:_ -> ys:_ -> {v:_ | SubConsElems v y ys} @-}
+qual1 :: a -> List a -> List a 
+qual1 y ys = undefined 
+
+{-@ qual2  :: y:_ -> ys:_ -> {v:_ | size v <= 1 + size ys} @-}
+qual2 :: a -> List a -> List a 
+qual2 y ys = undefined 
+
+
+
diff --git a/docs/slides/BOS14/hs/end/03_Termination.hs b/docs/slides/BOS14/hs/end/03_Termination.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/end/03_Termination.hs
@@ -0,0 +1,142 @@
+module Termination where
+
+import Prelude hiding (gcd, mod, map, repeat, take)
+import Language.Haskell.Liquid.Prelude
+
+fac   :: Int -> Int
+tfac  :: Int -> Int -> Int
+map   :: (a -> b) -> List a -> List b
+merge :: (Ord a) => List a -> List a -> List a
+
+
+-------------------------------------------------------------------------
+-- | Simple Termination
+-------------------------------------------------------------------------
+
+{-@ fac :: Nat -> Nat @-}
+fac 0 = 1
+fac 1 = 1
+fac n = n * fac (n-1)
+
+
+
+
+-------------------------------------------------------------------------
+-- | Semantic Termination
+-------------------------------------------------------------------------
+
+{-@ gcd :: a:Nat -> b:{v:Nat | v < a} -> Int @-}
+gcd :: Int -> Int -> Int
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+
+
+{-@ mod :: a:Nat -> b:{v:Nat| 0 < v && v < a} -> {v:Nat | v < b} @-}
+mod :: Int -> Int -> Int
+mod a b | a - b >  b = mod (a - b) b
+        | a - b <  b = a - b
+        | a - b == b = 0
+
+-------------------------------------------------------------------------
+-- | Explicit Metrics #1 
+-------------------------------------------------------------------------
+
+tfac acc 0 = acc
+tfac acc n = tfac (n * acc) (n-1)
+
+
+
+
+-------------------------------------------------------------------------
+-- Explicit Metrics #2 
+-------------------------------------------------------------------------
+
+range :: Int -> Int -> [Int]
+range lo hi
+  | lo < hi   = lo : range (lo + 1) hi
+  | otherwise = []
+
+
+
+-------------------------------------------------------------------------
+-- | Structural Recursion 
+-------------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+{-@ measure size @-}
+size :: List a -> Int 
+size (C x xs) = 1 + size xs
+size (N)      = 0
+
+{-@ map :: (a -> b) -> xs:List a -> (List b) / [size xs] @-}
+map _ N        = N
+map f (C x xs) = f x `C` map f xs
+
+
+
+-------------------------------------------------------------------------
+-- | Default Metrics
+-------------------------------------------------------------------------
+
+{-@ data List a = N | C {x :: a, xs :: List a } @-}
+
+map' _ N        = N
+map' f (C x xs) = f x `C` map' f xs
+
+
+
+-------------------------------------------------------------------------
+-- | Termination Expressions Metrics
+-------------------------------------------------------------------------
+
+merge (C x xs) (C y ys)
+  | x < y      = x `C` merge xs (y `C` ys)
+  | otherwise  = y `C` merge (x `C` xs) ys
+merge _   ys   = ys
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------
+take            :: Int -> List a -> List a
+{-@ invariant {v : List a | 0 <= size v} @-}
+
+
+
+
+
+
+
+
+-- CHEAT CODES, in case I forget :)
+
+{- tfac :: Nat -> n:Nat -> Nat / [n] @-}
+{- range :: lo:Nat -> hi:Nat -> [Nat] / [hi-lo] @-}
+{- merge :: xs:_ -> ys:_ -> _ / [size xs + size ys] @-}
diff --git a/docs/slides/BOS14/hs/end/04_Streams.hs b/docs/slides/BOS14/hs/end/04_Streams.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/end/04_Streams.hs
@@ -0,0 +1,106 @@
+module Streams where
+
+import Prelude hiding (take, repeat)
+
+import Language.Haskell.Liquid.Prelude
+
+-------------------------------------------------------------------------
+-- | Lists 
+-------------------------------------------------------------------------
+ 
+data List a = N | C { x :: a, xs :: List a }
+
+-- | Associate an abstract refinement with the _tail_ xs
+
+{-@ data List a <p :: List a -> Prop>
+      = N | C { x  :: a
+              , xs :: List <p> a <<p>>
+              }
+  @-}
+
+-------------------------------------------------------------------------
+-- | Infinite Streams
+-------------------------------------------------------------------------
+
+-- | Infinite List = List where _each_ tail is a `cons` ...
+
+{-@ type Stream a = {xs: List <{\v -> cons v}> a | cons xs} @-}
+
+-- | A simple measure for when a `List` is a `Cons`
+
+{-@ measure cons  :: (List a) -> Prop
+    cons (C x xs) = true 
+    cons (N)      = false 
+  @-}
+
+-------------------------------------------------------------------------
+-- | Creating an Infinite Stream
+-------------------------------------------------------------------------
+
+{-@ Lazy repeat @-}
+                 
+{-@ repeat :: a -> Stream a @-}
+repeat   :: a -> List a
+repeat x = x `C` repeat x
+
+
+-------------------------------------------------------------------------
+-- | Using an Infinite Stream
+-------------------------------------------------------------------------
+
+{-@ take        :: n:Nat -> Stream a -> {v:List a | size v = n} @-}
+take 0 _        = N
+take n (C x xs) = x `C` take (n-1) xs
+take _ N        = liquidError "never happens"
+
+-------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+-- | Other specs from before ...
+
+{-@ measure size :: List a -> Int 
+    size (N)      = 0
+    size (C x xs) = (1 + size xs)
+  @-}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------
+take            :: Int -> List a -> List a
+
+
+
+
+
+
+
+
+
diff --git a/docs/slides/BOS14/hs/end/05_Memory.hs b/docs/slides/BOS14/hs/end/05_Memory.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/end/05_Memory.hs
@@ -0,0 +1,387 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--diffcheck"     @-}
+
+module Memory where
+
+import Prelude hiding (null)
+import Data.Char
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
+import System.IO.Unsafe
+import Data.ByteString.Internal (c2w, w2c)
+import Language.Haskell.Liquid.Prelude
+
+
+------------------------------------------------------------------------
+-- | 1. Low-level Pointer API  -----------------------------------------
+------------------------------------------------------------------------
+
+-- | Create a buffer of size 4 and initialize it with zeros
+
+zero4  = do fp <- mallocForeignPtrBytes 4
+            withForeignPtr fp $ \p -> do
+              poke (p `plusPtr` 0) zero 
+              poke (p `plusPtr` 1) zero 
+              poke (p `plusPtr` 2) zero 
+              poke (p `plusPtr` 3) zero 
+            return fp
+        where
+            zero = 0 :: Word8
+
+-- But whats to prevent an overflow, e.g. writing to offset 5 or 50?
+            
+
+
+-- | Types for Pointers
+
+-- data Ptr a         
+-- data ForeignPtr a 
+
+-- | Size of Ptr and ForeignPtr
+
+-- measure plen  :: Ptr a -> Int 
+-- measure fplen :: ForeignPtr a -> Int 
+
+
+{-@ type PtrN a N        = {v:Ptr a        |  plen v  = N}  @-}
+{-@ type ForeignPtrN a N = {v:ForeignPtr a |  fplen v = N}  @-}
+
+-- | Allocating Memory
+
+{-@ assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignPtrN a n) @-}
+
+-- | Using a pointer
+
+{- withForeignPtr :: fp:ForeignPtr a 
+                  -> (PtrN a (fplen fp) -> IO b)  
+                  -> IO b             
+-}
+
+-- | Pointer Arithmetic
+
+{- plusPtr :: p:Ptr a
+           -> o:{Nat|o <= plen p}   -- in bounds
+           -> PtrN b (plen b - o)   -- remainder
+-}
+
+-- | Read and Write
+
+{- peek :: {v:Ptr a | 0 < plen v} -> IO a  
+   poke :: {v:Ptr a | 0 < plen v} -> a -> IO ()  
+ -}
+
+-- | Example: Preventing Overflows e.g. writing 5 or 50 zeros?
+
+zero4' = do fp <- mallocForeignPtrBytes 4
+            withForeignPtr fp $ \p -> do
+              poke (p `plusPtr` 0) zero 
+              poke (p `plusPtr` 1) zero 
+              poke (p `plusPtr` 2) zero 
+              poke (p `plusPtr` 5) zero 
+            return fp
+        where
+            zero = 0 :: Word8
+
+
+
+------------------------------------------------------------------------
+-- | 2. ByteString API -------------------------------------------------
+------------------------------------------------------------------------
+
+data ByteString = PS {
+    bPtr :: ForeignPtr Word8
+  , bOff :: !Int
+  , bLen :: !Int
+  }
+
+
+-- | Refined Type, with invariants
+
+{-@ data ByteString = PS {
+      bPtr :: ForeignPtr Word8
+    , bOff :: {v:Nat| v        <= fplen bPtr}
+    , bLen :: {v:Nat| v + bOff <= fplen bPtr}
+    }
+
+  @-}
+
+-- | Some useful abbreviations
+
+{-@ type ByteStringN N = {v:ByteString | bLen v = N} @-}
+{-@ type StringN N     = {v:String     | len v  = N} @-}
+
+-- | Legal Bytestrings 
+
+{-@ good1 :: IO (ByteStringN 5) @-}
+good1 = do fp <- mallocForeignPtrBytes 5
+           return $ PS fp 0 5
+
+{-@ good2 :: IO (ByteStringN 3) @-}
+good2 = do fp <- mallocForeignPtrBytes 5
+           return $ PS fp 2 3
+
+-- | Illegal Bytestrings 
+
+bad1 = do fp <- mallocForeignPtrBytes 3 
+          return $ PS fp 0 10 
+
+bad2 = do fp <- mallocForeignPtrBytes 3
+          return $ PS fp 2 2
+
+
+
+-- | ByteString API: `create`
+
+create :: Int -> (Ptr Word8 -> IO ()) -> ByteString
+
+create n fill = unsafePerformIO $ do
+  fp  <- mallocForeignPtrBytes n
+  withForeignPtr fp fill 
+  return $! PS fp 0 n
+
+
+-- Yikes, there is an error! How to fix?
+
+-- | ByteStringN API: `unsafeTake`
+
+unsafeTake n (PS x s l) = PS x s n
+
+-- Wow, thats super fast. O(1)! But how to fix the error?
+
+-- | ByteString API: `pack`
+
+pack          :: String -> ByteString
+pack str      = create n $ \p -> go p xs
+  where
+  n           = length str
+  xs          = map c2w str
+  go p (x:xs) = poke p x >> go (plusPtr p 1) xs
+  go _ []     = return  ()
+
+-- Hmm. How to fix the error?
+
+
+
+-- | ByteString API: `unpack` 
+
+
+
+{-@ qualif Unpack(v:a, acc:b, n:int) : len v = 1 + n + len acc @-}
+
+unpack :: ByteString -> String 
+unpack (PS _  _ 0)  = []
+unpack (PS ps s l)  = unsafePerformIO $ withForeignPtr ps $ \p ->
+   go (p `plusPtr` s) (l - 1)  []
+  where
+   go p 0 acc = peek p >>= \e -> return (w2c e : acc)
+   go p n acc = peek (p `plusPtr` n) >>= \e -> go p (n-1) (w2c e : acc)
+
+
+
+------------------------------------------------------------------------
+-- | 3. Application API (Heartbleed no more!) --------------------------
+------------------------------------------------------------------------
+
+chop     :: String -> Int -> String 
+chop s n =  s'
+  where 
+    b    = pack s          -- down to low-level
+    b'   = unsafeTake n b  -- grab n chars
+    s'   = unpack b'       -- up to high-level
+
+-- Whats the problem?
+
+
+
+
+
+-- | "HeartBleed" no more
+
+demo     = [ex6, ex30]
+  where
+    ex   = ['R','a','n','j','i','t']
+    ex6  = chop ex 6  -- ok
+    ex30 = chop ex 30 -- out of bounds
+
+
+-- "Bleeding" `chop ex 30` *rejected* by compiler
+
+
+
+------------------------------------------------------------------------
+-- | 3. Bonus Material -------------------------------------------------
+------------------------------------------------------------------------
+
+-- | `group` ing ByteStrings 
+
+{- How shall we type `group` where
+
+     group "foobaaar"
+
+   returns
+
+     ["f","oo", "b", "aaa", "r"]
+
+-}
+
+-- | An alias for NON-EMPTY ByteStrings
+    
+{-@ type ByteStringNE = {v:ByteString | bLen v > 0} @-}
+
+-- | A measure for the sum of sizes of a LIST of ByteStrings
+    
+{-@ measure bLens  :: [ByteString] -> Int
+    bLens ([])   = 0
+    bLens (x:xs) = (bLen x + bLens xs)
+  @-}
+
+-- | @group@
+    
+{-@ group :: b:ByteString -> {v: [ByteStringNE] | bLens v = bLen b} @-}
+group xs
+    | null xs   = []
+    | otherwise = let y = unsafeHead xs
+                      (ys, zs) = spanByte (unsafeHead xs) (unsafeTail xs)
+                  in (y `cons` ys) : group zs
+
+
+-- | @spanByte@ does the heavy lifting
+
+{-@ spanByte :: Word8 -> b:ByteString -> (ByteStringPair b) @-}
+spanByte :: Word8 -> ByteString -> (ByteString, ByteString)
+spanByte c ps@(PS x s l) = unsafePerformIO $ withForeignPtr x $ \p ->
+    go (p `plusPtr` s) 0
+  where
+    go p i | i >= l    = return (ps, empty)
+           | otherwise = do c' <- peekByteOff p i
+                            if c /= c'
+                                then return (unsafeTake i ps, unsafeDrop i ps)
+                                else go p (i+1)
+
+-- | Using the alias
+                            
+{-@ type ByteStringPair B = (ByteString, ByteString)<{\x1 x2 ->
+       bLen x1 + bLen x2 = bLen B}> @-}
+
+
+
+
+
+
+
+
+
+
+----------------------------------------------------------------------------
+-- | CHEAT AREA
+----------------------------------------------------------------------------
+
+{- create     :: n:Nat -> (PtrN Word8 n -> IO ()) -> ByteStringN n      @-}
+{- unsafeTake :: n:Nat -> b:{ByteString | n <= bLen b} -> ByteStringN n @-}
+{- pack       :: s:String -> ByteStringN (len s)                        @-}
+{- unpack     :: b:ByteString -> {v:String | len v = bLen b}            @-}
+{- chop       :: s:String -> n:{Nat | n <= len s} -> StringN n          @-} 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | Helper Code (Stuff from BS benchmark, to make demo self-contained)
+-----------------------------------------------------------------------
+
+{-@ unsafeCreate :: l:Nat -> ((PtrN Word8 l) -> IO ()) -> (ByteStringN l) @-}
+unsafeCreate n f = create n f -- unsafePerformIO $ create n f
+
+{-@ invariant {v:ByteString   | bLen  v >= 0} @-}
+{-@ invariant {v:[ByteString] | bLens v >= 0} @-}
+
+{-@ qualif PLLen(v:a, p:b) : (len v) <= (plen p) @-}
+{-@ qualif ForeignPtrN(v:ForeignPtr a, n:int): fplen v = n @-}
+{-@ qualif FPLenPLen(v:Ptr a, fp:ForeignPtr a): fplen fp = plen v @-}
+{-@ qualif PtrLen(v:Ptr a, xs:List b): plen v = len xs @-}
+{-@ qualif PlenEq(v: Ptr a, x: int): x <= (plen v) @-}
+
+{-@ unsafeHead :: {v:ByteString | (bLen v) > 0} -> Word8 @-}
+
+unsafeHead :: ByteString -> Word8
+unsafeHead (PS x s l) = liquidAssert (l > 0) $
+  unsafePerformIO  $  withForeignPtr x $ \p -> peekByteOff p s
+
+{-@ unsafeTail :: b:{v:ByteString | (bLen v) > 0}
+               -> {v:ByteString | (bLen v) = (bLen b) - 1} @-}
+unsafeTail :: ByteString -> ByteString
+unsafeTail (PS ps s l) = liquidAssert (l > 0) $ PS ps (s+1) (l-1)
+
+{-@ null :: b:ByteString -> {v:Bool | ((Prop v) <=> ((bLen b) = 0))} @-}
+null :: ByteString -> Bool
+null (PS _ _ l) = liquidAssert (l >= 0) $ l <= 0
+
+{-@ unsafeDrop :: n:Nat
+               -> b:{v: ByteString | n <= (bLen v)} 
+               -> {v:ByteString | (bLen v) = (bLen b) - n} @-}
+unsafeDrop  :: Int -> ByteString -> ByteString
+unsafeDrop n (PS x s l) = liquidAssert (0 <= n && n <= l) $ PS x (s+n) (l-n)
+
+{-@ cons :: Word8 -> b:ByteString -> {v:ByteString | (bLen v) = 1 + (bLen b)} @-}
+cons :: Word8 -> ByteString -> ByteString
+cons c (PS x s l) = unsafeCreate (l+1) $ \p -> withForeignPtr x $ \f -> do
+        poke p c
+        memcpy (p `plusPtr` 1) (f `plusPtr` s) (fromIntegral l)
+
+{-@ empty :: {v:ByteString | (bLen v) = 0} @-} 
+empty :: ByteString
+empty = PS nullForeignPtr 0 0
+
+{-@ assume
+    c_memcpy :: dst:(PtrV Word8)
+             -> src:(PtrV Word8) 
+             -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))} 
+             -> IO (Ptr Word8)
+  @-}
+foreign import ccall unsafe "string.h memcpy" c_memcpy
+    :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)
+
+{-@ memcpy :: dst:(PtrV Word8)
+           -> src:(PtrV Word8) 
+           -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))} 
+           -> IO () 
+  @-}
+memcpy :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()
+memcpy p q s = c_memcpy p q s >> return ()
+
+{-@ assume nullForeignPtr :: {v: ForeignPtr Word8 | (fplen v) = 0} @-}
+nullForeignPtr :: ForeignPtr Word8
+nullForeignPtr = unsafePerformIO $ newForeignPtr_ nullPtr
+{-# NOINLINE nullForeignPtr #-}
+
+
+
diff --git a/docs/slides/BOS14/hs/end/06_Eval.hs b/docs/slides/BOS14/hs/end/06_Eval.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/end/06_Eval.hs
@@ -0,0 +1,71 @@
+{-@ LIQUID "--no-termination" @-}
+
+module Eval (eval) where
+
+import Language.Haskell.Liquid.Prelude (liquidError)
+import Prelude hiding (lookup)
+import Data.Set (Set (..))
+
+lookup :: Bndr -> Env Expr -> Expr 
+
+-------------------------------------------------------------------
+-- | Binders, Expressions, Environments
+-------------------------------------------------------------------
+
+type Bndr = String 
+
+data Expr = Const Int
+          | Var   Bndr
+          | Plus  Expr Expr
+          | Let   Bndr Expr Expr
+
+type Env a = [(Bndr, a)]
+
+-------------------------------------------------------------------
+-- | Values
+-------------------------------------------------------------------
+
+{-@ type Val = {v:Expr | val v} @-}
+
+{-@ measure val       :: Expr -> Prop
+    val (Const i)     = true
+    val (Var x)       = false
+    val (Plus e1 e2)  = false
+    val (Let x e1 e2) = false
+  @-}
+
+-------------------------------------------------------------------
+{-@ lookup :: x:Bndr -> {v:Env Val | Set_mem x (vars v)} -> Val @-}
+-------------------------------------------------------------------
+lookup x ((y,v):env)   
+  | x == y             = v
+  | otherwise          = lookup x env
+lookup x []            = liquidError "Unbound Variable"
+
+-------------------------------------------------------------------
+{-@ eval :: g:Env Val -> ClosedExpr g -> Val @-}
+-------------------------------------------------------------------
+eval env i@(Const _)   = i
+eval env (Var x)       = lookup x env 
+eval env (Plus e1 e2)  = plus (eval env e1) (eval env e2) 
+eval env (Let x e1 e2) = eval env' e2 
+  where 
+    env'               = (x, eval env e1) : env
+
+plus (Const i) (Const j) = Const (i+j)
+plus _         _         = liquidError "Bad call to plus"
+
+
+{-@ type ClosedExpr G  = {v:Expr | Set_sub (free v) (vars G)} @-}
+
+{-@ measure vars :: Env a -> (Set Bndr)
+    vars ([])    = (Set_empty 0)
+    vars (b:env) = (Set_cup (Set_sng (fst b)) (vars env))
+  @-}
+
+{-@ measure free       :: Expr -> (Set Bndr) 
+    free (Const i)     = (Set_empty 0)
+    free (Var x)       = (Set_sng x) 
+    free (Plus e1 e2)  = (Set_cup (free e1) (free e2))
+    free (Let x e1 e2) = (Set_cup (free e1) (Set_dif (free e2) (Set_sng x)))
+  @-}
diff --git a/docs/slides/BOS14/hs/long/AlphaConvert.hs b/docs/slides/BOS14/hs/long/AlphaConvert.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/long/AlphaConvert.hs
@@ -0,0 +1,145 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--fullcheck"      @-}
+{-@ LIQUID "--maxparams=3"    @-}
+
+-- | An example from "A Relational Framework for Higher-Order Shape Analysis",
+--   by Gowtham Kaki Suresh Jagannathan, ICFP 2014.
+
+module AlphaConvert (subst, alpha) where
+
+import Prelude hiding ((++), elem)
+import Data.Set (Set (..))
+import Language.Haskell.Liquid.Prelude   
+
+alpha  :: [Bndr] -> Expr -> Expr 
+subst  :: Expr -> Bndr -> Expr -> Expr
+maxs   :: [Int] -> Int 
+lemma1 :: Int -> [Int] -> Bool
+fresh  :: [Bndr] -> Bndr
+free   :: Expr -> [Bndr]
+
+---------------------------------------------------------------------
+-- | Datatype Definition --------------------------------------------
+---------------------------------------------------------------------
+
+type Bndr 
+  = Int
+
+data Expr 
+  = Var Bndr  
+  | Abs Bndr Expr
+  | App Expr Expr
+
+{-@ measure fv       :: Expr -> (Set Bndr)
+    fv (Var x)       = (Set_sng x)
+    fv (Abs x e)     = (Set_dif (fv e) (Set_sng x))
+    fv (App e a)     = (Set_cup (fv e) (fv a)) 
+  @-}
+
+{-@ measure isAbs    :: Expr -> Prop
+    isAbs (Var v)    = false
+    isAbs (Abs v e)  = true
+    isAbs (App e a)  = false             
+  @-}
+
+{-@ predicate AddV E E2 X E1   = fv E = Set_cup (Set_dif (fv E2) (Set_sng X)) (fv E1) @-}
+{-@ predicate EqV E1 E2        = fv E1 = fv E2                                        @-}
+{-@ predicate Occ X E          = Set_mem X (fv E)                                     @-}
+{-@ predicate Subst E E1 X E2  = if (Occ X E2) then (AddV E E2 X E1) else (EqV E E2)  @-}
+
+----------------------------------------------------------------------------
+-- | Part 5: Capture Avoiding Substitution ---------------------------------
+----------------------------------------------------------------------------
+{-@ subst :: e1:Expr -> x:Bndr -> e2:Expr -> {e:Expr | Subst e e1 x e2} @-} 
+----------------------------------------------------------------------------
+
+subst e1 x e2@(Var y)
+  | x == y                = e1
+  | otherwise             = e2
+
+subst e1 x (App ea eb)    = App ea' eb'
+  where
+    ea'                   = subst e1 x ea
+    eb'                   = subst e1 x eb
+
+subst e1 x e2@(Abs y e)  
+  | x == y                = e2
+  | y `elem` xs           = subst e1 x (alpha xs e2) 
+  | otherwise             = Abs y      (subst e1 x e)
+     where
+      xs                  = free e1 
+
+----------------------------------------------------------------------------
+-- | Part 4: Alpha Conversion ----------------------------------------------
+----------------------------------------------------------------------------
+{-@ alpha :: ys:[Bndr] -> e:{Expr | isAbs e} -> {v:Expr | EqV v e} @-}
+----------------------------------------------------------------------------
+alpha ys (Abs x e) = Abs x' (subst (Var x') x e)
+  where 
+    xs             = free e
+    x'             = fresh (x : ys ++ xs)
+
+alpha _  _         = liquidError "never"
+
+
+----------------------------------------------------------------------------
+-- | Part 3: Fresh Variables -----------------------------------------------
+----------------------------------------------------------------------------
+{-@ fresh :: xs:[Bndr] -> {v:Bndr | NotElem v xs} @-}
+----------------------------------------------------------------------------
+fresh bs = liquidAssert (lemma1 n bs) n
+  where 
+    n    = 1 + maxs bs
+
+{-@ maxs :: xs:_ -> {v:_ | v = maxs xs} @-}
+maxs ([])   = 0
+maxs (x:xs) = if (x > maxs xs) then x else (maxs xs) 
+ 
+ 
+{-@ measure maxs :: [Int] -> Int 
+    maxs ([])   = 0
+    maxs (x:xs) = if (x > maxs xs) then x else (maxs xs) 
+  @-}
+
+{-@ lemma1 :: x:Int -> xs:{[Int] | x > maxs xs} -> {v:Bool | Prop v && NotElem x xs} @-}
+lemma1 _ []     = True 
+lemma1 x (_:ys) = lemma1 x ys 
+
+
+----------------------------------------------------------------------------
+-- | Part 2: Free Variables ------------------------------------------------
+----------------------------------------------------------------------------
+
+----------------------------------------------------------------------------
+{-@ free         :: e:Expr -> {v:[Bndr] | elts v = fv e} @-}
+----------------------------------------------------------------------------
+free (Var x)     = [x]
+free (App e e')  = free e ++ free e'
+free (Abs x e)   = free e \\ x
+
+
+----------------------------------------------------------------------------
+-- | Part I: Sets with Lists -----------------------------------------------
+----------------------------------------------------------------------------
+
+{-@ predicate IsCup X Y Z  = elts X = Set_cup (elts Y) (elts Z)    @-}
+{-@ predicate IsDel X Y Z  = elts X = Set_dif (elts Y) (Set_sng Z) @-}
+{-@ predicate Elem  X Ys   = Set_mem X (elts Ys)                   @-}
+{-@ predicate NotElem X Ys = not (Elem X Ys)                       @-}
+
+{-@ (++)      :: xs:[a] -> ys:[a] -> {v:[a] | IsCup v xs ys}  @-}
+[]     ++ ys  = ys
+(x:xs) ++ ys  = x : (xs ++ ys)
+
+{-@ (\\)      :: (Eq a) => xs:[a] -> y:a -> {v:[a] | IsDel v xs y} @-}
+xs   \\ y     = [x | x <- xs, x /= y]
+
+{-@ elem      :: (Eq a) => x:a -> ys:[a] -> {v:Bool | Prop v <=> Elem x ys} @-}
+elem x []     = False
+elem x (y:ys) = x == y || elem x ys
+ 
+{-@ measure elts :: [a] -> (Set a) 
+    elts ([])    = {v | Set_emp v}
+    elts (x:xs)  = {v | v = Set_cup (Set_sng x) (elts xs) }
+  @-}
diff --git a/docs/slides/BOS14/hs/long/GhcListSort.hs b/docs/slides/BOS14/hs/long/GhcListSort.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/long/GhcListSort.hs
@@ -0,0 +1,128 @@
+{-@ LIQUID "--no-termination" @-}
+
+module GhcSort () where
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ type OList a =  [a]<{\fld v -> (v >= fld)}>  @-}
+
+---------------------------------------------------------------------------
+---------------------------  Official GHC Sort ----------------------------
+---------------------------------------------------------------------------
+
+{-@ assert sort1 :: (Ord a) => [a] -> OList a  @-}
+sort1 :: (Ord a) => [a] -> [a]
+sort1 = mergeAll . sequences
+  where
+    sequences (a:b:xs)
+      | a `compare` b == GT = descending b [a]  xs
+      | otherwise           = ascending  b (a:) xs
+    sequences [x] = [[x]]
+    sequences []  = [[]]
+
+    descending a as (b:bs)
+      | a `compare` b == GT = descending b (a:as) bs
+    descending a as bs      = (a:as): sequences bs
+
+    ascending a as (b:bs)
+      | a `compare` b /= GT = ascending b (\ys -> as (a:ys)) bs
+    ascending a as bs       = as [a]: sequences bs
+
+    mergeAll [x] = x
+    mergeAll xs  = mergeAll (mergePairs xs)
+
+    mergePairs (a:b:xs) = merge1 a b: mergePairs xs
+    mergePairs [x]      = [x]
+    mergePairs []       = []
+
+-- merge1 needs to be toplevel,
+-- to get applied transformRec tx
+merge1 (a:as') (b:bs')
+  | a `compare` b == GT = b:merge1 (a:as')  bs'
+  | otherwise           = a:merge1 as' (b:bs')
+merge1 [] bs            = bs
+merge1 as []            = as
+
+---------------------------------------------------------------------------
+------------------- Mergesort ---------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ assert sort2 :: (Ord a) => [a] -> OList a  @-}
+sort2 :: (Ord a) => [a] -> [a]
+sort2 = mergesort
+
+mergesort :: (Ord a) => [a] -> [a]
+mergesort = mergesort' . map wrap
+
+mergesort' :: (Ord a) => [[a]] -> [a]
+mergesort' [] = []
+mergesort' [xs] = xs
+mergesort' xss = mergesort' (merge_pairs xss)
+
+merge_pairs :: (Ord a) => [[a]] -> [[a]]
+merge_pairs [] = []
+merge_pairs [xs] = [xs]
+merge_pairs (xs:ys:xss) = merge xs ys : merge_pairs xss
+
+merge :: (Ord a) => [a] -> [a] -> [a]
+merge [] ys = ys
+merge xs [] = xs
+merge (x:xs) (y:ys)
+ = case x `compare` y of
+        GT -> y : merge (x:xs)   ys
+        _  -> x : merge    xs (y:ys)
+
+wrap :: a -> [a]
+wrap x = [x]
+
+----------------------------------------------------------------------
+-------------------- QuickSort ---------------------------------------
+----------------------------------------------------------------------
+
+{-@ assert sort3 :: (Ord a) => w:a -> [{v:a|v<=w}] -> OList a @-}
+sort3 :: (Ord a) => a -> [a] -> [a]
+sort3 w ls = qsort w ls []
+
+-- qsort is stable and does not concatenate.
+qsort :: (Ord a) =>  a -> [a] -> [a] -> [a]
+qsort _ []     r = r
+qsort _ [x]    r = x:r
+qsort w (x:xs) r = qpart w x xs [] [] r
+
+-- qpart partitions and sorts the sublists
+qpart :: (Ord a) => a -> a -> [a] -> [a] -> [a] -> [a] -> [a]
+qpart w x [] rlt rge r =
+    -- rlt and rge are in reverse order and must be sorted with an
+    -- anti-stable sorting
+    rqsort x rlt (x:rqsort w rge r)
+qpart w x (y:ys) rlt rge r =
+    case compare x y of
+        GT -> qpart w x ys (y:rlt) rge r
+        _  -> qpart w x ys rlt (y:rge) r
+
+-- rqsort is as qsort but anti-stable, i.e. reverses equal elements
+rqsort :: (Ord a) => a -> [a] -> [a] -> [a]
+rqsort _ []     r = r
+rqsort _ [x]    r = x:r
+rqsort w (x:xs) r = rqpart w x xs [] [] r
+
+rqpart :: (Ord a) => a -> a -> [a] -> [a] -> [a] -> [a] -> [a]
+rqpart w x [] rle rgt r =
+    qsort x rle (x:qsort w rgt r)
+rqpart w x (y:ys) rle rgt r =
+    case compare y x of
+        GT -> rqpart w x ys rle (y:rgt) r
+        _  -> rqpart w x ys (y:rle) rgt r
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/slides/BOS14/hs/long/KMP.hs b/docs/slides/BOS14/hs/long/KMP.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/long/KMP.hs
@@ -0,0 +1,90 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+
+module KMP (search) where
+
+import Language.Haskell.Liquid.Prelude (liquidError)
+import qualified Data.Map as M
+
+search pat str = kmpSearch (ofList pat) (ofList str) 
+
+-------------------------------------------------------------
+-- | Do the Search ------------------------------------------
+-------------------------------------------------------------
+
+{-@ type Upto N = {v:Nat | v < N} @-} 
+
+{-@ kmpSearch :: (Eq a) => p:Arr a -> s:Arr a -> Maybe (Upto (alen s)) @-}
+kmpSearch p@(A m _) s@(A n _) = go 0 0 
+  where
+    t              = kmpTable p
+    go i j
+      | i >= n     = Nothing 
+      | j >= m     = Just (i - m)
+      | s!i == p!j = go (i+1) (j+1)
+      | j == 0     = go (i+1) j
+      | otherwise  = go i     (t!j) 
+
+
+-------------------------------------------------------------
+-- | Make Table ---------------------------------------------
+-------------------------------------------------------------
+
+kmpTable p@(A m _) = go t 1 0 
+  where
+    t              = new m (\_ -> 0)
+    go t i j
+      | i >= m - 1 = t
+
+      | p!i == p!j = let i' = i + 1
+                         j' = j + 1
+                         t' = set t i' j'
+                     in go t' i' j'           
+    
+      | (j == 0)   = let i' = i + 1
+                         t' = set t i' 0
+                     in go t' i' j
+                             
+      | otherwise  = let j' = t ! j
+                     in go t i j' 
+
+
+-------------------------------------------------------------
+-- | A Pure Array -------------------------------------------
+-------------------------------------------------------------
+
+data Arr a   = A { alen :: Int
+                 , aval :: Int -> a
+                 }
+
+{-@ data Arr a <p :: Int -> a -> Prop>
+             = A { alen :: Nat 
+                 , aval :: i:Upto alen -> a<p i>
+                 }
+  @-}
+
+
+{-@ new :: forall <p :: Int -> a -> Prop>.
+             n:Nat -> (i:Upto n -> a<p i>) -> {v: Arr<p> a | alen v = n}
+  @-}
+new n v = A n v
+
+{-@ (!) :: forall <p :: Int -> a -> Prop>.
+             a:Arr<p> a -> i:Upto (alen a) -> a<p i>
+  @-}
+(A _ f) ! i = f i
+  
+{-@ set :: forall <p :: Int -> a -> Prop>.
+             a:Arr<p> a -> i:Upto (alen a) -> a<p i> -> {v:Arr<p> a | alen v = alen a}
+  @-}
+set a@(A _ f) i v = a { aval = \j -> if (i == j) then v else f j }
+
+{-@ ofList :: xs:[a] -> {v:Arr a | alen v = len xs} @-} 
+ofList xs = new n f
+  where
+    n     = length xs
+    m     = M.fromList $ zip [0..] xs
+    f i   = (M.!) m i 
+
+{-@ map :: (a -> b) -> a:Arr a -> {v:Arr b | alen v = alen a} @-}
+map f a@(A n z) = A n (f . z) 
diff --git a/docs/slides/BOS14/hs/long/RBTree-ord.hs b/docs/slides/BOS14/hs/long/RBTree-ord.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/long/RBTree-ord.hs
@@ -0,0 +1,143 @@
+
+{-@ LIQUID "--no-termination"   @-}
+
+module Foo (add, remove, deleteMin, deleteMin') where
+
+import Language.Haskell.Liquid.Prelude
+
+data RBTree a = Leaf 
+              | Node Color a !(RBTree a) !(RBTree a)
+              deriving (Show)
+
+data Color = B -- ^ Black
+           | R -- ^ Red
+           deriving (Eq,Show)
+
+---------------------------------------------------------------------------
+-- | Add an element -------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ add :: (Ord a) => a -> ORBT a -> ORBT a @-}
+add x s = makeBlack (ins x s)
+
+{-@ ins :: (Ord a) => a -> ORBT a -> ORBT a @-}
+ins kx Leaf             = Node R kx Leaf Leaf
+ins kx s@(Node B x l r) = case compare kx x of
+                            LT -> let t = lbal x (ins kx l) r in t 
+                            GT -> let t = rbal x l (ins kx r) in t 
+                            EQ -> s
+ins kx s@(Node R x l r) = case compare kx x of
+                            LT -> Node R x (ins kx l) r
+                            GT -> Node R x l (ins kx r)
+                            EQ -> s
+
+---------------------------------------------------------------------------
+-- | Delete an element ----------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ remove :: (Ord a) => a -> ORBT a -> ORBT a @-}
+remove x t = makeBlack (del x t)
+
+{-@ del              :: (Ord a) => a -> ORBT a -> ORBT a @-}
+del x Leaf           = Leaf
+del x (Node _ y a b) = case compare x y of
+   EQ -> append y a b 
+   LT -> case a of
+           Leaf         -> Node R y Leaf b
+           Node B _ _ _ -> lbalS y (del x a) b
+           _            -> let t = Node R y (del x a) b in t 
+   GT -> case b of
+           Leaf         -> Node R y a Leaf 
+           Node B _ _ _ -> rbalS y a (del x b)
+           _            -> Node R y a (del x b)
+
+{-@ append  :: y:a -> ORBT {v:a | v < y} -> ORBT {v:a | y < v} -> ORBT a @-}
+append :: a -> RBTree a -> RBTree a -> RBTree a
+
+append _ Leaf r                               
+  = r
+
+append _ l Leaf                               
+  = l
+
+append piv (Node R lx ll lr) (Node R rx rl rr)  
+  = case append piv lr rl of 
+      Node R x lr' rl' -> Node R x (Node R lx ll lr') (Node R rx rl' rr)
+      lrl              -> Node R lx ll (Node R rx lrl rr)
+
+append piv (Node B lx ll lr) (Node B rx rl rr)  
+  = case append piv lr rl of 
+      Node R x lr' rl' -> Node R x (Node B lx ll lr') (Node B rx rl' rr)
+      lrl              -> lbalS lx ll (Node B rx lrl rr)
+
+append piv l@(Node B _ _ _) (Node R rx rl rr)   
+  = Node R rx (append piv l rl) rr
+
+append piv l@(Node R lx ll lr) r@(Node B _ _ _) 
+  = Node R lx ll (append piv lr r)
+
+---------------------------------------------------------------------------
+-- | Delete Minimum Element -----------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ deleteMin  :: ORBT a -> ORBT a @-}
+deleteMin (Leaf)         = Leaf
+deleteMin (Node _ x l r) = makeBlack t
+  where 
+    (_, t)               = deleteMin' x l r
+
+
+{-@ deleteMin' :: k:a -> ORBT {v:a | v < k} -> ORBT {v:a | k < v} -> (a, ORBT a) @-}
+deleteMin' k Leaf r              = (k, r)
+deleteMin' x (Node R lx ll lr) r = (k, Node R x l' r)   where (k, l') = deleteMin' lx ll lr 
+deleteMin' x (Node B lx ll lr) r = (k, lbalS x l' r )   where (k, l') = deleteMin' lx ll lr 
+
+---------------------------------------------------------------------------
+-- | Rotations ------------------------------------------------------------
+---------------------------------------------------------------------------
+
+lbalS k (Node R x a b) r              = Node R k (Node B x a b) r
+lbalS k l (Node B y a b)              = let t = rbal k l (Node R y a b) in t 
+lbalS k l (Node R z (Node B y a b) c) = Node R y (Node B k l a) (rbal z b (makeRed c))
+lbalS k l r                           = error "nein" 
+
+rbalS k l (Node R y b c)              = Node R k l (Node B y b c)
+rbalS k (Node B x a b) r              = let t = lbal k (Node R x a b) r in t 
+rbalS k (Node R x a (Node B y b c)) r = Node R y (lbal x (makeRed a) b) (Node B k c r)
+rbalS k l r                           = error "nein"
+
+lbal k (Node R y (Node R x a b) c) r  = Node R y (Node B x a b) (Node B k c r)
+lbal k (Node R x a (Node R y b c)) r  = Node R y (Node B x a b) (Node B k c r)
+lbal k l r                            = Node B k l r
+
+rbal x a (Node R y b (Node R z c d))  = Node R y (Node B x a b) (Node B z c d)
+rbal x a (Node R z (Node R y b c) d)  = Node R y (Node B x a b) (Node B z c d)
+rbal x l r                            = Node B x l r
+
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+
+makeRed (Node _ x l r) = Node R x l r
+makeRed Leaf           = error "nein" 
+
+makeBlack Leaf           = Leaf
+makeBlack (Node _ x l r) = Node B x l r
+
+---------------------------------------------------------------------------
+-- | Specifications -------------------------------------------------------
+---------------------------------------------------------------------------
+
+-- | Ordered Red-Black Trees
+
+{-@ type ORBT a = RBTree <{\root v -> v < root }, {\root v -> v > root}> a @-}
+
+-- | Binary Search Ordering
+
+{-@ data RBTree a <l :: a -> a -> Prop, r :: a -> a -> Prop>
+            = Leaf
+            | Node (c    :: Color)
+                   (key  :: a)
+                   (left :: RBTree <l, r> (a <l key>))
+                   (left :: RBTree <l, r> (a <r key>))
+  @-}
diff --git a/docs/slides/BOS14/hs/long/RBTree.hs b/docs/slides/BOS14/hs/long/RBTree.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/long/RBTree.hs
@@ -0,0 +1,209 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--diff"           @-}
+
+module Foo where
+
+import Language.Haskell.Liquid.Prelude
+
+data RBTree a = Leaf 
+              | Node Color a !(RBTree a) !(RBTree a)
+              deriving (Show)
+
+data Color = B -- ^ Black
+           | R -- ^ Red
+           deriving (Eq,Show)
+
+---------------------------------------------------------------------------
+-- | Add an element -------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ add :: (Ord a) => a -> RBT a -> RBT a @-}
+add x s = makeBlack (ins x s)
+
+{-@ ins :: (Ord a) => a -> t:RBT a -> {v: ARBTN a {bh t} | IsB t => isRB v} @-}
+ins kx Leaf             = Node R kx Leaf Leaf
+ins kx s@(Node B x l r) = case compare kx x of
+                            LT -> let t = lbal x (ins kx l) r in t 
+                            GT -> let t = rbal x l (ins kx r) in t 
+                            EQ -> s
+ins kx s@(Node R x l r) = case compare kx x of
+                            LT -> Node R x (ins kx l) r
+                            GT -> Node R x l (ins kx r)
+                            EQ -> s
+
+---------------------------------------------------------------------------
+-- | Delete an element ----------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ remove :: (Ord a) => a -> RBT a -> RBT a @-}
+remove x t = makeBlack (del x t)
+
+{-@ predicate HDel T V = bh V = if (isB T) then (bh T) - 1 else bh T @-}
+
+{-@ del              :: (Ord a) => a -> t:RBT a -> {v:ARBT a | HDel t v && (isB t || isRB v)} @-}
+del x Leaf           = Leaf
+del x (Node _ y a b) = case compare x y of
+   EQ -> append y a b 
+   LT -> case a of
+           Leaf         -> Node R y Leaf b
+           Node B _ _ _ -> lbalS y (del x a) b
+           _            -> let t = Node R y (del x a) b in t 
+   GT -> case b of
+           Leaf         -> Node R y a Leaf 
+           Node B _ _ _ -> rbalS y a (del x b)
+           _            -> Node R y a (del x b)
+
+{-@ append :: y:a -> l:RBT {v:a | v < y} -> r:RBTN {v:a | y < v} {bh l} -> ARBT2 a l r @-}
+append :: a -> RBTree a -> RBTree a -> RBTree a
+append _ Leaf r                               = r
+append _ l Leaf                               = l
+append piv (Node R lx ll lr) (Node R rx rl rr)  = case append piv lr rl of 
+                                                    Node R x lr' rl' -> Node R x (Node R lx ll lr') (Node R rx rl' rr)
+                                                    lrl              -> Node R lx ll (Node R rx lrl rr)
+append piv (Node B lx ll lr) (Node B rx rl rr)  = case append piv lr rl of 
+                                                    Node R x lr' rl' -> Node R x (Node B lx ll lr') (Node B rx rl' rr)
+                                                    lrl              -> lbalS lx ll (Node B rx lrl rr)
+append piv l@(Node B _ _ _) (Node R rx rl rr)   = Node R rx (append piv l rl) rr
+append piv l@(Node R lx ll lr) r@(Node B _ _ _) = Node R lx ll (append piv lr r)
+
+---------------------------------------------------------------------------
+-- | Delete Minimum Element -----------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ deleteMin            :: RBT a -> RBT a @-}
+deleteMin (Leaf)         = Leaf
+deleteMin (Node _ x l r) = makeBlack t
+  where 
+    (_, t)               = deleteMin' x l r
+
+
+{-@ deleteMin'                   :: k:a -> l:RBT {v:a | v < k} -> r:RBTN {v:a | k < v} {bh l} -> (a, ARBT2 a l r) @-}
+deleteMin' k Leaf r              = (k, r)
+deleteMin' x (Node R lx ll lr) r = (k, Node R x l' r)   where (k, l') = deleteMin' lx ll lr 
+deleteMin' x (Node B lx ll lr) r = (k, lbalS x l' r )   where (k, l') = deleteMin' lx ll lr 
+
+---------------------------------------------------------------------------
+-- | Rotations ------------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ lbalS                             :: k:a -> l:ARBT {v:a | v < k} -> r:RBTN {v:a | k < v} {1 + bh l} -> {v: ARBTN a {1 + bh l} | IsB r => isRB v} @-}
+lbalS k (Node R x a b) r              = Node R k (Node B x a b) r
+lbalS k l (Node B y a b)              = let t = rbal k l (Node R y a b) in t 
+lbalS k l (Node R z (Node B y a b) c) = Node R y (Node B k l a) (rbal z b (makeRed c))
+lbalS k l r                           = liquidError "nein"
+
+{-@ rbalS                             :: k:a -> l:RBT {v:a | v < k} -> r:ARBTN {v:a | k < v} {bh l - 1} -> {v: ARBTN a {bh l} | IsB l => isRB v} @-}
+rbalS k l (Node R y b c)              = Node R k l (Node B y b c)
+rbalS k (Node B x a b) r              = let t = lbal k (Node R x a b) r  in t 
+rbalS k (Node R x a (Node B y b c)) r = Node R y (lbal x (makeRed a) b) (Node B k c r)
+rbalS k l r                           = liquidError "nein"
+
+{-@ lbal                              :: k:a -> l:ARBT {v:a | v < k} -> RBTN {v:a | k < v} {bh l} -> RBTN a {1 + bh l} @-}
+lbal k (Node R y (Node R x a b) c) r  = Node R y (Node B x a b) (Node B k c r)
+lbal k (Node R x a (Node R y b c)) r  = Node R y (Node B x a b) (Node B k c r)
+lbal k l r                            = Node B k l r
+
+{-@ rbal                              :: k:a -> l:RBT {v:a | v < k} -> ARBTN {v:a | k < v} {bh l} -> RBTN a {1 + bh l} @-}
+rbal x a (Node R y b (Node R z c d))  = Node R y (Node B x a b) (Node B z c d)
+rbal x a (Node R z (Node R y b c) d)  = Node R y (Node B x a b) (Node B z c d)
+rbal x l r                            = Node B x l r
+
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ type BlackRBT a = {v: RBT a | IsB v && bh v > 0} @-}
+
+{-@ makeRed :: l:BlackRBT a -> ARBTN a {bh l - 1} @-}
+makeRed (Node B x l r) = Node R x l r
+makeRed _              = liquidError "nein"
+
+{-@ makeBlack :: ARBT a -> RBT a @-}
+makeBlack Leaf           = Leaf
+makeBlack (Node _ x l r) = Node B x l r
+
+---------------------------------------------------------------------------
+-- | Specifications -------------------------------------------------------
+---------------------------------------------------------------------------
+
+-- | Red-Black Trees
+
+{-@ type RBT a    = {v: ORBT a | isRB v && isBH v } @-}
+{-@ type RBTN a N = {v: RBT a  | bh v = N }         @-}
+
+-- | Invariant 1: Binary Search Ordering 
+
+{-@ data RBTree a <l :: a -> a -> Prop, r :: a -> a -> Prop>
+            = Leaf
+            | Node (c    :: Color)
+                   (key  :: a)
+                   (left :: RBTree <l, r> (a <l key>))
+                   (left :: RBTree <l, r> (a <r key>))
+  @-}
+
+{-@ type ORBT a = RBTree <{\root v -> v < root }, {\root v -> v > root}> a @-}
+
+-- | Invariant 2: Black Height Same on All Paths 
+
+{-@ measure isBH        :: RBTree a -> Prop
+    isBH (Leaf)         = true
+    isBH (Node c x l r) = (isBH l && isBH r && bh l = bh r)
+  @-}
+
+{-@ measure bh        :: RBTree a -> Int
+    bh (Leaf)         = 0
+    bh (Node c x l r) = bh l + if (c == R) then 0 else 1 
+  @-}
+
+-- | Invariant 3: Red Nodes have Black Children
+
+{-@ measure isRB        :: RBTree a -> Prop
+    isRB (Leaf)         = true
+    isRB (Node c x l r) = isRB l && isRB r && (c == R => (IsB l && IsB r))
+  @-}
+
+{-@ measure col         :: RBTree a -> Color
+    col (Node c x l r)  = c
+    col (Leaf)          = B
+  @-}
+
+{-@ measure isB        :: RBTree a -> Prop
+    isB (Leaf)         = false
+    isB (Node c x l r) = c == B 
+  @-}
+
+{-@ predicate IsB T = not (col T == R) @-}
+
+--------------------------------------------------------------------------
+-- | Auxiliary Specifications --------------------------------------------
+--------------------------------------------------------------------------
+
+-- | Almost Red-Black Trees
+
+{-@ measure isARB        :: (RBTree a) -> Prop
+    isARB (Leaf)         = true 
+    isARB (Node c x l r) = (isRB l && isRB r)
+  @-}
+
+
+-- | Conditionally Red-Black Tree
+
+{-@ type ARBT2 a L R = {v:ARBTN a {bh L} | (IsB L && IsB R) => isRB v} @-}
+{-@ type ARBT a      = {v: ORBT a | isARB v && isBH v} @-}
+{-@ type ARBTN a N   = {v: ARBT a | bh v = N }         @-}
+
+
+-------------------------------------------------------------------------------
+-- Auxiliary Invariants -------------------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ predicate Invs V = Inv1 V && Inv2 V && Inv3 V   @-}
+{-@ predicate Inv1 V = (isARB V && IsB V) => isRB V @-}
+{-@ predicate Inv2 V = isRB v => isARB v            @-}
+{-@ predicate Inv3 V = 0 <= bh v                    @-}
+{-@ invariant {v: Color | v = R || v = B}           @-}
+{-@ invariant {v: RBTree a | Invs v}                @-}
+
+{-@ inv :: RBTree a -> {v:RBTree a | Invs v}        @-}
+inv Leaf           = Leaf
+inv (Node c x l r) = Node c x (inv l) (inv r)
diff --git a/docs/slides/BOS14/hs/long/SoCalledHeartBleed.hs b/docs/slides/BOS14/hs/long/SoCalledHeartBleed.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/long/SoCalledHeartBleed.hs
@@ -0,0 +1,24 @@
+module HeartBleed where
+
+import Data.ByteString.Char8  (pack, unpack) 
+import Data.ByteString.Unsafe (unsafeTake)
+
+heartBleed s n = s'
+  where 
+    b          = pack s         
+    b'         = unsafeTake n b
+    s'         = unpack b'
+
+-- > let ex = "Ranjit Loves Burritos"
+    
+-- > heartBleed ex 1
+--   "R"
+    
+-- > heartBleed ex 6
+-- > "Ranjit"
+
+-- > heartBleed ex 10
+-- > "Ranjit Lov"
+    
+-- > heartBleed ex 30
+-- > "Ranjit Loves Burritos\NUL\NUL\NUL\201\&1j\DC3\SOH\NUL"
diff --git a/docs/slides/BOS14/hs/start/000_Refinements.hs b/docs/slides/BOS14/hs/start/000_Refinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/000_Refinements.hs
@@ -0,0 +1,109 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module Refinements where
+
+import Prelude hiding (abs)
+
+divide    :: Int -> Int -> Int
+
+
+-----------------------------------------------------------------------
+-- | 1. Simple Refinement Types
+-----------------------------------------------------------------------
+
+{-@ type Nat     = {v:Int | v >= 0} @-}
+{-@ type Pos     = {v:Int | v >  0} @-}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+
+
+{-@ six :: NonZero @-}
+six = 10 :: Int
+
+
+
+-----------------------------------------------------------------------
+-- | 2. Function Contracts: Preconditions & Dead Code 
+-----------------------------------------------------------------------
+
+{-@ die :: {v:_ | false} -> a @-}
+die msg = error msg
+
+-- Precondition says, there are **NO** valid inputs for @die@.
+-- If program type-checks, means @die@ is **NEVER** called at run-time.
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 3. Function Contracts: Safe Division 
+-----------------------------------------------------------------------
+
+divide x 0 = undefined -- die "divide-by-zero"
+divide x n = x `div` n
+
+
+
+-- | What's the problem above? Nothing to *prevent*
+--   us from calling `divide` with 0. Oops.
+--   How shall we fix it?
+
+
+
+
+
+
+
+avg2 x y   = divide (x + y)     2
+avg3 x y z = divide (x + y + z) 3
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | But whats the problem here?
+-----------------------------------------------------------------------
+
+avg xs     = divide total n 
+  where
+    total  = sum xs
+    n      = length xs
+
+
+
+-- | Try to fix the above using `abs`olute values?
+
+abs :: Int -> Int
+abs x | x > 0     = x
+      | otherwise = 0 - x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------
+-- | CHEAT AREA ----------------------------------------------
+--------------------------------------------------------------
+
+-- # START Errors 0
+-- # END   Errors 1 (avg)
+
+{- abs    :: x:Int -> {v:Nat | x <= v} @-}
+{- divide :: Int -> NonZero -> Int     @-}
diff --git a/docs/slides/BOS14/hs/start/001_Refinements.hs b/docs/slides/BOS14/hs/start/001_Refinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/001_Refinements.hs
@@ -0,0 +1,107 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module Refinements where
+
+import Prelude hiding (map, foldr, foldr1)
+
+divide    :: Int -> Int -> Int
+wtAverage :: List (Int, Int) -> Int
+
+-----------------------------------------------------------------------
+-- | Our first Data Type
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+-----------------------------------------------------------------------
+-- | A few Higher-Order Functions
+-----------------------------------------------------------------------
+
+map                  :: (a -> b) -> List a -> List b
+map f N              = N
+map f (C x xs)       = C (f x) (map f xs) 
+
+
+foldr                :: (a -> b -> b) -> b -> List a -> b 
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+
+
+-- Uh oh. How shall we fix the error? Lets move on for now...
+
+foldr1           :: (a -> a -> a) -> List a -> a   
+foldr1 f (C x xs)    = foldr f x xs
+foldr1 f N           = die "foldr1"
+
+
+-----------------------------------------------------------------------
+-- | 6. Weighted-Averages 
+-----------------------------------------------------------------------
+
+-- Yikes, a divide-by-zero. How shall we fix it?
+
+wtAverage wxs = total `divide` weights
+  where
+    total     = sum $ map (\(w, x) -> w * x) wxs
+    weights   = sum $ map (\(w, _) -> w    ) wxs
+    sum       = foldr1 (+)
+
+
+-- | Exercise: How would you modify the types to get output `Pos` above? 
+
+
+ 
+-----------------------------------------------------------------------
+-- | Measuring the Size of Data
+-----------------------------------------------------------------------
+
+{-@ measure size @-}
+size          :: List a -> Int
+size (C x xs) = 1 + size xs 
+size N        = 0
+
+
+append N        ys = ys
+append (C x xs) ys = C x (append xs ys)
+
+
+-----------------------------------------------------------------------
+-- | But there are limitations: why does this not work? ...
+-----------------------------------------------------------------------
+
+{-@ append' :: xs:_ -> ys:_ -> {v: _ | size v = size xs + size ys} @-}
+append' xs ys =  foldr C ys  xs
+
+
+
+
+-----------------------------------------------------------------------
+-- | Definitions from 000_Refinements.hs
+-----------------------------------------------------------------------
+
+{-@ type Nat     = {v:Int | v >= 0} @-}
+{-@ type Pos     = {v:Int | v >  0} @-}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+
+{-@ die :: {v:_ | false} -> a @-}
+die msg = error msg
+
+{-@ divide :: Int -> NonZero -> Int @-}
+divide x 0 = die "divide-by-zero"
+divide x n = x `div` n
+
+-----------------------------------------------------------------------
+-- | CHEAT AREA 
+-----------------------------------------------------------------------
+
+-- # START-ERRORS 3 (foldr1, wtAverage, append')
+-- # END-ERRORS   1 (append')
+
+{- map    :: _ -> xs:_ -> {v:_ | size v = size xs}               @-}
+{- append :: xs:_ -> ys:_ -> {v: _ | size v = size ys + size xs} @-}
+{- foldr1 :: (a -> a -> a) -> {v:List a | size v > 0} -> a       @-}   
+{- wtAverage :: {v : List (Pos, Pos) | size v > 0} -> Int        @-}
diff --git a/docs/slides/BOS14/hs/start/01_Elements.hs b/docs/slides/BOS14/hs/start/01_Elements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/01_Elements.hs
@@ -0,0 +1,108 @@
+module Elems where
+
+import Prelude hiding (elem)
+
+import Data.Set (Set (..))
+
+
+-----------------------------------------------------------------------------
+-- | 1. Reasoning about the Set of Elements in a List ----------------------- 
+-----------------------------------------------------------------------------
+
+-- | The set of `elems` of a list
+
+
+
+
+
+{-@ measure elems :: [a] -> (Set a)
+    elems ([])    = (Set_empty 0)
+    elems (x:xs)  = (Set_cup (Set_sng x) (elems xs))
+  @-}
+
+
+
+
+-- | A few handy aliases
+
+{-@ predicate EqElts Xs Ys    = elems Xs = elems Ys                      @-}
+{-@ predicate UnElts Xs Ys Zs = elems Xs = Set_cup (elems Ys) (elems Zs) @-}
+
+-- | Reasoning about `append` and `reverse`
+
+{-@ append  :: xs:_ -> ys:_ -> {v:_ | UnElts v xs ys} @-}  
+append [] ys     = ys
+append (x:xs) ys = x : append xs ys 
+
+
+{-@ reverse :: xs:_ -> {v:_ | EqElts v xs} @-}
+reverse xs           = revAcc xs []
+  where 
+   revAcc []     acc = acc
+   revAcc (x:xs) acc = revAcc xs (x:acc)
+
+
+
+-- But, there are limitations...
+   
+{-@ append'  :: xs:_ -> ys:_ -> {v:_ | UnElts v xs ys} @-}  
+append' xs ys = foldr (:) ys xs
+
+
+-----------------------------------------------------------------------------
+-- | 2. Checking for duplicates (xmonad) ------------------------------------ 
+-----------------------------------------------------------------------------
+
+-- | Is a list free of duplicates?
+   
+{-@ measure nodups :: [a] -> Prop
+    nodups ([])   = true
+    nodups (x:xs) = (not (Set_mem x (elems xs)) && nodups xs)
+  @-}
+
+-- | Weeding out duplicates.
+   
+{-@ nub :: xs:_ -> {v:_ | nodups v && EqElts v xs} @-}
+nub xs             = go xs []
+  where
+    go (x:xs) l
+      | x `elem` l = go xs l     
+      | otherwise  = go xs (x:l) 
+    go [] l        = l
+
+
+{-@ elem :: x:_ -> ys:_ -> {v:Bool | Prop v <=> Set_mem x (elems ys)} @-}
+elem x []     = False
+elem x (y:ys) = x == y || elem x ys
+
+-----------------------------------------------------------------------------
+-- | 3. Associative Lookups ------------------------------------------------- 
+-----------------------------------------------------------------------------
+
+-- The dread "key-not-found". How can we fix it?
+find key ((k,v) : kvs)
+  | key == k  = v
+  | otherwise = find key kvs
+find _ []     = die "Key not found! Lookup failed!"
+
+
+{-@ die :: {v:_ | false} -> b @-}
+die x = error x
+
+
+----------------------------------------------------------------------------
+-- | CHEAT AREA ------------------------------------------------------------
+----------------------------------------------------------------------------
+
+{-@ predicate ValidKey K M    = Set_mem K (keys M)  @-}
+
+{-@ measure keys  :: [(a, b)] -> (Set a)
+    keys ([])     = (Set_empty 0)
+    keys (kv:kvs) = (Set_cup (Set_sng (fst kv)) (keys kvs))
+  @-}
+
+-- # START ERRORS 2 (find, append')
+-- # END   ERRORS 1 (append')
+
+{-@ find :: k:_ -> {m:_ | ValidKey k m} -> _ @-}
+
diff --git a/docs/slides/BOS14/hs/start/02_AbstractRefinements.hs b/docs/slides/BOS14/hs/start/02_AbstractRefinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/02_AbstractRefinements.hs
@@ -0,0 +1,252 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module AbstractRefinements (
+    listMax
+  , insertSort
+  , insertSort'
+  , insertSort''
+  ) where
+
+import Data.Set hiding (insert, foldr,size,filter, append) 
+import Prelude hiding (map, foldr, filter, append)
+
+listMax     :: [Int] -> Int
+
+
+
+-----------------------------------------------------------------------
+-- | #1. Abstract Refinements 
+-----------------------------------------------------------------------
+
+{-@ listMax :: forall <p :: Int -> Prop>. {v:[Int<p>] | len v > 0} -> Int<p> @-} 
+listMax xs  = foldr1 max xs 
+
+
+-- Lets define a few different subsets of Int
+
+{-@ type Even = {v:Int | v mod 2 == 0}      @-}
+{-@ type Odd  = {v:Int | v mod 2 /= 0}      @-}
+{-@ type RGB  = {v:Int | 0 <= v && v < 256} @-}
+
+
+{-@ xE :: Even @-}
+xE = listMax [0, 200, 4000, 60] 
+
+
+{-@ xO :: Odd @-}
+xO = listMax [1, 21, 4001, 961] 
+
+
+{-@ xR :: RGB @-}
+xR = listMax [1, 21, 41, 61] 
+
+
+
+
+
+
+
+-- > RJ: Return to slides for 06_Inductive
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | #2. Induction, as an Abstract Refinement 
+-----------------------------------------------------------------------
+
+
+{-@ ifoldr :: forall a b <p :: List a -> b -> Prop>. 
+                 (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
+               -> b<p N> 
+               -> ys:List a
+               -> b<p ys>                            @-}
+ifoldr :: (List a -> a -> b -> b) -> b -> List a -> b
+ifoldr f b N        = b
+ifoldr f b (C x xs) = f xs x (ifoldr f b xs)
+
+
+
+
+
+
+
+
+{-@ append :: xs:List a -> ys:List a -> {v:List a | UnElems v xs ys} @-} 
+append xs ys = ifoldr (\_ -> C) ys xs 
+
+
+
+
+
+
+
+{-@ filter :: (a -> Bool) -> xs:List a -> {v:List a | SubElems v xs } @-} 
+filter f xs = ifoldr (id (\_ x ys -> if f x then C x ys else ys)) N xs
+
+
+
+
+
+
+-- > RJ: Return to slides for 08_Recursive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | #3. Abstract Refinement from List's Type 
+-----------------------------------------------------------------------
+
+
+{-@ data List a <p :: a -> a -> Prop> 
+     = N | C {hd :: a, tl :: List<p> (a<p hd>) } @-}
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | #4. Instantiating Abstract Refinements on Lists 
+-----------------------------------------------------------------------
+
+
+{-@ type IncrList a = List <{\x y -> x <= y}> a @-} 
+{-@ type DecrList a = List <{\x y -> x >= y}> a @-} 
+{-@ type DiffList a = List <{\x y -> x /= y}> a @-} 
+
+{-@ ups   :: IncrList Integer @-}
+ups       = 1 `C` 2 `C` 4 `C` N
+
+{-@ downs :: DecrList Integer @-}
+downs     = 100 `C` 20 `C` 4 `C` N
+
+{-@ diffs :: DiffList Integer @-}
+diffs     = 100 `C` 1000 `C` 10 `C` 1 `C`  N
+
+-----------------------------------------------------------------------
+-- | 5. Insertion Sort
+-----------------------------------------------------------------------
+
+{-@ insert         :: x:a -> xs:IncrList a -> {v:IncrList a | AddElt v x xs && size v = 1 + size xs} @-}
+insert x N         = x `C` N
+insert x (C y ys)
+  | x < y          = x `C` y `C` ys
+  | otherwise      = y `C` insert x ys 
+
+{-@ insertSort      :: xs:List a -> IncrList a @-}
+insertSort N        = N
+insertSort (C x xs) = insert x (insertSort xs)
+
+-----------------------------------------------------------------------
+-- | 6. Insertion Sort: using a `foldr` 
+-----------------------------------------------------------------------
+
+{-@ insertSort' :: xs:List a -> IncrList a @-}
+insertSort' xs = foldr insert N xs
+
+
+
+
+
+
+
+-- Or even better... we can use `ifoldr`
+
+{-@ insertSort'' :: xs:List a -> {v:IncrList a | EqSize v xs && EqElem v xs} @-}
+insertSort'' xs = ifoldr (\_ -> insert) N xs
+
+
+
+
+
+
+
+
+-- > RJ: Return to slides for "07_Array"
+
+
+
+
+
+
+              
+-----------------------------------------------------------------------
+-- | Boilerplate definitions from 00_Refinements.hs
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+{-@ measure size @-}
+size          :: List a -> Int
+size (C x xs) = 1 + size xs 
+size N        = 0
+
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+
+{-@ predicate EqSize X Y    = size X  = size Y                         @-}
+{-@ predicate EqElem X Y    = elems X = elems Y                        @-}
+{-@ predicate UnElems X Y Z = elems X = Set_cup (elems Y) (elems Z)    @-}
+{-@ predicate SubElems X Y  = Set_sub (elems X) (elems Y)              @-}
+{-@ predicate AddElt V X Xs = elems V = Set_cup (Set_sng X) (elems Xs) @-}
+
+{-@ measure elems ::List a -> (Set a)
+    elems (N)      = (Set_empty 0)
+    elems (C x xs) = (Set_cup (Set_sng x) (elems xs))
+  @-}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{-@ predicate SubConsElems X Y Ys = Set_sub (elems X) (Set_cup (Set_sng Y) (elems Ys)) @-}
+
+{-@ qual1  :: y:_ -> ys:_ -> {v:_ | SubConsElems v y ys} @-}
+qual1 :: a -> List a -> List a 
+qual1 y ys = undefined 
+
+{-@ qual2  :: y:_ -> ys:_ -> {v:_ | size v <= 1 + size ys} @-}
+qual2 :: a -> List a -> List a 
+qual2 y ys = undefined 
+
+
+
diff --git a/docs/slides/BOS14/hs/start/03_Termination.hs b/docs/slides/BOS14/hs/start/03_Termination.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/03_Termination.hs
@@ -0,0 +1,177 @@
+module Termination where
+
+import Prelude hiding (gcd, mod, map, repeat, take)
+import Language.Haskell.Liquid.Prelude
+
+fac   :: Int -> Int
+
+-------------------------------------------------------------------------
+-- | Simple Termination
+-------------------------------------------------------------------------
+
+{-@ fac :: Nat -> Nat @-}
+fac 0 = 1
+fac 1 = 1
+fac n = n * fac (n-1)
+
+
+
+
+-------------------------------------------------------------------------
+-- | Semantic Termination
+-------------------------------------------------------------------------
+
+gcd :: Int -> Int -> Int
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+
+
+mod :: Int -> Int -> Int
+mod a b | a - b >  b = mod (a - b) b
+        | a - b <  b = a - b
+        | a - b == b = 0
+
+-------------------------------------------------------------------------
+-- | Explicit Metrics #1 
+-------------------------------------------------------------------------
+
+tfac       :: Int -> Int -> Int
+tfac acc 0 = acc
+tfac acc n = tfac (n * acc) (n-1)
+
+
+
+
+-------------------------------------------------------------------------
+-- Explicit Metrics #2 
+-------------------------------------------------------------------------
+
+range :: Int -> Int -> [Int]
+range lo hi
+  | lo < hi   = lo : range (lo + 1) hi
+  | otherwise = []
+
+
+
+-------------------------------------------------------------------------
+-- | Structural Recursion 
+-------------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+{-@ measure size @-}
+size          :: List a -> Int 
+size (C x xs) = 1 + size xs
+size (N)      = 0
+
+
+map            :: (a -> b) -> List a -> List b
+map _ N        = N
+map f (C x xs) = f x `C` map f xs
+
+
+
+-------------------------------------------------------------------------
+-- | Default Metrics
+-------------------------------------------------------------------------
+
+map'            :: (a -> b) -> List a -> List b
+map' _ N        = N
+map' f (C x xs) = f x `C` map' f xs
+
+
+
+
+
+
+-------------------------------------------------------------------------
+-- | Termination Expressions Metrics
+-------------------------------------------------------------------------
+
+merge          :: (Ord a) => List a -> List a -> List a
+
+merge (C x xs) (C y ys)
+  | x < y      = x `C` merge xs (y `C` ys)
+  | otherwise  = y `C` merge (x `C` xs) ys
+merge _   ys   = ys
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------------
+-- | CHEAT AREA ----------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- # START ERRORS 8
+-- # END ERRORS   0
+
+{- gcd   :: a:Nat -> b:{v:Nat | v < a} -> Int @-}
+{- mod   :: a:Nat -> b:{v:Nat| 0 < v && v < a} -> {v:Nat | v < b} @-}
+{- tfac  :: Nat -> n:Nat -> Nat / [n] @-}
+{- range :: lo:Nat -> hi:Nat -> [Nat] / [hi-lo] @-}
+{- map   :: (a -> b) -> xs:List a -> (List b) / [size xs] @-}
+{- merge :: xs:_ -> ys:_ -> _ / [size xs + size ys] @-}
+{- data List [size] a = N | C {x :: a, xs :: List a } @-}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------------
+-- | BOILERPLATE ---------------------------------------------------------------
+--------------------------------------------------------------------------------
+                 
+{-@ invariant {v : List a | 0 <= size v} @-}
+
diff --git a/docs/slides/BOS14/hs/start/04_Streams.hs b/docs/slides/BOS14/hs/start/04_Streams.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/04_Streams.hs
@@ -0,0 +1,108 @@
+module Streams where
+
+import Prelude hiding (take, repeat)
+
+import Language.Haskell.Liquid.Prelude
+
+-------------------------------------------------------------------------
+-- | Lists 
+-------------------------------------------------------------------------
+ 
+data List a = N | C { x :: a, xs :: List a }
+
+-- | Associate an abstract refinement with the _tail_ xs
+
+{-@ data List a <p :: List a -> Prop>
+      = N | C { x  :: a
+              , xs :: List <p> a <<p>>
+              }
+  @-}
+
+-------------------------------------------------------------------------
+-- | Infinite Streams
+-------------------------------------------------------------------------
+
+-- | Infinite List = List where _each_ tail is a `cons` ...
+
+{-@ type Stream a = {xs: List <{\v -> cons v}> a | cons xs} @-}
+
+-- | A simple measure for when a `List` is a `Cons`
+
+{-@ measure cons  :: (List a) -> Prop
+    cons (C x xs) = true 
+    cons (N)      = false 
+  @-}
+
+-------------------------------------------------------------------------
+-- | Creating an Infinite Stream
+-------------------------------------------------------------------------
+
+{-@ Lazy repeat @-}
+                 
+{-@ repeat :: a -> Stream a @-}
+repeat   :: a -> List a
+repeat x = x `C` repeat x
+
+
+-------------------------------------------------------------------------
+-- | Using an Infinite Stream
+-------------------------------------------------------------------------
+
+{-@ take        :: n:Nat -> Stream a -> {v:List a | size v = n} @-}
+take 0 _        = N
+take n (C x xs) = x `C` take (n-1) xs
+take _ N        = liquidError "never happens"
+
+-------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+-------------------------------------------------------------------------
+-- | BOILERPLATE from before ...
+-------------------------------------------------------------------------
+
+{-@ measure size :: List a -> Int 
+    size (N)      = 0
+    size (C x xs) = (1 + size xs)
+  @-}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------
+take            :: Int -> List a -> List a
+
+
+
+
+
+
+
+
+
diff --git a/docs/slides/BOS14/hs/start/05_Memory.hs b/docs/slides/BOS14/hs/start/05_Memory.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/05_Memory.hs
@@ -0,0 +1,391 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--diffcheck"     @-}
+
+module Memory where
+
+import Prelude hiding (null)
+import Data.Char
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
+import System.IO.Unsafe
+import Data.ByteString.Internal (c2w, w2c)
+import Language.Haskell.Liquid.Prelude
+
+
+------------------------------------------------------------------------
+-- | 1. Low-level Pointer API  -----------------------------------------
+------------------------------------------------------------------------
+
+-- | Create a buffer of size 4 and initialize it with zeros
+
+zero4  = do fp <- mallocForeignPtrBytes 4
+            withForeignPtr fp $ \p -> do
+              poke (p `plusPtr` 0) zero 
+              poke (p `plusPtr` 1) zero 
+              poke (p `plusPtr` 2) zero 
+              poke (p `plusPtr` 3) zero 
+            return fp
+        where
+            zero = 0 :: Word8
+
+-- But whats to prevent an overflow, e.g. writing to offset 5 or 50?
+            
+
+
+-- | Types for Pointers
+
+-- data Ptr a         
+-- data ForeignPtr a 
+
+-- | Size of Ptr and ForeignPtr
+
+-- measure plen  :: Ptr a -> Int 
+-- measure fplen :: ForeignPtr a -> Int 
+
+
+{-@ type PtrN a N        = {v:Ptr a        |  plen v  = N}  @-}
+{-@ type ForeignPtrN a N = {v:ForeignPtr a |  fplen v = N}  @-}
+
+-- | Allocating Memory
+
+{-@ assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignPtrN a n) @-}
+
+-- | Using a pointer
+
+{- withForeignPtr :: fp:ForeignPtr a 
+                  -> (PtrN a (fplen fp) -> IO b)  
+                  -> IO b             
+-}
+
+-- | Pointer Arithmetic
+
+{- plusPtr :: p:Ptr a
+           -> o:{Nat|o <= plen p}   -- in bounds
+           -> PtrN b (plen b - o)   -- remainder
+-}
+
+-- | Read and Write
+
+{- peek :: {v:Ptr a | 0 < plen v} -> IO a  
+   poke :: {v:Ptr a | 0 < plen v} -> a -> IO ()  
+ -}
+
+-- | Example: Preventing Overflows e.g. writing 5 or 50 zeros?
+
+zero4' = do fp <- mallocForeignPtrBytes 4
+            withForeignPtr fp $ \p -> do
+              poke (p `plusPtr` 0) zero 
+              poke (p `plusPtr` 1) zero 
+              poke (p `plusPtr` 2) zero 
+              poke (p `plusPtr` 5) zero 
+            return fp
+        where
+            zero = 0 :: Word8
+
+
+
+------------------------------------------------------------------------
+-- | 2. ByteString API -------------------------------------------------
+------------------------------------------------------------------------
+
+data ByteString = PS {
+    bPtr :: ForeignPtr Word8
+  , bOff :: !Int
+  , bLen :: !Int
+  }
+
+
+-- | Refined Type, with invariants
+
+{-@ data ByteString = PS {
+      bPtr :: ForeignPtr Word8
+    , bOff :: {v:Nat| v        <= fplen bPtr}
+    , bLen :: {v:Nat| v + bOff <= fplen bPtr}
+    }
+
+  @-}
+
+-- | Some useful abbreviations
+
+{-@ type ByteStringN N = {v:ByteString | bLen v = N} @-}
+{-@ type StringN N     = {v:String     | len v  = N} @-}
+
+-- | Legal Bytestrings 
+
+{-@ good1 :: IO (ByteStringN 5) @-}
+good1 = do fp <- mallocForeignPtrBytes 5
+           return $ PS fp 0 5
+
+{-@ good2 :: IO (ByteStringN 3) @-}
+good2 = do fp <- mallocForeignPtrBytes 5
+           return $ PS fp 2 3
+
+-- | Illegal Bytestrings 
+
+bad1 = do fp <- mallocForeignPtrBytes 3 
+          return $ PS fp 0 10 
+
+bad2 = do fp <- mallocForeignPtrBytes 3
+          return $ PS fp 2 2
+
+
+
+-- | ByteString API: `create`
+
+create :: Int -> (Ptr Word8 -> IO ()) -> ByteString
+
+create n fill = unsafePerformIO $ do
+  fp  <- mallocForeignPtrBytes n
+  withForeignPtr fp fill 
+  return $! PS fp 0 n
+
+
+-- Yikes, there is an error! How to fix?
+
+-- | ByteStringN API: `unsafeTake`
+
+unsafeTake n (PS x s l) = PS x s n
+
+-- Wow, thats super fast. O(1)! But how to fix the error?
+
+-- | ByteString API: `pack`
+
+pack          :: String -> ByteString
+pack str      = create n $ \p -> go p xs
+  where
+  n           = length str
+  xs          = map c2w str
+  go p (x:xs) = poke p x >> go (plusPtr p 1) xs
+  go _ []     = return  ()
+
+-- Hmm. How to fix the error?
+
+
+
+-- | ByteString API: `unpack` 
+
+
+
+{-@ qualif Unpack(v:a, acc:b, n:int) : len v = 1 + n + len acc @-}
+
+unpack :: ByteString -> String 
+unpack (PS _  _ 0)  = []
+unpack (PS ps s l)  = unsafePerformIO $ withForeignPtr ps $ \p ->
+   go (p `plusPtr` s) (l - 1)  []
+  where
+   go p 0 acc = peek p >>= \e -> return (w2c e : acc)
+   go p n acc = peek (p `plusPtr` n) >>= \e -> go p (n-1) (w2c e : acc)
+
+
+
+------------------------------------------------------------------------
+-- | 3. Application API (Heartbleed no more!) --------------------------
+------------------------------------------------------------------------
+
+chop     :: String -> Int -> String 
+chop s n =  s'
+  where 
+    b    = pack s          -- down to low-level
+    b'   = unsafeTake n b  -- grab n chars
+    s'   = unpack b'       -- up to high-level
+
+-- Whats the problem?
+
+
+
+
+
+-- | "HeartBleed" no more
+
+demo     = [ex6, ex30]
+  where
+    ex   = ['R','a','n','j','i','t']
+    ex6  = chop ex 6  -- ok
+    ex30 = chop ex 30 -- out of bounds
+
+
+-- "Bleeding" `chop ex 30` *rejected* by compiler
+
+
+
+------------------------------------------------------------------------
+-- | 3. Bonus Material -------------------------------------------------
+------------------------------------------------------------------------
+
+-- | `group` ing ByteStrings 
+
+{- How shall we type `group` where
+
+     group "foobaaar"
+
+   returns
+
+     ["f","oo", "b", "aaa", "r"]
+
+-}
+
+-- | An alias for NON-EMPTY ByteStrings
+    
+{-@ type ByteStringNE = {v:ByteString | bLen v > 0} @-}
+
+-- | A measure for the sum of sizes of a LIST of ByteStrings
+    
+{-@ measure bLens  :: [ByteString] -> Int
+    bLens ([])   = 0
+    bLens (x:xs) = (bLen x + bLens xs)
+  @-}
+
+-- | @group@
+    
+{-@ group :: b:ByteString -> {v: [ByteStringNE] | bLens v = bLen b} @-}
+group xs
+    | null xs   = []
+    | otherwise = let y = unsafeHead xs
+                      (ys, zs) = spanByte (unsafeHead xs) (unsafeTail xs)
+                  in (y `cons` ys) : group zs
+
+
+-- | @spanByte@ does the heavy lifting
+
+{-@ spanByte :: Word8 -> b:ByteString -> (ByteStringPair b) @-}
+spanByte :: Word8 -> ByteString -> (ByteString, ByteString)
+spanByte c ps@(PS x s l) = unsafePerformIO $ withForeignPtr x $ \p ->
+    go (p `plusPtr` s) 0
+  where
+    go p i | i >= l    = return (ps, empty)
+           | otherwise = do c' <- peekByteOff p i
+                            if c /= c'
+                                then return (unsafeTake i ps, unsafeDrop i ps)
+                                else go p (i+1)
+
+-- | Using the alias
+                            
+{-@ type ByteStringPair B = (ByteString, ByteString)<{\x1 x2 ->
+       bLen x1 + bLen x2 = bLen B}> @-}
+
+
+
+
+
+
+
+
+
+
+
+----------------------------------------------------------------------------
+-- | CHEAT AREA
+----------------------------------------------------------------------------
+
+-- #START ERRORS 13
+-- #END   ERRORS 4 (zero4', bad1, bad2, ex30) 
+                            
+{- create     :: n:Nat -> (PtrN Word8 n -> IO ()) -> ByteStringN n      @-}
+{- unsafeTake :: n:Nat -> b:{ByteString | n <= bLen b} -> ByteStringN n @-}
+{- pack       :: s:String -> ByteStringN (len s)                        @-}
+{- unpack     :: b:ByteString -> {v:String | len v = bLen b}            @-}
+{- chop       :: s:String -> n:{Nat | n <= len s} -> StringN n          @-} 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | Helper Code (Stuff from BS benchmark, to make demo self-contained)
+-----------------------------------------------------------------------
+
+{-@ unsafeCreate :: l:Nat -> ((PtrN Word8 l) -> IO ()) -> (ByteStringN l) @-}
+unsafeCreate n f = create n f -- unsafePerformIO $ create n f
+
+{-@ invariant {v:ByteString   | bLen  v >= 0} @-}
+{-@ invariant {v:[ByteString] | bLens v >= 0} @-}
+
+{-@ qualif PLLen(v:a, p:b) : (len v) <= (plen p) @-}
+{-@ qualif ForeignPtrN(v:ForeignPtr a, n:int): fplen v = n @-}
+{-@ qualif FPLenPLen(v:Ptr a, fp:ForeignPtr a): fplen fp = plen v @-}
+{-@ qualif PtrLen(v:Ptr a, xs:List b): plen v = len xs @-}
+{-@ qualif PlenEq(v: Ptr a, x: int): x <= (plen v) @-}
+
+{-@ unsafeHead :: {v:ByteString | (bLen v) > 0} -> Word8 @-}
+
+unsafeHead :: ByteString -> Word8
+unsafeHead (PS x s l) = liquidAssert (l > 0) $
+  unsafePerformIO  $  withForeignPtr x $ \p -> peekByteOff p s
+
+{-@ unsafeTail :: b:{v:ByteString | (bLen v) > 0}
+               -> {v:ByteString | (bLen v) = (bLen b) - 1} @-}
+unsafeTail :: ByteString -> ByteString
+unsafeTail (PS ps s l) = liquidAssert (l > 0) $ PS ps (s+1) (l-1)
+
+{-@ null :: b:ByteString -> {v:Bool | ((Prop v) <=> ((bLen b) = 0))} @-}
+null :: ByteString -> Bool
+null (PS _ _ l) = liquidAssert (l >= 0) $ l <= 0
+
+{-@ unsafeDrop :: n:Nat
+               -> b:{v: ByteString | n <= (bLen v)} 
+               -> {v:ByteString | (bLen v) = (bLen b) - n} @-}
+unsafeDrop  :: Int -> ByteString -> ByteString
+unsafeDrop n (PS x s l) = liquidAssert (0 <= n && n <= l) $ PS x (s+n) (l-n)
+
+{-@ cons :: Word8 -> b:ByteString -> {v:ByteString | (bLen v) = 1 + (bLen b)} @-}
+cons :: Word8 -> ByteString -> ByteString
+cons c (PS x s l) = unsafeCreate (l+1) $ \p -> withForeignPtr x $ \f -> do
+        poke p c
+        memcpy (p `plusPtr` 1) (f `plusPtr` s) (fromIntegral l)
+
+{-@ empty :: {v:ByteString | (bLen v) = 0} @-} 
+empty :: ByteString
+empty = PS nullForeignPtr 0 0
+
+{-@ assume
+    c_memcpy :: dst:(PtrV Word8)
+             -> src:(PtrV Word8) 
+             -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))} 
+             -> IO (Ptr Word8)
+  @-}
+foreign import ccall unsafe "string.h memcpy" c_memcpy
+    :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)
+
+{-@ memcpy :: dst:(PtrV Word8)
+           -> src:(PtrV Word8) 
+           -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))} 
+           -> IO () 
+  @-}
+memcpy :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()
+memcpy p q s = c_memcpy p q s >> return ()
+
+{-@ assume nullForeignPtr :: {v: ForeignPtr Word8 | (fplen v) = 0} @-}
+nullForeignPtr :: ForeignPtr Word8
+nullForeignPtr = unsafePerformIO $ newForeignPtr_ nullPtr
+{-# NOINLINE nullForeignPtr #-}
+
+
+
diff --git a/docs/slides/BOS14/hs/start/06_Eval-done.hs b/docs/slides/BOS14/hs/start/06_Eval-done.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/06_Eval-done.hs
@@ -0,0 +1,83 @@
+{-@ LIQUID "--no-termination" @-}
+
+module Eval (eval) where
+
+import Language.Haskell.Liquid.Prelude (liquidError)
+import Prelude hiding (lookup)
+import Data.Set (Set (..))
+
+lookup :: Bndr -> Env Expr -> Expr 
+
+-------------------------------------------------------------------
+-- | Binders, Expressions, Environments
+-------------------------------------------------------------------
+
+type Bndr = String 
+
+data Expr = Const Int
+          | Var   Bndr
+          | Plus  Expr Expr
+          | Let   Bndr Expr Expr
+
+type Env a = [(Bndr, a)]
+
+-------------------------------------------------------------------
+-- | Values
+-------------------------------------------------------------------
+
+-------------------------------------------------------------------
+{-@ lookup :: x:Bndr -> {v:Env Val | Set_mem x (vars v)} -> Val @-}
+-------------------------------------------------------------------
+lookup x ((y,v):env)   
+  | x == y             = v
+  | otherwise          = lookup x env
+lookup x []            = die "Unbound Variable"
+
+-------------------------------------------------------------------
+{-@ eval :: g:Env Val -> ClosedExpr g -> Val @-}
+-------------------------------------------------------------------
+eval env i@(Const _)   = i
+eval env (Var x)       = lookup x env 
+eval env (Plus e1 e2)  = plus (eval env e1) (eval env e2) 
+eval env (Let x e1 e2) = eval env' e2 
+  where 
+    env'               = (x, eval env e1) : env
+
+plus (Const i) (Const j) = Const (i+j)
+plus _         _         = die "Bad call to plus"
+
+
+{-@ die :: {v:_ | false} -> a @-}
+die x   = error x
+
+
+
+
+
+
+
+
+
+{-@ type Val           = {v:Expr | val v} @-}
+
+{-@ type ClosedExpr G  = {v:Expr | Set_sub (free v) (vars G)} @-}
+
+{-@ measure vars :: Env a -> (Set Bndr)
+    vars ([])    = (Set_empty 0)
+    vars (b:env) = (Set_cup (Set_sng (fst b)) (vars env))
+  @-}
+
+{-@ measure free       :: Expr -> (Set Bndr) 
+    free (Const i)     = (Set_empty 0)
+    free (Var x)       = (Set_sng x) 
+    free (Plus e1 e2)  = (Set_cup (free e1) (free e2))
+    free (Let x e1 e2) = (Set_cup (free e1) (Set_dif (free e2) (Set_sng x)))
+  @-}
+
+{-@ measure val       :: Expr -> Prop
+    val (Const i)     = true
+    val (Var x)       = false
+    val (Plus e1 e2)  = false
+    val (Let x e1 e2) = false
+  @-}
+
diff --git a/docs/slides/BOS14/hs/start/06_Eval.hs b/docs/slides/BOS14/hs/start/06_Eval.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/hs/start/06_Eval.hs
@@ -0,0 +1,113 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+
+module Eval (eval) where
+
+import Language.Haskell.Liquid.Prelude (liquidError)
+import Prelude hiding (lookup)
+import Data.Set (Set (..))
+
+
+-------------------------------------------------------------------
+-- | Binders, Expressions, Environments
+-------------------------------------------------------------------
+
+type Bndr = String 
+
+data Expr = Const Int
+          | Var   Bndr
+          | Plus  Expr Expr
+          | Let   Bndr Expr Expr
+
+type Env a = [(Bndr, a)]
+
+-------------------------------------------------------------------
+eval :: Env Expr -> Expr -> Expr
+-------------------------------------------------------------------
+eval env i@(Const _)     = i
+eval env (Var x)         = lookup x env 
+eval env (Plus e1 e2)    = plus (eval env e1) (eval env e2) 
+eval env (Let x e1 e2)   = eval env' e2 
+  where 
+    env'                 = (x, eval env e1) : env
+
+-------------------------------------------------------------------
+plus :: Expr -> Expr -> Expr
+-------------------------------------------------------------------
+plus (Const i) (Const j) = Const (i+j)
+plus _         _         = die "Bad call to plus"
+
+
+-------------------------------------------------------------------
+lookup :: Bndr -> Env Expr -> Expr 
+-------------------------------------------------------------------
+lookup x ((y,v):env)   
+  | x == y             = v
+  | otherwise          = lookup x env
+lookup x []            = die "Unbound Variable"
+
+
+
+
+-------------------------------------------------------------------
+-- | Values
+-------------------------------------------------------------------
+
+-- Lets define `Value` as a refinement of `Expr`...
+
+
+
+-------------------------------------------------------------------
+-- | Closed Expressions
+-------------------------------------------------------------------
+
+-- Lets define `ClosedExpr` as a refinement of `Expr` ...
+
+
+
+-------------------------------------------------------------------
+-- | BOILERPLATE 
+-------------------------------------------------------------------
+
+{-@ die :: {v:_ | false} -> a @-}
+die x   = error x
+
+
+
+
+
+-------------------------------------------------------------------
+-- | CHEAT AREA ---------------------------------------------------
+-------------------------------------------------------------------
+
+{- lookup :: x:Bndr -> {v:Env Val | Set_mem x (vars v)} -> Val @-}
+
+{- eval :: g:Env Val -> ClosedExpr g -> Val @-}
+
+
+-- | Values
+
+{- type Val           = {v:Expr | val v} @-}
+
+{- measure val       :: Expr -> Prop
+    val (Const i)     = true
+    val (Var x)       = false
+    val (Plus e1 e2)  = false
+    val (Let x e1 e2) = false
+  @-}
+
+-- | Closed Expressions
+
+{- type ClosedExpr G  = {v:Expr | Set_sub (free v) (vars G)} @-}
+
+{- measure vars :: Env a -> (Set Bndr)
+    vars ([])    = (Set_empty 0)
+    vars (b:env) = (Set_cup (Set_sng (fst b)) (vars env))
+  @-}
+
+{- measure free       :: Expr -> (Set Bndr) 
+    free (Const i)     = (Set_empty 0)
+    free (Var x)       = (Set_sng x) 
+    free (Plus e1 e2)  = (Set_cup (free e1) (free e2))
+    free (Let x e1 e2) = (Set_cup (free e1) (Set_dif (free e2) (Set_sng x)))
+  @-}
diff --git a/docs/slides/BOS14/img/RedBlack.png b/docs/slides/BOS14/img/RedBlack.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/RedBlack.png differ
diff --git a/docs/slides/BOS14/img/RobertMorris.png b/docs/slides/BOS14/img/RobertMorris.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/RobertMorris.png differ
diff --git a/docs/slides/BOS14/img/bytestring.png b/docs/slides/BOS14/img/bytestring.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/bytestring.png differ
diff --git a/docs/slides/BOS14/img/code-spec-indiv.png b/docs/slides/BOS14/img/code-spec-indiv.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/code-spec-indiv.png differ
diff --git a/docs/slides/BOS14/img/code-spec-total.png b/docs/slides/BOS14/img/code-spec-total.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/code-spec-total.png differ
diff --git a/docs/slides/BOS14/img/firstbug-crop.jpg b/docs/slides/BOS14/img/firstbug-crop.jpg
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/firstbug-crop.jpg differ
diff --git a/docs/slides/BOS14/img/firstbug-crop2.jpg b/docs/slides/BOS14/img/firstbug-crop2.jpg
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/firstbug-crop2.jpg differ
diff --git a/docs/slides/BOS14/img/firstbug.jpg b/docs/slides/BOS14/img/firstbug.jpg
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/firstbug.jpg differ
diff --git a/docs/slides/BOS14/img/george-orwell.jpg b/docs/slides/BOS14/img/george-orwell.jpg
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/george-orwell.jpg differ
diff --git a/docs/slides/BOS14/img/gotofail.png b/docs/slides/BOS14/img/gotofail.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/gotofail.png differ
diff --git a/docs/slides/BOS14/img/heartbleed.png b/docs/slides/BOS14/img/heartbleed.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/heartbleed.png differ
diff --git a/docs/slides/BOS14/img/minindex-classic.png b/docs/slides/BOS14/img/minindex-classic.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/minindex-classic.png differ
diff --git a/docs/slides/BOS14/img/minindex-invariant.png b/docs/slides/BOS14/img/minindex-invariant.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/minindex-invariant.png differ
diff --git a/docs/slides/BOS14/img/minindex-modern.png b/docs/slides/BOS14/img/minindex-modern.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/minindex-modern.png differ
diff --git a/docs/slides/BOS14/img/minindex-reduce.png b/docs/slides/BOS14/img/minindex-reduce.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/minindex-reduce.png differ
diff --git a/docs/slides/BOS14/img/overflow.png b/docs/slides/BOS14/img/overflow.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/overflow.png differ
diff --git a/docs/slides/BOS14/img/rbtree-bad1.png b/docs/slides/BOS14/img/rbtree-bad1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/rbtree-bad1.png differ
diff --git a/docs/slides/BOS14/img/rbtree-bad2.png b/docs/slides/BOS14/img/rbtree-bad2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/rbtree-bad2.png differ
diff --git a/docs/slides/BOS14/img/rbtree-ok.png b/docs/slides/BOS14/img/rbtree-ok.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/rbtree-ok.png differ
diff --git a/docs/slides/BOS14/img/tension0.png b/docs/slides/BOS14/img/tension0.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/tension0.png differ
diff --git a/docs/slides/BOS14/img/tension1.png b/docs/slides/BOS14/img/tension1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/tension1.png differ
diff --git a/docs/slides/BOS14/img/tension2.png b/docs/slides/BOS14/img/tension2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/tension2.png differ
diff --git a/docs/slides/BOS14/img/tension3.png b/docs/slides/BOS14/img/tension3.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/tension3.png differ
diff --git a/docs/slides/BOS14/img/termination-results.png b/docs/slides/BOS14/img/termination-results.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/termination-results.png differ
diff --git a/docs/slides/BOS14/img/thoughtcrime.png b/docs/slides/BOS14/img/thoughtcrime.png
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/thoughtcrime.png differ
diff --git a/docs/slides/BOS14/img/ungood-small.jpg b/docs/slides/BOS14/img/ungood-small.jpg
new file mode 100644
Binary files /dev/null and b/docs/slides/BOS14/img/ungood-small.jpg differ
diff --git a/docs/slides/BOS14/lhs/00_Motivation.lhs b/docs/slides/BOS14/lhs/00_Motivation.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/00_Motivation.lhs
@@ -0,0 +1,233 @@
+Well-Typed Programs Can Go Wrong
+================================
+
+ {#asd}
+-------
+
+
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+Division By Zero
+----------------
+
+
+
+
+<div class="fragment"> 
+\begin{spec}
+λ> let average xs = sum xs `div` length xs
+
+λ> average [1,2,3]
+2
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment"> 
+\begin{spec}  
+λ> average []
+*** Exception: divide by zero
+\end{spec}
+
+</div>
+
+Missing Keys
+------------
+
+<div class="fragment"> 
+\begin{spec}  
+λ> :m +Data.Map 
+λ> let m = fromList [ ("haskell", "lazy")
+                    , ("pyret"  , "eager")]
+
+λ> m ! "haskell"
+"lazy"
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment"> 
+\begin{spec}
+λ> m ! "racket"
+"*** Exception: key is not in the map
+\end{spec}
+</div>
+
+Segmentation Faults
+-------------------
+
+<div class="fragment"> 
+\begin{spec}
+λ> :m +Data.Vector 
+λ> let v = fromList ["haskell", "pyret"]
+λ> unsafeIndex v 0
+"haskell"
+\end{spec}
+</div>
+
+<div class="fragment"> 
+<br>
+\begin{spec} 
+λ> V.unsafeIndex v 3
+
+
+'ghci' terminated by signal SIGSEGV ...
+\end{spec}
+</div>
+
+
+"HeartBleeds"
+-------------
+
+\begin{spec}
+λ> :m + Data.Text Data.Text.Unsafe 
+λ> let t = pack "Shriram"
+λ> takeWord16 5 t
+"Shrir"
+\end{spec}
+
+<br>
+
+<div class="fragment"> 
+Memory overflows **leaking secrets**...
+
+<br>
+
+\begin{spec}
+λ> takeWord16 20 t
+"Shriram\1912\3148\SOH\NUL\15928\2486\SOH\NUL"
+\end{spec}
+</div>
+
+Goal
+----
+
+Extend Type System
+
+<br>
+
++ To prevent *wider class* of errors
+
++ To enforce *program specific* properties 
+
+
+Algorithmic Verification
+========================
+
+
+Tension
+-------
+
+<img src="../img/tension0.png" height=300px>
+
+Automation vs. Expressiveness
+
+Tension
+-------
+
+<img src="../img/tension1.png" height=300px>
+
+Extremes: Hindley-Milner vs. CoC
+
+Tension
+-------
+
+<img src="../img/tension2.png" height=300px>
+
+Trading off Automation for Expressiveness
+
+Tension
+-------
+
+<img src="../img/tension3.png" height=300px>
+
+**Goal:** Find a sweet spot?
+
+<!-- BEGIN CUT
+
+Program Logics
+--------------
+
+<br>
+
+**Floyd-Hoare** (ESC, Dafny, SLAM/BLAST,...)
+
+<br>
+
++ **Properties:**   Assertions & Pre- and Post-conditions
+
++ **Proofs:**       Verification Conditions proved by SMT
+
++ **Inference:**    Abstract Interpretation
+
+<br>
+
+<div class="fragment"> Automatic but **not** Expressive </div>
+
+
+Program Logics
+--------------
+
+<br>
+
+**Floyd-Hoare** (ESC, Dafny, SLAM/BLAST,...)
+
+
+<br>
+
+Automatic but **not** Expressive
+
+<br>
+
++ Rich Data Types ?
+
++ Higher-order functions ?
+
++ Polymorphism ?
+
+
+Refinement Types
+----------------
+
+<br>
+
+Generalize *Program Logics* with *Types*
+
+<div class="fragment"> 
+<br>
+
++ **Properties:**  Types + Predicates
+
++ **Proofs:**      Subtyping + Verification Conditions
+
++ **Inference:**   Hindley-Milner + Abstract Interpretation
+
+</div>
+
+<div class="fragment"> 
+  <br>
+  Towards reconciling Automation and Expressiveness
+</div>
+
+END CUT -->
+
+Refinement Types
+----------------
+
+<br>
+<br>
+
+[[continue]](01_SimpleRefinements.lhs.slides.html)
+
+
+
diff --git a/docs/slides/BOS14/lhs/00_Motivation_Long.lhs b/docs/slides/BOS14/lhs/00_Motivation_Long.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/00_Motivation_Long.lhs
@@ -0,0 +1,377 @@
+
+ {#intro}
+=========
+
+ {#firstbug0}
+-------------
+
+<img src="../img/firstbug-crop.jpg" height=400px>
+
+The First *Bug* 
+---------------
+
+<img src="../img/firstbug-crop2.jpg" height=300px>
+
+**Page from Harvard Mark II log**
+
+A dead moth removed from the device
+
+<!-- BEGIN CUT
+
+Morris Worm (1988)
+------------------
+
+<img src="../img/RobertMorris.png" height=300px>
+
++ **Buffer overflow** in `fingerd`
+
++ "Breaks internet" for several days
+
++ Harmless internet probe gone berserk
+
+END CUT -->
+
+Slammer Worm (2003)
+-------------------
+
+<img src="../img/sapphire.gif" height=300px>
+
+**Buffer Overflow**
+
+Affected 90% of vulnerable machines in 10 mins
+
+Northeast Blackout (2003)
+-------------------------
+
+<img src="../img/blackout.gif" height=300px>
+
+**Race Condition**
+
+Cut power for 55 million, trigger: lines hitting foliage
+
+HeartBleed (2014)
+-----------------
+
+<img src="../img/heartbleed.png" height=300px>
+
+**Buffer Overflow**
+
+Compromises secret keys, passwords ...
+
+
+Goto Fail (2014)
+----------------
+
+<img src="../img/gotofail.png" height=300px>
+
+**Typo (?!)**
+
+Bypass critical check, compromise cryptography
+
+A Possible Solution
+===================
+
+ Modern Languages
+-----------------
+
+<div class="fragment">
+
+<img src="../img/george-orwell.jpg" height=250px>
+
+</div>
+
+<div class="fragment">
+
+<img src="../img/thoughtcrime.png" height=100px>
+
+</div>
+
+Modern Languages
+----------------
+
+<br>
+
+F#
+
+Rust
+
+Scala
+
+OCaml
+
+**Haskell**
+
+
+Modern Languages
+----------------
+
+<br>
+
+Static Typing
+
+<br>
+
+First-class Functions
+
+<br>
+
+Immutability by Default
+
+
+<br>
+
+<div class="fragment">
+
+Make **good** designs **easy** and **bad** designs **hard**
+
+</div>
+
+
+Modern Languages? 
+-------------------
+
+<br>
+
+Not so fast ...
+
+<br>
+
+<div class="fragment">
+
+Well-typed programs **can go wrong!**
+
+</div>
+
+
+Well-Typed Programs Can Go Wrong
+================================
+
+ {#asd}
+-------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+Division By Zero
+----------------
+
+
+
+
+<div class="fragment"> 
+\begin{spec}
+λ> let average xs = sum xs `div` length xs
+
+λ> average [1,2,3]
+2
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment"> 
+\begin{spec}  
+λ> average []
+*** Exception: divide by zero
+\end{spec}
+
+</div>
+
+Missing Keys
+------------
+
+<div class="fragment"> 
+\begin{spec}  
+λ> :m +Data.Map 
+λ> let m = fromList [ ("haskell", "lazy")
+                    , ("racket" , "eager")]
+
+λ> m ! "haskell"
+"lazy"
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment"> 
+\begin{spec}
+λ> m ! "javascript"
+"*** Exception: key is not in the map
+\end{spec}
+</div>
+
+Segmentation Faults
+-------------------
+
+<div class="fragment"> 
+\begin{spec}
+λ> :m +Data.Vector 
+λ> let v = fromList ["haskell", "racket"]
+λ> unsafeIndex v 0
+"haskell"
+\end{spec}
+</div>
+
+<div class="fragment"> 
+<br>
+\begin{spec} 
+λ> V.unsafeIndex v 3
+
+
+'ghci' terminated by signal SIGSEGV ...
+\end{spec}
+</div>
+
+
+"HeartBleeds"
+-------------
+
+\begin{spec}
+λ> :m + Data.Text Data.Text.Unsafe 
+λ> let t = pack "Norman"
+λ> takeWord16 4 t
+"Norm"
+\end{spec}
+
+<br>
+
+<div class="fragment"> 
+Memory overflows **leaking secrets**...
+
+<br>
+
+\begin{spec}
+λ> takeWord16 20 t
+"Norman\1912\3148\SOH\NUL\15928\2486\SOH\NUL"
+\end{spec}
+</div>
+
+Goal
+----
+
+<br>
+
+Extend Type System
+
+<br>
+
++ To prevent *wider class* of errors
+
++ To enforce *program specific* properties 
+
+<br>
+
+<div class="fragment">
+
+**Without sacrificing automation** 
+
+</div>
+
+Algorithmic Verification
+========================
+
+Tension
+-------
+
+<img src="../img/tension0.png" height=300px>
+
+Automation vs. Expressiveness
+
+Tension
+-------
+
+<img src="../img/tension1.png" height=300px>
+
+Extremes: Hindley-Milner vs. CoC
+
+Tension
+-------
+
+<img src="../img/tension2.png" height=300px>
+
+Trading off Automation for Expressiveness
+
+Tension
+-------
+
+<img src="../img/tension3.png" height=300px>
+
+**Goal:** Find a sweet spot?
+
+<!-- BEGIN CUT
+
+Program Logics
+--------------
+
+<br>
+
+**Floyd-Hoare** (ESC, Dafny, SLAM/BLAST,...)
+
+<br>
+
++ **Properties:**   Assertions & Pre- and Post-conditions
+
++ **Proofs:**       Verification Conditions proved by SMT
+
++ **Inference:**    Abstract Interpretation
+
+<br>
+
+<div class="fragment"> Automatic but **not** Expressive </div>
+
+END CUT -->
+
+Program Logics
+--------------
+
+<br>
+
+**Floyd-Hoare** (ESC, Dafny, SLAM/BLAST,...)
+
+
+<br>
+
+Automatic but **not** Expressive
+
+<br>
+
++ Rich Data Types ?
+
++ Higher-order functions ?
+
++ Polymorphism ?
+
+Refinement Types
+----------------
+
+<br>
+
+Generalize *Program Logics* with *Types*
+
+<br>
+
++ **Properties:**  Types + Predicates
+
++ **Proofs:**      Subtyping + SMT Solvers
+
+<!-- BEGIN CUT
++ **Inference:**   Hindley-Milner + Abstract Interpretation
+  -->
+
+<div class="fragment"> 
+  <br>
+  Towards reconciling Automation and Expressiveness
+</div>
+
+<br>
+
+<div class="fragment"> 
+[[continue]](01_SimpleRefinements.lhs.slides.html)
+</div>
+
diff --git a/docs/slides/BOS14/lhs/01_SimpleRefinements.lhs b/docs/slides/BOS14/lhs/01_SimpleRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/01_SimpleRefinements.lhs
@@ -0,0 +1,457 @@
+ {#simplerefinements}
+=======================
+
+Simple Refinement Types
+-----------------------
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+module SimpleRefinements where
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (abs, max)
+
+-- boring haskell type sigs
+zero    :: Int
+zero'   :: Int
+safeDiv :: Int -> Int -> Int
+abs     :: Int -> Int
+\end{code}
+
+</div>
+
+
+Simple Refinement Types
+=======================
+
+
+Types + Predicates 
+------------------
+
+
+Example: Integers equal to `0`
+------------------------------
+
+<br>
+
+\begin{code}
+{-@ type Zero = {v:Int | v = 0} @-}
+
+{-@ zero :: Zero @-}
+zero     =  0
+\end{code}
+
+<br>
+
+<div class="fragment">
+Refinement types via special comments `{-@ ... @-}` 
+
+<br>
+
+<div class="fragment">
+[DEMO](../hs/000_Refinements.hs)
+
+
+<!-- BEGIN CUT
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo</a> 
+-->
+
+</div>
+
+Refinements Are Predicates
+==========================
+
+From A Decidable Logic
+----------------------
+
+<br> 
+
+1. Expressions
+
+2. Predicates
+
+<br>
+
+<div class="fragment">
+
+**Refinement Logic: QF-UFLIA**
+
+Quant.-Free. Uninterpreted Functions and Linear Arithmetic 
+
+</div>
+
+
+Expressions
+-----------
+
+<br>
+
+\begin{spec} <div/> 
+e := x, y, z,...    -- variable
+   | 0, 1, 2,...    -- constant
+   | (e + e)        -- addition
+   | (e - e)        -- subtraction
+   | (c * e)        -- linear multiplication
+   | (f e1 ... en)  -- uninterpreted function
+\end{spec}
+
+Predicates
+----------
+
+<br>
+
+\begin{spec} <div/>
+p := e           -- atom 
+   | e1 == e2    -- equality
+   | e1 <  e2    -- ordering 
+   | (p && p)    -- and
+   | (p || p)    -- or
+   | (not p)     -- negation
+\end{spec}
+
+<br>
+
+
+Refinement Types
+----------------
+
+
+<br>
+
+\begin{spec}<div/>
+b := Int 
+   | Bool 
+   | ...         -- base types
+   | a, b, c     -- type variables
+
+t := {x:b | p}   -- refined base 
+   | x:t -> t    -- refined function  
+\end{spec}
+
+
+Subtyping Judgment 
+------------------
+
+<br>
+
+$$\boxed{\Gamma \vdash t_1 \preceq t_2}$$
+
+<div class="fragment">
+
+<br>
+
+Where **environment** $\Gamma$ is a sequence of binders
+
+<br>
+
+$$\Gamma \defeq \overline{\bindx{x_i}{t_i}}$$
+
+</div>
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+$$\boxed{\Gamma \vdash t_1 \preceq t_2}$$
+
+
+<br>
+
+[PVS' Predicate Subtyping](http://pvs.csl.sri.com/papers/subtypes98/tse98.pdf)
+
+<br>
+
+(For **Base** Types ...)
+
+
+
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+$$\boxed{\Gamma \vdash t_1 \preceq t_2}$$
+
+
+<br>
+
+$$
+\begin{array}{rl}
+{\mathbf{If\ VC\ is\ Valid}}   & \bigwedge_i P_i \Rightarrow  Q  \Rightarrow R \\
+                & \\
+{\mathbf{Then}} & \overline{\bindx{x_i}{P_i}} \vdash \reft{v}{b}{Q} \subty \reft{v}{b}{R} \\
+\end{array}
+$$ 
+
+
+Example: Natural Numbers
+------------------------
+
+<br>
+
+\begin{spec} <div/>  
+        type Nat = {v:Int | 0 <= v}
+\end{spec}
+
+<br>
+
+<div class="fragment">
+
+$$
+\begin{array}{rcrccll}
+\mathbf{VC\ is\ Valid:} & \True     & \Rightarrow &  v = 0   & \Rightarrow &  0 \leq v & \mbox{(by SMT)} \\
+%                &           &             &          &             &           \\
+\mathbf{So:}      & \emptyset & \vdash      & \Zero  & \subty      & \Nat   &   \\
+\end{array}
+$$
+</div>
+
+<br>
+
+<div class="fragment">
+
+Hence, we can type:
+
+\begin{code}
+{-@ zero' :: Nat @-}
+zero'     =  zero   -- zero :: Zero <: Nat
+\end{code}
+</div>
+
+Contracts: Function Types
+=========================
+
+ {#as}
+------
+
+Pre-Conditions
+--------------
+
+
+<br>
+
+\begin{code}
+safeDiv n d = n `div` d   -- crashes if d==0
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Requires** non-zero input divisor `d`
+
+\begin{code}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+\end{code}
+</div>
+
+<br>
+
+
+<div class="fragment">
+Specify pre-condition as **input type** 
+
+\begin{code}
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{code}
+
+</div>
+
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code}
+{-@ bad :: Nat -> Int @-}
+bad n   = 10 `safeDiv` n
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Rejected As** 
+
+$$\bindx{n}{\Nat} \vdash \reftx{v}{v = n} \not \subty \reftx{v}{v \not = 0}$$
+
+</div>
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code}
+{-@ ok  :: Nat -> Int @-}
+ok n    = 10 `safeDiv` (n+1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Verifies As** 
+
+$\bindx{n}{\Nat} \vdash \reftx{v}{v = n+1} \subty \reftx{v}{v \not = 0}$
+</div>
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{spec} <div/>
+{-@ ok  :: Nat -> Int @-}
+ok n    = 10 `safeDiv` (n+1)
+\end{spec}
+
+<br>
+
+**Verifies As**
+
+$$(0 \leq n) \Rightarrow (v = n+1) \Rightarrow (v \not = 0)$$
+
+
+
+Post-Conditions
+---------------
+
+**Ensures** output is a `Nat` greater than input `x`.
+
+\begin{code}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{code}
+
+<br>
+
+<div class="fragment">
+Specify post-condition as **output type**
+
+\begin{code}
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+**Dependent Function Types**
+
+Outputs *refer to* inputs
+</div>
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+Postcondition is checked at **return-site**
+
+<br>
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+**Verified As**
+
+<br>
+
+$$\begin{array}{rll}
+\bindx{x}{\Int},\bindx{\_}{0 \leq x}      & \vdash \reftx{v}{v = x}     & \subty \reftx{v}{0 \leq v \wedge x \leq v} \\
+\bindx{x}{\Int},\bindx{\_}{0 \not \leq x} & \vdash \reftx{v}{v = 0 - x} & \subty \reftx{v}{0 \leq v \wedge x \leq v} \\
+\end{array}$$
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+**Verified As**
+
+<br>
+
+$$\begin{array}{rll}
+(0 \leq x)      & \Rightarrow (v = x)     & \Rightarrow (0 \leq v \wedge x \leq v) \\
+(0 \not \leq x) & \Rightarrow (v = 0 - x) & \Rightarrow (0 \leq v \wedge x \leq v) \\
+\end{array}$$
+
+
+Recipe Scales Up
+----------------
+
+<br>
+
+<div class="fragment">
+Define type *checker* and get *inference* for free [[PLDI 08]](http://goto.ucsd.edu/~rjhala/papers/liquid_types.pdf)
+</div>
+
+<br>
+
+<div class="fragment">
+Scales to Collections, HOFs, Polymorphism ...
+</div>
+
+<br>
+
+<div class="fragment">
+[DEMO](../hs/001_Refinements.hs)
+
+<br>
+
+[[continue...]](02_Measures.lhs.slides.html)
+
+</div>
diff --git a/docs/slides/BOS14/lhs/02_Measures.lhs b/docs/slides/BOS14/lhs/02_Measures.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/02_Measures.lhs
@@ -0,0 +1,299 @@
+ {#measures}
+============
+
+Recap
+-----
+
+<br>
+<br>
+
+1. <div class="fragment">**Refinements:** Types + Predicates</div>
+2. <div class="fragment">**Subtyping:** SMT Implication</div>
+
+<br>
+<br>
+
+<div class="fragment">
+So far: only specify properties of **base values** (e.g. `Int`) ...
+</div>
+
+<br>
+
+<div class="fragment">
+How to specify properties of **structures**?
+</div>
+
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--full"           @-}
+
+module Measures where
+import Prelude hiding ((!!), length)
+import Language.Haskell.Liquid.Prelude
+
+-- length      :: L a -> Int
+-- (!)         :: L a -> Int -> a
+
+infixr `C`
+\end{code}
+
+</div>
+
+
+ {#meas}
+====================
+
+Measuring Data Types
+--------------------
+
+Measuring Data Types
+====================
+
+
+Example: Length of a List
+-------------------------
+
+Given a type for lists:
+
+<br>
+
+\begin{code}
+data L a = N | C a (L a)
+\end{code}
+
+<div class="fragment">
+<br>
+
+We can define the **length** as:
+
+<br>
+
+\begin{code}
+{-@ measure size  :: (L a) -> Int
+    size (N)      = 0
+    size (C x xs) = (1 + size xs)  @-}
+\end{code}
+
+<div class="hidden">
+
+\begin{code}
+{-@ data L [size] a = N | C {hd :: a, tl :: L a } @-}
+{-@ invariant {v: L a | 0 <= size v}              @-}
+\end{code}
+
+</div>
+
+Example: Length of a List
+-------------------------
+
+\begin{spec}
+{-@ measure size  :: (L a) -> Int
+    size (N)      = 0
+    size (C x xs) = 1 + size xs  @-}
+\end{spec}
+
+<br>
+
+We **strengthen** data constructor types
+
+<br>
+
+\begin{spec} <div/>
+data L a where
+  N :: {v: L a | size v = 0}
+  C :: a -> t:_ -> {v:_| size v = 1 + size t}
+\end{spec}
+
+Measures Are Uninterpreted
+--------------------------
+
+\begin{spec} <br>
+data L a where
+  N :: {v: L a | size v = 0}
+  C :: a -> t:_ -> {v:_| size v = 1 + size t}
+\end{spec}
+
+<br>
+
+`size` is an **uninterpreted function** in SMT logic
+
+Measures Are Uninterpreted
+--------------------------
+
+<br>
+
+In SMT, [uninterpreted function](http://fm.csl.sri.com/SSFT12/smt-euf-arithmetic.pdf) $f$ obeys **congruence** axiom:
+
+<br>
+
+$$\forall \overline{x}, \overline{y}. \overline{x} = \overline{y} \Rightarrow
+f(\overline{x}) = f(\overline{y})$$
+
+<br>
+
+<div class="fragment">
+Other properties of `size` asserted when typing **fold** & **unfold**
+</div>
+
+<br>
+
+<div class="fragment">
+Crucial for *efficient*, *decidable* and *predictable* verification.
+</div>
+
+Measures Are Uninterpreted
+--------------------------
+
+Other properties of `size` asserted when typing **fold** & **unfold**
+
+<br>
+
+<div class="fragment">
+\begin{spec}**Fold**<br>
+z = C x y     -- z :: {v | size v = 1 + size y}
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{spec}**Unfold**<br>
+case z of
+  N     -> e1 -- z :: {v | size v = 0}
+  C x y -> e2 -- z :: {v | size v = 1 + size y}
+\end{spec}
+</div>
+
+Example: Using Measures
+-----------------------
+
+<br>
+<br>
+
+[DEMO: 001_Refinements.hs](../hs/001_Refinements.hs)
+
+
+
+Multiple Measures
+=================
+
+ {#adasd}
+---------
+
+Can support *many* measures for a type
+
+
+Ex: List Emptiness
+------------------
+
+Measure describing whether a `List` is empty
+
+\begin{code}
+{-@ measure isNull :: (L a) -> Prop
+    isNull (N)      = true
+    isNull (C x xs) = false           @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+LiquidHaskell **strengthens** data constructors
+
+\begin{spec}
+data L a where
+  N :: {v : L a | isNull v}
+  C :: a -> L a -> {v:(L a) | not (isNull v)}
+\end{spec}
+
+</div>
+
+Conjoining Refinements
+----------------------
+
+Data constructor refinements are **conjoined**
+
+\begin{spec}
+data L a where
+  N :: {v:L a |  size v = 0
+              && isNull v }
+  C :: a
+    -> xs:L a
+    -> {v:L a |  size v = 1 + size xs
+              && not (isNull v)      }
+\end{spec}
+
+Multiple Measures: Red Black Trees
+==================================
+
+ {#elements}
+------------
+
+<br>
+<br>
+<br>
+
+<a href="13_RedBlack.lhs.slides.html" target="_blank">[continue]</a>
+
+
+
+<!-- BEGIN CUT
+
+Multiple Measures: Sets and Duplicates
+======================================
+
+ {#elements}
+------------
+
+[DEMO: 01_Elements.hs](../hs/01_Elements.hs)
+
+Measures vs. Index Types
+========================
+
+Decouple Property & Type
+------------------------
+
+Unlike [indexed types](http://dl.acm.org/citation.cfm?id=270793) ...
+
+<br>
+
+<div class="fragment">
+
++ Measures **decouple** properties from structures
+
++ Support **multiple** properties over structures
+
++ Enable  **reuse** of structures in different contexts
+
+</div>
+
+<br>
+
+<div class="fragment">Invaluable in practice!</div>
+
+END CUT -->
+
+
+Recap
+-----
+
+<br>
+<br>
+
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. **Measures:** Strengthened Constructors
+
+<br>
+
+<div class="fragment">Automatic Verification of Data Structures</div>
+
+<br>
+<br>
+
+<!-- BEGIN CUT
+<div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target="_blank">[continue]</a></div>
+     END CUT -->
diff --git a/docs/slides/BOS14/lhs/03_HigherOrderFunctions.lhs b/docs/slides/BOS14/lhs/03_HigherOrderFunctions.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/03_HigherOrderFunctions.lhs
@@ -0,0 +1,276 @@
+  {#hofs}
+=========
+
+<div class="hidden">
+\begin{code}
+module Loop (
+    listSum
+  , sumNats
+  ) where
+
+import Prelude
+
+{-@ LIQUID "--no-termination"@-}
+sumNats  :: [Int] -> Int
+add         :: Int -> Int -> Int
+\end{code}
+</div>
+
+Higher-Order Functions 
+----------------------
+
+Types scale to *Higher-Order Functions*  
+
+<br>
+
+<div class="fragment">
+
++ map
++ fold
++ visitors
++ callbacks
++ ...
+
+</div>
+
+<br>
+
+<div class="fragment">Difficult with *first-order program logics*</div>
+
+
+Higher Order Specifications 
+===========================
+
+Example: Higher Order Loop
+--------------------------
+
+<br>
+
+\begin{code}
+loop :: Int -> Int -> α -> (Int -> α -> α) -> α
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+By subtyping, we infer `f` called with values `(Btwn lo hi)`
+
+
+Example: Summing Lists
+----------------------
+
+\begin{code}
+listSum xs     = loop 0 n 0 body 
+  where 
+    body i acc = acc + (xs !! i)
+    n          = length xs
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Function Subtyping** 
+
+\begin{spec}
+loop :: l -> h -> α -> (Btwn l h -> α -> α) -> α
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+At callsite, since `l := 0` and `h := llen xs` 
+
+\begin{spec}
+body :: Btwn 0 (llen xs) -> Int -> Int
+\end{spec}
+</div>
+
+Example: Summing Lists
+----------------------
+
+\begin{spec}
+listSum xs     = loop 0 n 0 body 
+  where 
+    body i acc = acc + (xs !! i)
+    n          = length xs
+\end{spec}
+
+<br>
+
+**Function Subtyping** 
+
+\begin{spec}
+body :: Btwn 0 (llen xs) -> Int -> Int
+\end{spec}
+
+<br>
+
+So `i` is `Btwn 0 (llen xs)`; indexing `!!` is verified safe.
+
+
+ {#polyinst}
+============
+
+Polymorphic Instantiation
+-------------------------
+
+<br>
+<br>
+<br>
+
+<div class="fragment">
+"Plugging in" summaries at call-sites
+</div>
+
+Polymorphic Instantiation
+=========================
+
+ {#poly}
+--------
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{code}
+{-@ sumNats :: [Nat] -> Nat @-}
+sumNats xs  = foldl (+) 0 xs 
+\end{code}
+
+<br>
+
+<div class="fragment">
+\begin{spec} Recall 
+foldl :: (α -> β -> α) -> α -> [β] -> α
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+How to **instantiate** `α` and `β` ?
+</div>
+
+Function Subtyping
+------------------
+
+\begin{spec}<div/>
+(+) ::  x:Int -> y:Int -> {v:Int|v=x+y} 
+    <:  Nat   -> Nat   -> Nat
+\end{spec}
+
+<br>
+
+<div class="fragment">
+Because,
+
+\begin{spec}<div/>
+             |- Nat       <: Int  -- Contra (in)
+x:Nat, y:Nat |- {v = x+y} <: Nat  -- Co    (out)
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+Because,
+
+\begin{spec}<div/>
+  0<=x && 0<=y && v = x+y   => 0 <= v
+\end{spec}
+</div>
+
+
+
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{spec} <div/> 
+{-@ sumNats :: [Nat] -> Nat @-}
+sumNats xs  = foldl (+) 0 xs 
+\end{spec}
+
+<br>
+
+\begin{spec} Where:
+foldl :: (α -> β -> α) -> α -> [β] -> α
+(+)   :: Nat -> Nat -> Nat
+\end{spec}
+
+<br>
+
+<div class="fragment">
+Hence, `sumNats` verified by **instantiating** `α,β := Nat`
+</div>
+
+<br>
+
+<div class="fragment">
+`α` is **loop invariant**, instantiation is invariant **inference**
+</div>
+
+Instantiation And Inference
+---------------------------
+
+Polymorphism ubiquitous, so inference is critical!
+
+<br>
+
+<div class="fragment">
+**Step 1. Templates** 
+Instantiate with unknown refinements
+
+$$
+\begin{array}{rcl}
+\alpha & \defeq & \reft{v}{\Int}{\kvar{\alpha}}\\
+\beta  & \defeq & \reft{v}{\Int}{\kvar{\beta}}\\
+\end{array}
+$$
+</div>
+
+<br>
+<div class="fragment">
+**Step 2. Horn-Constraints** 
+By type checking the templates
+</div>
+
+<br>
+<div class="fragment">
+**Step 3. Fixpoint** 
+Abstract interpretation to get solution for $\kvar{}$
+</div>
+
+
+Iteration Dependence
+--------------------
+
+**Problem:** Cannot use parametric polymorphism to verify
+
+<br>
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+As property only holds after **last iteration** ...
+
+<br>
+
+... cannot instantiate $\alpha \defeq \reft{v}{\Int}{v = n + m}$
+</div>
+
+<br>
+
+<div class="fragment">
+**Problem:** *Iteration-dependent* invariants...? &nbsp; &nbsp; [[Continue]](04_AbstractRefinements.lhs.slides.html)
+</div>
+
diff --git a/docs/slides/BOS14/lhs/04_AbstractRefinements.lhs b/docs/slides/BOS14/lhs/04_AbstractRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/04_AbstractRefinements.lhs
@@ -0,0 +1,281 @@
+  {#abstractrefinements}
+========================
+
+<div class="hidden">
+
+\begin{code}
+module AbstractRefinements where
+
+import Prelude 
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+-- o,no        :: Int
+maxInt       :: Int -> Int -> Int
+\end{code}
+</div>
+
+
+Abstract Refinements
+--------------------
+
+Abstract Refinements
+====================
+
+A Pervasive Problem
+--------------------
+
+<br>
+
+<div class="fragment">
+
+Cannot use *context-independent* specifications.
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+Lets distill it to a simple example...
+
+</div>
+
+
+A Pervasive Problem
+--------------------
+
+
+<br>
+
+(First, a few aliases)
+
+<br>
+
+\begin{code}
+{-@ type Odd  = {v:Int | (v mod 2) = 1} @-}
+{-@ type Even = {v:Int | (v mod 2) = 0} @-}
+\end{code}
+
+
+
+Example: `maxInt` 
+-----------------
+
+Compute the larger of two `Int`s:
+
+\begin{spec} <br> 
+maxInt     :: Int -> Int -> Int 
+maxInt x y = if y <= x then x else y
+\end{spec}
+
+
+
+Example: `maxInt` 
+-----------------
+
+Has **many incomparable** refinement types/summaries
+
+\begin{spec}<br>
+maxInt :: Nat  -> Nat  -> Nat
+maxInt :: Even -> Even -> Even
+maxInt :: Odd  -> Odd  -> Odd 
+\end{spec}
+
+<br>
+
+<div class="fragment">*Which* should we use?</div>
+
+
+Refinement Polymorphism 
+-----------------------
+
+`maxInt` returns **one of** its two inputs `x` and `y` 
+
+<div class="fragment">
+
+<div align="center">
+
+<br>
+
+---------   ---   -------------------------------------------
+   **If**    :    the *inputs* satisfy a property  
+
+ **Then**    :    the *output* satisfies that property
+---------   ---   -------------------------------------------
+
+<br>
+
+</div>
+</div>
+
+<div class="fragment">Above holds **for all properties**!</div>
+
+<br>
+
+<div class="fragment"> 
+
+**Need to abstract properties over types**
+
+</div>
+
+Parametric Refinements 
+----------------------
+
+Enable *quantification over refinements* ...
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">Type says: **for any** `p` that is a property of `Int`, </div>
+
+- <div class="fragment">`max` **takes** two `Int`s that satisfy `p`,</div>
+
+- <div class="fragment">`max` **returns** an `Int` that satisfies `p`.</div>
+
+Parametric Refinements 
+----------------------
+
+Enable *quantification over refinements* ...
+
+<br>
+
+\begin{spec}<div/>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{spec}
+
+<br>
+
+[Key idea: ](http://goto.ucsd.edu/~rjhala/papers/abstract_refinement_types.html)
+&nbsp; `Int<p>` &nbsp; is just  &nbsp; $\reft{v}{\Int}{p(v)}$ 
+
+<br>
+
+Abstract Refinement is **uninterpreted function** in SMT logic
+
+Parametric Refinements 
+----------------------
+
+\begin{spec}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{spec}
+
+<br>
+
+**Check Implementation via SMT**
+
+Parametric Refinements 
+----------------------
+
+\begin{spec}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{spec}
+
+<br>
+
+**Check Implementation via SMT**
+
+<br>
+
+$$\begin{array}{rll}
+\ereft{x}{\Int}{p(x)},\ereft{y}{\Int}{p(y)} & \vdash \reftx{v}{v = y} & \subty \reftx{v}{p(v)} \\
+\ereft{x}{\Int}{p(x)},\ereft{y}{\Int}{p(y)} & \vdash \reftx{v}{v = x} & \subty \reftx{v}{p(v)} \\
+\end{array}$$
+
+Parametric Refinements 
+----------------------
+
+\begin{spec}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{spec}
+
+<br>
+
+**Check Implementation via SMT**
+
+<br>
+
+$$\begin{array}{rll}
+{p(x)} \wedge {p(y)} & \Rightarrow {v = y} & \Rightarrow {p(v)} \\
+{p(x)} \wedge {p(y)} & \Rightarrow {v = x} & \Rightarrow {p(v)} \\
+\end{array}$$
+
+
+Using Abstract Refinements
+--------------------------
+
+- <div class="fragment">**If** we call `maxInt` with args satisfying *common property*,</div>
+- <div class="fragment">**Then** `p` instantiated property, *result* gets same property.</div>
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ xo :: Odd  @-}
+xo = maxInt 3 7     -- p := \v -> Odd v 
+
+{-@ xe :: Even @-}
+xe = maxInt 2 8     -- p := \v -> Even v 
+\end{code}
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Automatically Infer Instantiation by Liquid Typing**
+<!-- CUT At call-site, instantiate `p` with unknown $\kvar{p}$ and solve! -->
+
+</div>
+
+Using Abstract Refinements
+--------------------------
+
+<br>
+<br>
+<br>
+
+[DEMO 02_AbstractRefinements.hs](../hs/02_AbstractRefinements.hs)
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. **Abstract Refinements** over functions 
+
+<br>
+<br>
+
+<div class="fragment">
+  Abstract Refinements decouple invariants from **code** ...
+<br>
+
+<a href="06_Inductive.lhs.slides.html" target="_blank">[continue]</a>
+</div>
+
diff --git a/docs/slides/BOS14/lhs/05_Composition.lhs b/docs/slides/BOS14/lhs/05_Composition.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/05_Composition.lhs
@@ -0,0 +1,161 @@
+Abstract Refinements {#composition}
+===================================
+
+Very General Mechanism 
+----------------------
+
+**Next:** Lets add parameters...
+
+<div class="hidden">
+\begin{code}
+module Composition where
+
+import Prelude hiding ((.))
+
+plus     :: Int -> Int -> Int
+plus3'   :: Int -> Int
+\end{code}
+</div>
+
+
+Example: `plus`
+---------------
+
+\begin{code}
+{-@ plus :: x:_ -> y:_ -> {v:_ | v=x+y} @-}
+plus x y = x + y
+\end{code}
+
+
+Example: `plus 3` 
+-----------------
+
+<br>
+
+\begin{code}
+{-@ plus3' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3'     = plus 3
+\end{code}
+
+<br>
+
+Easily verified by LiquidHaskell
+
+A Composed Variant
+------------------
+
+Lets define `plus3` by *composition*
+
+A Composition Operator 
+----------------------
+
+\begin{code}
+(#) :: (b -> c) -> (a -> b) -> a -> c
+(#) f g x = f (g x)
+\end{code}
+
+
+`plus3` By Composition
+-----------------------
+
+\begin{code}
+{-@ plus3'' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3''     = plus 1 # plus 2
+\end{code}
+
+<br>
+
+Yikes! Verification *fails*. But why?
+
+<br>
+
+<div class="fragment">(Hover mouse over `#` for a clue)</div>
+
+How to type compose (#) ? 
+-------------------------
+
+This specification is *too weak* <br>
+
+\begin{spec} <br>
+(#) :: (b -> c) -> (a -> b) -> (a -> c)
+\end{spec}
+
+<br>
+
+Output type does not *relate* `c` with `a`!
+
+How to type compose (.) ?
+-------------------------
+
+Write specification with abstract refinement type:
+
+<br>
+
+\begin{code}
+{-@ (.) :: forall <p :: b->c->Prop, 
+                   q :: a->b->Prop>.
+             f:(x:b -> c<p x>) 
+          -> g:(x:a -> b<q x>) 
+          -> y:a -> exists[z:b<q y>].c<p z>
+ @-}
+(.) f g y = f (g y)
+\end{code}
+
+Using (.) Operator 
+------------------
+
+<br>
+
+\begin{code}
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br>
+
+<div class="fragment">*Verifies!*</div>
+
+
+Using (.) Operator 
+------------------
+
+\begin{spec} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{spec}
+
+<br>
+
+LiquidHaskell *instantiates*
+
+- `p` with `\x -> v = x + 1`
+- `q` with `\x -> v = x + 2`
+
+Using (.) Operator 
+------------------
+
+\begin{spec} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{spec}
+
+<br> To *infer* that output of `plus3` has type: 
+
+`exists [z:{v = y + 2}].{v = z + 1}`
+
+<div class="fragment">
+
+`<:`
+
+`{v:Int|v=3}`
+</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract:** Refinements over Type Signatures
+    + <div class="fragment">*Dependencies* using refinement parameters</div>
diff --git a/docs/slides/BOS14/lhs/06_Inductive.lhs b/docs/slides/BOS14/lhs/06_Inductive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/06_Inductive.lhs
@@ -0,0 +1,535 @@
+Abstract Refinements {#induction}
+=================================
+
+Decoupling Invariants & Code
+----------------------------
+
+<br>
+
+Abstract refinements decouple invariants from code
+
+<br>
+
+<div class="fragment">
+
+**Next:** Precise Specifications for HOFs
+
+<div class="hidden">
+
+\begin{code}
+module Loop where
+import Prelude hiding ((!!), foldr, length, (++))
+import Data.Set hiding (insert, foldr,size,filter, append) 
+
+-- import Measures
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names" @-}
+
+{-@ measure size  :: (L a) -> Int
+    size (N)      = 0
+    size (C x xs) = 1 + (size xs)  @-}
+
+{-@ measure elems :: L a -> (Set a)
+    elems (N)      = (Set_empty 0)
+    elems (C x xs) = (Set_cup (Set_sng x) (elems xs))
+  @-}
+
+{-@ type UnElems Xs Ys = {v:_ | elems v = Set_cup (elems Xs) (elems Ys)} @-}
+
+size  :: L a -> Int
+add    :: Int -> Int -> Int
+loop   :: Int -> Int -> α -> (Int -> α -> α) -> α
+ifoldr :: (L a -> a -> b -> b) -> b -> L a -> b
+
+\end{code}
+</div>
+
+<!-- BEGIN CUT
+
+Induction
+=========
+
+Example: A Higher Order `loop` 
+-------------------------------
+
+
+<br>
+<br>
+
+\begin{code}
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+
+Iteration Dependence
+--------------------
+
+We can use `loop` to write 
+
+<br>
+
+\begin{spec} 
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop' 0 m n (\_ i -> i + 1)
+\end{spec}
+
+<br>
+
+<div class="fragment">
+
+**Problem** But cannot prove `add n m :: {v:_ | v = n + m}`
+
+- As property only holds after *last* loop iteration...
+
+- ... cannot instantiate `α` with `{v:Int | v = n + m}`
+
+</div>
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+<br>
+
+\begin{spec} 
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{spec}
+
+<br>
+
+**Problem** 
+
+Need invariant relating *iteration* `i` with *accumulator* `acc`
+
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{spec} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{spec}
+
+<br>
+
+**Solution** 
+
+- Abstract Refinement `p :: Int -> a -> Prop`
+
+- `(p i acc)` relates *iteration* `i` with *accumulator* `acc`
+
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+<div class="fragment">
+<div align="center">
+
+------------  ---   ----------------------------
+  **Assume**   :    `out = loop lo hi base f` 
+
+   **Prove**   :    `(p hi out)`
+------------  ---   ----------------------------
+
+</div>
+</div>
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{spec} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{spec}
+
+<br>
+
+**Base Case:** &nbsp; Initial accumulator `base` satisfies invariant
+
+
+`(p lo base)`   
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{spec} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{spec}
+
+<br>
+
+**Inductive Step:** &nbsp; `f` *preserves* invariant at `i`
+
+
+`(p i acc) => (p (i+1) (f i acc))`
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{spec} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{spec}
+
+<br>
+
+**"By Induction"** &nbsp; `out` satisfies invariant at `hi` 
+
+`(p hi out)`
+
+
+Induction in `loop` (by type)
+-----------------------------
+
+Induction is an **abstract refinement type** for `loop` 
+
+<br>
+
+\begin{code}
+{-@ loop :: forall a <p :: Int -> a -> Prop>.
+        lo:Int
+     -> hi:{Int | lo <= hi}
+     -> base:a<p lo>                      
+     -> f:(i:Int -> a<p i> -> a<p (i+1)>) 
+     -> a<p hi>                           @-}
+\end{code}
+
+<br>
+
+Induction in `loop` (by type)
+-----------------------------
+
+`p` is the *index dependent* invariant!
+
+
+\begin{spec}<br> 
+p    :: Int -> a -> Prop             -- invt 
+base :: a<p lo>                      -- base 
+f    :: i:Int -> a<p i> -> a<p(i+1)> -- step
+out  :: a<p hi>                      -- goal
+\end{spec}
+
+
+
+Using Induction
+---------------
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br>
+
+**Verified** by *instantiating* the abstract refinement of `loop`
+
+`p := \i acc -> acc = i + n`
+
+
+Generalizes To Structures 
+-------------------------
+
+Same idea applies for induction over *structures* ...
+
+<br>
+<br>
+
+[DEMO 02_AbstractRefinements.hs #2](../hs/02_AbstractRefinements.hs) 
+
+
+END CUT -->
+
+
+Structural Induction
+====================
+
+Example: Lists
+--------------
+
+<br>
+
+\begin{code}
+data L a = N 
+         | C a (L a)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets write a generic loop over lists ...
+</div>
+
+
+Example: `foldr`
+----------------
+
+<br>
+<br>
+
+\begin{code}
+foldr :: (α -> β -> β) -> β -> L α -> β
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+\end{code}
+
+
+Problem
+-------
+
+Recall our *failed attempt* to write `append` with `foldr`
+
+<br>
+
+\begin{spec} 
+{-@ app :: xs:_ -> ys:_ -> UnElems xs ys @-}
+app xs ys = foldr C ys xs
+\end{spec}
+
+<br>
+
+<div class="fragment">
+- Property holds after *last* iteration
+- Cannot instantiate `α` with `UnElems xs ys`
+</div>
+
+Problem
+-------
+
+Recall our *failed attempt* to write `append` with `foldr`
+
+<br>
+
+\begin{spec} 
+{-@ app :: xs:_ -> ys:_ -> UnElems xs ys @-}
+app xs ys = foldr C ys xs
+\end{spec}
+
+
+<br>
+
+Need to **relate** each *iteration* with *accumulator* `acc` 
+
+
+
+
+Solution: Inductive `foldr`
+---------------------------
+
+<br>
+<br>
+
+<div class="fragment">
+Lets brace ourselves for the type...
+</div>
+
+Solution: Inductive `foldr`
+---------------------------
+
+\begin{code}
+{-@ ifoldr :: 
+     forall a b <p :: L a -> b -> Prop>. 
+      (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
+    -> b<p N> 
+    -> ys:L a
+    -> b<p ys>                            @-}
+ifoldr f b N        = b
+ifoldr f b (C x xs) = f xs x (ifoldr f b xs)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets step through the type...
+</div>
+
+
+`ifoldr`: Abstract Refinement
+-----------------------------
+
+\begin{spec} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  ::  b<p ys>                            
+\end{spec}
+
+<br>
+
+`(p xs b)` relates `b` with **folded** `xs`
+
+`p :: L a -> b -> Prop`
+
+
+`ifoldr`: Base Case
+-------------------
+
+\begin{spec} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{spec}
+
+<br>
+
+`base` is related to **empty** list `N`
+
+`base :: b<p N>` 
+
+
+
+`ifoldr`: Ind. Step 
+-------------------
+
+\begin{spec} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{spec}
+
+<br>
+
+`step` **extends** relation from `xs` to `C x xs`
+
+`step :: xs:_ -> x:_ -> b<p xs> -> b<p (C x xs)>`
+
+
+`ifoldr`: Output
+----------------
+
+\begin{spec} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{spec}
+
+<br>
+
+Hence, relation holds between `out` and **entire input** list `ys`
+
+`out :: b<p ys>`
+
+Using `ifoldr`: Size
+-------------------
+
+We can now verify
+
+<br>
+
+\begin{code}
+{-@ size :: xs:_ -> {v:Int| v = size xs} @-}
+size     = ifoldr (\_ _ n -> n + 1) 0
+\end{code}
+
+<br>
+
+<div class="fragment">
+by *automatically instantiating* `p` with
+
+`\xs acc -> acc = size xs`
+</div>
+
+Using `foldr`: Append
+---------------------
+
+We can now verify
+
+<br>
+
+\begin{code}
+{-@ (++) :: xs:_ -> ys:_ -> UnElems xs ys @-} 
+xs ++ ys = ifoldr (\_ -> C) ys xs 
+\end{code}
+
+<br>
+
+<br>
+
+<div class="fragment">
+By *automatically* instantiating `p` with
+
+`\xs acc -> elems acc = Set_cup (elems xs) (elems ys)`
+
+</div>
+
+More Examples
+-------------
+
+Induction over *structures* from `GHC.List`
+
+<br>
+
++ `length`
++ `append`
++ `filter`
++ ...
+
+<br>
+
+[DEMO 02_AbstractRefinements.hs #2](../hs/02_AbstractRefinements.hs) 
+
+
+
+Recap
+-----
+
+<br>
+
+Abstract refinements *decouple* **invariant** from **iteration**
+
+<br>
+
+<div class="fragment">**Precise** specs for higher-order functions.</div>
+
+<br>
+
+<div class="fragment">**Automatic** checking and instantiation by SMT.</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over Type Signatures
+    + <div class="fragment">**Functions**</div>
+    + <div class="fragment">**Recursive Data** <a href="08_Recursive.lhs.slides.html" target="_blank">[continue]</a></div>
+5. <div class="fragment">[Evaluation](11_Evaluation.lhs.slides.html)</div>
diff --git a/docs/slides/BOS14/lhs/07_Array.lhs b/docs/slides/BOS14/lhs/07_Array.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/07_Array.lhs
@@ -0,0 +1,305 @@
+Abstract Refinements {#data}
+============================
+
+Recap
+-----
+
+<br>
+
+**So far**
+
+Abstract Refinements decouple invariants from *functions*
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+Decouple invariants from *indexed data structures*
+
+</div>
+
+
+
+Decouple Invariants From Data {#vector} 
+=======================================
+
+Example: Vectors 
+----------------
+
+<div class="hidden">
+\begin{code}
+module LiquidArray where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume, liquidError)
+
+{-@ LIQUID "--no-termination" @-}
+initialize :: Int -> Vec Int
+\end{code}
+</div>
+
+<div class="fragment">
+
+For simplicity, implemented as maps from `Int` to `a` 
+
+<br>
+
+\begin{code}
+data Vec a = V (Int -> a)
+\end{code}
+
+</div>
+
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Parameterize type with *two* abstract refinements:
+
+<br>
+
+\begin{code}
+{-@ data Vec a < dom :: Int -> Prop,
+                 rng :: Int -> a -> Prop >
+      = V {a :: i:Int<dom> -> a <rng i>}  @-}
+\end{code}
+
+<br>
+
+- `dom`: *domain* on which `Vec` is *defined* 
+
+- `rng`: *range*  and relationship with *index*
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Diverse `Vec`tors by *instantiating* `dom` and `rng`
+
+<br>
+
+<div class="fragment">
+
+An alias for *segments* between `I` and `J`
+
+<br>
+
+\begin{code}
+{-@ predicate Btwn I V J = I <= V && V < J @-}
+\end{code}
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type IdVec N = Vec <{\v -> Btwn 0 v N}, 
+                        {\k v -> v = k}> 
+                       Int                  @-}
+\end{code}
+
+</div>
+
+
+Ex: Zero-Terminated Vectors
+---------------------------
+
+Defined between `[0..N)`, with *last* element equal to `0`:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type ZeroTerm N = 
+     Vec <{\v -> Btwn 0 v N}, 
+          {\k v -> k = N-1 => v = 0}> 
+          Int                         @-}
+\end{code}
+
+</div>
+
+Ex: Fibonacci Table 
+-------------------
+
+A vector whose value at index `k` is either 
+
+- `0` (undefined), or, 
+
+- `k`th fibonacci number 
+
+\begin{code}
+{-@ type FibV =  
+     Vec <{\v -> true}, 
+          {\k v -> v = 0 || v = fib k}> 
+          Int                          @-}
+\end{code}
+
+
+An API for Vectors
+------------------
+
+
+<br>
+<br>
+
+- `empty`
+
+- `set`
+
+- `get`
+
+
+API: Empty Vectors
+-----------------
+
+`empty` a Vector whose domain is `false` (defined at *no* key)
+
+<br>
+
+\begin{code}
+{-@ empty :: forall <p :: Int -> a -> Prop>. 
+               Vec <{v:Int|false}, p> a     @-}
+
+empty     = V $ \_ -> error "empty vector!"
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+What would happen if we changed `false` to `true`?
+</div>
+
+API: `get` Key's Value 
+----------------------
+
+- *Input* `key` in *domain*
+
+- *Output* value in *range* related with `k`
+
+<br>
+
+\begin{code}
+{-@ get :: forall a <d :: Int -> Prop,  
+                     r :: Int -> a -> Prop>.
+           key:Int <d>
+        -> vec:Vec <d, r> a
+        -> a<r key>                        @-}
+
+get k (V f) = f k
+\end{code}
+
+
+API: `set` Key's Value 
+----------------------
+
+- <div class="fragment">Input `key` in *domain*</div>
+
+- <div class="fragment">Input `val` in *range* related with `key`</div>
+
+- <div class="fragment">Input `vec` defined at *domain except at* `key`</div>
+
+- <div class="fragment">Output domain *includes* `key`</div>
+
+API: `set` Key's Value 
+----------------------
+
+\begin{code}
+{-@ set :: forall a <d :: Int -> Prop,
+                     r :: Int -> a -> Prop>.
+           key: Int<d> -> val: a<r key>
+        -> vec: Vec<{v:Int<d>| v /= key},r> a
+        -> Vec <d, r> a                     @-}
+
+set key val (V f) = V $ \k -> if k == key 
+                                then val 
+                                else f k
+\end{code}
+
+<br>
+
+<div class="hidden">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+Help! Can you spot and fix the errors? 
+</div>
+
+Using the Vector API
+--------------------
+
+Loop over vector, setting each key `i` equal to `i`:
+
+<br>
+
+\begin{code}
+{-@ initialize :: n:Nat -> IdVec n @-}
+initialize n      = loop 0 empty
+  where
+    loop i a 
+      | i < n     = let a' = set i i a
+                    in
+                        loop (i+1) a'
+      | otherwise = a 
+\end{code}
+
+Example: Knuth-Morris-Pratt
+---------------------------
+
+<br>
+<br>
+<br>
+
+[DEMO KMP.hs](../hs/KMP.hs)
+
+
+Recap
+-----
+
+<br>
+
++ Created a `Vec` (Array) container 
+
++ Decoupled *domain* and *range* invariants from *data*
+
++ Enabled analysis of *array segments*
+
+<br>
+
+Recap
+-----
+
+<br>
+
+Custom *array segment* program analyses: 
+
+<br>
+
+- Gopan-Reps-Sagiv, POPL 05
+- J.-McMillan, CAV 07
+- Logozzo-Cousot-Cousot, POPL 11
+- Dillig-Dillig, POPL 12 
+
+<br>
+
+Encoded in (abstract) refinement typed API.
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over Type Signatures
+    + Functions
+    + Recursive Data
+    + <div class="fragment">**Indexed Data**</div>
+
+<div class="fragment">[[continue...]](11_Evaluation.lhs.slides.html)</div>
diff --git a/docs/slides/BOS14/lhs/08_Recursive.lhs b/docs/slides/BOS14/lhs/08_Recursive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/08_Recursive.lhs
@@ -0,0 +1,495 @@
+Abstract Refinements {#data}
+============================
+
+Recap
+-----
+
+**So far**
+
+Abstract Invariants from Functions
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+Decouple invariants from **recursive** data structures
+</div>
+
+
+
+Decouple Invariants From Data {#recursive} 
+==========================================
+
+ {#asd}
+-------
+
+Recursive Structures 
+--------------------
+
+Lets see another example of decoupling...
+
+<div class="hidden">
+\begin{code}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+
+module List (insertSort) where
+
+{-@ LIQUID "--no-termination" @-}
+
+mergeSort     :: Ord a => [a] -> [a]
+insertSort :: (Ord a) => [a] -> L a 
+slist :: L Int
+slist' :: L Int
+iGoUp, iGoDn, iDiff :: [Int]
+infixr `C`
+\end{code}
+</div>
+
+Decouple Invariants From Recursive Data
+=======================================
+
+Recall: Lists
+-------------
+
+\begin{code}
+data L a = N 
+         | C { hd :: a, tl :: L a }
+\end{code}
+
+
+Recall: Refined Constructors 
+----------------------------
+
+Define **increasing** Lists with *strengthened constructors*:
+
+\begin{spec} <br>
+data L a where
+  N :: L a
+  C :: hd:a -> tl: L {v:a | hd <= v} -> L a
+\end{spec}
+
+Problem: Decreasing Lists?
+--------------------------
+
+What if we need *both* [increasing *and* decreasing lists?](http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Data-List.html#sort)
+
+<br>
+
+<div class="hidden">
+[Separate (indexed) types](http://web.cecs.pdx.edu/~sheard/Code/QSort.html) get quite complicated ...
+</div>
+
+Abstract That Refinement!
+-------------------------
+
+\begin{code}
+{-@ data L a <p :: a -> a -> Prop>
+      = N 
+      | C { hd :: a, tl :: L <p> a<p hd> } @-}
+\end{code}
+
+<br>
+
+<div class="fragment"> `p` is a **binary relation** between two `a` values</div>
+
+<br>
+
+<div class="fragment"> Definition relates `hd` with **all** the elements of `tl`</div>
+
+<br>
+
+<div class="fragment"> Recursive: `p` holds for **every pair** of elements!</div>
+
+Example
+-------
+
+Consider a list with *three* or more elements 
+
+\begin{spec} <br>
+x1 `C` x2 `C` x3 `C` rest :: L <p> a 
+\end{spec}
+
+Example: Unfold Once
+--------------------
+
+\begin{spec} <br> 
+x1                 :: a
+x2 `C` x3 `C` rest :: L <p> a<p x1> 
+\end{spec}
+
+Example: Unfold Twice
+---------------------
+
+\begin{spec} <br> 
+x1          :: a
+x2          :: a<p x1>  
+x3 `C` rest :: L <p> a<p x1 && p x2> 
+\end{spec}
+
+Example: Unfold Thrice
+----------------------
+
+\begin{spec} <br> 
+x1   :: a
+x2   :: a<p x1>  
+x3   :: a<p x1 && p x2>  
+rest :: L <p> a<p x1 && p x2 && p x3> 
+\end{spec}
+
+<br>
+
+<div class="fragment">
+Note how `p` holds between **every pair** of elements in the list. 
+</div>
+
+A Concrete Example
+------------------
+
+That was a rather *abstract*!
+
+<br>
+
+How can we *use* fact that `p` holds between *every pair*?
+
+<br>
+
+<div class="fragment">**Instantiate** `p` with a *concrete* refinement</div>
+
+
+
+Example: Increasing Lists
+-------------------------
+
+**Instantiate** `p` with a *concrete* refinement
+
+<br>
+
+\begin{code}
+{-@ type IncL a = L <{\hd v -> hd <= v}> a @-}
+\end{code}
+
+<br>
+
+<div class="fragment"> Refinement says: &nbsp; `hd` less than **every** `v` in tail,</div>
+
+<br>
+
+<div class="fragment"> i.e., `IncL` denotes **increasing** lists. </div>
+
+<br>
+
+<div class="fragment"> [DEMO 02_AbstractRefinements.hs #3](02_AbstractRefinements.hs) </div>
+
+<!-- BEGIN CUT 
+
+Example: Increasing Lists
+-------------------------
+
+LiquidHaskell *verifies* that `slist` is indeed increasing...
+
+\begin{code}
+{-@ slist :: IncL Int @-}
+slist     = 1 `C` 6 `C` 12 `C` N
+\end{code}
+
+<br> 
+
+<div class="fragment">
+
+... and *protests* that `slist'` is not: 
+
+\begin{code}
+{-@ slist' :: IncL Int @-}
+slist' = 6 `C` 1 `C` 12 `C` N
+\end{code}
+</div>
+
+Insertion Sort
+--------------
+
+\begin{code}
+{-@ insertSort :: (Ord a) => [a] -> IncL a @-}
+insertSort     = foldr insert N
+
+insert y N          = y `C` N
+insert y (x `C` xs) 
+  | y < x           = y `C` (x `C` xs)
+  | otherwise       = x `C` insert y xs
+\end{code}
+
+<br>
+
+(Mouseover `insert` to see inferred type.)
+
+Checking GHC Lists
+------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target= "_blank">Demo:</a> 
+Above applies to GHC's List definition:
+
+\begin{spec} <br> 
+data [a] <p :: a -> a -> Prop>
+  = [] 
+  | (:) { h :: a, tl :: [a<p h>]<p> }
+\end{spec}
+
+Checking GHC Lists
+------------------
+
+Increasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Incs a = [a]<{\h v -> h <= v}> @-}
+
+{-@ iGoUp :: Incs Int @-}
+iGoUp     = [1,2,3]
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Decreasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Decs a = [a]<{\h v -> h >= v}> @-}
+
+{-@ iGoDn :: Decs Int @-}
+iGoDn     = [3,2,1]
+\end{code}
+
+
+Checking GHC Lists
+------------------
+
+Duplicate-free Lists
+
+<br>
+
+\begin{code}
+{-@ type Difs a = [a]<{\h v -> h /= v}> @-}
+
+{-@ iDiff :: Difs Int @-}
+iDiff     = [1,3,2]
+\end{code}
+
+END CUT -->
+
+Example: Sorting Lists
+----------------------
+
+Now we can check all the usual list sorting algorithms 
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target="_blank">Demo:</a> List Sorting
+
+<br>
+<br>
+
+[DEMO GhcListSort.hs](../hs/GhcListSort.hs)
+
+<!-- BEGIN CUT 
+
+Example: `mergeSort` [1/2]
+--------------------------
+
+\begin{code}
+{-@ mergeSort  :: (Ord a) => [a] -> Incs a @-}
+mergeSort []   = []
+mergeSort [x]  = [x]
+mergeSort xs   = merge xs1' xs2' 
+  where 
+   (xs1, xs2)  = split xs
+   xs1'        = mergeSort xs1
+   xs2'        = mergeSort xs2
+\end{code}
+
+Example: `mergeSort` [2/2]
+--------------------------
+
+\begin{code}
+split (x:y:zs) = (x:xs, y:ys) 
+  where 
+    (xs, ys)   = split zs
+split xs       = (xs, [])
+
+merge xs []    = xs
+merge [] ys    = ys
+merge (x:xs) (y:ys) 
+  | x <= y     = x : merge xs (y:ys)
+  | otherwise  = y : merge (x:xs) ys
+\end{code}
+
+END CUT -->
+
+Example: Binary Trees
+---------------------
+
+`Map` from keys of type `k` to values of type `a` 
+
+<br>
+
+<div class="fragment">
+
+Implemented, as a binary tree:
+
+<br>
+
+\begin{code}
+data Map k a = Tip
+             | Bin Int k a (Map k a) (Map k a)
+\end{code}
+</div>
+
+Two Abstract Refinements
+------------------------
+
+- `l` : relates root `key` with `left`-subtree keys
+- `r` : relates root `key` with `right`-subtree keys
+
+<br>
+
+\begin{code}
+{-@ data Map k a < l :: k -> k -> Prop
+                 , r :: k -> k -> Prop >
+    = Tip
+    | Bin { sz    :: Int
+          , key   :: k
+          , val   :: a
+          , left  :: Map <l,r> k<l key> a
+          , right :: Map <l,r> k<r key> a} @-}
+\end{code}
+
+
+Ex: Binary Search Trees
+-----------------------
+
+Keys are *Binary-Search* Ordered
+
+<br>
+
+\begin{code}
+{-@ type BST k a = 
+      Map <{\r v -> v < r }, 
+           {\r v -> v > r }> 
+          k a                   @-}
+\end{code}
+
+Ex: Minimum Heaps 
+-----------------
+
+Root contains *minimum* value
+
+<br>
+
+\begin{code}
+{-@ type MinHeap k a = 
+      Map <{\r v -> r <= v}, 
+           {\r v -> r <= v}> 
+           k a               @-}
+\end{code}
+
+Ex: Maximum Heaps 
+-----------------
+
+Root contains *maximum* value
+
+<br>
+
+\begin{code}
+{-@ type MaxHeap k a = 
+      Map <{\r v -> r >= v}, 
+           {\r v -> r >= v}> 
+           k a               @-}
+\end{code}
+
+
+Example: Data.Map
+-----------------
+
+Standard Key-Value container
+
+<br>
+
+- <div class="fragment">1300+ non-comment lines</div>
+
+- <div class="fragment">`insert`, `split`, `merge`,...</div>
+
+- <div class="fragment">Rotation, Rebalance,...</div>
+
+<br>
+
+<div class="fragment">
+SMT & inference crucial for [verification](https://github.com/ucsd-progsys/liquidhaskell/blob/master/benchmarks/esop2013-submission/Base.hs)
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Map.hs" target="_blank">Demo:</a> Binary Search Maps
+</div>
+
+Example: Red-Black Tree 
+-----------------------
+
+<br>
+
+Binary-Search Ordered Keys
+
+<br>
+
+[DEMO RBTree-Ord.hs](../hs/RBTree-ord.hs)
+Example: Infinite Streams 
+-------------------------
+
+<br>
+
+How to distinguish between **finite** and **infinite** lists?
+
+<br>
+
+[DEMO Streams.hs](../hs/Streams.hs)
+
+
+Recap: Abstract Refinements
+---------------------------
+
+<div class="fragment">
+
+Decouple invariants from **functions**
+
++ `max`
++ `foldr`
+
+</div>
+
+<br>
+
+<div class="fragment">
+Decouple invariants from **data**
+
++ `List`
++ `Tree`
+
+</div>
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract Refinements over Functions
+5. **Abstract** Refinements over Recursive Data
+6. <div class="fragment">[Evaluation](11_Evaluation.lhs.slides.html)</div>
+<br>
+<br>
+
+<div class="fragment">[[continue...]](11_Evaluation.lhs.slides.html)</div>
diff --git a/docs/slides/BOS14/lhs/09_Laziness.lhs b/docs/slides/BOS14/lhs/09_Laziness.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/09_Laziness.lhs
@@ -0,0 +1,241 @@
+ {#laziness}
+============
+
+<div class="hidden">
+\begin{code}
+module Laziness where
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ LIQUID "--no-termination" @-}
+
+safeDiv :: Int -> Int -> Int
+foo     :: Int -> Int
+-- zero    :: Int 
+-- diverge :: a -> b
+\end{code}
+</div>
+
+
+Lazy Evaluation?
+----------------
+
+
+Lazy Evaluation
+===============
+
+SMT based Verification
+----------------------
+
+Techniques developed for **strict** languages
+
+<br>
+
+<div class="fragment">
+
+-----------------------   ---   ------------------------------------------
+        **Floyd-Hoare**    :    `ESCJava`, `SpecSharp` ...
+     **Model Checkers**    :    `Slam`, `Blast` ...
+   **Refinement Types**    :    `DML`, `Stardust`, `Sage`, `F7`, `F*`, ...
+-----------------------   ---   ------------------------------------------
+
+</div>
+
+<br>
+
+<div class="fragment">
+Surely soundness carries over to Haskell, right?
+</div>
+
+
+Back To the Beginning
+---------------------
+
+\begin{code}
+{-@ safeDiv :: _ -> {v:_ |v /= 0} -> Int @-}
+safeDiv n 0 = liquidError "div-by-zero!"
+safeDiv n d = n `div` d
+\end{code}
+
+<br>
+
+<div class="fragment">
+Should only call `safeDiv` with **non-zero** values
+</div>
+
+An Innocent Function
+--------------------
+
+`foo` returns a value **strictly less than** input.
+
+<br>
+
+\begin{spec}
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+\end{spec}
+
+LiquidHaskell Lies! 
+-------------------
+
+\begin{code}
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0    
+              a = foo z
+          in  
+              (\x -> 2014 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+<div class="fragment">
+Why is this program **deemed safe**?! 
+</div>
+
+
+*Is Safe* With Eager Eval
+-------------------------
+
+\begin{spec}
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2014 `safeDiv` z) a 
+\end{spec}
+
+<br>
+
+**Safe** in Java, ML: program **never hits** divide-by-zero 
+
+*Unsafe* With Lazy Eval
+-----------------------
+
+\begin{spec} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2014 `safeDiv` z) a 
+\end{spec}
+
+<br>
+
+**Unsafe** in Haskell: skips `foo z` **hits** divide-by-zero!
+
+Problem: Divergence
+-------------------
+
+What is denoted by:
+
+$$ e :: \reft{v}{\Int}{p}$$
+
+<br>
+
+<div class="fragment">
+$e$ evaluates to $\Int$ that satisfies $p$  
+</div>
+
+<div class="fragment">
+or
+
+**diverges**! 
+</div>
+
+<div class="fragment">
+<br>
+
+Classical Floyd-Hoare notion of [partial correctness](http://en.wikipedia.org/wiki/Hoare_logic#Partial_and_total_correctness)
+
+</div>
+
+
+
+Problem: Divergence
+-------------------
+
+\begin{spec} **Consider** <div/> 
+        {-@ e :: {v : Int | P} @-}
+
+        let x = e in body 
+\end{spec}
+
+<br>
+
+<div class="fragment">
+**Eager Evaluation** 
+
+*Can* assume `P(x)` when checking `body`
+</div>
+
+<br>
+
+<div class="fragment">
+**Lazy Evaluation** 
+
+*Cannot* assume `P(x)` when checking `body`
+</div>
+
+Eager vs. Lazy Binders 
+----------------------
+
+\begin{spec} 
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2014 `safeDiv` z) a 
+\end{spec}
+
+<br>
+
+Inconsistent `a` is sound for **eager**, unsound for **lazy**
+
+
+Panic! Now what?
+---------------
+
+<div class="fragment">
+**Solution** 
+
+Assign *non-trivial* refinements to *non-diverging* terms!
+</div>
+
+<br>
+
+<div class="fragment">
+**Harder Problem?**
+
+Yikes, doesn't non-divergence mean tracking *permination?*
+</div>
+
+<br>
+
+<div class="fragment">
+**Relax**
+
+Its *easy* ... since we have *refinements*! [[continue...]](10_Termination.lhs.slides.html)
+</div>
+
+<br>
+
+
+
diff --git a/docs/slides/BOS14/lhs/10_Termination.lhs b/docs/slides/BOS14/lhs/10_Termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/10_Termination.lhs
@@ -0,0 +1,336 @@
+Termination {#termination}
+==========================
+
+
+<div class="hidden">
+\begin{code}
+module Termination where
+
+import Prelude hiding (gcd, mod, map)
+fib :: Int -> Int
+gcd :: Int -> Int -> Int
+infixr `C`
+
+data L a = N | C a (L a)
+
+{-@ invariant {v: L a | 0 <= llen v} @-}
+
+mod :: Int -> Int -> Int
+mod a b
+  | a - b >  b = mod (a - b) b
+  | a - b <  b = a - b
+  | a - b == b = 0
+
+merge :: Ord a => L a -> L a -> L a
+\end{code}
+</div>
+
+<!-- BEGIN CUT
+
+Dependent != Refinement
+-----------------------
+
+<div class="fragment">**Dependent Types**</div>
+
++ <div class="fragment">*Arbitrary terms* appear inside types</div> 
++ <div class="fragment">Termination ensures well-defined</div>
+
+<br>
+
+<div class="fragment">**Refinement Types**</div>
+
++ <div class="fragment">*Restricted refinements* appear in types</div>
++ <div class="fragment">Termination *not* required ...</div> 
++ <div class="fragment">... except, alas, with *lazy* evaluation!</div>
+
+END CUT -->
+
+Refinements & Termination
+-------------------------
+
+<div class="fragment">
+Fortunately, we can ensure termination **using refinements**
+</div>
+
+
+Main Idea
+---------
+
+Recursive calls must be on **smaller** inputs
+
+<br>
+
++ [Turing](http://classes.soe.ucsc.edu/cmps210/Winter11/Papers/turing-1936.pdf)
++ [Sized Types](http://dl.acm.org/citation.cfm?id=240882)
++ [DML](http://dl.acm.org/citation.cfm?id=609232)
++ [Size Change Principle](http://dl.acm.org/citation.cfm?id=360210)
+
+Recur On *Smaller* `Nat` 
+------------------------
+
+<div class="fragment">
+
+**To ensure termination of**
+
+\begin{spec} <div/>
+foo   :: Nat -> T
+foo x =  body
+\end{spec}
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:Nat | v < x} -> T`
+
+<br>
+
+*i.e.* require recursive calls have `Nat` inputs *smaller than* `x`
+</div>
+
+
+
+Ex: Recur On *Smaller* `Nat` 
+----------------------------
+
+\begin{code}
+{-@ fib  :: Nat -> Nat @-}
+fib 0    = 1
+fib 1    = 1
+fib n    = fib (n-1) + fib (n-2)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Terminates, as both `n-1` and `n-2` are `< n`
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=GCD.hs" target="_blank">Demo:</a> &nbsp; What if we drop the `fib 1` equation? 
+</div>
+
+Refinements Are Essential!
+--------------------------
+
+\begin{code}
+{-@ gcd :: a:Nat -> {b:Nat | b < a} -> Int @-}
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Need refinements to prove `(a mod b) < b` at *recursive* call!
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ mod :: a:Nat 
+        -> b:{v:Nat|0 < v && v < a} 
+        -> {v:Nat| v < b}           @-}
+\end{code}
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+<br>
+
+What of input types other than `Nat` ?
+
+<br>
+
+[DEMO](../hs/03_Termination.hs)
+
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{spec}<div/>
+foo   :: S -> T
+foo x = body
+\end{spec}
+
+<br>
+
+<div class="fragment">
+**Reduce** to `Nat` case...
+</div>
+
+<br>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{spec}<div/>
+foo   :: S -> T
+foo x = body
+\end{spec}
+
+<br>
+
+Specify a **default measure** `mS :: S -> Int`
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:s | 0 <= mS v < mS x} -> T`
+</div>
+
+
+Ex: Recur on *smaller* `List`
+-----------------------------
+
+\begin{code} 
+map f N        = N
+map f (C x xs) = (f x) `C` (map f xs) 
+\end{code}
+
+<br>
+
+Terminates using **default** measure `llen` 
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ data L [llen] a = N 
+                    | C { x::a, xs :: L a} @-}
+
+{-@ measure llen :: L a -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)   @-}
+\end{code}
+</div>
+
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of smallness spread across **multiple inputs**?
+
+<br>
+
+\begin{code}
+merge xs@(x `C` xs') ys@(y `C` ys')
+  | x < y     = x `C` merge xs' ys
+  | otherwise = y `C` merge xs ys'
+\end{code}
+
+<br>
+
+<div class="fragment">
+Neither input decreases, but their **sum** does.
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+Neither input decreases, but their **sum** does.
+
+<br>
+
+\begin{code}
+{-@ merge :: Ord a => xs:_ -> ys:_ -> _ 
+          /  [llen xs + llen ys]     @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+Synthesize **ghost** parameter equal to `[...]`
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+... thereby reducing to decreasing **single parameter** case. 
+
+</div>
+
+Important Extensions 
+--------------------
+
+<br>
+
+<div class="fragment">**Mutual** recursion</div>
+
+<br>
+
+<div class="fragment">**Lexicographic** ordering</div>
+
+<br>
+
+<div class="fragment">Fit easily into our framework ...</div>
+
+Recap
+-----
+
+Main idea: Recursive calls on **smaller** inputs
+
+<br>
+
+<div class="fragment">Use refinements to **check** smaller</div>
+
+<br>
+
+<div class="fragment">Use refinements to **establish** smaller</div>
+
+
+A Curious Circularity
+---------------------
+
+<div class="fragment">Refinements require termination ...</div> 
+
+<br>
+
+<div class="fragment">... Termination requires refinements!</div>
+
+<br>
+
+<div class="fragment"> Meta-theory is tricky, but all ends well.</div>
+
+Termination in Practice
+-----------------------
+
+<img src="../img/tension1.png" height=300px>
+
+96% proved *terminating*
+
+61% proved *automatically*
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. Lazy Evaluation: Requires Termination
+6. **Termination:** via Refinements!
+7. <div class="fragment">**Evaluation:** How good is this in practice?</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](11_Evaluation.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/BOS14/lhs/11_Evaluation.lhs b/docs/slides/BOS14/lhs/11_Evaluation.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/11_Evaluation.lhs
@@ -0,0 +1,322 @@
+ {#ASda}
+========
+
+Evaluation
+----------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+Evaluation
+==========
+
+LiquidHaskell 
+-------------
+
+<br>
+
+**Diverse Code Bases**
+
+<br>
+
+10KLoc
+
+<br>
+
+56 Modules
+
+LiquidHaskell 
+-------------
+
+<br>
+
+**Complex Properties**
+
+<br>
+
+Memory Safety
+
+
+Functional Correctness*
+
+
+Termination
+
+<br>
+
+<div class="fragment">
+**Inference is Crucial**
+</div>
+
+Benchmarks
+----------
+
+<div align="center">
+
+**Library**                     
+---------------------------   ---------
+`XMonad.StackSet`                      
+`Data.List`                         
+`Data.Set.Splay`                    
+`Data.Vector.Algorithms`           
+`HsColour`                        
+`Data.Map.Base`                
+`Data.Text`                        
+`Data.Bytestring`                  
+---------------------------   ---------
+
+</div>
+
+
+Benchmarks 
+----------
+
+<div align="center">
+
+**Library**                     **LOC**
+---------------------------   ---------
+`XMonad.StackSet`                   256 
+`Data.List`                         814
+`Data.Set.Splay`                    149
+`Data.Vector.Algorithms`           1219
+`HsColour`                         1047
+`Data.Map.Base`                    1396
+`Data.Text`                        3128
+`Data.Bytestring`                  3505
+**Total**                     **11512**
+---------------------------   ---------
+
+</div>
+
+Benchmarks
+----------
+
+<div align="center">
+
+**Library**                     **LOC**     **Specs**    
+---------------------------   ---------   -----------    
+`XMonad.StackSet`                   256            74    
+`Data.List`                         814            46    
+`Data.Set.Splay`                    149            27    
+`Data.Vector.Algorithms`           1219            76    
+`HsColour`                         1047            19    
+`Data.Map.Base`                    1396           125    
+`Data.Text`                        3128           305    
+`Data.Bytestring`                  3505           307    
+**Total**                     **11512**       **977**    
+---------------------------   ---------   -----------    
+
+</div>
+
+
+Code v. Specs 
+-------------
+
+<img src="../img/code-spec-indiv.png" height=400px>
+
+
+Code v. Specs 
+-------------
+
+<br>
+
+<img src="../img/code-spec-total.png" height=100px>
+ 
+**About 8.5%**
+
+*Very* coarse measure...
+
+Running Time
+------------
+
+<div align="center">
+
+**Library**                     **LOC**     **Specs**      **Time**
+---------------------------   ---------   -----------    ----------
+`XMonad.StackSet`                   256            74          27s
+`Data.List`                         814            46          26s
+`Data.Set.Splay`                    149            27          27s
+`Data.Vector.Algorithms`           1219            76          89s 
+`HsColour`                         1047            19         196s
+`Data.Map.Base`                    1396           125         174s
+`Data.Text`                        3128           305         499s
+`Data.Bytestring`                  3505           307         294s
+**Total**                     **11512**       **977**    **1336s**
+---------------------------   ---------   -----------    ----------
+
+</div>
+
+
+
+ {#comments}
+============
+
+Types as Comments
+-----------------
+
+<br>
+
+**Types are Machine Checked Comments**
+
+<br>
+
++ Express same *requirements*
+
++ But *connected to* code
+
+<br>
+
+<div class="fragment">
+**Always in sync as code changes**
+</div>
+
+Liquid Types as Machine Checked Comments
+========================================
+
+Example: Data.Map
+-----------------
+
+<br>
+
+**Requirement**
+
+<br>
+
+`Map a b` is a *binary search* ordered tree
+
+Example: Data.Map
+-----------------
+
+**Comment**
+
+\begin{spec}
+-- @join@ assumes that all values in [l] < [k]
+-- and all values in [r] > [k], and
+-- that [l] and [r] are valid trees.
+\end{spec}
+
+<br>
+
+<div class="fragment">
+
+**Type**
+
+\begin{spec}
+join :: k:a -> b
+     -> l:Map {v:a | v < k} b
+     -> r:Map {v:a | v > k} b
+     -> Map a b 
+\end{spec}
+
+</div>
+
+Example: Data.ByteString
+------------------------
+
+<br>
+
+**Requirement**
+
+<br>
+
+Fast, low-level indices into a `ByteString` must be in bounds.
+
+
+Example: Data.ByteString
+------------------------
+
+**Comment**
+
+\begin{spec}
+-- Unsafe 'ByteString' index (subscript) ...
+-- omits the bounds check, which means there
+-- is an obligation to ensure the bounds are
+-- checked in some other way.
+\end{spec}
+
+<br>
+
+<div class="fragment">
+
+**Type**
+
+\begin{spec}
+unsafeIndex :: b:ByteString
+            -> {v:Nat | v < bLength b}
+            -> Word8 
+\end{spec}
+
+</div>
+
+Example: Data.ByteString
+------------------------
+
+<br>
+
+**Requirement**
+
+<br>
+
+Fast *truncation* requires valid size.
+
+
+Example: Data.ByteString
+------------------------
+
+**Comment**
+
+\begin{spec}
+-- omits the checks on @n@ so there is
+-- an obligation to provide a proof
+-- that @0 <= n <= 'length' xs@             
+\end{spec}
+
+<br>
+
+<div class="fragment">
+**Type**
+
+\begin{spec}
+unsafeTake :: n:Nat
+           -> {v:ByteString | n <= bLength v}
+           -> {v:ByteString | n = bLength v} 
+\end{spec}
+
+</div>
+
+ {#cont}
+=========
+
+
+Continue
+--------
+
+<br>
+<br>
+<br>
+
+[[continue...]](12_Conclusion.lhs.slides.html)
+
+ {#recap}
+=========
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. **Evaluation**
+6. <div class="fragment"><a href="12_Conclusion.lhs.slides.html" target="_blank">Conclusion</a></div>
+
+<br>
+<br>
+
diff --git a/docs/slides/BOS14/lhs/12_Conclusion.lhs b/docs/slides/BOS14/lhs/12_Conclusion.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/12_Conclusion.lhs
@@ -0,0 +1,82 @@
+ {#ASda}
+========
+
+Conclusion
+----------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+Conclusion
+==========
+
+Liquid Types
+------------
+
+<br>
+
+**Types** lift **Program Logic + Analysis** to Modern Programs
+
+<br>
+
+<div class="fragment">
+
+-------------------       ------------------------------------------------
+**Properties:**           Predicates  *+ Types*
+**Proofs:**               SMT Solvers *+ Subtyping*
+**Inference:**            Abstract Interpretation *+ Hindley-Milner*
+-------------------       ------------------------------------------------
+
+</div>
+
+Current & Future Work
+---------------------
+
+<br>
+
+**Technology**
+
+<br>
+
++ GHC
++ Speed
++ Effects
++ *Error Messages*
+
+Current & Future Work
+---------------------
+
+<br>
+
+**Applications**
+
+<br>
+
++ Testing
++ Web frameworks
++ Concurrency
++ Code Completion
+
+ {#asd}
+=======
+
+Thank You!
+----------
+
+<br>
+<br>
+
+`cabal install liquidhaskell`
+
+Thank You!
+----------
+
+<br>
+<br>
+
+[`http://goto.ucsd.edu/liquid`](http://goto.ucsd.edu/liquid)
diff --git a/docs/slides/BOS14/lhs/13_RedBlack.lhs b/docs/slides/BOS14/lhs/13_RedBlack.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/13_RedBlack.lhs
@@ -0,0 +1,268 @@
+
+
+Red-Black Trees
+===============
+
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--diff"           @-}
+
+module RBTree (ok, bad1, bad2) where
+
+import Language.Haskell.Liquid.Prelude
+
+ok, bad1, bad2 :: RBTree Int
+
+---------------------------------------------------------------------------
+-- | Specifications -------------------------------------------------------
+---------------------------------------------------------------------------
+
+-- | Red-Black Trees
+{-@ type RBT a    = {v: RBTree a | isRB v && isBH v } @-}
+
+{-@ measure isRB        :: RBTree a -> Prop
+    isRB (Leaf)         = true
+    isRB (Node c x l r) = isRB l && isRB r && (c == R => (IsB l && IsB r))
+  @-}
+
+-- | Almost Red-Black Trees
+{-@ type ARBT a    = {v: RBTree a | isARB v && isBH v} @-}
+
+{-@ measure isARB        :: (RBTree a) -> Prop
+    isARB (Leaf)         = true 
+    isARB (Node c x l r) = (isRB l && isRB r)
+  @-}
+
+-- | Color of a tree
+{-@ measure col         :: RBTree a -> Color
+    col (Node c x l r)  = c
+    col (Leaf)          = B
+  @-}
+
+{-@ measure isB        :: RBTree a -> Prop
+    isB (Leaf)         = false
+    isB (Node c x l r) = c == B 
+  @-}
+
+{-@ predicate IsB T = not (col T == R) @-}
+
+-- | Black Height
+{-@ measure isBH        :: RBTree a -> Prop
+    isBH (Leaf)         = true
+    isBH (Node c x l r) = (isBH l && isBH r && bh l = bh r)
+  @-}
+
+{-@ measure bh        :: RBTree a -> Int
+    bh (Leaf)         = 0
+    bh (Node c x l r) = bh l + if (c == R) then 0 else 1 
+  @-}
+
+
+-- | Binary Search Ordering
+{-@ data RBTree a = Leaf
+      | Node { c     :: Color
+             , key   :: a
+             , left  :: RBTree ({v:a | v < key})
+             , right :: RBTree ({v:a | key < v}) } @-}
+\end{code}
+
+</div>
+
+
+
+ {#asdad}
+---------
+
+<img src="../img/RedBlack.png" height=300px>
+
++ <div class="fragment">**Color Invariant:** `Red` nodes have `Black` children</div>
++ <div class="fragment">**Height Invariant:** Number of `Black` nodes equal on *all paths*</div>
++ <div class="fragment">**Order Invariant:** Left keys < root < Right keys </div>
+
+
+Basic Type 
+----------
+
+\begin{code}
+data Color = R | B
+
+data RBTree a = Leaf
+              | Node { c     :: Color
+                     , key   :: a
+                     , left  :: RBTree a 
+                     , right :: RBTree a }
+\end{code}
+
+
+1. Color Invariant 
+------------------
+
+`Red` nodes have `Black` children
+
+<div class="fragment">
+\begin{spec}
+measure isRB        :: Tree a -> Prop
+isRB (Leaf)         = true
+isRB (Node c x l r) = c == R => (isB l && isB r)
+                      && isRB l && isRB r
+\end{spec}
+</div>
+
+<div class="fragment">
+where 
+\begin{spec}
+measure isB         :: Tree a -> Prop 
+isB (Leaf)          = true
+isB (Node c x l r)  = c == B
+\end{spec}
+</div>
+
+
+1. *Almost* Color Invariant 
+---------------------------
+
+<br>
+
+Color Invariant **except** at root. 
+
+<br>
+
+<div class="fragment">
+\begin{spec}
+measure isAlmost        :: RBTree a -> Prop
+isAlmost (Leaf)         = true
+isAlmost (Node c x l r) = isRB l && isRB r
+\end{spec}
+</div>
+
+<!-- BEGIN CUT END CUT -->
+
+2. Height Invariant
+-------------------
+
+Number of `Black` nodes equal on **all paths**
+
+<div class="fragment">
+\begin{spec} 
+measure isBH        :: RBTree a -> Prop
+isBH (Leaf)         =  true
+isBH (Node c x l r) =  bh l == bh r 
+                    && isBH l && isBH r 
+\end{spec}
+</div>
+
+<div class="fragment">
+
+where
+
+\begin{spec}
+measure bh        :: RBTree a -> Int
+bh (Leaf)         = 0
+bh (Node c x l r) = bh l 
+                  + if c == R then 0 else 1
+\end{spec}
+</div>
+
+3. Order Invariant
+------------------
+
+**Binary Search Ordering**
+
+\begin{spec}
+data RBTree a
+  = Leaf
+  | Node { c     :: Color
+         , key   :: a
+         , left  :: RBTree {v:a | v < key}
+         , right :: RBTree {v:a | key < v}
+         }
+\end{spec}
+
+
+Valid Red-Black Trees
+---------------------
+
+<br>
+
+**Conjoining Specifications**
+
+<br>
+
+\begin{spec}
+-- | Red-Black Trees
+type RBT a  = {v:RBTree a|isRB v && isBH v}
+
+-- | Almost Red-Black Trees
+type ARBT a = {v:RBTree a|isAlmost v && isBH v}
+\end{spec}
+
+<br>
+
+[Details](https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/pos/RBTree.hs)
+
+Ex: Satisfies Invariants
+-------------------------
+
+<img src="../img/rbtree-ok.png" height=200px>
+
+<br>
+
+\begin{code}
+{-@ ok   :: RBT Int @-}
+ok = Node R 2 
+          (Node B 1 Leaf Leaf)
+          (Node B 3 Leaf Leaf)
+\end{code}
+
+
+Ex: Violates Order Invariant
+----------------------------
+
+<img src="../img/rbtree-bad1.png" height=200px>
+
+<br>
+
+\begin{code}
+{-@ bad1 :: RBT Int @-}
+bad1 = Node R 1
+          (Node B 2 Leaf Leaf)
+          (Node B 3 Leaf Leaf)
+\end{code}
+
+Ex: Violates Color Invariant
+----------------------------
+
+<img src="../img/rbtree-bad2.png" height=200px>
+
+<br>
+
+\begin{code}
+{-@ bad2 :: RBT Int @-}
+bad2 = Node  R 2
+         (Node R 1 Leaf Leaf)
+         (Node B 3 Leaf Leaf)
+\end{code}
+
+
+Verified Red-Black Operations 
+-----------------------------
+
+<br>
+
+**Types Verify Correctness of**
+
+<br>
+
++ Insertion
+
++ Deletion
+
++ Lookup ...
+
+<br>
+
+**In presence of rotation & rebalancing** [[details]](https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/pos/RBTree.hs)
+
diff --git a/docs/slides/BOS14/lhs/14_Memory.lhs b/docs/slides/BOS14/lhs/14_Memory.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/14_Memory.lhs
@@ -0,0 +1,914 @@
+Case Study: Low Level Memory
+============================
+
+ {#mem}
+-------
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--diffcheck"     @-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module Memory where
+
+import Prelude hiding (null)
+import Data.Char
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
+import System.IO.Unsafe
+import Data.ByteString.Internal (c2w, w2c)
+import Language.Haskell.Liquid.Prelude
+\end{code}
+
+</div>
+
+"HeartBleed" in Haskell
+-----------------------
+
+<br>
+
+**Modern languages are built on top of C**
+
+<br>
+
+<div class="fragment">
+Implementation errors could open up vulnerabilities
+</div>
+
+
+
+
+"HeartBleed" in Haskell (1/3)
+-----------------------------
+
+**A String Truncation Function**
+
+<br>
+
+<div class="hidden">
+\begin{spec}
+import Data.ByteString.Char8  (pack, unpack)
+import Data.ByteString.Unsafe (unsafeTake)
+\end{spec}
+</div>
+
+\begin{spec}
+chop     :: String -> Int -> String
+chop s n = s'
+  where
+    b    = pack s         -- down to low-level
+    b'   = unsafeTake n b -- grab n chars
+    s'   = unpack b'      -- up to high-level
+\end{spec}
+
+"HeartBleed" in Haskell (2/3)
+-----------------------------
+
+<img src="../img/overflow.png" height=100px>
+
+
+Works if you use the **valid prefix** size
+
+<br>
+
+\begin{spec}
+λ> let ex = "Ranjit Loves Burritos"
+
+λ> heartBleed ex 10
+"Ranjit Lov"
+\end{spec}
+
+
+"HeartBleed" in Haskell (3/3)
+-----------------------------
+
+<img src="../img/overflow.png" height=100px>
+
+Leaks *overflow buffer* if **invalid prefix** size!
+
+<br>
+
+\begin{spec}
+λ> let ex = "Ranjit Loves Burritos"
+
+λ> heartBleed ex 30
+"Ranjit Loves Burritos\NUL\201\&1j\DC3\SOH\NUL"
+\end{spec}
+
+Types Against Overflows
+-----------------------
+
+<br>
+
+**Strategy: Specify and Verify Types for**
+
+<br>
+
+1. <div class="fragment">Low-level `Pointer` API</div>
+2. <div class="fragment">Lib-level `ByteString` API</div>
+3. <div class="fragment">User-level `Application` API</div>
+
+<br>
+
+<div class="fragment">Errors at *each* level are prevented by types at *lower* levels</div>
+
+ {#ptr}
+=======
+
+1. Low-level Pointer API
+------------------------
+
+<br>
+
+Strategy: Specify and Verify Types for
+
+<br>
+
+1. **Low-level `Pointer` API**
+2. Lib-level `ByteString` API
+3. User-level `Application` API
+
+<br>
+
+Errors at *each* level are prevented by types at *lower* levels
+
+
+
+
+1. Low-Level Pointer API
+========================
+
+API: Types
+----------
+
+<br>
+
+**Low-level Pointers**
+
+\begin{spec}
+data Ptr a
+\end{spec}
+
+<br>
+
+<div class="fragment">
+**Foreign Pointers**
+
+\begin{spec}
+data ForeignPtr a
+\end{spec}
+
+<br>
+
+`ForeignPtr` wraps around `Ptr`; can be exported to/from C.
+</div>
+
+
+API: Operations (1/2)
+---------------------
+
+<div class="fragment">
+**Read**
+
+\begin{spec}
+peek     :: Ptr a -> IO a
+\end{spec}
+</div>
+
+<br>
+<div class="fragment">
+**Write**
+
+\begin{spec}
+poke     :: Ptr a -> a -> IO ()
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+**Arithmetic**
+\begin{spec}
+plusPtr  :: Ptr a -> Int -> Ptr b
+\end{spec}
+</div>
+
+API: Operations (2/2)
+---------------------
+
+<div class="fragment">
+**Create**
+
+\begin{spec}
+malloc  :: Int -> ForeignPtr a
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+**Unwrap and Use**
+
+\begin{spec}
+withForeignPtr :: ForeignPtr a     -- pointer
+               -> (Ptr a -> IO b)  -- action
+               -> IO b             -- result
+\end{spec}
+</div>
+
+Example
+-------
+
+**Allocate a block and write 4 zeros into it**
+
+<div class="fragment">
+
+\begin{code}
+zero4 = do fp <- malloc 4
+           withForeignPtr fp $ \p -> do
+             poke (p `plusPtr` 0) zero
+             poke (p `plusPtr` 1) zero
+             poke (p `plusPtr` 2) zero
+             poke (p `plusPtr` 3) zero
+           return fp
+        where
+           zero = 0 :: Word8
+\end{code}
+
+</div>
+
+Example
+-------
+
+**Allocate a block and write 4 zeros into it**
+
+How to *prevent overflows* e.g. writing 5 or 50 zeros?
+
+<br>
+
+<div class="fragment">
+**Step 1**
+
+*Refine pointers* with allocated size
+</div>
+
+<br>
+
+<div class="fragment">
+**Step 2**
+
+*Track sizes* in pointer operations
+</div>
+
+Refined API: Types
+------------------
+
+<br>
+
+**1. Refine pointers with allocated size**
+
+\begin{spec}
+measure plen  :: Ptr a -> Int
+measure fplen :: ForeignPtr a -> Int
+\end{spec}
+
+<br>
+
+<div class="fragment">
+Abbreviations for pointers of size `N`
+
+\begin{spec}
+type PtrN a N        = {v:_ |  plen v  = N}
+type ForeignPtrN a N = {v:_ |  fplen v = N}
+\end{spec}
+</div>
+
+
+Refined API: Ops (1/3)
+----------------------
+
+<div class="fragment">
+**Create**
+
+\begin{spec}
+malloc  :: n:Nat -> ForeignPtrN a n
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+**Unwrap and Use**
+
+\begin{spec}
+withForeignPtr :: fp:ForeignPtr a
+               -> (PtrN a (fplen fp) -> IO b)
+               -> IO b
+\end{spec}
+</div>
+
+Refined API: Ops (2/3)
+----------------------
+
+<br>
+
+**Arithmetic**
+
+Refine type to track *remaining* buffer size
+
+<br>
+
+<div class="fragment">
+\begin{spec}
+plusPtr :: p:Ptr a
+        -> o:{Nat|o <= plen p}   -- in bounds
+        -> PtrN b (plen b - o)   -- remainder
+\end{spec}
+
+</div>
+
+
+
+Refined API: Ops (3/3)
+----------------------
+
+**Read & Write require non-empty remaining buffer**
+
+<br>
+
+<div class="fragment">
+**Read**
+
+\begin{spec}
+peek :: {v:Ptr a | 0 < plen v} -> IO a
+\end{spec}
+</div>
+
+<br>
+<div class="fragment">
+**Write**
+
+\begin{spec}
+poke :: {v:Ptr a | 0 < plen v} -> a -> IO ()
+\end{spec}
+</div>
+
+Example: Overflow Prevented
+---------------------------
+
+How to *prevent overflows* e.g. writing 5 or 50 zeros?
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+exBad = do fp <- malloc 4
+           withForeignPtr fp $ \p -> do
+             poke (p `plusPtr` 0) zero
+             poke (p `plusPtr` 1) zero
+             poke (p `plusPtr` 2) zero
+             poke (p `plusPtr` 5) zero
+           return fp
+        where
+           zero = 0 :: Word8
+\end{code}
+
+</div>
+
+ {#bs}
+======
+
+2. ByteString API
+-----------------
+
+<br>
+
+Strategy: Specify and Verify Types for
+
+<br>
+
+1. Low-level `Pointer` API
+2. **Lib-level `ByteString` API**
+3. User-level `Application` API
+
+<br>
+
+Errors at *each* level are prevented by types at *lower* levels
+
+
+2. ByteString API
+=================
+
+Type
+-------
+
+<img src="../img/bytestring.png" height=150px>
+
+\begin{code}
+data ByteString = PS {
+    bPtr :: ForeignPtr Word8
+  , bOff :: !Int
+  , bLen :: !Int
+  }
+\end{code}
+
+
+Refined Type
+------------
+
+<img src="../img/bytestring.png" height=150px>
+
+\begin{code}
+{-@ data ByteString = PS {
+      bPtr :: ForeignPtr Word8
+    , bOff :: {v:Nat| v        <= fplen bPtr}
+    , bLen :: {v:Nat| v + bOff <= fplen bPtr}
+    }                                       @-}
+\end{code}
+
+Refined Type
+------------
+
+<img src="../img/bytestring.png" height=150px>
+
+<br>
+
+**A Useful Abbreviation**
+
+\begin{spec}
+type ByteStringN N = {v:ByteString| bLen v = N}
+\end{spec}
+
+
+<div class="hidden">
+\begin{code}
+{-@ type ByteStringN N = {v:ByteString | bLen v = N} @-}
+\end{code}
+</div>
+
+
+
+Legal Bytestrings
+-----------------
+
+
+<br>
+
+\begin{code}
+{-@ good1 :: IO (ByteStringN 5) @-}
+good1 = do fp <- malloc 5
+           return (PS fp 0 5)
+
+{-@ good2 :: IO (ByteStringN 3) @-}
+good2 = do fp <- malloc 5
+           return (PS fp 2 3)
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Note:** *length* of `good2` is `3` which is *less than* allocated size `5`
+</div>
+
+Illegal Bytestrings
+-----------------
+
+<br>
+
+\begin{code}
+bad1 = do fp <- malloc 3
+          return (PS fp 0 10)
+
+bad2 = do fp <- malloc 3
+          return (PS fp 2 2)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Claimed length *exceeds* allocation ... **rejected** at compile time
+</div>
+
+API: `create`
+-------------
+
+<div class="hidden">
+\begin{code}
+create :: Int -> (Ptr Word8 -> IO ()) -> ByteString
+\end{code}
+</div>
+
+*Allocate* and *fill* a `ByteString`
+
+<br>
+
+<div class="fragment">
+**Specification**
+\begin{code}
+{-@ create :: n:Nat -> (PtrN Word8 n -> IO ())
+           -> ByteStringN n                @-}
+\end{code}
+</div>
+
+
+<div class="fragment">
+**Implementation**
+
+\begin{code}
+create n fill = unsafePerformIO $ do
+  fp  <- malloc n
+  withForeignPtr fp fill
+  return (PS fp 0 n)
+\end{code}
+</div>
+
+<!-- CUT
+<div class="fragment">
+Yikes, there is an error! How to fix?
+</div>
+-->
+
+API: `pack`
+------------
+
+**Specification**
+
+\begin{code}
+{-@ pack :: s:String -> ByteStringN (len s) @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+**Implementation**
+
+\begin{code}
+pack str      = create n $ \p -> go p xs
+  where
+  n           = length str
+  xs          = map c2w str
+  go p (x:xs) = poke p x >> go (plusPtr p 1) xs
+  go _ []     = return  ()
+\end{code}
+
+</div>
+
+
+
+API: `unsafeTake`
+-----------------
+
+Extract *prefix* string of size `n`
+
+<br>
+
+<div class="fragment">
+**Specification**
+
+\begin{code}
+{-@ unsafeTake :: n:Nat
+               -> b:{ByteString | n <= bLen b}
+               -> ByteStringN n            @-}
+\end{code}
+</div>
+
+
+<br>
+
+<div class="fragment">
+**Implementation**
+
+\begin{code}
+unsafeTake n (PS x s l) = PS x s n
+\end{code}
+</div>
+
+API: `unpack`
+-------------
+
+**Specification**
+
+\begin{spec}
+unpack
+ :: b:ByteString -> StringN (bLen b)
+\end{spec}
+
+<br>
+
+<div class="fragment">
+**Implementation**
+
+\begin{spec}
+unpack b = you . get . the . idea -- see source
+\end{spec}
+</div>
+
+<div class="hidden">
+\begin{code}
+{-@ qualif Unpack(v:a, acc:b, n:int) : len v = 1 + n + len acc @-}
+
+{-@ unpack :: b:ByteString -> StringN (bLen b) @-}
+unpack :: ByteString -> String
+unpack (PS _  _ 0)  = []
+unpack (PS ps s l)  = unsafePerformIO $ withForeignPtr ps $ \p ->
+   go (p `plusPtr` s) (l - 1)  []
+  where
+   go p 0 acc = peek p >>= \e -> return (w2c e : acc)
+   go p n acc = peek (p `plusPtr` n) >>=   \e -> go p (n-1) (w2c e : acc)
+\end{code}
+
+</div>
+
+ {#heartbleedredux}
+==================
+
+
+3. Application API
+-------------------
+
+
+<br>
+
+Strategy: Specify and Verify Types for
+
+<br>
+
+1. Low-level `Pointer` API
+2. Lib-level `ByteString` API
+3. **User-level `Application` API**
+
+<br>
+
+Errors at *each* level are prevented by types at *lower* levels
+
+3. Application API
+==================
+
+Revisit "HeartBleed"
+--------------------
+
+Lets revisit our potentially "bleeding" `chop`
+
+<br>
+
+<div class="hidden">
+\begin{code}
+{-@ type StringN N = {v:String | len v = N} @-}
+\end{code}
+</div>
+<div class="fragment">
+
+\begin{code}
+{-@ chop :: s:String
+         -> n:{Nat | n <= len s}
+         -> StringN n
+  @-}
+chop s n =  s'
+  where
+    b    = pack s          -- down to low-level
+    b'   = unsafeTake n b  -- grab n chars
+    s'   = unpack b'       -- up to high-level
+\end{code}
+
+<!-- BEGIN CUT
+<br>
+
+Yikes! How shall we fix it?
+
+     END CUT -->
+</div>
+
+<!-- BEGIN CUT
+
+A Well Typed `chop`
+-------------------
+
+\begin{spec}
+{-@ chop :: s:String
+         -> n:{Nat | n <= len s}
+         -> {v:String | len v = n} @-}
+chop s n = s'
+  where
+    b    = pack s          -- down to low-level
+    b'   = unsafeTake n b  -- grab n chars
+    s'   = unpack b'       -- up to high-level
+\end{spec}
+
+END CUT -->
+
+"HeartBleed" no more
+--------------------
+
+<br>
+
+\begin{code}
+demo     = [ex6, ex30]
+  where
+    ex   = ['N','o','r','m','a','n']
+    ex6  = chop ex 6  -- ok
+    ex30 = chop ex 30  -- out of bounds
+\end{code}
+
+<br>
+
+"Bleeding" `chop ex 30` *rejected* by compiler
+
+Recap: Types vs Overflows
+-------------------------
+
+<br>
+
+**Strategy: Specify and Verify Types for**
+
+<br>
+
+1. Low-level `Pointer` API
+2. Lib-level `ByteString` API
+3. User-level `Application` API
+
+<br>
+
+**Errors at *each* level are prevented by types at *lower* levels**
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="hidden">
+Bonus Material
+==============
+
+Nested ByteStrings
+------------------
+
+For a more in depth example, let's take a look at `group`,
+which transforms strings like
+
+   `"foobaaar"`
+
+into *lists* of strings like
+
+   `["f","oo", "b", "aaa", "r"]`.
+
+The specification is that `group` should produce a list of `ByteStrings`
+
+1. that are all *non-empty* (safety)
+2. the sum of whose lengths is equal to the length of the input string (precision)
+
+We use the type alias
+
+\begin{code}
+{-@ type ByteStringNE = {v:ByteString | bLen v > 0} @-}
+\end{code}
+
+to specify (safety) and introduce a new measure
+
+\begin{code}
+{-@ measure bLens  :: [ByteString] -> Int
+    bLens ([])   = 0
+    bLens (x:xs) = (bLen x + bLens xs)
+  @-}
+\end{code}
+
+to specify (precision). The full type-specification looks like this:
+
+\begin{code}
+{-@ group :: b:ByteString -> {v: [ByteStringNE] | bLens v = bLen b} @-}
+group xs
+    | null xs   = []
+    | otherwise = let y = unsafeHead xs
+                      (ys, zs) = spanByte (unsafeHead xs) (unsafeTail xs)
+                  in (y `cons` ys) : group zs
+\end{code}
+
+As you can probably tell, `spanByte` appears to be doing a lot of the work here,
+so let's take a closer look at it to see why the post-condition holds.
+
+\begin{code}
+spanByte :: Word8 -> ByteString -> (ByteString, ByteString)
+spanByte c ps@(PS x s l) = unsafePerformIO $ withForeignPtr x $ \p ->
+    go (p `plusPtr` s) 0
+  where
+    go p i | i >= l    = return (ps, empty)
+           | otherwise = do c' <- peekByteOff p i
+                            if c /= c'
+                                then return (unsafeTake i ps, unsafeDrop i ps)
+                                else go p (i+1)
+\end{code}
+
+LiquidHaskell infers that `0 <= i <= l` and therefore that all of the memory
+accesses are safe. Furthermore, due to the precise specifications given to
+`unsafeTake` and `unsafeDrop`, it is able to prove that `spanByte` has the type
+
+\begin{code}
+{-@ spanByte :: Word8 -> b:ByteString -> (ByteStringPair b) @-}
+\end{code}
+
+where `ByteStringPair b` describes a pair of `ByteString`s whose
+lengths sum to the length of `b`.
+
+\begin{code}
+{-@ type ByteStringPair B = (ByteString, ByteString)<{\x1 x2 ->
+       bLen x1 + bLen x2 = bLen B}> @-}
+\end{code}
+
+
+
+
+
+
+
+
+\begin{code}
+-----------------------------------------------------------------------
+-- Helper Code
+-----------------------------------------------------------------------
+
+{-@ unsafeCreate :: l:Nat -> ((PtrN Word8 l) -> IO ()) -> (ByteStringN l) @-}
+unsafeCreate n f = create n f -- unsafePerformIO $ create n f
+
+{-@ invariant {v:ByteString   | bLen  v >= 0} @-}
+{-@ invariant {v:[ByteString] | bLens v >= 0} @-}
+
+{-@ qualif PLLen(v:a, p:b) : (len v) <= (plen p) @-}
+{-@ qualif ForeignPtrN(v:ForeignPtr a, n:int): fplen v = n @-}
+{-@ qualif FPLenPLen(v:Ptr a, fp:ForeignPtr a): fplen fp = plen v @-}
+{-@ qualif PtrLen(v:Ptr a, xs:List b): plen v = len xs @-}
+{-@ qualif PlenEq(v: Ptr a, x: int): x <= (plen v) @-}
+
+{-@ unsafeHead :: {v:ByteString | (bLen v) > 0} -> Word8 @-}
+
+unsafeHead :: ByteString -> Word8
+unsafeHead (PS x s l) = liquidAssert (l > 0) $
+  unsafePerformIO  $  withForeignPtr x $ \p -> peekByteOff p s
+
+{-@ unsafeTail :: b:{v:ByteString | (bLen v) > 0}
+               -> {v:ByteString | (bLen v) = (bLen b) - 1} @-}
+unsafeTail :: ByteString -> ByteString
+unsafeTail (PS ps s l) = liquidAssert (l > 0) $ PS ps (s+1) (l-1)
+
+{-@ null :: b:ByteString -> {v:Bool | ((Prop v) <=> ((bLen b) = 0))} @-}
+null :: ByteString -> Bool
+null (PS _ _ l) = liquidAssert (l >= 0) $ l <= 0
+
+{-@ unsafeDrop :: n:Nat
+               -> b:{v: ByteString | n <= (bLen v)}
+               -> {v:ByteString | (bLen v) = (bLen b) - n} @-}
+unsafeDrop  :: Int -> ByteString -> ByteString
+unsafeDrop n (PS x s l) = liquidAssert (0 <= n && n <= l) $ PS x (s+n) (l-n)
+
+{-@ cons :: Word8 -> b:ByteString -> {v:ByteString | (bLen v) = 1 + (bLen b)} @-}
+cons :: Word8 -> ByteString -> ByteString
+cons c (PS x s l) = unsafeCreate (l+1) $ \p -> withForeignPtr x $ \f -> do
+        poke p c
+        memcpy (p `plusPtr` 1) (f `plusPtr` s) (fromIntegral l)
+
+{-@ empty :: {v:ByteString | (bLen v) = 0} @-}
+empty :: ByteString
+empty = PS nullForeignPtr 0 0
+
+{-@ assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignPtrN a n) @-}
+{-@ type ForeignPtrN a N = {v:ForeignPtr a | fplen v = N} @-}
+{-@ malloc :: n:Nat -> IO (ForeignPtrN a n) @-}
+malloc = mallocForeignPtrBytes
+
+{-@ assume
+    c_memcpy :: dst:(PtrV Word8)
+             -> src:(PtrV Word8)
+             -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))}
+             -> IO (Ptr Word8)
+  @-}
+foreign import ccall unsafe "string.h memcpy" c_memcpy
+    :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)
+
+{-@ memcpy :: dst:(PtrV Word8)
+           -> src:(PtrV Word8)
+           -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))}
+           -> IO ()
+  @-}
+memcpy :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()
+memcpy p q s = c_memcpy p q s >> return ()
+
+{-@ assume nullForeignPtr :: {v: ForeignPtr Word8 | (fplen v) = 0} @-}
+nullForeignPtr :: ForeignPtr Word8
+nullForeignPtr = unsafePerformIO $ newForeignPtr_ nullPtr
+{-# NOINLINE nullForeignPtr #-}
+\end{code}
+
+</div>
diff --git a/docs/slides/BOS14/lhs/Index-Boston-Haskell.lhs b/docs/slides/BOS14/lhs/Index-Boston-Haskell.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/Index-Boston-Haskell.lhs
@@ -0,0 +1,160 @@
+<div class="hidden">
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+</div>
+
+LiquidHaskell 
+==============
+
+Refinement Types for Haskell
+------------------------------
+
+
+<br>
+<br>
+
+<div class="fragment">
+**Ranjit Jhala**
+
+University of California, San Diego
+
+<br>
+<br>
+
+Joint work with: 
+
+N. Vazou, E. Seidel, P. Rondon, M. Kawaguchi
+
+D. Vytiniotis, S. Peyton-Jones
+
+</div>
+
+
+ {#plan}
+-------
+
+**Part I**
+
+Refinement Types
+
+<br>
+
+<div class="fragment">
+**Part II**
+
+Case Studies
+</div>
+
+<br>
+
+
+<div class="fragment">
+**Part III**
+
+Haskell (Lazy Evaluation)
+</div>
+
+ {#plan}
+--------
+
+
+<br>
+
+(And *if* we have time...)
+
+
+<br>
+
+**Part IV**
+
+Abstract Refinements
+
+I: Refinement Types
+-------------------
+
+<br>
+
+<a href="00_Motivation.lhs.slides.html" target="_blank">**Motivation**</a>
+
+<br>
+
+<div class="fragment">
+<a href="01_SimpleRefinements.lhs.slides.html" target="_blank">**Refinements**</a>
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="02_Measures.lhs.slides.html" target= "_blank">**Measures**</a>
+</div>
+
+II: Case Studies 
+----------------
+
+<br>
+
+<a href="13_RedBlack.lhs.slides.html" target="_blank">**Red-Black Trees**</a>
+
+<br>
+
+<a href="14_Memory.lhs.slides.html" target="_blank">**Low-level Memory Safety**</a>
+
+
+III: Haskell
+------------
+
+<br>
+
+<a href="09_Laziness.lhs.slides.html" target="_blank">**Lazy Evaluation**</a>
+
+<br>
+
+<div class="fragment">
+<a href="10_Termination.lhs.slides.html" target="_blank">**Termination**</a>
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="11_Evaluation.lhs.slides.html" target="_blank">**Evaluation**</a>
+</div>
+
+
+IV: Abstract Refinements
+------------------------
+
+
+<br>
+
+<a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">**Abstracting Refinements over Types**</a>
+
+<br>
+
+<div class="fragment">
+
+**Demos**
+
+<br>
+
++ [Basic](../hs/02_AbstractRefinements.hs)
++ [Induction](../hs/02_AbstractRefinements.hs)
++ [Recursion](../hs/02_AbstractRefinements.hs)
++ [Key-Value](../hs/02_AbstractRefinements.hs)
+
+</div>
+
+
+Conclusion
+----------
+
+<br>
+<br>
+<br>
+
+<div class="fragment">
+
+<a href="12_Conclusion.lhs.slides.html" target="_blank">[Continue]</a>
+
+</div>
+
diff --git a/docs/slides/BOS14/lhs/Index-Tufts.lhs b/docs/slides/BOS14/lhs/Index-Tufts.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/Index-Tufts.lhs
@@ -0,0 +1,73 @@
+<div class="hidden">
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+</div>
+
+LiquidHaskell 
+==============
+
+Refinement Types for Haskell
+------------------------------
+
+
+<br>
+<br>
+
+<div class="fragment">
+**Ranjit Jhala**
+
+University of California, San Diego
+
+<br>
+<br>
+
+Joint work with: 
+
+N. Vazou, E. Seidel, P. Rondon, M. Kawaguchi
+
+D. Vytiniotis, S. Peyton-Jones
+
+</div>
+
+ {#motivation}
+--------------
+
+
+<br>
+<br>
+
+<a href="00_Motivation_Long.lhs.slides.html" target="_blank">[Continue...]</a>
+
+
+Plan
+----
+
+<div class="fragment">
+<a href="01_SimpleRefinements.lhs.slides.html" target="_blank">**Refinement Types**</a>
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="02_Measures.lhs.slides.html" target= "_blank">**Data Structures**</a>
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="14_Memory.lhs.slides.html" target="_blank">**Low-level Memory Safety**</a>
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="11_Evaluation.lhs.slides.html" target="_blank">**Evaluation**</a>
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="12_Conclusion.lhs.slides.html" target="_blank">**Conclusion**</a>
+</div>
+
diff --git a/docs/slides/BOS14/lhs/Index.lhs b/docs/slides/BOS14/lhs/Index.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/BOS14/lhs/Index.lhs
@@ -0,0 +1,49 @@
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+
+ {#ASD}
+=======
+
+
+Abstract Refinement Types
+-------------------------
+
+
+<br>
+<br>
+
+**Ranjit Jhala**
+
+University of California, San Diego
+
+<br>
+<br>
+
+Joint work with: 
+
+N. Vazou, E. Seidel, P. Rondon, D. Vytiniotis, S. Peyton-Jones
+
+<br>
+
+<div class="fragment">
+[[continue]](00_Motivation.lhs.slides.html)
+</div>
+
+
+Plan 
+----
+
++ <a href="00_Motivation.lhs.slides.html" target="_blank">Motivation</a>
++ <div class="fragment"><a href="01_SimpleRefinements.lhs.slides.html" target="_blank">Refinements</a></div>
++ <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
++ <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements:</a> <a href="06_Inductive.lhs.slides.html" target="_blank">Functions</a>,<a href="08_Inductive.lhs.slides.html" target="_blank">Trees</a>,<a href="07_Array.lhs.slides.html" target= "_blank">Arrays</a></div>
++ <div class="fragment"><a href="11_Evaluation.lhs.slides.html" target="_blank">Evaluation</a></div>
++ <div class="fragment"><a href="12_Conclusion.lhs.slides.html" target="_blank">Conclusion</a></div>
+
diff --git a/docs/slides/ETH14/Makefile b/docs/slides/ETH14/Makefile
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/Makefile
@@ -0,0 +1,92 @@
+####################################################################
+SERVERHOME=nvazou@goto.ucsd.edu:~/public_html/liquidtutorial/
+RJSERVER=rjhala@goto.ucsd.edu:~/public_html/liquid/haskell/plpv/lhs/
+## LOCAL
+## MATHJAX=file:///Users/rjhala/research/MathJax
+## REMOTE 
+MATHJAX=https://c328740.ssl.cf1.rackcdn.com/mathjax/latest
+####################################################################
+
+STRIPCODE=./MkCode.hs
+
+REVEAL=pandoc \
+	   --from=markdown\
+	   --to=html5                           \
+	   --standalone                         \
+	   --mathjax \
+	   --section-divs                       \
+	   --template=_support/template.reveal  \
+	   --variable reveal=../_support/reveal.js \
+	   --variable mathjax=$(MATHJAX)
+
+FREVEAL=pandoc \
+ 	   --from=markdown+lhs\
+	   --to=html5                           \
+	   --standalone                         \
+	   --mathjax \
+	   --section-divs                       \
+	   --template=_support/template.reveal  \
+	   --variable reveal=../_support/reveal.js
+
+PANDOC=pandoc --columns=80  -s --mathjax --slide-level=2
+SLIDY=$(PANDOC) -t slidy
+DZSLIDES=$(PANDOC) --highlight-style tango --css=slides.css -w dzslides
+HANDOUT=$(PANDOC) --highlight-style tango --css=text.css -w html5
+WEBTEX=$(PANDOC) -s --webtex -i -t slidy
+BEAMER=pandoc -t beamer
+LIQUID=liquid --short-names 
+
+mdObjects   := $(patsubst %.lhs,%.lhs.markdown,$(wildcard lhs/*.lhs))
+htmlObjects := $(patsubst %.lhs,%.lhs.slides.html,$(wildcard lhs/*.lhs))
+pdfObjects  := $(patsubst %.lhs,%.lhs.slides.pdf,$(wildcard lhs/*.lhs))
+fhtmlObjects := $(patsubst %.lhs,%.fast.html,$(wildcard lhs/*.lhs))
+
+####################################################################
+
+
+all: slides 
+
+fast: $(fhtmlObjects)
+
+one: $(mdObjects)
+	$(REVEAL) lhs/.liquid/00_Index.lhs.markdown > lhs/index.html
+
+tut: $(mdObjects)
+	$(REVEAL) lhs/.liquid/*.markdown > lhs/tutorial.html 
+
+slides: $(htmlObjects)
+
+pdfslides: $(pdfObjects)
+
+lhs/.liquid/%.lhs.markdown: lhs/%.lhs
+	-$(LIQUID) $?
+
+
+lhs/%.fast: lhs/%.lhs
+	$(STRIPCODE) $? > $@ 
+
+lhs/%.fast.html: lhs/%.fast
+	$(FREVEAL) $? -o $@ 
+
+lhs/%.lhs.slides.html: lhs/.liquid/%.lhs.markdown
+	$(REVEAL) $? -o $@ 
+
+lhs/%.lhs.slides.pdf: lhs/.liquid/%.lhs.markdown
+	$(BEAMER) $? -o $@
+
+
+copy:
+	cp lhs/*lhs.html html/
+	cp lhs/*lhs.slides.html html/
+	cp css/*.css html/
+	cp -r fonts html/
+	cp index.html html/
+	cp Benchmarks.html html/
+
+clean:
+	cd lhs/ && ../cleanup && cd ../
+#	cd html/ && rm -rf * && cd ../
+#	cp index.html html/
+
+upload: 
+	scp -r html/* $(SERVERHOME)
diff --git a/docs/slides/ETH14/MkCode.hs b/docs/slides/ETH14/MkCode.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/MkCode.hs
@@ -0,0 +1,17 @@
+#!/usr/bin/env runhaskell
+
+import System.Environment   (getArgs)
+import System.FilePath      (replaceExtension)
+import Data.Char            (isSpace)
+import Data.List            (isPrefixOf)
+
+main     = getArgs >>= mapM txFile 
+
+txFile f = (putStrLn . unlines . map txLine . lines) =<< readFile f
+
+txLine l 
+  | pfx `isPrefixOf` l = pfx
+  | otherwise          = l
+  where
+    pfx                = "\\begin{code}"
+
diff --git a/docs/slides/ETH14/_support/liquid.css b/docs/slides/ETH14/_support/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/liquid.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/ETH14/_support/liquidhaskell.css b/docs/slides/ETH14/_support/liquidhaskell.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/liquidhaskell.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/ETH14/_support/reveal.js/.travis.yml b/docs/slides/ETH14/_support/reveal.js/.travis.yml
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - 0.8
+before_script:
+  - npm install -g grunt-cli
diff --git a/docs/slides/ETH14/_support/reveal.js/Gruntfile.js b/docs/slides/ETH14/_support/reveal.js/Gruntfile.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/Gruntfile.js
@@ -0,0 +1,137 @@
+/* global module:false */
+module.exports = function(grunt) {
+	var port = grunt.option('port') || 8000;
+	// Project configuration
+	grunt.initConfig({
+		pkg: grunt.file.readJSON('package.json'),
+		meta: {
+			banner:
+				'/*!\n' +
+				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
+				' * http://lab.hakim.se/reveal-js\n' +
+				' * MIT licensed\n' +
+				' *\n' +
+				' * Copyright (C) 2014 Hakim El Hattab, http://hakim.se\n' +
+				' */'
+		},
+
+		qunit: {
+			files: [ 'test/*.html' ]
+		},
+
+		uglify: {
+			options: {
+				banner: '<%= meta.banner %>\n'
+			},
+			build: {
+				src: 'js/reveal.js',
+				dest: 'js/reveal.min.js'
+			}
+		},
+
+		cssmin: {
+			compress: {
+				files: {
+					'css/reveal.min.css': [ 'css/reveal.css' ]
+				}
+			}
+		},
+
+		sass: {
+			main: {
+				files: {
+					'css/theme/default.css': 'css/theme/source/default.scss',
+					'css/theme/beige.css': 'css/theme/source/beige.scss',
+					'css/theme/night.css': 'css/theme/source/night.scss',
+					'css/theme/serif.css': 'css/theme/source/serif.scss',
+					'css/theme/simple.css': 'css/theme/source/simple.scss',
+					'css/theme/sky.css': 'css/theme/source/sky.scss',
+					'css/theme/moon.css': 'css/theme/source/moon.scss',
+					'css/theme/solarized.css': 'css/theme/source/solarized.scss',
+					'css/theme/blood.css': 'css/theme/source/blood.scss'
+				}
+			}
+		},
+
+		jshint: {
+			options: {
+				curly: false,
+				eqeqeq: true,
+				immed: true,
+				latedef: true,
+				newcap: true,
+				noarg: true,
+				sub: true,
+				undef: true,
+				eqnull: true,
+				browser: true,
+				expr: true,
+				globals: {
+					head: false,
+					module: false,
+					console: false,
+					unescape: false
+				}
+			},
+			files: [ 'Gruntfile.js', 'js/reveal.js' ]
+		},
+
+		connect: {
+			server: {
+				options: {
+					port: port,
+					base: '.'
+				}
+			}
+		},
+
+		zip: {
+			'reveal-js-presentation.zip': [
+				'index.html',
+				'css/**',
+				'js/**',
+				'lib/**',
+				'images/**',
+				'plugin/**'
+			]
+		},
+
+		watch: {
+			main: {
+				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
+				tasks: 'default'
+			},
+			theme: {
+				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
+				tasks: 'themes'
+			}
+		}
+
+	});
+
+	// Dependencies
+	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
+	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
+	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
+	grunt.loadNpmTasks( 'grunt-contrib-watch' );
+	grunt.loadNpmTasks( 'grunt-contrib-sass' );
+	grunt.loadNpmTasks( 'grunt-contrib-connect' );
+	grunt.loadNpmTasks( 'grunt-zip' );
+
+	// Default task
+	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );
+
+	// Theme task
+	grunt.registerTask( 'themes', [ 'sass' ] );
+
+	// Package presentation to archive
+	grunt.registerTask( 'package', [ 'default', 'zip' ] );
+
+	// Serve presentation locally
+	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );
+
+	// Run tests
+	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );
+
+};
diff --git a/docs/slides/ETH14/_support/reveal.js/LICENSE b/docs/slides/ETH14/_support/reveal.js/LICENSE
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.eot b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.eot
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.eot differ
diff --git a/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.svg b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.svg
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.svg
@@ -0,0 +1,230 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="LeagueGothicRegular" horiz-adv-x="724" >
+<font-face units-per-em="2048" ascent="1505" descent="-543" />
+<missing-glyph horiz-adv-x="315" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="2048" />
+<glyph unicode="&#xd;" horiz-adv-x="682" />
+<glyph unicode=" "  horiz-adv-x="315" />
+<glyph unicode="&#x09;" horiz-adv-x="315" />
+<glyph unicode="&#xa0;" horiz-adv-x="315" />
+<glyph unicode="!" horiz-adv-x="387" d="M74 1505h239l-55 -1099h-129zM86 0v227h215v-227h-215z" />
+<glyph unicode="&#x22;" horiz-adv-x="329" d="M57 1505h215l-30 -551h-154z" />
+<glyph unicode="#" horiz-adv-x="1232" d="M49 438l27 195h198l37 258h-196l26 194h197l57 420h197l-57 -420h260l57 420h197l-58 -420h193l-27 -194h-192l-37 -258h190l-26 -195h-191l-59 -438h-197l60 438h-261l-59 -438h-197l60 438h-199zM471 633h260l37 258h-260z" />
+<glyph unicode="$" horiz-adv-x="692" d="M37 358l192 13q12 -186 129 -187q88 0 93 185q0 74 -61 175q-21 36 -34 53l-40 55q-28 38 -65.5 90t-70.5 101.5t-70.5 141.5t-37.5 170q4 293 215 342v131h123v-125q201 -23 235 -282l-192 -25q-14 129 -93 125q-80 -2 -84 -162q0 -102 94 -227l41 -59q30 -42 37 -52 t33 -48l37 -52q41 -57 68 -109l26 -55q43 -94 43 -186q-4 -338 -245 -369v-217h-123v221q-236 41 -250 352z" />
+<glyph unicode="%" horiz-adv-x="1001" d="M55 911v437q0 110 82 156q33 18 90.5 18t97.5 -44t44 -87l4 -43v-437q0 -107 -81 -157q-32 -19 -77 -19q-129 0 -156 135zM158 0l553 1505h131l-547 -1505h-137zM178 911q-4 -55 37 -55q16 0 25.5 14.5t9.5 26.5v451q2 55 -35 55q-18 0 -27.5 -13.5t-9.5 -27.5v-451z M631 158v436q0 108 81 156q33 20 79 20q125 0 153 -135l4 -41v-436q0 -110 -80 -156q-32 -18 -90.5 -18t-98.5 43t-44 88zM754 158q-4 -57 37 -58q37 0 34 58v436q2 55 -34 55q-18 0 -27.5 -13t-9.5 -28v-450z" />
+<glyph unicode="&#x26;" horiz-adv-x="854" d="M49 304q0 126 44 225.5t126 222.5q-106 225 -106 442v18q0 94 47 180q70 130 223 130q203 0 252 -215q14 -61 12 -113q0 -162 -205 -434q76 -174 148 -285q33 96 47 211l176 -33q-16 -213 -92 -358q55 -63 92 -76v-235q-23 0 -86 37.5t-123 101.5q-123 -139 -252 -139 t-216 97t-87 223zM263 325.5q1 -65.5 28.5 -107.5t78.5 -42t117 86q-88 139 -174 295q-18 -30 -34.5 -98t-15.5 -133.5zM305 1194q0 -111 55 -246q101 156 101 252q-2 2 0 15.5t-2 36t-11 42.5q-19 52 -61.5 52t-62 -38t-19.5 -75v-39z" />
+<glyph unicode="'" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="(" horiz-adv-x="561" d="M66 645q0 143 29.5 292.5t73.5 261.5q92 235 159 343l30 47l162 -84q-38 -53 -86.5 -148t-82.5 -189.5t-61.5 -238t-27.5 -284.5t26.5 -282.5t64.5 -240.5q80 -207 141 -296l26 -39l-162 -84q-41 61 -96 173t-94 217.5t-70.5 257t-31.5 294.5z" />
+<glyph unicode=")" horiz-adv-x="561" d="M41 -213q36 50 85.5 147t83.5 190t61.5 236.5t27.5 284.5t-26.5 282.5t-64.5 240.5q-78 205 -140 298l-27 39l162 84q41 -61 96 -173.5t94 -217t71 -257.5t32 -296t-30 -292.5t-74 -260.5q-92 -233 -159 -342l-30 -47z" />
+<glyph unicode="*" horiz-adv-x="677" d="M74 1251l43 148l164 -70l-19 176h154l-19 -176l164 70l43 -148l-172 -34l115 -138l-131 -80l-78 152l-76 -152l-131 80l115 138z" />
+<glyph unicode="+" horiz-adv-x="1060" d="M74 649v172h370v346h172v-346h371v-172h-371v-346h-172v346h-370z" />
+<glyph unicode="," horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="-" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="." horiz-adv-x="321" d="M53 0v227h215v-227h-215z" />
+<glyph unicode="/" horiz-adv-x="720" d="M8 -147l543 1652h162l-537 -1652h-168z" />
+<glyph unicode="0" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="1" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="2" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="3" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="4" horiz-adv-x="684" d="M25 328v194l323 983h221v-983h103v-194h-103v-328h-202v328h-342zM213 522h154v516h-13z" />
+<glyph unicode="5" horiz-adv-x="704" d="M74 438h221v-59q0 -115 14.5 -159t52 -44t53 45t15.5 156v336q0 111 -70 110q-33 0 -59.5 -40t-26.5 -70h-186v792h535v-219h-344v-313q74 55 127 51q78 0 133 -40t77 -100q35 -98 35 -171v-336q0 -393 -289 -393q-78 0 -133 29.5t-84.5 71.5t-46.5 109q-24 98 -24 244z " />
+<glyph unicode="6" horiz-adv-x="700" d="M66 309v856q0 356 288.5 356.5t288.5 -356.5v-94h-221q0 162 -11.5 210t-53.5 48t-56 -37t-14 -127v-268q59 37 124.5 37t119 -36t75.5 -93q37 -92 37 -189v-307q0 -90 -42 -187q-26 -61 -89 -99.5t-157.5 -38.5t-158 38.5t-88.5 99.5q-42 98 -42 187zM287 244 q0 -20 17.5 -44t49 -24t50 24.5t18.5 43.5v450q0 18 -18.5 43t-49 25t-48 -20.5t-19.5 -41.5v-456z" />
+<glyph unicode="7" horiz-adv-x="589" d="M8 1286v219h557v-221l-221 -1284h-229l225 1286h-332z" />
+<glyph unicode="8" horiz-adv-x="696" d="M53 322v176q0 188 115 297q-102 102 -102 276v127q0 213 147 293q57 31 135 31t135.5 -31t84 -71t42.5 -93q21 -66 21 -129v-127q0 -174 -103 -276q115 -109 115 -297v-176q0 -222 -153 -306q-60 -32 -142 -32t-141.5 32.5t-88 73.5t-44.5 96q-21 69 -21 136zM269 422 q1 -139 16.5 -187.5t57.5 -48.5t59.5 30t21.5 71t4 158t-13.5 174t-66.5 57t-66.5 -57.5t-12.5 -196.5zM284 1116q-1 -123 11 -173t53 -50t53.5 50t12.5 170t-12.5 167t-51.5 47t-52 -44t-14 -167z" />
+<glyph unicode="9" horiz-adv-x="700" d="M57 340v94h222q0 -162 11 -210t53 -48t56.5 37t14.5 127v283q-59 -37 -125 -37t-119 35.5t-76 92.5q-37 96 -37 189v293q0 87 43 188q25 60 88.5 99t157.5 39t157.5 -39t88.5 -99q43 -101 43 -188v-856q0 -356 -289 -356t-289 356zM279 825q0 -18 18 -42.5t49 -24.5 t48.5 20.5t19.5 40.5v443q0 20 -17.5 43.5t-49.5 23.5t-50 -24.5t-18 -42.5v-437z" />
+<glyph unicode=":" horiz-adv-x="362" d="M74 0v227h215v-227h-215zM74 893v227h215v-227h-215z" />
+<glyph unicode=";" horiz-adv-x="362" d="M74 0v227h215v-227l-113 -266h-102l71 266h-71zM74 893v227h215v-227h-215z" />
+<glyph unicode="&#x3c;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="=" horiz-adv-x="1058" d="M74 477v172h911v-172h-911zM74 864v172h911v-172h-911z" />
+<glyph unicode="&#x3e;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="?" horiz-adv-x="645" d="M25 1260q24 67 78 131q105 128 235 122q82 -2 138 -33.5t82 -81.5q46 -88 46 -170.5t-80 -219.5l-57 -96q-18 -32 -42 -106.5t-24 -143.5v-256h-190v256q0 102 24.5 195t48 140t65.5 118t50 105t-9 67.5t-60 34.5t-78 -48t-49 -98zM199 0h215v227h-215v-227z" />
+<glyph unicode="@" horiz-adv-x="872" d="M66 303v889q0 97 73 200q39 56 117 93t184.5 37t184 -37t116.5 -93q74 -105 74 -200v-793h-164l-20 56q-14 -28 -46 -48t-67 -20q-145 0 -145 172v485q0 170 145 170q71 0 113 -67v45q0 51 -45 104.5t-145.5 53.5t-145.5 -53.5t-45 -104.5v-889q0 -53 44 -103t153.5 -50 t160.5 63l152 -86q-109 -143 -320 -143q-106 0 -184 35.5t-117 90.5q-73 102 -73 193zM535 573q0 -53 48 -53t48 53v455q0 53 -48 53t-48 -53v-455z" />
+<glyph unicode="A" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="B" horiz-adv-x="745" d="M82 0v1505h194q205 0 304.5 -91t99.5 -308q0 -106 -29.5 -175t-107.5 -136q14 -5 47 -38.5t54 -71.5q52 -97 52 -259q0 -414 -342 -426h-272zM303 219q74 0 109 31q55 56 55 211t-63 195q-42 26 -93 26h-8v-463zM303 885q87 0 119 39q45 55 45 138t-14.5 124t-30.5 60.5 t-45 28.5q-35 11 -74 11v-401z" />
+<glyph unicode="C" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175z" />
+<glyph unicode="D" horiz-adv-x="761" d="M82 0v1505h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174zM303 221q117 0 140.5 78t23.5 399v111q0 322 -23.5 398.5t-140.5 76.5v-1063z" />
+<glyph unicode="E" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506z" />
+<glyph unicode="F" horiz-adv-x="616" d="M82 0v1505h526v-227h-305v-395h205v-228h-205v-655h-221z" />
+<glyph unicode="G" horiz-adv-x="737" d="M67 271.5q0 26.5 1 37.5v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-231h-221v231q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-905q0 -46 19.5 -78.5t54 -32.5t53 28t18.5 54l2 29v272h-88v187h309v-750h-131l-26 72 q-70 -88 -172 -88q-203 0 -250 213q-11 48 -11 74.5z" />
+<glyph unicode="H" horiz-adv-x="778" d="M82 0v1505h221v-622h172v622h221v-1505h-221v655h-172v-655h-221z" />
+<glyph unicode="I" horiz-adv-x="385" d="M82 0v1505h221v-1505h-221z" />
+<glyph unicode="J" horiz-adv-x="423" d="M12 -14v217q4 0 12.5 -1t29 2t35.5 12t28.5 34.5t13.5 62.5v1192h221v-1226q0 -137 -74 -216q-74 -78 -223 -78h-4q-19 0 -39 1z" />
+<glyph unicode="K" horiz-adv-x="768" d="M82 0v1505h221v-526h8l195 526h215l-203 -495l230 -1010h-216l-153 655l-6 31h-6l-64 -154v-532h-221z" />
+<glyph unicode="L" horiz-adv-x="604" d="M82 0v1505h221v-1300h293v-205h-514z" />
+<glyph unicode="M" horiz-adv-x="991" d="M82 0v1505h270l131 -688l11 -80h4l10 80l131 688h270v-1505h-204v1010h-13l-149 -1010h-94l-142 946l-8 64h-12v-1010h-205z" />
+<glyph unicode="N" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203z" />
+<glyph unicode="O" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="P" horiz-adv-x="720" d="M82 0v1505h221q166 0 277.5 -105.5t111.5 -345t-111.5 -346t-277.5 -106.5v-602h-221zM303 827q102 0 134 45.5t32 175.5t-33 181t-133 51v-453z" />
+<glyph unicode="Q" horiz-adv-x="729" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -94 -45 -182q33 -43 88 -53v-189q-160 0 -227 117q-55 -18 -125 -18t-130 33.5t-88 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887 q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="R" horiz-adv-x="739" d="M82 0v1505h221q377 0 377 -434q0 -258 -123 -342l141 -729h-221l-115 635h-59v-635h-221zM303 840q117 0 149 98q15 49 15 125t-15.5 125t-45.5 68q-44 30 -103 30v-446z" />
+<glyph unicode="S" horiz-adv-x="702" d="M37 422l217 20q0 -256 104 -256q90 0 91 166q0 59 -32 117.5t-45 79.5l-54 79q-40 58 -77 113t-73.5 117t-68 148.5t-31.5 162.5q0 139 71.5 245t216.5 108h10q88 0 152 -36t94 -100q54 -120 54 -264l-217 -20q0 217 -89 217q-75 -2 -75 -146q0 -59 23 -105 q32 -66 58 -104l197 -296q31 -49 67 -139.5t36 -166.5q0 -378 -306 -378h-2q-229 0 -290 188q-31 99 -31 250z" />
+<glyph unicode="T" horiz-adv-x="647" d="M4 1278v227h639v-227h-209v-1278h-221v1278h-209z" />
+<glyph unicode="U" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175z" />
+<glyph unicode="V" horiz-adv-x="716" d="M18 1505h215l111 -827l8 -64h13l118 891h215l-229 -1505h-221z" />
+<glyph unicode="W" horiz-adv-x="1036" d="M25 1505h204l88 -782l5 -49h16l100 831h160l100 -831h17l92 831h205l-203 -1505h-172l-115 801h-8l-115 -801h-172z" />
+<glyph unicode="X" horiz-adv-x="737" d="M16 0l244 791l-240 714h218l120 -381l7 -18h8l127 399h217l-240 -714l244 -791h-217l-127 449l-4 18h-8l-132 -467h-217z" />
+<glyph unicode="Y" horiz-adv-x="700" d="M14 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641z" />
+<glyph unicode="Z" horiz-adv-x="626" d="M20 0v238l347 1048h-297v219h536v-219l-352 -1067h352v-219h-586z" />
+<glyph unicode="[" horiz-adv-x="538" d="M82 -213v1718h399v-196h-202v-1325h202v-197h-399z" />
+<glyph unicode="\" horiz-adv-x="792" d="M8 1692h162l614 -1872h-168z" />
+<glyph unicode="]" horiz-adv-x="538" d="M57 -16h203v1325h-203v196h400v-1718h-400v197z" />
+<glyph unicode="^" horiz-adv-x="1101" d="M53 809l381 696h234l381 -696h-199l-299 543l-299 -543h-199z" />
+<glyph unicode="_" horiz-adv-x="1210" d="M74 -154h1063v-172h-1063v172z" />
+<glyph unicode="`" horiz-adv-x="1024" d="M293 1489h215l106 -184h-159z" />
+<glyph unicode="a" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="b" horiz-adv-x="686" d="M82 0v1505h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-74h-207zM289 246q0 -29 19.5 -48.5t42 -19.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -21.5t-19.5 -46.5v-628z" />
+<glyph unicode="c" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331z" />
+<glyph unicode="d" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v458h207v-1505h-207v74q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 19.5t19.5 48.5v628q0 25 -19.5 46.5t-42 21.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="e" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="f" horiz-adv-x="475" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-65 0 -65 -175v-5v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="g" horiz-adv-x="700" d="M12 -184q0 94 162 170q-125 35 -125 149q0 45 40 93t89 75q-51 35 -80.5 95.5t-34.5 105.5l-4 43v305q0 35 16.5 91t41 94t79 69t126.5 31q135 0 206 -103q102 102 170 103v-185q-72 0 -120 -24l10 -70v-317q0 -37 -17.5 -90.5t-42 -90t-79 -66.5t-104.5 -30t-62 2 q-29 -25 -29 -46t11 -33.5t42 -20.5t45.5 -10t65.5 -10.5t95 -21.5t89 -41q96 -60 96 -205t-103 -212q-100 -65 -250 -65h-9q-156 2 -240 50t-84 165zM213 -150q0 -77 132 -77h3q59 0 108.5 19t49.5 54t-20.5 52.5t-90.5 29.5l-106 21q-76 -43 -76 -99zM262 509 q0 -17 15.5 -45t44.5 -28q63 6 63 101v307q-2 0 0 10q1 3 1 7q0 8 -3 19q-4 15 -9 30q-11 36 -46 36t-50.5 -25.5t-15.5 -52.5v-359z" />
+<glyph unicode="h" horiz-adv-x="690" d="M82 0v1505h207v-479l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="i" horiz-adv-x="370" d="M82 0v1120h207v-1120h-207zM82 1298v207h207v-207h-207z" />
+<glyph unicode="j" horiz-adv-x="364" d="M-45 -182q29 -8 57 -8q64 0 64 142v1168h207v-1149q0 -186 -51 -266q-23 -35 -71 -62.5t-115 -27.5t-91 12v191zM76 1298v207h207v-207h-207z" />
+<glyph unicode="k" horiz-adv-x="641" d="M82 0v1505h207v-714h10l113 329h186l-149 -364l188 -756h-199l-102 453l-4 16h-10l-33 -82v-387h-207z" />
+<glyph unicode="l" horiz-adv-x="370" d="M82 0v1505h207v-1505h-207z" />
+<glyph unicode="m" horiz-adv-x="1021" d="M82 0v1120h207v-94q2 0 33 30q80 81 139 81q100 0 139 -125q125 125 194.5 125t109.5 -69t40 -150v-918h-194v887q-1 49 -56 49q-41 0 -78 -53v-883h-194v887q0 49 -55 49q-41 0 -78 -53v-883h-207z" />
+<glyph unicode="n" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="o" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="p" horiz-adv-x="686" d="M82 -385v1505h207v-73q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="q" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v73h207v-1505h-207v459q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 21.5t19.5 46.5v628q0 29 -19.5 48.5t-42 19.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="r" horiz-adv-x="503" d="M82 0v1120h207v-125q8 41 58.5 91.5t148.5 50.5v-230q-34 11 -77 11t-86.5 -39t-43.5 -101v-778h-207z" />
+<glyph unicode="s" horiz-adv-x="630" d="M37 326h192q0 -170 97 -170q71 0 71 131q0 78 -129 202q-68 66 -98.5 99t-64 101.5t-33.5 134t12 114.5t39 95q59 100 201 104h11q161 0 211 -105q42 -86 42 -198h-193q0 131 -67 131q-63 -2 -64 -131q0 -33 23.5 -73t45 -62.5t66.5 -65.5q190 -182 191 -342 q0 -123 -64.5 -215t-199.5 -92q-197 0 -260 170q-29 76 -29 172z" />
+<glyph unicode="t" horiz-adv-x="501" d="M20 934v186h105v277h207v-277h141v-186h-141v-557q0 -184 65 -184l76 8v-203q-45 -14 -112 -14t-114.5 28.5t-70 64.5t-34.5 96q-17 79 -17 187v574h-105z" />
+<glyph unicode="u" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5z" />
+<glyph unicode="v" horiz-adv-x="602" d="M16 1120h201l68 -649l8 -72h16l76 721h201l-183 -1120h-204z" />
+<glyph unicode="w" horiz-adv-x="905" d="M20 1120h189l65 -585l9 -64h12l96 649h123l86 -585l10 -64h13l73 649h189l-166 -1120h-172l-80 535l-10 63h-8l-91 -598h-172z" />
+<glyph unicode="x" horiz-adv-x="618" d="M16 0l193 578l-176 542h194l74 -262l6 -31h4l6 31l74 262h195l-176 -542l192 -578h-201l-84 283l-6 30h-4l-6 -30l-84 -283h-201z" />
+<glyph unicode="y" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5z" />
+<glyph unicode="z" horiz-adv-x="532" d="M12 0v168l285 764h-240v188h459v-168l-285 -764h285v-188h-504z" />
+<glyph unicode="{" horiz-adv-x="688" d="M61 453v163q72 0 102 49.5t30 90.5v397q0 223 96 298t342 71v-172q-135 2 -188.5 -38t-53.5 -159v-397q0 -143 -127 -221q127 -82 127 -222v-397q0 -119 53.5 -159t188.5 -38v-172q-246 -4 -342 71t-96 298v397q0 57 -41 97.5t-91 42.5z" />
+<glyph unicode="|" horiz-adv-x="356" d="M82 -512v2204h192v-2204h-192z" />
+<glyph unicode="}" horiz-adv-x="688" d="M57 -281q135 -2 188.5 38t53.5 159v397q0 139 127 222q-127 78 -127 221v397q0 119 -53 159t-189 38v172q246 4 342.5 -71t96.5 -298v-397q0 -63 41 -101.5t90 -38.5v-163q-72 -4 -101.5 -52.5t-29.5 -87.5v-397q0 -223 -96.5 -298t-342.5 -71v172z" />
+<glyph unicode="~" horiz-adv-x="1280" d="M113 1352q35 106 115 200q34 41 94.5 74t121 33t116.5 -18.5t82 -33t83 -51.5q106 -72 174 -71q109 0 178 153l13 29l135 -57q-63 -189 -206 -276q-56 -34 -120 -34q-121 0 -272 101q-115 74 -178.5 74t-113.5 -45.5t-69 -90.5l-18 -45z" />
+<glyph unicode="&#xa1;" horiz-adv-x="387" d="M74 -385l55 1100h129l55 -1100h-239zM86 893v227h215v-227h-215z" />
+<glyph unicode="&#xa2;" horiz-adv-x="636" d="M66 508v489q0 297 208 328v242h123v-244q98 -16 144.5 -88t46.5 -227v-88h-189v135q0 90 -72.5 90t-72.5 -90v-604q0 -90 72 -91q74 0 73 91v155h189v-108q0 -156 -46 -228.5t-145 -89.5v-303h-123v301q-209 31 -208 330z" />
+<glyph unicode="&#xa3;" horiz-adv-x="817" d="M4 63q8 20 23.5 53.5t70 91.5t117.5 68q37 111 37 189t-31 184h-188v137h147l-6 21q-78 254 -78 333t15.5 140t48.5 116q72 122 231 126q190 4 267 -126q65 -108 65 -276h-213q0 201 -115 197q-47 -2 -68.5 -51t-21.5 -139.5t70 -315.5l6 -25h211v-137h-174 q25 -100 24.5 -189t-57.5 -204q16 -8 44 -24q59 -35 89 -35q74 4 82 190l188 -22q-12 -182 -81.5 -281.5t-169.5 -99.5q-51 0 -143.5 51t-127.5 51t-63.5 -25.5t-40.5 -52.5l-12 -24z" />
+<glyph unicode="&#xa5;" horiz-adv-x="720" d="M25 1505h217l110 -481l6 -14h4l7 14l110 481h217l-196 -753h147v-138h-176v-137h176v-137h-176v-340h-221v340h-176v137h176v137h-176v138h147z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1024" d="M272 1305v200h191v-200h-191zM561 1305v200h191v-200h-191z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM627 487v531q0 122 97 174q40 22 95 22 q147 0 182 -147l7 -49v-125h-138v142q0 11 -12 28.5t-37 17.5q-47 -2 -49 -63v-531q0 -63 49 -63q53 2 49 63v125h138v-125q0 -68 -40 -127q-18 -26 -57 -47.5t-108.5 -21.5t-117.5 49t-54 98z" />
+<glyph unicode="&#xaa;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xad;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#xae;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM625 313v879h196q231 0 232 -258 q0 -76 -16.5 -125t-71.5 -96l106 -400h-151l-95 365h-55v-365h-145zM770 805h45q43 0 65.5 21.5t27.5 45t5 61.5t-5 62.5t-27.5 46t-65.5 21.5h-45v-258z" />
+<glyph unicode="&#xaf;" horiz-adv-x="1024" d="M313 1315v162h398v-162h-398z" />
+<glyph unicode="&#xb2;" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="&#xb3;" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="&#xb4;" horiz-adv-x="1024" d="M410 1305l106 184h215l-162 -184h-159z" />
+<glyph unicode="&#xb7;" horiz-adv-x="215" d="M0 649v228h215v-228h-215z" />
+<glyph unicode="&#xb8;" horiz-adv-x="1024" d="M426 -111h172v-141l-45 -133h-104l40 133h-63v141z" />
+<glyph unicode="&#xb9;" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="&#xba;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="&#xbf;" horiz-adv-x="645" d="M41 -106q0 82 80 219l57 95q18 32 42 106.5t24 144.5v256h190v-256q0 -102 -24.5 -195.5t-48 -140.5t-65.5 -118t-50 -104.5t9 -67.5t60 -35t78 48.5t49 98.5l179 -84q-24 -66 -78 -132q-104 -126 -236 -122q-163 4 -220 115q-46 90 -46 172zM231 893v227h215v-227h-215z " />
+<glyph unicode="&#xc0;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM141 1823h215l107 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc1;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM293 1638l106 185h215l-161 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc2;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM133 1638l141 185h220l141 -185h-189l-63 72l-61 -72h-189zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc3;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM184 1632v152q49 39 95.5 39t104.5 -18.5t100.5 -19.5t97.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-98 19.5t-102 -33zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc4;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM143 1638v201h191v-201h-191zM307 541h152l-64 475l-6 39h-12zM432 1638v201h191v-201h-191z" />
+<glyph unicode="&#xc5;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM231 1761.5q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM307 541h152l-64 475l-6 39h-12zM309 1761.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50 t-23.5 50t-52.5 21.5t-52.5 -21.5t-23.5 -50z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1099" d="M16 0l420 1505h623v-227h-285v-395h205v-242h-205v-414h285v-227h-506v307h-227l-90 -307h-220zM393 541h160v514h-10z" />
+<glyph unicode="&#xc7;" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM268 -111v-141h64l-41 -133h104l45 133v141h-172z" />
+<glyph unicode="&#xc8;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM111 1823h215l106 -185h-160z" />
+<glyph unicode="&#xc9;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM236 1638l106 185h215l-162 -185h-159z" />
+<glyph unicode="&#xca;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM84 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xcb;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM94 1638v201h191v-201h-191zM383 1638v201h190v-201h-190z" />
+<glyph unicode="&#xcc;" horiz-adv-x="401" d="M-6 1823h215l106 -185h-159zM98 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcd;" horiz-adv-x="401" d="M82 0v1505h221v-1505h-221zM86 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xce;" horiz-adv-x="370" d="M-66 1638l142 185h219l141 -185h-188l-64 72l-61 -72h-189zM74 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcf;" horiz-adv-x="372" d="M-53 1638v201h190v-201h-190zM76 0v1505h221v-1505h-221zM236 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd0;" horiz-adv-x="761" d="M20 655v228h62v622h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174v655h-62zM303 221q117 0 141.5 81t22.5 452q2 371 -22.5 450.5t-141.5 79.5v-401h84v-228h-84v-434z " />
+<glyph unicode="&#xd1;" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203zM207 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39t-102.5 19.5t-100 19.5t-99.5 -33z" />
+<glyph unicode="&#xd2;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM121 1823h215l106 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd3;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM285 1638l106 185h215l-162 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5 t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd4;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM113 1638l141 185h219l141 -185h-188l-64 72l-61 -72h-188zM289 309q0 -46 19.5 -78 t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd5;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM164 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39 t-102.5 19.5t-100 19.5t-99.5 -33zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd6;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM123 1638v201h190v-201h-190zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887zM412 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd8;" d="M59 -20l47 157q-36 74 -36 148l-2 24v887q0 42 17 106t45 107t88.5 78t148 35t153.5 -43l15 47h122l-45 -150q43 -84 43 -155l2 -25v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-150.5 -34.5t-153 43l-15 -47h-129zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v488zM289 727l147 479q-8 100 -74 101q-35 0 -53 -28t-18 -54l-2 -29v-469z" />
+<glyph unicode="&#xd9;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM145 1823h215l107 -185h-160z" />
+<glyph unicode="&#xda;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM307 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xdb;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM125 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xdc;" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175zM135 1638v201h191v-201h-191zM424 1638v201h190v-201h-190z" />
+<glyph unicode="&#xdd;" horiz-adv-x="704" d="M16 1505l226 -864v-641h221v641l225 864h-217l-111 -481l-6 -14h-4l-6 14l-111 481h-217zM254 1638l106 185h215l-161 -185h-160z" />
+<glyph unicode="&#xde;" d="M82 0v1505h219v-241h2q166 0 277.5 -105.5t111.5 -345.5t-111.5 -346.5t-277.5 -106.5v-360h-221zM303 586q102 0 134 45t32 175t-33 181t-133 51v-452z" />
+<glyph unicode="&#xdf;" horiz-adv-x="733" d="M66 0v1235q0 123 70.5 205t206.5 82t204.5 -81t68.5 -197t-88 -181q152 -88 152 -488q0 -362 -87 -475q-46 -59 -102.5 -79.5t-144.5 -20.5v193q45 0 70 25q57 57 57 357q0 316 -57 377q-25 27 -70 27v141q35 0 60.5 33t25.5 84q0 100 -86 100q-74 0 -74 -102v-1235h-206 z" />
+<glyph unicode="&#xe0;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1489h215 l107 -184h-160zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe1;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xe2;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM90 1305 l141 184h220l141 -184h-189l-63 71l-61 -71h-189zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe3;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM143 1305v151 q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe4;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1305v200 h191v-200h-191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM391 1305v200h191v-200h-191z" />
+<glyph unicode="&#xe5;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM188 1421.5 q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM266 1421.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50t-23.5 50t-52.5 21.5t-52.5 -21.5 t-23.5 -50z" />
+<glyph unicode="&#xe6;" horiz-adv-x="989" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t197.5 88q84 0 152 -52q66 51 162 52q199 0 251 -197q14 -51 15 -92v-326h-342v-256q0 -60 38 -88q17 -12 38 -12q70 10 73 113v122h193v-129 q0 -37 -16.5 -93t-41 -95t-80 -69.5t-130.5 -30.5q-158 0 -226 131q-102 -131 -221 -131q-59 0 -112.5 60t-53.5 191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM588 684h149v158q0 48 -19.5 81t-53 33t-53 -28.5t-21.5 -57.5l-2 -28v-158z " />
+<glyph unicode="&#xe7;" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331zM238 -111v-141h63l-41 -133h105l45 133v141h-172z " />
+<glyph unicode="&#xe8;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM102 1489h215l107 -184 h-160zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xe9;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xea;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM80 1305l141 184h219 l142 -184h-189l-63 71l-62 -71h-188zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xeb;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM90 1305v200h191v-200 h-191zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xec;" horiz-adv-x="370" d="M-33 1489h215l107 -184h-160zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xed;" horiz-adv-x="370" d="M82 0h207v1120h-207v-1120zM82 1305l106 184h215l-161 -184h-160z" />
+<glyph unicode="&#xee;" horiz-adv-x="370" d="M-66 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xef;" horiz-adv-x="372" d="M-53 1305v200h190v-200h-190zM82 0v1120h207v-1120h-207zM236 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf0;" horiz-adv-x="673" d="M76 279v579q0 279 172 279q63 0 155 -78q-12 109 -51 203l-82 -72l-55 63l100 88l-45 66l109 100q25 -27 53 -61l94 82l56 -66l-101 -88q125 -201 125 -446v-656q0 -102 -56 -188q-26 -39 -80 -69.5t-129 -30.5t-130 30.5t-80 73.5q-53 91 -53 160zM270 267.5 q-2 -11.5 2 -29t10 -34.5q16 -38 58 -38q70 10 72 113v563q-2 0 0 11t-2 28.5t-10 34.5q-16 40 -60 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf1;" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207zM147 1305v151q49 39 95.5 39t105 -18.5t97 -19.5t100.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#xf2;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM98 1489h215l107 -184h-160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf3;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5 t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM260 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xf4;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM78 1305l141 184h219l142 -184h-189l-63 71l-62 -71h-188zM258 267.5q-2 -11.5 2 -29 t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf5;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM131 1305v151q49 39 95.5 39t104.5 -18.5t98.5 -19.5t98.5 32v-152q-51 -39 -95 -39 t-102 19.5t-101 19.5t-99 -32zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf6;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM90 1305v200h191v-200h-191zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf8;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t118 32t117.5 -19l21 80h75l-30 -121q88 -84 94 -229v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-120.5 -30.5t-112 16l-20 -78h-80l31 121q-41 39 -64.5 97.5t-25.5 97.5zM258 436l125 486q-18 35 -55 34q-68 -10 -70 -114 v-406zM274 197q17 -31 54 -31q70 10 71 113v403z" />
+<glyph unicode="&#xf9;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM113 1489h215l106 -184h-160z" />
+<glyph unicode="&#xfa;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM274 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfb;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM94 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189z" />
+<glyph unicode="&#xfc;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM106 1305v200h191v-200h-191zM395 1305v200h191v-200h-191z" />
+<glyph unicode="&#xfd;" horiz-adv-x="634" d="M25 1120l190 -1153q0 -68 -36 -123t-97 -61l-49 4v-184q70 -4 92 -4q115 0 192.5 95t94.5 222l198 1204h-202l-82 -688l-4 -57h-9l-4 57l-82 688h-202zM231 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfe;" horiz-adv-x="686" d="M82 -385v1890h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="&#xff;" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5zM78 1305v200h190v-200h-190zM367 1305v200h190v-200h-190z" />
+<glyph unicode="&#x152;" horiz-adv-x="983" d="M68 309v887q0 41 17 101.5t45 100.5t88.5 73.5t143.5 33.5h580v-227h-285v-395h205v-242h-205v-414h285v-227h-580q-84 0 -144 31.5t-88 78.5q-55 91 -60 169zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v901q-6 96 -74 97q-35 0 -53 -28t-18 -54l-2 -29 v-887z" />
+<glyph unicode="&#x153;" horiz-adv-x="995" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t145.5 32t156 -60q66 59 170 60q199 0 252 -197q14 -51 14 -92v-326h-342v-250q0 -46 22.5 -76t53.5 -30q70 10 73 113v122h193v-129q0 -37 -16.5 -93t-41 -95t-80 -69.5t-146 -30.5t-154.5 57q-68 -57 -156 -57t-143.5 30.5 t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM594 684h149v158q0 48 -19 81t-58 33t-55.5 -37.5t-16.5 -70.5v-164z" />
+<glyph unicode="&#x178;" horiz-adv-x="704" d="M16 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641zM113 1638v201h190v-201h-190zM401 1638v201h191v-201h-191z" />
+<glyph unicode="&#x2c6;" horiz-adv-x="1021" d="M260 1305l141 184h220l141 -184h-189l-63 71l-61 -71h-189z" />
+<glyph unicode="&#x2dc;" horiz-adv-x="1024" d="M313 1305v151q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#x2000;" horiz-adv-x="952" />
+<glyph unicode="&#x2001;" horiz-adv-x="1905" />
+<glyph unicode="&#x2002;" horiz-adv-x="952" />
+<glyph unicode="&#x2003;" horiz-adv-x="1905" />
+<glyph unicode="&#x2004;" horiz-adv-x="635" />
+<glyph unicode="&#x2005;" horiz-adv-x="476" />
+<glyph unicode="&#x2006;" horiz-adv-x="317" />
+<glyph unicode="&#x2007;" horiz-adv-x="317" />
+<glyph unicode="&#x2008;" horiz-adv-x="238" />
+<glyph unicode="&#x2009;" horiz-adv-x="381" />
+<glyph unicode="&#x200a;" horiz-adv-x="105" />
+<glyph unicode="&#x2010;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2011;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2012;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2013;" horiz-adv-x="806" d="M74 649v195h659v-195h-659z" />
+<glyph unicode="&#x2014;" horiz-adv-x="972" d="M74 649v195h825v-195h-825z" />
+<glyph unicode="&#x2018;" horiz-adv-x="309" d="M49 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x2019;" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="&#x201a;" horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="&#x201c;" horiz-adv-x="624" d="M53 1012v227l113 266h102l-71 -266h71v-227h-215zM356 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x201d;" horiz-adv-x="624" d="M53 1012l72 266h-72v227h215v-227l-112 -266h-103zM356 1012l72 266h-72v227h215v-227l-112 -266h-103z" />
+<glyph unicode="&#x201e;" horiz-adv-x="624" d="M53 0v227h215v-227l-112 -266h-103l72 266h-72zM356 0v227h215v-227l-112 -266h-103l72 266h-72z" />
+<glyph unicode="&#x2022;" horiz-adv-x="663" d="M82 815q0 104 72.5 177t177 73t177.5 -72.5t73 -177t-73 -177.5t-177 -73t-177 73t-73 177z" />
+<glyph unicode="&#x2026;" horiz-adv-x="964" d="M53 0v227h215v-227h-215zM375 0v227h215v-227h-215zM696 0v227h215v-227h-215z" />
+<glyph unicode="&#x202f;" horiz-adv-x="381" />
+<glyph unicode="&#x2039;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="&#x203a;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="&#x205f;" horiz-adv-x="476" />
+<glyph unicode="&#x20ac;" horiz-adv-x="813" d="M53 547v137h107v137h-107v137h107v238q0 42 17.5 106t45 107t88 78t144.5 35t144 -34t88 -81q53 -90 61 -178l2 -33v-84h-207v84q-2 0 0 11.5t-3 27.5t-12 33q-18 39 -69 39q-70 -10 -78 -111v-238h233v-137h-233v-137h233v-137h-233v-238q0 -43 21.5 -76.5t59.5 -33.5 t58.5 27.5t20.5 56.5l2 26v84h207v-84q0 -38 -17.5 -104t-45.5 -109t-88 -77.5t-144 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175l-2 35v238h-107z" />
+<glyph unicode="&#x2122;" horiz-adv-x="937" d="M74 1401v104h321v-104h-104v-580h-113v580h-104zM440 821v684h138l67 -319h6l68 319h137v-684h-104v449l-78 -449h-51l-80 449v-449h-103z" />
+<glyph unicode="&#xe000;" horiz-adv-x="1120" d="M0 0v1120h1120v-1120h-1120z" />
+<glyph unicode="&#xfb01;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2v-184q-41 12 -91 12t-69.5 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h358v-1120h-207v934h-151v-934h-207v934h-105z" />
+<glyph unicode="&#xfb02;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2h164v-1505h-207v1329q-37 4 -67.5 4t-50 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="&#xfb03;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1120h207v-1120h-207zM1032 1298v207h207v-207h-207z" />
+<glyph unicode="&#xfb04;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1505h207v-1505h-207z" />
+</font>
+</defs></svg> 
diff --git a/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.ttf b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.ttf differ
diff --git a/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.woff b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.woff
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic-webfont.woff differ
diff --git a/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic_license b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic_license
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/lib/font/league_gothic_license
@@ -0,0 +1,2 @@
+SIL Open Font License (OFL)
+http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/highlight/highlight.js b/docs/slides/ETH14/_support/reveal.js/plugin/highlight/highlight.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/highlight/highlight.js
@@ -0,0 +1,32 @@
+// START CUSTOM REVEAL.JS INTEGRATION
+(function() {
+	if( typeof window.addEventListener === 'function' ) {
+		var hljs_nodes = document.querySelectorAll( 'pre code' );
+
+		for( var i = 0, len = hljs_nodes.length; i < len; i++ ) {
+			var element = hljs_nodes[i];
+
+			// trim whitespace if data-trim attribute is present
+			if( element.hasAttribute( 'data-trim' ) && typeof element.innerHTML.trim === 'function' ) {
+				element.innerHTML = element.innerHTML.trim();
+			}
+
+			// Now escape html unless prevented by author
+			if( ! element.hasAttribute( 'data-noescape' )) {
+				element.innerHTML = element.innerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;");
+			}
+
+			// re-highlight when focus is lost (for edited code)
+			element.addEventListener( 'focusout', function( event ) {
+				hljs.highlightBlock( event.currentTarget );
+			}, false );
+		}
+	}
+})();
+// END CUSTOM REVEAL.JS INTEGRATION
+
+// highlight.js build includes support for:
+// All languages in master + fsharp
+
+
+var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName=="CODE"){return o}if(!(o.nodeType==3&&o.nodeValue.match(/\s+/))){break}}}function h(p,o){return Array.prototype.map.call(p.childNodes,function(q){if(q.nodeType==3){return o?q.nodeValue.replace(/\n/g,""):q.nodeValue}if(q.nodeName=="BR"){return"\n"}return h(q,o)}).join("")}function a(q){var p=(q.className+" "+(q.parentNode?q.parentNode.className:"")).split(/\s+/);p=p.map(function(r){return r.replace(/^language-/,"")});for(var o=0;o<p.length;o++){if(e[p[o]]||p[o]=="no-highlight"){return p[o]}}}function c(q){var o=[];(function p(r,s){for(var t=r.firstChild;t;t=t.nextSibling){if(t.nodeType==3){s+=t.nodeValue.length}else{if(t.nodeName=="BR"){s+=1}else{if(t.nodeType==1){o.push({event:"start",offset:s,node:t});s=p(t,s);o.push({event:"stop",offset:s,node:t})}}}}return s})(q,0);return o}function j(x,v,w){var p=0;var y="";var r=[];function t(){if(x.length&&v.length){if(x[0].offset!=v[0].offset){return(x[0].offset<v[0].offset)?x:v}else{return v[0].event=="start"?x:v}}else{return x.length?x:v}}function s(A){function z(B){return" "+B.nodeName+'="'+l(B.value)+'"'}return"<"+A.nodeName+Array.prototype.map.call(A.attributes,z).join("")+">"}while(x.length||v.length){var u=t().splice(0,1)[0];y+=l(w.substr(p,u.offset-p));p=u.offset;if(u.event=="start"){y+=s(u.node);r.push(u.node)}else{if(u.event=="stop"){var o,q=r.length;do{q--;o=r[q];y+=("</"+o.nodeName.toLowerCase()+">")}while(o!=u.node);r.splice(q,1);while(q<r.length){y+=s(r[q]);q++}}}}return y+l(w.substr(p))}function f(r){function o(s){return(s&&s.source)||s}function p(t,s){return RegExp(o(t),"m"+(r.cI?"i":"")+(s?"g":""))}function q(z,x){if(z.compiled){return}z.compiled=true;var u=[];if(z.k){var s={};function A(B,t){t.split(" ").forEach(function(C){var D=C.split("|");s[D[0]]=[B,D[1]?Number(D[1]):1];u.push(D[0])})}z.lR=p(z.l||hljs.IR+"(?!\\.)",true);if(typeof z.k=="string"){A("keyword",z.k)}else{for(var y in z.k){if(!z.k.hasOwnProperty(y)){continue}A(y,z.k[y])}}z.k=s}if(x){if(z.bWK){z.b="\\b("+u.join("|")+")\\b(?!\\.)\\s*"}z.bR=p(z.b?z.b:"\\B|\\b");if(!z.e&&!z.eW){z.e="\\B|\\b"}if(z.e){z.eR=p(z.e)}z.tE=o(z.e)||"";if(z.eW&&x.tE){z.tE+=(z.e?"|":"")+x.tE}}if(z.i){z.iR=p(z.i)}if(z.r===undefined){z.r=1}if(!z.c){z.c=[]}for(var w=0;w<z.c.length;w++){if(z.c[w]=="self"){z.c[w]=z}q(z.c[w],z)}if(z.starts){q(z.starts,x)}var v=[];for(var w=0;w<z.c.length;w++){v.push(o(z.c[w].b))}if(z.tE){v.push(o(z.tE))}if(z.i){v.push(o(z.i))}z.t=v.length?p(v.join("|"),true):{exec:function(t){return null}}}q(r)}function d(E,F,C){function o(r,N){for(var M=0;M<N.c.length;M++){var L=N.c[M].bR.exec(r);if(L&&L.index==0){return N.c[M]}}}function s(L,r){if(L.e&&L.eR.test(r)){return L}if(L.eW){return s(L.parent,r)}}function t(r,L){return !C&&L.i&&L.iR.test(r)}function y(M,r){var L=G.cI?r[0].toLowerCase():r[0];return M.k.hasOwnProperty(L)&&M.k[L]}function H(){var L=l(w);if(!A.k){return L}var r="";var O=0;A.lR.lastIndex=0;var M=A.lR.exec(L);while(M){r+=L.substr(O,M.index-O);var N=y(A,M);if(N){v+=N[1];r+='<span class="'+N[0]+'">'+M[0]+"</span>"}else{r+=M[0]}O=A.lR.lastIndex;M=A.lR.exec(L)}return r+L.substr(O)}function z(){if(A.sL&&!e[A.sL]){return l(w)}var r=A.sL?d(A.sL,w):g(w);if(A.r>0){v+=r.keyword_count;B+=r.r}return'<span class="'+r.language+'">'+r.value+"</span>"}function K(){return A.sL!==undefined?z():H()}function J(M,r){var L=M.cN?'<span class="'+M.cN+'">':"";if(M.rB){x+=L;w=""}else{if(M.eB){x+=l(r)+L;w=""}else{x+=L;w=r}}A=Object.create(M,{parent:{value:A}})}function D(L,r){w+=L;if(r===undefined){x+=K();return 0}var N=o(r,A);if(N){x+=K();J(N,r);return N.rB?0:r.length}var O=s(A,r);if(O){var M=A;if(!(M.rE||M.eE)){w+=r}x+=K();do{if(A.cN){x+="</span>"}B+=A.r;A=A.parent}while(A!=O.parent);if(M.eE){x+=l(r)}w="";if(O.starts){J(O.starts,"")}return M.rE?0:r.length}if(t(r,A)){throw new Error('Illegal lexem "'+r+'" for mode "'+(A.cN||"<unnamed>")+'"')}w+=r;return r.length||1}var G=e[E];f(G);var A=G;var w="";var B=0;var v=0;var x="";try{var u,q,p=0;while(true){A.t.lastIndex=p;u=A.t.exec(F);if(!u){break}q=D(F.substr(p,u.index-p),u[0]);p=u.index+q}D(F.substr(p));return{r:B,keyword_count:v,value:x,language:E}}catch(I){if(I.message.indexOf("Illegal")!=-1){return{r:0,keyword_count:0,value:l(F)}}else{throw I}}}function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p in e){if(!e.hasOwnProperty(p)){continue}var r=d(p,s,false);r.language=p;if(r.keyword_count+r.r>q.keyword_count+q.r){q=r}if(r.keyword_count+r.r>o.keyword_count+o.r){q=o;o=r}}if(q.language){o.second_best=q}return o}function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\t)+)/gm,function(r,v,u,t){return v.replace(/\t/g,p)})}if(o){q=q.replace(/\n/g,"<br>")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}var w=t?d(t,v,true):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match("(\\s|^)(language-)?"+t+"(\\s|$)")){s=s?(s+" "+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagName("pre"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener("DOMContentLoaded",n,false);window.addEventListener("load",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES["1c"]=function(b){var f="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*";var c="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт";var e="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку  стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон";var a={cN:"dquote",b:'""'};var d={cN:"string",b:'"',e:'"|$',c:[a],r:0};var g={cN:"string",b:"\\|",e:'"|$',c:[a]};return{cI:true,l:f,k:{keyword:c,built_in:e},c:[b.CLCM,b.NM,d,g,{cN:"function",b:"(процедура|функция)",e:"$",l:f,k:"процедура функция",c:[{cN:"title",b:f},{cN:"tail",eW:true,c:[{cN:"params",b:"\\(",e:"\\)",l:f,k:"знач",c:[d,g]},{cN:"export",b:"экспорт",eW:true,l:f,k:"экспорт",c:[b.CLCM]}]},b.CLCM]},{cN:"preprocessor",b:"#",e:"$"},{cN:"date",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}}(hljs);hljs.LANGUAGES.actionscript=function(a){var d="[a-zA-Z_$][a-zA-Z0-9_$]*";var c="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";var e={cN:"rest_arg",b:"[.]{3}",e:d,r:10};var b={cN:"title",b:d};return{k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{cN:"package",bWK:true,e:"{",k:"package",c:[b]},{cN:"class",bWK:true,e:"{",k:"class interface",c:[{bWK:true,k:"extends implements"},b]},{cN:"preprocessor",bWK:true,e:";",k:"import include"},{cN:"function",bWK:true,e:"[{;]",k:"function",i:"\\S",c:[b,{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,e]},{cN:"type",b:":",e:c,r:10}]}]}}(hljs);hljs.LANGUAGES.apache=function(a){var b={cN:"number",b:"[\\$%]\\d+"};return{cI:true,k:{keyword:"acceptfilter acceptmutex acceptpathinfo accessfilename action addalt addaltbyencoding addaltbytype addcharset adddefaultcharset adddescription addencoding addhandler addicon addiconbyencoding addiconbytype addinputfilter addlanguage addmoduleinfo addoutputfilter addoutputfilterbytype addtype alias aliasmatch allow allowconnect allowencodedslashes allowoverride anonymous anonymous_logemail anonymous_mustgiveemail anonymous_nouserid anonymous_verifyemail authbasicauthoritative authbasicprovider authdbduserpwquery authdbduserrealmquery authdbmgroupfile authdbmtype authdbmuserfile authdefaultauthoritative authdigestalgorithm authdigestdomain authdigestnccheck authdigestnonceformat authdigestnoncelifetime authdigestprovider authdigestqop authdigestshmemsize authgroupfile authldapbinddn authldapbindpassword authldapcharsetconfig authldapcomparednonserver authldapdereferencealiases authldapgroupattribute authldapgroupattributeisdn authldapremoteuserattribute authldapremoteuserisdn authldapurl authname authnprovideralias authtype authuserfile authzdbmauthoritative authzdbmtype authzdefaultauthoritative authzgroupfileauthoritative authzldapauthoritative authzownerauthoritative authzuserauthoritative balancermember browsermatch browsermatchnocase bufferedlogs cachedefaultexpire cachedirlength cachedirlevels cachedisable cacheenable cachefile cacheignorecachecontrol cacheignoreheaders cacheignorenolastmod cacheignorequerystring cachelastmodifiedfactor cachemaxexpire cachemaxfilesize cacheminfilesize cachenegotiateddocs cacheroot cachestorenostore cachestoreprivate cgimapextension charsetdefault charsetoptions charsetsourceenc checkcaseonly checkspelling chrootdir contentdigest cookiedomain cookieexpires cookielog cookiename cookiestyle cookietracking coredumpdirectory customlog dav davdepthinfinity davgenericlockdb davlockdb davmintimeout dbdexptime dbdkeep dbdmax dbdmin dbdparams dbdpersist dbdpreparesql dbdriver defaulticon defaultlanguage defaulttype deflatebuffersize deflatecompressionlevel deflatefilternote deflatememlevel deflatewindowsize deny directoryindex directorymatch directoryslash documentroot dumpioinput dumpiologlevel dumpiooutput enableexceptionhook enablemmap enablesendfile errordocument errorlog example expiresactive expiresbytype expiresdefault extendedstatus extfilterdefine extfilteroptions fileetag filterchain filterdeclare filterprotocol filterprovider filtertrace forcelanguagepriority forcetype forensiclog gracefulshutdowntimeout group header headername hostnamelookups identitycheck identitychecktimeout imapbase imapdefault imapmenu include indexheadinsert indexignore indexoptions indexorderdefault indexstylesheet isapiappendlogtoerrors isapiappendlogtoquery isapicachefile isapifakeasync isapilognotsupported isapireadaheadbuffer keepalive keepalivetimeout languagepriority ldapcacheentries ldapcachettl ldapconnectiontimeout ldapopcacheentries ldapopcachettl ldapsharedcachefile ldapsharedcachesize ldaptrustedclientcert ldaptrustedglobalcert ldaptrustedmode ldapverifyservercert limitinternalrecursion limitrequestbody limitrequestfields limitrequestfieldsize limitrequestline limitxmlrequestbody listen listenbacklog loadfile loadmodule lockfile logformat loglevel maxclients maxkeepaliverequests maxmemfree maxrequestsperchild maxrequestsperthread maxspareservers maxsparethreads maxthreads mcachemaxobjectcount mcachemaxobjectsize mcachemaxstreamingbuffer mcacheminobjectsize mcacheremovalalgorithm mcachesize metadir metafiles metasuffix mimemagicfile minspareservers minsparethreads mmapfile mod_gzip_on mod_gzip_add_header_count mod_gzip_keep_workfiles mod_gzip_dechunk mod_gzip_min_http mod_gzip_minimum_file_size mod_gzip_maximum_file_size mod_gzip_maximum_inmem_size mod_gzip_temp_dir mod_gzip_item_include mod_gzip_item_exclude mod_gzip_command_version mod_gzip_can_negotiate mod_gzip_handle_methods mod_gzip_static_suffix mod_gzip_send_vary mod_gzip_update_static modmimeusepathinfo multiviewsmatch namevirtualhost noproxy nwssltrustedcerts nwsslupgradeable options order passenv pidfile protocolecho proxybadheader proxyblock proxydomain proxyerroroverride proxyftpdircharset proxyiobuffersize proxymaxforwards proxypass proxypassinterpolateenv proxypassmatch proxypassreverse proxypassreversecookiedomain proxypassreversecookiepath proxypreservehost proxyreceivebuffersize proxyremote proxyremotematch proxyrequests proxyset proxystatus proxytimeout proxyvia readmename receivebuffersize redirect redirectmatch redirectpermanent redirecttemp removecharset removeencoding removehandler removeinputfilter removelanguage removeoutputfilter removetype requestheader require rewritebase rewritecond rewriteengine rewritelock rewritelog rewriteloglevel rewritemap rewriteoptions rewriterule rlimitcpu rlimitmem rlimitnproc satisfy scoreboardfile script scriptalias scriptaliasmatch scriptinterpretersource scriptlog scriptlogbuffer scriptloglength scriptsock securelisten seerequesttail sendbuffersize serveradmin serveralias serverlimit servername serverpath serverroot serversignature servertokens setenv setenvif setenvifnocase sethandler setinputfilter setoutputfilter ssienableaccess ssiendtag ssierrormsg ssistarttag ssitimeformat ssiundefinedecho sslcacertificatefile sslcacertificatepath sslcadnrequestfile sslcadnrequestpath sslcarevocationfile sslcarevocationpath sslcertificatechainfile sslcertificatefile sslcertificatekeyfile sslciphersuite sslcryptodevice sslengine sslhonorciperorder sslmutex ssloptions sslpassphrasedialog sslprotocol sslproxycacertificatefile sslproxycacertificatepath sslproxycarevocationfile sslproxycarevocationpath sslproxyciphersuite sslproxyengine sslproxymachinecertificatefile sslproxymachinecertificatepath sslproxyprotocol sslproxyverify sslproxyverifydepth sslrandomseed sslrequire sslrequiressl sslsessioncache sslsessioncachetimeout sslusername sslverifyclient sslverifydepth startservers startthreads substitute suexecusergroup threadlimit threadsperchild threadstacksize timeout traceenable transferlog typesconfig unsetenv usecanonicalname usecanonicalphysicalport user userdir virtualdocumentroot virtualdocumentrootip virtualscriptalias virtualscriptaliasip win32disableacceptex xbithack",literal:"on off"},c:[a.HCM,{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",b]},b,{cN:"tag",b:"</?",e:">"},a.QSM]}}(hljs);hljs.LANGUAGES.applescript=function(a){var b=a.inherit(a.QSM,{i:""});var e={cN:"title",b:a.UIR};var d={cN:"params",b:"\\(",e:"\\)",c:["self",a.CNM,b]};var c=[{cN:"comment",b:"--",e:"$",},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",{b:"--",e:"$"}]},a.HCM];return{k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[b,a.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bWK:true,k:"on",i:"[${=;\\n]",c:[e,d]}].concat(c),i:"//"}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);hljs.LANGUAGES.asciidoc=function(a){return{c:[{cN:"comment",b:"^/{4,}\\n",e:"\\n/{4,}$",r:10},{cN:"comment",b:"^//",e:"$",r:0},{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"header",b:"^(={1,5}) .+?( \\1)?$",r:10},{cN:"header",b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$",r:10},{cN:"attribute",b:"^:.+?:",e:"\\s",eE:true,r:10},{cN:"attribute",b:"^\\[.+?\\]$",r:0},{cN:"blockquote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"label",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{cN:"horizontal_rule",b:"^'{4,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:true,c:[{b:"(link|image:?):",r:0},{cN:"link_url",b:"\\w",e:"[^\\[]+",r:0},{cN:"link_label",b:"\\[",e:"\\]",eB:true,eE:true,r:0}],r:10}]}}(hljs);hljs.LANGUAGES.avrasm=function(a){return{cI:true,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf"},c:[a.CBLCLM,{cN:"comment",b:";",e:"$"},a.CNM,a.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"label",b:"^[A-Za-z0-9_.$]+:"},{cN:"preprocessor",b:"#",e:"$"},{cN:"preprocessor",b:"\\.[a-zA-Z]+"},{cN:"localvars",b:"@[0-9]+"}]}}(hljs);hljs.LANGUAGES.axapta=function(a){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"{",i:":",k:"class interface",c:[{cN:"inheritance",bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]}]}}(hljs);hljs.LANGUAGES.bash=function(a){var c={cN:"variable",b:/\$[\w\d#@][\w\d_]*/};var b={cN:"variable",b:/\$\{(.*?)\}/};var e={cN:"string",b:/"/,e:/"/,c:[a.BE,c,b,{cN:"variable",b:/\$\(/,e:/\)/,c:a.BE}],r:0};var d={cN:"string",b:/'/,e:/'/,r:0};return{l:/-?[a-z]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[{cN:"title",b:/\w[\w\d_]*/}],r:0},a.HCM,a.NM,e,d,c,b]}}(hljs);hljs.LANGUAGES.brainfuck=function(a){return{c:[{cN:"comment",b:"[^\\[\\]\\.,\\+\\-<> \r\n]",eE:true,e:"[\\[\\]\\.,\\+\\-<> \r\n]",r:0},{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]"},{cN:"literal",b:"[\\+\\-]"}]}}(hljs);hljs.LANGUAGES.clojure=function(l){var e={built_in:"def cond apply if-not if-let if not not= = &lt; < > &lt;= <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for doseq dosync dotimes and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import intern refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! import use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if throw printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time ns assert re-find re-groups rand-int rand mod locking assert-valid-fdecl alias namespace resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! memfn to-array future future-call into-array aset gen-class reduce merge map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"};var f="[a-zA-Z_0-9\\!\\.\\?\\-\\+\\*\\/\\<\\=\\>\\&\\#\\$';]+";var a="[\\s:\\(\\{]+\\d+(\\.\\d+)?";var d={cN:"number",b:a,r:0};var j={cN:"string",b:'"',e:'"',c:[l.BE],r:0};var o={cN:"comment",b:";",e:"$",r:0};var n={cN:"collection",b:"[\\[\\{]",e:"[\\]\\}]"};var c={cN:"comment",b:"\\^"+f};var b={cN:"comment",b:"\\^\\{",e:"\\}"};var h={cN:"attribute",b:"[:]"+f};var m={cN:"list",b:"\\(",e:"\\)"};var g={eW:true,k:{literal:"true false nil"},r:0};var i={k:e,l:f,cN:"title",b:f,starts:g};m.c=[{cN:"comment",b:"comment"},i];g.c=[m,j,c,b,o,h,n,d];n.c=[m,j,c,o,h,n,d];return{i:"\\S",c:[o,m]}}(hljs);hljs.LANGUAGES.cmake=function(a){return{cI:true,k:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file",c:[{cN:"envvar",b:"\\${",e:"}"},a.HCM,a.QSM,a.NM]}}(hljs);hljs.LANGUAGES.coffeescript=function(c){var b={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module exports global window document"};var a="[A-Za-z$_][0-9A-Za-z$_]*";var f={cN:"title",b:a};var e={cN:"subst",b:"#\\{",e:"}",k:b,};var d=[c.BNM,c.inherit(c.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",b:"'''",e:"'''",c:[c.BE]},{cN:"string",b:"'",e:"'",c:[c.BE],r:0},{cN:"string",b:'"""',e:'"""',c:[c.BE,e]},{cN:"string",b:'"',e:'"',c:[c.BE,e],r:0},{cN:"regexp",b:"///",e:"///",c:[c.HCM]},{cN:"regexp",b:"//[gim]*",r:0},{cN:"regexp",b:"/\\S(\\\\.|[^\\n])*?/[gim]*(?=\\s|\\W|$)"},{cN:"property",b:"@"+a},{b:"`",e:"`",eB:true,eE:true,sL:"javascript"}];e.c=d;return{k:b,c:d.concat([{cN:"comment",b:"###",e:"###"},c.HCM,{cN:"function",b:"("+a+"\\s*=\\s*)?(\\(.*\\))?\\s*[-=]>",e:"[-=]>",rB:true,c:[f,{cN:"params",b:"\\(",rB:true,c:[{b:/\(/,e:/\)/,k:b,c:["self"].concat(d)}]}]},{cN:"class",bWK:true,k:"class",e:"$",i:"[:\\[\\]]",c:[{bWK:true,k:"extends",eW:true,i:":",c:[f]},f]},{cN:"attribute",b:a+":",e:":",rB:true,eE:true}])}}(hljs);hljs.LANGUAGES.cpp=function(a){var b={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long throw volatile static protected bool template mutable if public friend do return goto auto void enum else break new extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'\\\\?.",e:"'",i:"."},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},a.CNM,{cN:"preprocessor",b:"#",e:"$",c:[{b:"<",e:">",i:"\\n"},a.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,r:10,c:["self"]}]}}(hljs);hljs.LANGUAGES.cs=function(a){return{k:"abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async await ascending descending from get group into join let orderby partial select set value var where yield",c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"}]},a.CLCM,a.CBLCLM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},a.ASM,a.QSM,a.CNM]}}(hljs);hljs.LANGUAGES.css=function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.NM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}}(hljs);hljs.LANGUAGES.d=function(x){var b={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"};var c="(0|[1-9][\\d_]*)",q="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",h="0[bB][01_]+",v="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",y="0[xX]"+v,p="([eE][+-]?"+q+")",o="("+q+"(\\.\\d*|"+p+")|\\d+\\."+q+q+"|\\."+c+p+"?)",k="(0[xX]("+v+"\\."+v+"|\\.?"+v+")[pP][+-]?"+q+")",l="("+c+"|"+h+"|"+y+")",n="("+k+"|"+o+")";var z="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};";var m={cN:"number",b:"\\b"+l+"(L|u|U|Lu|LU|uL|UL)?",r:0};var j={cN:"number",b:"\\b("+n+"([fF]|L|i|[fF]i|Li)?|"+l+"(i|[fF]i|Li))",r:0};var s={cN:"string",b:"'("+z+"|.)",e:"'",i:"."};var r={b:z,r:0};var w={cN:"string",b:'"',c:[r],e:'"[cwd]?',r:0};var f={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5};var u={cN:"string",b:"`",e:"`[cwd]?"};var i={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10};var t={cN:"string",b:'q"\\{',e:'\\}"'};var e={cN:"shebang",b:"^#!",e:"$",r:5};var g={cN:"preprocessor",b:"#(line)",e:"$",r:5};var d={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"};var a={cN:"comment",b:"\\/\\+",c:["self"],e:"\\+\\/",r:10};return{l:x.UIR,k:b,c:[x.CLCM,x.CBLCLM,a,i,w,f,u,t,j,m,s,e,g,d]}}(hljs);hljs.LANGUAGES.delphi=function(b){var f="and safecall cdecl then string exports library not pascal set virtual file in array label packed end. index while const raise for to implementation with except overload destructor downto finally program exit unit inherited override if type until function do begin repeat goto nil far initialization object else var uses external resourcestring interface end finalization class asm mod case on shr shl of register xorwrite threadvar try record near stored constructor stdcall inline div out or procedure";var e="safecall stdcall pascal stored const implementation finalization except to finally program inherited override then exports string read not mod shr try div shl set library message packed index for near overload label downto exit public goto interface asm on of constructor or private array unit raise destructor var type until function else external with case default record while protected property procedure published and cdecl do threadvar file in if end virtual write far out begin repeat nil initialization object uses resourcestring class register xorwrite inline static";var a={cN:"comment",b:"{",e:"}",r:0};var g={cN:"comment",b:"\\(\\*",e:"\\*\\)",r:10};var c={cN:"string",b:"'",e:"'",c:[{b:"''"}],r:0};var d={cN:"string",b:"(#\\d+)+"};var h={cN:"function",bWK:true,e:"[:;]",k:"function constructor|10 destructor|10 procedure|10",c:[{cN:"title",b:b.IR},{cN:"params",b:"\\(",e:"\\)",k:f,c:[c,d]},a,g]};return{cI:true,k:f,i:'("|\\$[G-Zg-z]|\\/\\*|</)',c:[a,g,b.CLCM,c,d,b.NM,h,{cN:"class",b:"=\\bclass\\b",e:"end;",k:e,c:[c,d,a,g,b.CLCM,h]}]}}(hljs);hljs.LANGUAGES.diff=function(a){return{c:[{cN:"chunk",b:"^\\@\\@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +\\@\\@$",r:10},{cN:"chunk",b:"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$",r:10},{cN:"chunk",b:"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$",r:10},{cN:"header",b:"Index: ",e:"$"},{cN:"header",b:"=====",e:"=====$"},{cN:"header",b:"^\\-\\-\\-",e:"$"},{cN:"header",b:"^\\*{3} ",e:"$"},{cN:"header",b:"^\\+\\+\\+",e:"$"},{cN:"header",b:"\\*{5}",e:"\\*{5}$"},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}(hljs);hljs.LANGUAGES.django=function(c){function e(h,g){return(g==undefined||(!h.cN&&g.cN=="tag")||h.cN=="value")}function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}if(e(l,k)){m=b.concat(m)}if(m.length){g.c=m}}return g}var d={cN:"filter",b:"\\|[A-Za-z]+\\:?",k:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone",c:[{cN:"argument",b:'"',e:'"'}]};var b=[{cN:"template_comment",b:"{%\\s*comment\\s*%}",e:"{%\\s*endcomment\\s*%}"},{cN:"template_comment",b:"{#",e:"#}"},{cN:"template_tag",b:"{%",e:"%}",k:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor in ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup by as ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim",c:[d]},{cN:"variable",b:"{{",e:"}}",c:[d]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.dos=function(a){return{cI:true,k:{flow:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",keyword:"shift cd dir echo setlocal endlocal set pause copy",stream:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux",winutils:"ping net ipconfig taskkill xcopy ren del"},c:[{cN:"envvar",b:"%%[^ ]"},{cN:"envvar",b:"%[^ ]+?%"},{cN:"envvar",b:"![^ ]+?!"},{cN:"number",b:"\\b\\d+",r:0},{cN:"comment",b:"@?rem",e:"$"}]}}(hljs);hljs.LANGUAGES["erlang-repl"]=function(a){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},{cN:"comment",b:"%",e:"$"},{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a.ASM,a.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}}(hljs);hljs.LANGUAGES.erlang=function(i){var c="[a-z'][a-zA-Z0-9_']*";var o="("+c+":"+c+"|"+c+")";var f={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun let not of orelse|10 query receive rem try when xor",literal:"false true"};var l={cN:"comment",b:"%",e:"$",r:0};var e={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0};var g={b:"fun\\s+"+c+"/\\d+"};var n={b:o+"\\(",e:"\\)",rB:true,r:0,c:[{cN:"function_name",b:o,r:0},{b:"\\(",e:"\\)",eW:true,rE:true,r:0}]};var h={cN:"tuple",b:"{",e:"}",r:0};var a={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0};var m={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0};var b={b:"#",e:"}",i:".",r:0,rB:true,c:[{cN:"record_name",b:"#"+i.UIR,r:0},{b:"{",eW:true,r:0}]};var k={k:f,b:"(fun|receive|if|try|case)",e:"end"};k.c=[l,g,i.inherit(i.ASM,{cN:""}),k,n,i.QSM,e,h,a,m,b];var j=[l,g,k,n,i.QSM,e,h,a,m,b];n.c[1].c=j;h.c=j;b.c[1].c=j;var d={cN:"params",b:"\\(",e:"\\)",c:j};return{k:f,i:"(</|\\*=|\\+=|-=|/=|/\\*|\\*/|\\(\\*|\\*\\))",c:[{cN:"function",b:"^"+c+"\\s*\\(",e:"->",rB:true,i:"\\(|#|//|/\\*|\\\\|:",c:[d,{cN:"title",b:c}],starts:{e:";|\\.",k:f,c:j}},l,{cN:"pp",b:"^-",e:"\\.",r:0,eE:true,rB:true,l:"-"+i.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior",c:[d]},e,i.QSM,b,a,m,h]}}(hljs);hljs.LANGUAGES.fsharp=function(a){var b="'[a-zA-Z0-9_]+";return{k:"yield! return! let! do!abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun|10 function global if in inherit inline interface internal lazy let match member module mutable|10 namespace new null of open or override private public rec|10 return sig static struct then to true try type upcast use val void when while with yield",c:[{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},{cN:"comment",b:"//",e:"$",rB:true},{cN:"comment",b:"\\(\\*",e:"\\*\\)"},{cN:"class",bWK:true,e:"\\(|=|$",k:"type",c:[{cN:"title",b:a.UIR}]},{cN:"annotation",b:"\\[<",e:">\\]",r:10},{cN:"typeparam",b:"<",e:">",c:[{cN:"title",b:b}]},a.CLCM,a.CBLCLM,a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),a.CNM]}}(hljs);hljs.LANGUAGES.glsl=function(a){return{k:{keyword:"atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly",built_in:"gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffsetgl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse",literal:"true false"},i:'"',c:[a.CLCM,a.CBLCLM,a.CNM,{cN:"preprocessor",b:"#",e:"$"}]}}(hljs);hljs.LANGUAGES.go=function(a){var b={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer",constant:"true false iota nil",typename:"bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"string",b:"`",e:"`"},{cN:"number",b:"[^a-zA-Z_0-9](\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?",r:0},a.CNM]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.haml=function(a){return{cI:true,c:[{cN:"doctype",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},{cN:"comment",b:"^\\s*(-#|/).*$",r:0},{b:"^\\s*-(?!#)",starts:{e:"\\n",sL:"ruby"},r:0},{cN:"tag",b:"^\\s*%",c:[{cN:"title",b:"\\w+",r:0},{cN:"value",b:"[#\\.]\\w+",r:0},{b:"{\\s*",e:"\\s*}",eE:true,c:[{b:":\\w+\\s*=>",e:",\\s+",rB:true,eW:true,r:0,c:[{cN:"symbol",b:":\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0},{b:"\\(\\s*",e:"\\s*\\)",eE:true,c:[{b:"\\w+\\s*=",e:"\\s+",rB:true,eW:true,r:0,c:[{cN:"attribute",b:"\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0}],r:10},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"},r:0}]}}(hljs);hljs.LANGUAGES.handlebars=function(c){function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}m=d.concat(m);if(m.length){g.c=m}}return g}var b="each in with if else unless bindattr action collection debugger log outlet template unbound view yield";var e={cN:"variable",b:"[a-zA-Z.]+",k:b};var d=[{cN:"expression",b:"{{",e:"}}",c:[{cN:"begin-block",b:"#[a-zA-Z .]+",k:b},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z .]+",k:b},{cN:"variable",b:"[a-zA-Z.]+",k:b}]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.haskell=function(a){var d={cN:"type",b:"\\b[A-Z][\\w']*",r:0};var c={cN:"container",b:"\\(",e:"\\)",i:'"',c:[{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},{cN:"title",b:"[_a-z][\\w']*"}]};var b={cN:"container",b:"{",e:"}",c:c.c};return{k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance not as foreign ccall safe unsafe",c:[{cN:"comment",b:"--",e:"$"},{cN:"preprocessor",b:"{-#",e:"#-}"},{cN:"comment",c:["self"],b:"{-",e:"-}"},{cN:"string",b:"\\s+'",e:"'",c:[a.BE],r:0},a.QSM,{cN:"import",b:"\\bimport",e:"$",k:"import qualified as hiding",c:[c],i:"\\W\\.|;"},{cN:"module",b:"\\bmodule",e:"where",k:"module where",c:[c],i:"\\W\\.|;"},{cN:"class",b:"\\b(class|instance)",e:"where",k:"class where instance",c:[d]},{cN:"typedef",b:"\\b(data|(new)?type)",e:"$",k:"data type newtype deriving",c:[d,c,b]},a.CNM,{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},d,{cN:"title",b:"^[_a-z][\\w']*"},{b:"->|<-"}]}}(hljs);hljs.LANGUAGES.http=function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}}(hljs);hljs.LANGUAGES.ini=function(a){return{cI:true,i:"[^\\s]",c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:"on off true false yes no",c:[a.QSM,a.NM],r:0}]}]}}(hljs);hljs.LANGUAGES.java=function(a){return{k:"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,{cN:"class",bWK:true,e:"{",k:"class interface",eE:true,i:":",c:[{bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]},a.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}}(hljs);hljs.LANGUAGES.javascript=function(a){return{k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const",literal:"true false null undefined NaN Infinity"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,a.REGEXP_MODE,{b:/</,e:/>;/,sL:"xml"}],r:0},{cN:"function",bWK:true,e:/{/,k:"function",c:[{cN:"title",b:/[A-Za-z$_][0-9A-Za-z$_]*/},{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBLCLM],i:/["'\(]/}],i:/\[|%/}]}}(hljs);hljs.LANGUAGES.json=function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}}(hljs);hljs.LANGUAGES.lasso=function(b){var a="[a-zA-Z_][a-zA-Z0-9_.]*|&[lg]t;";var c="<\\?(lasso(script)?|=)";return{cI:true,l:a,k:{literal:"true false none minimal full all infinity nan and or not bw ew cn lt lte gt gte eq neq ft rx nrx",built_in:"array date decimal duration integer map pair string tag xml null list queue set stack staticarray local var variable data global self inherited void",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require skip split_thread sum take thread to trait type where with yield"},c:[{cN:"preprocessor",b:"\\]|\\?>",r:0,starts:{cN:"markup",e:"\\[|"+c,rE:true}},{cN:"preprocessor",b:"\\[noprocess\\]",starts:{cN:"markup",e:"\\[/noprocess\\]",rE:true}},{cN:"preprocessor",b:"\\[no_square_brackets|\\[/noprocess|"+c},{cN:"preprocessor",b:"\\[",r:0},{cN:"shebang",b:"^#!.+lasso9\\b",r:10},b.CLCM,{cN:"javadoc",b:"/\\*\\*!",e:"\\*/"},b.CBLCLM,b.CNM,b.inherit(b.ASM,{i:null}),b.inherit(b.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{cN:"variable",b:"#\\d+|[#$]"+a},{cN:"tag",b:"::",e:a},{cN:"attribute",b:"\\.\\.\\.|-"+b.UIR},{cN:"class",bWK:true,k:"define",eE:true,e:"\\(|=>",c:[{cN:"title",b:b.UIR+"=?"}]}]}}(hljs);hljs.LANGUAGES.lisp=function(i){var l="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*";var m="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?";var k={cN:"shebang",b:"^#!",e:"$"};var a={cN:"literal",b:"\\b(t{1}|nil)\\b"};var d=[{cN:"number",b:m},{cN:"number",b:"#b[0-1]+(/[0-1]+)?"},{cN:"number",b:"#o[0-7]+(/[0-7]+)?"},{cN:"number",b:"#x[0-9a-f]+(/[0-9a-f]+)?"},{cN:"number",b:"#c\\("+m+" +"+m,e:"\\)"}];var h={cN:"string",b:'"',e:'"',c:[i.BE],r:0};var n={cN:"comment",b:";",e:"$"};var g={cN:"variable",b:"\\*",e:"\\*"};var o={cN:"keyword",b:"[:&]"+l};var b={b:"\\(",e:"\\)",c:["self",a,h].concat(d)};var e={cN:"quoted",b:"['`]\\(",e:"\\)",c:d.concat([h,g,o,b])};var c={cN:"quoted",b:"\\(quote ",e:"\\)",k:{title:"quote"},c:d.concat([h,g,o,b])};var j={cN:"list",b:"\\(",e:"\\)"};var f={eW:true,r:0};j.c=[{cN:"title",b:l},f];f.c=[e,c,j,a].concat(d).concat([h,n,g,o]);return{i:"[^\\s]",c:d.concat([k,a,h,n,e,c,j])}}(hljs);hljs.LANGUAGES.lua=function(b){var a="\\[=*\\[";var e="\\]=*\\]";var c={b:a,e:e,c:["self"]};var d=[{cN:"comment",b:"--(?!"+a+")",e:"$"},{cN:"comment",b:"--"+a,e:e,c:[c],r:10}];return{l:b.UIR,k:{keyword:"and break do else elseif end false for if in local nil not or repeat return then true until while",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},c:d.concat([{cN:"function",bWK:true,e:"\\)",k:"function",c:[{cN:"title",b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"},{cN:"params",b:"\\(",eW:true,c:d}].concat(d)},b.CNM,b.ASM,b.QSM,{cN:"string",b:a,e:e,c:[c],r:10}])}}(hljs);hljs.LANGUAGES.markdown=function(a){return{c:[{cN:"header",b:"^#{1,3}",e:"$"},{cN:"header",b:"^.+?\\n[=-]{2,}$"},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",b:"\\*.+?\\*"},{cN:"emphasis",b:"_.+?_",r:0},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",b:"`.+?`"},{cN:"code",b:"^    ",e:"$",r:0},{cN:"horizontal_rule",b:"^-{3,}",e:"$"},{b:"\\[.+?\\]\\(.+?\\)",rB:true,c:[{cN:"link_label",b:"\\[.+\\]"},{cN:"link_url",b:"\\(",e:"\\)",eB:true,eE:true}]}]}}(hljs);hljs.LANGUAGES.matlab=function(a){var b=[a.CNM,{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0}];return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bWK:true,e:"$",k:"function",c:[{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)"},{cN:"params",b:"\\[",e:"\\]"}]},{cN:"transposed_variable",b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:""},{cN:"matrix",b:"\\[",e:"\\]'*[\\.']*",c:b},{cN:"cell",b:"\\{",e:"\\}'*[\\.']*",c:b},{cN:"comment",b:"\\%",e:"$"}].concat(b)}}(hljs);hljs.LANGUAGES.mel=function(a){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:"</",c:[a.CNM,a.ASM,a.QSM,{cN:"string",b:"`",e:"`",c:[a.BE]},{cN:"variable",b:"\\$\\d",r:5},{cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+|[^\\s\\w{]|{\\w+}|\\w+)"},a.CLCM,a.CBLCLM]}}(hljs);hljs.LANGUAGES.mizar=function(a){return{k:["environ vocabularies notations constructors definitions registrations theorems schemes requirements","begin end definition registration cluster existence pred func defpred deffunc theorem proof","let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from","be being by means equals implies iff redefine define now not or attr is mode suppose per cases set","thesis contradiction scheme reserve struct","correctness compatibility coherence symmetry assymetry reflexivity irreflexivity","connectedness uniqueness commutativity idempotence involutiveness projectivity"].join(" "),c:[{cN:"comment",b:"::",e:"$"}]}}(hljs);hljs.LANGUAGES.nginx=function(b){var c=[{cN:"variable",b:"\\$\\d+"},{cN:"variable",b:"\\${",e:"}"},{cN:"variable",b:"[\\$\\@]"+b.UIR}];var a={eW:true,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[b.HCM,{cN:"string",b:'"',e:'"',c:[b.BE].concat(c),r:0},{cN:"string",b:"'",e:"'",c:[b.BE].concat(c),r:0},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:true,eE:true},{cN:"regexp",b:"\\s\\^",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"~\\*?\\s+",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"\\*(\\.[a-z\\-]+)+",c:[b.BE].concat(c)},{cN:"regexp",b:"([a-z\\-]+\\.)+\\*",c:[b.BE].concat(c)},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0}].concat(c)};return{c:[b.HCM,{b:b.UIR+"\\s",e:";|{",rB:true,c:[{cN:"title",b:b.UIR,starts:a}],r:0}],i:"[^\\s\\}]"}}(hljs);hljs.LANGUAGES.objectivec=function(a){var b={keyword:"int float while private char catch export sizeof typedef const struct for union unsigned long volatile static protected bool mutable if public do return goto void enum else break extern asm case short default double throw register explicit signed typename try this switch continue wchar_t inline readonly assign property self synchronized end synthesize id optional required nonatomic super unichar finally dynamic IBOutlet IBAction selector strong weak readonly",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection UIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.CNM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"preprocessor",b:"#import",e:"$",c:[{cN:"title",b:'"',e:'"'},{cN:"title",b:"<",e:">"}]},{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"({|$)",k:"interface class protocol implementation",c:[{cN:"id",b:a.UIR}]},{cN:"variable",b:"\\."+a.UIR,r:0}]}}(hljs);hljs.LANGUAGES.parser3=function(a){return{sL:"xml",r:0,c:[{cN:"comment",b:"^#",e:"$"},{cN:"comment",b:"\\^rem{",e:"}",r:10,c:[{b:"{",e:"}",c:["self"]}]},{cN:"preprocessor",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},a.CNM]}}(hljs);hljs.LANGUAGES.perl=function(e){var a="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when";var d={cN:"subst",b:"[$@]\\{",e:"\\}",k:a,r:10};var b={cN:"variable",b:"\\$\\d"};var i={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var f=[e.BE,d,b,i];var h={b:"->",c:[{b:e.IR},{b:"{",e:"}"}]};var g={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5};var c=[b,i,e.HCM,g,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:true},h,{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:f,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:f,r:5},{cN:"string",b:"'",e:"'",c:[e.BE],r:0},{cN:"string",b:'"',e:'"',c:f,r:0},{cN:"string",b:"`",e:"`",c:[e.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"("+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,g,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bWK:true,e:"(\\s*\\(.*?\\))?[;{]",k:"sub",r:5},{cN:"operator",b:"-\\w\\b",r:0}];d.c=c;h.c[1].c=c;return{k:a,c:c}}(hljs);hljs.LANGUAGES.php=function(a){var e={cN:"variable",b:"\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"};var b=[a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),{cN:"string",b:'b"',e:'"',c:[a.BE]},{cN:"string",b:"b'",e:"'",c:[a.BE]}];var c=[a.BNM,a.CNM];var d={cN:"title",b:a.UIR};return{cI:true,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return implements parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception php_user_filter default die require __FUNCTION__ enddeclare final try this switch continue endfor endif declare unset true false namespace trait goto instanceof insteadof __DIR__ __NAMESPACE__ __halt_compiler",c:[a.CLCM,a.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"}]},{cN:"comment",eB:true,b:"__halt_compiler.+?;",eW:true},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[a.BE]},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"},e,{cN:"function",bWK:true,e:"{",k:"function",i:"\\$|\\[|%",c:[d,{cN:"params",b:"\\(",e:"\\)",c:["self",e,a.CBLCLM].concat(b).concat(c)}]},{cN:"class",bWK:true,e:"{",k:"class",i:"[:\\(\\$]",c:[{bWK:true,eW:true,k:"extends",c:[d]},d]},{b:"=>"}].concat(b).concat(c)}}(hljs);hljs.LANGUAGES.profile=function(a){return{c:[a.CNM,{cN:"built_in",b:"{",e:"}$",eB:true,eE:true,c:[a.ASM,a.QSM],r:0},{cN:"filename",b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:true},{cN:"header",b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{cN:"summary",b:"function calls",e:"$",c:[a.CNM],r:10},a.ASM,a.QSM,{cN:"function",b:"\\(",e:"\\)$",c:[{cN:"title",b:a.UIR,r:0}],r:0}]}}(hljs);hljs.LANGUAGES.python=function(a){var f={cN:"prompt",b:/^(>>>|\.\.\.) /};var c=[{cN:"string",b:/(u|b)?r?'''/,e:/'''/,c:[f],r:10},{cN:"string",b:/(u|b)?r?"""/,e:/"""/,c:[f],r:10},{cN:"string",b:/(u|r|ur)'/,e:/'/,c:[a.BE],r:10},{cN:"string",b:/(u|r|ur)"/,e:/"/,c:[a.BE],r:10},{cN:"string",b:/(b|br)'/,e:/'/,c:[a.BE]},{cN:"string",b:/(b|br)"/,e:/"/,c:[a.BE]}].concat([a.ASM,a.QSM]);var e={cN:"title",b:a.UIR};var d={cN:"params",b:/\(/,e:/\)/,c:["self",a.CNM,f].concat(c)};var b={bWK:true,e:/:/,i:/[${=;\n]/,c:[e,d],r:10};return{k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10",built_in:"None True False Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:c.concat([f,a.HCM,a.inherit(b,{cN:"function",k:"def"}),a.inherit(b,{cN:"class",k:"class"}),a.CNM,{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}])}}(hljs);hljs.LANGUAGES.r=function(a){var b="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[a.HCM,{b:b,l:b,k:{keyword:"function if in break next repeat else for return switch while try tryCatch|10 stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...|10",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",b:'"',e:'"',c:[a.BE],r:0},{cN:"string",b:"'",e:"'",c:[a.BE],r:0}]}}(hljs);hljs.LANGUAGES.rib=function(a){return{k:"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd",i:"</",c:[a.HCM,a.CNM,a.ASM,a.QSM]}}(hljs);hljs.LANGUAGES.rsl=function(a){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,a.ASM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"shader",bWK:true,e:"\\(",k:"surface displacement light volume imager"},{cN:"shading",bWK:true,e:"\\(",k:"illuminate illuminance gather"}]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.ruleslanguage=function(a){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEMASK|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN DELETE SAVE SAVE_UPDATE CLEAR DETERMINANT LABEL REPORT REVENUE ABORT CALL DONE LEAVE EACH IN LIST NOVALUE FROM TOTAL CHARGE BLOCK AND OR CSV_FILE BILL_PERIOD RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM ABORT WARN NUMDAYS RATE_CODE READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}}(hljs);hljs.LANGUAGES.rust=function(b){var d={cN:"title",b:b.UIR};var c={cN:"number",b:"\\b(0[xb][A-Za-z0-9_]+|[0-9_]+(\\.[0-9_]+)?([uif](8|16|32|64)?)?)",r:0};var a="assert bool break char check claim comm const cont copy dir do drop else enum extern export f32 f64 fail false float fn for i16 i32 i64 i8 if impl int let log loop match mod move mut priv pub pure ref return self static str struct task true trait type u16 u32 u64 u8 uint unsafe use vec while";return{k:a,i:"</",c:[b.CLCM,b.CBLCLM,b.inherit(b.QSM,{i:null}),b.ASM,c,{cN:"function",bWK:true,e:"(\\(|<)",k:"fn",c:[d]},{cN:"preprocessor",b:"#\\[",e:"\\]"},{bWK:true,e:"(=|<)",k:"type",c:[d],i:"\\S"},{bWK:true,e:"({|<)",k:"trait enum",c:[d],i:"\\S"}]}}(hljs);hljs.LANGUAGES.scala=function(a){var c={cN:"annotation",b:"@[A-Za-z]+"};var b={cN:"string",b:'u?r?"""',e:'"""',r:10};return{k:"type yield lazy override def with val var false true sealed abstract private trait object null if for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,b,{cN:"class",b:"((case )?class |object |trait )",e:"({|$)",i:":",k:"case class trait object",c:[{bWK:true,k:"extends with",r:10},{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,b,c]}]},a.CNM,c]}}(hljs);hljs.LANGUAGES.scss=function(a){var c="[a-zA-Z-][a-zA-Z0-9_-]*";var d={cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};var b={cN:"hexcolor",b:"#[0-9A-Fa-f]+"};var e={cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[d,b,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"important",b:"!important"}]}};return{cI:true,i:"[=/|']",c:[a.CLCM,a.CBLCLM,{cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]},{cN:"id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{cN:"pseudo",b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{cN:"pseudo",b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{cN:"value",b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{cN:"value",b:":",e:";",c:[b,a.NM,a.QSM,a.ASM,{cN:"important",b:"!important"}]},{cN:"at_rule",b:"@",e:"[{;]",k:"mixin include for extend charset import media page font-face namespace",c:[d,a.QSM,a.ASM,b,a.NM,{cN:"preprocessor",b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}}(hljs);hljs.LANGUAGES.smalltalk=function(a){var b="[a-z][a-zA-Z0-9_]*";var d={cN:"char",b:"\\$.{1}"};var c={cN:"symbol",b:"#"+a.UIR};return{k:"self super nil true false thisContext",c:[{cN:"comment",b:'"',e:'"',r:0},a.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:b+":"},a.CNM,c,d,{cN:"localvars",b:"\\|\\s*"+b+"(\\s+"+b+")*\\s*\\|"},{cN:"array",b:"\\#\\(",e:"\\)",c:[a.ASM,d,a.CNM,c]}]}}(hljs);hljs.LANGUAGES.sql=function(a){return{cI:true,c:[{cN:"operator",b:"(begin|end|start|commit|rollback|savepoint|lock|alter|create|drop|rename|call|delete|do|handler|insert|load|replace|select|truncate|update|set|show|pragma|grant)\\b(?!:)",e:";",eW:true,k:{keyword:"all partial global month current_timestamp using go revoke smallint indicator end-exec disconnect zone with character assertion to add current_user usage input local alter match collate real then rollback get read timestamp session_user not integer bit unique day minute desc insert execute like ilike|2 level decimal drop continue isolation found where constraints domain right national some module transaction relative second connect escape close system_user for deferred section cast current sqlstate allocate intersect deallocate numeric public preserve full goto initially asc no key output collation group by union session both last language constraint column of space foreign deferrable prior connection unknown action commit view or first into float year primary cascaded except restrict set references names table outer open select size are rows from prepare distinct leading create only next inner authorization schema corresponding option declare precision immediate else timezone_minute external varying translation true case exception join hour default double scroll value cursor descriptor values dec fetch procedure delete and false int is describe char as at in varchar null trailing any absolute current_time end grant privileges when cross check write current_date pad begin temporary exec time update catalog user sql date on identity timezone_hour natural whenever interval work order cascade diagnostics nchar having left call do handler load replace truncate start lock show pragma exists number trigger if before after each row",aggregate:"count sum min max avg"},c:[{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0},{cN:"string",b:'"',e:'"',c:[a.BE,{b:'""'}],r:0},{cN:"string",b:"`",e:"`",c:[a.BE]},a.CNM]},a.CBLCLM,{cN:"comment",b:"--",e:"$"}]}}(hljs);hljs.LANGUAGES.tex=function(a){var d={cN:"command",b:"\\\\[a-zA-Zа-яА-я]+[\\*]?"};var c={cN:"command",b:"\\\\[^a-zA-Zа-яА-я0-9]"};var b={cN:"special",b:"[{}\\[\\]\\&#~]",r:0};return{c:[{b:"\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",rB:true,c:[d,c,{cN:"number",b:" *=",e:"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",eB:true}],r:10},d,c,b,{cN:"formula",b:"\\$\\$",e:"\\$\\$",c:[d,c,b],r:0},{cN:"formula",b:"\\$",e:"\\$",c:[d,c,b],r:0},{cN:"comment",b:"%",e:"$",r:0}]}}(hljs);hljs.LANGUAGES.vala=function(a){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object",literal:"false true null"},c:[{cN:"class",bWK:true,e:"{",k:"class interface delegate namespace",i:"[^,:\\n\\s\\.]",c:[{cN:"title",b:a.UIR}]},a.CLCM,a.CBLCLM,{cN:"string",b:'"""',e:'"""',r:5},a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"^#",e:"$",r:2},{cN:"constant",b:" [A-Z_]+ ",r:0}]}}(hljs);hljs.LANGUAGES.vbnet=function(a){return{cI:true,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"(//|endif|gosub|variant|wend)",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"'''|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"},]},a.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end region externalsource"},]}}(hljs);hljs.LANGUAGES.vbscript=function(a){return{cI:true,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$"},a.CNM]}}(hljs);hljs.LANGUAGES.vhdl=function(a){return{cI:true,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",typename:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[a.CBLCLM,{cN:"comment",b:"--",e:"$"},a.QSM,a.CNM,{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[a.BE]},{cN:"attribute",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[a.BE]}]}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/leap/leap.js b/docs/slides/ETH14/_support/reveal.js/plugin/leap/leap.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/leap/leap.js
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2013, Leap Motion, Inc.
+ * 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 HOLDER 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.
+ *
+ * Version 0.2.0 - http://js.leapmotion.com/0.2.0/leap.min.js
+ * Grab latest versions from http://js.leapmotion.com/
+ */
+
+!function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i}({1:[function(require,module,exports){var chooseProtocol=require("./protocol").chooseProtocol,EventEmitter=require("events").EventEmitter,_=require("underscore");var BaseConnection=module.exports=function(opts){this.opts=_.defaults(opts||{},{host:"127.0.0.1",enableGestures:false,port:6437,enableHeartbeat:true,heartbeatInterval:100,requestProtocolVersion:3});this.host=opts.host;this.port=opts.port;this.on("ready",function(){this.enableGestures(this.opts.enableGestures);if(this.opts.enableHeartbeat)this.startHeartbeat()});this.on("disconnect",function(){if(this.opts.enableHeartbeat)this.stopHeartbeat()});this.heartbeatTimer=null};BaseConnection.prototype.getUrl=function(){return"ws://"+this.host+":"+this.port+"/v"+this.opts.requestProtocolVersion+".json"};BaseConnection.prototype.sendHeartbeat=function(){if(this.protocol){this.setHeartbeatState(true);this.protocol.sendHeartbeat(this)}};BaseConnection.prototype.handleOpen=function(){this.emit("connect")};BaseConnection.prototype.enableGestures=function(enabled){this.gesturesEnabled=enabled?true:false;this.send(this.protocol.encode({enableGestures:this.gesturesEnabled}))};BaseConnection.prototype.handleClose=function(){this.disconnect();this.startReconnection()};BaseConnection.prototype.startReconnection=function(){var connection=this;setTimeout(function(){connection.connect()},1e3)};BaseConnection.prototype.disconnect=function(){if(!this.socket)return;this.socket.close();delete this.socket;delete this.protocol;this.emit("disconnect")};BaseConnection.prototype.handleData=function(data){var message=JSON.parse(data);var messageEvent;if(this.protocol===undefined){messageEvent=this.protocol=chooseProtocol(message);this.emit("ready")}else{messageEvent=this.protocol(message)}this.emit(messageEvent.type,messageEvent)};BaseConnection.prototype.connect=function(){if(this.socket)return;this.socket=this.setupSocket();return true};BaseConnection.prototype.send=function(data){this.socket.send(data)};BaseConnection.prototype.stopHeartbeat=function(){if(!this.heartbeatTimer)return;clearInterval(this.heartbeatTimer);delete this.heartbeatTimer;this.setHeartbeatState(false)};BaseConnection.prototype.setHeartbeatState=function(state){if(this.heartbeatState===state)return;this.heartbeatState=state;this.emit(this.heartbeatState?"focus":"blur")};_.extend(BaseConnection.prototype,EventEmitter.prototype)},{"./protocol":12,events:17,underscore:20}],2:[function(require,module,exports){var CircularBuffer=module.exports=function(size){this.pos=0;this._buf=[];this.size=size};CircularBuffer.prototype.get=function(i){if(i==undefined)i=0;if(i>=this.size)return undefined;if(i>=this._buf.length)return undefined;return this._buf[(this.pos-i-1)%this.size]};CircularBuffer.prototype.push=function(o){this._buf[this.pos%this.size]=o;return this.pos++}},{}],3:[function(require,module,exports){var Connection=module.exports=require("./base_connection");Connection.prototype.setupSocket=function(){var connection=this;var socket=new WebSocket(this.getUrl());socket.onopen=function(){connection.handleOpen()};socket.onmessage=function(message){connection.handleData(message.data)};socket.onclose=function(){connection.handleClose()};return socket};Connection.prototype.startHeartbeat=function(){if(!this.protocol.sendHeartbeat||this.heartbeatTimer)return;var connection=this;var propertyName=null;if(typeof document.hidden!=="undefined"){propertyName="hidden"}else if(typeof document.mozHidden!=="undefined"){propertyName="mozHidden"}else if(typeof document.msHidden!=="undefined"){propertyName="msHidden"}else if(typeof document.webkitHidden!=="undefined"){propertyName="webkitHidden"}else{propertyName=undefined}var windowVisible=true;var focusListener=window.addEventListener("focus",function(e){windowVisible=true});var blurListener=window.addEventListener("blur",function(e){windowVisible=false});this.on("disconnect",function(){if(connection.heartbeatTimer){clearTimeout(connection.heartbeatTimer);delete connection.heartbeatTimer}window.removeEventListener(focusListener);window.removeEventListener(blurListener)});this.heartbeatTimer=setInterval(function(){var isVisible=propertyName===undefined?true:document[propertyName]===false;if(isVisible&&windowVisible){connection.sendHeartbeat()}else{connection.setHeartbeatState(false)}},this.opts.heartbeatInterval)}},{"./base_connection":1}],4:[function(require,module,exports){!function(process){var Frame=require("./frame"),CircularBuffer=require("./circular_buffer"),Pipeline=require("./pipeline"),EventEmitter=require("events").EventEmitter,gestureListener=require("./gesture").gestureListener,_=require("underscore");var Controller=module.exports=function(opts){var inNode=typeof process!=="undefined"&&process.title==="node";opts=_.defaults(opts||{},{inNode:inNode});this.inNode=opts.inNode;opts=_.defaults(opts||{},{frameEventName:this.useAnimationLoop()?"animationFrame":"deviceFrame",supressAnimationLoop:false});this.supressAnimationLoop=opts.supressAnimationLoop;this.frameEventName=opts.frameEventName;this.history=new CircularBuffer(200);this.lastFrame=Frame.Invalid;this.lastValidFrame=Frame.Invalid;this.lastConnectionFrame=Frame.Invalid;this.accumulatedGestures=[];if(opts.connectionType===undefined){this.connectionType=this.inBrowser()?require("./connection"):require("./node_connection")}else{this.connectionType=opts.connectionType}this.connection=new this.connectionType(opts);this.setupConnectionEvents()};Controller.prototype.gesture=function(type,cb){var creator=gestureListener(this,type);if(cb!==undefined){creator.stop(cb)}return creator};Controller.prototype.inBrowser=function(){return!this.inNode};Controller.prototype.useAnimationLoop=function(){return this.inBrowser()&&typeof chrome==="undefined"};Controller.prototype.connect=function(){var controller=this;if(this.connection.connect()&&this.inBrowser()&&!controller.supressAnimationLoop){var callback=function(){controller.emit("animationFrame",controller.lastConnectionFrame);window.requestAnimFrame(callback)};window.requestAnimFrame(callback)}};Controller.prototype.disconnect=function(){this.connection.disconnect()};Controller.prototype.frame=function(num){return this.history.get(num)||Frame.Invalid};Controller.prototype.loop=function(callback){switch(callback.length){case 1:this.on(this.frameEventName,callback);break;case 2:var controller=this;var scheduler=null;var immediateRunnerCallback=function(frame){callback(frame,function(){if(controller.lastFrame!=frame){immediateRunnerCallback(controller.lastFrame)}else{controller.once(controller.frameEventName,immediateRunnerCallback)}})};this.once(this.frameEventName,immediateRunnerCallback);break}this.connect()};Controller.prototype.addStep=function(step){if(!this.pipeline)this.pipeline=new Pipeline(this);this.pipeline.addStep(step)};Controller.prototype.processFrame=function(frame){if(frame.gestures){this.accumulatedGestures=this.accumulatedGestures.concat(frame.gestures)}if(this.pipeline){frame=this.pipeline.run(frame);if(!frame)frame=Frame.Invalid}this.lastConnectionFrame=frame;this.emit("deviceFrame",frame)};Controller.prototype.processFinishedFrame=function(frame){this.lastFrame=frame;if(frame.valid){this.lastValidFrame=frame}frame.controller=this;frame.historyIdx=this.history.push(frame);if(frame.gestures){frame.gestures=this.accumulatedGestures;this.accumulatedGestures=[];for(var gestureIdx=0;gestureIdx!=frame.gestures.length;gestureIdx++){this.emit("gesture",frame.gestures[gestureIdx],frame)}}this.emit("frame",frame)};Controller.prototype.setupConnectionEvents=function(){var controller=this;this.connection.on("frame",function(frame){controller.processFrame(frame)});this.on(this.frameEventName,function(frame){controller.processFinishedFrame(frame)});this.connection.on("disconnect",function(){controller.emit("disconnect")});this.connection.on("ready",function(){controller.emit("ready")});this.connection.on("connect",function(){controller.emit("connect")});this.connection.on("focus",function(){controller.emit("focus")});this.connection.on("blur",function(){controller.emit("blur")});this.connection.on("protocol",function(protocol){controller.emit("protocol",protocol)});this.connection.on("deviceConnect",function(evt){controller.emit(evt.state?"deviceConnected":"deviceDisconnected")})};_.extend(Controller.prototype,EventEmitter.prototype)}(require("__browserify_process"))},{"./circular_buffer":2,"./connection":3,"./frame":5,"./gesture":6,"./node_connection":16,"./pipeline":10,__browserify_process:18,events:17,underscore:20}],5:[function(require,module,exports){var Hand=require("./hand"),Pointable=require("./pointable"),createGesture=require("./gesture").createGesture,glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,InteractionBox=require("./interaction_box"),_=require("underscore");var Frame=module.exports=function(data){this.valid=true;this.id=data.id;this.timestamp=data.timestamp;this.hands=[];this.handsMap={};this.pointables=[];this.tools=[];this.fingers=[];if(data.interactionBox){this.interactionBox=new InteractionBox(data.interactionBox)}this.gestures=[];this.pointablesMap={};this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.data=data;this.type="frame";this.currentFrameRate=data.currentFrameRate;var handMap={};for(var handIdx=0,handCount=data.hands.length;handIdx!=handCount;handIdx++){var hand=new Hand(data.hands[handIdx]);hand.frame=this;this.hands.push(hand);this.handsMap[hand.id]=hand;handMap[hand.id]=handIdx}for(var pointableIdx=0,pointableCount=data.pointables.length;pointableIdx!=pointableCount;pointableIdx++){var pointable=new Pointable(data.pointables[pointableIdx]);pointable.frame=this;this.pointables.push(pointable);this.pointablesMap[pointable.id]=pointable;(pointable.tool?this.tools:this.fingers).push(pointable);if(pointable.handId!==undefined&&handMap.hasOwnProperty(pointable.handId)){var hand=this.hands[handMap[pointable.handId]];hand.pointables.push(pointable);(pointable.tool?hand.tools:hand.fingers).push(pointable)}}if(data.gestures){for(var gestureIdx=0,gestureCount=data.gestures.length;gestureIdx!=gestureCount;gestureIdx++){this.gestures.push(createGesture(data.gestures[gestureIdx]))}}};Frame.prototype.tool=function(id){var pointable=this.pointable(id);return pointable.tool?pointable:Pointable.Invalid};Frame.prototype.pointable=function(id){return this.pointablesMap[id]||Pointable.Invalid};Frame.prototype.finger=function(id){var pointable=this.pointable(id);return!pointable.tool?pointable:Pointable.Invalid};Frame.prototype.hand=function(id){return this.handsMap[id]||Hand.Invalid};Frame.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Frame.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceFrame._rotation[5],this._rotation[2]-sinceFrame._rotation[6],this._rotation[3]-sinceFrame._rotation[1]])};Frame.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);return mat3.multiply(mat3.create(),sinceFrame._rotation,transpose)};Frame.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;return Math.exp(this._scaleFactor-sinceFrame._scaleFactor)};Frame.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.subtract(vec3.create(),this._translation,sinceFrame._translation)};Frame.prototype.toString=function(){var str="Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")";if(this.gestures)str+=" | Gesture count:("+this.gestures.length+")";str+=" ]";return str};Frame.prototype.dump=function(){var out="";out+="Frame Info:<br/>";out+=this.toString();out+="<br/><br/>Hands:<br/>";for(var handIdx=0,handCount=this.hands.length;handIdx!=handCount;handIdx++){out+="  "+this.hands[handIdx].toString()+"<br/>"}out+="<br/><br/>Pointables:<br/>";for(var pointableIdx=0,pointableCount=this.pointables.length;pointableIdx!=pointableCount;pointableIdx++){out+="  "+this.pointables[pointableIdx].toString()+"<br/>"}if(this.gestures){out+="<br/><br/>Gestures:<br/>";for(var gestureIdx=0,gestureCount=this.gestures.length;gestureIdx!=gestureCount;gestureIdx++){out+="  "+this.gestures[gestureIdx].toString()+"<br/>"}}out+="<br/><br/>Raw JSON:<br/>";out+=JSON.stringify(this.data);return out};Frame.Invalid={valid:false,hands:[],fingers:[],tools:[],gestures:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},hand:function(){return Hand.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"gl-matrix":19,underscore:20}],6:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3,EventEmitter=require("events").EventEmitter,_=require("underscore");var createGesture=exports.createGesture=function(data){var gesture;switch(data.type){case"circle":gesture=new CircleGesture(data);break;case"swipe":gesture=new SwipeGesture(data);break;case"screenTap":gesture=new ScreenTapGesture(data);break;case"keyTap":gesture=new KeyTapGesture(data);break;default:throw"unkown gesture type"}gesture.id=data.id;gesture.handIds=data.handIds;gesture.pointableIds=data.pointableIds;gesture.duration=data.duration;gesture.state=data.state;gesture.type=data.type;return gesture};var gestureListener=exports.gestureListener=function(controller,type){var handlers={};var gestureMap={};var gestureCreator=function(){var candidateGesture=gestureMap[gesture.id];if(candidateGesture!==undefined)gesture.update(gesture,frame);if(gesture.state=="start"||gesture.state=="stop"){if(type==gesture.type&&gestureMap[gesture.id]===undefined){gestureMap[gesture.id]=new Gesture(gesture,frame);gesture.update(gesture,frame)}if(gesture.state=="stop"){delete gestureMap[gesture.id]}}};controller.on("gesture",function(gesture,frame){if(gesture.type==type){if(gesture.state=="start"||gesture.state=="stop"){if(gestureMap[gesture.id]===undefined){var gestureTracker=new Gesture(gesture,frame);gestureMap[gesture.id]=gestureTracker;_.each(handlers,function(cb,name){gestureTracker.on(name,cb)})}}gestureMap[gesture.id].update(gesture,frame);if(gesture.state=="stop"){delete gestureMap[gesture.id]}}});var builder={start:function(cb){handlers["start"]=cb;return builder},stop:function(cb){handlers["stop"]=cb;return builder},complete:function(cb){handlers["stop"]=cb;return builder},update:function(cb){handlers["update"]=cb;return builder}};return builder};var Gesture=exports.Gesture=function(gesture,frame){this.gestures=[gesture];this.frames=[frame]};Gesture.prototype.update=function(gesture,frame){this.gestures.push(gesture);this.frames.push(frame);this.emit(gesture.state,this)};_.extend(Gesture.prototype,EventEmitter.prototype);var CircleGesture=function(data){this.center=data.center;this.normal=data.normal;this.progress=data.progress;this.radius=data.radius};CircleGesture.prototype.toString=function(){return"CircleGesture ["+JSON.stringify(this)+"]"};var SwipeGesture=function(data){this.startPosition=data.startPosition;this.position=data.position;this.direction=data.direction;this.speed=data.speed};SwipeGesture.prototype.toString=function(){return"SwipeGesture ["+JSON.stringify(this)+"]"};var ScreenTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};ScreenTapGesture.prototype.toString=function(){return"ScreenTapGesture ["+JSON.stringify(this)+"]"};var KeyTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};KeyTapGesture.prototype.toString=function(){return"KeyTapGesture ["+JSON.stringify(this)+"]"}},{events:17,"gl-matrix":19,underscore:20}],7:[function(require,module,exports){var Pointable=require("./pointable"),glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,_=require("underscore");var Hand=module.exports=function(data){this.id=data.id;this.palmPosition=data.palmPosition;this.direction=data.direction;this.palmVelocity=data.palmVelocity;this.palmNormal=data.palmNormal;this.sphereCenter=data.sphereCenter;this.sphereRadius=data.sphereRadius;this.valid=true;this.pointables=[];this.fingers=[];this.tools=[];this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.timeVisible=data.timeVisible;this.stabilizedPalmPosition=data.stabilizedPalmPosition};Hand.prototype.finger=function(id){var finger=this.frame.finger(id);return finger&&finger.handId==this.id?finger:Pointable.Invalid};Hand.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Hand.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceHand._rotation[5],this._rotation[2]-sinceHand._rotation[6],this._rotation[3]-sinceHand._rotation[1]])};Hand.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);var m=mat3.multiply(mat3.create(),sinceHand._rotation,transpose);return m};Hand.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 1;return Math.exp(this._scaleFactor-sinceHand._scaleFactor)};Hand.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return[this._translation[0]-sinceHand._translation[0],this._translation[1]-sinceHand._translation[1],this._translation[2]-sinceHand._translation[2]]};Hand.prototype.toString=function(){return"Hand [ id: "+this.id+" | palm velocity:"+this.palmVelocity+" | sphere center:"+this.sphereCenter+" ] "};Hand.Invalid={valid:false,fingers:[],tools:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./pointable":11,"gl-matrix":19,underscore:20}],8:[function(require,module,exports){!function(){module.exports={Controller:require("./controller"),Frame:require("./frame"),Gesture:require("./gesture"),Hand:require("./hand"),Pointable:require("./pointable"),InteractionBox:require("./interaction_box"),Connection:require("./connection"),CircularBuffer:require("./circular_buffer"),UI:require("./ui"),glMatrix:require("gl-matrix"),mat3:require("gl-matrix").mat3,vec3:require("gl-matrix").vec3,loopController:undefined,loop:function(opts,callback){if(callback===undefined){callback=opts;opts={}}if(!this.loopController)this.loopController=new this.Controller(opts);this.loopController.loop(callback)}}}()},{"./circular_buffer":2,"./connection":3,"./controller":4,"./frame":5,"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"./ui":13,"gl-matrix":19}],9:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var InteractionBox=module.exports=function(data){this.valid=true;this.center=data.center;this.size=data.size;this.width=data.size[0];this.height=data.size[1];this.depth=data.size[2]};InteractionBox.prototype.denormalizePoint=function(normalizedPosition){return vec3.fromValues((normalizedPosition[0]-.5)*this.size[0]+this.center[0],(normalizedPosition[1]-.5)*this.size[1]+this.center[1],(normalizedPosition[2]-.5)*this.size[2]+this.center[2])};InteractionBox.prototype.normalizePoint=function(position,clamp){var vec=vec3.fromValues((position[0]-this.center[0])/this.size[0]+.5,(position[1]-this.center[1])/this.size[1]+.5,(position[2]-this.center[2])/this.size[2]+.5);if(clamp){vec[0]=Math.min(Math.max(vec[0],0),1);vec[1]=Math.min(Math.max(vec[1],0),1);vec[2]=Math.min(Math.max(vec[2],0),1)}return vec};InteractionBox.prototype.toString=function(){return"InteractionBox [ width:"+this.width+" | height:"+this.height+" | depth:"+this.depth+" ]"};InteractionBox.Invalid={valid:false}},{"gl-matrix":19}],10:[function(require,module,exports){var Pipeline=module.exports=function(){this.steps=[]};Pipeline.prototype.addStep=function(step){this.steps.push(step)};Pipeline.prototype.run=function(frame){var stepsLength=this.steps.length;for(var i=0;i!=stepsLength;i++){if(!frame)break;frame=this.steps[i](frame)}return frame}},{}],11:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var Pointable=module.exports=function(data){this.valid=true;this.id=data.id;this.handId=data.handId;this.length=data.length;this.tool=data.tool;this.width=data.width;this.direction=data.direction;this.stabilizedTipPosition=data.stabilizedTipPosition;this.tipPosition=data.tipPosition;this.tipVelocity=data.tipVelocity;this.touchZone=data.touchZone;this.touchDistance=data.touchDistance;this.timeVisible=data.timeVisible};Pointable.prototype.toString=function(){if(this.tool==true){return"Pointable [ id:"+this.id+" "+this.length+"mmx | with:"+this.width+"mm | direction:"+this.direction+" ]"}else{return"Pointable [ id:"+this.id+" "+this.length+"mmx | direction: "+this.direction+" ]"}};Pointable.Invalid={valid:false}},{"gl-matrix":19}],12:[function(require,module,exports){var Frame=require("./frame");var Event=function(data){this.type=data.type;this.state=data.state};var chooseProtocol=exports.chooseProtocol=function(header){var protocol;switch(header.version){case 1:protocol=JSONProtocol(1,function(data){return new Frame(data)});break;case 2:protocol=JSONProtocol(2,function(data){return new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;case 3:protocol=JSONProtocol(3,function(data){return data.event?new Event(data.event):new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;default:throw"unrecognized version"}return protocol};var JSONProtocol=function(version,cb){var protocol=cb;protocol.encode=function(message){return JSON.stringify(message)};protocol.version=version;protocol.versionLong="Version "+version;protocol.type="protocol";return protocol}},{"./frame":5}],13:[function(require,module,exports){exports.UI={Region:require("./ui/region"),Cursor:require("./ui/cursor")}},{"./ui/cursor":14,"./ui/region":15}],14:[function(require,module,exports){var Cursor=module.exports=function(){return function(frame){var pointable=frame.pointables.sort(function(a,b){return a.z-b.z})[0];if(pointable&&pointable.valid){frame.cursorPosition=pointable.tipPosition}return frame}}},{}],15:[function(require,module,exports){var EventEmitter=require("events").EventEmitter,_=require("underscore");var Region=module.exports=function(start,end){this.start=new Vector(start);this.end=new Vector(end);this.enteredFrame=null};Region.prototype.hasPointables=function(frame){for(var i=0;i!=frame.pointables.length;i++){var position=frame.pointables[i].tipPosition;if(position.x>=this.start.x&&position.x<=this.end.x&&position.y>=this.start.y&&position.y<=this.end.y&&position.z>=this.start.z&&position.z<=this.end.z){return true}}return false};Region.prototype.listener=function(opts){var region=this;if(opts&&opts.nearThreshold)this.setupNearRegion(opts.nearThreshold);return function(frame){return region.updatePosition(frame)}};Region.prototype.clipper=function(){var region=this;return function(frame){region.updatePosition(frame);return region.enteredFrame?frame:null}};Region.prototype.setupNearRegion=function(distance){var nearRegion=this.nearRegion=new Region([this.start.x-distance,this.start.y-distance,this.start.z-distance],[this.end.x+distance,this.end.y+distance,this.end.z+distance]);var region=this;nearRegion.on("enter",function(frame){region.emit("near",frame)});nearRegion.on("exit",function(frame){region.emit("far",frame)});region.on("exit",function(frame){region.emit("near",frame)})};Region.prototype.updatePosition=function(frame){if(this.nearRegion)this.nearRegion.updatePosition(frame);if(this.hasPointables(frame)&&this.enteredFrame==null){this.enteredFrame=frame;this.emit("enter",this.enteredFrame)}else if(!this.hasPointables(frame)&&this.enteredFrame!=null){this.enteredFrame=null;this.emit("exit",this.enteredFrame)}return frame};Region.prototype.normalize=function(position){return new Vector([(position.x-this.start.x)/(this.end.x-this.start.x),(position.y-this.start.y)/(this.end.y-this.start.y),(position.z-this.start.z)/(this.end.z-this.start.z)])};Region.prototype.mapToXY=function(position,width,height){var normalized=this.normalize(position);var x=normalized.x,y=normalized.y;if(x>1)x=1;else if(x<-1)x=-1;if(y>1)y=1;else if(y<-1)y=-1;return[(x+1)/2*width,(1-y)/2*height,normalized.z]};_.extend(Region.prototype,EventEmitter.prototype)},{events:17,underscore:20}],16:[function(require,module,exports){},{}],17:[function(require,module,exports){!function(process){if(!process.EventEmitter)process.EventEmitter=function(){};var EventEmitter=exports.EventEmitter=process.EventEmitter;var isArray=typeof Array.isArray==="function"?Array.isArray:function(xs){return Object.prototype.toString.call(xs)==="[object Array]"};function indexOf(xs,x){if(xs.indexOf)return xs.indexOf(x);for(var i=0;i<xs.length;i++){if(x===xs[i])return i}return-1}var defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!this._events)this._events={};this._events.maxListeners=n};EventEmitter.prototype.emit=function(type){if(type==="error"){if(!this._events||!this._events.error||isArray(this._events.error)&&!this._events.error.length){if(arguments[1]instanceof Error){throw arguments[1]}else{throw new Error("Uncaught, unspecified 'error' event.")}return false}}if(!this._events)return false;var handler=this._events[type];if(!handler)return false;if(typeof handler=="function"){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:var args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}return true}else if(isArray(handler)){var args=Array.prototype.slice.call(arguments,1);var listeners=handler.slice();for(var i=0,l=listeners.length;i<l;i++){listeners[i].apply(this,args)}return true}else{return false}};EventEmitter.prototype.addListener=function(type,listener){if("function"!==typeof listener){throw new Error("addListener only takes instances of Function")}if(!this._events)this._events={};this.emit("newListener",type,listener);if(!this._events[type]){this._events[type]=listener}else if(isArray(this._events[type])){if(!this._events[type].warned){var m;if(this._events.maxListeners!==undefined){m=this._events.maxListeners}else{m=defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);console.trace()}}this._events[type].push(listener)}else{this._events[type]=[this._events[type],listener]}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){var self=this;self.on(type,function g(){self.removeListener(type,g);listener.apply(this,arguments)});return this};EventEmitter.prototype.removeListener=function(type,listener){if("function"!==typeof listener){throw new Error("removeListener only takes instances of Function")}if(!this._events||!this._events[type])return this;var list=this._events[type];if(isArray(list)){var i=indexOf(list,listener);if(i<0)return this;list.splice(i,1);if(list.length==0)delete this._events[type]}else if(this._events[type]===listener){delete this._events[type]}return this};EventEmitter.prototype.removeAllListeners=function(type){if(arguments.length===0){this._events={};return this}if(type&&this._events&&this._events[type])this._events[type]=null;return this};EventEmitter.prototype.listeners=function(type){if(!this._events)this._events={};if(!this._events[type])this._events[type]=[];if(!isArray(this._events[type])){this._events[type]=[this._events[type]]}return this._events[type]}}(require("__browserify_process"))},{__browserify_process:18}],18:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){if(ev.source===window&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}],19:[function(require,module,exports){!function(){!function(){"use strict";var shim={};if(typeof exports==="undefined"){if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){shim.exports={};define(function(){return shim.exports})}else{shim.exports=window}}else{shim.exports=exports}!function(exports){var vec2={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec2.create=function(){return new Float32Array(2)};vec2.clone=function(a){var out=new Float32Array(2);out[0]=a[0];out[1]=a[1];return out};vec2.fromValues=function(x,y){var out=new Float32Array(2);out[0]=x;out[1]=y;return out};vec2.copy=function(out,a){out[0]=a[0];out[1]=a[1];return out};vec2.set=function(out,x,y){out[0]=x;out[1]=y;return out};vec2.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];return out};vec2.sub=vec2.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];return out};vec2.mul=vec2.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];return out};vec2.div=vec2.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];return out};vec2.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);
+out[1]=Math.min(a[1],b[1]);return out};vec2.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);return out};vec2.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;return out};vec2.dist=vec2.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return Math.sqrt(x*x+y*y)};vec2.sqrDist=vec2.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return x*x+y*y};vec2.len=vec2.length=function(a){var x=a[0],y=a[1];return Math.sqrt(x*x+y*y)};vec2.sqrLen=vec2.squaredLength=function(a){var x=a[0],y=a[1];return x*x+y*y};vec2.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];return out};vec2.normalize=function(out,a){var x=a[0],y=a[1];var len=x*x+y*y;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len}return out};vec2.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]};vec2.cross=function(out,a,b){var z=a[0]*b[1]-a[1]*b[0];out[0]=out[1]=0;out[2]=z;return out};vec2.lerp=function(out,a,b,t){var ax=a[0],ay=a[1];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);return out};vec2.transformMat2=function(out,a,m){var x=a[0],y=a[1];out[0]=x*m[0]+y*m[1];out[1]=x*m[2]+y*m[3];return out};vec2.forEach=function(){var vec=new Float32Array(2);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=2}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1]}return a}}();vec2.str=function(a){return"vec2("+a[0]+", "+a[1]+")"};if(typeof exports!=="undefined"){exports.vec2=vec2}var vec3={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec3.create=function(){return new Float32Array(3)};vec3.clone=function(a){var out=new Float32Array(3);out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.fromValues=function(x,y,z){var out=new Float32Array(3);out[0]=x;out[1]=y;out[2]=z;return out};vec3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.set=function(out,x,y,z){out[0]=x;out[1]=y;out[2]=z;return out};vec3.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];return out};vec3.sub=vec3.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];return out};vec3.mul=vec3.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];return out};vec3.div=vec3.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];return out};vec3.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);return out};vec3.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);return out};vec3.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;return out};vec3.dist=vec3.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrDist=vec3.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return x*x+y*y+z*z};vec3.len=vec3.length=function(a){var x=a[0],y=a[1],z=a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrLen=vec3.squaredLength=function(a){var x=a[0],y=a[1],z=a[2];return x*x+y*y+z*z};vec3.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];return out};vec3.normalize=function(out,a){var x=a[0],y=a[1],z=a[2];var len=x*x+y*y+z*z;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len}return out};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};vec3.cross=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2];out[0]=ay*bz-az*by;out[1]=az*bx-ax*bz;out[2]=ax*by-ay*bx;return out};vec3.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);return out};vec3.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12];out[1]=m[1]*x+m[5]*y+m[9]*z+m[13];out[2]=m[2]*x+m[6]*y+m[10]*z+m[14];return out};vec3.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec3.forEach=function(){var vec=new Float32Array(3);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=3}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2]}return a}}();vec3.str=function(a){return"vec3("+a[0]+", "+a[1]+", "+a[2]+")"};if(typeof exports!=="undefined"){exports.vec3=vec3}var vec4={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec4.create=function(){return new Float32Array(4)};vec4.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.fromValues=function(x,y,z,w){var out=new Float32Array(4);out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.set=function(out,x,y,z,w){out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];out[3]=a[3]+b[3];return out};vec4.sub=vec4.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];out[3]=a[3]-b[3];return out};vec4.mul=vec4.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];out[3]=a[3]*b[3];return out};vec4.div=vec4.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];out[3]=a[3]/b[3];return out};vec4.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);out[3]=Math.min(a[3],b[3]);return out};vec4.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);out[3]=Math.max(a[3],b[3]);return out};vec4.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;out[3]=a[3]*b;return out};vec4.dist=vec4.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrDist=vec4.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return x*x+y*y+z*z+w*w};vec4.len=vec4.length=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrLen=vec4.squaredLength=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return x*x+y*y+z*z+w*w};vec4.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=-a[3];return out};vec4.normalize=function(out,a){var x=a[0],y=a[1],z=a[2],w=a[3];var len=x*x+y*y+z*z+w*w;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len;out[3]=a[3]*len}return out};vec4.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]};vec4.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);out[3]=aw+t*(b[3]-aw);return out};vec4.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2],w=a[3];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12]*w;out[1]=m[1]*x+m[5]*y+m[9]*z+m[13]*w;out[2]=m[2]*x+m[6]*y+m[10]*z+m[14]*w;out[3]=m[3]*x+m[7]*y+m[11]*z+m[15]*w;return out};vec4.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec4.forEach=function(){var vec=new Float32Array(4);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=4}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];vec[3]=a[i+3];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2];a[i+3]=vec[3]}return a}}();vec4.str=function(a){return"vec4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.vec4=vec4}var mat2={};var mat2Identity=new Float32Array([1,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat2.create=function(){return new Float32Array(mat2Identity)};mat2.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=1;return out};mat2.transpose=function(out,a){if(out===a){var a1=a[1];out[1]=a[2];out[2]=a1}else{out[0]=a[0];out[1]=a[2];out[2]=a[1];out[3]=a[3]}return out};mat2.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],det=a0*a3-a2*a1;if(!det){return null}det=1/det;out[0]=a3*det;out[1]=-a1*det;out[2]=-a2*det;out[3]=a0*det;return out};mat2.adjoint=function(out,a){var a0=a[0];out[0]=a[3];out[1]=-a[1];out[2]=-a[2];out[3]=a0;return out};mat2.determinant=function(a){return a[0]*a[3]-a[2]*a[1]};mat2.mul=mat2.multiply=function(out,a,b){var a0=a[0],a1=a[1],a2=a[2],a3=a[3];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=a0*b0+a1*b2;out[1]=a0*b1+a1*b3;out[2]=a2*b0+a3*b2;out[3]=a2*b1+a3*b3;return out};mat2.rotate=function(out,a,rad){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],s=Math.sin(rad),c=Math.cos(rad);out[0]=a0*c+a1*s;out[1]=a0*-s+a1*c;out[2]=a2*c+a3*s;out[3]=a2*-s+a3*c;return out};mat2.scale=function(out,a,v){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],v0=v[0],v1=v[1];out[0]=a0*v0;out[1]=a1*v1;out[2]=a2*v0;out[3]=a3*v1;return out};mat2.str=function(a){return"mat2("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.mat2=mat2}var mat3={};var mat3Identity=new Float32Array([1,0,0,0,1,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat3.create=function(){return new Float32Array(mat3Identity)};mat3.clone=function(a){var out=new Float32Array(9);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=1;out[5]=0;out[6]=0;out[7]=0;out[8]=1;return out};mat3.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a12=a[5];out[1]=a[3];out[2]=a[6];out[3]=a01;out[5]=a[7];out[6]=a02;out[7]=a12}else{out[0]=a[0];out[1]=a[3];out[2]=a[6];out[3]=a[1];out[4]=a[4];out[5]=a[7];out[6]=a[2];out[7]=a[5];out[8]=a[8]}return out};mat3.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b01=a22*a11-a12*a21,b11=-a22*a10+a12*a20,b21=a21*a10-a11*a20,det=a00*b01+a01*b11+a02*b21;if(!det){return null}det=1/det;out[0]=b01*det;out[1]=(-a22*a01+a02*a21)*det;out[2]=(a12*a01-a02*a11)*det;out[3]=b11*det;out[4]=(a22*a00-a02*a20)*det;out[5]=(-a12*a00+a02*a10)*det;out[6]=b21*det;out[7]=(-a21*a00+a01*a20)*det;out[8]=(a11*a00-a01*a10)*det;return out};mat3.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];out[0]=a11*a22-a12*a21;out[1]=a02*a21-a01*a22;out[2]=a01*a12-a02*a11;out[3]=a12*a20-a10*a22;out[4]=a00*a22-a02*a20;out[5]=a02*a10-a00*a12;out[6]=a10*a21-a11*a20;out[7]=a01*a20-a00*a21;out[8]=a00*a11-a01*a10;return out};mat3.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];return a00*(a22*a11-a12*a21)+a01*(-a22*a10+a12*a20)+a02*(a21*a10-a11*a20)};mat3.mul=mat3.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b00=b[0],b01=b[1],b02=b[2],b10=b[3],b11=b[4],b12=b[5],b20=b[6],b21=b[7],b22=b[8];out[0]=b00*a00+b01*a10+b02*a20;out[1]=b00*a01+b01*a11+b02*a21;out[2]=b00*a02+b01*a12+b02*a22;out[3]=b10*a00+b11*a10+b12*a20;out[4]=b10*a01+b11*a11+b12*a21;out[5]=b10*a02+b11*a12+b12*a22;out[6]=b20*a00+b21*a10+b22*a20;out[7]=b20*a01+b21*a11+b22*a21;out[8]=b20*a02+b21*a12+b22*a22;return out};mat3.str=function(a){return"mat3("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+")"};if(typeof exports!=="undefined"){exports.mat3=mat3}var mat4={};var mat4Identity=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat4.create=function(){return new Float32Array(mat4Identity)};mat4.clone=function(a){var out=new Float32Array(16);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=1;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=1;out[11]=0;out[12]=0;out[13]=0;out[14]=0;out[15]=1;return out};mat4.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a03=a[3],a12=a[6],a13=a[7],a23=a[11];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a01;out[6]=a[9];out[7]=a[13];out[8]=a02;out[9]=a12;out[11]=a[14];out[12]=a03;out[13]=a13;out[14]=a23}else{out[0]=a[0];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a[1];out[5]=a[5];out[6]=a[9];out[7]=a[13];out[8]=a[2];out[9]=a[6];out[10]=a[10];out[11]=a[14];out[12]=a[3];out[13]=a[7];out[14]=a[11];out[15]=a[15]}return out};mat4.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32,det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;if(!det){return null}det=1/det;out[0]=(a11*b11-a12*b10+a13*b09)*det;out[1]=(a02*b10-a01*b11-a03*b09)*det;out[2]=(a31*b05-a32*b04+a33*b03)*det;out[3]=(a22*b04-a21*b05-a23*b03)*det;out[4]=(a12*b08-a10*b11-a13*b07)*det;out[5]=(a00*b11-a02*b08+a03*b07)*det;out[6]=(a32*b02-a30*b05-a33*b01)*det;out[7]=(a20*b05-a22*b02+a23*b01)*det;out[8]=(a10*b10-a11*b08+a13*b06)*det;out[9]=(a01*b08-a00*b10-a03*b06)*det;out[10]=(a30*b04-a31*b02+a33*b00)*det;out[11]=(a21*b02-a20*b04-a23*b00)*det;out[12]=(a11*b07-a10*b09-a12*b06)*det;out[13]=(a00*b09-a01*b07+a02*b06)*det;out[14]=(a31*b01-a30*b03-a32*b00)*det;out[15]=(a20*b03-a21*b01+a22*b00)*det;return out};mat4.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];out[0]=a11*(a22*a33-a23*a32)-a21*(a12*a33-a13*a32)+a31*(a12*a23-a13*a22);out[1]=-(a01*(a22*a33-a23*a32)-a21*(a02*a33-a03*a32)+a31*(a02*a23-a03*a22));out[2]=a01*(a12*a33-a13*a32)-a11*(a02*a33-a03*a32)+a31*(a02*a13-a03*a12);out[3]=-(a01*(a12*a23-a13*a22)-a11*(a02*a23-a03*a22)+a21*(a02*a13-a03*a12));out[4]=-(a10*(a22*a33-a23*a32)-a20*(a12*a33-a13*a32)+a30*(a12*a23-a13*a22));out[5]=a00*(a22*a33-a23*a32)-a20*(a02*a33-a03*a32)+a30*(a02*a23-a03*a22);out[6]=-(a00*(a12*a33-a13*a32)-a10*(a02*a33-a03*a32)+a30*(a02*a13-a03*a12));out[7]=a00*(a12*a23-a13*a22)-a10*(a02*a23-a03*a22)+a20*(a02*a13-a03*a12);out[8]=a10*(a21*a33-a23*a31)-a20*(a11*a33-a13*a31)+a30*(a11*a23-a13*a21);out[9]=-(a00*(a21*a33-a23*a31)-a20*(a01*a33-a03*a31)+a30*(a01*a23-a03*a21));out[10]=a00*(a11*a33-a13*a31)-a10*(a01*a33-a03*a31)+a30*(a01*a13-a03*a11);out[11]=-(a00*(a11*a23-a13*a21)-a10*(a01*a23-a03*a21)+a20*(a01*a13-a03*a11));out[12]=-(a10*(a21*a32-a22*a31)-a20*(a11*a32-a12*a31)+a30*(a11*a22-a12*a21));out[13]=a00*(a21*a32-a22*a31)-a20*(a01*a32-a02*a31)+a30*(a01*a22-a02*a21);out[14]=-(a00*(a11*a32-a12*a31)-a10*(a01*a32-a02*a31)+a30*(a01*a12-a02*a11));out[15]=a00*(a11*a22-a12*a21)-a10*(a01*a22-a02*a21)+a20*(a01*a12-a02*a11);return out};mat4.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32;return b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06};mat4.mul=mat4.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=b0*a00+b1*a10+b2*a20+b3*a30;out[1]=b0*a01+b1*a11+b2*a21+b3*a31;out[2]=b0*a02+b1*a12+b2*a22+b3*a32;out[3]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[4];b1=b[5];b2=b[6];b3=b[7];out[4]=b0*a00+b1*a10+b2*a20+b3*a30;out[5]=b0*a01+b1*a11+b2*a21+b3*a31;out[6]=b0*a02+b1*a12+b2*a22+b3*a32;out[7]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[8];b1=b[9];b2=b[10];b3=b[11];out[8]=b0*a00+b1*a10+b2*a20+b3*a30;out[9]=b0*a01+b1*a11+b2*a21+b3*a31;out[10]=b0*a02+b1*a12+b2*a22+b3*a32;out[11]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[12];b1=b[13];b2=b[14];b3=b[15];out[12]=b0*a00+b1*a10+b2*a20+b3*a30;out[13]=b0*a01+b1*a11+b2*a21+b3*a31;out[14]=b0*a02+b1*a12+b2*a22+b3*a32;out[15]=b0*a03+b1*a13+b2*a23+b3*a33;return out};mat4.translate=function(out,a,v){var x=v[0],y=v[1],z=v[2],a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23;if(a===out){out[12]=a[0]*x+a[4]*y+a[8]*z+a[12];out[13]=a[1]*x+a[5]*y+a[9]*z+a[13];out[14]=a[2]*x+a[6]*y+a[10]*z+a[14];out[15]=a[3]*x+a[7]*y+a[11]*z+a[15]}else{a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];out[0]=a00;out[1]=a01;out[2]=a02;out[3]=a03;out[4]=a10;out[5]=a11;out[6]=a12;out[7]=a13;out[8]=a20;out[9]=a21;out[10]=a22;out[11]=a23;out[12]=a00*x+a10*y+a20*z+a[12];out[13]=a01*x+a11*y+a21*z+a[13];out[14]=a02*x+a12*y+a22*z+a[14];out[15]=a03*x+a13*y+a23*z+a[15]}return out};mat4.scale=function(out,a,v){var x=v[0],y=v[1],z=v[2];out[0]=a[0]*x;out[1]=a[1]*x;out[2]=a[2]*x;out[3]=a[3]*x;out[4]=a[4]*y;out[5]=a[5]*y;out[6]=a[6]*y;out[7]=a[7]*y;out[8]=a[8]*z;out[9]=a[9]*z;out[10]=a[10]*z;out[11]=a[11]*z;out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.rotate=function(out,a,rad,axis){var x=axis[0],y=axis[1],z=axis[2],len=Math.sqrt(x*x+y*y+z*z),s,c,t,a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23,b00,b01,b02,b10,b11,b12,b20,b21,b22;if(Math.abs(len)<GLMAT_EPSILON){return null}len=1/len;x*=len;y*=len;z*=len;s=Math.sin(rad);c=Math.cos(rad);t=1-c;a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];b00=x*x*t+c;b01=y*x*t+z*s;b02=z*x*t-y*s;b10=x*y*t-z*s;b11=y*y*t+c;b12=z*y*t+x*s;b20=x*z*t+y*s;b21=y*z*t-x*s;b22=z*z*t+c;out[0]=a00*b00+a10*b01+a20*b02;out[1]=a01*b00+a11*b01+a21*b02;out[2]=a02*b00+a12*b01+a22*b02;out[3]=a03*b00+a13*b01+a23*b02;out[4]=a00*b10+a10*b11+a20*b12;out[5]=a01*b10+a11*b11+a21*b12;out[6]=a02*b10+a12*b11+a22*b12;out[7]=a03*b10+a13*b11+a23*b12;out[8]=a00*b20+a10*b21+a20*b22;out[9]=a01*b20+a11*b21+a21*b22;out[10]=a02*b20+a12*b21+a22*b22;out[11]=a03*b20+a13*b21+a23*b22;if(a!==out){out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}return out};mat4.rotateX=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[4]=a10*c+a20*s;out[5]=a11*c+a21*s;out[6]=a12*c+a22*s;out[7]=a13*c+a23*s;out[8]=a20*c-a10*s;out[9]=a21*c-a11*s;out[10]=a22*c-a12*s;out[11]=a23*c-a13*s;return out};mat4.rotateY=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c-a20*s;out[1]=a01*c-a21*s;out[2]=a02*c-a22*s;out[3]=a03*c-a23*s;out[8]=a00*s+a20*c;out[9]=a01*s+a21*c;out[10]=a02*s+a22*c;out[11]=a03*s+a23*c;return out};mat4.rotateZ=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7];if(a!==out){out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c+a10*s;out[1]=a01*c+a11*s;out[2]=a02*c+a12*s;out[3]=a03*c+a13*s;out[4]=a10*c-a00*s;out[5]=a11*c-a01*s;out[6]=a12*c-a02*s;out[7]=a13*c-a03*s;return out};mat4.fromRotationTranslation=function(out,q,v){var x=q[0],y=q[1],z=q[2],w=q[3],x2=x+x,y2=y+y,z2=z+z,xx=x*x2,xy=x*y2,xz=x*z2,yy=y*y2,yz=y*z2,zz=z*z2,wx=w*x2,wy=w*y2,wz=w*z2;out[0]=1-(yy+zz);out[1]=xy+wz;out[2]=xz-wy;out[3]=0;out[4]=xy-wz;out[5]=1-(xx+zz);out[6]=yz+wx;out[7]=0;out[8]=xz+wy;out[9]=yz-wx;out[10]=1-(xx+yy);out[11]=0;out[12]=v[0];out[13]=v[1];out[14]=v[2];out[15]=1;return out};mat4.frustum=function(out,left,right,bottom,top,near,far){var rl=1/(right-left),tb=1/(top-bottom),nf=1/(near-far);out[0]=near*2*rl;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=near*2*tb;out[6]=0;out[7]=0;out[8]=(right+left)*rl;out[9]=(top+bottom)*tb;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=far*near*2*nf;out[15]=0;return out};mat4.perspective=function(out,fovy,aspect,near,far){var f=1/Math.tan(fovy/2),nf=1/(near-far);out[0]=f/aspect;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=f;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=2*far*near*nf;out[15]=0;return out};mat4.ortho=function(out,left,right,bottom,top,near,far){var lr=1/(left-right),bt=1/(bottom-top),nf=1/(near-far);out[0]=-2*lr;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=-2*bt;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=2*nf;out[11]=0;out[12]=(left+right)*lr;out[13]=(top+bottom)*bt;out[14]=(far+near)*nf;out[15]=1;return out};mat4.lookAt=function(out,eye,center,up){var x0,x1,x2,y0,y1,y2,z0,z1,z2,len,eyex=eye[0],eyey=eye[1],eyez=eye[2],upx=up[0],upy=up[1],upz=up[2],centerx=center[0],centery=center[1],centerz=center[2];if(Math.abs(eyex-centerx)<GLMAT_EPSILON&&Math.abs(eyey-centery)<GLMAT_EPSILON&&Math.abs(eyez-centerz)<GLMAT_EPSILON){return mat4.identity(out)}z0=eyex-centerx;z1=eyey-centery;z2=eyez-centerz;len=1/Math.sqrt(z0*z0+z1*z1+z2*z2);z0*=len;z1*=len;z2*=len;x0=upy*z2-upz*z1;x1=upz*z0-upx*z2;x2=upx*z1-upy*z0;len=Math.sqrt(x0*x0+x1*x1+x2*x2);if(!len){x0=0;x1=0;x2=0}else{len=1/len;x0*=len;x1*=len;x2*=len}y0=z1*x2-z2*x1;y1=z2*x0-z0*x2;y2=z0*x1-z1*x0;len=Math.sqrt(y0*y0+y1*y1+y2*y2);if(!len){y0=0;y1=0;y2=0}else{len=1/len;y0*=len;y1*=len;y2*=len}out[0]=x0;out[1]=y0;out[2]=z0;out[3]=0;out[4]=x1;out[5]=y1;out[6]=z1;out[7]=0;out[8]=x2;out[9]=y2;out[10]=z2;out[11]=0;out[12]=-(x0*eyex+x1*eyey+x2*eyez);out[13]=-(y0*eyex+y1*eyey+y2*eyez);out[14]=-(z0*eyex+z1*eyey+z2*eyez);out[15]=1;return out};mat4.str=function(a){return"mat4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+")"};if(typeof exports!=="undefined"){exports.mat4=mat4}var quat={};var quatIdentity=new Float32Array([0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}quat.create=function(){return new Float32Array(quatIdentity)};quat.clone=vec4.clone;quat.fromValues=vec4.fromValues;quat.copy=vec4.copy;quat.set=vec4.set;quat.identity=function(out){out[0]=0;out[1]=0;out[2]=0;out[3]=1;return out};quat.setAxisAngle=function(out,axis,rad){rad=rad*.5;var s=Math.sin(rad);out[0]=s*axis[0];out[1]=s*axis[1];out[2]=s*axis[2];out[3]=Math.cos(rad);return out};quat.add=vec4.add;quat.mul=quat.multiply=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=b[3];out[0]=ax*bw+aw*bx+ay*bz-az*by;out[1]=ay*bw+aw*by+az*bx-ax*bz;out[2]=az*bw+aw*bz+ax*by-ay*bx;out[3]=aw*bw-ax*bx-ay*by-az*bz;return out};quat.scale=vec4.scale;quat.rotateX=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+aw*bx;out[1]=ay*bw+az*bx;out[2]=az*bw-ay*bx;out[3]=aw*bw-ax*bx;return out};quat.rotateY=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],by=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw-az*by;out[1]=ay*bw+aw*by;out[2]=az*bw+ax*by;out[3]=aw*bw-ay*by;return out};quat.rotateZ=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bz=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+ay*bz;out[1]=ay*bw-ax*bz;out[2]=az*bw+aw*bz;out[3]=aw*bw-az*bz;return out};quat.calculateW=function(out,a){var x=a[0],y=a[1],z=a[2];out[0]=x;out[1]=y;out[2]=z;out[3]=-Math.sqrt(Math.abs(1-x*x-y*y-z*z));return out};quat.dot=vec4.dot;quat.lerp=vec4.lerp;quat.slerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=a[3];var cosHalfTheta=ax*bx+ay*by+az*bz+aw*bw,halfTheta,sinHalfTheta,ratioA,ratioB;if(Math.abs(cosHalfTheta)>=1){if(out!==a){out[0]=ax;out[1]=ay;out[2]=az;out[3]=aw}return out}halfTheta=Math.acos(cosHalfTheta);sinHalfTheta=Math.sqrt(1-cosHalfTheta*cosHalfTheta);if(Math.abs(sinHalfTheta)<.001){out[0]=ax*.5+bx*.5;out[1]=ay*.5+by*.5;out[2]=az*.5+bz*.5;out[3]=aw*.5+bw*.5;return out}ratioA=Math.sin((1-t)*halfTheta)/sinHalfTheta;ratioB=Math.sin(t*halfTheta)/sinHalfTheta;out[0]=ax*ratioA+bx*ratioB;out[1]=ay*ratioA+by*ratioB;out[2]=az*ratioA+bz*ratioB;out[3]=aw*ratioA+bw*ratioB;return out};quat.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],dot=a0*a0+a1*a1+a2*a2+a3*a3,invDot=dot?1/dot:0;out[0]=-a0*invDot;out[1]=-a1*invDot;out[2]=-a2*invDot;out[3]=a3*invDot;return out};quat.conjugate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=a[3];return out};quat.len=quat.length=vec4.length;quat.sqrLen=quat.squaredLength=vec4.squaredLength;quat.normalize=vec4.normalize;quat.str=function(a){return"quat("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.quat=quat}}(shim.exports)}()}()},{}],20:[function(require,module,exports){!function(){!function(){var root=this;var previousUnderscore=root._;var breaker={};var ArrayProto=Array.prototype,ObjProto=Object.prototype,FuncProto=Function.prototype;var push=ArrayProto.push,slice=ArrayProto.slice,concat=ArrayProto.concat,toString=ObjProto.toString,hasOwnProperty=ObjProto.hasOwnProperty;var nativeForEach=ArrayProto.forEach,nativeMap=ArrayProto.map,nativeReduce=ArrayProto.reduce,nativeReduceRight=ArrayProto.reduceRight,nativeFilter=ArrayProto.filter,nativeEvery=ArrayProto.every,nativeSome=ArrayProto.some,nativeIndexOf=ArrayProto.indexOf,nativeLastIndexOf=ArrayProto.lastIndexOf,nativeIsArray=Array.isArray,nativeKeys=Object.keys,nativeBind=FuncProto.bind;var _=function(obj){if(obj instanceof _)return obj;if(!(this instanceof _))return new _(obj);this._wrapped=obj};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=_}exports._=_}else{root._=_}_.VERSION="1.4.4";var each=_.each=_.forEach=function(obj,iterator,context){if(obj==null)return;if(nativeForEach&&obj.forEach===nativeForEach){obj.forEach(iterator,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){if(iterator.call(context,obj[i],i,obj)===breaker)return}}else{for(var key in obj){if(_.has(obj,key)){if(iterator.call(context,obj[key],key,obj)===breaker)return}}}};_.map=_.collect=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeMap&&obj.map===nativeMap)return obj.map(iterator,context);each(obj,function(value,index,list){results[results.length]=iterator.call(context,value,index,list)});return results};var reduceError="Reduce of empty array with no initial value";_.reduce=_.foldl=_.inject=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduce&&obj.reduce===nativeReduce){if(context)iterator=_.bind(iterator,context);return initial?obj.reduce(iterator,memo):obj.reduce(iterator)}each(obj,function(value,index,list){if(!initial){memo=value;initial=true}else{memo=iterator.call(context,memo,value,index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.reduceRight=_.foldr=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduceRight&&obj.reduceRight===nativeReduceRight){if(context)iterator=_.bind(iterator,context);return initial?obj.reduceRight(iterator,memo):obj.reduceRight(iterator)}var length=obj.length;if(length!==+length){var keys=_.keys(obj);length=keys.length}each(obj,function(value,index,list){index=keys?keys[--length]:--length;if(!initial){memo=obj[index];initial=true}else{memo=iterator.call(context,memo,obj[index],index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.find=_.detect=function(obj,iterator,context){var result;any(obj,function(value,index,list){if(iterator.call(context,value,index,list)){result=value;return true}});return result};_.filter=_.select=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeFilter&&obj.filter===nativeFilter)return obj.filter(iterator,context);each(obj,function(value,index,list){if(iterator.call(context,value,index,list))results[results.length]=value});return results};_.reject=function(obj,iterator,context){return _.filter(obj,function(value,index,list){return!iterator.call(context,value,index,list)},context)};_.every=_.all=function(obj,iterator,context){iterator||(iterator=_.identity);var result=true;if(obj==null)return result;if(nativeEvery&&obj.every===nativeEvery)return obj.every(iterator,context);each(obj,function(value,index,list){if(!(result=result&&iterator.call(context,value,index,list)))return breaker});return!!result};var any=_.some=_.any=function(obj,iterator,context){iterator||(iterator=_.identity);var result=false;if(obj==null)return result;if(nativeSome&&obj.some===nativeSome)return obj.some(iterator,context);each(obj,function(value,index,list){if(result||(result=iterator.call(context,value,index,list)))return breaker});return!!result};_.contains=_.include=function(obj,target){if(obj==null)return false;if(nativeIndexOf&&obj.indexOf===nativeIndexOf)return obj.indexOf(target)!=-1;return any(obj,function(value){return value===target})};_.invoke=function(obj,method){var args=slice.call(arguments,2);var isFunc=_.isFunction(method);return _.map(obj,function(value){return(isFunc?method:value[method]).apply(value,args)})};_.pluck=function(obj,key){return _.map(obj,function(value){return value[key]})};_.where=function(obj,attrs,first){if(_.isEmpty(attrs))return first?null:[];return _[first?"find":"filter"](obj,function(value){for(var key in attrs){if(attrs[key]!==value[key])return false}return true})};_.findWhere=function(obj,attrs){return _.where(obj,attrs,true)};_.max=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.max.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return-Infinity;var result={computed:-Infinity,value:-Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed>=result.computed&&(result={value:value,computed:computed})});return result.value};_.min=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.min.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return Infinity;var result={computed:Infinity,value:Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed<result.computed&&(result={value:value,computed:computed})});return result.value};_.shuffle=function(obj){var rand;var index=0;var shuffled=[];each(obj,function(value){rand=_.random(index++);shuffled[index-1]=shuffled[rand];shuffled[rand]=value});return shuffled};var lookupIterator=function(value){return _.isFunction(value)?value:function(obj){return obj[value]}};_.sortBy=function(obj,value,context){var iterator=lookupIterator(value);return _.pluck(_.map(obj,function(value,index,list){return{value:value,index:index,criteria:iterator.call(context,value,index,list)}}).sort(function(left,right){var a=left.criteria;
+var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)return-1}return left.index<right.index?-1:1}),"value")};var group=function(obj,value,context,behavior){var result={};var iterator=lookupIterator(value||_.identity);each(obj,function(value,index){var key=iterator.call(context,value,index,obj);behavior(result,key,value)});return result};_.groupBy=function(obj,value,context){return group(obj,value,context,function(result,key,value){(_.has(result,key)?result[key]:result[key]=[]).push(value)})};_.countBy=function(obj,value,context){return group(obj,value,context,function(result,key){if(!_.has(result,key))result[key]=0;result[key]++})};_.sortedIndex=function(array,obj,iterator,context){iterator=iterator==null?_.identity:lookupIterator(iterator);var value=iterator.call(context,obj);var low=0,high=array.length;while(low<high){var mid=low+high>>>1;iterator.call(context,array[mid])<value?low=mid+1:high=mid}return low};_.toArray=function(obj){if(!obj)return[];if(_.isArray(obj))return slice.call(obj);if(obj.length===+obj.length)return _.map(obj,_.identity);return _.values(obj)};_.size=function(obj){if(obj==null)return 0;return obj.length===+obj.length?obj.length:_.keys(obj).length};_.first=_.head=_.take=function(array,n,guard){if(array==null)return void 0;return n!=null&&!guard?slice.call(array,0,n):array[0]};_.initial=function(array,n,guard){return slice.call(array,0,array.length-(n==null||guard?1:n))};_.last=function(array,n,guard){if(array==null)return void 0;if(n!=null&&!guard){return slice.call(array,Math.max(array.length-n,0))}else{return array[array.length-1]}};_.rest=_.tail=_.drop=function(array,n,guard){return slice.call(array,n==null||guard?1:n)};_.compact=function(array){return _.filter(array,_.identity)};var flatten=function(input,shallow,output){each(input,function(value){if(_.isArray(value)){shallow?push.apply(output,value):flatten(value,shallow,output)}else{output.push(value)}});return output};_.flatten=function(array,shallow){return flatten(array,shallow,[])};_.without=function(array){return _.difference(array,slice.call(arguments,1))};_.uniq=_.unique=function(array,isSorted,iterator,context){if(_.isFunction(isSorted)){context=iterator;iterator=isSorted;isSorted=false}var initial=iterator?_.map(array,iterator,context):array;var results=[];var seen=[];each(initial,function(value,index){if(isSorted?!index||seen[seen.length-1]!==value:!_.contains(seen,value)){seen.push(value);results.push(array[index])}});return results};_.union=function(){return _.uniq(concat.apply(ArrayProto,arguments))};_.intersection=function(array){var rest=slice.call(arguments,1);return _.filter(_.uniq(array),function(item){return _.every(rest,function(other){return _.indexOf(other,item)>=0})})};_.difference=function(array){var rest=concat.apply(ArrayProto,slice.call(arguments,1));return _.filter(array,function(value){return!_.contains(rest,value)})};_.zip=function(){var args=slice.call(arguments);var length=_.max(_.pluck(args,"length"));var results=new Array(length);for(var i=0;i<length;i++){results[i]=_.pluck(args,""+i)}return results};_.object=function(list,values){if(list==null)return{};var result={};for(var i=0,l=list.length;i<l;i++){if(values){result[list[i]]=values[i]}else{result[list[i][0]]=list[i][1]}}return result};_.indexOf=function(array,item,isSorted){if(array==null)return-1;var i=0,l=array.length;if(isSorted){if(typeof isSorted=="number"){i=isSorted<0?Math.max(0,l+isSorted):isSorted}else{i=_.sortedIndex(array,item);return array[i]===item?i:-1}}if(nativeIndexOf&&array.indexOf===nativeIndexOf)return array.indexOf(item,isSorted);for(;i<l;i++)if(array[i]===item)return i;return-1};_.lastIndexOf=function(array,item,from){if(array==null)return-1;var hasIndex=from!=null;if(nativeLastIndexOf&&array.lastIndexOf===nativeLastIndexOf){return hasIndex?array.lastIndexOf(item,from):array.lastIndexOf(item)}var i=hasIndex?from:array.length;while(i--)if(array[i]===item)return i;return-1};_.range=function(start,stop,step){if(arguments.length<=1){stop=start||0;start=0}step=arguments[2]||1;var len=Math.max(Math.ceil((stop-start)/step),0);var idx=0;var range=new Array(len);while(idx<len){range[idx++]=start;start+=step}return range};_.bind=function(func,context){if(func.bind===nativeBind&&nativeBind)return nativeBind.apply(func,slice.call(arguments,1));var args=slice.call(arguments,2);return function(){return func.apply(context,args.concat(slice.call(arguments)))}};_.partial=function(func){var args=slice.call(arguments,1);return function(){return func.apply(this,args.concat(slice.call(arguments)))}};_.bindAll=function(obj){var funcs=slice.call(arguments,1);if(funcs.length===0)funcs=_.functions(obj);each(funcs,function(f){obj[f]=_.bind(obj[f],obj)});return obj};_.memoize=function(func,hasher){var memo={};hasher||(hasher=_.identity);return function(){var key=hasher.apply(this,arguments);return _.has(memo,key)?memo[key]:memo[key]=func.apply(this,arguments)}};_.delay=function(func,wait){var args=slice.call(arguments,2);return setTimeout(function(){return func.apply(null,args)},wait)};_.defer=function(func){return _.delay.apply(_,[func,1].concat(slice.call(arguments,1)))};_.throttle=function(func,wait){var context,args,timeout,result;var previous=0;var later=function(){previous=new Date;timeout=null;result=func.apply(context,args)};return function(){var now=new Date;var remaining=wait-(now-previous);context=this;args=arguments;if(remaining<=0){clearTimeout(timeout);timeout=null;previous=now;result=func.apply(context,args)}else if(!timeout){timeout=setTimeout(later,remaining)}return result}};_.debounce=function(func,wait,immediate){var timeout,result;return function(){var context=this,args=arguments;var later=function(){timeout=null;if(!immediate)result=func.apply(context,args)};var callNow=immediate&&!timeout;clearTimeout(timeout);timeout=setTimeout(later,wait);if(callNow)result=func.apply(context,args);return result}};_.once=function(func){var ran=false,memo;return function(){if(ran)return memo;ran=true;memo=func.apply(this,arguments);func=null;return memo}};_.wrap=function(func,wrapper){return function(){var args=[func];push.apply(args,arguments);return wrapper.apply(this,args)}};_.compose=function(){var funcs=arguments;return function(){var args=arguments;for(var i=funcs.length-1;i>=0;i--){args=[funcs[i].apply(this,args)]}return args[0]}};_.after=function(times,func){if(times<=0)return func();return function(){if(--times<1){return func.apply(this,arguments)}}};_.keys=nativeKeys||function(obj){if(obj!==Object(obj))throw new TypeError("Invalid object");var keys=[];for(var key in obj)if(_.has(obj,key))keys[keys.length]=key;return keys};_.values=function(obj){var values=[];for(var key in obj)if(_.has(obj,key))values.push(obj[key]);return values};_.pairs=function(obj){var pairs=[];for(var key in obj)if(_.has(obj,key))pairs.push([key,obj[key]]);return pairs};_.invert=function(obj){var result={};for(var key in obj)if(_.has(obj,key))result[obj[key]]=key;return result};_.functions=_.methods=function(obj){var names=[];for(var key in obj){if(_.isFunction(obj[key]))names.push(key)}return names.sort()};_.extend=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){obj[prop]=source[prop]}}});return obj};_.pick=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));each(keys,function(key){if(key in obj)copy[key]=obj[key]});return copy};_.omit=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));for(var key in obj){if(!_.contains(keys,key))copy[key]=obj[key]}return copy};_.defaults=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){if(obj[prop]==null)obj[prop]=source[prop]}}});return obj};_.clone=function(obj){if(!_.isObject(obj))return obj;return _.isArray(obj)?obj.slice():_.extend({},obj)};_.tap=function(obj,interceptor){interceptor(obj);return obj};var eq=function(a,b,aStack,bStack){if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;if(a instanceof _)a=a._wrapped;if(b instanceof _)b=b._wrapped;var className=toString.call(a);if(className!=toString.call(b))return false;switch(className){case"[object String]":return a==String(b);case"[object Number]":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case"[object Date]":case"[object Boolean]":return+a==+b;case"[object RegExp]":return a.source==b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return false;var length=aStack.length;while(length--){if(aStack[length]==a)return bStack[length]==b}aStack.push(a);bStack.push(b);var size=0,result=true;if(className=="[object Array]"){size=a.length;result=size==b.length;if(result){while(size--){if(!(result=eq(a[size],b[size],aStack,bStack)))break}}}else{var aCtor=a.constructor,bCtor=b.constructor;if(aCtor!==bCtor&&!(_.isFunction(aCtor)&&aCtor instanceof aCtor&&_.isFunction(bCtor)&&bCtor instanceof bCtor)){return false}for(var key in a){if(_.has(a,key)){size++;if(!(result=_.has(b,key)&&eq(a[key],b[key],aStack,bStack)))break}}if(result){for(key in b){if(_.has(b,key)&&!size--)break}result=!size}}aStack.pop();bStack.pop();return result};_.isEqual=function(a,b){return eq(a,b,[],[])};_.isEmpty=function(obj){if(obj==null)return true;if(_.isArray(obj)||_.isString(obj))return obj.length===0;for(var key in obj)if(_.has(obj,key))return false;return true};_.isElement=function(obj){return!!(obj&&obj.nodeType===1)};_.isArray=nativeIsArray||function(obj){return toString.call(obj)=="[object Array]"};_.isObject=function(obj){return obj===Object(obj)};each(["Arguments","Function","String","Number","Date","RegExp"],function(name){_["is"+name]=function(obj){return toString.call(obj)=="[object "+name+"]"}});if(!_.isArguments(arguments)){_.isArguments=function(obj){return!!(obj&&_.has(obj,"callee"))}}if(typeof/./!=="function"){_.isFunction=function(obj){return typeof obj==="function"}}_.isFinite=function(obj){return isFinite(obj)&&!isNaN(parseFloat(obj))};_.isNaN=function(obj){return _.isNumber(obj)&&obj!=+obj};_.isBoolean=function(obj){return obj===true||obj===false||toString.call(obj)=="[object Boolean]"};_.isNull=function(obj){return obj===null};_.isUndefined=function(obj){return obj===void 0};_.has=function(obj,key){return hasOwnProperty.call(obj,key)};_.noConflict=function(){root._=previousUnderscore;return this};_.identity=function(value){return value};_.times=function(n,iterator,context){var accum=Array(n);for(var i=0;i<n;i++)accum[i]=iterator.call(context,i);return accum};_.random=function(min,max){if(max==null){max=min;min=0}return min+Math.floor(Math.random()*(max-min+1))};var entityMap={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};entityMap.unescape=_.invert(entityMap.escape);var entityRegexes={escape:new RegExp("["+_.keys(entityMap.escape).join("")+"]","g"),unescape:new RegExp("("+_.keys(entityMap.unescape).join("|")+")","g")};_.each(["escape","unescape"],function(method){_[method]=function(string){if(string==null)return"";return(""+string).replace(entityRegexes[method],function(match){return entityMap[method][match]})}});_.result=function(object,property){if(object==null)return null;var value=object[property];return _.isFunction(value)?value.call(object):value};_.mixin=function(obj){each(_.functions(obj),function(name){var func=_[name]=obj[name];_.prototype[name]=function(){var args=[this._wrapped];push.apply(args,arguments);return result.call(this,func.apply(_,args))}})};var idCounter=0;_.uniqueId=function(prefix){var id=++idCounter+"";return prefix?prefix+id:id};_.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var noMatch=/(.)^/;var escapes={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"};var escaper=/\\|'|\r|\n|\t|\u2028|\u2029/g;_.template=function(text,data,settings){var render;settings=_.defaults({},settings,_.templateSettings);var matcher=new RegExp([(settings.escape||noMatch).source,(settings.interpolate||noMatch).source,(settings.evaluate||noMatch).source].join("|")+"|$","g");var index=0;var source="__p+='";text.replace(matcher,function(match,escape,interpolate,evaluate,offset){source+=text.slice(index,offset).replace(escaper,function(match){return"\\"+escapes[match]});if(escape){source+="'+\n((__t=("+escape+"))==null?'':_.escape(__t))+\n'"}if(interpolate){source+="'+\n((__t=("+interpolate+"))==null?'':__t)+\n'"}if(evaluate){source+="';\n"+evaluate+"\n__p+='"}index=offset+match.length;return match});source+="';\n";if(!settings.variable)source="with(obj||{}){\n"+source+"}\n";source="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+source+"return __p;\n";try{render=new Function(settings.variable||"obj","_",source)}catch(e){e.source=source;throw e}if(data)return render(data,_);var template=function(data){return render.call(this,data,_)};template.source="function("+(settings.variable||"obj")+"){\n"+source+"}";return template};_.chain=function(obj){return _(obj).chain()};var result=function(obj){return this._chain?_(obj).chain():obj};_.mixin(_);each(["pop","push","reverse","shift","sort","splice","unshift"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){var obj=this._wrapped;method.apply(obj,arguments);if((name=="shift"||name=="splice")&&obj.length===0)delete obj[0];return result.call(this,obj)}});each(["concat","join","slice"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){return result.call(this,method.apply(this._wrapped,arguments))}});_.extend(_.prototype,{chain:function(){this._chain=true;return this},value:function(){return this._wrapped}})}.call(this)}()},{}],21:[function(require,module,exports){window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){window.setTimeout(callback,1e3/60)}}();Leap=require("../lib/index")},{"../lib/index":8}]},{},[21]);
+
+/*
+ * Leap Motion integration for Reveal.js.
+ * James Sun  [sun16]
+ * Rory Hardy [gneatgeek]
+ */
+
+(function () {
+  var body        = document.body,
+      controller  = new Leap.Controller({ enableGestures: true }),
+      lastGesture = 0,
+      leapConfig  = Reveal.getConfig().leap,
+      pointer     = document.createElement( 'div' ),
+      config      = {
+        autoCenter       : true,      // Center pointer around detected position.
+        gestureDelay     : 500,       // How long to delay between gestures.
+        naturalSwipe     : true,      // Swipe as if it were a touch screen.
+        pointerColor     : '#00aaff', // Default color of the pointer.
+        pointerOpacity   : 0.7,       // Default opacity of the pointer.
+        pointerSize      : 15,        // Default minimum height/width of the pointer.
+        pointerTolerance : 120        // Bigger = slower pointer.
+      },
+      entered, enteredPosition, now, size, tipPosition; // Other vars we need later, but don't need to redeclare.
+
+      // Merge user defined settings with defaults
+      if( leapConfig ) {
+        for( key in leapConfig ) {
+          config[key] = leapConfig[key];
+        }
+      }
+
+      pointer.id = 'leap';
+
+      pointer.style.position        = 'absolute';
+      pointer.style.visibility      = 'hidden';
+      pointer.style.zIndex          = 50;
+      pointer.style.opacity         = config.pointerOpacity;
+      pointer.style.backgroundColor = config.pointerColor;
+
+      body.appendChild( pointer );
+
+  // Leap's loop
+  controller.on( 'frame', function ( frame ) {
+    // Timing code to rate limit gesture execution
+    now = new Date().getTime();
+
+    // Pointer: 1 to 2 fingers. Strictly one finger works but may cause innaccuracies.
+    // The innaccuracies were observed on a development model and may not be an issue with consumer models.
+    if( frame.fingers.length > 0 && frame.fingers.length < 3 ) {
+      // Invert direction and multiply by 3 for greater effect.
+      size = -3 * frame.fingers[0].tipPosition[2];
+
+      if( size < config.pointerSize ) {
+        size = config.pointerSize;
+      }
+
+      pointer.style.width        = size     + 'px';
+      pointer.style.height       = size     + 'px';
+      pointer.style.borderRadius = size - 5 + 'px';
+      pointer.style.visibility   = 'visible';
+
+      if( config.autoCenter ) {
+        tipPosition = frame.fingers[0].tipPosition;
+
+        // Check whether the finger has entered the z range of the Leap Motion. Used for the autoCenter option.
+        if( !entered ) {
+          entered         = true;
+          enteredPosition = frame.fingers[0].tipPosition;
+        }
+
+        pointer.style.top =
+          (-1 * (( tipPosition[1] - enteredPosition[1] ) * body.offsetHeight / config.pointerTolerance )) +
+            ( body.offsetHeight / 2 ) + 'px';
+
+        pointer.style.left =
+          (( tipPosition[0] - enteredPosition[0] ) * body.offsetWidth / config.pointerTolerance ) +
+            ( body.offsetWidth / 2 ) + 'px';
+      }
+      else {
+        pointer.style.top  = ( 1 - (( tipPosition[1] - 50) / config.pointerTolerance )) *
+          body.offsetHeight + 'px';
+
+        pointer.style.left = ( tipPosition[0] * body.offsetWidth / config.pointerTolerance ) +
+          ( body.offsetWidth / 2 ) + 'px';
+      }
+    }
+    else {
+      // Hide pointer on exit
+      entered                  = false;
+      pointer.style.visibility = 'hidden';
+    }
+
+    // Gestures
+    if( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) {
+      var gesture = frame.gestures[0];
+
+      // One hand gestures
+      if( frame.hands.length === 1 ) {
+        // Swipe gestures. 3+ fingers.
+        if( frame.fingers.length > 2 && gesture.type === 'swipe' ) {
+          // Define here since some gestures will throw undefined for these.
+          var x = gesture.direction[0],
+              y = gesture.direction[1];
+
+          // Left/right swipe gestures
+          if( Math.abs( x ) > Math.abs( y )) {
+            if( x > 0 ) {
+              config.naturalSwipe ? Reveal.left() : Reveal.right();
+            }
+            else {
+              config.naturalSwipe ? Reveal.right() : Reveal.left();
+            }
+          }
+          // Up/down swipe gestures
+          else {
+            if( y > 0 ) {
+              config.naturalSwipe ? Reveal.down() : Reveal.up();
+            }
+            else {
+              config.naturalSwipe ? Reveal.up() : Reveal.down();
+            }
+          }
+
+          lastGesture = now;
+        }
+      }
+      // Two hand gestures
+      else if( frame.hands.length === 2 ) {
+        // Upward two hand swipe gesture
+        if( gesture.direction[1] > 0 && gesture.type === 'swipe' ) {
+          Reveal.toggleOverview();
+        }
+
+        lastGesture = now;
+      }
+    }
+  });
+
+  controller.connect();
+})();
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/markdown/markdown.js b/docs/slides/ETH14/_support/reveal.js/plugin/markdown/markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/markdown/markdown.js
@@ -0,0 +1,392 @@
+/**
+ * The reveal.js markdown plugin. Handles parsing of
+ * markdown inside of presentations as well as loading
+ * of external markdown documents.
+ */
+(function( root, factory ) {
+	if( typeof exports === 'object' ) {
+		module.exports = factory( require( './marked' ) );
+	}
+	else {
+		// Browser globals (root is window)
+		root.RevealMarkdown = factory( root.marked );
+		root.RevealMarkdown.initialize();
+	}
+}( this, function( marked ) {
+
+	if( typeof marked === 'undefined' ) {
+		throw 'The reveal.js Markdown plugin requires marked to be loaded';
+	}
+
+	if( typeof hljs !== 'undefined' ) {
+		marked.setOptions({
+			highlight: function( lang, code ) {
+				return hljs.highlightAuto( lang, code ).value;
+			}
+		});
+	}
+
+	var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$',
+		DEFAULT_NOTES_SEPARATOR = 'note:',
+		DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
+		DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
+
+
+	/**
+	 * Retrieves the markdown contents of a slide section
+	 * element. Normalizes leading tabs/whitespace.
+	 */
+	function getMarkdownFromSlide( section ) {
+
+		var template = section.querySelector( 'script' );
+
+		// strip leading whitespace so it isn't evaluated as code
+		var text = ( template || section ).textContent;
+
+		var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
+			leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
+
+		if( leadingTabs > 0 ) {
+			text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+		}
+		else if( leadingWs > 1 ) {
+			text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+		}
+
+		return text;
+
+	}
+
+	/**
+	 * Given a markdown slide section element, this will
+	 * return all arguments that aren't related to markdown
+	 * parsing. Used to forward any other user-defined arguments
+	 * to the output markdown slide.
+	 */
+	function getForwardedAttributes( section ) {
+
+		var attributes = section.attributes;
+		var result = [];
+
+		for( var i = 0, len = attributes.length; i < len; i++ ) {
+			var name = attributes[i].name,
+				value = attributes[i].value;
+
+			// disregard attributes that are used for markdown loading/parsing
+			if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
+
+			if( value ) {
+				result.push( name + '=' + value );
+			}
+			else {
+				result.push( name );
+			}
+		}
+
+		return result.join( ' ' );
+
+	}
+
+	/**
+	 * Inspects the given options and fills out default
+	 * values for what's not defined.
+	 */
+	function getSlidifyOptions( options ) {
+
+		options = options || {};
+		options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
+		options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
+		options.attributes = options.attributes || '';
+
+		return options;
+
+	}
+
+	/**
+	 * Helper function for constructing a markdown slide.
+	 */
+	function createMarkdownSlide( content, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
+
+		if( notesMatch.length === 2 ) {
+			content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
+		}
+
+		return '<script type="text/template">' + content + '</script>';
+
+	}
+
+	/**
+	 * Parses a data string into multiple slides based
+	 * on the passed in separator arguments.
+	 */
+	function slidify( markdown, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
+			horizontalSeparatorRegex = new RegExp( options.separator );
+
+		var matches,
+			lastIndex = 0,
+			isHorizontal,
+			wasHorizontal = true,
+			content,
+			sectionStack = [];
+
+		// iterate until all blocks between separators are stacked up
+		while( matches = separatorRegex.exec( markdown ) ) {
+			notes = null;
+
+			// determine direction (horizontal by default)
+			isHorizontal = horizontalSeparatorRegex.test( matches[0] );
+
+			if( !isHorizontal && wasHorizontal ) {
+				// create vertical stack
+				sectionStack.push( [] );
+			}
+
+			// pluck slide content from markdown input
+			content = markdown.substring( lastIndex, matches.index );
+
+			if( isHorizontal && wasHorizontal ) {
+				// add to horizontal stack
+				sectionStack.push( content );
+			}
+			else {
+				// add to vertical stack
+				sectionStack[sectionStack.length-1].push( content );
+			}
+
+			lastIndex = separatorRegex.lastIndex;
+			wasHorizontal = isHorizontal;
+		}
+
+		// add the remaining slide
+		( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
+
+		var markdownSections = '';
+
+		// flatten the hierarchical stack, and insert <section data-markdown> tags
+		for( var i = 0, len = sectionStack.length; i < len; i++ ) {
+			// vertical
+			if( sectionStack[i] instanceof Array ) {
+				markdownSections += '<section '+ options.attributes +'>';
+
+				sectionStack[i].forEach( function( child ) {
+					markdownSections += '<section data-markdown>' +  createMarkdownSlide( child, options ) + '</section>';
+				} );
+
+				markdownSections += '</section>';
+			}
+			else {
+				markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
+			}
+		}
+
+		return markdownSections;
+
+	}
+
+	/**
+	 * Parses any current data-markdown slides, splits
+	 * multi-slide markdown into separate sections and
+	 * handles loading of external markdown.
+	 */
+	function processSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]'),
+			section;
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			section = sections[i];
+
+			if( section.getAttribute( 'data-markdown' ).length ) {
+
+				var xhr = new XMLHttpRequest(),
+					url = section.getAttribute( 'data-markdown' );
+
+				datacharset = section.getAttribute( 'data-charset' );
+
+				// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
+				if( datacharset != null && datacharset != '' ) {
+					xhr.overrideMimeType( 'text/html; charset=' + datacharset );
+				}
+
+				xhr.onreadystatechange = function() {
+					if( xhr.readyState === 4 ) {
+						if ( xhr.status >= 200 && xhr.status < 300 ) {
+
+							section.outerHTML = slidify( xhr.responseText, {
+								separator: section.getAttribute( 'data-separator' ),
+								verticalSeparator: section.getAttribute( 'data-vertical' ),
+								notesSeparator: section.getAttribute( 'data-notes' ),
+								attributes: getForwardedAttributes( section )
+							});
+
+						}
+						else {
+
+							section.outerHTML = '<section data-state="alert">' +
+								'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
+								'Check your browser\'s JavaScript console for more details.' +
+								'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
+								'</section>';
+
+						}
+					}
+				};
+
+				xhr.open( 'GET', url, false );
+
+				try {
+					xhr.send();
+				}
+				catch ( e ) {
+					alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
+				}
+
+			}
+			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) {
+
+				section.outerHTML = slidify( getMarkdownFromSlide( section ), {
+					separator: section.getAttribute( 'data-separator' ),
+					verticalSeparator: section.getAttribute( 'data-vertical' ),
+					notesSeparator: section.getAttribute( 'data-notes' ),
+					attributes: getForwardedAttributes( section )
+				});
+
+			}
+			else {
+				section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
+			}
+		}
+
+	}
+
+	/**
+	 * Check if a node value has the attributes pattern.
+	 * If yes, extract it and add that value as one or several attributes
+	 * the the terget element.
+	 *
+	 * You need Cache Killer on Chrome to see the effect on any FOM transformation
+	 * directly on refresh (F5)
+	 * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
+	 */
+	function addAttributeInElement( node, elementTarget, separator ) {
+
+		var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
+		var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
+		var nodeValue = node.nodeValue;
+		if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
+
+			var classes = matches[1];
+			nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
+			node.nodeValue = nodeValue;
+			while( matchesClass = mardownClassRegex.exec( classes ) ) {
+				elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Add attributes to the parent element of a text node,
+	 * or the element of an attribute node.
+	 */
+	function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
+
+		if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
+			previousParentElement = element;
+			for( var i = 0; i < element.childNodes.length; i++ ) {
+				childElement = element.childNodes[i];
+				if ( i > 0 ) {
+					j = i - 1;
+					while ( j >= 0 ) {
+						aPreviousChildElement = element.childNodes[j];
+						if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
+							previousParentElement = aPreviousChildElement;
+							break;
+						}
+						j = j - 1;
+					}
+				}
+				parentSection = section;
+				if( childElement.nodeName ==  "section" ) {
+					parentSection = childElement ;
+					previousParentElement = childElement ;
+				}
+				if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
+					addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
+				}
+			}
+		}
+
+		if ( element.nodeType == Node.COMMENT_NODE ) {
+			if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
+				addAttributeInElement( element, section, separatorSectionAttributes );
+			}
+		}
+	}
+
+	/**
+	 * Converts any current data-markdown slides in the
+	 * DOM to HTML.
+	 */
+	function convertSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]');
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			var section = sections[i];
+
+			// Only parse the same slide once
+			if( !section.getAttribute( 'data-markdown-parsed' ) ) {
+
+				section.setAttribute( 'data-markdown-parsed', true )
+
+				var notes = section.querySelector( 'aside.notes' );
+				var markdown = getMarkdownFromSlide( section );
+
+				section.innerHTML = marked( markdown );
+				addAttributes( 	section, section, null, section.getAttribute( 'data-element-attributes' ) ||
+								section.parentNode.getAttribute( 'data-element-attributes' ) ||
+								DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
+								section.getAttribute( 'data-attributes' ) ||
+								section.parentNode.getAttribute( 'data-attributes' ) ||
+								DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
+
+				// If there were notes, we need to re-add them after
+				// having overwritten the section's HTML
+				if( notes ) {
+					section.appendChild( notes );
+				}
+
+			}
+
+		}
+
+	}
+
+	// API
+	return {
+
+		initialize: function() {
+			processSlides();
+			convertSlides();
+		},
+
+		// TODO: Do these belong in the API?
+		processSlides: processSlides,
+		convertSlides: convertSlides,
+		slidify: slidify
+
+	};
+
+}));
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/markdown/marked.js b/docs/slides/ETH14/_support/reveal.js/plugin/markdown/marked.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/markdown/marked.js
@@ -0,0 +1,37 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){3,} *\n*/,blockquote:/^( *>[^\n]+(\n[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr",/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";block.html=replace(block.html)("comment",/\x3c!--[\s\S]*?--\x3e/)("closed",
+/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1",
+"\\2")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm)if(this.options.tables)this.rules=block.tables;else this.rules=block.gfm}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};
+Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1)this.tokens.push({type:"space"})}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,
+"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,
+"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]="center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].split(/ *\| */);this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=
+src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);
+bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+
+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item[item.length-1]==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:cap[1]==="pre"||cap[1]==="script",text:cap[0]});continue}if(top&&
+(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]=
+"center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */);this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1][cap[1].length-1]==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",
+text:cap[0]});continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^\x3c!--[\s\S]*?--\x3e|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;
+if(!this.links)throw new Error("Tokens array requires a `links` property.");if(this.options.gfm)if(this.options.breaks)this.rules=inline.breaks;else this.rules=inline.gfm;else if(this.options.pedantic)this.rules=inline.pedantic}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);
+out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1][6]===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.url.exec(src)){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.tag.exec(src)){src=src.substring(cap[0].length);
+out+=this.options.sanitize?escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);out+=this.outputLink(cap,{href:cap[2],title:cap[3]});continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0][0];src=cap[0].substring(1)+src;continue}out+=this.outputLink(cap,link);continue}if(cap=this.rules.strong.exec(src)){src=
+src.substring(cap[0].length);out+="<strong>"+this.output(cap[2]||cap[1])+"</strong>";continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+="<em>"+this.output(cap[2]||cap[1])+"</em>";continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+="<code>"+escape(cap[2],true)+"</code>";continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+="<br>";continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+="<del>"+
+this.output(cap[1])+"</del>";continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=escape(cap[0]);continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return out};InlineLexer.prototype.outputLink=function(cap,link){if(cap[0][0]!=="!")return'<a href="'+escape(link.href)+'"'+(link.title?' title="'+escape(link.title)+'"':"")+">"+this.output(cap[1])+"</a>";else return'<img src="'+escape(link.href)+'" alt="'+escape(cap[1])+'"'+(link.title?' title="'+
+escape(link.title)+'"':"")+">"};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/--/g,"\u2014").replace(/'([^']*)'/g,"\u2018$1\u2019").replace(/"([^"]*)"/g,"\u201c$1\u201d").replace(/\.{3}/g,"\u2026")};InlineLexer.prototype.mangle=function(text){var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>0.5)ch="x"+ch.toString(16);out+="&#"+ch+";"}return out};function Parser(options){this.tokens=[];this.token=null;
+this.options=options||marked.defaults}Parser.parse=function(src,options){var parser=new Parser(options);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options);this.tokens=src.reverse();var out="";while(this.next())out+=this.tok();return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;
+while(this.peek().type==="text")body+="\n"+this.next().text;return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case "space":return"";case "hr":return"<hr>\n";case "heading":return"<h"+this.token.depth+">"+this.inline.output(this.token.text)+"</h"+this.token.depth+">\n";case "code":if(this.options.highlight){var code=this.options.highlight(this.token.text,this.token.lang);if(code!=null&&code!==this.token.text){this.token.escaped=true;this.token.text=code}}if(!this.token.escaped)this.token.text=
+escape(this.token.text,true);return"<pre><code"+(this.token.lang?' class="'+this.options.langPrefix+this.token.lang+'"':"")+">"+this.token.text+"</code></pre>\n";case "table":var body="",heading,i,row,cell,j;body+="<thead>\n<tr>\n";for(i=0;i<this.token.header.length;i++){heading=this.inline.output(this.token.header[i]);body+=this.token.align[i]?'<th align="'+this.token.align[i]+'">'+heading+"</th>\n":"<th>"+heading+"</th>\n"}body+="</tr>\n</thead>\n";body+="<tbody>\n";for(i=0;i<this.token.cells.length;i++){row=
+this.token.cells[i];body+="<tr>\n";for(j=0;j<row.length;j++){cell=this.inline.output(row[j]);body+=this.token.align[j]?'<td align="'+this.token.align[j]+'">'+cell+"</td>\n":"<td>"+cell+"</td>\n"}body+="</tr>\n"}body+="</tbody>\n";return"<table>\n"+body+"</table>\n";case "blockquote_start":var body="";while(this.next().type!=="blockquote_end")body+=this.tok();return"<blockquote>\n"+body+"</blockquote>\n";case "list_start":var type=this.token.ordered?"ol":"ul",body="";while(this.next().type!=="list_end")body+=
+this.tok();return"<"+type+">\n"+body+"</"+type+">\n";case "list_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.token.type==="text"?this.parseText():this.tok();return"<li>"+body+"</li>\n";case "loose_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.tok();return"<li>"+body+"</li>\n";case "html":return!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;case "paragraph":return"<p>"+this.inline.output(this.token.text)+
+"</p>\n";case "text":return"<p>"+this.parseText()+"</p>\n"}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=
+1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target)if(Object.prototype.hasOwnProperty.call(target,key))obj[key]=target[key]}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}if(opt)opt=merge({},marked.defaults,opt);var tokens=Lexer.lex(tokens,opt),highlight=opt.highlight,pending=0,l=tokens.length,i=0;if(!highlight||highlight.length<3)return callback(null,Parser.parse(tokens,opt));var done=function(){delete opt.highlight;
+var out=Parser.parse(tokens,opt);opt.highlight=highlight;return callback(null,out)};for(;i<l;i++)(function(token){if(token.type!=="code")return;pending++;return highlight(token.text,token.lang,function(err,code){if(code==null||code===token.text)return--pending||done();token.text=code;token.escaped=true;--pending||done()})})(tokens[i]);return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";
+if((opt||marked.defaults).silent)return"<p>An error occured:</p><pre>"+escape(e.message+"",true)+"</pre>";throw e;}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,smartLists:false,silent:false,highlight:null,langPrefix:""};marked.Parser=Parser;marked.parser=Parser.parse;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;
+marked.parse=marked;if(typeof exports==="object")module.exports=marked;else if(typeof define==="function"&&define.amd)define(function(){return marked});else this.marked=marked}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/math/math.js b/docs/slides/ETH14/_support/reveal.js/plugin/math/math.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/math/math.js
@@ -0,0 +1,64 @@
+/**
+ * A plugin which enables rendering of math equations inside
+ * of reveal.js slides. Essentially a thin wrapper for MathJax.
+ *
+ * @author Hakim El Hattab
+ */
+var RevealMath = window.RevealMath || (function(){
+
+	var options = Reveal.getConfig().math || {};
+	options.mathjax = options.mathjax || 'http://cdn.mathjax.org/mathjax/latest/MathJax.js';
+	options.config = options.config || 'TeX-AMS_HTML-full';
+
+	loadScript( options.mathjax + '?config=' + options.config, function() {
+
+		MathJax.Hub.Config({
+			messageStyle: 'none',
+			tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] },
+			skipStartupTypeset: true
+		});
+
+		// Typeset followed by an immediate reveal.js layout since
+		// the typesetting process could affect slide height
+		MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
+		MathJax.Hub.Queue( Reveal.layout );
+
+		// Reprocess equations in slides when they turn visible
+		Reveal.addEventListener( 'slidechanged', function( event ) {
+
+			MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
+
+		} );
+
+	} );
+
+	function loadScript( url, callback ) {
+
+		var head = document.querySelector( 'head' );
+		var script = document.createElement( 'script' );
+		script.type = 'text/javascript';
+		script.src = url;
+
+		// Wrapper for callback to make sure it only fires once
+		var finish = function() {
+			if( typeof callback === 'function' ) {
+				callback.call();
+				callback = null;
+			}
+		}
+
+		script.onload = finish;
+
+		// IE
+		script.onreadystatechange = function() {
+			if ( this.readyState === 'loaded' ) {
+				finish();
+			}
+		}
+
+		// Normal browsers
+		head.appendChild( script );
+
+	}
+
+})();
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/client.js b/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/client.js
@@ -0,0 +1,13 @@
+(function() {
+	var multiplex = Reveal.getConfig().multiplex;
+	var socketId = multiplex.id;
+	var socket = io.connect(multiplex.url);
+
+	socket.on(multiplex.id, function(data) {
+		// ignore data from sockets that aren't ours
+		if (data.socketId !== socketId) { return; }
+		if( window.location.host === 'localhost:1947' ) return;
+
+		Reveal.slide(data.indexh, data.indexv, data.indexf, 'remote');
+	});
+}());
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/index.js b/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/index.js
@@ -0,0 +1,56 @@
+var express		= require('express');
+var fs			= require('fs');
+var io			= require('socket.io');
+var crypto		= require('crypto');
+
+var app			= express.createServer();
+var staticDir	= express.static;
+
+io				= io.listen(app);
+
+var opts = {
+	port: 1948,
+	baseDir : __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		if (typeof slideData.secret == 'undefined' || slideData.secret == null || slideData.secret === '') return;
+		if (createHash(slideData.secret) === slideData.socketId) {
+			slideData.secret = null;
+			socket.broadcast.emit(slideData.socketId, slideData);
+		};
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/token", function(req,res) {
+	var ts = new Date().getTime();
+	var rand = Math.floor(Math.random()*9999999);
+	var secret = ts.toString() + rand.toString();
+	res.send({secret: secret, socketId: createHash(secret)});
+});
+
+var createHash = function(secret) {
+	var cipher = crypto.createCipher('blowfish', secret);
+	return(cipher.final('hex'));
+};
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset );
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/master.js b/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/master.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/multiplex/master.js
@@ -0,0 +1,51 @@
+(function() {
+	// Don't emit events from inside of notes windows
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var multiplex = Reveal.getConfig().multiplex;
+
+	var socket = io.connect(multiplex.url);
+
+	var notify = function( slideElement, indexh, indexv, origin ) {
+		if( typeof origin === 'undefined' && origin !== 'remote' ) {
+			var nextindexh;
+			var nextindexv;
+
+			var fragmentindex = Reveal.getIndices().f;
+			if (typeof fragmentindex == 'undefined') {
+				fragmentindex = 0;
+			}
+
+			if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+				nextindexh = indexh;
+				nextindexv = indexv + 1;
+			} else {
+				nextindexh = indexh + 1;
+				nextindexv = 0;
+			}
+
+			var slideData = {
+				indexh : indexh,
+				indexv : indexv,
+				indexf : fragmentindex,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				secret: multiplex.secret,
+				socketId : multiplex.id
+			};
+
+			socket.emit('slidechanged', slideData);
+		}
+	}
+
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		notify( event.currentSlide, event.indexh, event.indexv, event.origin );
+	} );
+
+	var fragmentNotify = function( event ) {
+		notify( Reveal.getCurrentSlide(), Reveal.getIndices().h, Reveal.getIndices().v, event.origin );
+	};
+
+	Reveal.addEventListener( 'fragmentshown', fragmentNotify );
+	Reveal.addEventListener( 'fragmenthidden', fragmentNotify );
+}());
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/notes-server/client.js b/docs/slides/ETH14/_support/reveal.js/plugin/notes-server/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/notes-server/client.js
@@ -0,0 +1,57 @@
+(function() {
+	// don't emit events from inside the previews themselves
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var socket = io.connect(window.location.origin);
+	var socketId = Math.random().toString().slice(2);
+	
+	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
+	window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId);
+
+	// Fires when a fragment is shown
+	Reveal.addEventListener( 'fragmentshown', function( event ) {
+		var fragmentData = {
+			fragment : 'next',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when a fragment is hidden
+	Reveal.addEventListener( 'fragmenthidden', function( event ) {
+		var fragmentData = {
+			fragment : 'previous',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when slide is changed
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		var nextindexh;
+		var nextindexv;
+		var slideElement = event.currentSlide;
+
+		if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+			nextindexh = event.indexh;
+			nextindexv = event.indexv + 1;
+		} else {
+			nextindexh = event.indexh + 1;
+			nextindexv = 0;
+		}
+
+		var notes = slideElement.querySelector('aside.notes');
+		var slideData = {
+			notes : notes ? notes.innerHTML : '',
+			indexh : event.indexh,
+			indexv : event.indexv,
+			nextindexh : nextindexh,
+			nextindexv : nextindexv,
+			socketId : socketId,
+			markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false
+
+		};
+
+		socket.emit('slidechanged', slideData);
+	} );
+}());
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/notes-server/index.js b/docs/slides/ETH14/_support/reveal.js/plugin/notes-server/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/notes-server/index.js
@@ -0,0 +1,59 @@
+var express   = require('express');
+var fs        = require('fs');
+var io        = require('socket.io');
+var _         = require('underscore');
+var Mustache  = require('mustache');
+
+var app       = express.createServer();
+var staticDir = express.static;
+
+io            = io.listen(app);
+
+var opts = {
+	port :      1947,
+	baseDir :   __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		socket.broadcast.emit('slidedata', slideData);
+	});
+	socket.on('fragmentchanged', function(fragmentData) {
+		socket.broadcast.emit('fragmentdata', fragmentData);
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/notes/:socketId", function(req, res) {
+
+	fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) {
+		res.send(Mustache.to_html(data.toString(), {
+			socketId : req.params.socketId
+		}));
+	});
+	// fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res);
+});
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
+
+console.log( brown + "reveal.js - Speaker Notes" + reset );
+console.log( "1. Open the slides at " + green + slidesLocation + reset );
+console.log( "2. Click on the link your JS console to go to the notes page" );
+console.log( "3. Advance through your slides and your notes will advance automatically" );
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/notes/notes.js b/docs/slides/ETH14/_support/reveal.js/plugin/notes/notes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/notes/notes.js
@@ -0,0 +1,78 @@
+/**
+ * Handles opening of and synchronization with the reveal.js
+ * notes window.
+ */
+var RevealNotes = (function() {
+
+	function openNotes() {
+		var jsFileLocation = document.querySelector('script[src$="notes.js"]').src;  // this js file path
+		jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, '');   // the js folder path
+		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' );
+
+		// Fires when slide is changed
+		Reveal.addEventListener( 'slidechanged', post );
+
+		// Fires when a fragment is shown
+		Reveal.addEventListener( 'fragmentshown', post );
+
+		// Fires when a fragment is hidden
+		Reveal.addEventListener( 'fragmenthidden', post );
+
+		/**
+		 * Posts the current slide data to the notes window
+		 */
+		function post() {
+			var slideElement = Reveal.getCurrentSlide(),
+				slideIndices = Reveal.getIndices(),
+				messageData;
+
+			var notes = slideElement.querySelector( 'aside.notes' ),
+				nextindexh,
+				nextindexv;
+
+			if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
+				nextindexh = slideIndices.h;
+				nextindexv = slideIndices.v + 1;
+			} else {
+				nextindexh = slideIndices.h + 1;
+				nextindexv = 0;
+			}
+
+			messageData = {
+				notes : notes ? notes.innerHTML : '',
+				indexh : slideIndices.h,
+				indexv : slideIndices.v,
+				indexf : slideIndices.f,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
+			};
+
+			notesPopup.postMessage( JSON.stringify( messageData ), '*' );
+		}
+
+		// Navigate to the current slide when the notes are loaded
+		notesPopup.addEventListener( 'load', function( event ) {
+			post();
+		}, false );
+	}
+
+	// If the there's a 'notes' query set, open directly
+	if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
+		openNotes();
+	}
+
+	// Open the notes when the 's' key is hit
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openNotes();
+		}
+	}, false );
+
+	return { open: openNotes };
+})();
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/postmessage/postmessage.js b/docs/slides/ETH14/_support/reveal.js/plugin/postmessage/postmessage.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/postmessage/postmessage.js
@@ -0,0 +1,42 @@
+/*
+
+	simple postmessage plugin
+
+	Useful when a reveal slideshow is inside an iframe.
+	It allows to call reveal methods from outside.
+
+	Example:
+		 var reveal =  window.frames[0];
+
+		 // Reveal.prev(); 
+		 reveal.postMessage(JSON.stringify({method: 'prev', args: []}), '*');
+		 // Reveal.next(); 
+		 reveal.postMessage(JSON.stringify({method: 'next', args: []}), '*');
+		 // Reveal.slide(2, 2); 
+		 reveal.postMessage(JSON.stringify({method: 'slide', args: [2,2]}), '*');
+
+	Add to the slideshow:
+
+		dependencies: [
+			...
+			{ src: 'plugin/postmessage/postmessage.js', async: true, condition: function() { return !!document.body.classList; } }
+		]
+
+*/
+
+(function (){
+
+	window.addEventListener( "message", function ( event ) {
+		var data = JSON.parse( event.data ),
+				method = data.method,
+				args = data.args;
+
+		if( typeof Reveal[method] === 'function' ) {
+			Reveal[method].apply( Reveal, data.args );
+		}
+	}, false);
+
+}());
+
+
+
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/print-pdf/print-pdf.js b/docs/slides/ETH14/_support/reveal.js/plugin/print-pdf/print-pdf.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/print-pdf/print-pdf.js
@@ -0,0 +1,44 @@
+/**
+ * phantomjs script for printing presentations to PDF.
+ *
+ * Example:
+ * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf
+ *
+ * By Manuel Bieh (https://github.com/manuelbieh)
+ */
+
+// html2pdf.js
+var page = new WebPage();
+var system = require( 'system' );
+
+page.viewportSize  = {
+	width: 1024,
+	height: 768
+};
+
+page.paperSize = {
+	format: 'letter',
+	orientation: 'landscape',
+	margin: {
+		left: '0',
+		right: '0',
+		top: '0',
+		bottom: '0'
+	}
+};
+
+var revealFile = system.args[1] || 'index.html?print-pdf';
+var slideFile = system.args[2] || 'slides.pdf';
+
+if( slideFile.match( /\.pdf$/gi ) === null ) {
+	slideFile += '.pdf';
+}
+
+console.log( 'Printing PDF...' );
+
+page.open( revealFile, function( status ) {
+	console.log( 'Printed succesfully' );
+	page.render( slideFile );
+	phantom.exit();
+} );
+
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/remotes/remotes.js b/docs/slides/ETH14/_support/reveal.js/plugin/remotes/remotes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/remotes/remotes.js
@@ -0,0 +1,39 @@
+/**
+ * Touch-based remote controller for your presentation courtesy 
+ * of the folks at http://remotes.io
+ */
+
+(function(window){
+
+    /**
+     * Detects if we are dealing with a touch enabled device (with some false positives)
+     * Borrowed from modernizr: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touch.js   
+     */
+    var hasTouch  = (function(){
+        return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
+    })();
+
+    /**
+     * Detects if notes are enable and the current page is opened inside an /iframe
+     * this prevents loading Remotes.io several times
+     */
+    var isNotesAndIframe = (function(){
+        return window.RevealNotes && !(self == top);
+    })();
+
+    if(!hasTouch && !isNotesAndIframe){
+        head.ready( 'remotes.ne.min.js', function() {
+            new Remotes("preview")
+                .on("swipe-left", function(e){ Reveal.right(); })
+                .on("swipe-right", function(e){ Reveal.left(); })
+                .on("swipe-up", function(e){ Reveal.down(); })
+                .on("swipe-down", function(e){ Reveal.up(); })
+                .on("tap", function(e){ Reveal.next(); })
+                .on("zoom-out", function(e){ Reveal.toggleOverview(true); })
+                .on("zoom-in", function(e){ Reveal.toggleOverview(false); })
+            ;
+        } );
+
+        head.js('https://hakim-static.s3.amazonaws.com/reveal-js/remotes.ne.min.js');
+    }
+})(window);
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/search/search.js b/docs/slides/ETH14/_support/reveal.js/plugin/search/search.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/search/search.js
@@ -0,0 +1,196 @@
+/*
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
+ * by navigatating to that slide and highlighting it.
+ *
+ * By Jon Snyder <snyder.jon@gmail.com>, February 2013
+ */
+
+var RevealSearch = (function() {
+
+	var matchedSlides;
+	var currentMatchedIndex;
+	var searchboxDirty;
+	var myHilitor;
+
+// Original JavaScript code by Chirp Internet: www.chirp.com.au
+// Please acknowledge use of this code by including this header.
+// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
+
+function Hilitor(id, tag)
+{
+
+  var targetNode = document.getElementById(id) || document.body;
+  var hiliteTag = tag || "EM";
+  var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
+  var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
+  var wordColor = [];
+  var colorIdx = 0;
+  var matchRegex = "";
+  var matchingSlides = [];
+
+  this.setRegex = function(input)
+  {
+    input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
+    matchRegex = new RegExp("(" + input + ")","i");
+  }
+
+  this.getRegex = function()
+  {
+    return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
+  }
+
+  // recursively apply word highlighting
+  this.hiliteWords = function(node)
+  {
+    if(node == undefined || !node) return;
+    if(!matchRegex) return;
+    if(skipTags.test(node.nodeName)) return;
+
+    if(node.hasChildNodes()) {
+      for(var i=0; i < node.childNodes.length; i++)
+        this.hiliteWords(node.childNodes[i]);
+    }
+    if(node.nodeType == 3) { // NODE_TEXT
+      if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
+      	//find the slide's section element and save it in our list of matching slides
+      	var secnode = node.parentNode;
+      	while (secnode.nodeName != 'SECTION') {
+      		secnode = secnode.parentNode;
+      	}
+      	
+      	var slideIndex = Reveal.getIndices(secnode);
+      	var slidelen = matchingSlides.length;
+      	var alreadyAdded = false;
+      	for (var i=0; i < slidelen; i++) {
+      		if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
+      			alreadyAdded = true;
+      		}
+      	}
+      	if (! alreadyAdded) {
+      		matchingSlides.push(slideIndex);
+      	}
+      	
+        if(!wordColor[regs[0].toLowerCase()]) {
+          wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
+        }
+
+        var match = document.createElement(hiliteTag);
+        match.appendChild(document.createTextNode(regs[0]));
+        match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
+        match.style.fontStyle = "inherit";
+        match.style.color = "#000";
+
+        var after = node.splitText(regs.index);
+        after.nodeValue = after.nodeValue.substring(regs[0].length);
+        node.parentNode.insertBefore(match, after);
+      }
+    }
+  };
+
+  // remove highlighting
+  this.remove = function()
+  {
+    var arr = document.getElementsByTagName(hiliteTag);
+    while(arr.length && (el = arr[0])) {
+      el.parentNode.replaceChild(el.firstChild, el);
+    }
+  };
+
+  // start highlighting at target node
+  this.apply = function(input)
+  {
+    if(input == undefined || !input) return;
+    this.remove();
+    this.setRegex(input);
+    this.hiliteWords(targetNode);
+    return matchingSlides;
+  };
+
+}
+
+	function openSearch() {
+		//ensure the search term input dialog is visible and has focus:
+		var inputbox = document.getElementById("searchinput");
+		inputbox.style.display = "inline";
+		inputbox.focus();
+		inputbox.select();
+	}
+
+	function toggleSearch() {
+		var inputbox = document.getElementById("searchinput");
+		if (inputbox.style.display !== "inline") {
+			openSearch();
+		}
+		else {
+			inputbox.style.display = "none";
+			myHilitor.remove();
+		}
+	}
+
+	function doSearch() {
+		//if there's been a change in the search term, perform a new search:
+		if (searchboxDirty) {
+			var searchstring = document.getElementById("searchinput").value;
+
+			//find the keyword amongst the slides
+			myHilitor = new Hilitor("slidecontent");
+			matchedSlides = myHilitor.apply(searchstring);
+			currentMatchedIndex = 0;
+		}
+
+		//navigate to the next slide that has the keyword, wrapping to the first if necessary
+		if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
+			currentMatchedIndex = 0;
+		}
+		if (matchedSlides.length > currentMatchedIndex) {
+			Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
+			currentMatchedIndex++;
+		}
+	}
+
+	var dom = {};
+	dom.wrapper = document.querySelector( '.reveal' );
+
+	if( !dom.wrapper.querySelector( '.searchbox' ) ) {
+			var searchElement = document.createElement( 'div' );
+			searchElement.id = "searchinputdiv";
+			searchElement.classList.add( 'searchdiv' );
+      searchElement.style.position = 'absolute';
+      searchElement.style.top = '10px';
+      searchElement.style.left = '10px';
+      //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
+			searchElement.innerHTML = '<span><input type="search" id="searchinput" class="searchinput" style="vertical-align: top;"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJiSURBVHjatFZNaxNBGH5md+Mmu92NVdKDRipSAyqCghgQD4L4cRe86UUtAQ+eFCxoa4/25EXBFi8eBE+eRPoDhB6KgiiixdAPCEkx2pjvTXadd9yNsflwuyUDD/O+u8PzzDPvzOwyx3EwyCZhwG3gAkp7MnpjgbopjsltcD4gjuXZZKeAR348MYLYTm3LzOs/y3j3JTfZxgXWXmTuwPHIc4VmoOmv5IrI53+AO2DdHLjkDWQ3GoEEVFXtXQOvkSnPWcyUceviLhwbDYv8/XIVj97kse7TodLvZXxYxrPUHkQ1ufXs3FEdybEIxucySOesoNvUgWU1cP3MkCBfTFdw9fGaAMVmRELq7LBw2Q3/FaAxxWIRpw+ZIr/7IouPqzUBiqmdHAv7EuhRAwf1er2Vy4x1jW3b2d5Jfvu5IPp7l2LYbcgCFFNb+FoJ7oBqEAqFMPNqFcmEgVMJDfMT+1tvN0pNjERlMS6QA5pFOKxiKVPFhakPeL3It+WGJUDxt2wFR+JhzI7v5ctkd8DXOZAkCYYxhO+lKm4+Xfqz/rIixBuNBl7eOYzkQQNzqX249mRl6zUgEcYkaJrGhUwBinVdh6IouPzwE6/DL5w4oLkH8y981aDf+uq6hlKpJESiUdNfDZi7/ehG9K6KfiA3pml0PLcsq+cSMTj2NL9ukc4UOmz7AZ3+crkC4mHujFvXNaMFB3bEr8xPS6p5O+jXxq4VZtaen7/PwzrntjcLUE0iHPS1Ud1cdiEJl/8WivZk0wXd7zWOMkeF8s0CcAmkNrC2nvXZDbbbN73ccYnZoH9bfgswAFzAe9/h3dbKAAAAAElFTkSuQmCC" id="searchbutton" class="searchicon" style="vertical-align: top; margin-top: -1px;"/></span>';
+			dom.wrapper.appendChild( searchElement );
+	}
+
+	document.getElementById("searchbutton").addEventListener( 'click', function(event) {
+		doSearch();
+	}, false );
+
+	document.getElementById("searchinput").addEventListener( 'keyup', function( event ) {
+		switch (event.keyCode) {
+			case 13:
+				event.preventDefault();
+				doSearch();
+				searchboxDirty = false;
+				break;
+			default:
+				searchboxDirty = true;
+		}
+	}, false );
+
+	// Open the search when the 's' key is hit (yes, this conflicts with the notes plugin, disabling for now)
+	/*
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openSearch();
+		}
+	}, false );
+*/
+	return { open: openSearch };
+})();
diff --git a/docs/slides/ETH14/_support/reveal.js/plugin/zoom-js/zoom.js b/docs/slides/ETH14/_support/reveal.js/plugin/zoom-js/zoom.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/plugin/zoom-js/zoom.js
@@ -0,0 +1,258 @@
+// Custom reveal.js integration
+(function(){
+	var isEnabled = true;
+
+	document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) {
+		var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key';
+
+		if( event[ modifier ] && isEnabled ) {
+			event.preventDefault();
+			zoom.to({ element: event.target, pan: false });
+		}
+	} );
+
+	Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
+	Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
+})();
+
+/*!
+ * zoom.js 0.2 (modified version for use with reveal.js)
+ * http://lab.hakim.se/zoom-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var zoom = (function(){
+
+	// The current zoom level (scale)
+	var level = 1;
+
+	// The current mouse position, used for panning
+	var mouseX = 0,
+		mouseY = 0;
+
+	// Timeout before pan is activated
+	var panEngageTimeout = -1,
+		panUpdateInterval = -1;
+
+	var currentOptions = null;
+
+	// Check for transform support so that we can fallback otherwise
+	var supportsTransforms = 	'WebkitTransform' in document.body.style ||
+								'MozTransform' in document.body.style ||
+								'msTransform' in document.body.style ||
+								'OTransform' in document.body.style ||
+								'transform' in document.body.style;
+
+	if( supportsTransforms ) {
+		// The easing that will be applied when we zoom in/out
+		document.body.style.transition = 'transform 0.8s ease';
+		document.body.style.OTransition = '-o-transform 0.8s ease';
+		document.body.style.msTransition = '-ms-transform 0.8s ease';
+		document.body.style.MozTransition = '-moz-transform 0.8s ease';
+		document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
+	}
+
+	// Zoom out if the user hits escape
+	document.addEventListener( 'keyup', function( event ) {
+		if( level !== 1 && event.keyCode === 27 ) {
+			zoom.out();
+		}
+	}, false );
+
+	// Monitor mouse movement for panning
+	document.addEventListener( 'mousemove', function( event ) {
+		if( level !== 1 ) {
+			mouseX = event.clientX;
+			mouseY = event.clientY;
+		}
+	}, false );
+
+	/**
+	 * Applies the CSS required to zoom in, prioritizes use of CSS3
+	 * transforms but falls back on zoom for IE.
+	 *
+	 * @param {Number} pageOffsetX
+	 * @param {Number} pageOffsetY
+	 * @param {Number} elementOffsetX
+	 * @param {Number} elementOffsetY
+	 * @param {Number} scale
+	 */
+	function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) {
+
+		if( supportsTransforms ) {
+			var origin = pageOffsetX +'px '+ pageOffsetY +'px',
+				transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')';
+
+			document.body.style.transformOrigin = origin;
+			document.body.style.OTransformOrigin = origin;
+			document.body.style.msTransformOrigin = origin;
+			document.body.style.MozTransformOrigin = origin;
+			document.body.style.WebkitTransformOrigin = origin;
+
+			document.body.style.transform = transform;
+			document.body.style.OTransform = transform;
+			document.body.style.msTransform = transform;
+			document.body.style.MozTransform = transform;
+			document.body.style.WebkitTransform = transform;
+		}
+		else {
+			// Reset all values
+			if( scale === 1 ) {
+				document.body.style.position = '';
+				document.body.style.left = '';
+				document.body.style.top = '';
+				document.body.style.width = '';
+				document.body.style.height = '';
+				document.body.style.zoom = '';
+			}
+			// Apply scale
+			else {
+				document.body.style.position = 'relative';
+				document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px';
+				document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px';
+				document.body.style.width = ( scale * 100 ) + '%';
+				document.body.style.height = ( scale * 100 ) + '%';
+				document.body.style.zoom = scale;
+			}
+		}
+
+		level = scale;
+
+		if( level !== 1 && document.documentElement.classList ) {
+			document.documentElement.classList.add( 'zoomed' );
+		}
+		else {
+			document.documentElement.classList.remove( 'zoomed' );
+		}
+	}
+
+	/**
+	 * Pan the document when the mosue cursor approaches the edges
+	 * of the window.
+	 */
+	function pan() {
+		var range = 0.12,
+			rangeX = window.innerWidth * range,
+			rangeY = window.innerHeight * range,
+			scrollOffset = getScrollOffset();
+
+		// Up
+		if( mouseY < rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
+		}
+		// Down
+		else if( mouseY > window.innerHeight - rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
+		}
+
+		// Left
+		if( mouseX < rangeX ) {
+			window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
+		}
+		// Right
+		else if( mouseX > window.innerWidth - rangeX ) {
+			window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
+		}
+	}
+
+	function getScrollOffset() {
+		return {
+			x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
+			y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset
+		}
+	}
+
+	return {
+		/**
+		 * Zooms in on either a rectangle or HTML element.
+		 *
+		 * @param {Object} options
+		 *   - element: HTML element to zoom in on
+		 *   OR
+		 *   - x/y: coordinates in non-transformed space to zoom in on
+		 *   - width/height: the portion of the screen to zoom in on
+		 *   - scale: can be used instead of width/height to explicitly set scale
+		 */
+		to: function( options ) {
+			// Due to an implementation limitation we can't zoom in
+			// to another element without zooming out first
+			if( level !== 1 ) {
+				zoom.out();
+			}
+			else {
+				options.x = options.x || 0;
+				options.y = options.y || 0;
+
+				// If an element is set, that takes precedence
+				if( !!options.element ) {
+					// Space around the zoomed in element to leave on screen
+					var padding = 20;
+
+					options.width = options.element.getBoundingClientRect().width + ( padding * 2 );
+					options.height = options.element.getBoundingClientRect().height + ( padding * 2 );
+					options.x = options.element.getBoundingClientRect().left - padding;
+					options.y = options.element.getBoundingClientRect().top - padding;
+				}
+
+				// If width/height values are set, calculate scale from those values
+				if( options.width !== undefined && options.height !== undefined ) {
+					options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
+				}
+
+				if( options.scale > 1 ) {
+					options.x *= options.scale;
+					options.y *= options.scale;
+
+					var scrollOffset = getScrollOffset();
+
+					if( options.element ) {
+						scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2;
+					}
+
+					magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale );
+
+					if( options.pan !== false ) {
+
+						// Wait with engaging panning as it may conflict with the
+						// zoom transition
+						panEngageTimeout = setTimeout( function() {
+							panUpdateInterval = setInterval( pan, 1000 / 60 );
+						}, 800 );
+
+					}
+				}
+
+				currentOptions = options;
+			}
+		},
+
+		/**
+		 * Resets the document zoom state to its default.
+		 */
+		out: function() {
+			clearTimeout( panEngageTimeout );
+			clearInterval( panUpdateInterval );
+
+			var scrollOffset = getScrollOffset();
+
+			if( currentOptions && currentOptions.element ) {
+				scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2;
+			}
+
+			magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 );
+
+			level = 1;
+		},
+
+		// Alias
+		magnify: function( options ) { this.to( options ) },
+		reset: function() { this.out() },
+
+		zoomLevel: function() {
+			return level;
+		}
+	}
+
+})();
+
diff --git a/docs/slides/ETH14/_support/reveal.js/test/examples/assets/image1.png b/docs/slides/ETH14/_support/reveal.js/test/examples/assets/image1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/_support/reveal.js/test/examples/assets/image1.png differ
diff --git a/docs/slides/ETH14/_support/reveal.js/test/examples/assets/image2.png b/docs/slides/ETH14/_support/reveal.js/test/examples/assets/image2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/_support/reveal.js/test/examples/assets/image2.png differ
diff --git a/docs/slides/ETH14/_support/reveal.js/test/qunit-1.12.0.css b/docs/slides/ETH14/_support/reveal.js/test/qunit-1.12.0.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/test/qunit-1.12.0.css
@@ -0,0 +1,244 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+	margin: 0;
+	padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+	padding: 0.5em 0 0.5em 1em;
+
+	color: #8699a4;
+	background-color: #0d3349;
+
+	font-size: 1.5em;
+	line-height: 1em;
+	font-weight: normal;
+
+	border-radius: 5px 5px 0 0;
+	-moz-border-radius: 5px 5px 0 0;
+	-webkit-border-top-right-radius: 5px;
+	-webkit-border-top-left-radius: 5px;
+}
+
+#qunit-header a {
+	text-decoration: none;
+	color: #c2ccd1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+	color: #fff;
+}
+
+#qunit-testrunner-toolbar label {
+	display: inline-block;
+	padding: 0 .5em 0 .1em;
+}
+
+#qunit-banner {
+	height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+	padding: 0.5em 0 0.5em 2em;
+	color: #5E740B;
+	background-color: #eee;
+	overflow: hidden;
+}
+
+#qunit-userAgent {
+	padding: 0.5em 0 0.5em 2.5em;
+	background-color: #2b81af;
+	color: #fff;
+	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+#qunit-modulefilter-container {
+	float: right;
+}
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+	list-style-position: inside;
+}
+
+#qunit-tests li {
+	padding: 0.4em 0.5em 0.4em 2.5em;
+	border-bottom: 1px solid #fff;
+	list-style-position: inside;
+}
+
+#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
+	display: none;
+}
+
+#qunit-tests li strong {
+	cursor: pointer;
+}
+
+#qunit-tests li a {
+	padding: 0.5em;
+	color: #c2ccd1;
+	text-decoration: none;
+}
+#qunit-tests li a:hover,
+#qunit-tests li a:focus {
+	color: #000;
+}
+
+#qunit-tests li .runtime {
+	float: right;
+	font-size: smaller;
+}
+
+.qunit-assert-list {
+	margin-top: 0.5em;
+	padding: 0.5em;
+
+	background-color: #fff;
+
+	border-radius: 5px;
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+}
+
+.qunit-collapsed {
+	display: none;
+}
+
+#qunit-tests table {
+	border-collapse: collapse;
+	margin-top: .2em;
+}
+
+#qunit-tests th {
+	text-align: right;
+	vertical-align: top;
+	padding: 0 .5em 0 0;
+}
+
+#qunit-tests td {
+	vertical-align: top;
+}
+
+#qunit-tests pre {
+	margin: 0;
+	white-space: pre-wrap;
+	word-wrap: break-word;
+}
+
+#qunit-tests del {
+	background-color: #e0f2be;
+	color: #374e0c;
+	text-decoration: none;
+}
+
+#qunit-tests ins {
+	background-color: #ffcaca;
+	color: #500;
+	text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts                       { color: black; }
+#qunit-tests b.passed                       { color: #5E740B; }
+#qunit-tests b.failed                       { color: #710909; }
+
+#qunit-tests li li {
+	padding: 5px;
+	background-color: #fff;
+	border-bottom: none;
+	list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+	color: #3c510c;
+	background-color: #fff;
+	border-left: 10px solid #C6E746;
+}
+
+#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name               { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected           { color: #999999; }
+
+#qunit-banner.qunit-pass                    { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+	color: #710909;
+	background-color: #fff;
+	border-left: 10px solid #EE5757;
+	white-space: pre;
+}
+
+#qunit-tests > li:last-child {
+	border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-webkit-border-bottom-right-radius: 5px;
+	-webkit-border-bottom-left-radius: 5px;
+}
+
+#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name             { color: #000000; }
+
+#qunit-tests .fail .test-actual             { color: #EE5757; }
+#qunit-tests .fail .test-expected           { color: green;   }
+
+#qunit-banner.qunit-fail                    { background-color: #EE5757; }
+
+
+/** Result */
+
+#qunit-testresult {
+	padding: 0.5em 0.5em 0.5em 2.5em;
+
+	color: #2b81af;
+	background-color: #D2E0E6;
+
+	border-bottom: 1px solid white;
+}
+#qunit-testresult .module-name {
+	font-weight: bold;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+	position: absolute;
+	top: -10000px;
+	left: -10000px;
+	width: 1000px;
+	height: 1000px;
+}
diff --git a/docs/slides/ETH14/_support/reveal.js/test/qunit-1.12.0.js b/docs/slides/ETH14/_support/reveal.js/test/qunit-1.12.0.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/test/qunit-1.12.0.js
@@ -0,0 +1,2212 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * https://jquery.org/license/
+ */
+
+(function( window ) {
+
+var QUnit,
+	assert,
+	config,
+	onErrorFnPrev,
+	testId = 0,
+	fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	// Keep a local reference to Date (GH-283)
+	Date = window.Date,
+	setTimeout = window.setTimeout,
+	defined = {
+		setTimeout: typeof window.setTimeout !== "undefined",
+		sessionStorage: (function() {
+			var x = "qunit-test-string";
+			try {
+				sessionStorage.setItem( x, x );
+				sessionStorage.removeItem( x );
+				return true;
+			} catch( e ) {
+				return false;
+			}
+		}())
+	},
+	/**
+	 * Provides a normalized error string, correcting an issue
+	 * with IE 7 (and prior) where Error.prototype.toString is
+	 * not properly implemented
+	 *
+	 * Based on http://es5.github.com/#x15.11.4.4
+	 *
+	 * @param {String|Error} error
+	 * @return {String} error message
+	 */
+	errorString = function( error ) {
+		var name, message,
+			errorString = error.toString();
+		if ( errorString.substring( 0, 7 ) === "[object" ) {
+			name = error.name ? error.name.toString() : "Error";
+			message = error.message ? error.message.toString() : "";
+			if ( name && message ) {
+				return name + ": " + message;
+			} else if ( name ) {
+				return name;
+			} else if ( message ) {
+				return message;
+			} else {
+				return "Error";
+			}
+		} else {
+			return errorString;
+		}
+	},
+	/**
+	 * Makes a clone of an object using only Array or Object as base,
+	 * and copies over the own enumerable properties.
+	 *
+	 * @param {Object} obj
+	 * @return {Object} New object with only the own properties (recursively).
+	 */
+	objectValues = function( obj ) {
+		// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
+		/*jshint newcap: false */
+		var key, val,
+			vals = QUnit.is( "array", obj ) ? [] : {};
+		for ( key in obj ) {
+			if ( hasOwn.call( obj, key ) ) {
+				val = obj[key];
+				vals[key] = val === Object(val) ? objectValues(val) : val;
+			}
+		}
+		return vals;
+	};
+
+function Test( settings ) {
+	extend( this, settings );
+	this.assertions = [];
+	this.testNumber = ++Test.count;
+}
+
+Test.count = 0;
+
+Test.prototype = {
+	init: function() {
+		var a, b, li,
+			tests = id( "qunit-tests" );
+
+		if ( tests ) {
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml;
+
+			// `a` initialized at top of scope
+			a = document.createElement( "a" );
+			a.innerHTML = "Rerun";
+			a.href = QUnit.url({ testNumber: this.testNumber });
+
+			li = document.createElement( "li" );
+			li.appendChild( b );
+			li.appendChild( a );
+			li.className = "running";
+			li.id = this.id = "qunit-test-output" + testId++;
+
+			tests.appendChild( li );
+		}
+	},
+	setup: function() {
+		if (
+			// Emit moduleStart when we're switching from one module to another
+			this.module !== config.previousModule ||
+				// They could be equal (both undefined) but if the previousModule property doesn't
+				// yet exist it means this is the first test in a suite that isn't wrapped in a
+				// module, in which case we'll just emit a moduleStart event for 'undefined'.
+				// Without this, reporters can get testStart before moduleStart  which is a problem.
+				!hasOwn.call( config, "previousModule" )
+		) {
+			if ( hasOwn.call( config, "previousModule" ) ) {
+				runLoggingCallbacks( "moduleDone", QUnit, {
+					name: config.previousModule,
+					failed: config.moduleStats.bad,
+					passed: config.moduleStats.all - config.moduleStats.bad,
+					total: config.moduleStats.all
+				});
+			}
+			config.previousModule = this.module;
+			config.moduleStats = { all: 0, bad: 0 };
+			runLoggingCallbacks( "moduleStart", QUnit, {
+				name: this.module
+			});
+		}
+
+		config.current = this;
+
+		this.testEnvironment = extend({
+			setup: function() {},
+			teardown: function() {}
+		}, this.moduleTestEnvironment );
+
+		this.started = +new Date();
+		runLoggingCallbacks( "testStart", QUnit, {
+			name: this.testName,
+			module: this.module
+		});
+
+		/*jshint camelcase:false */
+
+
+		/**
+		 * Expose the current test environment.
+		 *
+		 * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
+		 */
+		QUnit.current_testEnvironment = this.testEnvironment;
+
+		/*jshint camelcase:true */
+
+		if ( !config.pollution ) {
+			saveGlobal();
+		}
+		if ( config.notrycatch ) {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+			return;
+		}
+		try {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+		} catch( e ) {
+			QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+		}
+	},
+	run: function() {
+		config.current = this;
+
+		var running = id( "qunit-testresult" );
+
+		if ( running ) {
+			running.innerHTML = "Running: <br/>" + this.nameHtml;
+		}
+
+		if ( this.async ) {
+			QUnit.stop();
+		}
+
+		this.callbackStarted = +new Date();
+
+		if ( config.notrycatch ) {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+			return;
+		}
+
+		try {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+		} catch( e ) {
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+
+			QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
+			// else next test will carry the responsibility
+			saveGlobal();
+
+			// Restart the tests if they're blocking
+			if ( config.blocking ) {
+				QUnit.start();
+			}
+		}
+	},
+	teardown: function() {
+		config.current = this;
+		if ( config.notrycatch ) {
+			if ( typeof this.callbackRuntime === "undefined" ) {
+				this.callbackRuntime = +new Date() - this.callbackStarted;
+			}
+			this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			return;
+		} else {
+			try {
+				this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			} catch( e ) {
+				QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+			}
+		}
+		checkPollution();
+	},
+	finish: function() {
+		config.current = this;
+		if ( config.requireExpects && this.expected === null ) {
+			QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
+		} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
+			QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
+		} else if ( this.expected === null && !this.assertions.length ) {
+			QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
+		}
+
+		var i, assertion, a, b, time, li, ol,
+			test = this,
+			good = 0,
+			bad = 0,
+			tests = id( "qunit-tests" );
+
+		this.runtime = +new Date() - this.started;
+		config.stats.all += this.assertions.length;
+		config.moduleStats.all += this.assertions.length;
+
+		if ( tests ) {
+			ol = document.createElement( "ol" );
+			ol.className = "qunit-assert-list";
+
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				assertion = this.assertions[i];
+
+				li = document.createElement( "li" );
+				li.className = assertion.result ? "pass" : "fail";
+				li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
+				ol.appendChild( li );
+
+				if ( assertion.result ) {
+					good++;
+				} else {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+
+			// store result when possible
+			if ( QUnit.config.reorder && defined.sessionStorage ) {
+				if ( bad ) {
+					sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
+				} else {
+					sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
+				}
+			}
+
+			if ( bad === 0 ) {
+				addClass( ol, "qunit-collapsed" );
+			}
+
+			// `b` initialized at top of scope
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+
+			addEvent(b, "click", function() {
+				var next = b.parentNode.lastChild,
+					collapsed = hasClass( next, "qunit-collapsed" );
+				( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
+			});
+
+			addEvent(b, "dblclick", function( e ) {
+				var target = e && e.target ? e.target : window.event.srcElement;
+				if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
+					target = target.parentNode;
+				}
+				if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
+					window.location = QUnit.url({ testNumber: test.testNumber });
+				}
+			});
+
+			// `time` initialized at top of scope
+			time = document.createElement( "span" );
+			time.className = "runtime";
+			time.innerHTML = this.runtime + " ms";
+
+			// `li` initialized at top of scope
+			li = id( this.id );
+			li.className = bad ? "fail" : "pass";
+			li.removeChild( li.firstChild );
+			a = li.firstChild;
+			li.appendChild( b );
+			li.appendChild( a );
+			li.appendChild( time );
+			li.appendChild( ol );
+
+		} else {
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				if ( !this.assertions[i].result ) {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+		}
+
+		runLoggingCallbacks( "testDone", QUnit, {
+			name: this.testName,
+			module: this.module,
+			failed: bad,
+			passed: this.assertions.length - bad,
+			total: this.assertions.length,
+			duration: this.runtime
+		});
+
+		QUnit.reset();
+
+		config.current = undefined;
+	},
+
+	queue: function() {
+		var bad,
+			test = this;
+
+		synchronize(function() {
+			test.init();
+		});
+		function run() {
+			// each of these can by async
+			synchronize(function() {
+				test.setup();
+			});
+			synchronize(function() {
+				test.run();
+			});
+			synchronize(function() {
+				test.teardown();
+			});
+			synchronize(function() {
+				test.finish();
+			});
+		}
+
+		// `bad` initialized at top of scope
+		// defer when previous test run passed, if storage is available
+		bad = QUnit.config.reorder && defined.sessionStorage &&
+						+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
+
+		if ( bad ) {
+			run();
+		} else {
+			synchronize( run, true );
+		}
+	}
+};
+
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+QUnit = {
+
+	// call on start of module test to prepend name to all tests
+	module: function( name, testEnvironment ) {
+		config.currentModule = name;
+		config.currentModuleTestEnvironment = testEnvironment;
+		config.modules[name] = true;
+	},
+
+	asyncTest: function( testName, expected, callback ) {
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		QUnit.test( testName, expected, callback, true );
+	},
+
+	test: function( testName, expected, callback, async ) {
+		var test,
+			nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
+
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		if ( config.currentModule ) {
+			nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
+		}
+
+		test = new Test({
+			nameHtml: nameHtml,
+			testName: testName,
+			expected: expected,
+			async: async,
+			callback: callback,
+			module: config.currentModule,
+			moduleTestEnvironment: config.currentModuleTestEnvironment,
+			stack: sourceFromStacktrace( 2 )
+		});
+
+		if ( !validTest( test ) ) {
+			return;
+		}
+
+		test.queue();
+	},
+
+	// Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
+	expect: function( asserts ) {
+		if (arguments.length === 1) {
+			config.current.expected = asserts;
+		} else {
+			return config.current.expected;
+		}
+	},
+
+	start: function( count ) {
+		// QUnit hasn't been initialized yet.
+		// Note: RequireJS (et al) may delay onLoad
+		if ( config.semaphore === undefined ) {
+			QUnit.begin(function() {
+				// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+				setTimeout(function() {
+					QUnit.start( count );
+				});
+			});
+			return;
+		}
+
+		config.semaphore -= count || 1;
+		// don't start until equal number of stop-calls
+		if ( config.semaphore > 0 ) {
+			return;
+		}
+		// ignore if start is called more often then stop
+		if ( config.semaphore < 0 ) {
+			config.semaphore = 0;
+			QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
+			return;
+		}
+		// A slight delay, to avoid any current callbacks
+		if ( defined.setTimeout ) {
+			setTimeout(function() {
+				if ( config.semaphore > 0 ) {
+					return;
+				}
+				if ( config.timeout ) {
+					clearTimeout( config.timeout );
+				}
+
+				config.blocking = false;
+				process( true );
+			}, 13);
+		} else {
+			config.blocking = false;
+			process( true );
+		}
+	},
+
+	stop: function( count ) {
+		config.semaphore += count || 1;
+		config.blocking = true;
+
+		if ( config.testTimeout && defined.setTimeout ) {
+			clearTimeout( config.timeout );
+			config.timeout = setTimeout(function() {
+				QUnit.ok( false, "Test timed out" );
+				config.semaphore = 1;
+				QUnit.start();
+			}, config.testTimeout );
+		}
+	}
+};
+
+// `assert` initialized at top of scope
+// Assert helpers
+// All of these must either call QUnit.push() or manually do:
+// - runLoggingCallbacks( "log", .. );
+// - config.current.assertions.push({ .. });
+// We attach it to the QUnit object *after* we expose the public API,
+// otherwise `assert` will become a global variable in browsers (#341).
+assert = {
+	/**
+	 * Asserts rough true-ish result.
+	 * @name ok
+	 * @function
+	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+	 */
+	ok: function( result, msg ) {
+		if ( !config.current ) {
+			throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+		result = !!result;
+		msg = msg || (result ? "okay" : "failed" );
+
+		var source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: msg
+			};
+
+		msg = "<span class='test-message'>" + escapeText( msg ) + "</span>";
+
+		if ( !result ) {
+			source = sourceFromStacktrace( 2 );
+			if ( source ) {
+				details.source = source;
+				msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
+			}
+		}
+		runLoggingCallbacks( "log", QUnit, details );
+		config.current.assertions.push({
+			result: result,
+			message: msg
+		});
+	},
+
+	/**
+	 * Assert that the first two arguments are equal, with an optional message.
+	 * Prints out both actual and expected values.
+	 * @name equal
+	 * @function
+	 * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
+	 */
+	equal: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected == actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notEqual
+	 * @function
+	 */
+	notEqual: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected != actual, actual, expected, message );
+	},
+
+	/**
+	 * @name propEqual
+	 * @function
+	 */
+	propEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notPropEqual
+	 * @function
+	 */
+	notPropEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name deepEqual
+	 * @function
+	 */
+	deepEqual: function( actual, expected, message ) {
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notDeepEqual
+	 * @function
+	 */
+	notDeepEqual: function( actual, expected, message ) {
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name strictEqual
+	 * @function
+	 */
+	strictEqual: function( actual, expected, message ) {
+		QUnit.push( expected === actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notStrictEqual
+	 * @function
+	 */
+	notStrictEqual: function( actual, expected, message ) {
+		QUnit.push( expected !== actual, actual, expected, message );
+	},
+
+	"throws": function( block, expected, message ) {
+		var actual,
+			expectedOutput = expected,
+			ok = false;
+
+		// 'expected' is optional
+		if ( typeof expected === "string" ) {
+			message = expected;
+			expected = null;
+		}
+
+		config.current.ignoreGlobalErrors = true;
+		try {
+			block.call( config.current.testEnvironment );
+		} catch (e) {
+			actual = e;
+		}
+		config.current.ignoreGlobalErrors = false;
+
+		if ( actual ) {
+			// we don't want to validate thrown error
+			if ( !expected ) {
+				ok = true;
+				expectedOutput = null;
+			// expected is a regexp
+			} else if ( QUnit.objectType( expected ) === "regexp" ) {
+				ok = expected.test( errorString( actual ) );
+			// expected is a constructor
+			} else if ( actual instanceof expected ) {
+				ok = true;
+			// expected is a validation function which returns true is validation passed
+			} else if ( expected.call( {}, actual ) === true ) {
+				expectedOutput = null;
+				ok = true;
+			}
+
+			QUnit.push( ok, actual, expectedOutput, message );
+		} else {
+			QUnit.pushFailure( message, null, "No exception was thrown." );
+		}
+	}
+};
+
+/**
+ * @deprecated since 1.8.0
+ * Kept assertion helpers in root for backwards compatibility.
+ */
+extend( QUnit, assert );
+
+/**
+ * @deprecated since 1.9.0
+ * Kept root "raises()" for backwards compatibility.
+ * (Note that we don't introduce assert.raises).
+ */
+QUnit.raises = assert[ "throws" ];
+
+/**
+ * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
+ * Kept to avoid TypeErrors for undefined methods.
+ */
+QUnit.equals = function() {
+	QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
+};
+QUnit.same = function() {
+	QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
+};
+
+// We want access to the constructor's prototype
+(function() {
+	function F() {}
+	F.prototype = QUnit;
+	QUnit = new F();
+	// Make F QUnit's constructor so that we can add to the prototype later
+	QUnit.constructor = F;
+}());
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+	// The queue of tests to run
+	queue: [],
+
+	// block until document ready
+	blocking: true,
+
+	// when enabled, show only failing tests
+	// gets persisted through sessionStorage and can be changed in UI via checkbox
+	hidepassed: false,
+
+	// by default, run previously failed tests first
+	// very useful in combination with "Hide passed tests" checked
+	reorder: true,
+
+	// by default, modify document.title when suite is done
+	altertitle: true,
+
+	// when enabled, all tests must call expect()
+	requireExpects: false,
+
+	// add checkboxes that are persisted in the query-string
+	// when enabled, the id is set to `true` as a `QUnit.config` property
+	urlConfig: [
+		{
+			id: "noglobals",
+			label: "Check for Globals",
+			tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
+		},
+		{
+			id: "notrycatch",
+			label: "No try-catch",
+			tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
+		}
+	],
+
+	// Set of all modules.
+	modules: {},
+
+	// logging callback queues
+	begin: [],
+	done: [],
+	log: [],
+	testStart: [],
+	testDone: [],
+	moduleStart: [],
+	moduleDone: []
+};
+
+// Export global variables, unless an 'exports' object exists,
+// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
+if ( typeof exports === "undefined" ) {
+	extend( window, QUnit.constructor.prototype );
+
+	// Expose QUnit object
+	window.QUnit = QUnit;
+}
+
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+	var i,
+		location = window.location || { search: "", protocol: "file:" },
+		params = location.search.slice( 1 ).split( "&" ),
+		length = params.length,
+		urlParams = {},
+		current;
+
+	if ( params[ 0 ] ) {
+		for ( i = 0; i < length; i++ ) {
+			current = params[ i ].split( "=" );
+			current[ 0 ] = decodeURIComponent( current[ 0 ] );
+			// allow just a key to turn on a flag, e.g., test.html?noglobals
+			current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
+			urlParams[ current[ 0 ] ] = current[ 1 ];
+		}
+	}
+
+	QUnit.urlParams = urlParams;
+
+	// String search anywhere in moduleName+testName
+	config.filter = urlParams.filter;
+
+	// Exact match of the module name
+	config.module = urlParams.module;
+
+	config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
+
+	// Figure out if we're running the tests from a server or not
+	QUnit.isLocal = location.protocol === "file:";
+}());
+
+// Extend QUnit object,
+// these after set here because they should not be exposed as global functions
+extend( QUnit, {
+	assert: assert,
+
+	config: config,
+
+	// Initialize the configuration options
+	init: function() {
+		extend( config, {
+			stats: { all: 0, bad: 0 },
+			moduleStats: { all: 0, bad: 0 },
+			started: +new Date(),
+			updateRate: 1000,
+			blocking: false,
+			autostart: true,
+			autorun: false,
+			filter: "",
+			queue: [],
+			semaphore: 1
+		});
+
+		var tests, banner, result,
+			qunit = id( "qunit" );
+
+		if ( qunit ) {
+			qunit.innerHTML =
+				"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+				"<h2 id='qunit-banner'></h2>" +
+				"<div id='qunit-testrunner-toolbar'></div>" +
+				"<h2 id='qunit-userAgent'></h2>" +
+				"<ol id='qunit-tests'></ol>";
+		}
+
+		tests = id( "qunit-tests" );
+		banner = id( "qunit-banner" );
+		result = id( "qunit-testresult" );
+
+		if ( tests ) {
+			tests.innerHTML = "";
+		}
+
+		if ( banner ) {
+			banner.className = "";
+		}
+
+		if ( result ) {
+			result.parentNode.removeChild( result );
+		}
+
+		if ( tests ) {
+			result = document.createElement( "p" );
+			result.id = "qunit-testresult";
+			result.className = "result";
+			tests.parentNode.insertBefore( result, tests );
+			result.innerHTML = "Running...<br/>&nbsp;";
+		}
+	},
+
+	// Resets the test setup. Useful for tests that modify the DOM.
+	/*
+	DEPRECATED: Use multiple tests instead of resetting inside a test.
+	Use testStart or testDone for custom cleanup.
+	This method will throw an error in 2.0, and will be removed in 2.1
+	*/
+	reset: function() {
+		var fixture = id( "qunit-fixture" );
+		if ( fixture ) {
+			fixture.innerHTML = config.fixture;
+		}
+	},
+
+	// Trigger an event on an element.
+	// @example triggerEvent( document.body, "click" );
+	triggerEvent: function( elem, type, event ) {
+		if ( document.createEvent ) {
+			event = document.createEvent( "MouseEvents" );
+			event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+				0, 0, 0, 0, 0, false, false, false, false, 0, null);
+
+			elem.dispatchEvent( event );
+		} else if ( elem.fireEvent ) {
+			elem.fireEvent( "on" + type );
+		}
+	},
+
+	// Safe object type checking
+	is: function( type, obj ) {
+		return QUnit.objectType( obj ) === type;
+	},
+
+	objectType: function( obj ) {
+		if ( typeof obj === "undefined" ) {
+				return "undefined";
+		// consider: typeof null === object
+		}
+		if ( obj === null ) {
+				return "null";
+		}
+
+		var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+			type = match && match[1] || "";
+
+		switch ( type ) {
+			case "Number":
+				if ( isNaN(obj) ) {
+					return "nan";
+				}
+				return "number";
+			case "String":
+			case "Boolean":
+			case "Array":
+			case "Date":
+			case "RegExp":
+			case "Function":
+				return type.toLowerCase();
+		}
+		if ( typeof obj === "object" ) {
+			return "object";
+		}
+		return undefined;
+	},
+
+	push: function( result, actual, expected, message ) {
+		if ( !config.current ) {
+			throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
+		}
+
+		var output, source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: message,
+				actual: actual,
+				expected: expected
+			};
+
+		message = escapeText( message ) || ( result ? "okay" : "failed" );
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		if ( !result ) {
+			expected = escapeText( QUnit.jsDump.parse(expected) );
+			actual = escapeText( QUnit.jsDump.parse(actual) );
+			output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
+
+			if ( actual !== expected ) {
+				output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
+				output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
+			}
+
+			source = sourceFromStacktrace();
+
+			if ( source ) {
+				details.source = source;
+				output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+			}
+
+			output += "</table>";
+		}
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: !!result,
+			message: output
+		});
+	},
+
+	pushFailure: function( message, source, actual ) {
+		if ( !config.current ) {
+			throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+
+		var output,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: false,
+				message: message
+			};
+
+		message = escapeText( message ) || "error";
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		output += "<table>";
+
+		if ( actual ) {
+			output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
+		}
+
+		if ( source ) {
+			details.source = source;
+			output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+		}
+
+		output += "</table>";
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: false,
+			message: output
+		});
+	},
+
+	url: function( params ) {
+		params = extend( extend( {}, QUnit.urlParams ), params );
+		var key,
+			querystring = "?";
+
+		for ( key in params ) {
+			if ( hasOwn.call( params, key ) ) {
+				querystring += encodeURIComponent( key ) + "=" +
+					encodeURIComponent( params[ key ] ) + "&";
+			}
+		}
+		return window.location.protocol + "//" + window.location.host +
+			window.location.pathname + querystring.slice( 0, -1 );
+	},
+
+	extend: extend,
+	id: id,
+	addEvent: addEvent,
+	addClass: addClass,
+	hasClass: hasClass,
+	removeClass: removeClass
+	// load, equiv, jsDump, diff: Attached later
+});
+
+/**
+ * @deprecated: Created for backwards compatibility with test runner that set the hook function
+ * into QUnit.{hook}, instead of invoking it and passing the hook function.
+ * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
+ * Doing this allows us to tell if the following methods have been overwritten on the actual
+ * QUnit object.
+ */
+extend( QUnit.constructor.prototype, {
+
+	// Logging callbacks; all receive a single argument with the listed properties
+	// run test/logs.html for any related changes
+	begin: registerLoggingCallback( "begin" ),
+
+	// done: { failed, passed, total, runtime }
+	done: registerLoggingCallback( "done" ),
+
+	// log: { result, actual, expected, message }
+	log: registerLoggingCallback( "log" ),
+
+	// testStart: { name }
+	testStart: registerLoggingCallback( "testStart" ),
+
+	// testDone: { name, failed, passed, total, duration }
+	testDone: registerLoggingCallback( "testDone" ),
+
+	// moduleStart: { name }
+	moduleStart: registerLoggingCallback( "moduleStart" ),
+
+	// moduleDone: { name, failed, passed, total }
+	moduleDone: registerLoggingCallback( "moduleDone" )
+});
+
+if ( typeof document === "undefined" || document.readyState === "complete" ) {
+	config.autorun = true;
+}
+
+QUnit.load = function() {
+	runLoggingCallbacks( "begin", QUnit, {} );
+
+	// Initialize the config, saving the execution queue
+	var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
+		urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
+		numModules = 0,
+		moduleNames = [],
+		moduleFilterHtml = "",
+		urlConfigHtml = "",
+		oldconfig = extend( {}, config );
+
+	QUnit.init();
+	extend(config, oldconfig);
+
+	config.blocking = false;
+
+	len = config.urlConfig.length;
+
+	for ( i = 0; i < len; i++ ) {
+		val = config.urlConfig[i];
+		if ( typeof val === "string" ) {
+			val = {
+				id: val,
+				label: val,
+				tooltip: "[no tooltip available]"
+			};
+		}
+		config[ val.id ] = QUnit.urlParams[ val.id ];
+		urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
+			"' name='" + escapeText( val.id ) +
+			"' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
+			" title='" + escapeText( val.tooltip ) +
+			"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
+			"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
+	}
+	for ( i in config.modules ) {
+		if ( config.modules.hasOwnProperty( i ) ) {
+			moduleNames.push(i);
+		}
+	}
+	numModules = moduleNames.length;
+	moduleNames.sort( function( a, b ) {
+		return a.localeCompare( b );
+	});
+	moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+		( config.module === undefined  ? "selected='selected'" : "" ) +
+		">< All Modules ></option>";
+
+
+	for ( i = 0; i < numModules; i++) {
+			moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " +
+				( config.module === moduleNames[i] ? "selected='selected'" : "" ) +
+				">" + escapeText(moduleNames[i]) + "</option>";
+	}
+	moduleFilterHtml += "</select>";
+
+	// `userAgent` initialized at top of scope
+	userAgent = id( "qunit-userAgent" );
+	if ( userAgent ) {
+		userAgent.innerHTML = navigator.userAgent;
+	}
+
+	// `banner` initialized at top of scope
+	banner = id( "qunit-header" );
+	if ( banner ) {
+		banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
+	}
+
+	// `toolbar` initialized at top of scope
+	toolbar = id( "qunit-testrunner-toolbar" );
+	if ( toolbar ) {
+		// `filter` initialized at top of scope
+		filter = document.createElement( "input" );
+		filter.type = "checkbox";
+		filter.id = "qunit-filter-pass";
+
+		addEvent( filter, "click", function() {
+			var tmp,
+				ol = document.getElementById( "qunit-tests" );
+
+			if ( filter.checked ) {
+				ol.className = ol.className + " hidepass";
+			} else {
+				tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
+				ol.className = tmp.replace( / hidepass /, " " );
+			}
+			if ( defined.sessionStorage ) {
+				if (filter.checked) {
+					sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+				} else {
+					sessionStorage.removeItem( "qunit-filter-passed-tests" );
+				}
+			}
+		});
+
+		if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
+			filter.checked = true;
+			// `ol` initialized at top of scope
+			ol = document.getElementById( "qunit-tests" );
+			ol.className = ol.className + " hidepass";
+		}
+		toolbar.appendChild( filter );
+
+		// `label` initialized at top of scope
+		label = document.createElement( "label" );
+		label.setAttribute( "for", "qunit-filter-pass" );
+		label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
+		label.innerHTML = "Hide passed tests";
+		toolbar.appendChild( label );
+
+		urlConfigCheckboxesContainer = document.createElement("span");
+		urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
+		urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
+		// For oldIE support:
+		// * Add handlers to the individual elements instead of the container
+		// * Use "click" instead of "change"
+		// * Fallback from event.target to event.srcElement
+		addEvents( urlConfigCheckboxes, "click", function( event ) {
+			var params = {},
+				target = event.target || event.srcElement;
+			params[ target.name ] = target.checked ? true : undefined;
+			window.location = QUnit.url( params );
+		});
+		toolbar.appendChild( urlConfigCheckboxesContainer );
+
+		if (numModules > 1) {
+			moduleFilter = document.createElement( "span" );
+			moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+			moduleFilter.innerHTML = moduleFilterHtml;
+			addEvent( moduleFilter.lastChild, "change", function() {
+				var selectBox = moduleFilter.getElementsByTagName("select")[0],
+					selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+				window.location = QUnit.url({
+					module: ( selectedModule === "" ) ? undefined : selectedModule,
+					// Remove any existing filters
+					filter: undefined,
+					testNumber: undefined
+				});
+			});
+			toolbar.appendChild(moduleFilter);
+		}
+	}
+
+	// `main` initialized at top of scope
+	main = id( "qunit-fixture" );
+	if ( main ) {
+		config.fixture = main.innerHTML;
+	}
+
+	if ( config.autostart ) {
+		QUnit.start();
+	}
+};
+
+addEvent( window, "load", QUnit.load );
+
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will suppress the default browser handler,
+// returning false will let it run.
+window.onerror = function ( error, filePath, linerNr ) {
+	var ret = false;
+	if ( onErrorFnPrev ) {
+		ret = onErrorFnPrev( error, filePath, linerNr );
+	}
+
+	// Treat return value as window.onerror itself does,
+	// Only do our handling if not suppressed.
+	if ( ret !== true ) {
+		if ( QUnit.config.current ) {
+			if ( QUnit.config.current.ignoreGlobalErrors ) {
+				return true;
+			}
+			QUnit.pushFailure( error, filePath + ":" + linerNr );
+		} else {
+			QUnit.test( "global failure", extend( function() {
+				QUnit.pushFailure( error, filePath + ":" + linerNr );
+			}, { validTest: validTest } ) );
+		}
+		return false;
+	}
+
+	return ret;
+};
+
+function done() {
+	config.autorun = true;
+
+	// Log the last module results
+	if ( config.currentModule ) {
+		runLoggingCallbacks( "moduleDone", QUnit, {
+			name: config.currentModule,
+			failed: config.moduleStats.bad,
+			passed: config.moduleStats.all - config.moduleStats.bad,
+			total: config.moduleStats.all
+		});
+	}
+	delete config.previousModule;
+
+	var i, key,
+		banner = id( "qunit-banner" ),
+		tests = id( "qunit-tests" ),
+		runtime = +new Date() - config.started,
+		passed = config.stats.all - config.stats.bad,
+		html = [
+			"Tests completed in ",
+			runtime,
+			" milliseconds.<br/>",
+			"<span class='passed'>",
+			passed,
+			"</span> assertions of <span class='total'>",
+			config.stats.all,
+			"</span> passed, <span class='failed'>",
+			config.stats.bad,
+			"</span> failed."
+		].join( "" );
+
+	if ( banner ) {
+		banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
+	}
+
+	if ( tests ) {
+		id( "qunit-testresult" ).innerHTML = html;
+	}
+
+	if ( config.altertitle && typeof document !== "undefined" && document.title ) {
+		// show ✖ for good, ✔ for bad suite result in title
+		// use escape sequences in case file gets loaded with non-utf-8-charset
+		document.title = [
+			( config.stats.bad ? "\u2716" : "\u2714" ),
+			document.title.replace( /^[\u2714\u2716] /i, "" )
+		].join( " " );
+	}
+
+	// clear own sessionStorage items if all tests passed
+	if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
+		// `key` & `i` initialized at top of scope
+		for ( i = 0; i < sessionStorage.length; i++ ) {
+			key = sessionStorage.key( i++ );
+			if ( key.indexOf( "qunit-test-" ) === 0 ) {
+				sessionStorage.removeItem( key );
+			}
+		}
+	}
+
+	// scroll back to top to show results
+	if ( window.scrollTo ) {
+		window.scrollTo(0, 0);
+	}
+
+	runLoggingCallbacks( "done", QUnit, {
+		failed: config.stats.bad,
+		passed: passed,
+		total: config.stats.all,
+		runtime: runtime
+	});
+}
+
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+	var include,
+		filter = config.filter && config.filter.toLowerCase(),
+		module = config.module && config.module.toLowerCase(),
+		fullName = (test.module + ": " + test.testName).toLowerCase();
+
+	// Internally-generated tests are always valid
+	if ( test.callback && test.callback.validTest === validTest ) {
+		delete test.callback.validTest;
+		return true;
+	}
+
+	if ( config.testNumber ) {
+		return test.testNumber === config.testNumber;
+	}
+
+	if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
+		return false;
+	}
+
+	if ( !filter ) {
+		return true;
+	}
+
+	include = filter.charAt( 0 ) !== "!";
+	if ( !include ) {
+		filter = filter.slice( 1 );
+	}
+
+	// If the filter matches, we need to honour include
+	if ( fullName.indexOf( filter ) !== -1 ) {
+		return include;
+	}
+
+	// Otherwise, do the opposite
+	return !include;
+}
+
+// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
+// Later Safari and IE10 are supposed to support error.stack as well
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+	offset = offset === undefined ? 3 : offset;
+
+	var stack, include, i;
+
+	if ( e.stacktrace ) {
+		// Opera
+		return e.stacktrace.split( "\n" )[ offset + 3 ];
+	} else if ( e.stack ) {
+		// Firefox, Chrome
+		stack = e.stack.split( "\n" );
+		if (/^error$/i.test( stack[0] ) ) {
+			stack.shift();
+		}
+		if ( fileName ) {
+			include = [];
+			for ( i = offset; i < stack.length; i++ ) {
+				if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+					break;
+				}
+				include.push( stack[ i ] );
+			}
+			if ( include.length ) {
+				return include.join( "\n" );
+			}
+		}
+		return stack[ offset ];
+	} else if ( e.sourceURL ) {
+		// Safari, PhantomJS
+		// hopefully one day Safari provides actual stacktraces
+		// exclude useless self-reference for generated Error objects
+		if ( /qunit.js$/.test( e.sourceURL ) ) {
+			return;
+		}
+		// for actual exceptions, this is useful
+		return e.sourceURL + ":" + e.line;
+	}
+}
+function sourceFromStacktrace( offset ) {
+	try {
+		throw new Error();
+	} catch ( e ) {
+		return extractStacktrace( e, offset );
+	}
+}
+
+/**
+ * Escape text for attribute or text content.
+ */
+function escapeText( s ) {
+	if ( !s ) {
+		return "";
+	}
+	s = s + "";
+	// Both single quotes and double quotes (for attributes)
+	return s.replace( /['"<>&]/g, function( s ) {
+		switch( s ) {
+			case "'":
+				return "&#039;";
+			case "\"":
+				return "&quot;";
+			case "<":
+				return "&lt;";
+			case ">":
+				return "&gt;";
+			case "&":
+				return "&amp;";
+		}
+	});
+}
+
+function synchronize( callback, last ) {
+	config.queue.push( callback );
+
+	if ( config.autorun && !config.blocking ) {
+		process( last );
+	}
+}
+
+function process( last ) {
+	function next() {
+		process( last );
+	}
+	var start = new Date().getTime();
+	config.depth = config.depth ? config.depth + 1 : 1;
+
+	while ( config.queue.length && !config.blocking ) {
+		if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
+			config.queue.shift()();
+		} else {
+			setTimeout( next, 13 );
+			break;
+		}
+	}
+	config.depth--;
+	if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+		done();
+	}
+}
+
+function saveGlobal() {
+	config.pollution = [];
+
+	if ( config.noglobals ) {
+		for ( var key in window ) {
+			if ( hasOwn.call( window, key ) ) {
+				// in Opera sometimes DOM element ids show up here, ignore them
+				if ( /^qunit-test-output/.test( key ) ) {
+					continue;
+				}
+				config.pollution.push( key );
+			}
+		}
+	}
+}
+
+function checkPollution() {
+	var newGlobals,
+		deletedGlobals,
+		old = config.pollution;
+
+	saveGlobal();
+
+	newGlobals = diff( config.pollution, old );
+	if ( newGlobals.length > 0 ) {
+		QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
+	}
+
+	deletedGlobals = diff( old, config.pollution );
+	if ( deletedGlobals.length > 0 ) {
+		QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
+	}
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+	var i, j,
+		result = a.slice();
+
+	for ( i = 0; i < result.length; i++ ) {
+		for ( j = 0; j < b.length; j++ ) {
+			if ( result[i] === b[j] ) {
+				result.splice( i, 1 );
+				i--;
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+function extend( a, b ) {
+	for ( var prop in b ) {
+		if ( hasOwn.call( b, prop ) ) {
+			// Avoid "Member not found" error in IE8 caused by messing with window.constructor
+			if ( !( prop === "constructor" && a === window ) ) {
+				if ( b[ prop ] === undefined ) {
+					delete a[ prop ];
+				} else {
+					a[ prop ] = b[ prop ];
+				}
+			}
+		}
+	}
+
+	return a;
+}
+
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+	// Standards-based browsers
+	if ( elem.addEventListener ) {
+		elem.addEventListener( type, fn, false );
+	// IE
+	} else {
+		elem.attachEvent( "on" + type, fn );
+	}
+}
+
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+	var i = elems.length;
+	while ( i-- ) {
+		addEvent( elems[i], type, fn );
+	}
+}
+
+function hasClass( elem, name ) {
+	return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
+}
+
+function addClass( elem, name ) {
+	if ( !hasClass( elem, name ) ) {
+		elem.className += (elem.className ? " " : "") + name;
+	}
+}
+
+function removeClass( elem, name ) {
+	var set = " " + elem.className + " ";
+	// Class name may appear multiple times
+	while ( set.indexOf(" " + name + " ") > -1 ) {
+		set = set.replace(" " + name + " " , " ");
+	}
+	// If possible, trim it for prettiness, but not necessarily
+	elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
+}
+
+function id( name ) {
+	return !!( typeof document !== "undefined" && document && document.getElementById ) &&
+		document.getElementById( name );
+}
+
+function registerLoggingCallback( key ) {
+	return function( callback ) {
+		config[key].push( callback );
+	};
+}
+
+// Supports deprecated method of completely overwriting logging callbacks
+function runLoggingCallbacks( key, scope, args ) {
+	var i, callbacks;
+	if ( QUnit.hasOwnProperty( key ) ) {
+		QUnit[ key ].call(scope, args );
+	} else {
+		callbacks = config[ key ];
+		for ( i = 0; i < callbacks.length; i++ ) {
+			callbacks[ i ].call( scope, args );
+		}
+	}
+}
+
+// Test for equality any JavaScript type.
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = (function() {
+
+	// Call the o related callback with the given arguments.
+	function bindCallbacks( o, callbacks, args ) {
+		var prop = QUnit.objectType( o );
+		if ( prop ) {
+			if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
+				return callbacks[ prop ].apply( callbacks, args );
+			} else {
+				return callbacks[ prop ]; // or undefined
+			}
+		}
+	}
+
+	// the real equiv function
+	var innerEquiv,
+		// stack to decide between skip/abort functions
+		callers = [],
+		// stack to avoiding loops from circular referencing
+		parents = [],
+		parentsB = [],
+
+		getProto = Object.getPrototypeOf || function ( obj ) {
+			/*jshint camelcase:false */
+			return obj.__proto__;
+		},
+		callbacks = (function () {
+
+			// for string, boolean, number and null
+			function useStrictEquality( b, a ) {
+				/*jshint eqeqeq:false */
+				if ( b instanceof a.constructor || a instanceof b.constructor ) {
+					// to catch short annotation VS 'new' annotation of a
+					// declaration
+					// e.g. var i = 1;
+					// var j = new Number(1);
+					return a == b;
+				} else {
+					return a === b;
+				}
+			}
+
+			return {
+				"string": useStrictEquality,
+				"boolean": useStrictEquality,
+				"number": useStrictEquality,
+				"null": useStrictEquality,
+				"undefined": useStrictEquality,
+
+				"nan": function( b ) {
+					return isNaN( b );
+				},
+
+				"date": function( b, a ) {
+					return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
+				},
+
+				"regexp": function( b, a ) {
+					return QUnit.objectType( b ) === "regexp" &&
+						// the regex itself
+						a.source === b.source &&
+						// and its modifiers
+						a.global === b.global &&
+						// (gmi) ...
+						a.ignoreCase === b.ignoreCase &&
+						a.multiline === b.multiline &&
+						a.sticky === b.sticky;
+				},
+
+				// - skip when the property is a method of an instance (OOP)
+				// - abort otherwise,
+				// initial === would have catch identical references anyway
+				"function": function() {
+					var caller = callers[callers.length - 1];
+					return caller !== Object && typeof caller !== "undefined";
+				},
+
+				"array": function( b, a ) {
+					var i, j, len, loop, aCircular, bCircular;
+
+					// b could be an object literal here
+					if ( QUnit.objectType( b ) !== "array" ) {
+						return false;
+					}
+
+					len = a.length;
+					if ( len !== b.length ) {
+						// safe and faster
+						return false;
+					}
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+					for ( i = 0; i < len; i++ ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									parents.pop();
+									parentsB.pop();
+									return false;
+								}
+							}
+						}
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							parents.pop();
+							parentsB.pop();
+							return false;
+						}
+					}
+					parents.pop();
+					parentsB.pop();
+					return true;
+				},
+
+				"object": function( b, a ) {
+					/*jshint forin:false */
+					var i, j, loop, aCircular, bCircular,
+						// Default to true
+						eq = true,
+						aProperties = [],
+						bProperties = [];
+
+					// comparing constructors is more strict than using
+					// instanceof
+					if ( a.constructor !== b.constructor ) {
+						// Allow objects with no prototype to be equivalent to
+						// objects with Object as their constructor.
+						if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
+							( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
+								return false;
+						}
+					}
+
+					// stack constructor before traversing properties
+					callers.push( a.constructor );
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+
+					// be strict: don't ensure hasOwnProperty and go deep
+					for ( i in a ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									eq = false;
+									break;
+								}
+							}
+						}
+						aProperties.push(i);
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							eq = false;
+							break;
+						}
+					}
+
+					parents.pop();
+					parentsB.pop();
+					callers.pop(); // unstack, we are done
+
+					for ( i in b ) {
+						bProperties.push( i ); // collect b's properties
+					}
+
+					// Ensures identical properties name
+					return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
+				}
+			};
+		}());
+
+	innerEquiv = function() { // can take multiple arguments
+		var args = [].slice.apply( arguments );
+		if ( args.length < 2 ) {
+			return true; // end transition
+		}
+
+		return (function( a, b ) {
+			if ( a === b ) {
+				return true; // catch the most you can
+			} else if ( a === null || b === null || typeof a === "undefined" ||
+					typeof b === "undefined" ||
+					QUnit.objectType(a) !== QUnit.objectType(b) ) {
+				return false; // don't lose time with error prone cases
+			} else {
+				return bindCallbacks(a, callbacks, [ b, a ]);
+			}
+
+			// apply transition with (1..n) arguments
+		}( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) );
+	};
+
+	return innerEquiv;
+}());
+
+/**
+ * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
+ * http://flesler.blogspot.com Licensed under BSD
+ * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
+ *
+ * @projectDescription Advanced and extensible data dumping for Javascript.
+ * @version 1.0.0
+ * @author Ariel Flesler
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
+ */
+QUnit.jsDump = (function() {
+	function quote( str ) {
+		return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
+	}
+	function literal( o ) {
+		return o + "";
+	}
+	function join( pre, arr, post ) {
+		var s = jsDump.separator(),
+			base = jsDump.indent(),
+			inner = jsDump.indent(1);
+		if ( arr.join ) {
+			arr = arr.join( "," + s + inner );
+		}
+		if ( !arr ) {
+			return pre + post;
+		}
+		return [ pre, inner + arr, base + post ].join(s);
+	}
+	function array( arr, stack ) {
+		var i = arr.length, ret = new Array(i);
+		this.up();
+		while ( i-- ) {
+			ret[i] = this.parse( arr[i] , undefined , stack);
+		}
+		this.down();
+		return join( "[", ret, "]" );
+	}
+
+	var reName = /^function (\w+)/,
+		jsDump = {
+			// type is used mostly internally, you can fix a (custom)type in advance
+			parse: function( obj, type, stack ) {
+				stack = stack || [ ];
+				var inStack, res,
+					parser = this.parsers[ type || this.typeOf(obj) ];
+
+				type = typeof parser;
+				inStack = inArray( obj, stack );
+
+				if ( inStack !== -1 ) {
+					return "recursion(" + (inStack - stack.length) + ")";
+				}
+				if ( type === "function" )  {
+					stack.push( obj );
+					res = parser.call( this, obj, stack );
+					stack.pop();
+					return res;
+				}
+				return ( type === "string" ) ? parser : this.parsers.error;
+			},
+			typeOf: function( obj ) {
+				var type;
+				if ( obj === null ) {
+					type = "null";
+				} else if ( typeof obj === "undefined" ) {
+					type = "undefined";
+				} else if ( QUnit.is( "regexp", obj) ) {
+					type = "regexp";
+				} else if ( QUnit.is( "date", obj) ) {
+					type = "date";
+				} else if ( QUnit.is( "function", obj) ) {
+					type = "function";
+				} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
+					type = "window";
+				} else if ( obj.nodeType === 9 ) {
+					type = "document";
+				} else if ( obj.nodeType ) {
+					type = "node";
+				} else if (
+					// native arrays
+					toString.call( obj ) === "[object Array]" ||
+					// NodeList objects
+					( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
+				) {
+					type = "array";
+				} else if ( obj.constructor === Error.prototype.constructor ) {
+					type = "error";
+				} else {
+					type = typeof obj;
+				}
+				return type;
+			},
+			separator: function() {
+				return this.multiline ?	this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
+			},
+			// extra can be a number, shortcut for increasing-calling-decreasing
+			indent: function( extra ) {
+				if ( !this.multiline ) {
+					return "";
+				}
+				var chr = this.indentChar;
+				if ( this.HTML ) {
+					chr = chr.replace( /\t/g, "   " ).replace( / /g, "&nbsp;" );
+				}
+				return new Array( this.depth + ( extra || 0 ) ).join(chr);
+			},
+			up: function( a ) {
+				this.depth += a || 1;
+			},
+			down: function( a ) {
+				this.depth -= a || 1;
+			},
+			setParser: function( name, parser ) {
+				this.parsers[name] = parser;
+			},
+			// The next 3 are exposed so you can use them
+			quote: quote,
+			literal: literal,
+			join: join,
+			//
+			depth: 1,
+			// This is the list of parsers, to modify them, use jsDump.setParser
+			parsers: {
+				window: "[Window]",
+				document: "[Document]",
+				error: function(error) {
+					return "Error(\"" + error.message + "\")";
+				},
+				unknown: "[Unknown]",
+				"null": "null",
+				"undefined": "undefined",
+				"function": function( fn ) {
+					var ret = "function",
+						// functions never have name in IE
+						name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
+
+					if ( name ) {
+						ret += " " + name;
+					}
+					ret += "( ";
+
+					ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
+					return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
+				},
+				array: array,
+				nodelist: array,
+				"arguments": array,
+				object: function( map, stack ) {
+					/*jshint forin:false */
+					var ret = [ ], keys, key, val, i;
+					QUnit.jsDump.up();
+					keys = [];
+					for ( key in map ) {
+						keys.push( key );
+					}
+					keys.sort();
+					for ( i = 0; i < keys.length; i++ ) {
+						key = keys[ i ];
+						val = map[ key ];
+						ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
+					}
+					QUnit.jsDump.down();
+					return join( "{", ret, "}" );
+				},
+				node: function( node ) {
+					var len, i, val,
+						open = QUnit.jsDump.HTML ? "&lt;" : "<",
+						close = QUnit.jsDump.HTML ? "&gt;" : ">",
+						tag = node.nodeName.toLowerCase(),
+						ret = open + tag,
+						attrs = node.attributes;
+
+					if ( attrs ) {
+						for ( i = 0, len = attrs.length; i < len; i++ ) {
+							val = attrs[i].nodeValue;
+							// IE6 includes all attributes in .attributes, even ones not explicitly set.
+							// Those have values like undefined, null, 0, false, "" or "inherit".
+							if ( val && val !== "inherit" ) {
+								ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
+							}
+						}
+					}
+					ret += close;
+
+					// Show content of TextNode or CDATASection
+					if ( node.nodeType === 3 || node.nodeType === 4 ) {
+						ret += node.nodeValue;
+					}
+
+					return ret + open + "/" + tag + close;
+				},
+				// function calls it internally, it's the arguments part of the function
+				functionArgs: function( fn ) {
+					var args,
+						l = fn.length;
+
+					if ( !l ) {
+						return "";
+					}
+
+					args = new Array(l);
+					while ( l-- ) {
+						// 97 is 'a'
+						args[l] = String.fromCharCode(97+l);
+					}
+					return " " + args.join( ", " ) + " ";
+				},
+				// object calls it internally, the key part of an item in a map
+				key: quote,
+				// function calls it internally, it's the content of the function
+				functionCode: "[code]",
+				// node calls it internally, it's an html attribute value
+				attribute: quote,
+				string: quote,
+				date: quote,
+				regexp: literal,
+				number: literal,
+				"boolean": literal
+			},
+			// if true, entities are escaped ( <, >, \t, space and \n )
+			HTML: false,
+			// indentation unit
+			indentChar: "  ",
+			// if true, items in a collection, are separated by a \n, else just a space.
+			multiline: true
+		};
+
+	return jsDump;
+}());
+
+// from jquery.js
+function inArray( elem, array ) {
+	if ( array.indexOf ) {
+		return array.indexOf( elem );
+	}
+
+	for ( var i = 0, length = array.length; i < length; i++ ) {
+		if ( array[ i ] === elem ) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/*
+ * Javascript Diff Algorithm
+ *  By John Resig (http://ejohn.org/)
+ *  Modified by Chu Alan "sprite"
+ *
+ * Released under the MIT license.
+ *
+ * More Info:
+ *  http://ejohn.org/projects/javascript-diff-algorithm/
+ *
+ * Usage: QUnit.diff(expected, actual)
+ *
+ * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
+ */
+QUnit.diff = (function() {
+	/*jshint eqeqeq:false, eqnull:true */
+	function diff( o, n ) {
+		var i,
+			ns = {},
+			os = {};
+
+		for ( i = 0; i < n.length; i++ ) {
+			if ( !hasOwn.call( ns, n[i] ) ) {
+				ns[ n[i] ] = {
+					rows: [],
+					o: null
+				};
+			}
+			ns[ n[i] ].rows.push( i );
+		}
+
+		for ( i = 0; i < o.length; i++ ) {
+			if ( !hasOwn.call( os, o[i] ) ) {
+				os[ o[i] ] = {
+					rows: [],
+					n: null
+				};
+			}
+			os[ o[i] ].rows.push( i );
+		}
+
+		for ( i in ns ) {
+			if ( hasOwn.call( ns, i ) ) {
+				if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
+					n[ ns[i].rows[0] ] = {
+						text: n[ ns[i].rows[0] ],
+						row: os[i].rows[0]
+					};
+					o[ os[i].rows[0] ] = {
+						text: o[ os[i].rows[0] ],
+						row: ns[i].rows[0]
+					};
+				}
+			}
+		}
+
+		for ( i = 0; i < n.length - 1; i++ ) {
+			if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
+						n[ i + 1 ] == o[ n[i].row + 1 ] ) {
+
+				n[ i + 1 ] = {
+					text: n[ i + 1 ],
+					row: n[i].row + 1
+				};
+				o[ n[i].row + 1 ] = {
+					text: o[ n[i].row + 1 ],
+					row: i + 1
+				};
+			}
+		}
+
+		for ( i = n.length - 1; i > 0; i-- ) {
+			if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
+						n[ i - 1 ] == o[ n[i].row - 1 ]) {
+
+				n[ i - 1 ] = {
+					text: n[ i - 1 ],
+					row: n[i].row - 1
+				};
+				o[ n[i].row - 1 ] = {
+					text: o[ n[i].row - 1 ],
+					row: i - 1
+				};
+			}
+		}
+
+		return {
+			o: o,
+			n: n
+		};
+	}
+
+	return function( o, n ) {
+		o = o.replace( /\s+$/, "" );
+		n = n.replace( /\s+$/, "" );
+
+		var i, pre,
+			str = "",
+			out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
+			oSpace = o.match(/\s+/g),
+			nSpace = n.match(/\s+/g);
+
+		if ( oSpace == null ) {
+			oSpace = [ " " ];
+		}
+		else {
+			oSpace.push( " " );
+		}
+
+		if ( nSpace == null ) {
+			nSpace = [ " " ];
+		}
+		else {
+			nSpace.push( " " );
+		}
+
+		if ( out.n.length === 0 ) {
+			for ( i = 0; i < out.o.length; i++ ) {
+				str += "<del>" + out.o[i] + oSpace[i] + "</del>";
+			}
+		}
+		else {
+			if ( out.n[0].text == null ) {
+				for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
+					str += "<del>" + out.o[n] + oSpace[n] + "</del>";
+				}
+			}
+
+			for ( i = 0; i < out.n.length; i++ ) {
+				if (out.n[i].text == null) {
+					str += "<ins>" + out.n[i] + nSpace[i] + "</ins>";
+				}
+				else {
+					// `pre` initialized at top of scope
+					pre = "";
+
+					for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
+						pre += "<del>" + out.o[n] + oSpace[n] + "</del>";
+					}
+					str += " " + out.n[i].text + nSpace[i] + pre;
+				}
+			}
+		}
+
+		return str;
+	};
+}());
+
+// for CommonJS environments, export everything
+if ( typeof exports !== "undefined" ) {
+	extend( exports, QUnit.constructor.prototype );
+}
+
+// get at whatever the global object is, like window in browsers
+}( (function() {return this;}.call()) ));
diff --git a/docs/slides/ETH14/_support/reveal.js/test/test-markdown-element-attributes.js b/docs/slides/ETH14/_support/reveal.js/test/test-markdown-element-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/test/test-markdown-element-attributes.js
@@ -0,0 +1,46 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
+	});
+
+
+	test( 'Attributes on element header in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
+	});
+
+	test( 'Attributes on element paragraphs in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
+	});
+
+	test( 'Attributes on element list items in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.roll-in' ).length, 3, 'found a vertical slide with three list items with class fragment.roll-in' );
+	});
+
+	test( 'Attributes on element paragraphs in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
+	});
+
+	test( 'Attributes on elements in vertical slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
+	});
+
+	test( 'Attributes on elements in single slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/ETH14/_support/reveal.js/test/test-markdown-slide-attributes.js b/docs/slides/ETH14/_support/reveal.js/test/test-markdown-slide-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/test/test-markdown-slide-attributes.js
@@ -0,0 +1,47 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' );
+	});
+
+	test( 'Id on slide', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' );
+	});
+
+	test( 'data-background attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-background attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-transition attributes with inline content', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/ETH14/_support/reveal.js/test/test-markdown.js b/docs/slides/ETH14/_support/reveal.js/test/test-markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/test/test-markdown.js
@@ -0,0 +1,15 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/ETH14/_support/reveal.js/test/test.js b/docs/slides/ETH14/_support/reveal.js/test/test.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/reveal.js/test/test.js
@@ -0,0 +1,438 @@
+
+// These tests expect the DOM to contain a presentation
+// with the following slide structure:
+//
+// 1
+// 2 - Three sub-slides
+// 3 - Three fragment elements
+// 3 - Two fragments with same data-fragment-index
+// 4
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	// ---------------------------------------------------------------
+	// DOM TESTS
+
+	QUnit.module( 'DOM' );
+
+	test( 'Initial slides classes', function() {
+		var horizontalSlides = document.querySelectorAll( '.reveal .slides>section' )
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.past' ).length, 0, 'no .past slides' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section.present' ).length, 1, 'one .present slide' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section.future' ).length, horizontalSlides.length - 1, 'remaining horizontal slides are .future' );
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.stack' ).length, 2, 'two .stacks' );
+
+		ok( document.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length > 0, 'vertical slides are given .future' );
+	});
+
+	// ---------------------------------------------------------------
+	// API TESTS
+
+	QUnit.module( 'API' );
+
+	test( 'Reveal.isReady', function() {
+		strictEqual( Reveal.isReady(), true, 'returns true' );
+	});
+
+	test( 'Reveal.isOverview', function() {
+		strictEqual( Reveal.isOverview(), false, 'false by default' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), true, 'true after toggling on' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), false, 'false after toggling off' );
+	});
+
+	test( 'Reveal.isPaused', function() {
+		strictEqual( Reveal.isPaused(), false, 'false by default' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), true, 'true after pausing' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), false, 'false after resuming' );
+	});
+
+	test( 'Reveal.isFirstSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+
+		Reveal.slide( 1, 0 );
+		strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.isLastSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+
+		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
+
+		Reveal.slide( lastSlideIndex, 0 );
+		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( ', 0+ lastSlideIndex +' )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.getIndices', function() {
+		var indices = Reveal.getIndices();
+
+		ok( typeof indices.hasOwnProperty( 'h' ), 'h exists' );
+		ok( typeof indices.hasOwnProperty( 'v' ), 'v exists' );
+		ok( typeof indices.hasOwnProperty( 'f' ), 'f exists' );
+
+		Reveal.slide( 1, 0 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 0, 'h 1, v 0' );
+
+		Reveal.slide( 1, 2 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 2, 'h 1, v 2' );
+
+		Reveal.slide( 0, 0 );
+	});
+
+	test( 'Reveal.getSlide', function() {
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+
+		equal( Reveal.getSlide( 0 ), firstSlide, 'gets correct first slide' );
+
+		strictEqual( Reveal.getSlide( 100 ), undefined, 'returns undefined when slide can\'t be found' );
+	});
+
+	test( 'Reveal.getPreviousSlide/getCurrentSlide', function() {
+		Reveal.slide( 0, 0 );
+		Reveal.slide( 1, 0 );
+
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+		var secondSlide = document.querySelector( '.reveal .slides>section:nth-child(2)>section' );
+
+		equal( Reveal.getPreviousSlide(), firstSlide, 'previous is slide #0' );
+		equal( Reveal.getCurrentSlide(), secondSlide, 'current is slide #1' );
+	});
+
+	test( 'Reveal.getScale', function() {
+		ok( typeof Reveal.getScale() === 'number', 'has scale' );
+	});
+
+	test( 'Reveal.getConfig', function() {
+		ok( typeof Reveal.getConfig() === 'object', 'has config' );
+	});
+
+	test( 'Reveal.configure', function() {
+		strictEqual( Reveal.getConfig().loop, false, '"loop" is false to start with' );
+
+		Reveal.configure({ loop: true });
+		strictEqual( Reveal.getConfig().loop, true, '"loop" has changed to true' );
+
+		Reveal.configure({ loop: false, customTestValue: 1 });
+		strictEqual( Reveal.getConfig().customTestValue, 1, 'supports custom values' );
+	});
+
+	test( 'Reveal.availableRoutes', function() {
+		Reveal.slide( 0, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: false, up: false, down: false, right: true }, 'correct for first slide' );
+
+		Reveal.slide( 1, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: true, up: false, down: true, right: true }, 'correct for vertical slide' );
+	});
+
+	test( 'Reveal.next', function() {
+		Reveal.slide( 0, 0 );
+
+		// Step through vertical child slides
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 1, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } );
+
+		// Step through fragments
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } );
+	});
+
+	test( 'Reveal.next at end', function() {
+		Reveal.slide( 3 );
+
+		// We're at the end, this should have no effect
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+	});
+
+
+	// ---------------------------------------------------------------
+	// FRAGMENT TESTS
+
+	QUnit.module( 'Fragments' );
+
+	test( 'Sliding to fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'Reveal.slide( 2, 0, -1 )' );
+
+		Reveal.slide( 2, 0, 0 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'Reveal.slide( 2, 0, 0 )' );
+
+		Reveal.slide( 2, 0, 2 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'Reveal.slide( 2, 0, 2 )' );
+
+		Reveal.slide( 2, 0, 1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'Reveal.slide( 2, 0, 1 )' );
+	});
+
+	test( 'Hiding all fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' );
+
+		Reveal.slide( 2, 0, -1 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index is -1' );
+	});
+
+	test( 'Current fragment', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 1, 'one current fragment at index 0' );
+
+		Reveal.slide( 1, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
+	});
+
+	test( 'Stepping through fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+
+		// forwards:
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'next() goes to next fragment' );
+
+		Reveal.right();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'right() goes to next fragment' );
+
+		Reveal.down();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'down() goes to next fragment' );
+
+		Reveal.down(); // moves to f #3
+
+		// backwards:
+
+		Reveal.prev();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'prev() goes to prev fragment' );
+
+		Reveal.left();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'left() goes to prev fragment' );
+
+		Reveal.up();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'up() goes to prev fragment' );
+	});
+
+	test( 'Stepping past fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 0, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 3, 'all fragments visible when on future slide' );
+	});
+
+	test( 'Fragment indices', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(2)' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 2, 'both fragments of same index are shown' );
+	});
+
+	test( 'Index generation', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		// These have no indices defined to start with
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' );
+	});
+
+	test( 'Index normalization', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(3)' );
+
+		// These start out as 1-4-4 and should normalize to 0-1-1
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' );
+	});
+
+	asyncTest( 'fragmentshown event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmentshown', _onEvent );
+
+		Reveal.slide( 2, 0 );
+		Reveal.slide( 2, 0 ); // should do nothing
+		Reveal.slide( 2, 0, 0 ); // should do nothing
+		Reveal.next();
+		Reveal.next();
+		Reveal.prev(); // shouldn't fire fragmentshown
+
+		start();
+
+		Reveal.removeEventListener( 'fragmentshown', _onEvent );
+	});
+
+	asyncTest( 'fragmenthidden event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmenthidden', _onEvent );
+
+		Reveal.slide( 2, 0, 2 );
+		Reveal.slide( 2, 0, 2 ); // should do nothing
+		Reveal.prev();
+		Reveal.prev();
+		Reveal.next(); // shouldn't fire fragmenthidden
+
+		start();
+
+		Reveal.removeEventListener( 'fragmenthidden', _onEvent );
+	});
+
+
+	// ---------------------------------------------------------------
+	// CONFIGURATION VALUES
+
+	QUnit.module( 'Configuration' );
+
+	test( 'Controls', function() {
+		var controlsElement = document.querySelector( '.reveal>.controls' );
+
+		Reveal.configure({ controls: false });
+		equal( controlsElement.style.display, 'none', 'controls are hidden' );
+
+		Reveal.configure({ controls: true });
+		equal( controlsElement.style.display, 'block', 'controls are visible' );
+	});
+
+	test( 'Progress', function() {
+		var progressElement = document.querySelector( '.reveal>.progress' );
+
+		Reveal.configure({ progress: false });
+		equal( progressElement.style.display, 'none', 'progress are hidden' );
+
+		Reveal.configure({ progress: true });
+		equal( progressElement.style.display, 'block', 'progress are visible' );
+	});
+
+	test( 'Loop', function() {
+		Reveal.configure({ loop: true });
+
+		Reveal.slide( 0, 0 );
+
+		Reveal.left();
+		notEqual( Reveal.getIndices().h, 0, 'looped from start to end' );
+
+		Reveal.right();
+		equal( Reveal.getIndices().h, 0, 'looped from end to start' );
+
+		Reveal.configure({ loop: false });
+	});
+
+
+	// ---------------------------------------------------------------
+	// EVENT TESTS
+
+	QUnit.module( 'Events' );
+
+	asyncTest( 'slidechanged', function() {
+		expect( 3 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'slidechanged', _onEvent );
+
+		Reveal.slide( 1, 0 ); // should trigger
+		Reveal.slide( 1, 0 ); // should do nothing
+		Reveal.next(); // should trigger
+		Reveal.slide( 3, 0 ); // should trigger
+		Reveal.next(); // should do nothing
+
+		start();
+
+		Reveal.removeEventListener( 'slidechanged', _onEvent );
+
+	});
+
+	asyncTest( 'paused', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'paused', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'paused', _onEvent );
+	});
+
+	asyncTest( 'resumed', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'resumed', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'resumed', _onEvent );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/ETH14/_support/template.reveal b/docs/slides/ETH14/_support/template.reveal
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/_support/template.reveal
@@ -0,0 +1,128 @@
+<!doctype html>  
+<html lang="en">
+	
+<head>
+<meta charset="utf-8">
+
+<title>Liquid Types</title>
+
+<meta name="description" content="Liquid Types IHP 2014">
+<meta name="author" content="Ranjit Jhala">
+
+<meta name="apple-mobile-web-app-capable" content="yes" />
+
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+
+<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
+
+<link rel="stylesheet" href="$reveal$/css/reveal.css">
+<link rel="stylesheet" href="$reveal$/css/theme/seminar.css" id="theme">
+<!-- <link rel="stylesheet" href="$reveal$/css/print/pdf.css"> -->
+<link rel="stylesheet" href="../_support/liquidhaskell.css">
+
+<!-- For syntax highlighting -->
+<link rel="stylesheet" href="$reveal$/lib/css/zenburn.css">
+
+<script>
+	// If the query includes 'print-pdf' we'll use the PDF print sheet
+	document.write( '<link rel="stylesheet" href="$reveal$/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
+</script>
+
+<!--[if lt IE 9]>
+<script src="lib/js/html5shiv.js"></script>
+<![endif]-->
+</head>
+<body>
+
+\(
+\require{color}
+\definecolor{kvcol}{RGB}{203,23,206}
+\definecolor{tycol}{RGB}{5,177,93}
+\definecolor{refcol}{RGB}{18,110,213}
+
+\newcommand{\quals}{\mathbb{Q}}
+\newcommand{\defeq}{\ \doteq\ }
+\newcommand{\subty}{\preceq}
+\newcommand{\True}{\mathit{True}}
+\newcommand{\Int}{\mathtt{Int}}
+\newcommand{\Nat}{\mathtt{Nat}}
+\newcommand{\Zero}{\mathtt{Zero}}
+\newcommand{\foo}[4]{{#1}^{#4} + {#2}^{#4} = {#3}^{#4}}
+\newcommand{\reft}[3]{\{\bindx{#1}{#2} \mid {#3}\}}
+\newcommand{\ereft}[3]{\bindx{#1}{\{#2 \mid #3\}}}
+\newcommand{\bindx}[2]{{#1}\!:\!{#2}}
+\newcommand{\reftx}[2]{\{{#1}\mid{#2}\}}
+\newcommand{\inferrule}[3][]{\frac{#2}{#3}\;{#1}}
+\newcommand{\kvar}[1]{\color{kvcol}{\mathbf{\kappa_{#1}}}}
+\newcommand{\llen}[1]{\mathtt{llen}(#1)}
+\)
+
+<div class="reveal">
+<!-- 
+Used to fade in a background when a specific slide state is reached
+-->
+<div class="state-background"></div>
+
+<!-- Slides
+Any section element inside of this "slides" container is displayed as a slide
+-->
+<div class="slides">
+<!-- Pandoc -->
+$if(title)$
+<section class="titlepage">
+<h1 class="title">$title$</h1>
+$for(author)$
+<h2 class="author">$author$</h2>
+$endfor$
+<h3 class="date">$date$</h3>
+</section>
+$endif$
+$body$
+<!-- End Pandoc -->
+
+</div>
+<!-- End Slides -->
+
+<!-- Presentation progress bar -->
+<div class="progress"><span></span></div>
+</div>
+
+<!-- Initialize reveal.js :: make settings changes here -->
+<script src="$reveal$/lib/js/head.min.js"></script>
+<script src="$reveal$/js/reveal.js"></script>
+
+<!-- ORIGINAL <script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+     -->
+
+<!-- LOCAL
+<script type="text/javascript" src="file:///Users/rjhala/research/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+-->
+
+<script type="text/javascript" src="$mathjax$/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+
+<script>		
+	// Full list of configuration options available here:
+	// https://github.com/hakimel/reveal.js#configuration
+	Reveal.initialize({
+		controls: true,
+		progress: true,
+		history: true,
+		center: false,
+        rollingLinks: false,
+        theme: Reveal.getQueryHash().theme || 'seminar', // available themes are in /css/theme
+		transition: Reveal.getQueryHash().transition || 'fade', // default/cube/page/concave/linear(2d)
+
+		// Optional libraries used to extend on reveal.js
+		dependencies: [
+			//{ src: '$reveal$/lib/js/highlight.js', async: true, callback: function() { window.hljs.initHighlightingOnLoad(); } },
+			{ src: '$reveal$/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+			{ src: '$reveal$/lib/js/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/lib/js/data-markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/socket.io/socket.io.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+			{ src: '$reveal$/plugin/speakernotes/client.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+		]
+	});
+</script>
+
+</body>
+</html>
diff --git a/docs/slides/ETH14/cleanup b/docs/slides/ETH14/cleanup
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/cleanup
@@ -0,0 +1,1 @@
+find . | grep -E -e '\.(smt2|bak|json|css|md|hi|out|fqout|fq|o|err|annot|log|html|cgi|liquid)$' | xargs rm -rf
diff --git a/docs/slides/ETH14/img/RedBlack.png b/docs/slides/ETH14/img/RedBlack.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/RedBlack.png differ
diff --git a/docs/slides/ETH14/img/minindex-classic.png b/docs/slides/ETH14/img/minindex-classic.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/minindex-classic.png differ
diff --git a/docs/slides/ETH14/img/minindex-invariant.png b/docs/slides/ETH14/img/minindex-invariant.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/minindex-invariant.png differ
diff --git a/docs/slides/ETH14/img/minindex-modern.png b/docs/slides/ETH14/img/minindex-modern.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/minindex-modern.png differ
diff --git a/docs/slides/ETH14/img/minindex-reduce.png b/docs/slides/ETH14/img/minindex-reduce.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/minindex-reduce.png differ
diff --git a/docs/slides/ETH14/img/tension0.png b/docs/slides/ETH14/img/tension0.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/tension0.png differ
diff --git a/docs/slides/ETH14/img/tension1.png b/docs/slides/ETH14/img/tension1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/tension1.png differ
diff --git a/docs/slides/ETH14/img/tension2.png b/docs/slides/ETH14/img/tension2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/tension2.png differ
diff --git a/docs/slides/ETH14/img/tension3.png b/docs/slides/ETH14/img/tension3.png
new file mode 100644
Binary files /dev/null and b/docs/slides/ETH14/img/tension3.png differ
diff --git a/docs/slides/ETH14/lhs/00_Motivation.lhs b/docs/slides/ETH14/lhs/00_Motivation.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/00_Motivation.lhs
@@ -0,0 +1,243 @@
+ {#asds}
+========
+
+Algorithmic Verification 
+------------------------
+
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+<br>
+<br>
+
+**Goal**
+
+<br>
+
+Automatically Proving Properties of Programs 
+
+Algorithmic Verification
+========================
+
+A Classic Example 
+-----------------
+
+<img src="../img/minindex-classic.png" height=300px>
+
+**Verify:** indices `i`, `min` are *within bounds* of `arr`
+
+A Classic Example 
+-----------------
+
+<img src="../img/minindex-classic.png" height=300px>
+
+Easy, use Program **Logic** + **Analysis**
+
+Program Logic 
+-------------
+
+<img src="../img/minindex-invariant.png" height=300px>
+
+-------------------   ----------------------------------------------------
+**Specification**     *Predicates* eg. invariants, pre-/post-conditions
+**Verification**      *Conditions* checked by SMT solver
+-------------------   ----------------------------------------------------
+
+Program Logic 
+-------------
+
+<br>
+
+-------------------   ----------------------------------------------------
+**Specification**     *Predicates* eg. invariants, pre-/post-conditions
+**Verification**      *Conditions* checked by SMT solver
+-------------------   ----------------------------------------------------
+
+<br>
+
+No invariants? **Inference** via Analysis...
+
+Program Analysis 
+----------------
+
+<br>
+
+**Invariants are Fixpoints of Reachable States**
+
+<br>
+
+Computable via *Dataflow Analysis* or *Abstract Interpretation*
+
+<br>
+
+Logic + Analysis 
+----------------
+
+<br>
+
+-------------------   ----------------------------------------------------
+**Specification**     *Predicates*, eg. invariants, pre-/post-conditions
+**Verification**      *Conditions* checked by SMT solver
+**Inference**         *Fixpoint* over abstract domain
+-------------------   ----------------------------------------------------
+
+<br>
+
+<div class="fragment">
+But ... limited to "classical" programs!
+</div>
+
+
+"Classical" vs. "Modern" Programs
+=================================
+
+
+ {#classicalvmodern}
+--------------------
+
+
+"Classical" Programs
+--------------------
+
+<br>
+
+<div class="fragment">
+**Imperative**
+
+Assignments, Branches, Loops
+</div>
+
+<br>
+
+<div class="fragment">
+**First-Order Functions**
+
+Recursion 
+</div>
+
+<br>
+
+<div class="fragment">
+**Objects**
+
+Classes, Inheritance*
+</div>
+
+
+"Modern" Programs
+-----------------
+
+
+<div class="fragment">
+**Containers**
+
+Arrays, Lists, HashMaps,...
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Polymorphism**
+
+Generics, Typeclasses...
+</div>
+
+<br>
+
+<div class="fragment">
+**Higher Order Functions**
+
+Callbacks, map, reduce, filter,...
+</div>
+
+
+A "Modern" Example 
+------------------
+
+<img src="../img/minindex-modern.png" height=300px>
+
+Verify indices `i`, `min` are *within bounds* of `arr`
+
+A "Modern" Example 
+------------------
+
+<img src="../img/minindex-modern.png" height=300px>
+
+Pose vexing challenges for Logic + Analysis
+
+Logic + Analysis Challenges
+----------------------------
+
+<img src="../img/minindex-modern.png" height=250px>
+
++ How to analyze **unbounded** contents of `arr`?
++ <div class="fragment">How to **summarize** `reduce` independent of `callback`?</div>
++ <div class="fragment">How to precisely reuse summary at each **context** ?</div>
+
+
+ {#motiv}
+=========
+
+Logic + Analysis + *Types*
+--------------------------
+
+
+Logic + Analysis + *Types*
+==========================
+
+
+Refinement Types
+----------------
+
+<br>
+
+Use **Types** to lift **Logic + Analysis** to Modern Programs 
+
+<br>
+
+<div class="fragment">
+
+-----   ----   ---   ----   -------------------   -------------------------------------------
+                            **Specification**     *Types* + Predicates 
+                            **Verification**      *Subtyping* + Verification Conditions
+                            **Inference**         *Type Inference* + Abstract Interpretation
+-----   ----   ---   ----   -------------------   -------------------------------------------
+
+<br>
+<br>
+
+[[continue]](01_SimpleRefinements.lhs.slides.html)
+
+</div>
+
+Refinement Types
+----------------
+
+
+
+<br>
+<br>
+
+Plan 
+----
+
++ <a href="01_SimpleRefinements.lhs.slides.html" target="_blank">Refinements</a>
++ <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
++ <div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target= "_blank">Higher-Order Functions</a></div>
++ <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements:</a><a href="06_Inductive.lhs.slides.html" target="_blank">Code</a>,<a href="07_Array.lhs.slides.html" target= "_blank">Data</a></div>
++ <div class="fragment"><a href="11_Evaluation.lhs.slides.html" target="_blank">Evaluation</a></div>
++ <div class="fragment"><a href="12_Conclusion.lhs.slides.html" target="_blank">Conclusion</a></div>
+
+<br>
+<br>
+
+
+
+<div class="fragment">[[continue...]](01_SimpleRefinements.lhs.slides.html)</div>
diff --git a/docs/slides/ETH14/lhs/01_SimpleRefinements.lhs b/docs/slides/ETH14/lhs/01_SimpleRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/01_SimpleRefinements.lhs
@@ -0,0 +1,831 @@
+ {#simplerefinements}
+=======================
+
+Simple Refinement Types
+-----------------------
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+module SimpleRefinements where
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (abs, max)
+
+-- boring haskell type sigs
+zero    :: Int
+zero'   :: Int
+safeDiv :: Int -> Int -> Int
+abs     :: Int -> Int
+nats    :: L Int
+range   :: Int -> Int -> L Int
+\end{code}
+
+</div>
+
+
+Simple Refinement Types
+=======================
+
+
+Types + Predicates 
+------------------
+
+
+Example: Integers equal to `0`
+------------------------------
+
+<br>
+
+\begin{code}
+{-@ type Zero = {v:Int | v = 0} @-}
+
+{-@ zero :: Zero @-}
+zero     =  0
+\end{code}
+
+<br>
+
+<div class="fragment">
+Refinement types via special comments `{-@ ... @-}` 
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo</a> 
+</div>
+
+
+
+Refinements Are Predicates
+==========================
+
+From A Decidable Logic
+----------------------
+
+<br> 
+
+1. Expressions
+
+2. Predicates
+
+<br>
+
+<div class="fragment">
+
+**Refinement Logic: QF-UFLIA**
+
+Quant.-Free. Uninterpreted Functions and Linear Arithmetic 
+
+</div>
+
+
+Expressions
+-----------
+
+<br>
+
+\begin{spec} <div/> 
+e := x, y, z,...    -- variable
+   | 0, 1, 2,...    -- constant
+   | (e + e)        -- addition
+   | (e - e)        -- subtraction
+   | (c * e)        -- linear multiplication
+   | (f e1 ... en)  -- uninterpreted function
+\end{spec}
+
+Predicates
+----------
+
+<br>
+
+\begin{spec} <div/>
+p := e           -- atom 
+   | e1 == e2    -- equality
+   | e1 <  e2    -- ordering 
+   | (p && p)    -- and
+   | (p || p)    -- or
+   | (not p)     -- negation
+\end{spec}
+
+<br>
+
+
+Refinement Types
+----------------
+
+
+<br>
+
+\begin{spec}<div/>
+b := Int 
+   | Bool 
+   | ...         -- base types
+   | a, b, c     -- type variables
+
+t := {x:b | p}   -- refined base 
+   | x:t -> t    -- refined function  
+\end{spec}
+
+
+Subtyping Judgment 
+------------------
+
+<br>
+
+$$\boxed{\Gamma \vdash t_1 \preceq t_2}$$
+
+<div class="fragment">
+
+<br>
+
+Where **environment** $\Gamma$ is a sequence of binders
+
+<br>
+
+$$\Gamma \defeq \overline{\bindx{x_i}{t_i}}$$
+
+</div>
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+[PVS' Predicate Subtyping](http://pvs.csl.sri.com/papers/subtypes98/tse98.pdf)
+
+<br>
+
+(For **Base** Types ...)
+
+
+
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+$$
+\begin{array}{rl}
+{\mathbf{If\ VC\ is\ Valid}}   & \bigwedge_i P_i \Rightarrow  Q  \Rightarrow R \\
+                & \\
+{\mathbf{Then}} & \overline{\bindx{x_i}{P_i}} \vdash \reft{v}{b}{Q} \subty \reft{v}{b}{R} \\
+\end{array}
+$$ 
+
+
+Example: Natural Numbers
+------------------------
+
+<br>
+
+\begin{spec} <div/>  
+        type Nat = {v:Int | 0 <= v}
+\end{spec}
+
+<br>
+
+<div class="fragment">
+
+$$
+\begin{array}{rcrccll}
+\mathbf{VC\ is\ Valid:} & \True     & \Rightarrow &  v = 0   & \Rightarrow &  0 \leq v & \mbox{(by SMT)} \\
+%                &           &             &          &             &           \\
+\mathbf{So:}      & \emptyset & \vdash      & \Zero  & \subty      & \Nat   &   \\
+\end{array}
+$$
+</div>
+
+<br>
+
+<div class="fragment">
+
+Hence, we can type:
+
+\begin{code}
+{-@ zero' :: Nat @-}
+zero'     =  zero   -- zero :: Zero <: Nat
+\end{code}
+</div>
+
+Contracts: Function Types
+=========================
+
+ {#as}
+------
+
+Pre-Conditions
+--------------
+
+
+<br>
+
+\begin{code}
+safeDiv n d = n `div` d   -- crashes if d==0
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Requires** non-zero input divisor `d`
+
+\begin{code}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+\end{code}
+</div>
+
+<br>
+
+
+<div class="fragment">
+Specify pre-condition as **input type** 
+
+\begin{code}
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{code}
+
+</div>
+
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code}
+{-@ bad :: Nat -> Int @-}
+bad n   = 10 `safeDiv` n
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Rejected As** 
+
+$$\bindx{n}{\Nat} \vdash \reftx{v}{v = n} \not \subty \reftx{v}{v \not = 0}$$
+
+</div>
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code}
+{-@ ok  :: Nat -> Int @-}
+ok n    = 10 `safeDiv` (n+1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Verifies As** 
+
+$\bindx{n}{\Nat} \vdash \reftx{v}{v = n+1} \subty \reftx{v}{v \not = 0}$
+</div>
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{spec} <div/>
+{-@ ok  :: Nat -> Int @-}
+ok n    = 10 `safeDiv` (n+1)
+\end{spec}
+
+<br>
+
+**Verifies As**
+
+$$(0 \leq n) \Rightarrow (v = n+1) \Rightarrow (v \not = 0)$$
+
+
+
+Post-Conditions
+---------------
+
+**Ensures** output is a `Nat` greater than input `x`.
+
+\begin{code}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{code}
+
+<br>
+
+<div class="fragment">
+Specify post-condition as **output type**
+
+\begin{code}
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+**Dependent Function Types**
+
+Outputs *refer to* inputs
+</div>
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+Postcondition is checked at **return-site**
+
+<br>
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+**Verified As**
+
+<br>
+
+$$\begin{array}{rll}
+\bindx{x}{\Int},\bindx{\_}{0 \leq x}      & \vdash \reftx{v}{v = x}     & \subty \reftx{v}{0 \leq v \wedge x \leq v} \\
+\bindx{x}{\Int},\bindx{\_}{0 \not \leq x} & \vdash \reftx{v}{v = 0 - x} & \subty \reftx{v}{0 \leq v \wedge x \leq v} \\
+\end{array}$$
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+**Verified As**
+
+<br>
+
+$$\begin{array}{rll}
+(0 \leq x)      & \Rightarrow (v = x)     & \Rightarrow (0 \leq v \wedge x \leq v) \\
+(0 \not \leq x) & \Rightarrow (v = 0 - x) & \Rightarrow (0 \leq v \wedge x \leq v) \\
+\end{array}$$
+
+
+ {#inference}
+=============
+
+From Checking To Inference
+--------------------------
+
+<br>
+<br>
+
+**So far**
+
+How to **check** code against given signature
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+How to **infer** signatures from code
+
+</div>
+
+From Checking To Inference
+--------------------------
+
+<br>
+<br>
+
+
+**2-Phase Process**
+
+<div class="fragment">
+
+<br>
+
+1. Hindley-Milner infers **types**
+2. Abstract Interpr. infers **refinements**  
+
+</div>
+
+<br>
+
+<div class="fragment">Lets quickly look at 2. </div>
+
+
+
+From Checking To Inference
+==========================
+
+
+Recipe
+------
+
+<br>
+
+<div class="fragment">
+
+**Step 1. Templates**
+
+Types with variables $\kvar{}$ for *unknown* refinements
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Step 2. Constraints**
+
+Typecheck templates: VCs $\rightarrow$ Horn *constraints* over $\kvar{}$
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Step 3. Solve**
+
+Via *least-fixpoint* over suitable abstract domain
+
+</div>
+
+Step 1. Templates (`abs`)
+-------------------------
+
+<br>
+
+<div class="fragment">
+**Type**
+
+$$\bindx{x}{\Int} \rightarrow \Int$$
+</div>
+
+<br>
+
+<div class="fragment">
+**Template**
+
+$$\ereft{x}{\Int}{\kvar{1}} \rightarrow \reft{v}{\Int}{\kvar{2}}$$
+</div>
+
+Step 2. Constraints (`abs`)
+-------------------------
+
+<br>
+
+Step 2. Constraints (`abs`)
+-------------------------
+
+<br>
+
+**Subtyping Queries**
+
+<br>
+
+$$
+\begin{array}{rll}
+\bindx{x}{\kvar{1}},\bindx{\_}{0 \leq x}      & \vdash \reftx{v}{v = x}     & \subty \reftx{v}{\kvar{2}} \\
+\bindx{x}{\kvar{1}},\bindx{\_}{0 \not \leq x} & \vdash \reftx{v}{v = 0 - x} & \subty \reftx{v}{\kvar{2}} \\
+\end{array}
+$$
+
+Step 2. Constraints (`abs`)
+-------------------------
+
+<br>
+
+**Verification Conditions**
+
+<br>
+
+$$\begin{array}{rll}
+{\kvar{1}} \wedge (0 \leq x)      & \Rightarrow (v = x)     & \Rightarrow \kvar{2} \\
+{\kvar{1}} \wedge (0 \not \leq x) & \Rightarrow (v = 0 - x) & \Rightarrow \kvar{2} \\
+\end{array}$$
+
+
+Step 2. Constraints (`abs`)
+-------------------------
+
+<br>
+
+**Horn Constraints** over $\kvar{}$
+
+<br>
+
+$$\begin{array}{rll}
+{\kvar{1}} \wedge (0 \leq x)      & \Rightarrow (v = x)     & \Rightarrow \kvar{2} \\
+{\kvar{1}} \wedge (0 \not \leq x) & \Rightarrow (v = 0 - x) & \Rightarrow \kvar{2} \\
+\end{array}$$
+
+<br>
+<br>
+
+**Note:** $\kvar{}$ occur positively, hence constraints are monotone.
+
+Step 3. Solve (`abs`)
+---------------------
+
+<br>
+
+Least-fixpoint over abstract domain 
+
+<br>
+
+Step 3. Solve (`abs`)
+---------------------
+
+**Predicate Abstraction**
+
+Conjunction of predicates from (finite) ground set $\quals$
+
+<br>
+
+<div class="fragment">
+$$\mbox{e.g.}\ \quals \defeq \{ c \sim X \}$$
+
+<br>
+
+$$\begin{array}{ccll}
+  c     & \in & \{0,1,\ldots   \}                & \mbox{program constants} \\
+  X     & \in & \{n,x,v,\ldots \}                & \mbox{program variables} \\
+  \sim  & \in & \{<, \leq, >, \geq, =, \not =\}  & \mbox{comparisons}       \\
+  \end{array}$$
+
+</div>
+
+Step 3. Solve (`abs`)
+---------------------
+
+Least-fixpoint over abstract domain 
+
+<br>
+
+**Predicate Abstraction**
+
+Conjunction of predicates from (finite) ground set $\quals$
+
+<br>
+
++ Obtain $\quals$ via CEGAR
++ Or use other domains
+
+<br>
+
+[[Houdini](http://dl.acm.org/citation.cfm?id=730008), [HMC](http://goto.ucsd.edu/~rjhala/papers/hmc.html)]
+
+
+Recipe Scales Up
+----------------
+
+<br>
+
+**1. Templates** $\rightarrow$ **2. Horn Constraints** $\rightarrow$ **3. Fixpoint**
+
+<br>
+
+<div class="fragment">
++ Define type *checker* and get *inference* for free 
+
++ Scales to Collections, HOFs, Polymorphism
+
+</div>
+<br>
+
+<div class="fragment">
+**Next:** Collections
+</div>
+
+<!--
+<div class="fragment">
+**Key Requirement** 
+
+Refinements belong in abstract domain, e.g. QF-UFLIA
+</div>
+-->
+
+
+ {#universalinvariants}
+=======================
+
+Types = Universal Invariants
+----------------------------
+
+(Notoriously hard with *pure* SMT)
+
+Types Yield Universal Invariants
+================================
+
+Example: Lists
+--------------
+
+
+<div class="hidden">
+\begin{code}
+infixr `C`
+\end{code}
+</div>
+
+
+<br>
+
+
+\begin{code}
+data L a = N          -- Empty 
+         | C a (L a)  -- Cons 
+\end{code}
+
+
+<br>
+
+<div class="fragment">
+
+How to **specify** every element in `nats` is non-negative?
+
+\begin{code}
+nats     =  0 `C` 1 `C` 3 `C` N
+\end{code}
+</div>
+
+
+Example: Lists
+--------------
+
+<br>
+
+How to **specify** every element in `nats` is non-negative?
+
+\begin{spec} 
+nats     =  0 `C` 1 `C` 2 `C` N
+\end{spec}
+
+<br>
+
+**Logic**
+
+$$\forall x \in \mathtt{nats}. 0 \leq x$$
+
+<br>
+
+<div class="fragment">
+VCs over **quantified formulas** ... *challenging* for SMT
+</div>
+
+
+Example: Lists
+--------------
+
+<br>
+
+How to **specify** every element in `nats` is non-negative?
+
+\begin{spec} 
+nats     =  0 `C` 1 `C` 2 `C` N
+\end{spec}
+
+<br>
+
+**Refinement Types**
+
+\begin{code}
+{-@ nats :: L Nat @-}
+\end{code}
+
+<br>
+
++ <div class="fragment">Type *implicitly* has quantification</div>
++ <div class="fragment">Sub-typing *eliminates* quantifiers</div>
++ <div class="fragment">Robust verification via *quantifier-free* VCs</div>
+
+Example: Lists
+--------------
+
+How to **verify** ? 
+
+\begin{spec} <div/>
+{-@ nats :: L Nat @-}
+nats   = l0
+  where
+    l0 = 0 `C` l1  -- Nat `C` L Nat >>> L Nat
+    l1 = 1 `C` l2  -- Nat `C` L Nat >>> L Nat
+    l2 = 2 `C` l3  -- Nat `C` L Nat >>> L Nat
+    l3 = N         -- L Nat
+\end{spec}
+
+<br>
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s **between** `i` and `j`
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s **between** `i` and `j`
+
+<br>
+
+\begin{code}
+{-@ type Btwn I J = { v:_ | I<=v && v<J } @-}
+\end{code}
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+<br>
+
+\begin{code}
+{-@ range :: i:Int -> j:Int -> L (Btwn i j) @-}
+range i j            = go i
+  where
+    go n | n < j     = n `C` go (n + 1)  
+         | otherwise = N
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Note:** Type of `go` is automatically inferred
+</div>
+
+
+Example: Indexing Into List
+---------------------------
+
+\begin{code} 
+(!)          :: L a -> Int -> a
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "Oops!"
+\end{code}
+
+<br>
+
+<div class="fragment">(Mouseover to view type of `liquidError`)</div>
+
+<br>
+
+<div class="fragment">To ensure safety, *require* `i` between `0` and list **length**</div>
+
+<br>
+
+<div class="fragment">Need way to **measure** the length of a list [[continue...]](02_Measures.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/ETH14/lhs/02_Measures.lhs b/docs/slides/ETH14/lhs/02_Measures.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/02_Measures.lhs
@@ -0,0 +1,309 @@
+
+ {#measures}
+============
+
+Measuring Data Types
+--------------------
+
+<div class="hidden">
+
+\begin{code}
+
+{-# LIQUID "--no-termination" #-}
+{-# LIQUID "--full" #-}
+
+module Measures where
+import Prelude hiding ((!!), length)
+import Language.Haskell.Liquid.Prelude
+
+
+length      :: L a -> Int
+(!)         :: L a -> Int -> a
+insert      :: Ord a => a -> L a -> L a
+insertSort  :: Ord a => [a] -> L a
+
+infixr `C`
+\end{code}
+
+</div>
+
+
+Measuring Data Types 
+====================
+
+Recap
+-----
+
+1. <div class="fragment">**Refinements:** Types + Predicates</div>
+2. <div class="fragment">**Subtyping:** SMT Implication</div>
+
+
+Example: Length of a List 
+-------------------------
+
+Given a type for lists:
+
+<br>
+
+\begin{code}
+data L a = N | C a (L a)
+\end{code}
+
+<div class="fragment">
+<br>
+
+We can define the **length** as:
+
+<br>
+
+\begin{code}
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+\end{code}
+
+<div class="hidden">
+
+\begin{code}
+{-@ data L [llen] a = N | C {hd :: a, tl :: L a } @-}
+{-@ invariant {v: L a | 0 <= llen v}              @-} 
+\end{code}
+
+</div>
+
+Example: Length of a List 
+-------------------------
+
+\begin{spec}
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + llen xs  @-}
+\end{spec}
+
+<br>
+
+We **strengthen** data constructor types
+
+<br>
+
+\begin{spec} <div/>
+data L a where 
+  N :: {v: L a | (llen v) = 0}
+  C :: a -> t:_ -> {v:_| llen v = 1 + llen t}
+\end{spec}
+
+Measures Are Uninterpreted
+--------------------------
+
+\begin{spec} <br>
+data L a where 
+  N :: {v: L a | (llen v) = 0}
+  C :: a -> t:_ -> {v:_| llen v = 1 + llen t}
+\end{spec}
+
+<br>
+
+`llen` is an **uninterpreted function** in SMT logic
+
+Measures Are Uninterpreted
+--------------------------
+
+<br>
+
+In SMT, [uninterpreted function](http://fm.csl.sri.com/SSFT12/smt-euf-arithmetic.pdf) $f$ obeys **congruence** axiom:
+
+<br>
+
+$$\forall \overline{x}, \overline{y}. \overline{x} = \overline{y} \Rightarrow
+f(\overline{x}) = f(\overline{y})$$
+
+<br>
+
+<div class="fragment">
+Other properties of `llen` asserted when typing **fold** & **unfold**
+</div>
+
+<br>
+
+<div class="fragment">
+Crucial for *efficient*, *decidable* and *predictable* verification.
+</div>
+
+Measures Are Uninterpreted
+--------------------------
+
+Other properties of `llen` asserted when typing **fold** & **unfold**
+
+<br>
+
+<div class="fragment">
+\begin{spec}**Fold**<br>
+z = C x y     -- z :: {v | llen v = 1 + llen y}
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{spec}**Unfold**<br>
+case z of 
+  N     -> e1 -- z :: {v | llen v = 0}
+  C x y -> e2 -- z :: {v | llen v = 1 + llen y}
+\end{spec}
+</div>
+
+
+Measured Refinements
+--------------------
+
+Now, we can verify:
+
+<br>
+
+\begin{code}
+{-@ length      :: xs:L a -> EqLen xs @-}
+length N        = 0
+length (C _ xs) = 1 + length xs
+\end{code}
+
+<div class="fragment">
+
+<br>
+
+Where `EqLen` is a type alias:
+
+\begin{code}
+{-@ type EqLen Xs = {v:Nat | v = llen Xs} @-}
+\end{code}
+
+</div>
+
+List Indexing Redux
+-------------------
+
+We can type list lookup:
+
+\begin{code}
+{-@ (!)      :: xs:L a -> LtLen xs -> a @-}
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "never happens!"
+\end{code}
+
+<br>
+
+<div class="fragment">
+Where `LtLen` is a type alias:
+
+\begin{code}
+{-@ type LtLen Xs = {v:Nat | v < llen Xs} @-}
+\end{code}
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellMeasure.hs" target= "_blank">Demo:</a> 
+&nbsp; What if we *remove* the precondition?
+
+</div>
+
+Multiple Measures
+-----------------
+
+<br>
+
+**Multiple** measures by **conjoining** refinements.
+
+<br>
+
+<div class="fragment">
+
+e.g. Red Black Tree
+
++ Height
++ Color
++ Nodes, etc.
+
+<br>
+
+Refined Data Constructors
+=========================
+
+ {#refined-data-cons}
+---------------------
+
+Can encode *other* invariants **inside constructors**
+
+<div class="fragment">
+
+<br>
+
+\begin{code}
+{-@ data L a = N
+             | C { x  :: a 
+                 , xs :: L {v:a| x <= v} } @-}
+\end{code}
+</div>
+<br>
+
+<div class="fragment">
+Head `x` is less than **every** element of tail `xs`
+</div>
+
+<br>
+
+<div class="fragment">
+i.e. specifies **increasing** Lists 
+</div>
+
+Increasing Lists 
+----------------
+
+\begin{spec} <br>
+data L a where
+  N :: L a
+  C :: x:a -> xs: L {v:a | x <= v} -> L a
+\end{spec}
+
+<br>
+
+- <div class="fragment">We **check** property when **folding** `C`</div>
+- <div class="fragment">We **assume** property when **unfolding** `C`</div>
+
+Increasing Lists 
+----------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellInsertSort.hs" target= "_blank">Demo: Insertion Sort</a> (hover for inferred types) 
+
+<br>
+
+\begin{code}
+insertSort xs = foldr insert N xs
+
+insert y (x `C` xs) 
+  | y <= x    = y `C` (x `C` xs)
+  | otherwise = x `C` insert y xs
+insert y N    = y `C` N    
+\end{code}
+
+<br>
+
+Recap
+-----
+
+<br>
+<br>
+
+
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. **Measures:** Strengthened Constructors
+
+<br>
+
+<div class="fragment">Logic + Analysis for Collections</div>
+
+<br>
+<br>
+
+<div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target="_blank">[continue]</a></div>
diff --git a/docs/slides/ETH14/lhs/03_HigherOrderFunctions.lhs b/docs/slides/ETH14/lhs/03_HigherOrderFunctions.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/03_HigherOrderFunctions.lhs
@@ -0,0 +1,276 @@
+  {#hofs}
+=========
+
+<div class="hidden">
+\begin{code}
+module Loop (
+    listSum
+  , sumNats
+  ) where
+
+import Prelude
+
+{-@ LIQUID "--no-termination"@-}
+sumNats  :: [Int] -> Int
+add         :: Int -> Int -> Int
+\end{code}
+</div>
+
+Higher-Order Functions 
+----------------------
+
+Types scale to *Higher-Order Functions*  
+
+<br>
+
+<div class="fragment">
+
++ map
++ fold
++ visitors
++ callbacks
++ ...
+
+</div>
+
+<br>
+
+<div class="fragment">Difficult with *first-order program logics*</div>
+
+
+Higher Order Specifications 
+===========================
+
+Example: Higher Order Loop
+--------------------------
+
+<br>
+
+\begin{code}
+loop :: Int -> Int -> α -> (Int -> α -> α) -> α
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+By subtyping, we infer `f` called with values `(Btwn lo hi)`
+
+
+Example: Summing Lists
+----------------------
+
+\begin{code}
+listSum xs     = loop 0 n 0 body 
+  where 
+    body i acc = acc + (xs !! i)
+    n          = length xs
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Function Subtyping** 
+
+\begin{spec}
+loop :: l -> h -> α -> (Btwn l h -> α -> α) -> α
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+At callsite, since `l := 0` and `h := llen xs` 
+
+\begin{spec}
+body :: Btwn 0 (llen xs) -> Int -> Int
+\end{spec}
+</div>
+
+Example: Summing Lists
+----------------------
+
+\begin{spec}
+listSum xs     = loop 0 n 0 body 
+  where 
+    body i acc = acc + (xs !! i)
+    n          = length xs
+\end{spec}
+
+<br>
+
+**Function Subtyping** 
+
+\begin{spec}
+body :: Btwn 0 (llen xs) -> Int -> Int
+\end{spec}
+
+<br>
+
+So `i` is `Btwn 0 (llen xs)`; indexing `!!` is verified safe.
+
+
+ {#polyinst}
+============
+
+Polymorphic Instantiation
+-------------------------
+
+<br>
+<br>
+<br>
+
+<div class="fragment">
+"Plugging in" summaries at call-sites
+</div>
+
+Polymorphic Instantiation
+=========================
+
+ {#poly}
+--------
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{code}
+{-@ sumNats :: [Nat] -> Nat @-}
+sumNats xs  = foldl (+) 0 xs 
+\end{code}
+
+<br>
+
+<div class="fragment">
+\begin{spec} Recall 
+foldl :: (α -> β -> α) -> α -> [β] -> α
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+How to **instantiate** `α` and `β` ?
+</div>
+
+Function Subtyping
+------------------
+
+\begin{spec}<div/>
+(+) ::  x:Int -> y:Int -> {v:Int|v=x+y} 
+    <:  Nat   -> Nat   -> Nat
+\end{spec}
+
+<br>
+
+<div class="fragment">
+Because,
+
+\begin{spec}<div/>
+             |- Nat       <: Int  -- Contra (in)
+x:Nat, y:Nat |- {v = x+y} <: Nat  -- Co    (out)
+\end{spec}
+</div>
+
+<br>
+
+<div class="fragment">
+Because,
+
+\begin{spec}<div/>
+  0<=x && 0<=y && v = x+y   => 0 <= v
+\end{spec}
+</div>
+
+
+
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{spec} <div/> 
+{-@ sumNats :: [Nat] -> Nat @-}
+sumNats xs  = foldl (+) 0 xs 
+\end{spec}
+
+<br>
+
+\begin{spec} Where:
+foldl :: (α -> β -> α) -> α -> [β] -> α
+(+)   :: Nat -> Nat -> Nat
+\end{spec}
+
+<br>
+
+<div class="fragment">
+Hence, `sumNats` verified by **instantiating** `α,β := Nat`
+</div>
+
+<br>
+
+<div class="fragment">
+`α` is **loop invariant**, instantiation is invariant **inference**
+</div>
+
+Instantiation And Inference
+---------------------------
+
+Polymorphism ubiquitous, so inference is critical!
+
+<br>
+
+<div class="fragment">
+**Step 1. Templates** 
+Instantiate with unknown refinements
+
+$$
+\begin{array}{rcl}
+\alpha & \defeq & \reft{v}{\Int}{\kvar{\alpha}}\\
+\beta  & \defeq & \reft{v}{\Int}{\kvar{\beta}}\\
+\end{array}
+$$
+</div>
+
+<br>
+<div class="fragment">
+**Step 2. Horn-Constraints** 
+By type checking the templates
+</div>
+
+<br>
+<div class="fragment">
+**Step 3. Fixpoint** 
+Abstract interpretation to get solution for $\kvar{}$
+</div>
+
+
+Iteration Dependence
+--------------------
+
+**Problem:** Cannot use parametric polymorphism to verify
+
+<br>
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+As property only holds after **last iteration** ...
+
+<br>
+
+... cannot instantiate $\alpha \defeq \reft{v}{\Int}{v = n + m}$
+</div>
+
+<br>
+
+<div class="fragment">
+**Problem:** *Iteration-dependent* invariants...? &nbsp; &nbsp; [[Continue]](04_AbstractRefinements.lhs.slides.html)
+</div>
+
diff --git a/docs/slides/ETH14/lhs/04_AbstractRefinements.lhs b/docs/slides/ETH14/lhs/04_AbstractRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/04_AbstractRefinements.lhs
@@ -0,0 +1,285 @@
+  {#abstractrefinements}
+========================
+
+<div class="hidden">
+
+\begin{code}
+module AbstractRefinements where
+
+import Prelude 
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+-- o,no        :: Int
+maxInt       :: Int -> Int -> Int
+\end{code}
+</div>
+
+
+
+Abstract Refinements
+--------------------
+
+
+Abstract Refinements
+====================
+
+A Tricky Problem
+----------------
+
+<br>
+
+<div class="fragment">
+
+**Problem** 
+
+Require *context-dependent* invariants & summaries for HOFs.
+
+</div>
+
+<br>
+<br>
+
+<div class="fragment">
+
+**Example** 
+
+How to summarize *iteration-dependence* for higher-order `loop`?
+
+</div>
+
+
+
+
+Problem Is Pervasive
+--------------------
+
+Lets distill it to a simple example...
+
+<div class="fragment">
+
+<br>
+
+(First, a few aliases)
+
+<br>
+
+\begin{code}
+{-@ type Odd  = {v:Int | (v mod 2) = 1} @-}
+{-@ type Even = {v:Int | (v mod 2) = 0} @-}
+\end{code}
+
+</div>
+
+
+Example: `maxInt` 
+-----------------
+
+Compute the larger of two `Int`s:
+
+\begin{spec} <br> 
+maxInt     :: Int -> Int -> Int 
+maxInt x y = if y <= x then x else y
+\end{spec}
+
+
+
+Example: `maxInt` 
+-----------------
+
+Has **many incomparable** refinement types/summaries
+
+\begin{spec}<br>
+maxInt :: Nat  -> Nat  -> Nat
+maxInt :: Even -> Even -> Even
+maxInt :: Odd  -> Odd  -> Odd 
+\end{spec}
+
+<br>
+
+<div class="fragment">*Which* should we use?</div>
+
+
+Refinement Polymorphism 
+-----------------------
+
+`maxInt` returns **one of** its two inputs `x` and `y` 
+
+<div class="fragment">
+
+<div align="center">
+
+<br>
+
+---------   ---   -------------------------------------------
+   **If**    :    the *inputs* satisfy a property  
+
+ **Then**    :    the *output* satisfies that property
+---------   ---   -------------------------------------------
+
+<br>
+
+</div>
+</div>
+
+<div class="fragment">Above holds **for all properties**!</div>
+
+<br>
+
+<div class="fragment"> 
+
+**Need to abstract properties over types**
+
+</div>
+
+Parametric Refinements 
+----------------------
+
+Enable *quantification over refinements* ...
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">Type says: **for any** `p` that is a property of `Int`, </div>
+
+- <div class="fragment">`max` **takes** two `Int`s that satisfy `p`,</div>
+
+- <div class="fragment">`max` **returns** an `Int` that satisfies `p`.</div>
+
+Parametric Refinements 
+----------------------
+
+Enable *quantification over refinements* ...
+
+<br>
+
+\begin{spec}<div/>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{spec}
+
+<br>
+
+[Key idea: ](http://goto.ucsd.edu/~rjhala/papers/abstract_refinement_types.html)
+&nbsp; `Int<p>` &nbsp; is just  &nbsp; $\reft{v}{\Int}{p(v)}$ 
+
+<br>
+
+Abstract Refinement is **uninterpreted function** in SMT logic
+
+Parametric Refinements 
+----------------------
+
+\begin{spec}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{spec}
+
+<br>
+
+**Check Implementation via SMT**
+
+Parametric Refinements 
+----------------------
+
+\begin{spec}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{spec}
+
+<br>
+
+**Check Implementation via SMT**
+
+<br>
+
+$$\begin{array}{rll}
+\ereft{x}{\Int}{p(x)},\ereft{y}{\Int}{p(y)} & \vdash \reftx{v}{v = y} & \subty \reftx{v}{p(v)} \\
+\ereft{x}{\Int}{p(x)},\ereft{y}{\Int}{p(y)} & \vdash \reftx{v}{v = x} & \subty \reftx{v}{p(v)} \\
+\end{array}$$
+
+Parametric Refinements 
+----------------------
+
+\begin{spec}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{spec}
+
+<br>
+
+**Check Implementation via SMT**
+
+<br>
+
+$$\begin{array}{rll}
+{p(x)} \wedge {p(y)} & \Rightarrow {v = y} & \Rightarrow {p(v)} \\
+{p(x)} \wedge {p(y)} & \Rightarrow {v = x} & \Rightarrow {p(v)} \\
+\end{array}$$
+
+
+Using Abstract Refinements
+--------------------------
+
+- <div class="fragment">**If** we call `maxInt` with args satisfying *common property*,</div>
+- <div class="fragment">**Then** `p` instantiated property, *result* gets same property.</div>
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ xo :: Odd  @-}
+xo = maxInt 3 7     -- p := \v -> Odd v 
+
+{-@ xe :: Even @-}
+xe = maxInt 2 8     -- p := \v -> Even v 
+\end{code}
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Infer Instantiation by Liquid Typing**
+
+At call-site, instantiate `p` with unknown $\kvar{p}$ and solve!
+</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. **Abstract Refinements** over Types
+
+<br>
+<br>
+
+<div class="fragment">
+  Abstract Refinements decouple invariants from **code** ...
+
+<br>
+
+<a href="06_Inductive.lhs.slides.html" target="_blank">[continue]</a>
+</div>
+
diff --git a/docs/slides/ETH14/lhs/05_Composition.lhs b/docs/slides/ETH14/lhs/05_Composition.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/05_Composition.lhs
@@ -0,0 +1,161 @@
+Abstract Refinements {#composition}
+===================================
+
+Very General Mechanism 
+----------------------
+
+**Next:** Lets add parameters...
+
+<div class="hidden">
+\begin{code}
+module Composition where
+
+import Prelude hiding ((.))
+
+plus     :: Int -> Int -> Int
+plus3'   :: Int -> Int
+\end{code}
+</div>
+
+
+Example: `plus`
+---------------
+
+\begin{code}
+{-@ plus :: x:_ -> y:_ -> {v:_ | v=x+y} @-}
+plus x y = x + y
+\end{code}
+
+
+Example: `plus 3` 
+-----------------
+
+<br>
+
+\begin{code}
+{-@ plus3' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3'     = plus 3
+\end{code}
+
+<br>
+
+Easily verified by LiquidHaskell
+
+A Composed Variant
+------------------
+
+Lets define `plus3` by *composition*
+
+A Composition Operator 
+----------------------
+
+\begin{code}
+(#) :: (b -> c) -> (a -> b) -> a -> c
+(#) f g x = f (g x)
+\end{code}
+
+
+`plus3` By Composition
+-----------------------
+
+\begin{code}
+{-@ plus3'' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3''     = plus 1 # plus 2
+\end{code}
+
+<br>
+
+Yikes! Verification *fails*. But why?
+
+<br>
+
+<div class="fragment">(Hover mouse over `#` for a clue)</div>
+
+How to type compose (#) ? 
+-------------------------
+
+This specification is *too weak* <br>
+
+\begin{spec} <br>
+(#) :: (b -> c) -> (a -> b) -> (a -> c)
+\end{spec}
+
+<br>
+
+Output type does not *relate* `c` with `a`!
+
+How to type compose (.) ?
+-------------------------
+
+Write specification with abstract refinement type:
+
+<br>
+
+\begin{code}
+{-@ (.) :: forall <p :: b->c->Prop, 
+                   q :: a->b->Prop>.
+             f:(x:b -> c<p x>) 
+          -> g:(x:a -> b<q x>) 
+          -> y:a -> exists[z:b<q y>].c<p z>
+ @-}
+(.) f g y = f (g y)
+\end{code}
+
+Using (.) Operator 
+------------------
+
+<br>
+
+\begin{code}
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br>
+
+<div class="fragment">*Verifies!*</div>
+
+
+Using (.) Operator 
+------------------
+
+\begin{spec} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{spec}
+
+<br>
+
+LiquidHaskell *instantiates*
+
+- `p` with `\x -> v = x + 1`
+- `q` with `\x -> v = x + 2`
+
+Using (.) Operator 
+------------------
+
+\begin{spec} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{spec}
+
+<br> To *infer* that output of `plus3` has type: 
+
+`exists [z:{v = y + 2}].{v = z + 1}`
+
+<div class="fragment">
+
+`<:`
+
+`{v:Int|v=3}`
+</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract:** Refinements over Type Signatures
+    + <div class="fragment">*Dependencies* using refinement parameters</div>
diff --git a/docs/slides/ETH14/lhs/06_Inductive.lhs b/docs/slides/ETH14/lhs/06_Inductive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/06_Inductive.lhs
@@ -0,0 +1,491 @@
+Abstract Refinements {#induction}
+=================================
+
+Decoupling Invariants & Code
+----------------------------
+
++ Abstract refinements deoouple invariants from code
+
++ Yield precise, reusable **summaries** of HOFs
+
+Recall: Tricky Problem
+----------------------
+
+<br>
+
+<div class="fragment">
+
+**Problem** 
+
+Require *context-dependent* invariants & summaries for HOFs.
+
+</div>
+
+<br>
+<br>
+
+<div class="fragment">
+
+**A Solution** 
+
+Decoupled invariants yield *precise* & *reusable* summaries
+
+
+
+</div>
+
+
+
+
+<div class="hidden">
+
+\begin{code}
+module Loop where
+import Prelude hiding ((!!), foldr, length, (++))
+-- import Measures
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+
+size  :: L a -> Int
+add   :: Int -> Int -> Int
+loop  :: Int -> Int -> α -> (Int -> α -> α) -> α
+foldr :: (L a -> a -> b -> b) -> b -> L a -> b
+\end{code}
+</div>
+
+Induction
+=========
+
+Example: `loop` redux 
+---------------------
+
+Recall the *higher-order* `loop` 
+
+<br>
+
+\begin{code}
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{spec} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{spec}
+
+<br>
+
+<div class="fragment">
+
+**Problem**
+
+- As property only holds after *last* loop iteration...
+
+- ... cannot instantiate `α` with `{v:Int | v = n + m}`
+
+</div>
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{spec} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{spec}
+
+<br>
+
+**Problem** 
+
+Need invariant relating *iteration* `i` with *accumulator* `acc`
+
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{spec} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{spec}
+
+<br>
+
+**Solution** 
+
+- Abstract Refinement `p :: Int -> a -> Prop`
+
+- `(p i acc)` relates *iteration* `i` with *accumulator* `acc`
+
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{spec} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{spec}
+
+<br>
+
+<div class="fragment">
+<div align="center">
+
+------------  ---   ----------------------------
+  **Assume**   :    `out = loop lo hi base f` 
+
+   **Prove**   :    `(p hi out)`
+------------  ---   ----------------------------
+
+</div>
+</div>
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{spec} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{spec}
+
+<br>
+
+**Base Case:** &nbsp; Initial accumulator `base` satisfies invariant
+
+
+`(p lo base)`   
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{spec} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{spec}
+
+<br>
+
+**Inductive Step:** &nbsp; `f` *preserves* invariant at `i`
+
+
+`(p i acc) => (p (i+1) (f i acc))`
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{spec} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{spec}
+
+<br>
+
+**"By Induction"** &nbsp; `out` satisfies invariant at `hi` 
+
+`(p hi out)`
+
+
+Induction in `loop` (by type)
+-----------------------------
+
+Induction is an **abstract refinement type** for `loop` 
+
+<br>
+
+\begin{code}
+{-@ loop :: forall a <p :: Int -> a -> Prop>.
+        lo:Int
+     -> hi:{Int | lo <= hi}
+     -> base:a<p lo>                      
+     -> f:(i:Int -> a<p i> -> a<p (i+1)>) 
+     -> a<p hi>                           @-}
+\end{code}
+
+<br>
+
+Induction in `loop` (by type)
+-----------------------------
+
+`p` is the *index dependent* invariant!
+
+
+\begin{spec}<br> 
+p    :: Int -> a -> Prop             -- invt 
+base :: a<p lo>                      -- base 
+f    :: i:Int -> a<p i> -> a<p(i+1)> -- step
+out  :: a<p hi>                      -- goal
+\end{spec}
+
+
+
+Using Induction
+---------------
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br>
+
+**Verified** by *instantiating* the abstract refinement of `loop`
+
+`p := \i acc -> acc = i + n`
+
+
+<!--
+
+Using Induction
+---------------
+
+\begin{spec} <div/>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{spec}
+
+<br>
+
+Verified by instantiating `p := \i acc -> acc = i + n`
+
+- <div class="fragment">**Base:**  `n = 0 + n`</div>
+
+- <div class="fragment">**Step:**  `acc = i + n  =>  acc + 1 = (i + 1) + n`</div>
+
+- <div class="fragment">**Goal:**  `out = m + n`</div>
+
+-->
+
+Generalizes To Structures 
+-------------------------
+
+Same idea applies for induction over *structures* ...
+
+
+Structural Induction
+====================
+
+Example: Lists
+--------------
+
+<br>
+
+\begin{code}
+data L a = N 
+         | C a (L a)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets write a generic loop over such lists ...
+</div>
+
+Example: `foldr`
+----------------
+
+\begin{spec} <br>
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{spec}
+
+<br>
+
+<div class="fragment">
+Lets brace ourselves for the type...
+</div>
+
+Example: `foldr`
+----------------
+
+\begin{code}
+{-@ foldr :: 
+    forall a b <p :: L a -> b -> Prop>. 
+      (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
+    -> b<p N> 
+    -> ys:L a
+    -> b<p ys>                            @-}
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets step through the type...
+</div>
+
+
+`foldr`: Abstract Refinement
+----------------------------
+
+\begin{spec} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  ::  b<p ys>                            
+\end{spec}
+
+<br>
+
+`(p xs b)` relates `b` with **folded** `xs`
+
+`p :: L a -> b -> Prop`
+
+
+`foldr`: Base Case
+------------------
+
+\begin{spec} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{spec}
+
+<br>
+
+`base` is related to **empty** list `N`
+
+`base :: b<p N>` 
+
+
+
+`foldr`: Ind. Step 
+------------------
+
+\begin{spec} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{spec}
+
+<br>
+
+`step` **extends** relation from `xs` to `C x xs`
+
+`step :: xs:_ -> x:_ -> b<p xs> -> b<p (C x xs)>`
+
+
+`foldr`: Output
+---------------
+
+\begin{spec} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{spec}
+
+<br>
+
+Hence, relation holds between `out` and **entire input** list `ys`
+
+`out :: b<p ys>`
+
+Using `foldr`: Size
+-------------------
+
+We can now verify <br>
+
+\begin{code}
+{-@ size :: xs:_ -> {v:Int| v = llen xs} @-}
+size     = foldr (\_ _ n -> n + 1) 0
+\end{code}
+
+<br>
+
+<div class="fragment">
+by *automatically instantiating*
+
+`p := \xs acc -> acc = llen xs`
+</div>
+
+Using `foldr`: Append
+---------------------
+
+We can now verify <br>
+
+\begin{code}
+{-@ (++) :: xs:_ -> ys:_ -> Cat a xs ys @-} 
+xs ++ ys = foldr (\_ -> C) ys xs 
+\end{code}
+
+<br>
+
+<div class="fragment">
+where 
+
+\begin{code}
+{-@ type Cat a X Y = 
+    {v:_| llen v = llen X + llen Y} @-}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+By automatically instantiating 
+
+`p := \xs acc -> llen acc = llen xs + llen ys`
+
+</div>
+
+Recap
+-----
+
+<br>
+
+Abstract refinements *decouple* **invariant** from **iteration**
+
+<br>
+
+<div class="fragment">**Reusable** summaries for higher-order functions.</div>
+
+<br>
+
+<div class="fragment">**Automatic** checking and instantiation by SMT.</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over Type Signatures
+    + <div class="fragment">**Functions**</div>
+    + <div class="fragment">**Data** <a href="07_Array.lhs.slides.html" target="_blank">[continue]</a></div>
diff --git a/docs/slides/ETH14/lhs/07_Array.lhs b/docs/slides/ETH14/lhs/07_Array.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/07_Array.lhs
@@ -0,0 +1,294 @@
+Abstract Refinements {#data}
+============================
+
+Recap
+-----
+
+<br>
+
+**So far**
+
+Abstract Refinements decouple invariants from *functions*
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+Decouple invariants from *data structures*
+
+</div>
+
+
+
+Decouple Invariants From Data {#vector} 
+=======================================
+
+Example: Vectors 
+----------------
+
+<div class="hidden">
+\begin{code}
+module LiquidArray where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume, liquidError)
+
+{-@ LIQUID "--no-termination" @-}
+initialize :: Int -> Vec Int
+\end{code}
+</div>
+
+<div class="fragment">
+
+For this talk, implemented as maps from `Int` to `a` 
+
+<br>
+
+\begin{code}
+data Vec a = V (Int -> a)
+\end{code}
+
+</div>
+
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Parameterize type with *two* abstract refinements:
+
+<br>
+
+\begin{code}
+{-@ data Vec a < dom :: Int -> Prop,
+                 rng :: Int -> a -> Prop >
+      = V {a :: i:Int<dom> -> a <rng i>}  @-}
+\end{code}
+
+<br>
+
+- `dom`: *domain* on which `Vec` is *defined* 
+
+- `rng`: *range*  and relationship with *index*
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Diverse `Vec`tors by *instantiating* `dom` and `rng`
+
+<br>
+
+<div class="fragment">
+
+An alias for *segments* between `I` and `J`
+
+<br>
+
+\begin{code}
+{-@ predicate Btwn I V J = I <= V && V < J @-}
+\end{code}
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type IdVec N = Vec <{\v -> Btwn 0 v N}, 
+                        {\k v -> v = k}> 
+                       Int                  @-}
+\end{code}
+
+</div>
+
+
+Ex: Zero-Terminated Vectors
+---------------------------
+
+Defined between `[0..N)`, with *last* element equal to `0`:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type ZeroTerm N = 
+     Vec <{\v -> Btwn 0 v N}, 
+          {\k v -> k = N-1 => v = 0}> 
+          Int                         @-}
+\end{code}
+
+</div>
+
+Ex: Fibonacci Table 
+-------------------
+
+A vector whose value at index `k` is either 
+
+- `0` (undefined), or, 
+
+- `k`th fibonacci number 
+
+\begin{code}
+{-@ type FibV =  
+     Vec <{\v -> true}, 
+          {\k v -> v = 0 || v = fib k}> 
+          Int                          @-}
+\end{code}
+
+
+An API for Vectors
+------------------
+
+
+<br>
+<br>
+
+- `empty`
+
+- `set`
+
+- `get`
+
+
+API: Empty Vectors
+-----------------
+
+`empty` a Vector whose domain is `false` (defined at *no* key)
+
+<br>
+
+\begin{code}
+{-@ empty :: forall <p :: Int -> a -> Prop>. 
+               Vec <{v:Int|false}, p> a     @-}
+
+empty     = V $ \_ -> error "empty vector!"
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+What would happen if we changed `false` to `true`?
+</div>
+
+API: `get` Key's Value 
+----------------------
+
+- *Input* `key` in *domain*
+
+- *Output* value in *range* related with `k`
+
+<br>
+
+\begin{code}
+{-@ get :: forall a <d :: Int -> Prop,  
+                     r :: Int -> a -> Prop>.
+           key:Int <d>
+        -> vec:Vec <d, r> a
+        -> a<r key>                        @-}
+
+get k (V f) = f k
+\end{code}
+
+
+API: `set` Key's Value 
+----------------------
+
+- <div class="fragment">Input `key` in *domain*</div>
+
+- <div class="fragment">Input `val` in *range* related with `key`</div>
+
+- <div class="fragment">Input `vec` defined at *domain except at* `key`</div>
+
+- <div class="fragment">Output domain *includes* `key`</div>
+
+API: `set` Key's Value 
+----------------------
+
+\begin{code}
+{-@ set :: forall a <d :: Int -> Prop,
+                     r :: Int -> a -> Prop>.
+           key: Int<d> -> val: a<r key>
+        -> vec: Vec<{v:Int<d>| v /= key},r> a
+        -> Vec <d, r> a                     @-}
+
+set key val (V f) = V $ \k -> if k == key 
+                                then val 
+                                else f k
+\end{code}
+
+<br>
+
+<div class="hidden">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+Help! Can you spot and fix the errors? 
+</div>
+
+Using the Vector API
+--------------------
+
+Loop over vector, setting each key `i` equal to `i`:
+
+<br>
+
+\begin{code}
+{-@ initialize :: n:Nat -> IdVec n @-}
+initialize n      = loop 0 empty
+  where
+    loop i a 
+      | i < n     = let a' = set i i a
+                    in
+                        loop (i+1) a'
+      | otherwise = a 
+\end{code}
+
+Recap
+-----
+
+<br>
+
++ Created a `Vec` (Array) container 
+
++ Decoupled *domain* and *range* invariants from *data*
+
++ Enabled analysis of *array segments*
+
+<br>
+
+Recap
+-----
+
+<br>
+
+Custom *array segment* program analyses: 
+
+<br>
+
+- Gopan-Reps-Sagiv, POPL 05
+- J.-McMillan, CAV 07
+- Logozzo-Cousot-Cousot, POPL 11
+- Dillig-Dillig, POPL 12 
+
+<br>
+
+Encoded in (abstract) refinement typed API.
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over Type Signatures
+    + Functions
+    + <div class="fragment">**Data**</div>
+
+<div class="fragment">[[continue...]](11_Evaluation.lhs.slides.html)</div>
diff --git a/docs/slides/ETH14/lhs/08_Recursive.lhs b/docs/slides/ETH14/lhs/08_Recursive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/08_Recursive.lhs
@@ -0,0 +1,460 @@
+Abstract Refinements {#data}
+============================
+
+Recap
+-----
+
+**So far**
+
+Abstract Refinements decouple invariants from
+
++ functions
++ indexed data
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+Decouple invariants from **recursive** data structures
+</div>
+
+
+
+Decouple Invariants From Data {#recursive} 
+==========================================
+
+ {#asd}
+-------
+
+Recursive Structures 
+--------------------
+
+Lets see another example of decoupling...
+
+<div class="hidden">
+\begin{code}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+
+module List (insertSort) where
+
+{-@ LIQUID "--no-termination" @-}
+
+mergeSort     :: Ord a => [a] -> [a]
+insertSort :: (Ord a) => [a] -> L a 
+slist :: L Int
+slist' :: L Int
+iGoUp, iGoDn, iDiff :: [Int]
+infixr `C`
+\end{code}
+</div>
+
+Decouple Invariants From Recursive Data
+=======================================
+
+Recall: Lists
+-------------
+
+\begin{code}
+data L a = N 
+         | C { hd :: a, tl :: L a }
+\end{code}
+
+
+Recall: Refined Constructors 
+----------------------------
+
+Define **increasing** Lists with strengthened constructors:
+
+\begin{spec} <br>
+data L a where
+  N :: L a
+  C :: hd:a -> tl: L {v:a | hd <= v} -> L a
+\end{spec}
+
+Problem: Decreasing Lists?
+--------------------------
+
+What if we need *both* [increasing *and* decreasing lists?](http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Data-List.html#sort)
+
+<br>
+
+<div class="hidden">
+[Separate (indexed) types](http://web.cecs.pdx.edu/~sheard/Code/QSort.html) get quite complicated ...
+</div>
+
+Abstract That Refinement!
+-------------------------
+
+\begin{code}
+{-@ data L a <p :: a -> a -> Prop>
+      = N 
+      | C { hd :: a, tl :: L <p> a<p hd> } @-}
+\end{code}
+
+<br>
+
+<div class="fragment"> `p` is a **binary relation** between two `a` values</div>
+
+<br>
+
+<div class="fragment"> Definition relates `hd` with **all** the elements of `tl`</div>
+
+<br>
+
+<div class="fragment"> Recursive: `p` holds for **every pair** of elements!</div>
+
+Example
+-------
+
+Consider a list with *three* or more elements 
+
+\begin{spec} <br>
+x1 `C` x2 `C` x3 `C` rest :: L <p> a 
+\end{spec}
+
+Example: Unfold Once
+--------------------
+
+\begin{spec} <br> 
+x1                 :: a
+x2 `C` x3 `C` rest :: L <p> a<p x1> 
+\end{spec}
+
+Example: Unfold Twice
+---------------------
+
+\begin{spec} <br> 
+x1          :: a
+x2          :: a<p x1>  
+x3 `C` rest :: L <p> a<p x1 && p x2> 
+\end{spec}
+
+Example: Unfold Thrice
+----------------------
+
+\begin{spec} <br> 
+x1   :: a
+x2   :: a<p x1>  
+x3   :: a<p x1 && p x2>  
+rest :: L <p> a<p x1 && p x2 && p x3> 
+\end{spec}
+
+<br>
+
+<div class="fragment">
+Note how `p` holds between **every pair** of elements in the list. 
+</div>
+
+A Concrete Example
+------------------
+
+That was a rather *abstract*!
+
+<br>
+
+How can we *use* fact that `p` holds between *every pair*?
+
+<br>
+
+<div class="fragment">**Instantiate** `p` with a *concrete* refinement</div>
+
+
+Example: Increasing Lists
+-------------------------
+
+**Instantiate** `p` with a *concrete* refinement
+
+<br>
+
+\begin{code}
+{-@ type IncL a = L <{\hd v -> hd <= v}> a @-}
+\end{code}
+
+<br>
+
+<div class="fragment"> Refinement says: &nbsp; `hd` less than **every** `v` in tail,</div>
+
+<br>
+
+<div class="fragment"> i.e., `IncL` denotes **increasing** lists. </div>
+
+Example: Increasing Lists
+-------------------------
+
+LiquidHaskell *verifies* that `slist` is indeed increasing...
+
+\begin{code}
+{-@ slist :: IncL Int @-}
+slist     = 1 `C` 6 `C` 12 `C` N
+\end{code}
+
+<br> 
+
+<div class="fragment">
+
+... and *protests* that `slist'` is not: 
+
+\begin{code}
+{-@ slist' :: IncL Int @-}
+slist' = 6 `C` 1 `C` 12 `C` N
+\end{code}
+</div>
+
+Insertion Sort
+--------------
+
+\begin{code}
+{-@ insertSort :: (Ord a) => [a] -> IncL a @-}
+insertSort     = foldr insert N
+
+insert y N          = y `C` N
+insert y (x `C` xs) 
+  | y < x           = y `C` (x `C` xs)
+  | otherwise       = x `C` insert y xs
+\end{code}
+
+<br>
+
+(Mouseover `insert` to see inferred type.)
+
+Checking GHC Lists
+------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target= "_blank">Demo:</a> 
+Above applies to GHC's List definition:
+
+\begin{spec} <br> 
+data [a] <p :: a -> a -> Prop>
+  = [] 
+  | (:) { h :: a, tl :: [a<p h>]<p> }
+\end{spec}
+
+Checking GHC Lists
+------------------
+
+Increasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Incs a = [a]<{\h v -> h <= v}> @-}
+
+{-@ iGoUp :: Incs Int @-}
+iGoUp     = [1,2,3]
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Decreasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Decs a = [a]<{\h v -> h >= v}> @-}
+
+{-@ iGoDn :: Decs Int @-}
+iGoDn     = [3,2,1]
+\end{code}
+
+
+Checking GHC Lists
+------------------
+
+Duplicate-free Lists
+
+<br>
+
+\begin{code}
+{-@ type Difs a = [a]<{\h v -> h /= v}> @-}
+
+{-@ iDiff :: Difs Int @-}
+iDiff     = [1,3,2]
+\end{code}
+
+Checking Lists
+--------------
+
+Now we can check all the usual list sorting algorithms 
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target="_blank">Demo:</a> List Sorting
+
+<!-- 
+
+Example: `mergeSort` [1/2]
+--------------------------
+
+\begin{code}
+{-@ mergeSort  :: (Ord a) => [a] -> Incs a @-}
+mergeSort []   = []
+mergeSort [x]  = [x]
+mergeSort xs   = merge xs1' xs2' 
+  where 
+   (xs1, xs2)  = split xs
+   xs1'        = mergeSort xs1
+   xs2'        = mergeSort xs2
+\end{code}
+
+Example: `mergeSort` [2/2]
+--------------------------
+
+\begin{code}
+split (x:y:zs) = (x:xs, y:ys) 
+  where 
+    (xs, ys)   = split zs
+split xs       = (xs, [])
+
+merge xs []    = xs
+merge [] ys    = ys
+merge (x:xs) (y:ys) 
+  | x <= y     = x : merge xs (y:ys)
+  | otherwise  = y : merge (x:xs) ys
+\end{code}
+
+Example: Binary Trees
+---------------------
+
+... `Map` from keys of type `k` to values of type `a` 
+
+<br>
+
+<div class="fragment">
+
+Implemented, as a binary tree:
+
+<br>
+
+\begin{code}
+data Map k a = Tip
+             | Bin Size k a (Map k a) (Map k a)
+
+type Size    = Int
+\end{code}
+</div>
+
+Two Abstract Refinements
+------------------------
+
+- `l` : relates root `key` with `left`-subtree keys
+- `r` : relates root `key` with `right`-subtree keys
+
+<br>
+
+\begin{code}
+{-@ data Map k a < l :: k -> k -> Prop
+                 , r :: k -> k -> Prop >
+    = Tip
+    | Bin (sz :: Size) (key :: k) (val :: a)
+          (left  :: Map <l,r> (k<l key>) a)
+          (right :: Map <l,r> (k<r key>) a) @-}
+\end{code}
+
+
+Ex: Binary Search Trees
+-----------------------
+
+Keys are *Binary-Search* Ordered
+
+<br>
+
+\begin{code}
+{-@ type BST k a = 
+      Map <{\r v -> v < r }, 
+           {\r v -> v > r }> 
+          k a                   @-}
+\end{code}
+
+Ex: Minimum Heaps 
+-----------------
+
+Root contains *minimum* value
+
+<br>
+
+\begin{code}
+{-@ type MinHeap k a = 
+      Map <{\r v -> r <= v}, 
+           {\r v -> r <= v}> 
+           k a               @-}
+\end{code}
+
+Ex: Maximum Heaps 
+-----------------
+
+Root contains *maximum* value
+
+<br>
+
+\begin{code}
+{-@ type MaxHeap k a = 
+      Map <{\r v -> r >= v}, 
+           {\r v -> r >= v}> 
+           k a               @-}
+\end{code}
+
+
+Example: Data.Map
+-----------------
+
+Standard Key-Value container
+
+<br>
+
+- <div class="fragment">1300+ non-comment lines</div>
+
+- <div class="fragment">`insert`, `split`, `merge`,...</div>
+
+- <div class="fragment">Rotation, Rebalance,...</div>
+
+<br>
+
+<div class="fragment">
+SMT & inference crucial for [verification](https://github.com/ucsd-progsys/liquidhaskell/blob/master/benchmarks/esop2013-submission/Base.hs)
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Map.hs" target="_blank">Demo:</a> Binary Search Maps
+</div>
+
+Recap: Abstract Refinements
+---------------------------
+
+<div class="fragment">
+
+Decouple invariants from **functions**
+
++ `max`
++ `loop`
++ `foldr`
+
+</div>
+
+<div class="fragment">
+Decouple invariants from **data**
+
++ `Vector`
++ `List`
++ `Tree`
+
+</div>
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. **Abstract:** Refinements over functions and data
+5. <div class="fragment"><a href="11_Evaluation.lhs.slides.html" target="_blank">Evaluation</a></div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](11_Evaluation.lhs.slides.html)</div>
diff --git a/docs/slides/ETH14/lhs/09_Laziness.lhs b/docs/slides/ETH14/lhs/09_Laziness.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/09_Laziness.lhs
@@ -0,0 +1,271 @@
+ {#laziness}
+============
+
+<div class="hidden">
+\begin{code}
+module Laziness where
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ LIQUID "--no-termination" @-}
+
+safeDiv :: Int -> Int -> Int
+foo     :: Int -> Int
+-- zero    :: Int 
+-- diverge :: a -> b
+\end{code}
+</div>
+
+
+Lazy Evaluation?
+----------------
+
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+
+
+[[Skip]](11_Evaluation.lhs.slides.html)
+
+Lazy Evaluation
+===============
+
+SMT based Verification
+----------------------
+
+Techniques developed for **strict** languages
+
+<br>
+
+<div class="fragment">
+
+-----------------------   ---   ------------------------------------------
+        **Floyd-Hoare**    :    `ESCJava`, `SpecSharp` ...
+     **Model Checkers**    :    `Slam`, `Blast` ...
+   **Refinement Types**    :    `DML`, `Stardust`, `Sage`, `F7`, `F*`, ...
+-----------------------   ---   ------------------------------------------
+
+</div>
+
+<br>
+
+<div class="fragment">
+Surely soundness carries over to Haskell, right?
+</div>
+
+
+Back To the Beginning
+---------------------
+
+\begin{code}
+{-@ safeDiv :: Int -> {v:Int|v /= 0} -> Int @-}
+safeDiv n 0 = liquidError "div-by-zero!"
+safeDiv n d = n `div` d
+\end{code}
+
+<br>
+
+<div class="fragment">
+Should only call `safeDiv` with **non-zero** values
+</div>
+
+An Innocent Function
+--------------------
+
+`foo` returns a value **strictly less than** input.
+
+<br>
+
+\begin{spec} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+\end{spec}
+
+LiquidHaskell Lies! 
+-------------------
+
+\begin{code}
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0    
+              a = foo z
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+<div class="fragment">
+Why is this program **deemed safe**?! 
+</div>
+
+
+*Safe* With Eager Eval
+----------------------
+
+\begin{spec} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{spec}
+
+<br>
+
+<div class="fragment">
+**Safe** in Java, ML: program spins away, **never hits** divide-by-zero 
+</div>
+
+*Unsafe* With Lazy Eval
+-----------------------
+
+\begin{spec} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{spec}
+
+<br>
+
+**Unsafe** in Haskell: program skips `foo z` and **hits** divide-by-zero!
+
+Problem: Divergence
+-------------------
+
+What is denoted by:
+
+`e :: {v:Int | P}`
+
+
+<br>
+
+<div class="fragment">
+`e` evaluates to `Int` satisfying `P`  
+</div>
+
+<div class="fragment">
+or
+
+**diverges**! 
+</div>
+
+<div class="fragment">
+<br>
+
+Classical Floyd-Hoare notion of [partial correctness](http://en.wikipedia.org/wiki/Hoare_logic#Partial_and_total_correctness)
+
+</div>
+
+
+
+Problem: Divergence
+-------------------
+
+\begin{spec} **Consider** <div/> 
+        {-@ e :: {v : Int | P} @-}
+
+        let x = e in body 
+\end{spec}
+
+<br>
+
+<div class="fragment">
+**Eager Evaluation** 
+
+*Can* assume `P(x)` when checking `body`
+</div>
+
+<br>
+
+<div class="fragment">
+**Lazy Evaluation** 
+
+*Cannot* assume `P(x)` when checking `body`
+</div>
+
+Eager vs. Lazy Binders 
+----------------------
+
+\begin{spec} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{spec}
+
+
+<br>
+
+Inconsistent refinement for `a` is sound for **eager**, unsound for **lazy**
+
+
+Panic! Now what?
+---------------
+
+<div class="fragment">
+**Solution** 
+
+Assign *non-trivial* refinements to *non-diverging* terms!
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Require A Termination Analysis**
+
+Don't worry, its easy...
+
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=TellingLies.hs" target="_blank">Demo:</a> &nbsp; Disable `"--no-termination"` and see what happens!
+</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. **Lazy Evaluation:** Requires Termination
+6. <div class="fragment">**Termination:** via Refinements!</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](10_Termination.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/ETH14/lhs/10_Termination.lhs b/docs/slides/ETH14/lhs/10_Termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/10_Termination.lhs
@@ -0,0 +1,314 @@
+Termination {#termination}
+==========================
+
+
+<div class="hidden">
+\begin{code}
+module Termination where
+
+import Prelude hiding (gcd, mod, map)
+fib :: Int -> Int
+gcd :: Int -> Int -> Int
+infixr `C`
+
+data L a = N | C a (L a)
+
+{-@ invariant {v: (L a) | 0 <= (llen v)} @-}
+
+mod :: Int -> Int -> Int
+mod a b | a - b >  b = mod (a - b) b
+        | a - b <  b = a - b
+        | a - b == b = 0
+
+merge :: Ord a => L a -> L a -> L a
+\end{code}
+</div>
+
+<!--
+
+Dependent != Refinement
+-----------------------
+
+<div class="fragment">**Dependent Types**</div>
+
++ <div class="fragment">*Arbitrary terms* appear inside types</div> 
++ <div class="fragment">Termination ensures well-defined</div>
+
+<br>
+
+<div class="fragment">**Refinement Types**</div>
+
++ <div class="fragment">*Restricted refinements* appear in types</div>
++ <div class="fragment">Termination *not* required ...</div> 
++ <div class="fragment">... except, alas, with *lazy* evaluation!</div>
+
+-->
+
+Refinements & Termination
+-------------------------
+
+<div class="fragment">
+Fortunately, we can ensure termination **using refinements**
+</div>
+
+
+Main Idea
+---------
+
+Recursive calls must be on **smaller** inputs
+
+<br>
+
++ [Turing](http://classes.soe.ucsc.edu/cmps210/Winter11/Papers/turing-1936.pdf)
++ [Sized Types](http://dl.acm.org/citation.cfm?id=240882)
++ [DML](http://dl.acm.org/citation.cfm?id=609232)
++ [Size Change Principle](http://dl.acm.org/citation.cfm?id=360210)
+
+Recur On *Smaller* `Nat` 
+------------------------
+
+<div class="fragment">
+
+**To ensure termination of**
+
+\begin{spec} <div/>
+foo   :: Nat -> T
+foo x =  body
+\end{spec}
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:Nat | v < x} -> T`
+
+<br>
+
+*i.e.* require recursive calls have `Nat` inputs *smaller than* `x`
+</div>
+
+
+
+Ex: Recur On *Smaller* `Nat` 
+----------------------------
+
+\begin{code}
+{-@ fib  :: Nat -> Nat @-}
+fib 0    = 1
+fib 1    = 1
+fib n    = fib (n-1) + fib (n-2)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Terminates, as both `n-1` and `n-2` are `< n`
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=GCD.hs" target="_blank">Demo:</a> &nbsp; What if we drop the `fib 1` equation? 
+</div>
+
+Refinements Are Essential!
+--------------------------
+
+\begin{code}
+{-@ gcd :: a:Nat -> {b:Nat | b < a} -> Int @-}
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Need refinements to prove `(a mod b) < b` at *recursive* call!
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ mod :: a:Nat 
+        -> b:{v:Nat|(0 < v && v < a)} 
+        -> {v:Nat| v < b}                 @-}
+\end{code}
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{spec}<div/>
+foo   :: S -> T
+foo x = body
+\end{spec}
+
+<br>
+
+<div class="fragment">
+**Reduce** to `Nat` case...
+</div>
+
+<br>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{spec}<div/>
+foo   :: S -> T
+foo x = body
+\end{spec}
+
+<br>
+
+Specify a **default measure** `mS :: S -> Int`
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:s | 0 <= (mS v) < (mS x)} -> T`
+</div>
+
+
+Ex: Recur on *smaller* `List`
+-----------------------------
+
+\begin{code} 
+map f N        = N
+map f (C x xs) = (f x) `C` (map f xs) 
+\end{code}
+
+<br>
+
+Terminates using **default** measure `llen` 
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ data L [llen] a = N 
+                    | C { x::a, xs :: L a} @-}
+
+{-@ measure llen :: L a -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)   @-}
+\end{code}
+</div>
+
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of smallness spread across **multiple inputs**?
+
+<br>
+
+\begin{code}
+merge xs@(x `C` xs') ys@(y `C` ys')
+  | x < y     = x `C` merge xs' ys
+  | otherwise = y `C` merge xs ys'
+\end{code}
+
+<br>
+
+<div class="fragment">
+Neither input decreases, but their **sum** does.
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+Neither input decreases, but their **sum** does.
+
+<br>
+
+\begin{code}
+{-@ merge :: Ord a => xs:_ -> ys:_ -> _ 
+          /  [(llen xs) + (llen ys)]     @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+Synthesize **ghost** parameter equal to `[...]`
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+... thereby reducing to decreasing **single parameter** case. 
+
+</div>
+
+Important Extensions 
+--------------------
+
+<br>
+
+<div class="fragment">**Mutual** recursion</div>
+
+<br>
+
+<div class="fragment">**Lexicographic** ordering</div>
+
+<br>
+
+<div class="fragment">Fit easily into our framework ...</div>
+
+Recap
+-----
+
+Main idea: Recursive calls on **smaller** inputs
+
+<br>
+
+<div class="fragment">Use refinements to **check** smaller</div>
+
+<br>
+
+<div class="fragment">Use refinements to **establish** smaller</div>
+
+
+A Curious Circularity
+---------------------
+
+<div class="fragment">Refinements require termination ...</div> 
+
+<br>
+
+<div class="fragment">... Termination requires refinements!</div>
+
+<br>
+
+<div class="fragment"> Meta-theory is tricky, but all ends well.</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. Lazy Evaluation: Requires Termination
+6. **Termination:** via Refinements!
+7. <div class="fragment">**Evaluation:** How good is this in practice?</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](11_Evaluation.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/ETH14/lhs/11_Evaluation.lhs b/docs/slides/ETH14/lhs/11_Evaluation.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/11_Evaluation.lhs
@@ -0,0 +1,93 @@
+ {#ASda}
+========
+
+Evaluation
+----------
+
+
+
+Evaluation
+==========
+
+LiquidHaskell Is For Real
+-------------------------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+<br>
+
+**Substantial Code Bases**
+
+10KLoc, 50+ Modules
+
+<br>
+
+**Complex Properties**
+
+Memory Safety, Functional Correctness*, Termination
+
+<br>
+
+<div class="fragment">
+**Inference is Crucial**
+</div>
+
+
+Numbers
+-------
+
+<div align="center">
+
+**Library**                     **LOC**
+---------------------------   ---------
+`Data.List`                         814
+`Data.Set.Splay`                    149
+`Data.Vector.Algorithms`           1219
+`HsColour`                         1047
+`Data.Map.Base`                    1396
+`Data.Text`                        3125
+`Data.Bytestring`                  3501
+**Total**                     **11251**
+---------------------------   ---------
+
+</div>
+
+Numbers
+-------
+
+<div align="center">
+
+**Library**                     **LOC**     **Time**
+---------------------------   ---------   ----------
+`Data.List`                         814          26s
+`Data.Set.Splay`                    149          27s
+`Data.Vector.Algorithms`           1219          89s 
+`HsColour`                         1047         196s
+`Data.Map.Base`                    1396         174s
+`Data.Text`                        3125         499s
+`Data.Bytestring`                  3501         294s
+**Total**                     **11251**    **1305s**
+---------------------------   ---------   ----------
+
+</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. **Evaluation**
+5. <div class="fragment"><a href="12_Conclusion.lhs.slides.html" target="_blank">Conclusion</a></div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](12_Conclusion.lhs.slides.html)</div>
diff --git a/docs/slides/ETH14/lhs/12_Conclusion.lhs b/docs/slides/ETH14/lhs/12_Conclusion.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/12_Conclusion.lhs
@@ -0,0 +1,96 @@
+ {#ASda}
+========
+
+Conclusion
+----------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+Conclusion
+==========
+
+Liquid Types 
+------------
+
+
+Use **Types** to lift **Logic + Analysis** to Modern Programs 
+
+<br>
+
+<div class="fragment"> 
+
+-------------------       ------------------------------------------------
+**Properties:**           Predicates *+ Types*
+**Proofs:**               Verification Conditions *+ Subtyping* 
+**Inference:**            Abstract Interpretation *+ Hindley-Milner*
+-------------------       ------------------------------------------------
+
+</div>
+
+
+Liquid Types 
+------------
+
+Use **Types** to lift **Logic + Analysis** to Modern Programs 
+
+<br>
+
+**Take Home: Types are a simple and uniform way to analyze**
+
++ Unbounded Data (eg. Arrays, Lists, HashMaps)
++ Polymorphism   (eg. Generics,...)
++ Callbacks/HOFs (eg. map, reduce, filter,...)
+
+<div class="hidden">
+
+Liquid Types 
+------------
+
+Use **Types** to lift **Logic + Analysis** to Modern Programs 
+
+<br>
+
+**Take Home 2: Uninterpreted Functions**
+
++ Measures for Datatype properties
+
++ Abstract Refinements 
+
+</div>
+
+Current & Future Work
+---------------------
+
+**Technology**
+
++ Speed
++ Imperative Features (Pointers, Mutation, ...) 
++ Diagnostics & *Error Messages*
+
+Current & Future Work
+---------------------
+
+**Applications**
+
++ Concurrency & Distribution
++ Probabilistic Behavior
++ Completion, Repair & Synthesis
+
+ {#asd}
+=======
+
+Thank You!
+----------
+
+<br>
+
+[`http://goto.ucsd.edu/liquid`](http://goto.ucsd.edu/liquid)
+
+<br>
+
diff --git a/docs/slides/ETH14/lhs/Index.lhs b/docs/slides/ETH14/lhs/Index.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/ETH14/lhs/Index.lhs
@@ -0,0 +1,50 @@
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+
+ {#ASD}
+=======
+
+
+Types & Program Analysis 
+------------------------
+
+
+<br>
+<br>
+
+**Ranjit Jhala**
+
+University of California, San Diego
+
+<br>
+<br>
+
+Joint work with: 
+
+N. Vazou, E. Seidel, P. Rondon, D. Vytiniotis, S. Peyton-Jones
+
+<br>
+
+<div class="fragment">
+[[continue]](00_Motivation.lhs.slides.html)
+</div>
+
+
+Plan 
+----
+
++ <a href="00_Motivation.lhs.slides.html" target="_blank">Motivation</a>
++ <div class="fragment"><a href="01_SimpleRefinements.lhs.slides.html" target="_blank">Refinements</a></div>
++ <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
++ <div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target= "_blank">Higher-Order Functions</a></div>
++ <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements:</a> <a href="06_Inductive.lhs.slides.html" target="_blank">Code</a>,<a href="07_Array.lhs.slides.html" target= "_blank">Data</a></div>
++ <div class="fragment"><a href="11_Evaluation.lhs.slides.html" target="_blank">Evaluation</a></div>
++ <div class="fragment"><a href="12_Conclusion.lhs.slides.html" target="_blank">Conclusion</a></div>
+
diff --git a/docs/slides/Galois2014/000_Refinements.hs b/docs/slides/Galois2014/000_Refinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/Galois2014/000_Refinements.hs
@@ -0,0 +1,119 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--smtsolver=cvc4" @-}
+
+module Refinements where
+
+import Prelude hiding (abs)
+
+divide    :: Int -> Int -> Int
+
+
+-----------------------------------------------------------------------
+-- | Simple Refinement Types
+-----------------------------------------------------------------------
+
+{-@ six :: {v:Int | v = 6} @-}
+six = 6 :: Int
+
+
+
+-----------------------------------------------------------------------
+-- | Type Aliases are nice, we're gonna be liberal in our use of them
+-----------------------------------------------------------------------
+
+{-@ type Nat     = {v:Int | v >= 0} @-}
+{-@ type Pos     = {v:Int | v >  0} @-}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+
+
+-----------------------------------------------------------------------
+-- | Subtyping via Implication
+-----------------------------------------------------------------------
+
+{-@ six' :: NonZero @-}
+six' = six
+
+-- {v:Int | v = 6} <: {v:Int | v /= 0}
+-- ==>
+--          v = 6  =>          v /= 0
+
+
+-----------------------------------------------------------------------
+-- | Function Contracts: Preconditions & Dead Code 
+-----------------------------------------------------------------------
+
+{-@ die :: {v:_ | false} -> a @-}
+die msg = error msg
+
+-- Precondition says, there are **NO** valid inputs for @die@.
+-- If program type-checks, means @die@ is **NEVER** called at run-time.
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | Function Contracts: Safe Division 
+-----------------------------------------------------------------------
+
+divide x 0 = die "divide-by-zero"
+divide x n = x `div` n
+
+
+
+-- | What's the problem above? Nothing to *prevent*
+--   us from calling `divide` with 0. Oops.
+--   How shall we fix it?
+
+
+
+
+
+
+
+avg2 x y   = divide (x + y)     2
+avg3 x y z = divide (x + y + z) 3
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | But whats the problem here?
+-----------------------------------------------------------------------
+
+avg xs     = divide total n 
+  where
+    total  = sum xs
+    n      = length xs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------
+-- | CHEAT AREA ----------------------------------------------
+--------------------------------------------------------------
+
+-- # START Errors 1 (divide)
+-- # END   Errors 1 (avg)
+
+{- divide :: Int -> NonZero -> Int     @-}
diff --git a/docs/slides/Galois2014/001_Refinements.hs b/docs/slides/Galois2014/001_Refinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/Galois2014/001_Refinements.hs
@@ -0,0 +1,91 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--totality"       @-}
+{-@ LIQUID "--smtsolver=cvc4" @-}
+
+module Refinements where
+
+import Prelude hiding (map, foldr, foldr1)
+
+divide    :: Int -> Int -> Int
+-----------------------------------------------------------------------
+-- | Our first Data Type
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+-----------------------------------------------------------------------
+-- | A few Higher-Order Functions
+-----------------------------------------------------------------------
+
+map                  :: (a -> b) -> List a -> List b
+map f N              = N
+map f (C x xs)       = C (f x) (map f xs) 
+
+
+foldr                :: (a -> b -> b) -> b -> List a -> b 
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+
+
+-- Uh oh. How shall we fix the error? Lets move on for now...
+
+foldr1           :: (a -> a -> a) -> List a -> a   
+foldr1 f (C x xs)    = foldr f x xs
+-- foldr1 f N           = die "foldr1"
+
+
+
+-- foldr1 f zs = case zs of
+--   C x xs -> foldr f x xs
+--   N      -> GHC.patError "YIKES"
+
+
+-----------------------------------------------------------------------
+-- | Measuring the Size of Data
+-----------------------------------------------------------------------
+
+{-@ measure size @-}
+size          :: List a -> Int
+size (C x xs) = 1 + size xs 
+size N        = 0
+
+
+-- N :: {v:List a | size v = 0}
+-- C :: x:a -> xs:List a
+--   -> {v:List a | size v = 1 + size xs}
+
+
+append N        ys = ys
+append (C x xs) ys = C x (append xs ys)
+
+
+
+-----------------------------------------------------------------------
+-- | Definitions from 000_Refinements.hs
+-----------------------------------------------------------------------
+
+{-@ type Nat     = {v:Int | v >= 0} @-}
+{-@ type Pos     = {v:Int | v >  0} @-}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+
+{-@ die :: {v:_ | false} -> a @-}
+die msg = error msg
+
+{-@ divide :: Int -> NonZero -> Int @-}
+divide x 0 = die "divide-by-zero"
+divide x n = x `div` n
+
+-----------------------------------------------------------------------
+-- | CHEAT AREA 
+-----------------------------------------------------------------------
+
+-- # START-ERRORS 1 (foldr1)
+-- # END-ERRORS   0
+
+{- map    :: _ -> xs:_ -> {v:_ | size v = size xs}               @-}
+{- append :: xs:_ -> ys:_ -> {v: _ | size v = size ys + size xs} @-}
+{- foldr1 :: (a -> a -> a) -> {v:List a | size v > 0} -> a       @-}   
diff --git a/docs/slides/Galois2014/01_Elements.hs b/docs/slides/Galois2014/01_Elements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/Galois2014/01_Elements.hs
@@ -0,0 +1,106 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--smtsolver=cvc4" @-}
+module Elems where
+
+import Prelude hiding (elem)
+
+import Data.Set (Set (..))
+
+
+-----------------------------------------------------------------------------
+-- | 1. Reasoning about the Set of Elements in a List ----------------------- 
+-----------------------------------------------------------------------------
+
+-- | The set of `elems` of a list
+
+
+
+
+
+{-@ measure elems :: [a] -> (Set a)
+    elems ([])    = (Set_empty 0)
+    elems (x:xs)  = (Set_cup (Set_sng x) (elems xs))
+  @-}
+
+
+
+
+-- | A few handy aliases
+
+{-@ predicate EqElts Xs Ys    = elems Xs = elems Ys                      @-}
+{-@ predicate UnElts Xs Ys Zs = elems Xs = Set_cup (elems Ys) (elems Zs) @-}
+
+-- | Reasoning about `append` and `reverse`
+
+{-@ append  :: xs:_ -> ys:_ -> {v:_ | UnElts v xs ys} @-}  
+append [] ys     = ys
+append (x:xs) ys = x : append xs ys 
+
+
+{-@ reverse :: xs:_ -> {v:_ | EqElts v xs} @-}
+reverse xs           = revAcc xs []
+  where 
+   revAcc []     acc = acc
+   revAcc (x:xs) acc = revAcc xs (x:acc)
+
+
+
+
+-----------------------------------------------------------------------------
+-- | 2. Checking for duplicates (xmonad) ------------------------------------ 
+-----------------------------------------------------------------------------
+
+-- | Is a list free of duplicates?
+   
+{-@ measure nodups :: [a] -> Prop
+    nodups ([])   = true
+    nodups (x:xs) = (not (Set_mem x (elems xs)) && nodups xs)
+  @-}
+
+-- | Weeding out duplicates.
+   
+{-@ nub :: xs:_ -> {v:_ | nodups v && EqElts v xs} @-}
+nub xs             = go xs []
+  where
+    go (x:xs) l
+      | x `elem` l = go xs l     
+      | otherwise  = go xs (x:l) 
+    go [] l        = l
+
+
+{-@ elem :: x:_ -> ys:_ -> {v:Bool | Prop v <=> Set_mem x (elems ys)} @-}
+elem x []     = False
+elem x (y:ys) = x == y || elem x ys
+
+-----------------------------------------------------------------------------
+-- | 3. Associative Lookups ------------------------------------------------- 
+-----------------------------------------------------------------------------
+
+-- The dread "key-not-found". How can we fix it?
+find key ((k,v) : kvs)
+  | key == k  = v
+  | otherwise = find key kvs
+find _ []     = die "Key not found! Lookup failed!"
+
+
+{-@ die :: {v:_ | false} -> b @-}
+die x = error x
+
+
+----------------------------------------------------------------------------
+-- | CHEAT AREA ------------------------------------------------------------
+----------------------------------------------------------------------------
+
+{- predicate ValidKey K M    = Set_mem K (keys M)  @-}
+
+{- measure keys  :: [(a, b)] -> (Set a)
+    keys ([])     = (Set_empty 0)
+    keys (kv:kvs) = (Set_cup (Set_sng (fst kv)) (keys kvs))
+  @-}
+
+-- # START ERRORS 1 (find)
+-- # END   ERRORS 0 
+
+{- find :: k:_ -> {m:_ | ValidKey k m} -> _ @-}
+
diff --git a/docs/slides/Galois2014/05_Memory.hs b/docs/slides/Galois2014/05_Memory.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/Galois2014/05_Memory.hs
@@ -0,0 +1,401 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--smtsolver=cvc4" @-}
+{-@ LIQUID "--diffcheck"     @-}
+
+module Memory where
+
+import Prelude hiding (null)
+import Data.Char
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
+import System.IO.Unsafe
+import Data.ByteString.Internal (c2w, w2c)
+import Language.Haskell.Liquid.Prelude
+
+------------------------------------------------------------------------
+-- | 1. Low-level Pointer API  -----------------------------------------
+------------------------------------------------------------------------
+
+-- | Create a buffer of size 4 and initialize it with zeros
+
+zero4  = do fp <- mallocForeignPtrBytes 4
+            withForeignPtr fp $ \p -> do
+              poke (p `plusPtr` 0) zero 
+              poke (p `plusPtr` 1) zero 
+              poke (p `plusPtr` 2) zero 
+              poke (p `plusPtr` 3) zero 
+            return fp
+        where
+            zero = 0 :: Word8
+
+-- But whats to prevent an overflow, e.g. writing to offset 5 or 50?
+            
+
+
+-- | Types for Pointers
+
+-- data Ptr a         
+-- data ForeignPtr a 
+
+-- | Size of Ptr and ForeignPtr
+
+-- measure plen  :: Ptr a -> Int 
+-- measure fplen :: ForeignPtr a -> Int 
+
+
+{-@ type PtrN a N        = {v:Ptr a        |  plen v  = N}  @-}
+{-@ type ForeignPtrN a N = {v:ForeignPtr a |  fplen v = N}  @-}
+
+-- | Allocating Memory
+
+{-@ assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignPtrN a n) @-}
+
+-- | Using a pointer
+
+{- withForeignPtr :: fp:ForeignPtr a 
+                  -> (PtrN a (fplen fp) -> IO b)  
+                  -> IO b             
+-}
+
+-- | Pointer Arithmetic
+
+{- plusPtr :: p:Ptr a
+           -> o:{Nat|o <= plen p}   -- in bounds
+           -> PtrN b (plen b - o)   -- remainder
+-}
+
+-- | Read and Write
+
+{- peek :: {v:Ptr a | 0 < plen v} -> IO a  
+   poke :: {v:Ptr a | 0 < plen v} -> a -> IO ()  
+ -}
+
+-- | Example: Preventing Overflows e.g. writing 5 or 50 zeros?
+
+zero4' = do fp <- mallocForeignPtrBytes 4
+            withForeignPtr fp $ \p -> do
+              poke (p `plusPtr` 0) zero 
+              poke (p `plusPtr` 1) zero 
+              poke (p `plusPtr` 2) zero 
+              poke (p `plusPtr` 5) zero 
+            return fp
+        where
+            zero = 0 :: Word8
+
+
+
+------------------------------------------------------------------------
+-- | 2. ByteString API -------------------------------------------------
+------------------------------------------------------------------------
+
+data ByteString = PS {
+    bPtr :: ForeignPtr Word8
+  , bOff :: !Int
+  , bLen :: !Int
+  }
+
+
+-- | Refined Type, with invariants
+
+{-@ data ByteString = PS {
+      bPtr :: ForeignPtr Word8
+    , bOff :: {v:Nat| v        <= fplen bPtr}
+    , bLen :: {v:Nat| v + bOff <= fplen bPtr}
+    }
+
+  @-}
+
+--             fplen ptr = 23
+--               v
+--       |-----------------------|
+-- ptr = "  eric loves burritos  "
+--          |------------------|
+--          ^          ^
+--         off = 2    len = 19
+
+-- ex = PS ptr off len              -- 2 <= 23  &&  (2 + 19) <= 23   ==> SAFE
+
+-- | Some useful abbreviations
+
+{-@ type ByteStringN N = {v:ByteString | bLen v = N} @-}
+{-@ type StringN N     = {v:String     | len v  = N} @-}
+
+-- | Legal Bytestrings 
+
+{- good1 :: IO (ByteStringN 5) @-}
+good1 = do fp <- mallocForeignPtrBytes 5
+           return $ PS fp 0 5
+
+{- good2 :: IO (ByteStringN 3) @-}
+good2 = do fp <- mallocForeignPtrBytes 5
+           return $ PS fp 2 3
+
+-- | Illegal Bytestrings 
+
+bad1 = do fp <- mallocForeignPtrBytes 3 
+          return $ PS fp 0 10 
+
+bad2 = do fp <- mallocForeignPtrBytes 3
+          return $ PS fp 2 2
+
+
+
+-- | ByteString API: `create`
+
+create :: Int -> (Ptr Word8 -> IO ()) -> ByteString
+
+create n fill = unsafePerformIO $ do
+  fp  <- mallocForeignPtrBytes n
+  withForeignPtr fp fill 
+  return $! PS fp 0 n
+
+
+-- Yikes, there is an error! How to fix?
+
+-- | ByteStringN API: `unsafeTake`
+
+unsafeTake n (PS x s l) = PS x s n
+
+-- Wow, thats super fast. O(1)! But how to fix the error?
+
+-- | ByteString API: `pack`
+
+pack          :: String -> ByteString
+pack str      = create n $ \p -> go p xs
+  where
+  n           = length str
+  xs          = map c2w str
+  go p (x:xs) = poke p x >> go (plusPtr p 1) xs
+  go _ []     = return  ()
+
+-- Hmm. How to fix the error?
+
+
+
+-- | ByteString API: `unpack` 
+
+
+
+
+unpack :: ByteString -> String 
+unpack (PS _  _ 0)  = []
+unpack (PS ps s l)  = unsafePerformIO $ withForeignPtr ps $ \p ->
+   go (p `plusPtr` s) (l - 1) []
+  where
+   go p 0 acc = peek p >>= \e -> return (w2c e : acc)
+   go p n acc = peek (p `plusPtr` n) >>= \e -> go p (n-1) (w2c e : acc)
+
+
+
+------------------------------------------------------------------------
+-- | 3. Application API (Heartbleed no more!) --------------------------
+------------------------------------------------------------------------
+
+chop     :: String -> Int -> String 
+chop s n =  s'
+  where 
+    b    = pack s          -- down to low-level
+    b'   = unsafeTake n b  -- grab n chars
+    s'   = unpack b'       -- up to high-level
+
+-- Whats the problem?
+
+
+
+
+
+-- | "HeartBleed" no more
+
+demo     = [ex6, ex30]
+  where
+    ex   = ['R','a','n','j','i','t']
+    ex6  = chop ex 6  -- ok
+    ex30 = chop ex 30 -- out of bounds
+
+
+-- "Bleeding" `chop ex 30` *rejected* by compiler
+
+
+
+------------------------------------------------------------------------
+-- | 3. Bonus Material -------------------------------------------------
+------------------------------------------------------------------------
+
+-- | `group` ing ByteStrings 
+
+{- How shall we type `group` where
+
+     group "foobaaar"
+
+   returns
+
+     ["f","oo", "b", "aaa", "r"]
+
+-}
+
+-- | An alias for NON-EMPTY ByteStrings
+    
+{-@ type ByteStringNE = {v:ByteString | bLen v > 0} @-}
+
+-- | A measure for the sum of sizes of a LIST of ByteStrings
+    
+{-@ measure bLens  :: [ByteString] -> Int
+    bLens ([])   = 0
+    bLens (x:xs) = (bLen x + bLens xs)
+  @-}
+
+-- | @group@
+    
+{-@ group :: b:ByteString -> {v: [ByteStringNE] | bLens v = bLen b} @-}
+group xs
+    | null xs   = []
+    | otherwise = let y = unsafeHead xs
+                      (ys, zs) = spanByte (unsafeHead xs) (unsafeTail xs)
+                  in (y `cons` ys) : group zs
+
+
+-- | @spanByte@ does the heavy lifting
+
+{-@ spanByte :: Word8 -> b:ByteString -> (ByteStringPair b) @-}
+spanByte :: Word8 -> ByteString -> (ByteString, ByteString)
+spanByte c ps@(PS x s l) = unsafePerformIO $ withForeignPtr x $ \p ->
+    go (p `plusPtr` s) 0
+  where
+    go p i | i >= l    = return (ps, empty)
+           | otherwise = do c' <- peekByteOff p i
+                            if c /= c'
+                                then return (unsafeTake i ps, unsafeDrop i ps)
+                                else go p (i+1)
+
+-- | Using the alias
+                            
+{-@ type ByteStringPair B = (ByteString, ByteString)<{\x1 x2 ->
+       bLen x1 + bLen x2 = bLen B}> @-}
+
+
+
+
+
+
+
+
+
+
+
+----------------------------------------------------------------------------
+-- | CHEAT AREA
+----------------------------------------------------------------------------
+
+-- #START ERRORS 13
+-- #END   ERRORS 4 (zero4', bad1, bad2, ex30) 
+                            
+{- create     :: n:Nat -> (PtrN Word8 n -> IO ()) -> ByteStringN n      @-}
+{- unsafeTake :: n:Nat -> b:{ByteString | n <= bLen b} -> ByteStringN n @-}
+{- pack       :: s:String -> ByteStringN (len s)                        @-}
+{- unpack     :: b:ByteString -> {v:String | len v = bLen b}            @-}
+{- chop       :: s:String -> n:{Nat | n <= len s} -> StringN n          @-} 
+
+{- qualif Unpack(v:a, acc:b, n:int) : len v = 1 + n + len acc @-}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | Helper Code (Stuff from BS benchmark, to make demo self-contained)
+-----------------------------------------------------------------------
+
+{-@ unsafeCreate :: l:Nat -> ((PtrN Word8 l) -> IO ()) -> (ByteStringN l) @-}
+unsafeCreate n f = create n f -- unsafePerformIO $ create n f
+
+{-@ invariant {v:ByteString   | bLen  v >= 0} @-}
+{-@ invariant {v:[ByteString] | bLens v >= 0} @-}
+
+{-@ qualif PLLen(v:a, p:b) : (len v) <= (plen p) @-}
+{-@ qualif ForeignPtrN(v:ForeignPtr a, n:int): fplen v = n @-}
+{-@ qualif FPLenPLen(v:Ptr a, fp:ForeignPtr a): fplen fp = plen v @-}
+{-@ qualif PtrLen(v:Ptr a, xs:List b): plen v = len xs @-}
+{-@ qualif PlenEq(v: Ptr a, x: int): x <= (plen v) @-}
+
+{-@ unsafeHead :: {v:ByteString | (bLen v) > 0} -> Word8 @-}
+
+unsafeHead :: ByteString -> Word8
+unsafeHead (PS x s l) = liquidAssert (l > 0) $
+  unsafePerformIO  $  withForeignPtr x $ \p -> peekByteOff p s
+
+{-@ unsafeTail :: b:{v:ByteString | (bLen v) > 0}
+               -> {v:ByteString | (bLen v) = (bLen b) - 1} @-}
+unsafeTail :: ByteString -> ByteString
+unsafeTail (PS ps s l) = liquidAssert (l > 0) $ PS ps (s+1) (l-1)
+
+{-@ null :: b:ByteString -> {v:Bool | ((Prop v) <=> ((bLen b) = 0))} @-}
+null :: ByteString -> Bool
+null (PS _ _ l) = liquidAssert (l >= 0) $ l <= 0
+
+{-@ unsafeDrop :: n:Nat
+               -> b:{v: ByteString | n <= (bLen v)} 
+               -> {v:ByteString | (bLen v) = (bLen b) - n} @-}
+unsafeDrop  :: Int -> ByteString -> ByteString
+unsafeDrop n (PS x s l) = liquidAssert (0 <= n && n <= l) $ PS x (s+n) (l-n)
+
+{-@ cons :: Word8 -> b:ByteString -> {v:ByteString | (bLen v) = 1 + (bLen b)} @-}
+cons :: Word8 -> ByteString -> ByteString
+cons c (PS x s l) = unsafeCreate (l+1) $ \p -> withForeignPtr x $ \f -> do
+        poke p c
+        memcpy (p `plusPtr` 1) (f `plusPtr` s) (fromIntegral l)
+
+{-@ empty :: {v:ByteString | (bLen v) = 0} @-} 
+empty :: ByteString
+empty = PS nullForeignPtr 0 0
+
+{-@ assume
+    c_memcpy :: dst:(PtrV Word8)
+             -> src:(PtrV Word8) 
+             -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))} 
+             -> IO (Ptr Word8)
+  @-}
+foreign import ccall unsafe "string.h memcpy" c_memcpy
+    :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)
+
+{-@ memcpy :: dst:(PtrV Word8)
+           -> src:(PtrV Word8) 
+           -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))} 
+           -> IO () 
+  @-}
+memcpy :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()
+memcpy p q s = c_memcpy p q s >> return ()
+
+{-@ assume nullForeignPtr :: {v: ForeignPtr Word8 | (fplen v) = 0} @-}
+nullForeignPtr :: ForeignPtr Word8
+nullForeignPtr = unsafePerformIO $ newForeignPtr_ nullPtr
+{-# NOINLINE nullForeignPtr #-}
+
+
+
diff --git a/docs/slides/HS2014/Basics-blank.hs b/docs/slides/HS2014/Basics-blank.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/HS2014/Basics-blank.hs
@@ -0,0 +1,105 @@
+module Basics where
+
+-- list of numbers between 0 and 100
+
+list = [1,10,30]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+range :: Int -> Int -> [Int]
+range lo hi
+  | lo <= hi  = lo : range (lo + 1)  hi
+  | otherwise = []
+
+-- range 1 4 = [1,2,3]
+-- range 1 1 = []
+
+
+
+
+
+
+
+
+
+
+-- length (range lo hi) = hi - lo
+
+
+
+
+
+
+
+
+
+
+
+
+-- measures let us describe properties of data
+-- without *embedding* them into the data definition!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+data CSV a = CSV { cols :: [String], rows :: [[a]] }
+
+csv = CSV [ "Month", "Days"]
+          [ ["Jan",  "31"]
+          , ["Feb", "28"] 
+          ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-- Local Variables:
+-- flycheck-checker: haskell-liquid
+-- End:
+
+-- list :: [Int]
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--diffcheck" @-}
+{-@ LIQUID "--short-names" @-}
diff --git a/docs/slides/HS2014/Basics.lhs b/docs/slides/HS2014/Basics.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/HS2014/Basics.lhs
@@ -0,0 +1,288 @@
+> {-@ LIQUID "--no-termination" @-}
+> {-@ LIQUID "--short-names"    @-}
+> 
+> module Basics where
+> 
+> import Prelude hiding (head, max)
+> import qualified Data.ByteString.Char8 as B
+> import qualified Data.ByteString.Unsafe as B
+> import Data.List (find)
+> import Language.Haskell.Liquid.Prelude
+
+Well-typed programs can't go wrong.
+
+> dog = B.pack "dog"
+
+< λ> B.unsafeIndex dog 2
+< 103
+< λ> B.unsafeIndex dog 10
+< 0
+< λ> B.unsafeIndex dog 10000000000
+< segmentation fault
+
+That's no good, it would be nice if the type system could prevent us from doing
+that. Today I'm going to present our experience in designing such a type system,
+and in using it to verify over 10KLoC of real Haskell code.
+
+
+Refinement Types
+================
+
+We'll start with a lightning tour of LiquidHaskell before getting into the
+gritty benchmarks.
+
+A refinment type is a Haskell type where each component of the type is annotated
+with a predicate from an SMT-decidable logic. For example,
+
+< {v:Int | v >= 0 && v < 100}
+
+describes the set of `Int`s that are between 0 and 100. We'll make heavy use of
+*aliases* to simplify the types, e.g.
+
+> {-@ predicate Btwn Lo N Hi = Lo <= N && N < Hi @-}
+> {-@ type Rng Lo Hi = {v:Int | Btwn Lo v Hi}    @-}
+
+< Rng 0 100
+
+is equivalent to the first type.
+
+To double check note that,
+
+> {-@ okRange :: [Rng 0 100] @-}
+> okRange = [1,10,30] :: [Int]
+ 
+but, of course,
+
+> {-@ badRange :: [Rng 0 100] @-}
+> badRange = [1,10,300] :: [Int]
+
+
+We can describe a function's *contract* by refining its input and output types
+with our desired pre- and post-conditions.
+
+> {-@ range :: lo:Int -> hi:{Int | lo <= hi} -> [Rng lo hi] @-}
+
+This type tells us that `range` accepts two `Int`s, the second being larger than
+the first, and returns a `[Int]` where all of the elements are between `lo` and
+`hi`. Now if we implement `range`
+
+> range :: Int -> Int -> [Int]
+> range lo hi
+>   | lo <= hi  = lo : range (lo + 1) hi
+>   | otherwise = []
+
+LiquidHaskell complains that `lo` is not *strictly* less than `hi`!
+
+Fortunately, that's easily fixed, we'll just replace the `<=` in the guard with `<`.
+
+> {-@ range' :: lo:Int -> hi:{Int | lo <= hi} -> [Rng lo hi] @-}
+> range' :: Int -> Int -> [Int]
+> range' lo hi
+>   | lo < hi   = lo : range' (lo + 1) hi
+>   | otherwise = []
+
+
+Holes
+-----
+
+Typing out the base Haskell types can be tedious, especially since GHC will
+infer them. So we use `_` to represent a *type-hole*, which LiquidHaskell will
+automatically fill in by asking GHC. For example, if we wrote a function
+`rangeFind` with type
+
+< (Int -> Bool) -> Int -> Int -> Maybe Int
+
+we could write the refined type
+
+> {-@ rangeFind :: _ -> lo:_ -> hi:{_ | lo <= hi} -> Maybe (Rng lo hi) @-}
+> rangeFind f lo hi = find f $ range lo hi
+
+Note that in order for `rangeFind` to type-check, LiquidHaskell has to infer
+that `find` returns a `Maybe (Rng lo hi)` (show off liquid-pos-tip), which it
+does by instantiating `find`s type parameter `a` with `Rng lo hi`.
+
+Ok, we can talk about Integers, what about arbitrary, user-defined datatypes?
+
+
+Measures
+========
+
+Let's go one step further with `range` and reason about the length of the 
+resulting list. Given that
+
+< range 0 2 == [0,1]
+
+and
+
+< range 1 1 == []
+
+it looks like the length of the output list should be `hi - lo`, but how do we 
+express that in LiquidHaskell?
+
+(Instead of defining an index that is baked into the type definition)
+we'll define a *measure*, which you can think of as a *view* of the datatype.
+
+< {-@ measure len :: [a] -> Int
+<     len ([])   = 0
+<     len (x:xs) = 1 + (len xs)
+<   @-}
+
+Measures look like Haskell functions, but they're *not*. They are a very
+restricted subset of inductively-defined Haskell functions with a single
+equation per data constructor. LiquidHaskell translates measures into refined
+types for the data constructors, e.g.
+
+< []  :: {v:[a] | len v = 0}
+< (:) :: _ -> xs:_ -> {v:[a] | len v = len xs + 1}
+
+ASIDE: another great spot to show off liquid-pos-tip.
+NV: state that measures are uninterpreted functions into logic
+
+> mylist = 1 : []
+
+LiquidHaskell's interpretation of measures is a key distinction from indexed
+data types, because we can define multiple measures independently of the actual
+type definition, and LiquidHaskell will just conjoin the refinements arising
+from the individual measures.
+
+ASIDE: perhaps quickly show by defining `measure null` as a throwaway.
+
+With our measure in hand we can now specify our final type for `range`
+
+> {-@ range'' :: lo:Int -> hi:{Int | lo <= hi} -> {v:[Rng lo hi] | len v = hi - lo } @-}
+
+Notice that we don't need to change the implementation at all, LiquidHaskell 
+accepts it as is!
+
+> range'' :: Int -> Int -> [Int]
+> range'' lo hi
+>   | lo < hi   = lo : range'' (lo + 1) hi
+>   | otherwise = []
+
+We can also give precise specifications to, e.g., `append`
+
+> {-@ append :: xs:_ -> ys:_ -> {v:_ | len v = len xs + len ys} @-}
+> append []     ys = ys
+> append (x:xs) ys = x : append xs ys
+
+
+
+
+Refined Data Types
+------------------
+
+Sometimes we *want* every instance of a type to satisfy some invariant. Every
+row in a `CSV` table should have the same number of columns.
+
+NV: Universal invariants that we get by type polymorphism is not trivial, 
+so maybe give a simple type like [{v:Int |  v > 0}]
+before going into [ListL a cols]
+
+
+> data CSV a = CSV { cols :: [String], rows :: [[a]] }
+> {-@ type ListL a L = {v:[a] | len v = len L} @-}
+> {-@ data CSV a = CSV { cols :: [String], rows :: [ListL a cols] } @-}
+
+Since the invariant is *baked into* the refined type definition, LiquidHaskell
+will reject *any* `CSV` value that does not satisfy the invariant.
+
+> good_2 = CSV [ "Month", "Days"]
+>              [ ["Jan", "31"]
+>              , ["Feb", "28"] ]
+> bad_2  = CSV [ "Month", "Days"]
+>              [ ["Jan", "31"]
+>              , ["Feb"] ]
+
+
+
+RJ:BEGIN-CUT
+
+Refined Type-Classes
+--------------------
+
+Perhaps there's a common interface that we want multiple data types to support,
+e.g. random-access. Many such interfaces have protocols that define how to
+*safely* use the interface, like "don't index out-of-bounds". We can describe
+these protocols in LiquidHaskell by packaging the functions into a type-class
+and giving it a refined definition.
+
+> class Indexable f where
+>   size :: f a -> Int
+>   at   :: f a -> Int -> a
+>
+> {-@
+> class Indexable f where
+>   size :: forall a. xs:f a -> {v:Nat | v = sz xs}
+>   at   :: forall a. xs:f a -> {v:Nat | v < sz xs} -> a
+> @-}
+
+This poses a bit of a problem though, how do we define the `sz` measure?
+Measures have to be defined for a specific datatype so LiquidHaskell can refine
+the constructors. We'll work around this issue by introducing *type-indexed*
+measures.
+
+> {-@ class measure sz :: forall a. a -> Int @-}
+> {-@ instance measure sz :: [a] -> Int
+>     sz ([])   = 0
+>     sz (x:xs) = 1 + (sz xs)
+>   @-}
+> {-@ invariant {v:[a] | sz v >= 0} @-}
+
+Apart from allowing definitions for multiple types, class measures work just
+like regular measures, i.e. they're translated into refined data constructor
+types.
+
+If we go ahead and define an instance for lists,
+
+> instance Indexable [] where
+>   size []        = 0
+>   size (x:xs)    = 1 + size xs
+>
+>   (x:xs) `at` 0  = x
+>   (x:xs) `at` i  = xs `at` (i-1)
+
+LiquidHaskell will verify that our implementation matches the class
+specification.
+
+Clients of a type-class get to assume that the instances have been defined
+correctly, i.e. LiquidHaskell will happily prove that 
+
+> sum :: (Indexable f) => f Int -> Int
+> sum xs = go 0 
+>   where
+>     go i | i < size xs = xs `at` i + go (i+1)
+>          | otherwise   = 0
+
+is safe for **all** instances of `Indexable`.
+
+
+Abstract Refinements
+--------------------
+
+All of the examples so far have used *concrete* refinements, but sometimes
+we just want to say that *some* property will be preserved by the function, e.g.
+
+> max     :: Int -> Int -> Int 
+> max x y = if x > y then x else y
+>
+> {-@ xPos  :: {v: _ | v > 0} @-}
+> xPos  = max 10 13
+>
+> {-@ xNeg  :: {v: _ | v < 0} @-}
+> xNeg  = max (0-5) (0-8)
+>
+> {-@ xEven :: {v: _ | v mod 2 == 0} @-}
+> xEven = max 4 (0-6)
+
+Since `max` returns one of it's arguments, we know that if *both* inputs share
+some property, then *so will the output*. In LiquidHaskell we can express this
+by abstracting over the refinements.
+
+> {-@ max :: forall <p :: Int -> Prop>.
+>            Int<p> -> Int<p> -> Int<p>
+>   @-}
+
+RJ:END-CUT
+
+Now that we've covered the basics of using LiquidHaskell, let's take a look at
+our first experiment: proving functions total.
diff --git a/docs/slides/HS2014/ByteString-BAD-DIFFCHECK.hs b/docs/slides/HS2014/ByteString-BAD-DIFFCHECK.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/HS2014/ByteString-BAD-DIFFCHECK.hs
@@ -0,0 +1,108 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--diffcheck"      @-}
+{-@ LIQUID "--short-names"    @-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module Bytestring where
+
+import Prelude hiding (null)
+import Data.Char
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
+import System.IO.Unsafe
+import Language.Haskell.Liquid.Prelude
+
+
+data ByteString = PS { bPayload :: ForeignPtr Word8
+                     , bOffset  :: !Int
+                     , bLength  :: !Int
+                     }
+
+{- measure fplen :: ForeignPtr a -> Int -}
+
+{-@ data ByteString = PS
+      { bPayload :: ForeignPtr Word8
+      , bOffset  :: {v:Nat | v           <= fplen bPayload}
+      , bLength  :: {v:Nat | bOffset + v <= fplen bPayload}
+      }
+  @-}
+
+{-@ type ByteStringN N = {v:ByteString | bLength v = N} @-}
+
+{-@ type ForeignN a N = {v:ForeignPtr a | fplen v = N} @-}
+{-@ assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignN a n) @-}
+
+bs = do fp <- mallocForeignPtrBytes 5
+        return $ PS fp 2 3
+
+{-@ create :: l:Nat -> (PtrN Word8 l -> IO ()) -> IO (ByteStringN l) @-}
+create l f = do
+    fp <- mallocForeignPtrBytes  l
+    withForeignPtr fp $ \p -> f p
+    return $! PS fp 0 l
+
+foo = create 5 $ \p -> poke (p `plusPtr` 4) (0 :: Word8)
+
+{-@ pack :: s:[Word8] -> ByteStringN (len s) @-}
+pack str = unsafeCreate (length str) $ \p -> go p  str
+  where
+    go _ []     = return  ()
+    go p (x:xs) = poke p x >> go (p `plusPtr` 1) xs
+
+
+-- uncomment this spec and then twiddle the definition to rerun diffcheck, it 
+-- will only resolve the type error on the line you twiddle.
+{- unsafeIndex :: b:ByteString -> {v:Nat | v < bLength b} -> Word8 @-}
+unsafeIndex (PS x s l) i = liquidAssert (i >= 0 && i < l)  $
+    unsafePerformIO $ withForeignPtr x $ \p -> peekByteOff p (s + i) --FIXME: diffcheck breaks here
+
+
+
+
+
+good = let b = pack [1,2,3]
+       in unsafeIndex b 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- Helper Code
+-----------------------------------------------------------------------
+{-@ unsafeCreate :: l:Nat -> (PtrN Word8 l -> IO ()) -> (ByteStringN l) @-}
+unsafeCreate n f = unsafePerformIO $ create n f
+
+{-@ invariant {v:ByteString   | bLength  v >= 0} @-}
+
+{-@ qualif PLLen(v:a, p:b) : (len v) <= (plen p) @-}
+{-@ qualif ForeignPtrN(v:ForeignPtr a, n:int): fplen v = n @-}
+{-@ qualif FPLenPLen(v:Ptr a, fp:ForeignPtr a): fplen fp = plen v @-}
+{-@ qualif PtrLen(v:Ptr a, xs:List b): plen v = len xs @-}
+{-@ qualif PlenEq(v: Ptr a, x: int): x <= (plen v) @-}
+
+-- Local Variables:
+-- flycheck-checker: haskell-liquid
+-- End:
+
+create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString
+unsafeIndex :: ByteString -> Int -> Word8
diff --git a/docs/slides/HS2014/ByteString-blank.hs b/docs/slides/HS2014/ByteString-blank.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/HS2014/ByteString-blank.hs
@@ -0,0 +1,213 @@
+module Bytestring where
+
+import Prelude hiding (null)
+import Data.Char
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
+import System.IO.Unsafe
+import Language.Haskell.Liquid.Prelude
+
+
+data ByteString = PS { bPayload :: ForeignPtr Word8
+                     , bOffset  :: !Int
+                     , bLength  :: !Int
+                     }
+
+{- measure fplen :: ForeignPtr a -> Int -}
+
+{-@ data ByteString = PS
+      { bPayload :: ForeignPtr Word8
+      , bOffset  :: {v:Nat | v           <= fplen bPayload}
+      , bLength  :: {v:Nat | bOffset + v <= fplen bPayload}
+      }
+  @-}
+
+{-@ type ByteStringN N = {v:ByteString | bLength v = N} @-}
+
+{-@ type ForeignN a N = {v:ForeignPtr a | fplen v = N} @-}
+{-@ assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignN a n) @-}
+
+bs = do fp <- mallocForeignPtrBytes 5
+        return $ PS fp 2 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+create l f = do
+    fp <- mallocForeignPtrBytes l
+    withForeignPtr fp $ \p -> f p
+    return $! PS fp 0 l
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+foo = create 5 $ \p -> poke (p `plusPtr` 4) (0 :: Word8)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+pack str = unsafeCreate (length str) $ \p -> go p  str
+  where
+    go _ []     = return ()
+    go p (x:xs) = poke p x >> go (p `plusPtr` 1) xs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+unsafeIndex (PS x s l) i = liquidAssert (i >= 0 && i < l)  $
+    unsafePerformIO $ withForeignPtr x $ \p -> peekByteOff p (s+i)
+
+
+
+
+good = let b = pack [1,2,3]
+       in unsafeIndex b 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- Helper Code
+-----------------------------------------------------------------------
+{-@ unsafeCreate :: l:Nat -> (PtrN Word8 l -> IO ()) -> (ByteStringN l) @-}
+unsafeCreate n f = unsafePerformIO $ create n f
+
+{-@ invariant {v:ByteString   | bLength  v >= 0} @-}
+
+{-@ qualif PLLen(v:a, p:b) : (len v) <= (plen p) @-}
+{-@ qualif ForeignPtrN(v:ForeignPtr a, n:int): fplen v = n @-}
+{-@ qualif FPLenPLen(v:Ptr a, fp:ForeignPtr a): fplen fp = plen v @-}
+{-@ qualif PtrLen(v:Ptr a, xs:List b): plen v = len xs @-}
+{-@ qualif PlenEq(v: Ptr a, x: int): x <= (plen v) @-}
+
+-- Local Variables:
+-- flycheck-checker: haskell-liquid
+-- End:
+
+create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString
+unsafeIndex :: ByteString -> Int -> Word8
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--diffcheck"      @-}
+{-@ LIQUID "--short-names"    @-}
diff --git a/docs/slides/HS2014/ByteString.lhs b/docs/slides/HS2014/ByteString.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/HS2014/ByteString.lhs
@@ -0,0 +1,344 @@
+> {-@ LIQUID "--no-termination" @-}
+> {-@ LIQUID "--short-names"    @-}
+> {-@  LIQUID "--diffcheck"     @-}
+> {-# LANGUAGE ForeignFunctionInterface #-}
+> 
+> module Bytestring where
+> 
+> import Prelude hiding (null)
+> import Data.Char
+> import Data.Word
+> import Foreign.C.Types
+> import Foreign.ForeignPtr
+> import Foreign.Ptr
+> import Foreign.Storable
+> import System.IO.Unsafe
+> import Language.Haskell.Liquid.Prelude
+
+Now for some real fun, let's try to prove that `ByteString` is memory-safe! 
+
+`ByteString`s are at the heart of many Haskell applications, e.g. web servers, 
+and, as we saw at the beginning of the talk, a bad access can lead to a segfault 
+or, even worse, leaking arbitrary memory.
+
+A `ByteString` consists of a pointer into a region of memory, an offset into 
+the region, and a length.
+
+> data ByteString = PS { bPayload :: ForeignPtr Word8
+>                      , bOffset  :: !Int
+>                      , bLength  :: !Int
+>                      }
+
+The crucial invariant is that we should only be able to reach valid memory 
+locations via the offset and length, i.e. the sum `off + len` *must not exceed* 
+the "length" of the pointer.
+
+> {-@ data ByteString = PS
+>       { bPayload :: ForeignPtr Word8
+>       , bOffset  :: {v:Nat | v           <= fplen bPayload}
+>       , bLength  :: {v:Nat | bOffset + v <= fplen bPayload}
+>       }
+>   @-}
+
+What is the "length" of a pointer? It's the number of bytes that are
+addressable from the base of the pointer. We can't compute it, but that
+won't stop us from talking about it in our types. We provide a "ghost"
+measure called `fplen` to refer to this length.
+
+NV: "ghost measure" is more complicated than uninterpreted function
+
+< {-@ measure fplen :: ForeignPtr a -> Int @-}
+
+and use it to define a foreign-pointer to a segment containing *N* bytes
+
+> {-@ type ForeignN a N = {v:ForeignPtr a | fplen v = N} @-}
+
+Since we haven't defined any equations for `fplen` we won't get strengthed 
+constructors. Instead, we will *assume* that `malloc` behaves sensibly and
+allocates the number of bytes you asked for.
+
+> {-@ assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignN a n) @-}
+
+Now let's create a few `ByteString`s. Here's a `ByteString` with 5 valid 
+indices. 
+
+> good_bs1 = do fp <- mallocForeignPtrBytes 5
+>               return $ PS fp 0 5
+
+Note that the *length* of the BS is *not* the same as the region
+of allocated memory. 
+
+Here's a `ByteString` whose pointer region has 5-bytes, but the BS itself
+is of size 4.
+ 
+> good_bs2 = do fp <- mallocForeignPtrBytes 5
+>               return $ PS fp 2 4
+
+LiquidHaskell won't let us build a `ByteString` that claims to have more valid 
+indices than it *actually* does
+
+> bad_bs1 = do
+>   fp <- mallocForeignPtrBytes 0 
+>   return $ PS fp 0 10 
+
+even if we try to be sneaky with the length parameter.
+
+> bad_bs2 = do fp <- mallocForeignPtrBytes 3
+>              return $ PS fp 2 2
+
+
+Creating ByteStrings
+--------------------
+
+Nobody actually builds `ByteString`s like this though.
+
+The authors have kindly provided a higher-order function
+called `create` to handle the actual allocation. To `create`
+a `ByteString` you have to say how many bytes you want and
+provide a function that will fill in the newly allocated memory.
+
+> create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString
+> create l f = do
+>     fp <- mallocForeignPtrBytes l
+>     withForeignPtr fp $ \p -> f p
+>     return $! PS fp 0 l
+
+But this seems horribly unsafe!
+
+What's to stop the parameter `f` from poking any random,
+invalid offset from the pointer it wants to?
+
+We could, e.g.
+
+* create a BS of size `5`, and
+* write a `0` at the index `10`.
+
+ASIDE: have these assumed types around to suppress the type-errors that LH will 
+       show, just remove them when script introduces type
+
+> {- assume plusPtr :: p:Ptr a -> n:Int -> Ptr b      @-}
+> {- assume poke :: Storable a => Ptr a -> a -> IO () @-}
+
+END ASIDE
+
+> bad_create = create 5 $ \p -> poke (p `plusPtr` 10) (0 :: Word8)
+
+which clearly isn't correct. We'd like to say that the provided
+function can only address locations a up to a certain offset
+from the pointer.
+
+Just as we had `fplen` to talk about the "length" of a `ForeignPtr`,
+we have provided `plen` to talk about the "length" of a `Ptr`, and
+we've defined a helpful alias
+
+< {-@ type PtrN a N = {v:Ptr a | plen v = N} @-}
+
+which says that a `PtrN a n` has precisely `n` addressable bytes
+from its base.
+
+
+Pointer Arithmetic
+------------------
+
+We have also given `plusPtr` the type
+
+< {-@ plusPtr :: p:Ptr a -> n:Int -> {v:Ptr a | plen v = plen p - n} @-}
+
+which says that as you increment a `Ptr`, you're left with fewer addressable
+bytes.
+
+Finally, we type `poke` as 
+
+< {-@ poke :: Storable a => {v:Ptr a | 0 <= plen v } -> a -> IO () @-}
+
+which says that the given `Ptr` must be addressable in order to safely `poke` it.
+
+Now we have all of the necessary tools to *prevent* ourselves from
+shooting ourselves in the foot with functions like `bad_create`.
+
+We'll just give `create` the type
+ 
+> {-@ create :: l:Nat -> (PtrN Word8 l -> IO ()) -> IO (ByteStringN l) @-}
+
+where the alias
+
+> {-@ type ByteStringN N = {v:ByteString | bLength v = N} @-}
+
+describes `ByteString`s of length `N`.
+
+Lo and behold, LiquidHaskell has flagged `bad_create` as unsafe! 
+
+Furthermore, we can write things like
+
+> good_create = create 5 $ \p -> poke (p `plusPtr` 2) (0 :: Word8)
+
+Here's a real example from the BS library:
+
+> packWith        :: (a -> Word8) -> [a] -> ByteString
+> packWith k str  = unsafeCreate (length str) $ \p -> go p str
+>   where
+>     go _ []     = return ()
+>     go p (x:xs) = poke p (k x) >> go (p `plusPtr` 1) xs
+
+proving that `pack` will *never* write out-of-bounds!
+
+
+ES: CUT
+
+
+Nested Data
+-----------
+
+For a more in depth example, let's take a look at `group`,
+which transforms strings like
+
+   `"foobaaar"`
+
+into *lists* of strings like
+
+   `["f","oo", "b", "aaa", "r"]`.
+
+The specification is that `group` should produce a list of `ByteStrings`
+
+1. that are all *non-empty* (safety)
+2. the sum of whose lengths is equal to the length of the input string (precision)
+
+We use the type alias
+
+> {-@ type ByteStringNE = {v:ByteString | bLength v > 0} @-}
+
+to specify (safety) and introduce a new measure
+
+> {-@ measure bLengths  :: [ByteString] -> Int
+>     bLengths ([])   = 0
+>     bLengths (x:xs) = (bLength x) + (bLengths xs)
+>   @-}
+
+to specify (precision). The full type-specification looks like this:
+
+> {-@ group :: b:ByteString -> {v: [ByteStringNE] | bLengths v = bLength b} @-}
+> group xs
+>     | null xs   = []
+>     | otherwise = let y = unsafeHead xs
+>                       (ys, zs) = spanByte (unsafeHead xs) (unsafeTail xs)
+>                   in (y `cons` ys) : group zs
+
+As you can probably tell, `spanByte` appears to be doing a lot of the work here,
+so let's take a closer look at it to see why the post-condition holds.
+
+> spanByte :: Word8 -> ByteString -> (ByteString, ByteString)
+> spanByte c ps@(PS x s l) = unsafePerformIO $ withForeignPtr x $ \p ->
+>     go (p `plusPtr` s) 0
+>   where
+>     go p i | i >= l    = return (ps, empty)
+>            | otherwise = do c' <- peekByteOff p i
+>                             if c /= c'
+>                                 then return (unsafeTake i ps, unsafeDrop i ps)
+>                                 else go p (i+1)
+
+LiquidHaskell infers that `0 <= i <= l` and therefore that all of the memory
+accesses are safe. Furthermore, due to the precise specifications given to
+`unsafeTake` and `unsafeDrop`, it is able to prove that `spanByte` has the type
+
+> {-@ spanByte :: Word8 -> b:ByteString -> (ByteStringPair b) @-}
+
+where `ByteStringPair b` describes a pair of `ByteString`s whose lengths sum to
+the length of `b`.
+
+> {-@ type ByteStringPair B = (ByteString, ByteString)<{\x1 x2 ->
+>       bLength x1 + bLength x2 = bLength B}> @-}
+
+
+RJ:LIMITATIONS
+
+Those familiar with the internals of ByteString may notice that we have made a
+small change in `group`, the original implementation was
+
+< group :: ByteString -> [ByteString]
+< group xs
+<     | null xs   = []
+<     | otherwise = ys : group zs
+<     where
+<         (ys, zs) = spanByte (unsafeHead xs) xs
+
+Unfortunately this change was necessary in order to prove the safety invariant,
+that `group` returns a list of non-empty `ByteString`s. The real type we would
+like to give to `spanByte` (which would enable verification of the original
+`group`) would say something like
+
+  `spanByte x b` returns a pair of `ByteString`s, the first of which is non-empty
+  *iff* `x = head b`
+
+but it is unclear how to prove this at the moment in LiquidHaskell
+(TODO: figure out what would need to change to prove this.)
+
+> -----------------------------------------------------------------------
+> -- Helper Code
+> -----------------------------------------------------------------------
+> {-@ unsafeCreate :: l:Nat -> ((PtrN Word8 l) -> IO ()) -> (ByteStringN l) @-}
+> unsafeCreate n f = unsafePerformIO $ create n f
+>
+> {-@ invariant {v:ByteString   | bLength  v >= 0} @-}
+> {-@ invariant {v:[ByteString] | bLengths v >= 0} @-}
+> 
+> {-@ qualif PLLen(v:a, p:b) : (len v) <= (plen p) @-}
+> {-@ qualif ForeignPtrN(v:ForeignPtr a, n:int): fplen v = n @-}
+> {-@ qualif FPLenPLen(v:Ptr a, fp:ForeignPtr a): fplen fp = plen v @-}
+> {-@ qualif PtrLen(v:Ptr a, xs:List b): plen v = len xs @-}
+> {-@ qualif PlenEq(v: Ptr a, x: int): x <= (plen v) @-}
+>
+> {-@ unsafeHead :: {v:ByteString | (bLength v) > 0} -> Word8 @-}
+> unsafeHead :: ByteString -> Word8
+> unsafeHead (PS x s l) = liquidAssert (l > 0) $
+>   unsafePerformIO  $  withForeignPtr x $ \p -> peekByteOff p s
+> 
+> {-@ unsafeTail :: b:{v:ByteString | (bLength v) > 0}
+>                -> {v:ByteString | (bLength v) = (bLength b) - 1} @-}
+> unsafeTail :: ByteString -> ByteString
+> unsafeTail (PS ps s l) = liquidAssert (l > 0) $ PS ps (s+1) (l-1)
+> 
+> {-@ null :: b:ByteString -> {v:Bool | ((Prop v) <=> ((bLength b) = 0))} @-}
+> null :: ByteString -> Bool
+> null (PS _ _ l) = liquidAssert (l >= 0) $ l <= 0
+> 
+> {-@ unsafeTake :: n:Nat -> b:{v: ByteString | n <= (bLength v)} -> (ByteStringN n) @-}
+> unsafeTake :: Int -> ByteString -> ByteString
+> unsafeTake n (PS x s l) = liquidAssert (0 <= n && n <= l) $ PS x s n
+> 
+> {-@ unsafeDrop :: n:Nat
+>                -> b:{v: ByteString | n <= (bLength v)} 
+>                -> {v:ByteString | (bLength v) = (bLength b) - n} @-}
+> unsafeDrop  :: Int -> ByteString -> ByteString
+> unsafeDrop n (PS x s l) = liquidAssert (0 <= n && n <= l) $ PS x (s+n) (l-n)
+> 
+> {-@ cons :: Word8 -> b:ByteString -> {v:ByteString | (bLength v) = 1 + (bLength b)} @-}
+> cons :: Word8 -> ByteString -> ByteString
+> cons c (PS x s l) = unsafeCreate (l+1) $ \p -> withForeignPtr x $ \f -> do
+>         poke p c
+>         memcpy (p `plusPtr` 1) (f `plusPtr` s) (fromIntegral l)
+> 
+> {-@ empty :: {v:ByteString | (bLength v) = 0} @-} 
+> empty :: ByteString
+> empty = PS nullForeignPtr 0 0
+> 
+> {-@ assume
+>     c_memcpy :: dst:(PtrV Word8)
+>              -> src:(PtrV Word8) 
+>              -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))} 
+>              -> IO (Ptr Word8)
+>   @-}
+> foreign import ccall unsafe "string.h memcpy" c_memcpy
+>     :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)
+> 
+> {-@ memcpy :: dst:(PtrV Word8)
+>            -> src:(PtrV Word8) 
+>            -> size: {v:CSize | (v <= (plen src) && v <= (plen dst))} 
+>            -> IO () 
+>   @-}
+> memcpy :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()
+> memcpy p q s = c_memcpy p q s >> return ()
+> 
+> {-@ assume nullForeignPtr :: {v: ForeignPtr Word8 | (fplen v) = 0} @-}
+> nullForeignPtr :: ForeignPtr Word8
+> nullForeignPtr = unsafePerformIO $ newForeignPtr_ nullPtr
+> {-# NOINLINE nullForeignPtr #-}
diff --git a/docs/slides/HS2014/TODO.md b/docs/slides/HS2014/TODO.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/HS2014/TODO.md
@@ -0,0 +1,26 @@
+# Timing
+- basics     5min (currently 12)
+- totality   7min (currently 7)
+- bytestring 8min (currently 12)
+
+figure out sub-segments, allocate time to each, rehearse in isolation
+
+## Desired
+- intro / contrived unsafeIndex motivator: 1 min
+- basics: 6 min
+  - list of numbers between 0 and 100: 1.5 min
+  - range + bug: 1.5 min
+  - measures​ / add length to range output​: ​3​ min
+  - CSV: 1 min
+- totality: 5 min
+  - head: 2 min
+  - safeZipWith: 1 min
+  - nestcomment: 2 min
+- bytestring: 9 min
+  - data definition: 1 min
+  - fplen / "ghost measures": 1 min
+  - make good / bad bytestrings manually: 1 min
+  - create: 4 min
+  - pack: 1 min
+  - unsafeIndex / preventing motivating segfault: 1 min
+- results / conclusion: 1 min
diff --git a/docs/slides/HS2014/Totality-blank.hs b/docs/slides/HS2014/Totality-blank.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/HS2014/Totality-blank.hs
@@ -0,0 +1,73 @@
+{-@ LIQUID "--totality" @-}
+module Totality where
+
+import Prelude hiding (head)
+
+head (x:_) = x
+
+-- head xs = case xs of
+--   (x:_) -> x
+--   []    -> patError "..."
+
+-- patError :: {v:String | false} -> a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+nestcomment n ('{':'-':ss) | n>=0 = (("{-"++cs),rm)
+                                  where (cs,rm) = nestcomment (n+1) ss
+nestcomment n ('-':'}':ss) | n>0  = let (cs,rm) = nestcomment (n-1) ss
+                                    in (("-}"++cs),rm)
+nestcomment n ('-':'}':ss) | n==0 = ("-}",ss)
+nestcomment n (s:ss)       | n>=0 = ((s:cs),rm)
+                                  where (cs,rm) = nestcomment n ss
+nestcomment n [] = ([],[])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-- Local Variables:
+-- flycheck-checker: haskell-liquid
+-- End:
+
+nestcomment :: Int -> String -> (String,String)
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--diffcheck"      @-}
+{-@ LIQUID "--short-names"    @-}
diff --git a/docs/slides/HS2014/Totality.lhs b/docs/slides/HS2014/Totality.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/HS2014/Totality.lhs
@@ -0,0 +1,126 @@
+> {-@ LIQUID "--no-termination" @-}
+> {-@ LIQUID "--totality"       @-}
+> {-@ LIQUID "--diffcheck"      @-}
+> 
+> module Totality where
+> 
+> import Prelude hiding (head)
+> import Language.Haskell.Liquid.Prelude
+> import Control.Exception.Base
+
+One of the most maligned Haskell functions is also one of the simplest.
+
+> head (x:_) = x
+
+Many people argue that `head` and co. should be removed from the Prelude because
+they're partial functions, and partial functions are dangerous.
+
+The often-recommended alternative of making partial functions return a `Maybe` or
+`Either` is often tedious and encourages the use of *other* partial functions like `fromJust`.
+
+What we really ought to do is *prove* that undefined case can never arise.
+
+This is relatively easy in LiquidHaskell.
+
+GHC already does much of the heavy lifting by filling in all of the undefined
+cases with explicit calls to various error functions, e.g.
+
+< head (x:_) = x
+
+is transformed into
+
+< head xs = case xs of
+<   (x:_) = x
+<   []    = patError "..."
+
+The path is clear, we want to make LiquidHaskell prove that we will never call 
+any of these internal error functions that GHC inserts. We can accomplish this 
+by giving each function a refined type where the pre-condition is `false`, i.e.
+
+< {-@ patError :: {v:_ | false} -> a @-}
+
+*If* LiquidHaskell can prove `false` at any of these callsites, it means there 
+was a contradiction somewhere along the way and the call is effectively dead 
+code. So how do we prove that `patError` is unreachable in `head`?
+
+We can specify that `head` should only be called with *non-empty* lists by 
+giving it a refined type like
+
+> {-@ head :: {v:[a] | 0 < len v} -> a @-}
+
+Now, when LiquidHaskell sees the case-analysis on the `[]` case, it puts
+
+< len xs = 0
+
+in the environemnt as usual, *but* we just gave `head` a pre-condition that
+
+< len xs > 0
+
+So we actually end up with
+
+< len xs = 0 && len xs > 0
+
+which is a contradiction, therefore it is safe to "call" `patError` since we 
+have proven that the call will never *actually* happen.
+
+
+Partial Zipping
+---------------
+
+Inside LiquidHaskell, we often want to combine multiple lists, so we use the 
+stalwart `zipWith` function. The problem with `zipWith` is that if the two 
+lists are *not* the same size, it will *silently drop* the remaining items of 
+the longer list.
+
+This is almost *never* what we want, instead we consider it an error to call 
+`zipWith` on lists of non-equal length. So we've written our own `safeZipWith` 
+function that leaves the case of zipping a nil and a cons undefined.
+
+> safeZipWith f = go
+>   where
+>     go (x:xs) (y:ys) = f x y : go xs ys
+>     go []     []     = []
+
+As you can see, LiquidHaskell is not happy with this definition! It (rightly) 
+complains that we've left a case unhandled because we haven't yet told it that 
+we only want `safeZipWith` to accept lists of equal length. Luckily, this is 
+easily rectified, we'll introduce a handy type-alias for a list with the same
+length as another list
+
+> {-@ type ListL a Xs = {v:[a] | len v == len Xs} @-} 
+
+and use it to concisely express our contract for `safeZipWith`.
+
+> {-@ safeZipWith :: (a -> b -> c) -> xs:[a] -> ListL b xs -> ListL c xs @-}
+
+
+Totality in Real-World
+----------------------
+
+If that was not convincing enough, I'll leave you with a final example from 
+HsColour, which is probably invoked thousands of times per day.
+
+> nestcomment :: Int -> String -> (String, String)
+> nestcomment n ('{':'-':ss) | n>=0 = (("{-"++   cs),rm)
+>                                   where (cs,rm) = nestcomment (n+1) ss
+> nestcomment n ('-':'}':ss) | n>0  = let (cs,rm) = nestcomment (n-1) ss
+>                                     in (("-}"++cs),rm)
+> nestcomment n ('-':'}':ss) | n==0 = ("-}",ss)
+> nestcomment n (s:ss)       | n>=0 = ((s:cs),rm)
+>                                   where (cs,rm) = nestcomment n ss
+> nestcomment n [] = ([],[])
+
+What this function does precisely is not that important, notice instead that 
+LiquidHaskell has flagged it as partial, because there's an unhandled case
+
+< nestcomment n (s:ss) | n < 0 = ????
+
+Well, it doesn't seem particularly sensible to have a *negative* nesting depth, 
+so we'll just tell LiquidHaskell that `nestcomment` should really only be 
+called with natural numbers (without incurring the wrath of Peano numbers)!
+
+> {-@ nestcomment :: Nat -> _ -> (_,_) @-}
+
+
+So that was totality, next let's try something more ambitious, proving memory 
+safety in `ByteString`!
diff --git a/docs/slides/IHP14/Makefile b/docs/slides/IHP14/Makefile
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/Makefile
@@ -0,0 +1,91 @@
+####################################################################
+SERVERHOME=nvazou@goto.ucsd.edu:~/public_html/liquidtutorial/
+RJSERVER=rjhala@goto.ucsd.edu:~/public_html/liquid/haskell/plpv/lhs/
+####################################################################
+
+STRIPCODE=./MkCode.hs
+
+REVEAL=pandoc \
+	   --from=markdown\
+	   --to=html5                           \
+	   --standalone                         \
+	   --mathjax \
+	   --section-divs                       \
+	   --template=_support/template.reveal  \
+	   --variable reveal=../_support/reveal.js
+
+FREVEAL=pandoc \
+ 	   --from=markdown+lhs\
+	   --to=html5                           \
+	   --standalone                         \
+	   --mathjax \
+	   --section-divs                       \
+	   --template=_support/template.reveal  \
+	   --variable reveal=../_support/reveal.js
+
+PANDOC=pandoc --columns=80  -s --mathjax --slide-level=2
+SLIDY=$(PANDOC) -t slidy
+DZSLIDES=$(PANDOC) --highlight-style tango --css=slides.css -w dzslides
+HANDOUT=$(PANDOC) --highlight-style tango --css=text.css -w html5
+WEBTEX=$(PANDOC) -s --webtex -i -t slidy
+BEAMER=pandoc -t beamer
+LIQUID=liquid --short-names 
+
+mdObjects   := $(patsubst %.lhs,%.lhs.markdown,$(wildcard lhs/*.lhs))
+htmlObjects := $(patsubst %.lhs,%.lhs.slides.html,$(wildcard lhs/*.lhs))
+pdfObjects  := $(patsubst %.lhs,%.lhs.slides.pdf,$(wildcard lhs/*.lhs))
+fhtmlObjects := $(patsubst %.lhs,%.fast.html,$(wildcard lhs/*.lhs))
+
+####################################################################
+
+
+all: slides 
+
+fast: $(fhtmlObjects)
+
+one: $(mdObjects)
+	$(REVEAL) lhs/.liquid/00_Index.lhs.markdown > lhs/index.html
+
+tut: $(mdObjects)
+	$(REVEAL) lhs/.liquid/*.markdown > lhs/tutorial.html 
+
+slides: $(htmlObjects)
+
+
+pdfslides: $(pdfObjects)
+
+plpv: slides
+	scp lhs/*.html $(RJSERVER)
+
+lhs/.liquid/%.lhs.markdown: lhs/%.lhs
+	-$(LIQUID) $?
+
+
+lhs/%.fast: lhs/%.lhs
+	$(STRIPCODE) $? > $@ 
+
+lhs/%.fast.html: lhs/%.fast
+	$(FREVEAL) $? -o $@ 
+
+lhs/%.lhs.slides.html: lhs/.liquid/%.lhs.markdown
+	$(REVEAL) $? -o $@ 
+
+lhs/%.lhs.slides.pdf: lhs/.liquid/%.lhs.markdown
+	$(BEAMER) $? -o $@
+
+
+copy:
+	cp lhs/*lhs.html html/
+	cp lhs/*lhs.slides.html html/
+	cp css/*.css html/
+	cp -r fonts html/
+	cp index.html html/
+	cp Benchmarks.html html/
+
+clean:
+	cd lhs/ && ../cleanup && cd ../
+#	cd html/ && rm -rf * && cd ../
+#	cp index.html html/
+
+upload: 
+	scp -r html/* $(SERVERHOME)
diff --git a/docs/slides/IHP14/MkCode.hs b/docs/slides/IHP14/MkCode.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/MkCode.hs
@@ -0,0 +1,17 @@
+#!/usr/bin/env runhaskell
+
+import System.Environment   (getArgs)
+import System.FilePath      (replaceExtension)
+import Data.Char            (isSpace)
+import Data.List            (isPrefixOf)
+
+main     = getArgs >>= mapM txFile 
+
+txFile f = (putStrLn . unlines . map txLine . lines) =<< readFile f
+
+txLine l 
+  | pfx `isPrefixOf` l = pfx
+  | otherwise          = l
+  where
+    pfx                = "\\begin{code}"
+
diff --git a/docs/slides/IHP14/_support/.template2.reveal.swp b/docs/slides/IHP14/_support/.template2.reveal.swp
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/_support/.template2.reveal.swp differ
diff --git a/docs/slides/IHP14/_support/liquid.css b/docs/slides/IHP14/_support/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/liquid.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/IHP14/_support/liquidhaskell.css b/docs/slides/IHP14/_support/liquidhaskell.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/liquidhaskell.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/IHP14/_support/reveal.js/.travis.yml b/docs/slides/IHP14/_support/reveal.js/.travis.yml
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - 0.8
+before_script:
+  - npm install -g grunt-cli
diff --git a/docs/slides/IHP14/_support/reveal.js/Gruntfile.js b/docs/slides/IHP14/_support/reveal.js/Gruntfile.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/Gruntfile.js
@@ -0,0 +1,137 @@
+/* global module:false */
+module.exports = function(grunt) {
+	var port = grunt.option('port') || 8000;
+	// Project configuration
+	grunt.initConfig({
+		pkg: grunt.file.readJSON('package.json'),
+		meta: {
+			banner:
+				'/*!\n' +
+				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
+				' * http://lab.hakim.se/reveal-js\n' +
+				' * MIT licensed\n' +
+				' *\n' +
+				' * Copyright (C) 2014 Hakim El Hattab, http://hakim.se\n' +
+				' */'
+		},
+
+		qunit: {
+			files: [ 'test/*.html' ]
+		},
+
+		uglify: {
+			options: {
+				banner: '<%= meta.banner %>\n'
+			},
+			build: {
+				src: 'js/reveal.js',
+				dest: 'js/reveal.min.js'
+			}
+		},
+
+		cssmin: {
+			compress: {
+				files: {
+					'css/reveal.min.css': [ 'css/reveal.css' ]
+				}
+			}
+		},
+
+		sass: {
+			main: {
+				files: {
+					'css/theme/default.css': 'css/theme/source/default.scss',
+					'css/theme/beige.css': 'css/theme/source/beige.scss',
+					'css/theme/night.css': 'css/theme/source/night.scss',
+					'css/theme/serif.css': 'css/theme/source/serif.scss',
+					'css/theme/simple.css': 'css/theme/source/simple.scss',
+					'css/theme/sky.css': 'css/theme/source/sky.scss',
+					'css/theme/moon.css': 'css/theme/source/moon.scss',
+					'css/theme/solarized.css': 'css/theme/source/solarized.scss',
+					'css/theme/blood.css': 'css/theme/source/blood.scss'
+				}
+			}
+		},
+
+		jshint: {
+			options: {
+				curly: false,
+				eqeqeq: true,
+				immed: true,
+				latedef: true,
+				newcap: true,
+				noarg: true,
+				sub: true,
+				undef: true,
+				eqnull: true,
+				browser: true,
+				expr: true,
+				globals: {
+					head: false,
+					module: false,
+					console: false,
+					unescape: false
+				}
+			},
+			files: [ 'Gruntfile.js', 'js/reveal.js' ]
+		},
+
+		connect: {
+			server: {
+				options: {
+					port: port,
+					base: '.'
+				}
+			}
+		},
+
+		zip: {
+			'reveal-js-presentation.zip': [
+				'index.html',
+				'css/**',
+				'js/**',
+				'lib/**',
+				'images/**',
+				'plugin/**'
+			]
+		},
+
+		watch: {
+			main: {
+				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
+				tasks: 'default'
+			},
+			theme: {
+				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
+				tasks: 'themes'
+			}
+		}
+
+	});
+
+	// Dependencies
+	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
+	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
+	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
+	grunt.loadNpmTasks( 'grunt-contrib-watch' );
+	grunt.loadNpmTasks( 'grunt-contrib-sass' );
+	grunt.loadNpmTasks( 'grunt-contrib-connect' );
+	grunt.loadNpmTasks( 'grunt-zip' );
+
+	// Default task
+	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );
+
+	// Theme task
+	grunt.registerTask( 'themes', [ 'sass' ] );
+
+	// Package presentation to archive
+	grunt.registerTask( 'package', [ 'default', 'zip' ] );
+
+	// Serve presentation locally
+	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );
+
+	// Run tests
+	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );
+
+};
diff --git a/docs/slides/IHP14/_support/reveal.js/LICENSE b/docs/slides/IHP14/_support/reveal.js/LICENSE
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/docs/slides/IHP14/_support/reveal.js/README.md b/docs/slides/IHP14/_support/reveal.js/README.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/README.md
@@ -0,0 +1,933 @@
+# reveal.js [![Build Status](https://travis-ci.org/hakimel/reveal.js.png?branch=master)](https://travis-ci.org/hakimel/reveal.js)
+
+A framework for easily creating beautiful presentations using HTML. [Check out the live demo](http://lab.hakim.se/reveal-js/).
+
+reveal.js comes with a broad range of features including [nested slides](https://github.com/hakimel/reveal.js#markup), [markdown contents](https://github.com/hakimel/reveal.js#markdown), [PDF export](https://github.com/hakimel/reveal.js#pdf-export), [speaker notes](https://github.com/hakimel/reveal.js#speaker-notes) and a [JavaScript API](https://github.com/hakimel/reveal.js#api). It's best viewed in a browser with support for CSS 3D transforms but [fallbacks](https://github.com/hakimel/reveal.js/wiki/Browser-Support) are available to make sure your presentation can still be viewed elsewhere.
+
+
+#### More reading:
+- [Installation](#installation): Step-by-step instructions for getting reveal.js running on your computer.
+- [Changelog](https://github.com/hakimel/reveal.js/releases): Up-to-date version history.
+- [Examples](https://github.com/hakimel/reveal.js/wiki/Example-Presentations): Presentations created with reveal.js, add your own!
+- [Browser Support](https://github.com/hakimel/reveal.js/wiki/Browser-Support): Explanation of browser support and fallbacks.
+
+## Online Editor
+
+Presentations are written using HTML or markdown but there's also an online editor for those of you who prefer a graphical interface. Give it a try at [http://slid.es](http://slid.es).
+
+
+## Instructions
+
+### Markup
+
+Markup hierarchy needs to be ``<div class="reveal"> <div class="slides"> <section>`` where the ``<section>`` represents one slide and can be repeated indefinitely. If you place multiple ``<section>``'s inside of another ``<section>`` they will be shown as vertical slides. The first of the vertical slides is the "root" of the others (at the top), and it will be included in the horizontal sequence. For example:
+
+```html
+<div class="reveal">
+	<div class="slides">
+		<section>Single Horizontal Slide</section>
+		<section>
+			<section>Vertical Slide 1</section>
+			<section>Vertical Slide 2</section>
+		</section>
+	</div>
+</div>
+```
+
+### Markdown
+
+It's possible to write your slides using Markdown. To enable Markdown, add the ```data-markdown``` attribute to your ```<section>``` elements and wrap the contents in a ```<script type="text/template">``` like the example below.
+
+This is based on [data-markdown](https://gist.github.com/1343518) from [Paul Irish](https://github.com/paulirish) modified to use [marked](https://github.com/chjj/marked) to support [Github Flavoured Markdown](https://help.github.com/articles/github-flavored-markdown). Sensitive to indentation (avoid mixing tabs and spaces) and line breaks (avoid consecutive breaks).
+
+```html
+<section data-markdown>
+	<script type="text/template">
+		## Page title
+
+		A paragraph with some text and a [link](http://hakim.se).
+	</script>
+</section>
+```
+
+#### External Markdown
+
+You can write your content as a separate file and have reveal.js load it at runtime. Note the separator arguments which determine how slides are delimited in the external file. The ```data-charset``` attribute is optional and specifies which charset to use when loading the external file.
+
+When used locally, this feature requires that reveal.js [runs from a local web server](#full-setup).
+
+```html
+<section data-markdown="example.md"  
+         data-separator="^\n\n\n"  
+         data-vertical="^\n\n"  
+         data-notes="^Note:"  
+         data-charset="iso-8859-15">
+</section>
+```
+
+#### Element Attributes
+
+Special syntax (in html comment) is available for adding attributes to Markdown elements. This is useful for fragments, amongst other things.
+
+```html
+<section data-markdown>
+	<script type="text/template">
+		- Item 1 <!-- .element: class="fragment" data-fragment-index="2" -->
+		- Item 2 <!-- .element: class="fragment" data-fragment-index="1" -->
+	</script>
+</section>
+```
+
+#### Slide Attributes
+
+Special syntax (in html comment) is available for adding attributes to the slide `<section>` elements generated by your Markdown.
+
+```html
+<section data-markdown>
+	<script type="text/template">
+	<!-- .slide: data-background="#ff0000" -->
+		Markdown content
+	</script>
+</section>
+```
+
+
+### Configuration
+
+At the end of your page you need to initialize reveal by running the following code. Note that all config values are optional and will default as specified below.
+
+```javascript
+Reveal.initialize({
+
+	// Display controls in the bottom right corner
+	controls: true,
+
+	// Display a presentation progress bar
+	progress: true,
+
+	// Display the page number of the current slide
+	slideNumber: false,
+
+	// Push each slide change to the browser history
+	history: false,
+
+	// Enable keyboard shortcuts for navigation
+	keyboard: true,
+
+	// Enable the slide overview mode
+	overview: true,
+
+	// Vertical centering of slides
+	center: true,
+
+	// Enables touch navigation on devices with touch input
+	touch: true,
+
+	// Loop the presentation
+	loop: false,
+
+	// Change the presentation direction to be RTL
+	rtl: false,
+
+	// Turns fragments on and off globally
+	fragments: true,
+
+	// Flags if the presentation is running in an embedded mode,
+	// i.e. contained within a limited portion of the screen
+	embedded: false,
+
+	// Number of milliseconds between automatically proceeding to the
+	// next slide, disabled when set to 0, this value can be overwritten
+	// by using a data-autoslide attribute on your slides
+	autoSlide: 0,
+
+	// Stop auto-sliding after user input
+	autoSlideStoppable: true,
+
+	// Enable slide navigation via mouse wheel
+	mouseWheel: false,
+
+	// Hides the address bar on mobile devices
+	hideAddressBar: true,
+
+	// Opens links in an iframe preview overlay
+	previewLinks: false,
+
+	// Transition style
+	transition: 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+	// Transition speed
+	transitionSpeed: 'default', // default/fast/slow
+
+	// Transition style for full page slide backgrounds
+	backgroundTransition: 'default', // default/none/slide/concave/convex/zoom
+
+	// Number of slides away from the current that are visible
+	viewDistance: 3,
+
+	// Parallax background image
+	parallaxBackgroundImage: '', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
+
+	// Parallax background size
+	parallaxBackgroundSize: '' // CSS syntax, e.g. "2100px 900px"
+
+
+});
+```
+
+Note that the new default vertical centering option will break compatibility with slides that were using transitions with backgrounds (`cube` and `page`). To restore the previous behavior, set `center` to `false`.
+
+
+The configuration can be updated after initialization using the ```configure``` method:
+
+```javascript
+// Turn autoSlide off
+Reveal.configure({ autoSlide: 0 });
+
+// Start auto-sliding every 5s
+Reveal.configure({ autoSlide: 5000 });
+```
+
+
+### Dependencies
+
+Reveal.js doesn't _rely_ on any third party scripts to work but a few optional libraries are included by default. These libraries are loaded as dependencies in the order they appear, for example:
+
+```javascript
+Reveal.initialize({
+	dependencies: [
+		// Cross-browser shim that fully implements classList - https://github.com/eligrey/classList.js/
+		{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
+
+		// Interpret Markdown in <section> elements
+		{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+		{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+
+		// Syntax highlight for <code> elements
+		{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+
+		// Zoom in and out with Alt+click
+		{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
+
+		// Speaker notes
+		{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
+
+		// Remote control your reveal.js presentation using a touch device
+		{ src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } },
+
+		// MathJax
+		{ src: 'plugin/math/math.js', async: true }
+	]
+});
+```
+
+You can add your own extensions using the same syntax. The following properties are available for each dependency object:
+- **src**: Path to the script to load
+- **async**: [optional] Flags if the script should load after reveal.js has started, defaults to false
+- **callback**: [optional] Function to execute when the script has loaded
+- **condition**: [optional] Function which must return true for the script to be loaded
+
+
+### Presentation Size
+
+All presentations have a normal size, that is the resolution at which they are authored. The framework will automatically scale presentations uniformly based on this size to ensure that everything fits on any given display or viewport.
+
+See below for a list of configuration options related to sizing, including default values:
+
+```javascript
+Reveal.initialize({
+
+	...
+
+	// The "normal" size of the presentation, aspect ratio will be preserved
+	// when the presentation is scaled to fit different resolutions. Can be
+	// specified using percentage units.
+	width: 960,
+	height: 700,
+
+	// Factor of the display size that should remain empty around the content
+	margin: 0.1,
+
+	// Bounds for smallest/largest possible scale to apply to content
+	minScale: 0.2,
+	maxScale: 1.0
+
+});
+```
+
+
+### Auto-sliding
+
+Presentations can be configure to progress through slides automatically, without any user input. To enable this you will need to tell the framework how many milliseconds it should wait between slides:
+
+```javascript
+// Slide every five seconds
+Reveal.configure({
+  autoSlide: 5000
+});
+```
+
+When this is turned on a control element will appear that enables users to pause and resume auto-sliding. Sliding is also paused automatically as soon as the user starts navigating. You can disable these controls by specifying ```autoSlideStoppable: false``` in your reveal.js config.
+
+You can also override the slide duration for individual slides by using the ```data-autoslide``` attribute on individual sections:
+
+```html
+<section data-autoslide="10000">This will remain on screen for 10 seconds</section>
+```
+
+
+### Keyboard Bindings
+
+If you're unhappy with any of the default keyboard bindings you can override them using the ```keyboard``` config option:
+
+```javascript
+Reveal.configure({
+  keyboard: {
+    13: 'next', // go to the next slide when the ENTER key is pressed
+    27: function() {}, // do something custom when ESC is pressed
+    32: null // don't do anything when SPACE is pressed (i.e. disable a reveal.js default binding)
+  }
+});
+```
+
+
+### API
+
+The ``Reveal`` class provides a JavaScript API for controlling navigation and reading state:
+
+```javascript
+// Navigation
+Reveal.slide( indexh, indexv, indexf );
+Reveal.left();
+Reveal.right();
+Reveal.up();
+Reveal.down();
+Reveal.prev();
+Reveal.next();
+Reveal.prevFragment();
+Reveal.nextFragment();
+Reveal.toggleOverview();
+Reveal.togglePause();
+
+// Retrieves the previous and current slide elements
+Reveal.getPreviousSlide();
+Reveal.getCurrentSlide();
+
+Reveal.getIndices(); // { h: 0, v: 0 } }
+
+// State checks
+Reveal.isFirstSlide();
+Reveal.isLastSlide();
+Reveal.isOverview();
+Reveal.isPaused();
+```
+
+### Ready Event
+
+The 'ready' event is fired when reveal.js has loaded all (synchronous) dependencies and is ready to start navigating.
+
+```javascript
+Reveal.addEventListener( 'ready', function( event ) {
+	// event.currentSlide, event.indexh, event.indexv
+} );
+```
+
+### Slide Changed Event
+
+An 'slidechanged' event is fired each time the slide is changed (regardless of state). The event object holds the index values of the current slide as well as a reference to the previous and current slide HTML nodes.
+
+Some libraries, like MathJax (see [#226](https://github.com/hakimel/reveal.js/issues/226#issuecomment-10261609)), get confused by the transforms and display states of slides. Often times, this can be fixed by calling their update or render function from this callback.
+
+```javascript
+Reveal.addEventListener( 'slidechanged', function( event ) {
+	// event.previousSlide, event.currentSlide, event.indexh, event.indexv
+} );
+```
+
+
+### States
+
+If you set ``data-state="somestate"`` on a slide ``<section>``, "somestate" will be applied as a class on the document element when that slide is opened. This allows you to apply broad style changes to the page based on the active slide.
+
+Furthermore you can also listen to these changes in state via JavaScript:
+
+```javascript
+Reveal.addEventListener( 'somestate', function() {
+	// TODO: Sprinkle magic
+}, false );
+```
+
+### Slide Backgrounds
+
+Slides are contained within a limited portion of the screen by default to allow them to fit any display and scale uniformly. You can apply full page background colors or images by applying a ```data-background``` attribute to your ```<section>``` elements. Below are a few examples.
+
+```html
+<section data-background="#ff0000">
+	<h2>All CSS color formats are supported, like rgba() or hsl().</h2>
+</section>
+<section data-background="http://example.com/image.png">
+	<h2>This slide will have a full-size background image.</h2>
+</section>
+<section data-background="http://example.com/image.png" data-background-size="100px" data-background-repeat="repeat">
+	<h2>This background image will be sized to 100px and repeated.</h2>
+</section>
+```
+
+Backgrounds transition using a fade animation by default. This can be changed to a linear sliding transition by passing ```backgroundTransition: 'slide'``` to the ```Reveal.initialize()``` call. Alternatively you can set ```data-background-transition``` on any section with a background to override that specific transition.
+
+
+### Parallax Background
+
+If you want to use a parallax scrolling background, set the two following config properties when initializing reveal.js (the third one is optional).
+
+```javascript
+Reveal.initialize({
+
+	// Parallax background image
+	parallaxBackgroundImage: '', // e.g. "https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg"
+
+	// Parallax background size
+	parallaxBackgroundSize: '', // CSS syntax, e.g. "2100px 900px" - currently only pixels are supported (don't use % or auto)
+
+	// This slide transition gives best results:
+	transition: linear
+
+});
+```
+
+Make sure that the background size is much bigger than screen size to allow for some scrolling. [View example](http://lab.hakim.se/reveal-js/?parallaxBackgroundImage=https%3A%2F%2Fs3.amazonaws.com%2Fhakim-static%2Freveal-js%2Freveal-parallax-1.jpg&parallaxBackgroundSize=2100px%20900px).
+
+
+
+### Slide Transitions
+The global presentation transition is set using the ```transition``` config value. You can override the global transition for a specific slide by using the ```data-transition``` attribute:
+
+```html
+<section data-transition="zoom">
+	<h2>This slide will override the presentation transition and zoom!</h2>
+</section>
+
+<section data-transition-speed="fast">
+	<h2>Choose from three transition speeds: default, fast or slow!</h2>
+</section>
+```
+
+Note that this does not work with the page and cube transitions.
+
+
+### Internal links
+
+It's easy to link between slides. The first example below targets the index of another slide whereas the second targets a slide with an ID attribute (```<section id="some-slide">```):
+
+```html
+<a href="#/2/2">Link</a>
+<a href="#/some-slide">Link</a>
+```
+
+You can also add relative navigation links, similar to the built in reveal.js controls, by appending one of the following classes on any element. Note that each element is automatically given an ```enabled``` class when it's a valid navigation route based on the current slide.
+
+```html
+<a href="#" class="navigate-left">
+<a href="#" class="navigate-right">
+<a href="#" class="navigate-up">
+<a href="#" class="navigate-down">
+<a href="#" class="navigate-prev"> <!-- Previous vertical or horizontal slide -->
+<a href="#" class="navigate-next"> <!-- Next vertical or horizontal slide -->
+```
+
+
+### Fragments
+Fragments are used to highlight individual elements on a slide. Every element with the class ```fragment``` will be stepped through before moving on to the next slide. Here's an example: http://lab.hakim.se/reveal-js/#/fragments
+
+The default fragment style is to start out invisible and fade in. This style can be changed by appending a different class to the fragment:
+
+```html
+<section>
+	<p class="fragment grow">grow</p>
+	<p class="fragment shrink">shrink</p>
+	<p class="fragment roll-in">roll-in</p>
+	<p class="fragment fade-out">fade-out</p>
+	<p class="fragment current-visible">visible only once</p>
+	<p class="fragment highlight-current-blue">blue only once</p>
+	<p class="fragment highlight-red">highlight-red</p>
+	<p class="fragment highlight-green">highlight-green</p>
+	<p class="fragment highlight-blue">highlight-blue</p>
+</section>
+```
+
+Multiple fragments can be applied to the same element sequentially by wrapping it, this will fade in the text on the first step and fade it back out on the second.
+
+```html
+<section>
+	<span class="fragment fade-in">
+		<span class="fragment fade-out">I'll fade in, then out</span>
+	</span>
+</section>
+```
+
+The display order of fragments can be controlled using the ```data-fragment-index``` attribute.
+
+```html
+<section>
+	<p class="fragment" data-fragment-index="3">Appears last</p>
+	<p class="fragment" data-fragment-index="1">Appears first</p>
+	<p class="fragment" data-fragment-index="2">Appears second</p>
+</section>
+```
+
+### Fragment events
+
+When a slide fragment is either shown or hidden reveal.js will dispatch an event.
+
+Some libraries, like MathJax (see #505), get confused by the initially hidden fragment elements. Often times this can be fixed by calling their update or render function from this callback.
+
+```javascript
+Reveal.addEventListener( 'fragmentshown', function( event ) {
+	// event.fragment = the fragment DOM element
+} );
+Reveal.addEventListener( 'fragmenthidden', function( event ) {
+	// event.fragment = the fragment DOM element
+} );
+```
+
+### Code syntax highlighting
+
+By default, Reveal is configured with [highlight.js](http://softwaremaniacs.org/soft/highlight/en/) for code syntax highlighting. Below is an example with clojure code that will be syntax highlighted. When the `data-trim` attribute is present surrounding whitespace is automatically removed.
+
+```html
+<section>
+	<pre><code data-trim>
+(def lazy-fib
+  (concat
+   [0 1]
+   ((fn rfib [a b]
+        (lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
+	</code></pre>
+</section>
+```
+
+### Slide number
+If you would like to display the page number of the current slide you can do so using the ```slideNumber``` configuration value.
+
+```javascript
+Reveal.configure({ slideNumber: true });
+```
+
+
+### Overview mode
+
+Press "Esc" or "o" keys to toggle the overview mode on and off. While you're in this mode, you can still navigate between slides,
+as if you were at 1,000 feet above your presentation. The overview mode comes with a few API hooks:
+
+```javascript
+Reveal.addEventListener( 'overviewshown', function( event ) { /* ... */ } );
+Reveal.addEventListener( 'overviewhidden', function( event ) { /* ... */ } );
+
+// Toggle the overview mode programmatically
+Reveal.toggleOverview();
+```
+
+### Fullscreen mode
+Just press »F« on your keyboard to show your presentation in fullscreen mode. Press the »ESC« key to exit fullscreen mode.
+
+
+### Embedded media
+Embedded HTML5 `<video>`/`<audio>` and YouTube iframes are automatically paused when you navigate away from a slide. This can be disabled by decorating your element with a `data-ignore` attribute.
+
+Add `data-autoplay` to your media element if you want it to automatically start playing when the slide is shown:
+
+```html
+<video data-autoplay src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
+```
+
+Additionally the framework automatically pushes two [post messages](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) to all iframes, ```slide:start``` when the slide containing the iframe is made visible and ```slide:stop``` when it is hidden.
+
+
+### Stretching elements
+Sometimes it's desirable to have an element, like an image or video, stretch to consume as much space as possible within a given slide. This can be done by adding the ```.stretch``` class to an element as seen below:
+
+```html
+<section>
+	<h2>This video will use up the remaining space on the slide</h2>
+    <video class="stretch" src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
+</section>
+```
+
+Limitations:
+- Only direct descendants of a slide section can be stretched
+- Only one descendant per slide section can be stretched
+
+
+## PDF Export
+
+Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome).
+Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-13872948.
+
+1. Open your presentation with [css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css) included on the page. The default index HTML lets you add *print-pdf* anywhere in the query to include the stylesheet, for example: [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf).
+2. Open the in-browser print dialog (CMD+P).
+3. Change the **Destination** setting to **Save as PDF**.
+4. Change the **Layout** to **Landscape**.
+5. Change the **Margins** to **None**.
+6. Click **Save**.
+
+![Chrome Print Settings](https://s3.amazonaws.com/hakim-static/reveal-js/pdf-print-settings.png)
+
+## Theming
+
+The framework comes with a few different themes included:
+
+- default: Gray background, white text, blue links
+- beige: Beige background, dark text, brown links
+- sky: Blue background, thin white text, blue links
+- night: Black background, thick white text, orange links
+- serif: Cappuccino background, gray text, brown links
+- simple: White background, black text, blue links
+- solarized: Cream-colored background, dark green text, blue links
+
+Each theme is available as a separate stylesheet. To change theme you will need to replace **default** below with your desired theme name in index.html:
+
+```html
+<link rel="stylesheet" href="css/theme/default.css" id="theme">
+```
+
+If you want to add a theme of your own see the instructions here: [/css/theme/README.md](https://github.com/hakimel/reveal.js/blob/master/css/theme/README.md).
+
+
+## Speaker Notes
+
+reveal.js comes with a speaker notes plugin which can be used to present per-slide notes in a separate browser window. The notes window also gives you a preview of the next upcoming slide so it may be helpful even if you haven't written any notes. Press the 's' key on your keyboard to open the notes window.
+
+Notes are defined by appending an ```<aside>``` element to a slide as seen below. You can add the ```data-markdown``` attribute to the aside element if you prefer writing notes using Markdown.
+
+When used locally, this feature requires that reveal.js [runs from a local web server](#full-setup).
+
+```html
+<section>
+	<h2>Some Slide</h2>
+
+	<aside class="notes">
+		Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
+	</aside>
+</section>
+```
+
+If you're using the external Markdown plugin, you can add notes with the help of a special delimiter:
+
+```html
+<section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n" data-notes="^Note:"></section>
+
+# Title
+## Sub-title
+
+Here is some content...
+
+Note:
+This will only display in the notes window.
+```
+
+## Server Side Speaker Notes
+
+In some cases it can be desirable to run notes on a separate device from the one you're presenting on. The Node.js-based notes plugin lets you do this using the same note definitions as its client side counterpart. Include the required scripts by adding the following dependencies:
+
+```javascript
+Reveal.initialize({
+	...
+
+	dependencies: [
+		{ src: 'socket.io/socket.io.js', async: true },
+		{ src: 'plugin/notes-server/client.js', async: true }
+	]
+});
+```
+
+Then:
+
+1. Install [Node.js](http://nodejs.org/)
+2. Run ```npm install```
+3. Run ```node plugin/notes-server```
+
+
+## Multiplexing
+
+The multiplex plugin allows your audience to view the slides of the presentation you are controlling on their own phone, tablet or laptop. As the master presentation navigates the slides, all client presentations will update in real time. See a demo at [http://revealjs.jit.su/](http://revealjs.jit.su).
+
+The multiplex plugin needs the following 3 things to operate:
+
+1. Master presentation that has control
+2. Client presentations that follow the master
+3. Socket.io server to broadcast events from the master to the clients
+
+More details:
+
+#### Master presentation
+Served from a static file server accessible (preferably) only to the presenter. This need only be on your (the presenter's) computer. (It's safer to run the master presentation from your own computer, so if the venue's Internet goes down it doesn't stop the show.) An example would be to execute the following commands in the directory of your master presentation: 
+
+1. ```npm install node-static```
+2. ```static```
+
+If you want to use the speaker notes plugin with your master presentation then make sure you have the speaker notes plugin configured correctly along with the configuration shown below, then execute ```node plugin/notes-server``` in the directory of your master presentation. The configuration below will cause it to connect to the socket.io server as a master, as well as launch your speaker-notes/static-file server.
+
+You can then access your master presentation at ```http://localhost:1947```
+
+Example configuration:
+```javascript
+Reveal.initialize({
+	// other options...
+
+	multiplex: {
+		// Example values. To generate your own, see the socket.io server instructions.
+		secret: '13652805320794272084', // Obtained from the socket.io server. Gives this (the master) control of the presentation
+		id: '1ea875674b17ca76', // Obtained from socket.io server
+		url: 'revealjs.jit.su:80' // Location of socket.io server
+	},
+
+	// Don't forget to add the dependencies
+	dependencies: [
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: 'plugin/multiplex/master.js', async: true },
+
+		// and if you want speaker notes
+		{ src: 'plugin/notes-server/client.js', async: true }
+
+		// other dependencies...
+	]
+});
+```
+
+#### Client presentation
+Served from a publicly accessible static file server. Examples include: GitHub Pages, Amazon S3, Dreamhost, Akamai, etc. The more reliable, the better. Your audience can then access the client presentation via ```http://example.com/path/to/presentation/client/index.html```, with the configuration below causing them to connect to the socket.io server as clients.
+
+Example configuration:
+```javascript
+Reveal.initialize({
+	// other options...
+
+	multiplex: {
+		// Example values. To generate your own, see the socket.io server instructions.
+		secret: null, // null so the clients do not have control of the master presentation
+		id: '1ea875674b17ca76', // id, obtained from socket.io server
+		url: 'revealjs.jit.su:80' // Location of socket.io server
+	},
+
+	// Don't forget to add the dependencies
+	dependencies: [
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: 'plugin/multiplex/client.js', async: true }
+
+		// other dependencies...
+	]
+});
+```
+
+#### Socket.io server
+Server that receives the slideChanged events from the master presentation and broadcasts them out to the connected client presentations. This needs to be publicly accessible. You can run your own socket.io server with the commands:
+
+1. ```npm install```
+2. ```node plugin/multiplex```
+
+Or you use the socket.io server at [http://revealjs.jit.su](http://revealjs.jit.su).
+
+You'll need to generate a unique secret and token pair for your master and client presentations. To do so, visit ```http://example.com/token```, where ```http://example.com``` is the location of your socket.io server. Or if you're going to use the socket.io server at [http://revealjs.jit.su](http://revealjs.jit.su), visit [http://revealjs.jit.su/token](http://revealjs.jit.su/token).
+
+You are very welcome to point your presentations at the Socket.io server running at [http://revealjs.jit.su](http://revealjs.jit.su), but availability and stability are not guaranteed. For anything mission critical I recommend you run your own server. It is simple to deploy to nodejitsu, heroku, your own environment, etc.
+
+##### socket.io server as file static server
+
+The socket.io server can play the role of static file server for your client presentation, as in the example at [http://revealjs.jit.su](http://revealjs.jit.su). (Open [http://revealjs.jit.su](http://revealjs.jit.su) in two browsers. Navigate through the slides on one, and the other will update to match.) 
+
+Example configuration:
+```javascript
+Reveal.initialize({
+	// other options...
+
+	multiplex: {
+		// Example values. To generate your own, see the socket.io server instructions.
+		secret: null, // null so the clients do not have control of the master presentation
+		id: '1ea875674b17ca76', // id, obtained from socket.io server
+		url: 'example.com:80' // Location of your socket.io server
+	},
+
+	// Don't forget to add the dependencies
+	dependencies: [
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: 'plugin/multiplex/client.js', async: true }
+
+		// other dependencies...
+	]
+```
+
+It can also play the role of static file server for your master presentation and client presentations at the same time (as long as you don't want to use speaker notes). (Open [http://revealjs.jit.su](http://revealjs.jit.su) in two browsers. Navigate through the slides on one, and the other will update to match. Navigate through the slides on the second, and the first will update to match.) This is probably not desirable, because you don't want your audience to mess with your slides while you're presenting. ;)
+
+Example configuration:
+```javascript
+Reveal.initialize({
+	// other options...
+
+	multiplex: {
+		// Example values. To generate your own, see the socket.io server instructions.
+		secret: '13652805320794272084', // Obtained from the socket.io server. Gives this (the master) control of the presentation
+		id: '1ea875674b17ca76', // Obtained from socket.io server
+		url: 'example.com:80' // Location of your socket.io server
+	},
+
+	// Don't forget to add the dependencies
+	dependencies: [
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: 'plugin/multiplex/master.js', async: true },
+		{ src: 'plugin/multiplex/client.js', async: true }
+
+		// other dependencies...
+	]
+});
+```
+
+## Leap Motion
+The Leap Motion plugin lets you utilize your [Leap Motion](https://www.leapmotion.com/) device to control basic navigation of your presentation. The gestures currently supported are:
+
+##### 1 to 2 fingers
+Pointer &mdash; Point to anything on screen. Move your finger past the device to expand the pointer.
+
+##### 1 hand + 3 or more fingers (left/right/up/down)
+Navigate through your slides. See config options to invert movements.
+
+##### 2 hands upwards
+Toggle the overview mode. Do it a second time to exit the overview.
+
+#### Config Options
+You can edit the following options:
+
+| Property          | Default           | Description
+| ----------------- |:-----------------:| :-------------
+| autoCenter        | true              | Center the pointer based on where you put your finger into the leap motions detection field.
+| gestureDelay      | 500               | How long to delay between gestures in milliseconds.
+| naturalSwipe      | true              | Swipe as though you were touching a touch screen. Set to false to invert.
+| pointerColor      | #00aaff           | The color of the pointer.
+| pointerOpacity    | 0.7               | The opacity of the pointer.
+| pointerSize       | 15                | The minimum height and width of the pointer.
+| pointerTolerance  | 120               | Bigger = slower pointer.
+
+
+Example configuration:
+```js
+Reveal.initialize({
+
+	// other options...
+
+	leap: {
+		naturalSwipe   : false,    // Invert swipe gestures
+		pointerOpacity : 0.5,      // Set pointer opacity to 0.5
+		pointerColor   : '#d80000' // Red pointer
+	},
+
+	dependencies: [
+		{ src: 'plugin/leap/leap.js', async: true }
+	]
+
+});
+```
+
+## MathJax
+
+If you want to display math equations in your presentation you can easily do so by including this plugin. The plugin is a very thin wrapper around the [MathJax](http://www.mathjax.org/) library. To use it you'll need to include it as a reveal.js dependency, [find our more about dependencies here](#dependencies).
+
+The plugin defaults to using [LaTeX](http://en.wikipedia.org/wiki/LaTeX) but that can be adjusted through the ```math``` configuration object. Note that MathJax is loaded from a remote server. If you want to use it offline you'll need to download a copy of the library and adjust the ```mathjax``` configuration value. 
+
+Below is an example of how the plugin can be configured. If you don't intend to change these values you do not need to include the ```math``` config object at all.
+
+```js
+Reveal.initialize({
+
+	// other options ...
+
+	math: {
+		mathjax: 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
+		config: 'TeX-AMS_HTML-full'  // See http://docs.mathjax.org/en/latest/config-files.html
+	},
+	
+	dependencies: [
+		{ src: 'plugin/math/math.js', async: true }
+	]
+
+});
+```
+
+Read MathJax's documentation if you need [HTTPS delivery](http://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn) or serving of [specific versions](http://docs.mathjax.org/en/latest/configuration.html#loading-mathjax-from-the-cdn) for stability.
+
+
+## Installation
+
+The **basic setup** is for authoring presentations only. The **full setup** gives you access to all reveal.js features and plugins such as speaker notes as well as the development tasks needed to make changes to the source.
+
+### Basic setup
+
+The core of reveal.js is very easy to install. You'll simply need to download a copy of this repository and open the index.html file directly in your browser.
+
+1. Download the latest version of reveal.js from <https://github.com/hakimel/reveal.js/releases>
+
+2. Unzip and replace the example contents in index.html with your own
+
+3. Open index.html in a browser to view it
+
+
+### Full setup
+
+Some reveal.js features, like external markdown and speaker notes, require that presentations run from a local web server. The following instructions will set up such a server as well as all of the development tasks needed to make edits to the reveal.js source code.
+
+1. Install [Node.js](http://nodejs.org/)
+
+2. Install [Grunt](http://gruntjs.com/getting-started#installing-the-cli)
+
+4. Clone the reveal.js repository
+   ```sh
+   $ git clone https://github.com/hakimel/reveal.js.git
+   ```
+
+5. Navigate to the reveal.js folder
+   ```sh
+   $ cd reveal.js
+   ```
+
+6. Install dependencies
+   ```sh
+   $ npm install
+   ```
+
+7. Serve the presentation and monitor source files for changes
+   ```sh
+   $ grunt serve
+   ```
+
+8. Open <http://localhost:8000> to view your presentation
+
+   You can change the port by using `grunt serve --port 8001`.
+
+
+### Folder Structure
+- **css/** Core styles without which the project does not function
+- **js/** Like above but for JavaScript
+- **plugin/** Components that have been developed as extensions to reveal.js
+- **lib/** All other third party assets (JavaScript, CSS, fonts)
+
+
+### Contributing
+
+Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**. If you are reporting a bug make sure to include information about which browser and operating system you are using as well as the necessary steps to reproduce the issue.
+
+If you have personal support questions use [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
+
+
+#### Pull requests
+
+- Should follow the coding style of the file you work in, most importantly:
+  - Tabs to indent
+  - Single-quoted strings
+- Should be made towards the **dev branch**
+- Should be submitted from a feature/topic branch (not your master)
+- Should not include the minified **reveal.min.js** file
+
+
+## License
+
+MIT licensed
+
+Copyright (C) 2014 Hakim El Hattab, http://hakim.se
diff --git a/docs/slides/IHP14/_support/reveal.js/css/print/paper.css b/docs/slides/IHP14/_support/reveal.js/css/print/paper.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/print/paper.css
@@ -0,0 +1,176 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+body {
+	background: #fff;
+	font-size: 13pt;
+	width: auto;
+	height: auto;
+	border: 0;
+	margin: 0 5%;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+}
+html {
+	background: #fff;
+	width: auto;
+	height: auto;
+	overflow: visible;
+}
+
+/* SECTION 2: Remove any elements not needed in print.
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow,
+.controls,
+.reveal .progress,
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display: none !important;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div, a {
+	font-size: 16pt!important;
+	font-family: Georgia, "Times New Roman", Times, serif !important;
+	color: #000;
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Differentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	color: #000!important;
+	height: auto;
+	line-height: normal;
+	font-family: Georgia, "Times New Roman", Times, serif !important;
+	text-shadow: 0 0 0 #000 !important;
+	text-align: left;
+	letter-spacing: normal;
+}
+/* Need to reduce the size of the fonts for printing */
+h1 { font-size: 26pt !important;  }
+h2 { font-size: 22pt !important; }
+h3 { font-size: 20pt !important; }
+h4 { font-size: 20pt !important; font-variant: small-caps; }
+h5 { font-size: 19pt !important; }
+h6 { font-size: 18pt !important; font-style: italic; }
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link,
+a:visited {
+	color: #000 !important;
+	font-weight: bold;
+	text-decoration: underline;
+}
+/*
+.reveal a:link:after,
+.reveal a:visited:after {
+	content: " (" attr(href) ") ";
+	color: #222 !important;
+	font-size: 90%;
+}
+*/
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+	text-align: left !important;
+}
+.reveal .slides {
+	position: static;
+	width: auto;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin-left: auto;
+	margin-top: auto;
+	padding: auto;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides>section,
+.reveal .slides>section>section {
+
+	visibility: visible !important;
+	position: static !important;
+	width: 90% !important;
+	height: auto !important;
+	display: block !important;
+	overflow: visible !important;
+
+	left: 0% !important;
+	top: 0% !important;
+	margin-left: 0px !important;
+	margin-top: 0px !important;
+	padding: 20px 0px !important;
+
+	opacity: 1 !important;
+
+	-webkit-transform-style: flat !important;
+	   -moz-transform-style: flat !important;
+	    -ms-transform-style: flat !important;
+	        transform-style: flat !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section {
+	page-break-after: always !important;
+	display: block !important;
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+	visibility: visible !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section:last-of-type {
+	page-break-after: avoid !important;
+}
+.reveal section img {
+	display: block;
+	margin: 15px 0px;
+	background: rgba(255,255,255,1);
+	border: 1px solid #666;
+	box-shadow: none;
+}
diff --git a/docs/slides/IHP14/_support/reveal.js/css/print/pdf.css b/docs/slides/IHP14/_support/reveal.js/css/print/pdf.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/print/pdf.css
@@ -0,0 +1,190 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+
+* {
+	-webkit-print-color-adjust: exact;
+}
+
+body {
+	font-size: 18pt;
+	width: 297mm;
+	height: 229mm;
+	margin: 0 auto !important;
+	border: 0;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+}
+
+html {
+	width: 100%;
+	height: 100%;
+	overflow: visible;
+}
+
+@page {
+	size: letter landscape;
+	margin: 0;
+}
+
+/* SECTION 2: Remove any elements not needed in print.
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow,
+.controls,
+.reveal .progress,
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display: none !important;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div {
+	font-size: 18pt;
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Differentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	text-shadow: 0 0 0 #000 !important;
+}
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link,
+a:visited {
+	font-weight: normal;
+	text-decoration: underline;
+}
+
+.reveal pre code {
+	overflow: hidden !important;
+	font-family: monospace !important;
+}
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+}
+.reveal {
+	width: auto !important;
+	height: auto !important;
+	overflow: hidden !important;
+}
+.reveal .slides {
+	position: static;
+	width: 100%;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin: 0 !important;
+	padding: 0 !important;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides section {
+
+	page-break-after: always !important;
+
+	visibility: visible !important;
+	position: relative !important;
+	width: 100% !important;
+	height: 229mm !important;
+	min-height: 229mm !important;
+	display: block !important;
+	overflow: hidden !important;
+
+	left: 0 !important;
+	top: 0 !important;
+	margin: 0 !important;
+	padding: 2cm 2cm 0 2cm !important;
+	box-sizing: border-box !important;
+
+	opacity: 1 !important;
+
+	-webkit-transform-style: flat !important;
+	   -moz-transform-style: flat !important;
+	    -ms-transform-style: flat !important;
+	        transform-style: flat !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section.stack {
+	margin: 0 !important;
+	padding: 0 !important;
+	page-break-after: avoid !important;
+	height: auto !important;
+	min-height: auto !important;
+}
+.reveal .absolute-element {
+	margin-left: 2.2cm;
+	margin-top: 1.8cm;
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+	visibility: visible !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section .slide-background {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	z-index: 0;
+}
+.reveal section>* {
+	position: relative;
+	z-index: 1;
+}
+.reveal img {
+	box-shadow: none;
+}
+.reveal .roll {
+	overflow: visible;
+	line-height: 1em;
+}
+.reveal small a {
+	font-size: 16pt !important;
+}
diff --git a/docs/slides/IHP14/_support/reveal.js/css/reveal.css b/docs/slides/IHP14/_support/reveal.js/css/reveal.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/reveal.css
@@ -0,0 +1,1882 @@
+@charset "UTF-8";
+
+/*!
+ * reveal.js
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+ */
+
+
+/*********************************************
+ * RESET STYLES
+ *********************************************/
+
+html, body, .reveal div, .reveal span, .reveal applet, .reveal object, .reveal iframe,
+.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6, .reveal p, .reveal blockquote, .reveal pre,
+.reveal a, .reveal abbr, .reveal acronym, .reveal address, .reveal big, .reveal cite, .reveal code,
+.reveal del, .reveal dfn, .reveal em, .reveal img, .reveal ins, .reveal kbd, .reveal q, .reveal s, .reveal samp,
+.reveal small, .reveal strike, .reveal strong, .reveal sub, .reveal sup, .reveal tt, .reveal var,
+.reveal b, .reveal u, .reveal i, .reveal center,
+.reveal dl, .reveal dt, .reveal dd, .reveal ol, .reveal ul, .reveal li,
+.reveal fieldset, .reveal form, .reveal label, .reveal legend,
+.reveal table, .reveal caption, .reveal tbody, .reveal tfoot, .reveal thead, .reveal tr, .reveal th, .reveal td,
+.reveal article, .reveal aside, .reveal canvas, .reveal details, .reveal embed,
+.reveal figure, .reveal figcaption, .reveal footer, .reveal header, .reveal hgroup,
+.reveal menu, .reveal nav, .reveal output, .reveal ruby, .reveal section, .reveal summary,
+.reveal time, .reveal mark, .reveal audio, video {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font-size: 100%;
+	font: inherit;
+	vertical-align: baseline;
+}
+
+.reveal article, .reveal aside, .reveal details, .reveal figcaption, .reveal figure,
+.reveal footer, .reveal header, .reveal hgroup, .reveal menu, .reveal nav, .reveal section {
+	display: block;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+html,
+body {
+	width: 100%;
+	height: 100%;
+	overflow: hidden;
+}
+
+body {
+	position: relative;
+	line-height: 1;
+}
+
+::selection {
+	background: #FF5E99;
+	color: #fff;
+	text-shadow: none;
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+	-webkit-hyphens: auto;
+	   -moz-hyphens: auto;
+	        hyphens: auto;
+
+	word-wrap: break-word;
+	line-height: 1;
+}
+
+.reveal h1 { font-size: 3.77em; }
+.reveal h2 { font-size: 1.85em;	}
+.reveal h3 { font-size: 1.55em;	}
+.reveal h4 { font-size: 1em;	}
+
+
+/*********************************************
+ * VIEW FRAGMENTS
+ *********************************************/
+
+.reveal .slides section .fragment {
+	opacity: 0;
+
+	-webkit-transition: all .2s ease;
+	   -moz-transition: all .2s ease;
+	    -ms-transition: all .2s ease;
+	     -o-transition: all .2s ease;
+	        transition: all .2s ease;
+}
+	.reveal .slides section .fragment.visible {
+		opacity: 1;
+	}
+
+.reveal .slides section .fragment.grow {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.grow.visible {
+		-webkit-transform: scale( 1.3 );
+		   -moz-transform: scale( 1.3 );
+		    -ms-transform: scale( 1.3 );
+		     -o-transform: scale( 1.3 );
+		        transform: scale( 1.3 );
+	}
+
+.reveal .slides section .fragment.shrink {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.shrink.visible {
+		-webkit-transform: scale( 0.7 );
+		   -moz-transform: scale( 0.7 );
+		    -ms-transform: scale( 0.7 );
+		     -o-transform: scale( 0.7 );
+		        transform: scale( 0.7 );
+	}
+
+.reveal .slides section .fragment.zoom-in {
+	opacity: 0;
+
+	-webkit-transform: scale( 0.1 );
+	   -moz-transform: scale( 0.1 );
+	    -ms-transform: scale( 0.1 );
+	     -o-transform: scale( 0.1 );
+	        transform: scale( 0.1 );
+}
+
+	.reveal .slides section .fragment.zoom-in.visible {
+		opacity: 1;
+
+		-webkit-transform: scale( 1 );
+		   -moz-transform: scale( 1 );
+		    -ms-transform: scale( 1 );
+		     -o-transform: scale( 1 );
+		        transform: scale( 1 );
+	}
+
+.reveal .slides section .fragment.roll-in {
+	opacity: 0;
+
+	-webkit-transform: rotateX( 90deg );
+	   -moz-transform: rotateX( 90deg );
+	    -ms-transform: rotateX( 90deg );
+	     -o-transform: rotateX( 90deg );
+	        transform: rotateX( 90deg );
+}
+	.reveal .slides section .fragment.roll-in.visible {
+		opacity: 1;
+
+		-webkit-transform: rotateX( 0 );
+		   -moz-transform: rotateX( 0 );
+		    -ms-transform: rotateX( 0 );
+		     -o-transform: rotateX( 0 );
+		        transform: rotateX( 0 );
+	}
+
+.reveal .slides section .fragment.fade-out {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.fade-out.visible {
+		opacity: 0;
+	}
+
+.reveal .slides section .fragment.semi-fade-out {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.semi-fade-out.visible {
+		opacity: 0.5;
+	}
+
+.reveal .slides section .fragment.current-visible {
+	opacity:0;
+}
+
+.reveal .slides section .fragment.current-visible.current-fragment {
+	opacity:1;
+}
+
+.reveal .slides section .fragment.highlight-red,
+.reveal .slides section .fragment.highlight-current-red,
+.reveal .slides section .fragment.highlight-green,
+.reveal .slides section .fragment.highlight-current-green,
+.reveal .slides section .fragment.highlight-blue,
+.reveal .slides section .fragment.highlight-current-blue {
+	opacity: 1;
+}
+	.reveal .slides section .fragment.highlight-red.visible {
+		color: #ff2c2d
+	}
+	.reveal .slides section .fragment.highlight-green.visible {
+		color: #17ff2e;
+	}
+	.reveal .slides section .fragment.highlight-blue.visible {
+		color: #1b91ff;
+	}
+
+.reveal .slides section .fragment.highlight-current-red.current-fragment {
+	color: #ff2c2d
+}
+.reveal .slides section .fragment.highlight-current-green.current-fragment {
+	color: #17ff2e;
+}
+.reveal .slides section .fragment.highlight-current-blue.current-fragment {
+	color: #1b91ff;
+}
+
+
+/*********************************************
+ * DEFAULT ELEMENT STYLES
+ *********************************************/
+
+/* Fixes issue in Chrome where italic fonts did not appear when printing to PDF */
+.reveal:after {
+  content: '';
+  font-style: italic;
+}
+
+.reveal iframe {
+	z-index: 1;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+	max-width: 95%;
+	max-height: 95%;
+}
+
+/** Prevents layering issues in certain browser/transition combinations */
+.reveal a {
+	position: relative;
+}
+
+.reveal strong,
+.reveal b {
+	font-weight: bold;
+}
+
+.reveal em,
+.reveal i {
+	font-style: italic;
+}
+
+.reveal ol,
+.reveal ul {
+	display: inline-block;
+
+	text-align: left;
+	margin: 0 0 0 1em;
+}
+
+.reveal ol {
+	list-style-type: decimal;
+}
+
+.reveal ul {
+	list-style-type: disc;
+}
+
+.reveal ul ul {
+	list-style-type: square;
+}
+
+.reveal ul ul ul {
+	list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+	display: block;
+	margin-left: 40px;
+}
+
+.reveal p {
+	margin-bottom: 10px;
+	line-height: 1.2em;
+}
+
+.reveal q,
+.reveal blockquote {
+	quotes: none;
+}
+
+.reveal blockquote {
+	display: block;
+	position: relative;
+	width: 70%;
+	margin: 5px auto;
+	padding: 5px;
+
+	font-style: italic;
+	background: rgba(255, 255, 255, 0.05);
+	box-shadow: 0px 0px 2px rgba(0,0,0,0.2);
+}
+	.reveal blockquote p:first-child,
+	.reveal blockquote p:last-child {
+		display: inline-block;
+	}
+
+.reveal q {
+	font-style: italic;
+}
+
+.reveal pre {
+	display: block;
+	position: relative;
+	width: 90%;
+	margin: 10px auto;
+
+	text-align: left;
+	font-size: 0.81em;
+	font-family: monospace;
+	line-height: 1.2em;
+
+	word-wrap: break-word;
+
+	box-shadow: 0px 0px 6px rgba(0,0,0,0.3);
+}
+.reveal code {
+	font-family: monospace;
+	font-size: 0.81em;
+}
+.reveal pre code {
+	padding: 5px;
+	overflow: auto;
+	max-height: 400px;
+	word-wrap: normal;
+}
+.reveal pre.stretch code {
+	height: 100%;
+	max-height: 100%;
+
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+
+.reveal table th,
+.reveal table td {
+	text-align: left;
+	padding-right: .3em;
+}
+
+.reveal table th {
+	font-weight: bold;
+}
+
+.reveal sup {
+	vertical-align: super;
+}
+.reveal sub {
+	vertical-align: sub;
+}
+
+.reveal small {
+	display: inline-block;
+	font-size: 0.6em;
+	line-height: 1.2em;
+	vertical-align: top;
+}
+
+.reveal small * {
+	vertical-align: top;
+}
+
+.reveal .stretch {
+	max-width: none;
+	max-height: none;
+}
+
+
+/*********************************************
+ * CONTROLS
+ *********************************************/
+
+.reveal .controls {
+	display: none;
+	position: fixed;
+	width: 110px;
+	height: 110px;
+	z-index: 30;
+	right: 10px;
+	bottom: 10px;
+}
+
+.reveal .controls div {
+	position: absolute;
+	opacity: 0.05;
+	width: 0;
+	height: 0;
+	border: 12px solid transparent;
+
+	-moz-transform: scale(.9999);
+
+	-webkit-transition: all 0.2s ease;
+	   -moz-transition: all 0.2s ease;
+	    -ms-transition: all 0.2s ease;
+	     -o-transition: all 0.2s ease;
+	        transition: all 0.2s ease;
+}
+
+.reveal .controls div.enabled {
+	opacity: 0.7;
+	cursor: pointer;
+}
+
+.reveal .controls div.enabled:active {
+	margin-top: 1px;
+}
+
+	.reveal .controls div.navigate-left {
+		top: 42px;
+
+		border-right-width: 22px;
+		border-right-color: #eee;
+	}
+		.reveal .controls div.navigate-left.fragmented {
+			opacity: 0.3;
+		}
+
+	.reveal .controls div.navigate-right {
+		left: 74px;
+		top: 42px;
+
+		border-left-width: 22px;
+		border-left-color: #eee;
+	}
+		.reveal .controls div.navigate-right.fragmented {
+			opacity: 0.3;
+		}
+
+	.reveal .controls div.navigate-up {
+		left: 42px;
+
+		border-bottom-width: 22px;
+		border-bottom-color: #eee;
+	}
+		.reveal .controls div.navigate-up.fragmented {
+			opacity: 0.3;
+		}
+
+	.reveal .controls div.navigate-down {
+		left: 42px;
+		top: 74px;
+
+		border-top-width: 22px;
+		border-top-color: #eee;
+	}
+		.reveal .controls div.navigate-down.fragmented {
+			opacity: 0.3;
+		}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	position: fixed;
+	display: none;
+	height: 3px;
+	width: 100%;
+	bottom: 0;
+	left: 0;
+	z-index: 10;
+}
+	.reveal .progress:after {
+		content: '';
+		display: 'block';
+		position: absolute;
+		height: 20px;
+		width: 100%;
+		top: -20px;
+	}
+	.reveal .progress span {
+		display: block;
+		height: 100%;
+		width: 0px;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+
+.reveal .slide-number {
+	position: fixed;
+	display: block;
+	right: 15px;
+	bottom: 15px;
+	opacity: 0.5;
+	z-index: 31;
+	font-size: 12px;
+}
+
+/*********************************************
+ * SLIDES
+ *********************************************/
+
+.reveal {
+	position: relative;
+	width: 100%;
+	height: 100%;
+
+	-ms-touch-action: none;
+}
+
+.reveal .slides {
+	position: absolute;
+    max-width: 1024px;
+	width: 120%;
+	height: 100%;
+	left: 50%;
+	top: 50%;
+
+	overflow: visible;
+	z-index: 1;
+	text-align: center;
+
+	-webkit-transition: -webkit-perspective .4s ease;
+	   -moz-transition: -moz-perspective .4s ease;
+	    -ms-transition: -ms-perspective .4s ease;
+	     -o-transition: -o-perspective .4s ease;
+	        transition: perspective .4s ease;
+
+	-webkit-perspective: 600px;
+	   -moz-perspective: 600px;
+	    -ms-perspective: 600px;
+	        perspective: 600px;
+
+	-webkit-perspective-origin: 0px -100px;
+	   -moz-perspective-origin: 0px -100px;
+	    -ms-perspective-origin: 0px -100px;
+	        perspective-origin: 0px -100px;
+}
+
+.reveal .slides>section {
+	-ms-perspective: 600px;
+}
+
+.reveal .slides>section,
+.reveal .slides>section>section {
+	display: none;
+	position: absolute;
+	width: 100%;
+	padding: 20px 0px;
+
+	z-index: 10;
+	line-height: 1.2em;
+	font-weight: inherit;
+
+	-webkit-transform-style: preserve-3d;
+	   -moz-transform-style: preserve-3d;
+	    -ms-transform-style: preserve-3d;
+	        transform-style: preserve-3d;
+
+	-webkit-transition: -webkit-transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						-webkit-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	   -moz-transition: -moz-transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						-moz-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	    -ms-transition: -ms-transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						-ms-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	     -o-transition: -o-transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						-o-transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	        transition: transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
+						opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+}
+
+/* Global transition speed settings */
+.reveal[data-transition-speed="fast"] .slides section {
+	-webkit-transition-duration: 400ms;
+	   -moz-transition-duration: 400ms;
+	    -ms-transition-duration: 400ms;
+	        transition-duration: 400ms;
+}
+.reveal[data-transition-speed="slow"] .slides section {
+	-webkit-transition-duration: 1200ms;
+	   -moz-transition-duration: 1200ms;
+	    -ms-transition-duration: 1200ms;
+	        transition-duration: 1200ms;
+}
+
+/* Slide-specific transition speed overrides */
+.reveal .slides section[data-transition-speed="fast"] {
+	-webkit-transition-duration: 400ms;
+	   -moz-transition-duration: 400ms;
+	    -ms-transition-duration: 400ms;
+	        transition-duration: 400ms;
+}
+.reveal .slides section[data-transition-speed="slow"] {
+	-webkit-transition-duration: 1200ms;
+	   -moz-transition-duration: 1200ms;
+	    -ms-transition-duration: 1200ms;
+	        transition-duration: 1200ms;
+}
+
+.reveal .slides>section {
+	left: -50%;
+	top: -50%;
+}
+
+.reveal .slides>section.stack {
+	padding-top: 0;
+	padding-bottom: 0;
+}
+
+.reveal .slides>section.present,
+.reveal .slides>section>section.present {
+	display: block;
+	z-index: 11;
+	opacity: 1;
+}
+
+.reveal.center,
+.reveal.center .slides,
+.reveal.center .slides section {
+	min-height: auto !important;
+}
+
+/* Don't allow interaction with invisible slides */
+.reveal .slides>section.future,
+.reveal .slides>section>section.future,
+.reveal .slides>section.past,
+.reveal .slides>section>section.past {
+	pointer-events: none;
+}
+
+.reveal.overview .slides>section,
+.reveal.overview .slides>section>section {
+	pointer-events: auto;
+}
+
+
+
+/*********************************************
+ * DEFAULT TRANSITION
+ *********************************************/
+
+.reveal .slides>section[data-transition=default].past,
+.reveal .slides>section.past {
+	display: block;
+	opacity: 0;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+}
+.reveal .slides>section[data-transition=default].future,
+.reveal .slides>section.future {
+	display: block;
+	opacity: 0;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+}
+
+.reveal .slides>section>section[data-transition=default].past,
+.reveal .slides>section>section.past {
+	display: block;
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0);
+	   -moz-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0);
+	    -ms-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0);
+	        transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0);
+}
+.reveal .slides>section>section[data-transition=default].future,
+.reveal .slides>section>section.future {
+	display: block;
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
+	   -moz-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
+	    -ms-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
+	        transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
+}
+
+
+/*********************************************
+ * CONCAVE TRANSITION
+ *********************************************/
+
+.reveal .slides>section[data-transition=concave].past,
+.reveal.concave  .slides>section.past {
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+}
+.reveal .slides>section[data-transition=concave].future,
+.reveal.concave .slides>section.future {
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+}
+
+.reveal .slides>section>section[data-transition=concave].past,
+.reveal.concave .slides>section>section.past {
+	-webkit-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	   -moz-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	    -ms-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	        transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+}
+.reveal .slides>section>section[data-transition=concave].future,
+.reveal.concave .slides>section>section.future {
+	-webkit-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	   -moz-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	    -ms-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	        transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+}
+
+
+/*********************************************
+ * ZOOM TRANSITION
+ *********************************************/
+
+.reveal .slides>section[data-transition=zoom],
+.reveal.zoom .slides>section {
+	-webkit-transition-timing-function: ease;
+	   -moz-transition-timing-function: ease;
+	    -ms-transition-timing-function: ease;
+	     -o-transition-timing-function: ease;
+	        transition-timing-function: ease;
+}
+
+.reveal .slides>section[data-transition=zoom].past,
+.reveal.zoom .slides>section.past {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(16);
+	   -moz-transform: scale(16);
+	    -ms-transform: scale(16);
+	     -o-transform: scale(16);
+	        transform: scale(16);
+}
+.reveal .slides>section[data-transition=zoom].future,
+.reveal.zoom .slides>section.future {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(0.2);
+	   -moz-transform: scale(0.2);
+	    -ms-transform: scale(0.2);
+	     -o-transform: scale(0.2);
+	        transform: scale(0.2);
+}
+
+.reveal .slides>section>section[data-transition=zoom].past,
+.reveal.zoom .slides>section>section.past {
+	-webkit-transform: translate(0, -150%);
+	   -moz-transform: translate(0, -150%);
+	    -ms-transform: translate(0, -150%);
+	     -o-transform: translate(0, -150%);
+	        transform: translate(0, -150%);
+}
+.reveal .slides>section>section[data-transition=zoom].future,
+.reveal.zoom .slides>section>section.future {
+	-webkit-transform: translate(0, 150%);
+	   -moz-transform: translate(0, 150%);
+	    -ms-transform: translate(0, 150%);
+	     -o-transform: translate(0, 150%);
+	        transform: translate(0, 150%);
+}
+
+
+/*********************************************
+ * LINEAR TRANSITION
+ *********************************************/
+
+.reveal.linear section {
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	    -ms-backface-visibility: hidden;
+	        backface-visibility: hidden;
+}
+
+.reveal .slides>section[data-transition=linear].past,
+.reveal.linear .slides>section.past {
+	-webkit-transform: translate(-150%, 0);
+	   -moz-transform: translate(-150%, 0);
+	    -ms-transform: translate(-150%, 0);
+	     -o-transform: translate(-150%, 0);
+	        transform: translate(-150%, 0);
+}
+.reveal .slides>section[data-transition=linear].future,
+.reveal.linear .slides>section.future {
+	-webkit-transform: translate(150%, 0);
+	   -moz-transform: translate(150%, 0);
+	    -ms-transform: translate(150%, 0);
+	     -o-transform: translate(150%, 0);
+	        transform: translate(150%, 0);
+}
+
+.reveal .slides>section>section[data-transition=linear].past,
+.reveal.linear .slides>section>section.past {
+	-webkit-transform: translate(0, -150%);
+	   -moz-transform: translate(0, -150%);
+	    -ms-transform: translate(0, -150%);
+	     -o-transform: translate(0, -150%);
+	        transform: translate(0, -150%);
+}
+.reveal .slides>section>section[data-transition=linear].future,
+.reveal.linear .slides>section>section.future {
+	-webkit-transform: translate(0, 150%);
+	   -moz-transform: translate(0, 150%);
+	    -ms-transform: translate(0, 150%);
+	     -o-transform: translate(0, 150%);
+	        transform: translate(0, 150%);
+}
+
+
+/*********************************************
+ * CUBE TRANSITION
+ *********************************************/
+
+.reveal.cube .slides {
+	-webkit-perspective: 1300px;
+	   -moz-perspective: 1300px;
+	    -ms-perspective: 1300px;
+	        perspective: 1300px;
+}
+
+.reveal.cube .slides section {
+	padding: 30px;
+	min-height: 700px;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	    -ms-backface-visibility: hidden;
+	        backface-visibility: hidden;
+
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+	.reveal.center.cube .slides section {
+		min-height: auto;
+	}
+	.reveal.cube .slides section:not(.stack):before {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+		background: rgba(0,0,0,0.1);
+		border-radius: 4px;
+
+		-webkit-transform: translateZ( -20px );
+		   -moz-transform: translateZ( -20px );
+		    -ms-transform: translateZ( -20px );
+		     -o-transform: translateZ( -20px );
+		        transform: translateZ( -20px );
+	}
+	.reveal.cube .slides section:not(.stack):after {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 90%;
+		height: 30px;
+		left: 5%;
+		bottom: 0;
+		background: none;
+		z-index: 1;
+
+		border-radius: 4px;
+		box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ(-90px) rotateX( 65deg );
+		   -moz-transform: translateZ(-90px) rotateX( 65deg );
+		    -ms-transform: translateZ(-90px) rotateX( 65deg );
+		     -o-transform: translateZ(-90px) rotateX( 65deg );
+		        transform: translateZ(-90px) rotateX( 65deg );
+	}
+
+.reveal.cube .slides>section.stack {
+	padding: 0;
+	background: none;
+}
+
+.reveal.cube .slides>section.past {
+	-webkit-transform-origin: 100% 0%;
+	   -moz-transform-origin: 100% 0%;
+	    -ms-transform-origin: 100% 0%;
+	        transform-origin: 100% 0%;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+}
+
+.reveal.cube .slides>section.future {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg);
+}
+
+.reveal.cube .slides>section>section.past {
+	-webkit-transform-origin: 0% 100%;
+	   -moz-transform-origin: 0% 100%;
+	    -ms-transform-origin: 0% 100%;
+	        transform-origin: 0% 100%;
+
+	-webkit-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	   -moz-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	    -ms-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	        transform: translate3d(0, -100%, 0) rotateX(90deg);
+}
+
+.reveal.cube .slides>section>section.future {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	   -moz-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	    -ms-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	        transform: translate3d(0, 100%, 0) rotateX(-90deg);
+}
+
+
+/*********************************************
+ * PAGE TRANSITION
+ *********************************************/
+
+.reveal.page .slides {
+	-webkit-perspective-origin: 0% 50%;
+	   -moz-perspective-origin: 0% 50%;
+	    -ms-perspective-origin: 0% 50%;
+	        perspective-origin: 0% 50%;
+
+	-webkit-perspective: 3000px;
+	   -moz-perspective: 3000px;
+	    -ms-perspective: 3000px;
+	        perspective: 3000px;
+}
+
+.reveal.page .slides section {
+	padding: 30px;
+	min-height: 700px;
+
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+	.reveal.page .slides section.past {
+		z-index: 12;
+	}
+	.reveal.page .slides section:not(.stack):before {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+		background: rgba(0,0,0,0.1);
+
+		-webkit-transform: translateZ( -20px );
+		   -moz-transform: translateZ( -20px );
+		    -ms-transform: translateZ( -20px );
+		     -o-transform: translateZ( -20px );
+		        transform: translateZ( -20px );
+	}
+	.reveal.page .slides section:not(.stack):after {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 90%;
+		height: 30px;
+		left: 5%;
+		bottom: 0;
+		background: none;
+		z-index: 1;
+
+		border-radius: 4px;
+		box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ(-90px) rotateX( 65deg );
+	}
+
+.reveal.page .slides>section.stack {
+	padding: 0;
+	background: none;
+}
+
+.reveal.page .slides>section.past {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	   -moz-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	    -ms-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	        transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+}
+
+.reveal.page .slides>section.future {
+	-webkit-transform-origin: 100% 0%;
+	   -moz-transform-origin: 100% 0%;
+	    -ms-transform-origin: 100% 0%;
+	        transform-origin: 100% 0%;
+
+	-webkit-transform: translate3d(0, 0, 0);
+	   -moz-transform: translate3d(0, 0, 0);
+	    -ms-transform: translate3d(0, 0, 0);
+	        transform: translate3d(0, 0, 0);
+}
+
+.reveal.page .slides>section>section.past {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	   -moz-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	    -ms-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	        transform: translate3d(0, -40%, 0) rotateX(80deg);
+}
+
+.reveal.page .slides>section>section.future {
+	-webkit-transform-origin: 0% 100%;
+	   -moz-transform-origin: 0% 100%;
+	    -ms-transform-origin: 0% 100%;
+	        transform-origin: 0% 100%;
+
+	-webkit-transform: translate3d(0, 0, 0);
+	   -moz-transform: translate3d(0, 0, 0);
+	    -ms-transform: translate3d(0, 0, 0);
+	        transform: translate3d(0, 0, 0);
+}
+
+
+/*********************************************
+ * FADE TRANSITION
+ *********************************************/
+
+.reveal .slides section[data-transition=fade],
+.reveal.fade .slides section,
+.reveal.fade .slides>section>section {
+    -webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	     -o-transform: none;
+	        transform: none;
+
+	-webkit-transition: opacity 0.5s;
+	   -moz-transition: opacity 0.5s;
+	    -ms-transition: opacity 0.5s;
+	     -o-transition: opacity 0.5s;
+	        transition: opacity 0.5s;
+}
+
+
+.reveal.fade.overview .slides section,
+.reveal.fade.overview .slides>section>section,
+.reveal.fade.overview-deactivating .slides section,
+.reveal.fade.overview-deactivating .slides>section>section {
+	-webkit-transition: none;
+	   -moz-transition: none;
+	    -ms-transition: none;
+	     -o-transition: none;
+	        transition: none;
+}
+
+
+/*********************************************
+ * NO TRANSITION
+ *********************************************/
+
+.reveal .slides section[data-transition=none],
+.reveal.none .slides section {
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	     -o-transform: none;
+	        transform: none;
+
+	-webkit-transition: none;
+	   -moz-transition: none;
+	    -ms-transition: none;
+	     -o-transition: none;
+	        transition: none;
+}
+
+
+/*********************************************
+ * OVERVIEW
+ *********************************************/
+
+.reveal.overview .slides {
+	-webkit-perspective-origin: 0% 0%;
+	   -moz-perspective-origin: 0% 0%;
+	    -ms-perspective-origin: 0% 0%;
+	        perspective-origin: 0% 0%;
+
+	-webkit-perspective: 700px;
+	   -moz-perspective: 700px;
+	    -ms-perspective: 700px;
+	        perspective: 700px;
+}
+
+.reveal.overview .slides section {
+	height: 600px;
+	top: -300px !important;
+	overflow: hidden;
+	opacity: 1 !important;
+	visibility: visible !important;
+	cursor: pointer;
+	background: rgba(0,0,0,0.1);
+}
+.reveal.overview .slides section .fragment {
+	opacity: 1;
+}
+.reveal.overview .slides section:after,
+.reveal.overview .slides section:before {
+	display: none !important;
+}
+.reveal.overview .slides section>section {
+	opacity: 1;
+	cursor: pointer;
+}
+	.reveal.overview .slides section:hover {
+		background: rgba(0,0,0,0.3);
+	}
+	.reveal.overview .slides section.present {
+		background: rgba(0,0,0,0.3);
+	}
+.reveal.overview .slides>section.stack {
+	padding: 0;
+	top: 0 !important;
+	background: none;
+	overflow: visible;
+}
+
+
+/*********************************************
+ * PAUSED MODE
+ *********************************************/
+
+.reveal .pause-overlay {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	background: black;
+	visibility: hidden;
+	opacity: 0;
+	z-index: 100;
+
+	-webkit-transition: all 1s ease;
+	   -moz-transition: all 1s ease;
+	    -ms-transition: all 1s ease;
+	     -o-transition: all 1s ease;
+	        transition: all 1s ease;
+}
+.reveal.paused .pause-overlay {
+	visibility: visible;
+	opacity: 1;
+}
+
+
+/*********************************************
+ * FALLBACK
+ *********************************************/
+
+.no-transforms {
+	overflow-y: auto;
+}
+
+.no-transforms .reveal .slides {
+	position: relative;
+	width: 80%;
+	height: auto !important;
+	top: 0;
+	left: 50%;
+	margin: 0;
+	text-align: center;
+}
+
+.no-transforms .reveal .controls,
+.no-transforms .reveal .progress {
+	display: none !important;
+}
+
+.no-transforms .reveal .slides section {
+	display: block !important;
+	opacity: 1 !important;
+	position: relative !important;
+	height: auto;
+	min-height: auto;
+	top: 0;
+	left: -50%;
+	margin: 70px 0;
+
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	     -o-transform: none;
+	        transform: none;
+}
+
+.no-transforms .reveal .slides section section {
+	left: 0;
+}
+
+.reveal .no-transition,
+.reveal .no-transition * {
+	-webkit-transition: none !important;
+	   -moz-transition: none !important;
+	    -ms-transition: none !important;
+	     -o-transition: none !important;
+	        transition: none !important;
+}
+
+
+/*********************************************
+ * BACKGROUND STATES [DEPRECATED]
+ *********************************************/
+
+.reveal .state-background {
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	background: rgba( 0, 0, 0, 0 );
+
+	-webkit-transition: background 800ms ease;
+	   -moz-transition: background 800ms ease;
+	    -ms-transition: background 800ms ease;
+	     -o-transition: background 800ms ease;
+	        transition: background 800ms ease;
+}
+.alert .reveal .state-background {
+	background: rgba( 200, 50, 30, 0.6 );
+}
+.soothe .reveal .state-background {
+	background: rgba( 50, 200, 90, 0.4 );
+}
+.blackout .reveal .state-background {
+	background: rgba( 0, 0, 0, 0.6 );
+}
+.whiteout .reveal .state-background {
+	background: rgba( 255, 255, 255, 0.6 );
+}
+.cobalt .reveal .state-background {
+	background: rgba( 22, 152, 213, 0.6 );
+}
+.mint .reveal .state-background {
+	background: rgba( 22, 213, 75, 0.6 );
+}
+.submerge .reveal .state-background {
+	background: rgba( 12, 25, 77, 0.6);
+}
+.lila .reveal .state-background {
+	background: rgba( 180, 50, 140, 0.6 );
+}
+.sunset .reveal .state-background {
+	background: rgba( 255, 122, 0, 0.6 );
+}
+
+
+/*********************************************
+ * PER-SLIDE BACKGROUNDS
+ *********************************************/
+
+.reveal>.backgrounds {
+	position: absolute;
+	width: 100%;
+	height: 100%;
+
+	-webkit-perspective: 600px;
+	   -moz-perspective: 600px;
+	    -ms-perspective: 600px;
+	        perspective: 600px;
+}
+	.reveal .slide-background {
+		position: absolute;
+		width: 100%;
+		height: 100%;
+		opacity: 0;
+		visibility: hidden;
+
+		background-color: rgba( 0, 0, 0, 0 );
+		background-position: 50% 50%;
+		background-repeat: no-repeat;
+		background-size: cover;
+
+		-webkit-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+	.reveal .slide-background.present {
+		opacity: 1;
+		visibility: visible;
+	}
+
+	.print-pdf .reveal .slide-background {
+		opacity: 1 !important;
+		visibility: visible !important;
+	}
+
+/* Immediate transition style */
+.reveal[data-background-transition=none]>.backgrounds .slide-background,
+.reveal>.backgrounds .slide-background[data-background-transition=none] {
+	-webkit-transition: none;
+	   -moz-transition: none;
+	    -ms-transition: none;
+	     -o-transition: none;
+	        transition: none;
+}
+
+/* 2D slide */
+.reveal[data-background-transition=slide]>.backgrounds .slide-background,
+.reveal>.backgrounds .slide-background[data-background-transition=slide] {
+	opacity: 1;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	    -ms-backface-visibility: hidden;
+	        backface-visibility: hidden;
+}
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background.past,
+	.reveal>.backgrounds .slide-background.past[data-background-transition=slide] {
+		-webkit-transform: translate(-100%, 0);
+		   -moz-transform: translate(-100%, 0);
+		    -ms-transform: translate(-100%, 0);
+		     -o-transform: translate(-100%, 0);
+		        transform: translate(-100%, 0);
+	}
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background.future,
+	.reveal>.backgrounds .slide-background.future[data-background-transition=slide] {
+		-webkit-transform: translate(100%, 0);
+		   -moz-transform: translate(100%, 0);
+		    -ms-transform: translate(100%, 0);
+		     -o-transform: translate(100%, 0);
+		        transform: translate(100%, 0);
+	}
+
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past,
+	.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide] {
+		-webkit-transform: translate(0, -100%);
+		   -moz-transform: translate(0, -100%);
+		    -ms-transform: translate(0, -100%);
+		     -o-transform: translate(0, -100%);
+		        transform: translate(0, -100%);
+	}
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future,
+	.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide] {
+		-webkit-transform: translate(0, 100%);
+		   -moz-transform: translate(0, 100%);
+		    -ms-transform: translate(0, 100%);
+		     -o-transform: translate(0, 100%);
+		        transform: translate(0, 100%);
+	}
+
+
+/* Convex */
+.reveal[data-background-transition=convex]>.backgrounds .slide-background.past,
+.reveal>.backgrounds .slide-background.past[data-background-transition=convex] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+}
+.reveal[data-background-transition=convex]>.backgrounds .slide-background.future,
+.reveal>.backgrounds .slide-background.future[data-background-transition=convex] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+}
+
+.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past,
+.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
+	   -moz-transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
+	    -ms-transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
+	        transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
+}
+.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future,
+.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
+	   -moz-transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
+	    -ms-transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
+	        transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
+}
+
+
+/* Concave */
+.reveal[data-background-transition=concave]>.backgrounds .slide-background.past,
+.reveal>.backgrounds .slide-background.past[data-background-transition=concave] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+}
+.reveal[data-background-transition=concave]>.backgrounds .slide-background.future,
+.reveal>.backgrounds .slide-background.future[data-background-transition=concave] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+}
+
+.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past,
+.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
+	   -moz-transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
+	    -ms-transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
+	        transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
+}
+.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future,
+.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave] {
+	opacity: 0;
+
+	-webkit-transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
+	   -moz-transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
+	    -ms-transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
+	        transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
+}
+
+/* Zoom */
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background,
+.reveal>.backgrounds .slide-background[data-background-transition=zoom] {
+	-webkit-transition-timing-function: ease;
+	   -moz-transition-timing-function: ease;
+	    -ms-transition-timing-function: ease;
+	     -o-transition-timing-function: ease;
+	        transition-timing-function: ease;
+}
+
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past,
+.reveal>.backgrounds .slide-background.past[data-background-transition=zoom] {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(16);
+	   -moz-transform: scale(16);
+	    -ms-transform: scale(16);
+	     -o-transform: scale(16);
+	        transform: scale(16);
+}
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future,
+.reveal>.backgrounds .slide-background.future[data-background-transition=zoom] {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(0.2);
+	   -moz-transform: scale(0.2);
+	    -ms-transform: scale(0.2);
+	     -o-transform: scale(0.2);
+	        transform: scale(0.2);
+}
+
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past,
+.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom] {
+	opacity: 0;
+		visibility: hidden;
+
+		-webkit-transform: scale(16);
+		   -moz-transform: scale(16);
+		    -ms-transform: scale(16);
+		     -o-transform: scale(16);
+		        transform: scale(16);
+}
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future,
+.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom] {
+	opacity: 0;
+	visibility: hidden;
+
+	-webkit-transform: scale(0.2);
+	   -moz-transform: scale(0.2);
+	    -ms-transform: scale(0.2);
+	     -o-transform: scale(0.2);
+	        transform: scale(0.2);
+}
+
+
+/* Global transition speed settings */
+.reveal[data-transition-speed="fast"]>.backgrounds .slide-background {
+	-webkit-transition-duration: 400ms;
+	   -moz-transition-duration: 400ms;
+	    -ms-transition-duration: 400ms;
+	        transition-duration: 400ms;
+}
+.reveal[data-transition-speed="slow"]>.backgrounds .slide-background {
+	-webkit-transition-duration: 1200ms;
+	   -moz-transition-duration: 1200ms;
+	    -ms-transition-duration: 1200ms;
+	        transition-duration: 1200ms;
+}
+
+
+/*********************************************
+ * RTL SUPPORT
+ *********************************************/
+
+.reveal.rtl .slides,
+.reveal.rtl .slides h1,
+.reveal.rtl .slides h2,
+.reveal.rtl .slides h3,
+.reveal.rtl .slides h4,
+.reveal.rtl .slides h5,
+.reveal.rtl .slides h6 {
+	direction: rtl;
+	font-family: sans-serif;
+}
+
+.reveal.rtl pre,
+.reveal.rtl code {
+	direction: ltr;
+}
+
+.reveal.rtl ol,
+.reveal.rtl ul {
+	text-align: right;
+}
+
+.reveal.rtl .progress span {
+	float: right
+}
+
+/*********************************************
+ * PARALLAX BACKGROUND
+ *********************************************/
+
+.reveal.has-parallax-background .backgrounds {
+	-webkit-transition: all 0.8s ease;
+	   -moz-transition: all 0.8s ease;
+	    -ms-transition: all 0.8s ease;
+	        transition: all 0.8s ease;
+}
+
+/* Global transition speed settings */
+.reveal.has-parallax-background[data-transition-speed="fast"] .backgrounds {
+	-webkit-transition-duration: 400ms;
+	   -moz-transition-duration: 400ms;
+	    -ms-transition-duration: 400ms;
+	        transition-duration: 400ms;
+}
+.reveal.has-parallax-background[data-transition-speed="slow"] .backgrounds {
+	-webkit-transition-duration: 1200ms;
+	   -moz-transition-duration: 1200ms;
+	    -ms-transition-duration: 1200ms;
+	        transition-duration: 1200ms;
+}
+
+
+/*********************************************
+ * LINK PREVIEW OVERLAY
+ *********************************************/
+
+ .reveal .preview-link-overlay {
+ 	position: absolute;
+ 	top: 0;
+ 	left: 0;
+ 	width: 100%;
+ 	height: 100%;
+ 	z-index: 1000;
+ 	background: rgba( 0, 0, 0, 0.9 );
+ 	opacity: 0;
+ 	visibility: hidden;
+
+ 	-webkit-transition: all 0.3s ease;
+ 	   -moz-transition: all 0.3s ease;
+ 	    -ms-transition: all 0.3s ease;
+ 	        transition: all 0.3s ease;
+ }
+ 	.reveal .preview-link-overlay.visible {
+ 		opacity: 1;
+ 		visibility: visible;
+ 	}
+
+ 	.reveal .preview-link-overlay .spinner {
+ 		position: absolute;
+ 		display: block;
+ 		top: 50%;
+ 		left: 50%;
+ 		width: 32px;
+ 		height: 32px;
+ 		margin: -16px 0 0 -16px;
+ 		z-index: 10;
+ 		background-image: url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D);
+
+ 		visibility: visible;
+ 		opacity: 0.6;
+
+ 		-webkit-transition: all 0.3s ease;
+ 		   -moz-transition: all 0.3s ease;
+ 		    -ms-transition: all 0.3s ease;
+ 		        transition: all 0.3s ease;
+ 	}
+
+ 	.reveal .preview-link-overlay header {
+ 		position: absolute;
+ 		left: 0;
+ 		top: 0;
+ 		width: 100%;
+ 		height: 40px;
+ 		z-index: 2;
+ 		border-bottom: 1px solid #222;
+ 	}
+ 		.reveal .preview-link-overlay header a {
+ 			display: inline-block;
+ 			width: 40px;
+ 			height: 40px;
+ 			padding: 0 10px;
+ 			float: right;
+ 			opacity: 0.6;
+
+ 			box-sizing: border-box;
+ 		}
+ 			.reveal .preview-link-overlay header a:hover {
+ 				opacity: 1;
+ 			}
+ 			.reveal .preview-link-overlay header a .icon {
+ 				display: inline-block;
+ 				width: 20px;
+ 				height: 20px;
+
+ 				background-position: 50% 50%;
+ 				background-size: 100%;
+ 				background-repeat: no-repeat;
+ 			}
+ 			.reveal .preview-link-overlay header a.close .icon {
+ 				background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC);
+ 			}
+ 			.reveal .preview-link-overlay header a.external .icon {
+ 				background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==);
+ 			}
+
+ 	.reveal .preview-link-overlay .viewport {
+ 		position: absolute;
+ 		top: 40px;
+ 		right: 0;
+ 		bottom: 0;
+ 		left: 0;
+ 	}
+
+ 	.reveal .preview-link-overlay .viewport iframe {
+ 		width: 100%;
+ 		height: 100%;
+ 		max-width: 100%;
+ 		max-height: 100%;
+ 		border: 0;
+
+ 		opacity: 0;
+ 		visibility: hidden;
+
+ 		-webkit-transition: all 0.3s ease;
+ 		   -moz-transition: all 0.3s ease;
+ 		    -ms-transition: all 0.3s ease;
+ 		        transition: all 0.3s ease;
+ 	}
+
+ 	.reveal .preview-link-overlay.loaded .viewport iframe {
+ 		opacity: 1;
+ 		visibility: visible;
+ 	}
+
+ 	.reveal .preview-link-overlay.loaded .spinner {
+ 		opacity: 0;
+ 		visibility: hidden;
+
+ 		-webkit-transform: scale(0.2);
+ 		   -moz-transform: scale(0.2);
+ 		    -ms-transform: scale(0.2);
+ 		        transform: scale(0.2);
+ 	}
+
+
+
+/*********************************************
+ * PLAYBACK COMPONENT
+ *********************************************/
+
+.reveal .playback {
+	position: fixed;
+	left: 15px;
+	bottom: 15px;
+	z-index: 30;
+	cursor: pointer;
+
+	-webkit-transition: all 400ms ease;
+	   -moz-transition: all 400ms ease;
+	    -ms-transition: all 400ms ease;
+	        transition: all 400ms ease;
+}
+
+.reveal.overview .playback {
+	opacity: 0;
+	visibility: hidden;
+}
+
+
+/*********************************************
+ * ROLLING LINKS
+ *********************************************/
+
+.reveal .roll {
+	display: inline-block;
+	line-height: 1.2;
+	overflow: hidden;
+
+	vertical-align: top;
+
+	-webkit-perspective: 400px;
+	   -moz-perspective: 400px;
+	    -ms-perspective: 400px;
+	        perspective: 400px;
+
+	-webkit-perspective-origin: 50% 50%;
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+	.reveal .roll:hover {
+		background: none;
+		text-shadow: none;
+	}
+.reveal .roll span {
+	display: block;
+	position: relative;
+	padding: 0 2px;
+
+	pointer-events: none;
+
+	-webkit-transition: all 400ms ease;
+	   -moz-transition: all 400ms ease;
+	    -ms-transition: all 400ms ease;
+	        transition: all 400ms ease;
+
+	-webkit-transform-origin: 50% 0%;
+	   -moz-transform-origin: 50% 0%;
+	    -ms-transform-origin: 50% 0%;
+	        transform-origin: 50% 0%;
+
+	-webkit-transform-style: preserve-3d;
+	   -moz-transform-style: preserve-3d;
+	    -ms-transform-style: preserve-3d;
+	        transform-style: preserve-3d;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	        backface-visibility: hidden;
+}
+	.reveal .roll:hover span {
+	    background: rgba(0,0,0,0.5);
+
+	    -webkit-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	       -moz-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	        -ms-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	            transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	}
+.reveal .roll span:after {
+	content: attr(data-title);
+
+	display: block;
+	position: absolute;
+	left: 0;
+	top: 0;
+	padding: 0 2px;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	        backface-visibility: hidden;
+
+	-webkit-transform-origin: 50% 0%;
+	   -moz-transform-origin: 50% 0%;
+	    -ms-transform-origin: 50% 0%;
+	        transform-origin: 50% 0%;
+
+	-webkit-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	   -moz-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	    -ms-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	        transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+}
+
+
+/*********************************************
+ * SPEAKER NOTES
+ *********************************************/
+
+.reveal aside.notes {
+	display: none;
+}
+
+
+/*********************************************
+ * ZOOM PLUGIN
+ *********************************************/
+
+.zoomed .reveal *,
+.zoomed .reveal *:before,
+.zoomed .reveal *:after {
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+
+	-webkit-backface-visibility: visible !important;
+	   -moz-backface-visibility: visible !important;
+	    -ms-backface-visibility: visible !important;
+	        backface-visibility: visible !important;
+}
+
+.zoomed .reveal .progress,
+.zoomed .reveal .controls {
+	opacity: 0;
+}
+
+.zoomed .reveal .roll span {
+	background: none;
+}
+
+.zoomed .reveal .roll span:after {
+	visibility: hidden;
+}
+
+
diff --git a/docs/slides/IHP14/_support/reveal.js/css/reveal.min.css b/docs/slides/IHP14/_support/reveal.js/css/reveal.min.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/reveal.min.css
@@ -0,0 +1,7 @@
+@charset "UTF-8";/*!
+ * reveal.js
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+ */ html,body,.reveal div,.reveal span,.reveal applet,.reveal object,.reveal iframe,.reveal h1,.reveal h2,.reveal h3,.reveal h4,.reveal h5,.reveal h6,.reveal p,.reveal blockquote,.reveal pre,.reveal a,.reveal abbr,.reveal acronym,.reveal address,.reveal big,.reveal cite,.reveal code,.reveal del,.reveal dfn,.reveal em,.reveal img,.reveal ins,.reveal kbd,.reveal q,.reveal s,.reveal samp,.reveal small,.reveal strike,.reveal strong,.reveal sub,.reveal sup,.reveal tt,.reveal var,.reveal b,.reveal u,.reveal i,.reveal center,.reveal dl,.reveal dt,.reveal dd,.reveal ol,.reveal ul,.reveal li,.reveal fieldset,.reveal form,.reveal label,.reveal legend,.reveal table,.reveal caption,.reveal tbody,.reveal tfoot,.reveal thead,.reveal tr,.reveal th,.reveal td,.reveal article,.reveal aside,.reveal canvas,.reveal details,.reveal embed,.reveal figure,.reveal figcaption,.reveal footer,.reveal header,.reveal hgroup,.reveal menu,.reveal nav,.reveal output,.reveal ruby,.reveal section,.reveal summary,.reveal time,.reveal mark,.reveal audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}.reveal article,.reveal aside,.reveal details,.reveal figcaption,.reveal figure,.reveal footer,.reveal header,.reveal hgroup,.reveal menu,.reveal nav,.reveal section{display:block}html,body{width:100%;height:100%;overflow:hidden}body{position:relative;line-height:1}::selection{background:#FF5E99;color:#fff;text-shadow:none}.reveal h1,.reveal h2,.reveal h3,.reveal h4,.reveal h5,.reveal h6{-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto;word-wrap:break-word;line-height:1}.reveal h1{font-size:3.77em}.reveal h2{font-size:2.11em}.reveal h3{font-size:1.55em}.reveal h4{font-size:1em}.reveal .slides section .fragment{opacity:0;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-ms-transition:all .2s ease;-o-transition:all .2s ease;transition:all .2s ease}.reveal .slides section .fragment.visible{opacity:1}.reveal .slides section .fragment.grow{opacity:1}.reveal .slides section .fragment.grow.visible{-webkit-transform:scale(1.3);-moz-transform:scale(1.3);-ms-transform:scale(1.3);-o-transform:scale(1.3);transform:scale(1.3)}.reveal .slides section .fragment.shrink{opacity:1}.reveal .slides section .fragment.shrink.visible{-webkit-transform:scale(0.7);-moz-transform:scale(0.7);-ms-transform:scale(0.7);-o-transform:scale(0.7);transform:scale(0.7)}.reveal .slides section .fragment.zoom-in{opacity:0;-webkit-transform:scale(0.1);-moz-transform:scale(0.1);-ms-transform:scale(0.1);-o-transform:scale(0.1);transform:scale(0.1)}.reveal .slides section .fragment.zoom-in.visible{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}.reveal .slides section .fragment.roll-in{opacity:0;-webkit-transform:rotateX(90deg);-moz-transform:rotateX(90deg);-ms-transform:rotateX(90deg);-o-transform:rotateX(90deg);transform:rotateX(90deg)}.reveal .slides section .fragment.roll-in.visible{opacity:1;-webkit-transform:rotateX(0);-moz-transform:rotateX(0);-ms-transform:rotateX(0);-o-transform:rotateX(0);transform:rotateX(0)}.reveal .slides section .fragment.fade-out{opacity:1}.reveal .slides section .fragment.fade-out.visible{opacity:0}.reveal .slides section .fragment.semi-fade-out{opacity:1}.reveal .slides section .fragment.semi-fade-out.visible{opacity:.5}.reveal .slides section .fragment.current-visible{opacity:0}.reveal .slides section .fragment.current-visible.current-fragment{opacity:1}.reveal .slides section .fragment.highlight-red,.reveal .slides section .fragment.highlight-current-red,.reveal .slides section .fragment.highlight-green,.reveal .slides section .fragment.highlight-current-green,.reveal .slides section .fragment.highlight-blue,.reveal .slides section .fragment.highlight-current-blue{opacity:1}.reveal .slides section .fragment.highlight-red.visible{color:#ff2c2d}.reveal .slides section .fragment.highlight-green.visible{color:#17ff2e}.reveal .slides section .fragment.highlight-blue.visible{color:#1b91ff}.reveal .slides section .fragment.highlight-current-red.current-fragment{color:#ff2c2d}.reveal .slides section .fragment.highlight-current-green.current-fragment{color:#17ff2e}.reveal .slides section .fragment.highlight-current-blue.current-fragment{color:#1b91ff}.reveal:after{content:'';font-style:italic}.reveal iframe{z-index:1}.reveal img,.reveal video,.reveal iframe{max-width:95%;max-height:95%}.reveal a{position:relative}.reveal strong,.reveal b{font-weight:700}.reveal em,.reveal i{font-style:italic}.reveal ol,.reveal ul{display:inline-block;text-align:left;margin:0 0 0 1em}.reveal ol{list-style-type:decimal}.reveal ul{list-style-type:disc}.reveal ul ul{list-style-type:square}.reveal ul ul ul{list-style-type:circle}.reveal ul ul,.reveal ul ol,.reveal ol ol,.reveal ol ul{display:block;margin-left:40px}.reveal p{margin-bottom:10px;line-height:1.2em}.reveal q,.reveal blockquote{quotes:none}.reveal blockquote{display:block;position:relative;width:70%;margin:5px auto;padding:5px;font-style:italic;background:rgba(255,255,255,.05);box-shadow:0 0 2px rgba(0,0,0,.2)}.reveal blockquote p:first-child,.reveal blockquote p:last-child{display:inline-block}.reveal q{font-style:italic}.reveal pre{display:block;position:relative;width:90%;margin:15px auto;text-align:left;font-size:.55em;font-family:monospace;line-height:1.2em;word-wrap:break-word;box-shadow:0 0 6px rgba(0,0,0,.3)}.reveal code{font-family:monospace}.reveal pre code{padding:5px;overflow:auto;max-height:400px;word-wrap:normal}.reveal pre.stretch code{height:100%;max-height:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.reveal table th,.reveal table td{text-align:left;padding-right:.3em}.reveal table th{font-weight:700}.reveal sup{vertical-align:super}.reveal sub{vertical-align:sub}.reveal small{display:inline-block;font-size:.6em;line-height:1.2em;vertical-align:top}.reveal small *{vertical-align:top}.reveal .stretch{max-width:none;max-height:none}.reveal .controls{display:none;position:fixed;width:110px;height:110px;z-index:30;right:10px;bottom:10px}.reveal .controls div{position:absolute;opacity:.05;width:0;height:0;border:12px solid transparent;-moz-transform:scale(.9999);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-ms-transition:all .2s ease;-o-transition:all .2s ease;transition:all .2s ease}.reveal .controls div.enabled{opacity:.7;cursor:pointer}.reveal .controls div.enabled:active{margin-top:1px}.reveal .controls div.navigate-left{top:42px;border-right-width:22px;border-right-color:#eee}.reveal .controls div.navigate-left.fragmented{opacity:.3}.reveal .controls div.navigate-right{left:74px;top:42px;border-left-width:22px;border-left-color:#eee}.reveal .controls div.navigate-right.fragmented{opacity:.3}.reveal .controls div.navigate-up{left:42px;border-bottom-width:22px;border-bottom-color:#eee}.reveal .controls div.navigate-up.fragmented{opacity:.3}.reveal .controls div.navigate-down{left:42px;top:74px;border-top-width:22px;border-top-color:#eee}.reveal .controls div.navigate-down.fragmented{opacity:.3}.reveal .progress{position:fixed;display:none;height:3px;width:100%;bottom:0;left:0;z-index:10}.reveal .progress:after{content:'';display:'block';position:absolute;height:20px;width:100%;top:-20px}.reveal .progress span{display:block;height:100%;width:0;-webkit-transition:width 800ms cubic-bezier(0.26,.86,.44,.985);-moz-transition:width 800ms cubic-bezier(0.26,.86,.44,.985);-ms-transition:width 800ms cubic-bezier(0.26,.86,.44,.985);-o-transition:width 800ms cubic-bezier(0.26,.86,.44,.985);transition:width 800ms cubic-bezier(0.26,.86,.44,.985)}.reveal .slide-number{position:fixed;display:block;right:15px;bottom:15px;opacity:.5;z-index:31;font-size:12px}.reveal{position:relative;width:100%;height:100%;-ms-touch-action:none}.reveal .slides{position:absolute;width:100%;height:100%;left:50%;top:50%;overflow:visible;z-index:1;text-align:center;-webkit-transition:-webkit-perspective .4s ease;-moz-transition:-moz-perspective .4s ease;-ms-transition:-ms-perspective .4s ease;-o-transition:-o-perspective .4s ease;transition:perspective .4s ease;-webkit-perspective:600px;-moz-perspective:600px;-ms-perspective:600px;perspective:600px;-webkit-perspective-origin:0 -100px;-moz-perspective-origin:0 -100px;-ms-perspective-origin:0 -100px;perspective-origin:0 -100px}.reveal .slides>section{-ms-perspective:600px}.reveal .slides>section,.reveal .slides>section>section{display:none;position:absolute;width:100%;padding:20px 0;z-index:10;line-height:1.2em;font-weight:inherit;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transition:-webkit-transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),-webkit-transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985);-moz-transition:-moz-transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),-moz-transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985);-ms-transition:-ms-transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),-ms-transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985);-o-transition:-o-transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),-o-transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985);transition:transform-origin 800ms cubic-bezier(0.26,.86,.44,.985),transform 800ms cubic-bezier(0.26,.86,.44,.985),visibility 800ms cubic-bezier(0.26,.86,.44,.985),opacity 800ms cubic-bezier(0.26,.86,.44,.985)}.reveal[data-transition-speed=fast] .slides section{-webkit-transition-duration:400ms;-moz-transition-duration:400ms;-ms-transition-duration:400ms;transition-duration:400ms}.reveal[data-transition-speed=slow] .slides section{-webkit-transition-duration:1200ms;-moz-transition-duration:1200ms;-ms-transition-duration:1200ms;transition-duration:1200ms}.reveal .slides section[data-transition-speed=fast]{-webkit-transition-duration:400ms;-moz-transition-duration:400ms;-ms-transition-duration:400ms;transition-duration:400ms}.reveal .slides section[data-transition-speed=slow]{-webkit-transition-duration:1200ms;-moz-transition-duration:1200ms;-ms-transition-duration:1200ms;transition-duration:1200ms}.reveal .slides>section{left:-50%;top:-50%}.reveal .slides>section.stack{padding-top:0;padding-bottom:0}.reveal .slides>section.present,.reveal .slides>section>section.present{display:block;z-index:11;opacity:1}.reveal.center,.reveal.center .slides,.reveal.center .slides section{min-height:auto!important}.reveal .slides>section.future,.reveal .slides>section>section.future,.reveal .slides>section.past,.reveal .slides>section>section.past{pointer-events:none}.reveal.overview .slides>section,.reveal.overview .slides>section>section{pointer-events:auto}.reveal .slides>section[data-transition=default].past,.reveal .slides>section.past{display:block;opacity:0;-webkit-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);-moz-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=default].future,.reveal .slides>section.future{display:block;opacity:0;-webkit-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);-moz-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=default].past,.reveal .slides>section>section.past{display:block;opacity:0;-webkit-transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0);-moz-transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0);-ms-transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0);transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0)}.reveal .slides>section>section[data-transition=default].future,.reveal .slides>section>section.future{display:block;opacity:0;-webkit-transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0);-moz-transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0);-ms-transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0);transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0)}.reveal .slides>section[data-transition=concave].past,.reveal.concave .slides>section.past{-webkit-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);-moz-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=concave].future,.reveal.concave .slides>section.future{-webkit-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);-moz-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=concave].past,.reveal.concave .slides>section>section.past{-webkit-transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0);-moz-transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0);-ms-transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0);transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0)}.reveal .slides>section>section[data-transition=concave].future,.reveal.concave .slides>section>section.future{-webkit-transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0);-moz-transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0);-ms-transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0);transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0)}.reveal .slides>section[data-transition=zoom],.reveal.zoom .slides>section{-webkit-transition-timing-function:ease;-moz-transition-timing-function:ease;-ms-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.reveal .slides>section[data-transition=zoom].past,.reveal.zoom .slides>section.past{opacity:0;visibility:hidden;-webkit-transform:scale(16);-moz-transform:scale(16);-ms-transform:scale(16);-o-transform:scale(16);transform:scale(16)}.reveal .slides>section[data-transition=zoom].future,.reveal.zoom .slides>section.future{opacity:0;visibility:hidden;-webkit-transform:scale(0.2);-moz-transform:scale(0.2);-ms-transform:scale(0.2);-o-transform:scale(0.2);transform:scale(0.2)}.reveal .slides>section>section[data-transition=zoom].past,.reveal.zoom .slides>section>section.past{-webkit-transform:translate(0,-150%);-moz-transform:translate(0,-150%);-ms-transform:translate(0,-150%);-o-transform:translate(0,-150%);transform:translate(0,-150%)}.reveal .slides>section>section[data-transition=zoom].future,.reveal.zoom .slides>section>section.future{-webkit-transform:translate(0,150%);-moz-transform:translate(0,150%);-ms-transform:translate(0,150%);-o-transform:translate(0,150%);transform:translate(0,150%)}.reveal.linear section{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.reveal .slides>section[data-transition=linear].past,.reveal.linear .slides>section.past{-webkit-transform:translate(-150%,0);-moz-transform:translate(-150%,0);-ms-transform:translate(-150%,0);-o-transform:translate(-150%,0);transform:translate(-150%,0)}.reveal .slides>section[data-transition=linear].future,.reveal.linear .slides>section.future{-webkit-transform:translate(150%,0);-moz-transform:translate(150%,0);-ms-transform:translate(150%,0);-o-transform:translate(150%,0);transform:translate(150%,0)}.reveal .slides>section>section[data-transition=linear].past,.reveal.linear .slides>section>section.past{-webkit-transform:translate(0,-150%);-moz-transform:translate(0,-150%);-ms-transform:translate(0,-150%);-o-transform:translate(0,-150%);transform:translate(0,-150%)}.reveal .slides>section>section[data-transition=linear].future,.reveal.linear .slides>section>section.future{-webkit-transform:translate(0,150%);-moz-transform:translate(0,150%);-ms-transform:translate(0,150%);-o-transform:translate(0,150%);transform:translate(0,150%)}.reveal.cube .slides{-webkit-perspective:1300px;-moz-perspective:1300px;-ms-perspective:1300px;perspective:1300px}.reveal.cube .slides section{padding:30px;min-height:700px;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.reveal.center.cube .slides section{min-height:auto}.reveal.cube .slides section:not(.stack):before{content:'';position:absolute;display:block;width:100%;height:100%;left:0;top:0;background:rgba(0,0,0,.1);border-radius:4px;-webkit-transform:translateZ(-20px);-moz-transform:translateZ(-20px);-ms-transform:translateZ(-20px);-o-transform:translateZ(-20px);transform:translateZ(-20px)}.reveal.cube .slides section:not(.stack):after{content:'';position:absolute;display:block;width:90%;height:30px;left:5%;bottom:0;background:0;z-index:1;border-radius:4px;box-shadow:0 95px 25px rgba(0,0,0,.2);-webkit-transform:translateZ(-90px) rotateX(65deg);-moz-transform:translateZ(-90px) rotateX(65deg);-ms-transform:translateZ(-90px) rotateX(65deg);-o-transform:translateZ(-90px) rotateX(65deg);transform:translateZ(-90px) rotateX(65deg)}.reveal.cube .slides>section.stack{padding:0;background:0}.reveal.cube .slides>section.past{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0;-webkit-transform:translate3d(-100%,0,0) rotateY(-90deg);-moz-transform:translate3d(-100%,0,0) rotateY(-90deg);-ms-transform:translate3d(-100%,0,0) rotateY(-90deg);transform:translate3d(-100%,0,0) rotateY(-90deg)}.reveal.cube .slides>section.future{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translate3d(100%,0,0) rotateY(90deg);-moz-transform:translate3d(100%,0,0) rotateY(90deg);-ms-transform:translate3d(100%,0,0) rotateY(90deg);transform:translate3d(100%,0,0) rotateY(90deg)}.reveal.cube .slides>section>section.past{-webkit-transform-origin:0 100%;-moz-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:translate3d(0,-100%,0) rotateX(90deg);-moz-transform:translate3d(0,-100%,0) rotateX(90deg);-ms-transform:translate3d(0,-100%,0) rotateX(90deg);transform:translate3d(0,-100%,0) rotateX(90deg)}.reveal.cube .slides>section>section.future{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translate3d(0,100%,0) rotateX(-90deg);-moz-transform:translate3d(0,100%,0) rotateX(-90deg);-ms-transform:translate3d(0,100%,0) rotateX(-90deg);transform:translate3d(0,100%,0) rotateX(-90deg)}.reveal.page .slides{-webkit-perspective-origin:0 50%;-moz-perspective-origin:0 50%;-ms-perspective-origin:0 50%;perspective-origin:0 50%;-webkit-perspective:3000px;-moz-perspective:3000px;-ms-perspective:3000px;perspective:3000px}.reveal.page .slides section{padding:30px;min-height:700px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.reveal.page .slides section.past{z-index:12}.reveal.page .slides section:not(.stack):before{content:'';position:absolute;display:block;width:100%;height:100%;left:0;top:0;background:rgba(0,0,0,.1);-webkit-transform:translateZ(-20px);-moz-transform:translateZ(-20px);-ms-transform:translateZ(-20px);-o-transform:translateZ(-20px);transform:translateZ(-20px)}.reveal.page .slides section:not(.stack):after{content:'';position:absolute;display:block;width:90%;height:30px;left:5%;bottom:0;background:0;z-index:1;border-radius:4px;box-shadow:0 95px 25px rgba(0,0,0,.2);-webkit-transform:translateZ(-90px) rotateX(65deg)}.reveal.page .slides>section.stack{padding:0;background:0}.reveal.page .slides>section.past{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translate3d(-40%,0,0) rotateY(-80deg);-moz-transform:translate3d(-40%,0,0) rotateY(-80deg);-ms-transform:translate3d(-40%,0,0) rotateY(-80deg);transform:translate3d(-40%,0,0) rotateY(-80deg)}.reveal.page .slides>section.future{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.reveal.page .slides>section>section.past{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translate3d(0,-40%,0) rotateX(80deg);-moz-transform:translate3d(0,-40%,0) rotateX(80deg);-ms-transform:translate3d(0,-40%,0) rotateX(80deg);transform:translate3d(0,-40%,0) rotateX(80deg)}.reveal.page .slides>section>section.future{-webkit-transform-origin:0 100%;-moz-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.reveal .slides section[data-transition=fade],.reveal.fade .slides section,.reveal.fade .slides>section>section{-webkit-transform:none;-moz-transform:none;-ms-transform:none;-o-transform:none;transform:none;-webkit-transition:opacity .5s;-moz-transition:opacity .5s;-ms-transition:opacity .5s;-o-transition:opacity .5s;transition:opacity .5s}.reveal.fade.overview .slides section,.reveal.fade.overview .slides>section>section,.reveal.fade.overview-deactivating .slides section,.reveal.fade.overview-deactivating .slides>section>section{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.reveal .slides section[data-transition=none],.reveal.none .slides section{-webkit-transform:none;-moz-transform:none;-ms-transform:none;-o-transform:none;transform:none;-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.reveal.overview .slides{-webkit-perspective-origin:0 0;-moz-perspective-origin:0 0;-ms-perspective-origin:0 0;perspective-origin:0 0;-webkit-perspective:700px;-moz-perspective:700px;-ms-perspective:700px;perspective:700px}.reveal.overview .slides section{height:600px;top:-300px!important;overflow:hidden;opacity:1!important;visibility:visible!important;cursor:pointer;background:rgba(0,0,0,.1)}.reveal.overview .slides section .fragment{opacity:1}.reveal.overview .slides section:after,.reveal.overview .slides section:before{display:none!important}.reveal.overview .slides section>section{opacity:1;cursor:pointer}.reveal.overview .slides section:hover{background:rgba(0,0,0,.3)}.reveal.overview .slides section.present{background:rgba(0,0,0,.3)}.reveal.overview .slides>section.stack{padding:0;top:0!important;background:0;overflow:visible}.reveal .pause-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#000;visibility:hidden;opacity:0;z-index:100;-webkit-transition:all 1s ease;-moz-transition:all 1s ease;-ms-transition:all 1s ease;-o-transition:all 1s ease;transition:all 1s ease}.reveal.paused .pause-overlay{visibility:visible;opacity:1}.no-transforms{overflow-y:auto}.no-transforms .reveal .slides{position:relative;width:80%;height:auto!important;top:0;left:50%;margin:0;text-align:center}.no-transforms .reveal .controls,.no-transforms .reveal .progress{display:none!important}.no-transforms .reveal .slides section{display:block!important;opacity:1!important;position:relative!important;height:auto;min-height:auto;top:0;left:-50%;margin:70px 0;-webkit-transform:none;-moz-transform:none;-ms-transform:none;-o-transform:none;transform:none}.no-transforms .reveal .slides section section{left:0}.reveal .no-transition,.reveal .no-transition *{-webkit-transition:none!important;-moz-transition:none!important;-ms-transition:none!important;-o-transition:none!important;transition:none!important}.reveal .state-background{position:absolute;width:100%;height:100%;background:rgba(0,0,0,0);-webkit-transition:background 800ms ease;-moz-transition:background 800ms ease;-ms-transition:background 800ms ease;-o-transition:background 800ms ease;transition:background 800ms ease}.alert .reveal .state-background{background:rgba(200,50,30,.6)}.soothe .reveal .state-background{background:rgba(50,200,90,.4)}.blackout .reveal .state-background{background:rgba(0,0,0,.6)}.whiteout .reveal .state-background{background:rgba(255,255,255,.6)}.cobalt .reveal .state-background{background:rgba(22,152,213,.6)}.mint .reveal .state-background{background:rgba(22,213,75,.6)}.submerge .reveal .state-background{background:rgba(12,25,77,.6)}.lila .reveal .state-background{background:rgba(180,50,140,.6)}.sunset .reveal .state-background{background:rgba(255,122,0,.6)}.reveal>.backgrounds{position:absolute;width:100%;height:100%;-webkit-perspective:600px;-moz-perspective:600px;-ms-perspective:600px;perspective:600px}.reveal .slide-background{position:absolute;width:100%;height:100%;opacity:0;visibility:hidden;background-color:rgba(0,0,0,0);background-position:50% 50%;background-repeat:no-repeat;background-size:cover;-webkit-transition:all 800ms cubic-bezier(0.26,.86,.44,.985);-moz-transition:all 800ms cubic-bezier(0.26,.86,.44,.985);-ms-transition:all 800ms cubic-bezier(0.26,.86,.44,.985);-o-transition:all 800ms cubic-bezier(0.26,.86,.44,.985);transition:all 800ms cubic-bezier(0.26,.86,.44,.985)}.reveal .slide-background.present{opacity:1;visibility:visible}.print-pdf .reveal .slide-background{opacity:1!important;visibility:visible!important}.reveal[data-background-transition=none]>.backgrounds .slide-background,.reveal>.backgrounds .slide-background[data-background-transition=none]{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.reveal[data-background-transition=slide]>.backgrounds .slide-background,.reveal>.backgrounds .slide-background[data-background-transition=slide]{opacity:1;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.reveal[data-background-transition=slide]>.backgrounds .slide-background.past,.reveal>.backgrounds .slide-background.past[data-background-transition=slide]{-webkit-transform:translate(-100%,0);-moz-transform:translate(-100%,0);-ms-transform:translate(-100%,0);-o-transform:translate(-100%,0);transform:translate(-100%,0)}.reveal[data-background-transition=slide]>.backgrounds .slide-background.future,.reveal>.backgrounds .slide-background.future[data-background-transition=slide]{-webkit-transform:translate(100%,0);-moz-transform:translate(100%,0);-ms-transform:translate(100%,0);-o-transform:translate(100%,0);transform:translate(100%,0)}.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past,.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide]{-webkit-transform:translate(0,-100%);-moz-transform:translate(0,-100%);-ms-transform:translate(0,-100%);-o-transform:translate(0,-100%);transform:translate(0,-100%)}.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future,.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide]{-webkit-transform:translate(0,100%);-moz-transform:translate(0,100%);-ms-transform:translate(0,100%);-o-transform:translate(0,100%);transform:translate(0,100%)}.reveal[data-background-transition=convex]>.backgrounds .slide-background.past,.reveal>.backgrounds .slide-background.past[data-background-transition=convex]{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);-moz-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0);transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal[data-background-transition=convex]>.backgrounds .slide-background.future,.reveal>.backgrounds .slide-background.future[data-background-transition=convex]{opacity:0;-webkit-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);-moz-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0);transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past,.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex]{opacity:0;-webkit-transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0);-moz-transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0);transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0)}.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future,.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex]{opacity:0;-webkit-transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0);-moz-transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0);transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0)}.reveal[data-background-transition=concave]>.backgrounds .slide-background.past,.reveal>.backgrounds .slide-background.past[data-background-transition=concave]{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);-moz-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0);transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0)}.reveal[data-background-transition=concave]>.backgrounds .slide-background.future,.reveal>.backgrounds .slide-background.future[data-background-transition=concave]{opacity:0;-webkit-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);-moz-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0);transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0)}.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past,.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave]{opacity:0;-webkit-transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0);-moz-transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0);transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0)}.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future,.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave]{opacity:0;-webkit-transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0);-moz-transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0);transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0)}.reveal[data-background-transition=zoom]>.backgrounds .slide-background,.reveal>.backgrounds .slide-background[data-background-transition=zoom]{-webkit-transition-timing-function:ease;-moz-transition-timing-function:ease;-ms-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past,.reveal>.backgrounds .slide-background.past[data-background-transition=zoom]{opacity:0;visibility:hidden;-webkit-transform:scale(16);-moz-transform:scale(16);-ms-transform:scale(16);-o-transform:scale(16);transform:scale(16)}.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future,.reveal>.backgrounds .slide-background.future[data-background-transition=zoom]{opacity:0;visibility:hidden;-webkit-transform:scale(0.2);-moz-transform:scale(0.2);-ms-transform:scale(0.2);-o-transform:scale(0.2);transform:scale(0.2)}.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past,.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom]{opacity:0;visibility:hidden;-webkit-transform:scale(16);-moz-transform:scale(16);-ms-transform:scale(16);-o-transform:scale(16);transform:scale(16)}.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future,.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom]{opacity:0;visibility:hidden;-webkit-transform:scale(0.2);-moz-transform:scale(0.2);-ms-transform:scale(0.2);-o-transform:scale(0.2);transform:scale(0.2)}.reveal[data-transition-speed=fast]>.backgrounds .slide-background{-webkit-transition-duration:400ms;-moz-transition-duration:400ms;-ms-transition-duration:400ms;transition-duration:400ms}.reveal[data-transition-speed=slow]>.backgrounds .slide-background{-webkit-transition-duration:1200ms;-moz-transition-duration:1200ms;-ms-transition-duration:1200ms;transition-duration:1200ms}.reveal.rtl .slides,.reveal.rtl .slides h1,.reveal.rtl .slides h2,.reveal.rtl .slides h3,.reveal.rtl .slides h4,.reveal.rtl .slides h5,.reveal.rtl .slides h6{direction:rtl;font-family:sans-serif}.reveal.rtl pre,.reveal.rtl code{direction:ltr}.reveal.rtl ol,.reveal.rtl ul{text-align:right}.reveal.rtl .progress span{float:right}.reveal.has-parallax-background .backgrounds{-webkit-transition:all .8s ease;-moz-transition:all .8s ease;-ms-transition:all .8s ease;transition:all .8s ease}.reveal.has-parallax-background[data-transition-speed=fast] .backgrounds{-webkit-transition-duration:400ms;-moz-transition-duration:400ms;-ms-transition-duration:400ms;transition-duration:400ms}.reveal.has-parallax-background[data-transition-speed=slow] .backgrounds{-webkit-transition-duration:1200ms;-moz-transition-duration:1200ms;-ms-transition-duration:1200ms;transition-duration:1200ms}.reveal .preview-link-overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1000;background:rgba(0,0,0,.9);opacity:0;visibility:hidden;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;transition:all .3s ease}.reveal .preview-link-overlay.visible{opacity:1;visibility:visible}.reveal .preview-link-overlay .spinner{position:absolute;display:block;top:50%;left:50%;width:32px;height:32px;margin:-16px 0 0 -16px;z-index:10;background-image:url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D);visibility:visible;opacity:.6;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;transition:all .3s ease}.reveal .preview-link-overlay header{position:absolute;left:0;top:0;width:100%;height:40px;z-index:2;border-bottom:1px solid #222}.reveal .preview-link-overlay header a{display:inline-block;width:40px;height:40px;padding:0 10px;float:right;opacity:.6;box-sizing:border-box}.reveal .preview-link-overlay header a:hover{opacity:1}.reveal .preview-link-overlay header a .icon{display:inline-block;width:20px;height:20px;background-position:50% 50%;background-size:100%;background-repeat:no-repeat}.reveal .preview-link-overlay header a.close .icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC)}.reveal .preview-link-overlay header a.external .icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==)}.reveal .preview-link-overlay .viewport{position:absolute;top:40px;right:0;bottom:0;left:0}.reveal .preview-link-overlay .viewport iframe{width:100%;height:100%;max-width:100%;max-height:100%;border:0;opacity:0;visibility:hidden;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;transition:all .3s ease}.reveal .preview-link-overlay.loaded .viewport iframe{opacity:1;visibility:visible}.reveal .preview-link-overlay.loaded .spinner{opacity:0;visibility:hidden;-webkit-transform:scale(0.2);-moz-transform:scale(0.2);-ms-transform:scale(0.2);transform:scale(0.2)}.reveal .playback{position:fixed;left:15px;bottom:15px;z-index:30;cursor:pointer;-webkit-transition:all 400ms ease;-moz-transition:all 400ms ease;-ms-transition:all 400ms ease;transition:all 400ms ease}.reveal.overview .playback{opacity:0;visibility:hidden}.reveal .roll{display:inline-block;line-height:1.2;overflow:hidden;vertical-align:top;-webkit-perspective:400px;-moz-perspective:400px;-ms-perspective:400px;perspective:400px;-webkit-perspective-origin:50% 50%;-moz-perspective-origin:50% 50%;-ms-perspective-origin:50% 50%;perspective-origin:50% 50%}.reveal .roll:hover{background:0;text-shadow:none}.reveal .roll span{display:block;position:relative;padding:0 2px;pointer-events:none;-webkit-transition:all 400ms ease;-moz-transition:all 400ms ease;-ms-transition:all 400ms ease;transition:all 400ms ease;-webkit-transform-origin:50% 0;-moz-transform-origin:50% 0;-ms-transform-origin:50% 0;transform-origin:50% 0;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden}.reveal .roll:hover span{background:rgba(0,0,0,.5);-webkit-transform:translate3d(0px,0,-45px) rotateX(90deg);-moz-transform:translate3d(0px,0,-45px) rotateX(90deg);-ms-transform:translate3d(0px,0,-45px) rotateX(90deg);transform:translate3d(0px,0,-45px) rotateX(90deg)}.reveal .roll span:after{content:attr(data-title);display:block;position:absolute;left:0;top:0;padding:0 2px;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:50% 0;-moz-transform-origin:50% 0;-ms-transform-origin:50% 0;transform-origin:50% 0;-webkit-transform:translate3d(0px,110%,0) rotateX(-90deg);-moz-transform:translate3d(0px,110%,0) rotateX(-90deg);-ms-transform:translate3d(0px,110%,0) rotateX(-90deg);transform:translate3d(0px,110%,0) rotateX(-90deg)}.reveal aside.notes{display:none}.zoomed .reveal *,.zoomed .reveal :before,.zoomed .reveal :after{-webkit-transform:none!important;-moz-transform:none!important;-ms-transform:none!important;transform:none!important;-webkit-backface-visibility:visible!important;-moz-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important}.zoomed .reveal .progress,.zoomed .reveal .controls{opacity:0}.zoomed .reveal .roll span{background:0}.zoomed .reveal .roll span:after{visibility:hidden}
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/README.md b/docs/slides/IHP14/_support/reveal.js/css/theme/README.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/README.md
@@ -0,0 +1,25 @@
+## Dependencies
+
+Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceding: https://github.com/hakimel/reveal.js#full-setup
+
+You also need to install Ruby and then Sass (with `gem install sass`).
+
+## Creating a Theme
+
+To create your own theme, start by duplicating any ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source) and adding it to the compilation list in the [Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js).
+
+Each theme file does four things in the following order:
+
+1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)**
+Shared utility functions.
+
+2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)**
+Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3.
+
+3. **Override**
+This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding full selectors with hardcoded styles.
+
+4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)**
+The template theme file which will generate final CSS output based on the currently defined variables.
+
+When you are done, run `grunt themes` to compile the Sass file to CSS and you are ready to use your new theme.
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/beige.css b/docs/slides/IHP14/_support/reveal.js/css/theme/beige.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/beige.css
@@ -0,0 +1,148 @@
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Beige theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f7f2d3;
+  background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
+  background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background-color: #f7f3de; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #333333; }
+
+::selection {
+  color: white;
+  background: rgba(79, 64, 28, 0.99);
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #333333;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #8b743d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #c0a86e;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #564826; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #333333;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #8b743d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #8b743d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #8b743d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #8b743d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #8b743d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #c0a86e; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #c0a86e; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #c0a86e; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #c0a86e; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #8b743d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #8b743d; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/blood.css b/docs/slides/IHP14/_support/reveal.js/css/theme/blood.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/blood.css
@@ -0,0 +1,175 @@
+@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
+/**
+ * Blood theme for reveal.js
+ * Author: Walther http://github.com/Walther
+ *
+ * Designed to be used with highlight.js theme
+ * "monokai_sublime.css" available from
+ * https://github.com/isagalaev/highlight.js/
+ *
+ * For other themes, change $codeBackground accordingly.
+ *
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #222222;
+  background: -moz-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #626262), color-stop(100%, #222222));
+  background: -webkit-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background: -o-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background: -ms-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background: radial-gradient(center, circle cover, #626262 0%, #222222 100%);
+  background-color: #2b2b2b; }
+
+.reveal {
+  font-family: Ubuntu, "sans-serif";
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #eeeeee; }
+
+::selection {
+  color: white;
+  background: #aa2233;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eeeeee;
+  font-family: Ubuntu, "sans-serif";
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: 2px 2px 2px #222222; }
+
+.reveal h1 {
+  text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #aa2233;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #dd5566;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #6a1520; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #eeeeee;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #aa2233;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #aa2233; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #aa2233; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #aa2233; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #aa2233; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #dd5566; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #dd5566; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #dd5566; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #dd5566; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #aa2233;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #aa2233; }
+
+.reveal p {
+  font-weight: 300;
+  text-shadow: 1px 1px #222222; }
+
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  font-weight: 700; }
+
+.reveal a:not(.image),
+.reveal a:not(.image):hover {
+  text-shadow: 2px 2px 2px #000; }
+
+.reveal small a:not(.image),
+.reveal small a:not(.image):hover {
+  text-shadow: 1px 1px 1px #000; }
+
+.reveal p code {
+  background-color: #23241f;
+  display: inline-block;
+  border-radius: 7px; }
+
+.reveal small code {
+  vertical-align: baseline; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/default.css b/docs/slides/IHP14/_support/reveal.js/css/theme/default.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/default.css
@@ -0,0 +1,148 @@
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Default theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #1c1e20;
+  background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
+  background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background-color: #2b2b2b; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #eeeeee; }
+
+::selection {
+  color: white;
+  background: #ff5e99;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eeeeee;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+.reveal h1 {
+  text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #13daec;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #71e9f4;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #0d99a5; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #eeeeee;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #13daec;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #13daec; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #13daec; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #13daec; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #13daec; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #71e9f4; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #71e9f4; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #71e9f4; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #71e9f4; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #13daec;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #13daec; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/moon.css b/docs/slides/IHP14/_support/reveal.js/css/theme/moon.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/moon.css
@@ -0,0 +1,148 @@
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Solarized Dark theme for reveal.js.
+ * Author: Achim Staebler
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal; }
+
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+  color-profile: sRGB;
+  rendering-intent: auto; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #002b36;
+  background-color: #002b36; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #93a1a1; }
+
+::selection {
+  color: white;
+  background: #d33682;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eee8d5;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #268bd2;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #78b9e6;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #1a6091; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #93a1a1;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #268bd2;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #268bd2; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #268bd2; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #268bd2; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #268bd2; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #78b9e6; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #78b9e6; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #78b9e6; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #78b9e6; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #268bd2;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #268bd2; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/night.css b/docs/slides/IHP14/_support/reveal.js/css/theme/night.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/night.css
@@ -0,0 +1,136 @@
+@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
+/**
+ * Black theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #111111;
+  background-color: #111111; }
+
+.reveal {
+  font-family: "Open Sans", sans-serif;
+  font-size: 30px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #eeeeee; }
+
+::selection {
+  color: white;
+  background: #e7ad52;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eeeeee;
+  font-family: "Montserrat", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: -0.03em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #e7ad52;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #f3d7ac;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #d08a1d; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #eeeeee;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #e7ad52;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #e7ad52; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #e7ad52; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #e7ad52; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #e7ad52; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #f3d7ac; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #f3d7ac; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #f3d7ac; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #f3d7ac; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #e7ad52;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #e7ad52; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/seminar.css b/docs/slides/IHP14/_support/reveal.js/css/theme/seminar.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/seminar.css
@@ -0,0 +1,200 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb; }
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+.reveal a {
+  color: #8b7c69;
+  text-decoration: none;
+}
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 40px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	// :color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.05em 0.05em 0.25em blue;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+/*
+.reveal a:not(.image) {
+  line-height: 1.3em; }
+
+
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c; }
+
+*/
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #51483d; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/seminar.orig.css b/docs/slides/IHP14/_support/reveal.js/css/theme/seminar.orig.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/seminar.orig.css
@@ -0,0 +1,301 @@
+/**
+ * The default theme for reveal.js presentations.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.ttf') format('truetype');
+	font-weight: normal;
+	font-style: normal;
+}
+
+@font-face {
+		font-family: 'PTSansNarrow';
+        src: url('../../lib/font/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+@font-face {
+		font-family: 'OpenSans';
+        src: url('../../lib/font/OpenSans-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'OpenSans', Times, 'Times New Roman', serif;
+	font-size: 36;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #eee;
+
+	background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM1NTVhNWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMWMxZTIwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+	background-color: #2b2b2b;
+	background: -moz-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%, rgba(28,30,32,1) 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(85,90,95,1)), color-stop(100%,rgba(28,30,32,1)));
+	background: -webkit-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -o-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+}
+
+
+/*********************************************
+ * main.css OVERIDES
+ *********************************************/
+
+
+/*--DW-- uncomment below to undo globally centered text from main.css*/
+
+/*.reveal .slides {
+	text-align: left;
+}
+
+.reveal li {
+	padding-bottom: 0.7em;
+	line-height: 1em;
+}
+.reveal ul ul {
+	padding-left: 8%;
+	padding-top: 0.7em;
+	font-size: 85%;
+}*/
+
+/*--DW--
+* override list width to make multiline list items
+* a bit more manageable
+*/
+.reveal ul {
+	max-width: 80%;
+}
+
+.reveal li {
+	padding-bottom: 0.3em;
+}
+
+/*--DW-- uncenter pararagraph blocks*/
+.reveal .slides p {
+	text-align: left
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2 {
+	margin: 0 0 20px 0;
+	color: #eee;
+	font-family: 'League Gothic', Impact, sans-serif;
+	line-height: 0.9em;
+	letter-spacing: 0.02em;
+	
+	text-align: center;
+	text-transform: uppercase;
+	text-shadow: 0px 1px 0px rgba(0,0,0,1);
+}
+
+.reveal h2 {
+	font-family: 'PTSansNarrow';
+	font-size: 130%;
+}
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+
+
+/*********************************************
+ * BLOCKQUOTES
+ *********************************************/
+
+/*--DW--*/
+.reveal blockquote
+{   background: rgba(255,255,255, .2);
+    font-size: 75%;
+    text-align: justify;
+    width: 70%;
+    padding: 0.5em 5% 0.2em;
+    margin: 0 10%;
+    border: 2px solid rgba(255, 255, 255, .1);
+    -webkit-box-shadow: .1em .1em .5em black inset;
+    -moz-box-shadow: .1em .1em .5em black inset;
+    box-shadow: .1em .1em .5em black inset;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: hsl(185, 85%, 50%);
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+.reveal a:not(.image):hover {
+	color: hsl(185, 85%, 70%);
+	
+	text-shadow: none;
+	border: none;
+	border-radius: 2px;
+}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: hsl(185, 60%, 35%);
+}
+
+
+/*********************************************
+ * IMAGES AND FIGURES
+ *********************************************/
+
+/*--DW-- added figures; changed img styling*/
+/*pandoc*/
+.reveal figure {
+	margin-left: auto;
+	margin-right: auto;
+}
+
+/*pandoc*/
+.reveal figcaption {
+	text-align: center;
+	font-size: 75%;
+	font-style: italic;
+}
+.reveal section img,
+.reveal section embed {
+/*	width: 80%;
+	height: 80%;
+*/	display: block;
+	margin-left: auto;
+	margin-right: auto;
+	padding: 15px;
+	background: rgba(255,255,255, .75);
+    border: 2px solid rgba(255, 255, 255, .1);
+    -webkit-box-shadow: .1em .1em .5em black inset;
+       -moz-box-shadow: .1em .1em .5em black inset;
+            box-shadow: .1em .1em .5em black inset;
+
+/*--DW-- original image box styling*/
+/*
+-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+
+-webkit-transition: all .2s linear;
+   -moz-transition: all .2s linear;
+    -ms-transition: all .2s linear;
+     -o-transition: all .2s linear;
+        transition: all .2s linear;
+*/
+}
+
+.reveal a:hover img {
+	background: rgba(255,255,255,0.2);
+	border-color: #13DAEC;
+	
+	-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		/*color: hsl(185, 85%, 70%);*/
+		color: rgba(138, 201, 85, 0.60);
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		/*background: hsl(185, 85%, 50%);*/
+		background: rgba(138, 201, 85, 0.60);
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/serif.css b/docs/slides/IHP14/_support/reveal.js/css/theme/serif.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/serif.css
@@ -0,0 +1,138 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+.reveal a:not(.image) {
+  line-height: 1.3em; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb; }
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #51483d; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/simple.css b/docs/slides/IHP14/_support/reveal.js/css/theme/simple.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/simple.css
@@ -0,0 +1,138 @@
+@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is darkblue.
+ *
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: white;
+  background-color: white; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+::selection {
+  color: white;
+  background: rgba(0, 0, 0, 0.99);
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: black;
+  font-family: "News Cycle", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: darkblue;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #0000f1;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #00003f; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: darkblue;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: darkblue; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: darkblue; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: darkblue; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: darkblue; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #0000f1; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #0000f1; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #0000f1; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #0000f1; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: darkblue;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: darkblue; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/sky.css b/docs/slides/IHP14/_support/reveal.js/css/theme/sky.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/sky.css
@@ -0,0 +1,145 @@
+@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+/**
+ * Sky theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+.reveal a:not(.image) {
+  line-height: 1.3em; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #add9e4;
+  background: -moz-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #f7fbfc), color-stop(100%, #add9e4));
+  background: -webkit-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -o-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -ms-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background-color: #f7fbfc; }
+
+.reveal {
+  font-family: "Open Sans", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #333333; }
+
+::selection {
+  color: white;
+  background: #134674;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #333333;
+  font-family: "Quicksand", sans-serif;
+  line-height: 0.9em;
+  letter-spacing: -0.08em;
+  text-transform: uppercase;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #3b759e;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #74a7cb;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #264c66; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #333333;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #3b759e;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #3b759e; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #3b759e; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #3b759e; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #3b759e; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #74a7cb; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #74a7cb; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #74a7cb; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #74a7cb; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #3b759e;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #3b759e; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/solarized.css b/docs/slides/IHP14/_support/reveal.js/css/theme/solarized.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/solarized.css
@@ -0,0 +1,148 @@
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Solarized Light theme for reveal.js.
+ * Author: Achim Staebler
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal; }
+
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+  color-profile: sRGB;
+  rendering-intent: auto; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #fdf6e3;
+  background-color: #fdf6e3; }
+
+.reveal {
+  font-family: "Lato", sans-serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: #657b83; }
+
+::selection {
+  color: white;
+  background: #d33682;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #586e75;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #268bd2;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #78b9e6;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #1a6091; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #657b83;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #268bd2;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #268bd2; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #268bd2; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #268bd2; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #268bd2; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #78b9e6; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #78b9e6; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #78b9e6; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #78b9e6; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #268bd2;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #268bd2; }
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/beige.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/beige.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/beige.scss
@@ -0,0 +1,50 @@
+/**
+ * Beige theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainColor: #333;
+$headingColor: #333;
+$headingTextShadow: none;
+$backgroundColor: #f7f3de;
+$linkColor: #8b743d;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
+$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/blood.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/blood.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/blood.scss
@@ -0,0 +1,91 @@
+/**
+ * Blood theme for reveal.js
+ * Author: Walther http://github.com/Walther
+ *
+ * Designed to be used with highlight.js theme
+ * "monokai_sublime.css" available from
+ * https://github.com/isagalaev/highlight.js/
+ *
+ * For other themes, change $codeBackground accordingly.
+ *
+ */
+
+ // Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+// Include theme-specific fonts
+
+@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
+
+// Colors used in the theme
+$blood: #a23;
+$coal: #222;
+$codeBackground: #23241f;
+
+// Main text
+$mainFont: Ubuntu, 'sans-serif';
+$mainFontSize: 36px;
+$mainColor: #eee;
+
+// Headings
+$headingFont: Ubuntu, 'sans-serif';
+$headingTextShadow: 2px 2px 2px $coal;
+
+// h1 shadow, borrowed humbly from 
+// (c) Default theme by Hakim El Hattab
+$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
+
+// Links
+$linkColor: $blood;
+$linkColorHover: lighten( $linkColor, 20% );
+
+// Text selection
+$selectionBackgroundColor: $blood;
+$selectionColor: #fff;
+
+// Background generator
+@mixin bodyBackground() {
+    @include radial-gradient( $coal, lighten( $coal, 25% ) );
+}
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
+
+// some overrides after theme template import
+
+.reveal p {
+    font-weight: 300;
+    text-shadow: 1px 1px $coal;
+}
+
+.reveal h1, 
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+    font-weight: 700;
+}
+
+.reveal a:not(.image),
+.reveal a:not(.image):hover {
+    text-shadow: 2px 2px 2px #000;
+}
+
+.reveal small a:not(.image),
+.reveal small a:not(.image):hover {
+    text-shadow: 1px 1px 1px #000;
+}
+
+.reveal p code {
+    background-color: $codeBackground;
+    display: inline-block;
+    border-radius: 7px;
+}
+
+.reveal small code {
+    vertical-align: baseline;
+}
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/default.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/default.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/default.scss
@@ -0,0 +1,42 @@
+/**
+ * Default theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+// Override theme settings (see ../template/settings.scss)
+$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/moon.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/moon.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/moon.scss
@@ -0,0 +1,68 @@
+/**
+ * Solarized Dark theme for reveal.js.
+ * Author: Achim Staebler
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+	color-profile: sRGB;
+	rendering-intent: auto;
+}
+
+// Solarized colors
+$base03:    #002b36;
+$base02:    #073642;
+$base01:    #586e75;
+$base00:    #657b83;
+$base0:     #839496;
+$base1:     #93a1a1;
+$base2:     #eee8d5;
+$base3:     #fdf6e3;
+$yellow:    #b58900;
+$orange:    #cb4b16;
+$red:       #dc322f;
+$magenta:   #d33682;
+$violet:    #6c71c4;
+$blue:      #268bd2;
+$cyan:      #2aa198;
+$green:     #859900;
+
+// Override theme settings (see ../template/settings.scss)
+$mainColor: $base1;
+$headingColor: $base2;
+$headingTextShadow: none;
+$backgroundColor: $base03;
+$linkColor: $blue;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: $magenta;
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/night.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/night.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/night.scss
@@ -0,0 +1,35 @@
+/**
+ * Black theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+// Include theme-specific fonts
+@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$backgroundColor: #111;
+
+$mainFont: 'Open Sans', sans-serif;
+$linkColor: #e7ad52;
+$linkColorHover: lighten( $linkColor, 20% );
+$headingFont: 'Montserrat', Impact, sans-serif;
+$headingTextShadow: none;
+$headingLetterSpacing: -0.03em;
+$headingTextTransform: none;
+$selectionBackgroundColor: #e7ad52;
+$mainFontSize: 30px;
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/serif.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/serif.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/serif.scss
@@ -0,0 +1,35 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+$mainColor: #000;
+$headingFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+$headingColor: #383D3D;
+$headingTextShadow: none;
+$headingTextTransform: none;
+$backgroundColor: #F0F1EB;
+$linkColor: #51483D;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: #26351C;
+
+.reveal a:not(.image) {
+  line-height: 1.3em;
+}
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/simple.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/simple.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/simple.scss
@@ -0,0 +1,38 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is darkblue.
+ *
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Lato', sans-serif;
+$mainColor: #000;
+$headingFont: 'News Cycle', Impact, sans-serif;
+$headingColor: #000;
+$headingTextShadow: none;
+$headingTextTransform: none;
+$backgroundColor: #fff;
+$linkColor: #00008B;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/sky.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/sky.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/sky.scss
@@ -0,0 +1,46 @@
+/**
+ * Sky theme for reveal.js.
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Open Sans', sans-serif;
+$mainColor: #333;
+$headingFont: 'Quicksand', sans-serif;
+$headingColor: #333;
+$headingLetterSpacing: -0.08em;
+$headingTextShadow: none;
+$backgroundColor: #f7fbfc;
+$linkColor: #3b759e;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: #134674;
+
+// Fix links so they are not cut off
+.reveal a:not(.image) {
+	line-height: 1.3em;
+}
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( #add9e4, #f7fbfc );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/source/solarized.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/source/solarized.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/source/solarized.scss
@@ -0,0 +1,74 @@
+/**
+ * Solarized Light theme for reveal.js.
+ * Author: Achim Staebler
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+
+/**
+ * Solarized colors by Ethan Schoonover
+ */
+html * {
+	color-profile: sRGB;
+	rendering-intent: auto;
+}
+
+// Solarized colors
+$base03:    #002b36;
+$base02:    #073642;
+$base01:    #586e75;
+$base00:    #657b83;
+$base0:     #839496;
+$base1:     #93a1a1;
+$base2:     #eee8d5;
+$base3:     #fdf6e3;
+$yellow:    #b58900;
+$orange:    #cb4b16;
+$red:       #dc322f;
+$magenta:   #d33682;
+$violet:    #6c71c4;
+$blue:      #268bd2;
+$cyan:      #2aa198;
+$green:     #859900;
+
+// Override theme settings (see ../template/settings.scss)
+$mainColor: $base00;
+$headingColor: $base01;
+$headingTextShadow: none;
+$backgroundColor: $base3;
+$linkColor: $blue;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: $magenta;
+
+// Background generator
+// @mixin bodyBackground() {
+// 	@include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
+// }
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/template/mixins.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/template/mixins.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/template/mixins.scss
@@ -0,0 +1,29 @@
+@mixin vertical-gradient( $top, $bottom ) {
+	background: $top;
+	background: -moz-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -webkit-gradient( linear, left top, left bottom, color-stop(0%,$top), color-stop(100%,$bottom) );
+	background: -webkit-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -o-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -ms-linear-gradient( top, $top 0%, $bottom 100% );
+	background: linear-gradient( top, $top 0%, $bottom 100% );
+}
+
+@mixin horizontal-gradient( $top, $bottom ) {
+	background: $top;
+	background: -moz-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -webkit-gradient( linear, left top, right top, color-stop(0%,$top), color-stop(100%,$bottom) );
+	background: -webkit-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -o-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -ms-linear-gradient( left, $top 0%, $bottom 100% );
+	background: linear-gradient( left, $top 0%, $bottom 100% );
+}
+
+@mixin radial-gradient( $outer, $inner, $type: circle ) {
+	background: $outer;
+	background: -moz-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -webkit-gradient( radial, center center, 0px, center center, 100%, color-stop(0%,$inner), color-stop(100%,$outer) );
+	background: -webkit-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -o-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -ms-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+}
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/template/settings.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/template/settings.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/template/settings.scss
@@ -0,0 +1,34 @@
+// Base settings for all themes that can optionally be
+// overridden by the super-theme
+
+// Background of the presentation
+$backgroundColor: #2b2b2b;
+
+// Primary/body text
+$mainFont: 'Lato', sans-serif;
+$mainFontSize: 36px;
+$mainColor: #eee;
+
+// Headings
+$headingMargin: 0 0 20px 0;
+$headingFont: 'League Gothic', Impact, sans-serif;
+$headingColor: #eee;
+$headingLineHeight: 0.9em;
+$headingLetterSpacing: 0.02em;
+$headingTextTransform: uppercase;
+$headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2);
+$heading1TextShadow: $headingTextShadow;
+
+// Links and actions
+$linkColor: #13DAEC;
+$linkColorHover: lighten( $linkColor, 20% );
+
+// Text selection
+$selectionBackgroundColor: #FF5E99;
+$selectionColor: #fff;
+
+// Generates the presentation background, can be overridden
+// to return a background image or gradient
+@mixin bodyBackground() {
+	background: $backgroundColor;
+}
diff --git a/docs/slides/IHP14/_support/reveal.js/css/theme/template/theme.scss b/docs/slides/IHP14/_support/reveal.js/css/theme/template/theme.scss
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/css/theme/template/theme.scss
@@ -0,0 +1,170 @@
+// Base theme template for reveal.js
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	@include bodyBackground();
+	background-color: $backgroundColor;
+}
+
+.reveal {
+	font-family: $mainFont;
+	font-size: $mainFontSize;
+	font-weight: normal;
+	letter-spacing: -0.02em;
+	color: $mainColor;
+}
+
+::selection {
+	color: $selectionColor;
+	background: $selectionBackgroundColor;
+	text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+	margin: $headingMargin;
+	color: $headingColor;
+
+	font-family: $headingFont;
+	line-height: $headingLineHeight;
+	letter-spacing: $headingLetterSpacing;
+
+	text-transform: $headingTextTransform;
+	text-shadow: $headingTextShadow;
+}
+
+.reveal h1 {
+	text-shadow: $heading1TextShadow;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: $linkColor;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		color: $linkColorHover;
+
+		text-shadow: none;
+		border: none;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: darken( $linkColor, 15% );
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 15px 0px;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid $mainColor;
+
+	box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: $linkColor;
+
+		box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+	border-right-color: $linkColor;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+	border-left-color: $linkColor;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+	border-bottom-color: $linkColor;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+	border-top-color: $linkColor;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+	border-right-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+	border-left-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+	border-bottom-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+	border-top-color: $linkColorHover;
+}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: $linkColor;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: $linkColor;
+}
+
+
diff --git a/docs/slides/IHP14/_support/reveal.js/index.html b/docs/slides/IHP14/_support/reveal.js/index.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/index.html
@@ -0,0 +1,394 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - The HTML Presentation Framework</title>
+
+		<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
+		<meta name="author" content="Hakim El Hattab">
+
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="css/reveal.min.css">
+		<link rel="stylesheet" href="css/theme/default.css" id="theme">
+
+		<!-- For syntax highlighting -->
+		<link rel="stylesheet" href="lib/css/zenburn.css">
+
+		<!-- If the query includes 'print-pdf', include the PDF print sheet -->
+		<script>
+			if( window.location.search.match( /print-pdf/gi ) ) {
+				var link = document.createElement( 'link' );
+				link.rel = 'stylesheet';
+				link.type = 'text/css';
+				link.href = 'css/print/pdf.css';
+				document.getElementsByTagName( 'head' )[0].appendChild( link );
+			}
+		</script>
+
+		<!--[if lt IE 9]>
+		<script src="lib/js/html5shiv.js"></script>
+		<![endif]-->
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<!-- Any section element inside of this container is displayed as a slide -->
+			<div class="slides">
+				<section>
+					<h1>Reveal.js</h1>
+					<h3>HTML Presentations Made Easy</h3>
+					<p>
+						<small>Created by <a href="http://hakim.se">Hakim El Hattab</a> / <a href="http://twitter.com/hakimel">@hakimel</a></small>
+					</p>
+				</section>
+
+				<section>
+					<h2>Heads Up</h2>
+					<p>
+						reveal.js is a framework for easily creating beautiful presentations using HTML. You'll need a browser with
+						support for CSS 3D transforms to see it in its full glory.
+					</p>
+
+					<aside class="notes">
+						Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
+					</aside>
+				</section>
+
+				<!-- Example of nested vertical slides -->
+				<section>
+					<section>
+						<h2>Vertical Slides</h2>
+						<p>
+							Slides can be nested inside of other slides,
+							try pressing <a href="#" class="navigate-down">down</a>.
+						</p>
+						<a href="#" class="image navigate-down">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
+						</a>
+					</section>
+					<section>
+						<h2>Basement Level 1</h2>
+						<p>Press down or up to navigate.</p>
+					</section>
+					<section>
+						<h2>Basement Level 2</h2>
+						<p>Cornify</p>
+						<a class="test" href="http://cornify.com">
+							<img width="280" height="326" src="https://s3.amazonaws.com/hakim-static/reveal-js/cornify.gif" alt="Unicorn">
+						</a>
+					</section>
+					<section>
+						<h2>Basement Level 3</h2>
+						<p>That's it, time to go back up.</p>
+						<a href="#/2" class="image">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="-webkit-transform: rotate(180deg);">
+						</a>
+					</section>
+				</section>
+
+				<section>
+					<h2>Slides</h2>
+					<p>
+						Not a coder? No problem. There's a fully-featured visual editor for authoring these, try it out at <a href="http://slid.es" target="_blank">http://slid.es</a>.
+					</p>
+				</section>
+
+				<section>
+					<h2>Point of View</h2>
+					<p>
+						Press <strong>ESC</strong> to enter the slide overview.
+					</p>
+					<p>
+						Hold down alt and click on any element to zoom in on it using <a href="http://lab.hakim.se/zoom-js">zoom.js</a>. Alt + click anywhere to zoom back out.
+					</p>
+				</section>
+
+				<section>
+					<h2>Works in Mobile Safari</h2>
+					<p>
+						Try it out! You can swipe through the slides and pinch your way to the overview.
+					</p>
+				</section>
+
+				<section>
+					<h2>Marvelous Unordered List</h2>
+					<ul>
+						<li>No order here</li>
+						<li>Or here</li>
+						<li>Or here</li>
+						<li>Or here</li>
+					</ul>
+				</section>
+
+				<section>
+					<h2>Fantastic Ordered List</h2>
+					<ol>
+						<li>One is smaller than...</li>
+						<li>Two is smaller than...</li>
+						<li>Three!</li>
+					</ol>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						## Markdown support
+
+						For those of you who like that sort of thing. Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
+
+						```
+						<section data-markdown>
+						  ## Markdown support
+
+						  For those of you who like that sort of thing.
+						  Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
+						</section>
+						```
+					</script>
+				</section>
+
+				<section id="transitions">
+					<h2>Transition Styles</h2>
+					<p>
+						You can select from different transitions, like: <br>
+						<a href="?transition=cube#/transitions">Cube</a> -
+						<a href="?transition=page#/transitions">Page</a> -
+						<a href="?transition=concave#/transitions">Concave</a> -
+						<a href="?transition=zoom#/transitions">Zoom</a> -
+						<a href="?transition=linear#/transitions">Linear</a> -
+						<a href="?transition=fade#/transitions">Fade</a> -
+						<a href="?transition=none#/transitions">None</a> -
+						<a href="?#/transitions">Default</a>
+					</p>
+				</section>
+
+				<section id="themes">
+					<h2>Themes</h2>
+					<p>
+						Reveal.js comes with a few themes built in: <br>
+						<a href="?#/themes">Default</a> -
+						<a href="?theme=sky#/themes">Sky</a> -
+						<a href="?theme=beige#/themes">Beige</a> -
+						<a href="?theme=simple#/themes">Simple</a> -
+						<a href="?theme=serif#/themes">Serif</a> -
+						<a href="?theme=night#/themes">Night</a> <br>
+						<a href="?theme=moon#/themes">Moon</a> -
+						<a href="?theme=solarized#/themes">Solarized</a>
+					</p>
+					<p>
+						<small>
+							* Theme demos are loaded after the presentation which leads to flicker. In production you should load your theme in the <code>&lt;head&gt;</code> using a <code>&lt;link&gt;</code>.
+						</small>
+					</p>
+				</section>
+
+				<section>
+					<h2>Global State</h2>
+					<p>
+						Set <code>data-state="something"</code> on a slide and <code>"something"</code>
+						will be added as a class to the document element when the slide is open. This lets you
+						apply broader style changes, like switching the background.
+					</p>
+				</section>
+
+				<section data-state="customevent">
+					<h2>Custom Events</h2>
+					<p>
+						Additionally custom events can be triggered on a per slide basis by binding to the <code>data-state</code> name.
+					</p>
+					<pre><code data-trim contenteditable style="font-size: 18px; margin-top: 20px;">
+Reveal.addEventListener( 'customevent', function() {
+	console.log( '"customevent" has fired' );
+} );
+					</code></pre>
+				</section>
+
+				<section>
+					<section data-background="#007777">
+						<h2>Slide Backgrounds</h2>
+						<p>
+							Set <code>data-background="#007777"</code> on a slide to change the full page background to the given color. All CSS color formats are supported.
+						</p>
+						<a href="#" class="image navigate-down">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
+						</a>
+					</section>
+					<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png">
+						<h2>Image Backgrounds</h2>
+						<pre><code>&lt;section data-background="image.png"&gt;</code></pre>
+					</section>
+					<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" data-background-repeat="repeat" data-background-size="100px">
+						<h2>Repeated Image Backgrounds</h2>
+						<pre><code style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre>
+					</section>
+				</section>
+
+				<section data-transition="linear" data-background="#4d7e65" data-background-transition="slide">
+					<h2>Background Transitions</h2>
+					<p>
+						Pass reveal.js the <code>backgroundTransition: 'slide'</code> config argument to make backgrounds slide rather than fade.
+					</p>
+				</section>
+
+				<section data-transition="linear" data-background="#8c4738" data-background-transition="slide">
+					<h2>Background Transition Override</h2>
+					<p>
+						You can override background transitions per slide by using <code>data-background-transition="slide"</code>.
+					</p>
+				</section>
+
+				<section>
+					<h2>Clever Quotes</h2>
+					<p>
+						These guys come in two forms, inline: <q cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
+						&ldquo;The nice thing about standards is that there are so many to choose from&rdquo;</q> and block:
+					</p>
+					<blockquote cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
+						&ldquo;For years there has been a theory that millions of monkeys typing at random on millions of typewriters would
+						reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.&rdquo;
+					</blockquote>
+				</section>
+
+				<section>
+					<h2>Pretty Code</h2>
+					<pre><code data-trim contenteditable>
+function linkify( selector ) {
+  if( supports3DTransforms ) {
+
+    var nodes = document.querySelectorAll( selector );
+
+    for( var i = 0, len = nodes.length; i &lt; len; i++ ) {
+      var node = nodes[i];
+
+      if( !node.className ) {
+        node.className += ' roll';
+      }
+    }
+  }
+}
+					</code></pre>
+					<p>Courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p>
+				</section>
+
+				<section>
+					<h2>Intergalactic Interconnections</h2>
+					<p>
+						You can link between slides internally,
+						<a href="#/2/3">like this</a>.
+					</p>
+				</section>
+
+				<section>
+					<section id="fragments">
+						<h2>Fragmented Views</h2>
+						<p>Hit the next arrow...</p>
+						<p class="fragment">... to step through ...</p>
+						<ol>
+							<li class="fragment"><code>any type</code></li>
+							<li class="fragment"><em>of view</em></li>
+							<li class="fragment"><strong>fragments</strong></li>
+						</ol>
+
+						<aside class="notes">
+							This slide has fragments which are also stepped through in the notes window.
+						</aside>
+					</section>
+					<section>
+						<h2>Fragment Styles</h2>
+						<p>There's a few styles of fragments, like:</p>
+						<p class="fragment grow">grow</p>
+						<p class="fragment shrink">shrink</p>
+						<p class="fragment roll-in">roll-in</p>
+						<p class="fragment fade-out">fade-out</p>
+						<p class="fragment highlight-red">highlight-red</p>
+						<p class="fragment highlight-green">highlight-green</p>
+						<p class="fragment highlight-blue">highlight-blue</p>
+						<p class="fragment current-visible">current-visible</p>
+						<p class="fragment highlight-current-blue">highlight-current-blue</p>
+					</section>
+				</section>
+
+				<section>
+					<h2>Spectacular image!</h2>
+					<a class="image" href="http://lab.hakim.se/meny/" target="_blank">
+						<img width="320" height="299" src="http://s3.amazonaws.com/hakim-static/portfolio/images/meny.png" alt="Meny">
+					</a>
+				</section>
+
+				<section>
+					<h2>Export to PDF</h2>
+					<p>Presentations can be <a href="https://github.com/hakimel/reveal.js#pdf-export">exported to PDF</a>, below is an example that's been uploaded to SlideShare.</p>
+					<iframe id="slideshare" src="http://www.slideshare.net/slideshow/embed_code/13872948" width="455" height="356" style="margin:0;overflow:hidden;border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen> </iframe>
+					<script>
+						document.getElementById('slideshare').attributeName = 'allowfullscreen';
+					</script>
+				</section>
+
+				<section>
+					<h2>Take a Moment</h2>
+					<p>
+						Press b or period on your keyboard to enter the 'paused' mode. This mode is helpful when you want to take distracting slides off the screen
+						during a presentation.
+					</p>
+				</section>
+
+				<section>
+					<h2>Stellar Links</h2>
+					<ul>
+						<li><a href="http://slid.es">Try the online editor</a></li>
+						<li><a href="https://github.com/hakimel/reveal.js">Source code on GitHub</a></li>
+						<li><a href="http://twitter.com/hakimel">Follow me on Twitter</a></li>
+					</ul>
+				</section>
+
+				<section>
+					<h1>THE END</h1>
+					<h3>BY Hakim El Hattab / hakim.se</h3>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="lib/js/head.min.js"></script>
+		<script src="js/reveal.min.js"></script>
+
+		<script>
+
+			// Full list of configuration options available here:
+			// https://github.com/hakimel/reveal.js#configuration
+			Reveal.initialize({
+				controls: true,
+				progress: true,
+				history: true,
+				center: true,
+
+				theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
+				transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+				// Parallax scrolling
+				// parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg',
+				// parallaxBackgroundSize: '2100px 900px',
+
+				// Optional libraries used to extend on reveal.js
+				dependencies: [
+					{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
+					{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+					{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
+					{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
+				]
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/js/reveal.js b/docs/slides/IHP14/_support/reveal.js/js/reveal.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/js/reveal.js
@@ -0,0 +1,3382 @@
+/*!
+ * reveal.js
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+ */
+var Reveal = (function(){
+
+	'use strict';
+
+	var SLIDES_SELECTOR = '.reveal .slides section',
+		HORIZONTAL_SLIDES_SELECTOR = '.reveal .slides>section',
+		VERTICAL_SLIDES_SELECTOR = '.reveal .slides>section.present>section',
+		HOME_SLIDE_SELECTOR = '.reveal .slides>section:first-of-type',
+
+		// Configurations defaults, can be overridden at initialization time
+		config = {
+
+			// The "normal" size of the presentation, aspect ratio will be preserved
+			// when the presentation is scaled to fit different resolutions
+			width: 960,
+			height: 700,
+
+			// Factor of the display size that should remain empty around the content
+			margin: 0.1,
+
+			// Bounds for smallest/largest possible scale to apply to content
+			minScale: 0.2,
+			maxScale: 1.0,
+
+			// Display controls in the bottom right corner
+			controls: true,
+
+			// Display a presentation progress bar
+			progress: true,
+
+			// Display the page number of the current slide
+			slideNumber: false,
+
+			// Push each slide change to the browser history
+			history: false,
+
+			// Enable keyboard shortcuts for navigation
+			keyboard: true,
+
+			// Enable the slide overview mode
+			overview: true,
+
+			// Vertical centering of slides
+			center: true,
+
+			// Enables touch navigation on devices with touch input
+			touch: true,
+
+			// Loop the presentation
+			loop: false,
+
+			// Change the presentation direction to be RTL
+			rtl: false,
+
+			// Turns fragments on and off globally
+			fragments: true,
+
+			// Flags if the presentation is running in an embedded mode,
+			// i.e. contained within a limited portion of the screen
+			embedded: false,
+
+			// Number of milliseconds between automatically proceeding to the
+			// next slide, disabled when set to 0, this value can be overwritten
+			// by using a data-autoslide attribute on your slides
+			autoSlide: 0,
+
+			// Stop auto-sliding after user input
+			autoSlideStoppable: true,
+
+			// Enable slide navigation via mouse wheel
+			mouseWheel: false,
+
+			// Apply a 3D roll to links on hover
+			rollingLinks: false,
+
+			// Hides the address bar on mobile devices
+			hideAddressBar: true,
+
+			// Opens links in an iframe preview overlay
+			previewLinks: false,
+
+			// Focuses body when page changes visiblity to ensure keyboard shortcuts work
+			focusBodyOnPageVisiblityChange: true,
+
+			// Theme (see /css/theme)
+			theme: null,
+
+			// Transition style
+			transition: 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+			// Transition speed
+			transitionSpeed: 'default', // default/fast/slow
+
+			// Transition style for full page slide backgrounds
+			backgroundTransition: 'default', // default/linear/none
+
+			// Parallax background image
+			parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg"
+
+			// Parallax background size
+			parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px"
+
+			// Number of slides away from the current that are visible
+			viewDistance: 3,
+
+			// Script dependencies to load
+			dependencies: []
+
+		},
+
+		// Flags if reveal.js is loaded (has dispatched the 'ready' event)
+		loaded = false,
+
+		// The horizontal and vertical index of the currently active slide
+		indexh,
+		indexv,
+
+		// The previous and current slide HTML elements
+		previousSlide,
+		currentSlide,
+
+		previousBackground,
+
+		// Slides may hold a data-state attribute which we pick up and apply
+		// as a class to the body. This list contains the combined state of
+		// all current slides.
+		state = [],
+
+		// The current scale of the presentation (see width/height config)
+		scale = 1,
+
+		// Cached references to DOM elements
+		dom = {},
+
+		// Features supported by the browser, see #checkCapabilities()
+		features = {},
+
+		// Client is a mobile device, see #checkCapabilities()
+		isMobileDevice,
+
+		// Throttles mouse wheel navigation
+		lastMouseWheelStep = 0,
+
+		// Delays updates to the URL due to a Chrome thumbnailer bug
+		writeURLTimeout = 0,
+
+		// A delay used to activate the overview mode
+		activateOverviewTimeout = 0,
+
+		// A delay used to deactivate the overview mode
+		deactivateOverviewTimeout = 0,
+
+		// Flags if the interaction event listeners are bound
+		eventsAreBound = false,
+
+		// The current auto-slide duration
+		autoSlide = 0,
+
+		// Auto slide properties
+		autoSlidePlayer,
+		autoSlideTimeout = 0,
+		autoSlideStartTime = -1,
+		autoSlidePaused = false,
+
+		// Holds information about the currently ongoing touch input
+		touch = {
+			startX: 0,
+			startY: 0,
+			startSpan: 0,
+			startCount: 0,
+			captured: false,
+			threshold: 40
+		};
+
+	/**
+	 * Starts up the presentation if the client is capable.
+	 */
+	function initialize( options ) {
+
+		checkCapabilities();
+
+		if( !features.transforms2d && !features.transforms3d ) {
+			document.body.setAttribute( 'class', 'no-transforms' );
+
+			// If the browser doesn't support core features we won't be
+			// using JavaScript to control the presentation
+			return;
+		}
+
+		// Force a layout when the whole page, incl fonts, has loaded
+		window.addEventListener( 'load', layout, false );
+
+		var query = Reveal.getQueryHash();
+
+		// Do not accept new dependencies via query config to avoid
+		// the potential of malicious script injection
+		if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];
+
+		// Copy options over to our config object
+		extend( config, options );
+		extend( config, query );
+
+		// Hide the address bar in mobile browsers
+		hideAddressBar();
+
+		// Loads the dependencies and continues to #start() once done
+		load();
+
+	}
+
+	/**
+	 * Inspect the client to see what it's capable of, this
+	 * should only happens once per runtime.
+	 */
+	function checkCapabilities() {
+
+		features.transforms3d = 'WebkitPerspective' in document.body.style ||
+								'MozPerspective' in document.body.style ||
+								'msPerspective' in document.body.style ||
+								'OPerspective' in document.body.style ||
+								'perspective' in document.body.style;
+
+		features.transforms2d = 'WebkitTransform' in document.body.style ||
+								'MozTransform' in document.body.style ||
+								'msTransform' in document.body.style ||
+								'OTransform' in document.body.style ||
+								'transform' in document.body.style;
+
+		features.requestAnimationFrameMethod = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
+		features.requestAnimationFrame = typeof features.requestAnimationFrameMethod === 'function';
+
+		features.canvas = !!document.createElement( 'canvas' ).getContext;
+
+		isMobileDevice = navigator.userAgent.match( /(iphone|ipod|android)/gi );
+
+	}
+
+
+    /**
+     * Loads the dependencies of reveal.js. Dependencies are
+     * defined via the configuration option 'dependencies'
+     * and will be loaded prior to starting/binding reveal.js.
+     * Some dependencies may have an 'async' flag, if so they
+     * will load after reveal.js has been started up.
+     */
+	function load() {
+
+		var scripts = [],
+			scriptsAsync = [],
+			scriptsToPreload = 0;
+
+		// Called once synchronous scripts finish loading
+		function proceed() {
+			if( scriptsAsync.length ) {
+				// Load asynchronous scripts
+				head.js.apply( null, scriptsAsync );
+			}
+
+			start();
+		}
+
+		function loadScript( s ) {
+			head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], function() {
+				// Extension may contain callback functions
+				if( typeof s.callback === 'function' ) {
+					s.callback.apply( this );
+				}
+
+				if( --scriptsToPreload === 0 ) {
+					proceed();
+				}
+			});
+		}
+
+		for( var i = 0, len = config.dependencies.length; i < len; i++ ) {
+			var s = config.dependencies[i];
+
+			// Load if there's no condition or the condition is truthy
+			if( !s.condition || s.condition() ) {
+				if( s.async ) {
+					scriptsAsync.push( s.src );
+				}
+				else {
+					scripts.push( s.src );
+				}
+
+				loadScript( s );
+			}
+		}
+
+		if( scripts.length ) {
+			scriptsToPreload = scripts.length;
+
+			// Load synchronous scripts
+			head.js.apply( null, scripts );
+		}
+		else {
+			proceed();
+		}
+
+	}
+
+	/**
+	 * Starts up reveal.js by binding input events and navigating
+	 * to the current URL deeplink if there is one.
+	 */
+	function start() {
+
+		// Make sure we've got all the DOM elements we need
+		setupDOM();
+
+		// Resets all vertical slides so that only the first is visible
+		resetVerticalSlides();
+
+		// Updates the presentation to match the current configuration values
+		configure();
+
+		// Read the initial hash
+		readURL();
+
+		// Update all backgrounds
+		updateBackground( true );
+
+		// Notify listeners that the presentation is ready but use a 1ms
+		// timeout to ensure it's not fired synchronously after #initialize()
+		setTimeout( function() {
+			// Enable transitions now that we're loaded
+			dom.slides.classList.remove( 'no-transition' );
+
+			loaded = true;
+
+			dispatchEvent( 'ready', {
+				'indexh': indexh,
+				'indexv': indexv,
+				'currentSlide': currentSlide
+			} );
+		}, 1 );
+
+	}
+
+	/**
+	 * Finds and stores references to DOM elements which are
+	 * required by the presentation. If a required element is
+	 * not found, it is created.
+	 */
+	function setupDOM() {
+
+		// Cache references to key DOM elements
+		dom.theme = document.querySelector( '#theme' );
+		dom.wrapper = document.querySelector( '.reveal' );
+		dom.slides = document.querySelector( '.reveal .slides' );
+
+		// Prevent transitions while we're loading
+		dom.slides.classList.add( 'no-transition' );
+
+		// Background element
+		dom.background = createSingletonNode( dom.wrapper, 'div', 'backgrounds', null );
+
+		// Progress bar
+		dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '<span></span>' );
+		dom.progressbar = dom.progress.querySelector( 'span' );
+
+		// Arrow controls
+		createSingletonNode( dom.wrapper, 'aside', 'controls',
+			'<div class="navigate-left"></div>' +
+			'<div class="navigate-right"></div>' +
+			'<div class="navigate-up"></div>' +
+			'<div class="navigate-down"></div>' );
+
+		// Slide number
+		dom.slideNumber = createSingletonNode( dom.wrapper, 'div', 'slide-number', '' );
+
+		// State background element [DEPRECATED]
+		createSingletonNode( dom.wrapper, 'div', 'state-background', null );
+
+		// Overlay graphic which is displayed during the paused mode
+		createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null );
+
+		// Cache references to elements
+		dom.controls = document.querySelector( '.reveal .controls' );
+
+		// There can be multiple instances of controls throughout the page
+		dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) );
+		dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) );
+		dom.controlsUp = toArray( document.querySelectorAll( '.navigate-up' ) );
+		dom.controlsDown = toArray( document.querySelectorAll( '.navigate-down' ) );
+		dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) );
+		dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) );
+
+	}
+
+	/**
+	 * Creates an HTML element and returns a reference to it.
+	 * If the element already exists the existing instance will
+	 * be returned.
+	 */
+	function createSingletonNode( container, tagname, classname, innerHTML ) {
+
+		var node = container.querySelector( '.' + classname );
+		if( !node ) {
+			node = document.createElement( tagname );
+			node.classList.add( classname );
+			if( innerHTML !== null ) {
+				node.innerHTML = innerHTML;
+			}
+			container.appendChild( node );
+		}
+		return node;
+
+	}
+
+	/**
+	 * Creates the slide background elements and appends them
+	 * to the background container. One element is created per
+	 * slide no matter if the given slide has visible background.
+	 */
+	function createBackgrounds() {
+
+		if( isPrintingPDF() ) {
+			document.body.classList.add( 'print-pdf' );
+		}
+
+		// Clear prior backgrounds
+		dom.background.innerHTML = '';
+		dom.background.classList.add( 'no-transition' );
+
+		// Helper method for creating a background element for the
+		// given slide
+		function _createBackground( slide, container ) {
+
+			var data = {
+				background: slide.getAttribute( 'data-background' ),
+				backgroundSize: slide.getAttribute( 'data-background-size' ),
+				backgroundImage: slide.getAttribute( 'data-background-image' ),
+				backgroundColor: slide.getAttribute( 'data-background-color' ),
+				backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
+				backgroundPosition: slide.getAttribute( 'data-background-position' ),
+				backgroundTransition: slide.getAttribute( 'data-background-transition' )
+			};
+
+			var element = document.createElement( 'div' );
+			element.className = 'slide-background';
+
+			if( data.background ) {
+				// Auto-wrap image urls in url(...)
+				if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
+					element.style.backgroundImage = 'url('+ data.background +')';
+				}
+				else {
+					element.style.background = data.background;
+				}
+			}
+
+			if( data.background || data.backgroundColor || data.backgroundImage ) {
+				element.setAttribute( 'data-background-hash', data.background + data.backgroundSize + data.backgroundImage + data.backgroundColor + data.backgroundRepeat + data.backgroundPosition + data.backgroundTransition );
+			}
+
+			// Additional and optional background properties
+			if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize;
+			if( data.backgroundImage ) element.style.backgroundImage = 'url("' + data.backgroundImage + '")';
+			if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
+			if( data.backgroundRepeat ) element.style.backgroundRepeat = data.backgroundRepeat;
+			if( data.backgroundPosition ) element.style.backgroundPosition = data.backgroundPosition;
+			if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
+
+			container.appendChild( element );
+
+			return element;
+
+		}
+
+		// Iterate over all horizontal slides
+		toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( slideh ) {
+
+			var backgroundStack;
+
+			if( isPrintingPDF() ) {
+				backgroundStack = _createBackground( slideh, slideh );
+			}
+			else {
+				backgroundStack = _createBackground( slideh, dom.background );
+			}
+
+			// Iterate over all vertical slides
+			toArray( slideh.querySelectorAll( 'section' ) ).forEach( function( slidev ) {
+
+				if( isPrintingPDF() ) {
+					_createBackground( slidev, slidev );
+				}
+				else {
+					_createBackground( slidev, backgroundStack );
+				}
+
+			} );
+
+		} );
+
+		// Add parallax background if specified
+		if( config.parallaxBackgroundImage ) {
+
+			dom.background.style.backgroundImage = 'url("' + config.parallaxBackgroundImage + '")';
+			dom.background.style.backgroundSize = config.parallaxBackgroundSize;
+
+			// Make sure the below properties are set on the element - these properties are
+			// needed for proper transitions to be set on the element via CSS. To remove
+			// annoying background slide-in effect when the presentation starts, apply
+			// these properties after short time delay
+			setTimeout( function() {
+				dom.wrapper.classList.add( 'has-parallax-background' );
+			}, 1 );
+
+		}
+		else {
+
+			dom.background.style.backgroundImage = '';
+			dom.wrapper.classList.remove( 'has-parallax-background' );
+
+		}
+
+	}
+
+	/**
+	 * Applies the configuration settings from the config
+	 * object. May be called multiple times.
+	 */
+	function configure( options ) {
+
+		var numberOfSlides = document.querySelectorAll( SLIDES_SELECTOR ).length;
+
+		dom.wrapper.classList.remove( config.transition );
+
+		// New config options may be passed when this method
+		// is invoked through the API after initialization
+		if( typeof options === 'object' ) extend( config, options );
+
+		// Force linear transition based on browser capabilities
+		if( features.transforms3d === false ) config.transition = 'linear';
+
+		dom.wrapper.classList.add( config.transition );
+
+		dom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed );
+		dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );
+
+		dom.controls.style.display = config.controls ? 'block' : 'none';
+		dom.progress.style.display = config.progress ? 'block' : 'none';
+
+		if( config.rtl ) {
+			dom.wrapper.classList.add( 'rtl' );
+		}
+		else {
+			dom.wrapper.classList.remove( 'rtl' );
+		}
+
+		if( config.center ) {
+			dom.wrapper.classList.add( 'center' );
+		}
+		else {
+			dom.wrapper.classList.remove( 'center' );
+		}
+
+		if( config.mouseWheel ) {
+			document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
+			document.addEventListener( 'mousewheel', onDocumentMouseScroll, false );
+		}
+		else {
+			document.removeEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
+			document.removeEventListener( 'mousewheel', onDocumentMouseScroll, false );
+		}
+
+		// Rolling 3D links
+		if( config.rollingLinks ) {
+			enableRollingLinks();
+		}
+		else {
+			disableRollingLinks();
+		}
+
+		// Iframe link previews
+		if( config.previewLinks ) {
+			enablePreviewLinks();
+		}
+		else {
+			disablePreviewLinks();
+			enablePreviewLinks( '[data-preview-link]' );
+		}
+
+		// Auto-slide playback controls
+		if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable && features.canvas && features.requestAnimationFrame ) {
+			autoSlidePlayer = new Playback( dom.wrapper, function() {
+				return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );
+			} );
+
+			autoSlidePlayer.on( 'click', onAutoSlidePlayerClick );
+			autoSlidePaused = false;
+		}
+		else if( autoSlidePlayer ) {
+			autoSlidePlayer.destroy();
+			autoSlidePlayer = null;
+		}
+
+		// Load the theme in the config, if it's not already loaded
+		if( config.theme && dom.theme ) {
+			var themeURL = dom.theme.getAttribute( 'href' );
+			var themeFinder = /[^\/]*?(?=\.css)/;
+			var themeName = themeURL.match(themeFinder)[0];
+
+			if(  config.theme !== themeName ) {
+				themeURL = themeURL.replace(themeFinder, config.theme);
+				dom.theme.setAttribute( 'href', themeURL );
+			}
+		}
+
+		sync();
+
+	}
+
+	/**
+	 * Binds all event listeners.
+	 */
+	function addEventListeners() {
+
+		eventsAreBound = true;
+
+		window.addEventListener( 'hashchange', onWindowHashChange, false );
+		window.addEventListener( 'resize', onWindowResize, false );
+
+		if( config.touch ) {
+			dom.wrapper.addEventListener( 'touchstart', onTouchStart, false );
+			dom.wrapper.addEventListener( 'touchmove', onTouchMove, false );
+			dom.wrapper.addEventListener( 'touchend', onTouchEnd, false );
+
+			// Support pointer-style touch interaction as well
+			if( window.navigator.msPointerEnabled ) {
+				dom.wrapper.addEventListener( 'MSPointerDown', onPointerDown, false );
+				dom.wrapper.addEventListener( 'MSPointerMove', onPointerMove, false );
+				dom.wrapper.addEventListener( 'MSPointerUp', onPointerUp, false );
+			}
+		}
+
+		if( config.keyboard ) {
+			document.addEventListener( 'keydown', onDocumentKeyDown, false );
+		}
+
+		if( config.progress && dom.progress ) {
+			dom.progress.addEventListener( 'click', onProgressClicked, false );
+		}
+
+		if( config.focusBodyOnPageVisiblityChange ) {
+			var visibilityChange;
+
+			if( 'hidden' in document ) {
+				visibilityChange = 'visibilitychange';
+			}
+			else if( 'msHidden' in document ) {
+				visibilityChange = 'msvisibilitychange';
+			}
+			else if( 'webkitHidden' in document ) {
+				visibilityChange = 'webkitvisibilitychange';
+			}
+
+			if( visibilityChange ) {
+				document.addEventListener( visibilityChange, onPageVisibilityChange, false );
+			}
+		}
+
+		[ 'touchstart', 'click' ].forEach( function( eventName ) {
+			dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } );
+			dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } );
+			dom.controlsUp.forEach( function( el ) { el.addEventListener( eventName, onNavigateUpClicked, false ); } );
+			dom.controlsDown.forEach( function( el ) { el.addEventListener( eventName, onNavigateDownClicked, false ); } );
+			dom.controlsPrev.forEach( function( el ) { el.addEventListener( eventName, onNavigatePrevClicked, false ); } );
+			dom.controlsNext.forEach( function( el ) { el.addEventListener( eventName, onNavigateNextClicked, false ); } );
+		} );
+
+	}
+
+	/**
+	 * Unbinds all event listeners.
+	 */
+	function removeEventListeners() {
+
+		eventsAreBound = false;
+
+		document.removeEventListener( 'keydown', onDocumentKeyDown, false );
+		window.removeEventListener( 'hashchange', onWindowHashChange, false );
+		window.removeEventListener( 'resize', onWindowResize, false );
+
+		dom.wrapper.removeEventListener( 'touchstart', onTouchStart, false );
+		dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false );
+		dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false );
+
+		if( window.navigator.msPointerEnabled ) {
+			dom.wrapper.removeEventListener( 'MSPointerDown', onPointerDown, false );
+			dom.wrapper.removeEventListener( 'MSPointerMove', onPointerMove, false );
+			dom.wrapper.removeEventListener( 'MSPointerUp', onPointerUp, false );
+		}
+
+		if ( config.progress && dom.progress ) {
+			dom.progress.removeEventListener( 'click', onProgressClicked, false );
+		}
+
+		[ 'touchstart', 'click' ].forEach( function( eventName ) {
+			dom.controlsLeft.forEach( function( el ) { el.removeEventListener( eventName, onNavigateLeftClicked, false ); } );
+			dom.controlsRight.forEach( function( el ) { el.removeEventListener( eventName, onNavigateRightClicked, false ); } );
+			dom.controlsUp.forEach( function( el ) { el.removeEventListener( eventName, onNavigateUpClicked, false ); } );
+			dom.controlsDown.forEach( function( el ) { el.removeEventListener( eventName, onNavigateDownClicked, false ); } );
+			dom.controlsPrev.forEach( function( el ) { el.removeEventListener( eventName, onNavigatePrevClicked, false ); } );
+			dom.controlsNext.forEach( function( el ) { el.removeEventListener( eventName, onNavigateNextClicked, false ); } );
+		} );
+
+	}
+
+	/**
+	 * Extend object a with the properties of object b.
+	 * If there's a conflict, object b takes precedence.
+	 */
+	function extend( a, b ) {
+
+		for( var i in b ) {
+			a[ i ] = b[ i ];
+		}
+
+	}
+
+	/**
+	 * Converts the target object to an array.
+	 */
+	function toArray( o ) {
+
+		return Array.prototype.slice.call( o );
+
+	}
+
+	/**
+	 * Measures the distance in pixels between point a
+	 * and point b.
+	 *
+	 * @param {Object} a point with x/y properties
+	 * @param {Object} b point with x/y properties
+	 */
+	function distanceBetween( a, b ) {
+
+		var dx = a.x - b.x,
+			dy = a.y - b.y;
+
+		return Math.sqrt( dx*dx + dy*dy );
+
+	}
+
+	/**
+	 * Applies a CSS transform to the target element.
+	 */
+	function transformElement( element, transform ) {
+
+		element.style.WebkitTransform = transform;
+		element.style.MozTransform = transform;
+		element.style.msTransform = transform;
+		element.style.OTransform = transform;
+		element.style.transform = transform;
+
+	}
+
+	/**
+	 * Retrieves the height of the given element by looking
+	 * at the position and height of its immediate children.
+	 */
+	function getAbsoluteHeight( element ) {
+
+		var height = 0;
+
+		if( element ) {
+			var absoluteChildren = 0;
+
+			toArray( element.childNodes ).forEach( function( child ) {
+
+				if( typeof child.offsetTop === 'number' && child.style ) {
+					// Count # of abs children
+					if( child.style.position === 'absolute' ) {
+						absoluteChildren += 1;
+					}
+
+					height = Math.max( height, child.offsetTop + child.offsetHeight );
+				}
+
+			} );
+
+			// If there are no absolute children, use offsetHeight
+			if( absoluteChildren === 0 ) {
+				height = element.offsetHeight;
+			}
+
+		}
+
+		return height;
+
+	}
+
+	/**
+	 * Returns the remaining height within the parent of the
+	 * target element after subtracting the height of all
+	 * siblings.
+	 *
+	 * remaining height = [parent height] - [ siblings height]
+	 */
+	function getRemainingHeight( element, height ) {
+
+		height = height || 0;
+
+		if( element ) {
+			var parent = element.parentNode;
+			var siblings = parent.childNodes;
+
+			// Subtract the height of each sibling
+			toArray( siblings ).forEach( function( sibling ) {
+
+				if( typeof sibling.offsetHeight === 'number' && sibling !== element ) {
+
+					var styles = window.getComputedStyle( sibling ),
+						marginTop = parseInt( styles.marginTop, 10 ),
+						marginBottom = parseInt( styles.marginBottom, 10 );
+
+					height -= sibling.offsetHeight + marginTop + marginBottom;
+
+				}
+
+			} );
+
+			var elementStyles = window.getComputedStyle( element );
+
+			// Subtract the margins of the target element
+			height -= parseInt( elementStyles.marginTop, 10 ) +
+						parseInt( elementStyles.marginBottom, 10 );
+
+		}
+
+		return height;
+
+	}
+
+	/**
+	 * Checks if this instance is being used to print a PDF.
+	 */
+	function isPrintingPDF() {
+
+		return ( /print-pdf/gi ).test( window.location.search );
+
+	}
+
+	/**
+	 * Hides the address bar if we're on a mobile device.
+	 */
+	function hideAddressBar() {
+
+		if( config.hideAddressBar && isMobileDevice ) {
+			// Events that should trigger the address bar to hide
+			window.addEventListener( 'load', removeAddressBar, false );
+			window.addEventListener( 'orientationchange', removeAddressBar, false );
+		}
+
+	}
+
+	/**
+	 * Causes the address bar to hide on mobile devices,
+	 * more vertical space ftw.
+	 */
+	function removeAddressBar() {
+
+		setTimeout( function() {
+			window.scrollTo( 0, 1 );
+		}, 10 );
+
+	}
+
+	/**
+	 * Dispatches an event of the specified type from the
+	 * reveal DOM element.
+	 */
+	function dispatchEvent( type, properties ) {
+
+		var event = document.createEvent( "HTMLEvents", 1, 2 );
+		event.initEvent( type, true, true );
+		extend( event, properties );
+		dom.wrapper.dispatchEvent( event );
+
+	}
+
+	/**
+	 * Wrap all links in 3D goodness.
+	 */
+	function enableRollingLinks() {
+
+		if( features.transforms3d && !( 'msPerspective' in document.body.style ) ) {
+			var anchors = document.querySelectorAll( SLIDES_SELECTOR + ' a:not(.image)' );
+
+			for( var i = 0, len = anchors.length; i < len; i++ ) {
+				var anchor = anchors[i];
+
+				if( anchor.textContent && !anchor.querySelector( '*' ) && ( !anchor.className || !anchor.classList.contains( anchor, 'roll' ) ) ) {
+					var span = document.createElement('span');
+					span.setAttribute('data-title', anchor.text);
+					span.innerHTML = anchor.innerHTML;
+
+					anchor.classList.add( 'roll' );
+					anchor.innerHTML = '';
+					anchor.appendChild(span);
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * Unwrap all 3D links.
+	 */
+	function disableRollingLinks() {
+
+		var anchors = document.querySelectorAll( SLIDES_SELECTOR + ' a.roll' );
+
+		for( var i = 0, len = anchors.length; i < len; i++ ) {
+			var anchor = anchors[i];
+			var span = anchor.querySelector( 'span' );
+
+			if( span ) {
+				anchor.classList.remove( 'roll' );
+				anchor.innerHTML = span.innerHTML;
+			}
+		}
+
+	}
+
+	/**
+	 * Bind preview frame links.
+	 */
+	function enablePreviewLinks( selector ) {
+
+		var anchors = toArray( document.querySelectorAll( selector ? selector : 'a' ) );
+
+		anchors.forEach( function( element ) {
+			if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) {
+				element.addEventListener( 'click', onPreviewLinkClicked, false );
+			}
+		} );
+
+	}
+
+	/**
+	 * Unbind preview frame links.
+	 */
+	function disablePreviewLinks() {
+
+		var anchors = toArray( document.querySelectorAll( 'a' ) );
+
+		anchors.forEach( function( element ) {
+			if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) {
+				element.removeEventListener( 'click', onPreviewLinkClicked, false );
+			}
+		} );
+
+	}
+
+	/**
+	 * Opens a preview window for the target URL.
+	 */
+	function openPreview( url ) {
+
+		closePreview();
+
+		dom.preview = document.createElement( 'div' );
+		dom.preview.classList.add( 'preview-link-overlay' );
+		dom.wrapper.appendChild( dom.preview );
+
+		dom.preview.innerHTML = [
+			'<header>',
+				'<a class="close" href="#"><span class="icon"></span></a>',
+				'<a class="external" href="'+ url +'" target="_blank"><span class="icon"></span></a>',
+			'</header>',
+			'<div class="spinner"></div>',
+			'<div class="viewport">',
+				'<iframe src="'+ url +'"></iframe>',
+			'</div>'
+		].join('');
+
+		dom.preview.querySelector( 'iframe' ).addEventListener( 'load', function( event ) {
+			dom.preview.classList.add( 'loaded' );
+		}, false );
+
+		dom.preview.querySelector( '.close' ).addEventListener( 'click', function( event ) {
+			closePreview();
+			event.preventDefault();
+		}, false );
+
+		dom.preview.querySelector( '.external' ).addEventListener( 'click', function( event ) {
+			closePreview();
+		}, false );
+
+		setTimeout( function() {
+			dom.preview.classList.add( 'visible' );
+		}, 1 );
+
+	}
+
+	/**
+	 * Closes the iframe preview window.
+	 */
+	function closePreview() {
+
+		if( dom.preview ) {
+			dom.preview.setAttribute( 'src', '' );
+			dom.preview.parentNode.removeChild( dom.preview );
+			dom.preview = null;
+		}
+
+	}
+
+	/**
+	 * Applies JavaScript-controlled layout rules to the
+	 * presentation.
+	 */
+	function layout() {
+
+		if( dom.wrapper && !isPrintingPDF() ) {
+
+			// Available space to scale within
+			var availableWidth = dom.wrapper.offsetWidth,
+				availableHeight = dom.wrapper.offsetHeight;
+
+			// Reduce available space by margin
+			availableWidth -= ( availableHeight * config.margin );
+			availableHeight -= ( availableHeight * config.margin );
+
+			// Dimensions of the content
+			var slideWidth = config.width,
+				slideHeight = config.height,
+				slidePadding = 20; // TODO Dig this out of DOM
+
+			// Layout the contents of the slides
+			layoutSlideContents( config.width, config.height, slidePadding );
+
+			// Slide width may be a percentage of available width
+			if( typeof slideWidth === 'string' && /%$/.test( slideWidth ) ) {
+				slideWidth = parseInt( slideWidth, 10 ) / 100 * availableWidth;
+			}
+
+			// Slide height may be a percentage of available height
+			if( typeof slideHeight === 'string' && /%$/.test( slideHeight ) ) {
+				slideHeight = parseInt( slideHeight, 10 ) / 100 * availableHeight;
+			}
+
+			dom.slides.style.width = slideWidth + 'px';
+			dom.slides.style.height = slideHeight + 'px';
+
+			// Determine scale of content to fit within available space
+			scale = Math.min( availableWidth / slideWidth, availableHeight / slideHeight );
+
+			// Respect max/min scale settings
+			scale = Math.max( scale, config.minScale );
+			scale = Math.min( scale, config.maxScale );
+
+			// Prefer applying scale via zoom since Chrome blurs scaled content
+			// with nested transforms
+			if( typeof dom.slides.style.zoom !== 'undefined' && !navigator.userAgent.match( /(iphone|ipod|ipad|android)/gi ) ) {
+				dom.slides.style.zoom = scale;
+			}
+			// Apply scale transform as a fallback
+			else {
+				transformElement( dom.slides, 'translate(-50%, -50%) scale('+ scale +') translate(50%, 50%)' );
+			}
+
+			// Select all slides, vertical and horizontal
+			var slides = toArray( document.querySelectorAll( SLIDES_SELECTOR ) );
+
+			for( var i = 0, len = slides.length; i < len; i++ ) {
+				var slide = slides[ i ];
+
+				// Don't bother updating invisible slides
+				if( slide.style.display === 'none' ) {
+					continue;
+				}
+
+				if( config.center || slide.classList.contains( 'center' ) ) {
+					// Vertical stacks are not centred since their section
+					// children will be
+					if( slide.classList.contains( 'stack' ) ) {
+						slide.style.top = 0;
+					}
+					else {
+						slide.style.top = Math.max( - ( getAbsoluteHeight( slide ) / 2 ) - slidePadding, -slideHeight / 2 ) + 'px';
+					}
+				}
+				else {
+					slide.style.top = '';
+				}
+
+			}
+
+			updateProgress();
+			updateParallax();
+
+		}
+
+	}
+
+	/**
+	 * Applies layout logic to the contents of all slides in
+	 * the presentation.
+	 */
+	function layoutSlideContents( width, height, padding ) {
+
+		// Handle sizing of elements with the 'stretch' class
+		toArray( dom.slides.querySelectorAll( 'section > .stretch' ) ).forEach( function( element ) {
+
+			// Determine how much vertical space we can use
+			var remainingHeight = getRemainingHeight( element, ( height - ( padding * 2 ) ) );
+
+			// Consider the aspect ratio of media elements
+			if( /(img|video)/gi.test( element.nodeName ) ) {
+				var nw = element.naturalWidth || element.videoWidth,
+					nh = element.naturalHeight || element.videoHeight;
+
+				var es = Math.min( width / nw, remainingHeight / nh );
+
+				element.style.width = ( nw * es ) + 'px';
+				element.style.height = ( nh * es ) + 'px';
+
+			}
+			else {
+				element.style.width = width + 'px';
+				element.style.height = remainingHeight + 'px';
+			}
+
+		} );
+
+	}
+
+	/**
+	 * Stores the vertical index of a stack so that the same
+	 * vertical slide can be selected when navigating to and
+	 * from the stack.
+	 *
+	 * @param {HTMLElement} stack The vertical stack element
+	 * @param {int} v Index to memorize
+	 */
+	function setPreviousVerticalIndex( stack, v ) {
+
+		if( typeof stack === 'object' && typeof stack.setAttribute === 'function' ) {
+			stack.setAttribute( 'data-previous-indexv', v || 0 );
+		}
+
+	}
+
+	/**
+	 * Retrieves the vertical index which was stored using
+	 * #setPreviousVerticalIndex() or 0 if no previous index
+	 * exists.
+	 *
+	 * @param {HTMLElement} stack The vertical stack element
+	 */
+	function getPreviousVerticalIndex( stack ) {
+
+		if( typeof stack === 'object' && typeof stack.setAttribute === 'function' && stack.classList.contains( 'stack' ) ) {
+			// Prefer manually defined start-indexv
+			var attributeName = stack.hasAttribute( 'data-start-indexv' ) ? 'data-start-indexv' : 'data-previous-indexv';
+
+			return parseInt( stack.getAttribute( attributeName ) || 0, 10 );
+		}
+
+		return 0;
+
+	}
+
+	/**
+	 * Displays the overview of slides (quick nav) by
+	 * scaling down and arranging all slide elements.
+	 *
+	 * Experimental feature, might be dropped if perf
+	 * can't be improved.
+	 */
+	function activateOverview() {
+
+		// Only proceed if enabled in config
+		if( config.overview ) {
+
+			// Don't auto-slide while in overview mode
+			cancelAutoSlide();
+
+			var wasActive = dom.wrapper.classList.contains( 'overview' );
+
+			// Vary the depth of the overview based on screen size
+			var depth = window.innerWidth < 400 ? 1000 : 2500;
+
+			dom.wrapper.classList.add( 'overview' );
+			dom.wrapper.classList.remove( 'overview-deactivating' );
+
+			clearTimeout( activateOverviewTimeout );
+			clearTimeout( deactivateOverviewTimeout );
+
+			// Not the pretties solution, but need to let the overview
+			// class apply first so that slides are measured accurately
+			// before we can position them
+			activateOverviewTimeout = setTimeout( function() {
+
+				var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+
+				for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
+					var hslide = horizontalSlides[i],
+						hoffset = config.rtl ? -105 : 105;
+
+					hslide.setAttribute( 'data-index-h', i );
+
+					// Apply CSS transform
+					transformElement( hslide, 'translateZ(-'+ depth +'px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)' );
+
+					if( hslide.classList.contains( 'stack' ) ) {
+
+						var verticalSlides = hslide.querySelectorAll( 'section' );
+
+						for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
+							var verticalIndex = i === indexh ? indexv : getPreviousVerticalIndex( hslide );
+
+							var vslide = verticalSlides[j];
+
+							vslide.setAttribute( 'data-index-h', i );
+							vslide.setAttribute( 'data-index-v', j );
+
+							// Apply CSS transform
+							transformElement( vslide, 'translate(0%, ' + ( ( j - verticalIndex ) * 105 ) + '%)' );
+
+							// Navigate to this slide on click
+							vslide.addEventListener( 'click', onOverviewSlideClicked, true );
+						}
+
+					}
+					else {
+
+						// Navigate to this slide on click
+						hslide.addEventListener( 'click', onOverviewSlideClicked, true );
+
+					}
+				}
+
+				updateSlidesVisibility();
+
+				layout();
+
+				if( !wasActive ) {
+					// Notify observers of the overview showing
+					dispatchEvent( 'overviewshown', {
+						'indexh': indexh,
+						'indexv': indexv,
+						'currentSlide': currentSlide
+					} );
+				}
+
+			}, 10 );
+
+		}
+
+	}
+
+	/**
+	 * Exits the slide overview and enters the currently
+	 * active slide.
+	 */
+	function deactivateOverview() {
+
+		// Only proceed if enabled in config
+		if( config.overview ) {
+
+			clearTimeout( activateOverviewTimeout );
+			clearTimeout( deactivateOverviewTimeout );
+
+			dom.wrapper.classList.remove( 'overview' );
+
+			// Temporarily add a class so that transitions can do different things
+			// depending on whether they are exiting/entering overview, or just
+			// moving from slide to slide
+			dom.wrapper.classList.add( 'overview-deactivating' );
+
+			deactivateOverviewTimeout = setTimeout( function () {
+				dom.wrapper.classList.remove( 'overview-deactivating' );
+			}, 1 );
+
+			// Select all slides
+			toArray( document.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) {
+				// Resets all transforms to use the external styles
+				transformElement( slide, '' );
+
+				slide.removeEventListener( 'click', onOverviewSlideClicked, true );
+			} );
+
+			slide( indexh, indexv );
+
+			cueAutoSlide();
+
+			// Notify observers of the overview hiding
+			dispatchEvent( 'overviewhidden', {
+				'indexh': indexh,
+				'indexv': indexv,
+				'currentSlide': currentSlide
+			} );
+
+		}
+	}
+
+	/**
+	 * Toggles the slide overview mode on and off.
+	 *
+	 * @param {Boolean} override Optional flag which overrides the
+	 * toggle logic and forcibly sets the desired state. True means
+	 * overview is open, false means it's closed.
+	 */
+	function toggleOverview( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? activateOverview() : deactivateOverview();
+		}
+		else {
+			isOverview() ? deactivateOverview() : activateOverview();
+		}
+
+	}
+
+	/**
+	 * Checks if the overview is currently active.
+	 *
+	 * @return {Boolean} true if the overview is active,
+	 * false otherwise
+	 */
+	function isOverview() {
+
+		return dom.wrapper.classList.contains( 'overview' );
+
+	}
+
+	/**
+	 * Checks if the current or specified slide is vertical
+	 * (nested within another slide).
+	 *
+	 * @param {HTMLElement} slide [optional] The slide to check
+	 * orientation of
+	 */
+	function isVerticalSlide( slide ) {
+
+		// Prefer slide argument, otherwise use current slide
+		slide = slide ? slide : currentSlide;
+
+		return slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i );
+
+	}
+
+	/**
+	 * Handling the fullscreen functionality via the fullscreen API
+	 *
+	 * @see http://fullscreen.spec.whatwg.org/
+	 * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode
+	 */
+	function enterFullscreen() {
+
+		var element = document.body;
+
+		// Check which implementation is available
+		var requestMethod = element.requestFullScreen ||
+							element.webkitRequestFullscreen ||
+							element.webkitRequestFullScreen ||
+							element.mozRequestFullScreen ||
+							element.msRequestFullScreen;
+
+		if( requestMethod ) {
+			requestMethod.apply( element );
+		}
+
+	}
+
+	/**
+	 * Enters the paused mode which fades everything on screen to
+	 * black.
+	 */
+	function pause() {
+
+		var wasPaused = dom.wrapper.classList.contains( 'paused' );
+
+		cancelAutoSlide();
+		dom.wrapper.classList.add( 'paused' );
+
+		if( wasPaused === false ) {
+			dispatchEvent( 'paused' );
+		}
+
+	}
+
+	/**
+	 * Exits from the paused mode.
+	 */
+	function resume() {
+
+		var wasPaused = dom.wrapper.classList.contains( 'paused' );
+		dom.wrapper.classList.remove( 'paused' );
+
+		cueAutoSlide();
+
+		if( wasPaused ) {
+			dispatchEvent( 'resumed' );
+		}
+
+	}
+
+	/**
+	 * Toggles the paused mode on and off.
+	 */
+	function togglePause() {
+
+		if( isPaused() ) {
+			resume();
+		}
+		else {
+			pause();
+		}
+
+	}
+
+	/**
+	 * Checks if we are currently in the paused mode.
+	 */
+	function isPaused() {
+
+		return dom.wrapper.classList.contains( 'paused' );
+
+	}
+
+	/**
+	 * Steps from the current point in the presentation to the
+	 * slide which matches the specified horizontal and vertical
+	 * indices.
+	 *
+	 * @param {int} h Horizontal index of the target slide
+	 * @param {int} v Vertical index of the target slide
+	 * @param {int} f Optional index of a fragment within the
+	 * target slide to activate
+	 * @param {int} o Optional origin for use in multimaster environments
+	 */
+	function slide( h, v, f, o ) {
+
+		// Remember where we were at before
+		previousSlide = currentSlide;
+
+		// Query all horizontal slides in the deck
+		var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+
+		// If no vertical index is specified and the upcoming slide is a
+		// stack, resume at its previous vertical index
+		if( v === undefined ) {
+			v = getPreviousVerticalIndex( horizontalSlides[ h ] );
+		}
+
+		// If we were on a vertical stack, remember what vertical index
+		// it was on so we can resume at the same position when returning
+		if( previousSlide && previousSlide.parentNode && previousSlide.parentNode.classList.contains( 'stack' ) ) {
+			setPreviousVerticalIndex( previousSlide.parentNode, indexv );
+		}
+
+		// Remember the state before this slide
+		var stateBefore = state.concat();
+
+		// Reset the state array
+		state.length = 0;
+
+		var indexhBefore = indexh || 0,
+			indexvBefore = indexv || 0;
+
+		// Activate and transition to the new slide
+		indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
+		indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
+
+		// Update the visibility of slides now that the indices have changed
+		updateSlidesVisibility();
+
+		layout();
+
+		// Apply the new state
+		stateLoop: for( var i = 0, len = state.length; i < len; i++ ) {
+			// Check if this state existed on the previous slide. If it
+			// did, we will avoid adding it repeatedly
+			for( var j = 0; j < stateBefore.length; j++ ) {
+				if( stateBefore[j] === state[i] ) {
+					stateBefore.splice( j, 1 );
+					continue stateLoop;
+				}
+			}
+
+			document.documentElement.classList.add( state[i] );
+
+			// Dispatch custom event matching the state's name
+			dispatchEvent( state[i] );
+		}
+
+		// Clean up the remains of the previous state
+		while( stateBefore.length ) {
+			document.documentElement.classList.remove( stateBefore.pop() );
+		}
+
+		// If the overview is active, re-activate it to update positions
+		if( isOverview() ) {
+			activateOverview();
+		}
+
+		// Find the current horizontal slide and any possible vertical slides
+		// within it
+		var currentHorizontalSlide = horizontalSlides[ indexh ],
+			currentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' );
+
+		// Store references to the previous and current slides
+		currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;
+
+		// Show fragment, if specified
+		if( typeof f !== 'undefined' ) {
+			navigateFragment( f );
+		}
+
+		// Dispatch an event if the slide changed
+		var slideChanged = ( indexh !== indexhBefore || indexv !== indexvBefore );
+		if( slideChanged ) {
+			dispatchEvent( 'slidechanged', {
+				'indexh': indexh,
+				'indexv': indexv,
+				'previousSlide': previousSlide,
+				'currentSlide': currentSlide,
+				'origin': o
+			} );
+		}
+		else {
+			// Ensure that the previous slide is never the same as the current
+			previousSlide = null;
+		}
+
+		// Solves an edge case where the previous slide maintains the
+		// 'present' class when navigating between adjacent vertical
+		// stacks
+		if( previousSlide ) {
+			previousSlide.classList.remove( 'present' );
+
+			// Reset all slides upon navigate to home
+			// Issue: #285
+			if ( document.querySelector( HOME_SLIDE_SELECTOR ).classList.contains( 'present' ) ) {
+				// Launch async task
+				setTimeout( function () {
+					var slides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.stack') ), i;
+					for( i in slides ) {
+						if( slides[i] ) {
+							// Reset stack
+							setPreviousVerticalIndex( slides[i], 0 );
+						}
+					}
+				}, 0 );
+			}
+		}
+
+		// Handle embedded content
+		if( slideChanged ) {
+			stopEmbeddedContent( previousSlide );
+			startEmbeddedContent( currentSlide );
+		}
+
+		updateControls();
+		updateProgress();
+		updateBackground();
+		updateParallax();
+		updateSlideNumber();
+
+		// Update the URL hash
+		writeURL();
+
+		cueAutoSlide();
+
+	}
+
+	/**
+	 * Syncs the presentation with the current DOM. Useful
+	 * when new slides or control elements are added or when
+	 * the configuration has changed.
+	 */
+	function sync() {
+
+		// Subscribe to input
+		removeEventListeners();
+		addEventListeners();
+
+		// Force a layout to make sure the current config is accounted for
+		layout();
+
+		// Reflect the current autoSlide value
+		autoSlide = config.autoSlide;
+
+		// Start auto-sliding if it's enabled
+		cueAutoSlide();
+
+		// Re-create the slide backgrounds
+		createBackgrounds();
+
+		sortAllFragments();
+
+		updateControls();
+		updateProgress();
+		updateBackground( true );
+		updateSlideNumber();
+
+	}
+
+	/**
+	 * Resets all vertical slides so that only the first
+	 * is visible.
+	 */
+	function resetVerticalSlides() {
+
+		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+		horizontalSlides.forEach( function( horizontalSlide ) {
+
+			var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
+			verticalSlides.forEach( function( verticalSlide, y ) {
+
+				if( y > 0 ) {
+					verticalSlide.classList.remove( 'present' );
+					verticalSlide.classList.remove( 'past' );
+					verticalSlide.classList.add( 'future' );
+				}
+
+			} );
+
+		} );
+
+	}
+
+	/**
+	 * Sorts and formats all of fragments in the
+	 * presentation.
+	 */
+	function sortAllFragments() {
+
+		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+		horizontalSlides.forEach( function( horizontalSlide ) {
+
+			var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
+			verticalSlides.forEach( function( verticalSlide, y ) {
+
+				sortFragments( verticalSlide.querySelectorAll( '.fragment' ) );
+
+			} );
+
+			if( verticalSlides.length === 0 ) sortFragments( horizontalSlide.querySelectorAll( '.fragment' ) );
+
+		} );
+
+	}
+
+	/**
+	 * Updates one dimension of slides by showing the slide
+	 * with the specified index.
+	 *
+	 * @param {String} selector A CSS selector that will fetch
+	 * the group of slides we are working with
+	 * @param {Number} index The index of the slide that should be
+	 * shown
+	 *
+	 * @return {Number} The index of the slide that is now shown,
+	 * might differ from the passed in index if it was out of
+	 * bounds.
+	 */
+	function updateSlides( selector, index ) {
+
+		// Select all slides and convert the NodeList result to
+		// an array
+		var slides = toArray( document.querySelectorAll( selector ) ),
+			slidesLength = slides.length;
+
+		if( slidesLength ) {
+
+			// Should the index loop?
+			if( config.loop ) {
+				index %= slidesLength;
+
+				if( index < 0 ) {
+					index = slidesLength + index;
+				}
+			}
+
+			// Enforce max and minimum index bounds
+			index = Math.max( Math.min( index, slidesLength - 1 ), 0 );
+
+			for( var i = 0; i < slidesLength; i++ ) {
+				var element = slides[i];
+
+				var reverse = config.rtl && !isVerticalSlide( element );
+
+				element.classList.remove( 'past' );
+				element.classList.remove( 'present' );
+				element.classList.remove( 'future' );
+
+				// http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute
+				element.setAttribute( 'hidden', '' );
+
+				if( i < index ) {
+					// Any element previous to index is given the 'past' class
+					element.classList.add( reverse ? 'future' : 'past' );
+
+					var pastFragments = toArray( element.querySelectorAll( '.fragment' ) );
+
+					// Show all fragments on prior slides
+					while( pastFragments.length ) {
+						var pastFragment = pastFragments.pop();
+						pastFragment.classList.add( 'visible' );
+						pastFragment.classList.remove( 'current-fragment' );
+					}
+				}
+				else if( i > index ) {
+					// Any element subsequent to index is given the 'future' class
+					element.classList.add( reverse ? 'past' : 'future' );
+
+					var futureFragments = toArray( element.querySelectorAll( '.fragment.visible' ) );
+
+					// No fragments in future slides should be visible ahead of time
+					while( futureFragments.length ) {
+						var futureFragment = futureFragments.pop();
+						futureFragment.classList.remove( 'visible' );
+						futureFragment.classList.remove( 'current-fragment' );
+					}
+				}
+
+				// If this element contains vertical slides
+				if( element.querySelector( 'section' ) ) {
+					element.classList.add( 'stack' );
+				}
+			}
+
+			// Mark the current slide as present
+			slides[index].classList.add( 'present' );
+			slides[index].removeAttribute( 'hidden' );
+
+			// If this slide has a state associated with it, add it
+			// onto the current state of the deck
+			var slideState = slides[index].getAttribute( 'data-state' );
+			if( slideState ) {
+				state = state.concat( slideState.split( ' ' ) );
+			}
+
+		}
+		else {
+			// Since there are no slides we can't be anywhere beyond the
+			// zeroth index
+			index = 0;
+		}
+
+		return index;
+
+	}
+
+	/**
+	 * Optimization method; hide all slides that are far away
+	 * from the present slide.
+	 */
+	function updateSlidesVisibility() {
+
+		// Select all slides and convert the NodeList result to
+		// an array
+		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ),
+			horizontalSlidesLength = horizontalSlides.length,
+			distanceX,
+			distanceY;
+
+		if( horizontalSlidesLength ) {
+
+			// The number of steps away from the present slide that will
+			// be visible
+			var viewDistance = isOverview() ? 10 : config.viewDistance;
+
+			// Limit view distance on weaker devices
+			if( isMobileDevice ) {
+				viewDistance = isOverview() ? 6 : 1;
+			}
+
+			for( var x = 0; x < horizontalSlidesLength; x++ ) {
+				var horizontalSlide = horizontalSlides[x];
+
+				var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ),
+					verticalSlidesLength = verticalSlides.length;
+
+				// Loops so that it measures 1 between the first and last slides
+				distanceX = Math.abs( ( indexh - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;
+
+				// Show the horizontal slide if it's within the view distance
+				horizontalSlide.style.display = distanceX > viewDistance ? 'none' : 'block';
+
+				if( verticalSlidesLength ) {
+
+					var oy = getPreviousVerticalIndex( horizontalSlide );
+
+					for( var y = 0; y < verticalSlidesLength; y++ ) {
+						var verticalSlide = verticalSlides[y];
+
+						distanceY = x === indexh ? Math.abs( indexv - y ) : Math.abs( y - oy );
+
+						verticalSlide.style.display = ( distanceX + distanceY ) > viewDistance ? 'none' : 'block';
+					}
+
+				}
+			}
+
+		}
+
+	}
+
+	/**
+	 * Updates the progress bar to reflect the current slide.
+	 */
+	function updateProgress() {
+
+		// Update progress if enabled
+		if( config.progress && dom.progress ) {
+
+			var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+
+			// The number of past and total slides
+			var totalCount = document.querySelectorAll( SLIDES_SELECTOR + ':not(.stack)' ).length;
+			var pastCount = 0;
+
+			// Step through all slides and count the past ones
+			mainLoop: for( var i = 0; i < horizontalSlides.length; i++ ) {
+
+				var horizontalSlide = horizontalSlides[i];
+				var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
+
+				for( var j = 0; j < verticalSlides.length; j++ ) {
+
+					// Stop as soon as we arrive at the present
+					if( verticalSlides[j].classList.contains( 'present' ) ) {
+						break mainLoop;
+					}
+
+					pastCount++;
+
+				}
+
+				// Stop as soon as we arrive at the present
+				if( horizontalSlide.classList.contains( 'present' ) ) {
+					break;
+				}
+
+				// Don't count the wrapping section for vertical slides
+				if( horizontalSlide.classList.contains( 'stack' ) === false ) {
+					pastCount++;
+				}
+
+			}
+
+			dom.progressbar.style.width = ( pastCount / ( totalCount - 1 ) ) * window.innerWidth + 'px';
+
+		}
+
+	}
+
+	/**
+	 * Updates the slide number div to reflect the current slide.
+	 */
+	function updateSlideNumber() {
+
+		// Update slide number if enabled
+		if( config.slideNumber && dom.slideNumber) {
+
+			// Display the number of the page using 'indexh - indexv' format
+			var indexString = indexh;
+			if( indexv > 0 ) {
+				indexString += ' - ' + indexv;
+			}
+
+			dom.slideNumber.innerHTML = indexString;
+		}
+
+	}
+
+	/**
+	 * Updates the state of all control/navigation arrows.
+	 */
+	function updateControls() {
+
+		var routes = availableRoutes();
+		var fragments = availableFragments();
+
+		// Remove the 'enabled' class from all directions
+		dom.controlsLeft.concat( dom.controlsRight )
+						.concat( dom.controlsUp )
+						.concat( dom.controlsDown )
+						.concat( dom.controlsPrev )
+						.concat( dom.controlsNext ).forEach( function( node ) {
+			node.classList.remove( 'enabled' );
+			node.classList.remove( 'fragmented' );
+		} );
+
+		// Add the 'enabled' class to the available routes
+		if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' );	} );
+		if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); } );
+		if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' );	} );
+		if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); } );
+
+		// Prev/next buttons
+		if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); } );
+		if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); } );
+
+		// Highlight fragment directions
+		if( currentSlide ) {
+
+			// Always apply fragment decorator to prev/next buttons
+			if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+			if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+
+			// Apply fragment decorators to directional buttons based on
+			// what slide axis they are in
+			if( isVerticalSlide( currentSlide ) ) {
+				if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+				if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+			}
+			else {
+				if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+				if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
+			}
+
+		}
+
+	}
+
+	/**
+	 * Updates the background elements to reflect the current
+	 * slide.
+	 *
+	 * @param {Boolean} includeAll If true, the backgrounds of
+	 * all vertical slides (not just the present) will be updated.
+	 */
+	function updateBackground( includeAll ) {
+
+		var currentBackground = null;
+
+		// Reverse past/future classes when in RTL mode
+		var horizontalPast = config.rtl ? 'future' : 'past',
+			horizontalFuture = config.rtl ? 'past' : 'future';
+
+		// Update the classes of all backgrounds to match the
+		// states of their slides (past/present/future)
+		toArray( dom.background.childNodes ).forEach( function( backgroundh, h ) {
+
+			if( h < indexh ) {
+				backgroundh.className = 'slide-background ' + horizontalPast;
+			}
+			else if ( h > indexh ) {
+				backgroundh.className = 'slide-background ' + horizontalFuture;
+			}
+			else {
+				backgroundh.className = 'slide-background present';
+
+				// Store a reference to the current background element
+				currentBackground = backgroundh;
+			}
+
+			if( includeAll || h === indexh ) {
+				toArray( backgroundh.childNodes ).forEach( function( backgroundv, v ) {
+
+					if( v < indexv ) {
+						backgroundv.className = 'slide-background past';
+					}
+					else if ( v > indexv ) {
+						backgroundv.className = 'slide-background future';
+					}
+					else {
+						backgroundv.className = 'slide-background present';
+
+						// Only if this is the present horizontal and vertical slide
+						if( h === indexh ) currentBackground = backgroundv;
+					}
+
+				} );
+			}
+
+		} );
+
+		// Don't transition between identical backgrounds. This
+		// prevents unwanted flicker.
+		if( currentBackground ) {
+			var previousBackgroundHash = previousBackground ? previousBackground.getAttribute( 'data-background-hash' ) : null;
+			var currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
+			if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== previousBackground ) {
+				dom.background.classList.add( 'no-transition' );
+			}
+
+			previousBackground = currentBackground;
+		}
+
+		// Allow the first background to apply without transition
+		setTimeout( function() {
+			dom.background.classList.remove( 'no-transition' );
+		}, 1 );
+
+	}
+
+	/**
+	 * Updates the position of the parallax background based
+	 * on the current slide index.
+	 */
+	function updateParallax() {
+
+		if( config.parallaxBackgroundImage ) {
+
+			var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
+				verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
+
+			var backgroundSize = dom.background.style.backgroundSize.split( ' ' ),
+				backgroundWidth, backgroundHeight;
+
+			if( backgroundSize.length === 1 ) {
+				backgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );
+			}
+			else {
+				backgroundWidth = parseInt( backgroundSize[0], 10 );
+				backgroundHeight = parseInt( backgroundSize[1], 10 );
+			}
+
+			var slideWidth = dom.background.offsetWidth;
+			var horizontalSlideCount = horizontalSlides.length;
+			var horizontalOffset = -( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) * indexh;
+
+			var slideHeight = dom.background.offsetHeight;
+			var verticalSlideCount = verticalSlides.length;
+			var verticalOffset = verticalSlideCount > 0 ? -( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 ) * indexv : 0;
+
+			dom.background.style.backgroundPosition = horizontalOffset + 'px ' + verticalOffset + 'px';
+
+		}
+
+	}
+
+	/**
+	 * Determine what available routes there are for navigation.
+	 *
+	 * @return {Object} containing four booleans: left/right/up/down
+	 */
+	function availableRoutes() {
+
+		var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
+			verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
+
+		var routes = {
+			left: indexh > 0 || config.loop,
+			right: indexh < horizontalSlides.length - 1 || config.loop,
+			up: indexv > 0,
+			down: indexv < verticalSlides.length - 1
+		};
+
+		// reverse horizontal controls for rtl
+		if( config.rtl ) {
+			var left = routes.left;
+			routes.left = routes.right;
+			routes.right = left;
+		}
+
+		return routes;
+
+	}
+
+	/**
+	 * Returns an object describing the available fragment
+	 * directions.
+	 *
+	 * @return {Object} two boolean properties: prev/next
+	 */
+	function availableFragments() {
+
+		if( currentSlide && config.fragments ) {
+			var fragments = currentSlide.querySelectorAll( '.fragment' );
+			var hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.visible)' );
+
+			return {
+				prev: fragments.length - hiddenFragments.length > 0,
+				next: !!hiddenFragments.length
+			};
+		}
+		else {
+			return { prev: false, next: false };
+		}
+
+	}
+
+	/**
+	 * Start playback of any embedded content inside of
+	 * the targeted slide.
+	 */
+	function startEmbeddedContent( slide ) {
+
+		if( slide && !isSpeakerNotes() ) {
+			// HTML5 media elements
+			toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
+				if( el.hasAttribute( 'data-autoplay' ) ) {
+					el.play();
+				}
+			} );
+
+			// iframe embeds
+			toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
+				el.contentWindow.postMessage( 'slide:start', '*' );
+			});
+
+			// YouTube embeds
+			toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
+				if( el.hasAttribute( 'data-autoplay' ) ) {
+					el.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
+				}
+			});
+		}
+
+	}
+
+	/**
+	 * Stop playback of any embedded content inside of
+	 * the targeted slide.
+	 */
+	function stopEmbeddedContent( slide ) {
+
+		if( slide ) {
+			// HTML5 media elements
+			toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
+				if( !el.hasAttribute( 'data-ignore' ) ) {
+					el.pause();
+				}
+			} );
+
+			// iframe embeds
+			toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
+				el.contentWindow.postMessage( 'slide:stop', '*' );
+			});
+
+			// YouTube embeds
+			toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
+				if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
+					el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
+				}
+			});
+		}
+
+	}
+
+	/**
+	 * Checks if this presentation is running inside of the
+	 * speaker notes window.
+	 */
+	function isSpeakerNotes() {
+
+		return !!window.location.search.match( /receiver/gi );
+
+	}
+
+	/**
+	 * Reads the current URL (hash) and navigates accordingly.
+	 */
+	function readURL() {
+
+		var hash = window.location.hash;
+
+		// Attempt to parse the hash as either an index or name
+		var bits = hash.slice( 2 ).split( '/' ),
+			name = hash.replace( /#|\//gi, '' );
+
+		// If the first bit is invalid and there is a name we can
+		// assume that this is a named link
+		if( isNaN( parseInt( bits[0], 10 ) ) && name.length ) {
+			// Find the slide with the specified name
+			var element = document.querySelector( '#' + name );
+
+			if( element ) {
+				// Find the position of the named slide and navigate to it
+				var indices = Reveal.getIndices( element );
+				slide( indices.h, indices.v );
+			}
+			// If the slide doesn't exist, navigate to the current slide
+			else {
+				slide( indexh || 0, indexv || 0 );
+			}
+		}
+		else {
+			// Read the index components of the hash
+			var h = parseInt( bits[0], 10 ) || 0,
+				v = parseInt( bits[1], 10 ) || 0;
+
+			if( h !== indexh || v !== indexv ) {
+				slide( h, v );
+			}
+		}
+
+	}
+
+	/**
+	 * Updates the page URL (hash) to reflect the current
+	 * state.
+	 *
+	 * @param {Number} delay The time in ms to wait before
+	 * writing the hash
+	 */
+	function writeURL( delay ) {
+
+		if( config.history ) {
+
+			// Make sure there's never more than one timeout running
+			clearTimeout( writeURLTimeout );
+
+			// If a delay is specified, timeout this call
+			if( typeof delay === 'number' ) {
+				writeURLTimeout = setTimeout( writeURL, delay );
+			}
+			else {
+				var url = '/';
+
+				// If the current slide has an ID, use that as a named link
+				if( currentSlide && typeof currentSlide.getAttribute( 'id' ) === 'string' ) {
+					url = '/' + currentSlide.getAttribute( 'id' );
+				}
+				// Otherwise use the /h/v index
+				else {
+					if( indexh > 0 || indexv > 0 ) url += indexh;
+					if( indexv > 0 ) url += '/' + indexv;
+				}
+
+				window.location.hash = url;
+			}
+		}
+
+	}
+
+	/**
+	 * Retrieves the h/v location of the current, or specified,
+	 * slide.
+	 *
+	 * @param {HTMLElement} slide If specified, the returned
+	 * index will be for this slide rather than the currently
+	 * active one
+	 *
+	 * @return {Object} { h: <int>, v: <int>, f: <int> }
+	 */
+	function getIndices( slide ) {
+
+		// By default, return the current indices
+		var h = indexh,
+			v = indexv,
+			f;
+
+		// If a slide is specified, return the indices of that slide
+		if( slide ) {
+			var isVertical = isVerticalSlide( slide );
+			var slideh = isVertical ? slide.parentNode : slide;
+
+			// Select all horizontal slides
+			var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+
+			// Now that we know which the horizontal slide is, get its index
+			h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
+
+			// If this is a vertical slide, grab the vertical index
+			if( isVertical ) {
+				v = Math.max( toArray( slide.parentNode.querySelectorAll( 'section' ) ).indexOf( slide ), 0 );
+			}
+		}
+
+		if( !slide && currentSlide ) {
+			var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;
+			if( hasFragments ) {
+				var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );
+				f = visibleFragments.length - 1;
+			}
+		}
+
+		return { h: h, v: v, f: f };
+
+	}
+
+	/**
+	 * Return a sorted fragments list, ordered by an increasing
+	 * "data-fragment-index" attribute.
+	 *
+	 * Fragments will be revealed in the order that they are returned by
+	 * this function, so you can use the index attributes to control the
+	 * order of fragment appearance.
+	 *
+	 * To maintain a sensible default fragment order, fragments are presumed
+	 * to be passed in document order. This function adds a "fragment-index"
+	 * attribute to each node if such an attribute is not already present,
+	 * and sets that attribute to an integer value which is the position of
+	 * the fragment within the fragments list.
+	 */
+	function sortFragments( fragments ) {
+
+		fragments = toArray( fragments );
+
+		var ordered = [],
+			unordered = [],
+			sorted = [];
+
+		// Group ordered and unordered elements
+		fragments.forEach( function( fragment, i ) {
+			if( fragment.hasAttribute( 'data-fragment-index' ) ) {
+				var index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );
+
+				if( !ordered[index] ) {
+					ordered[index] = [];
+				}
+
+				ordered[index].push( fragment );
+			}
+			else {
+				unordered.push( [ fragment ] );
+			}
+		} );
+
+		// Append fragments without explicit indices in their
+		// DOM order
+		ordered = ordered.concat( unordered );
+
+		// Manually count the index up per group to ensure there
+		// are no gaps
+		var index = 0;
+
+		// Push all fragments in their sorted order to an array,
+		// this flattens the groups
+		ordered.forEach( function( group ) {
+			group.forEach( function( fragment ) {
+				sorted.push( fragment );
+				fragment.setAttribute( 'data-fragment-index', index );
+			} );
+
+			index ++;
+		} );
+
+		return sorted;
+
+	}
+
+	/**
+	 * Navigate to the specified slide fragment.
+	 *
+	 * @param {Number} index The index of the fragment that
+	 * should be shown, -1 means all are invisible
+	 * @param {Number} offset Integer offset to apply to the
+	 * fragment index
+	 *
+	 * @return {Boolean} true if a change was made in any
+	 * fragments visibility as part of this call
+	 */
+	function navigateFragment( index, offset ) {
+
+		if( currentSlide && config.fragments ) {
+
+			var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) );
+			if( fragments.length ) {
+
+				// If no index is specified, find the current
+				if( typeof index !== 'number' ) {
+					var lastVisibleFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
+
+					if( lastVisibleFragment ) {
+						index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
+					}
+					else {
+						index = -1;
+					}
+				}
+
+				// If an offset is specified, apply it to the index
+				if( typeof offset === 'number' ) {
+					index += offset;
+				}
+
+				var fragmentsShown = [],
+					fragmentsHidden = [];
+
+				toArray( fragments ).forEach( function( element, i ) {
+
+					if( element.hasAttribute( 'data-fragment-index' ) ) {
+						i = parseInt( element.getAttribute( 'data-fragment-index' ), 10 );
+					}
+
+					// Visible fragments
+					if( i <= index ) {
+						if( !element.classList.contains( 'visible' ) ) fragmentsShown.push( element );
+						element.classList.add( 'visible' );
+						element.classList.remove( 'current-fragment' );
+
+						if( i === index ) {
+							element.classList.add( 'current-fragment' );
+						}
+					}
+					// Hidden fragments
+					else {
+						if( element.classList.contains( 'visible' ) ) fragmentsHidden.push( element );
+						element.classList.remove( 'visible' );
+						element.classList.remove( 'current-fragment' );
+					}
+
+
+				} );
+
+				if( fragmentsHidden.length ) {
+					dispatchEvent( 'fragmenthidden', { fragment: fragmentsHidden[0], fragments: fragmentsHidden } );
+				}
+
+				if( fragmentsShown.length ) {
+					dispatchEvent( 'fragmentshown', { fragment: fragmentsShown[0], fragments: fragmentsShown } );
+				}
+
+				updateControls();
+
+				return !!( fragmentsShown.length || fragmentsHidden.length );
+
+			}
+
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Navigate to the next slide fragment.
+	 *
+	 * @return {Boolean} true if there was a next fragment,
+	 * false otherwise
+	 */
+	function nextFragment() {
+
+		return navigateFragment( null, 1 );
+
+	}
+
+	/**
+	 * Navigate to the previous slide fragment.
+	 *
+	 * @return {Boolean} true if there was a previous fragment,
+	 * false otherwise
+	 */
+	function previousFragment() {
+
+		return navigateFragment( null, -1 );
+
+	}
+
+	/**
+	 * Cues a new automated slide if enabled in the config.
+	 */
+	function cueAutoSlide() {
+
+		cancelAutoSlide();
+
+		if( currentSlide ) {
+
+			var parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;
+			var slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );
+
+			// Pick value in the following priority order:
+			// 1. Current slide's data-autoslide
+			// 2. Parent slide's data-autoslide
+			// 3. Global autoSlide setting
+			if( slideAutoSlide ) {
+				autoSlide = parseInt( slideAutoSlide, 10 );
+			}
+			else if( parentAutoSlide ) {
+				autoSlide = parseInt( parentAutoSlide, 10 );
+			}
+			else {
+				autoSlide = config.autoSlide;
+			}
+
+			// If there are media elements with data-autoplay,
+			// automatically set the autoSlide duration to the
+			// length of that media
+			toArray( currentSlide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
+				if( el.hasAttribute( 'data-autoplay' ) ) {
+					if( autoSlide && el.duration * 1000 > autoSlide ) {
+						autoSlide = ( el.duration * 1000 ) + 1000;
+					}
+				}
+			} );
+
+			// Cue the next auto-slide if:
+			// - There is an autoSlide value
+			// - Auto-sliding isn't paused by the user
+			// - The presentation isn't paused
+			// - The overview isn't active
+			// - The presentation isn't over
+			if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || config.loop === true ) ) {
+				autoSlideTimeout = setTimeout( navigateNext, autoSlide );
+				autoSlideStartTime = Date.now();
+			}
+
+			if( autoSlidePlayer ) {
+				autoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );
+			}
+
+		}
+
+	}
+
+	/**
+	 * Cancels any ongoing request to auto-slide.
+	 */
+	function cancelAutoSlide() {
+
+		clearTimeout( autoSlideTimeout );
+		autoSlideTimeout = -1;
+
+	}
+
+	function pauseAutoSlide() {
+
+		autoSlidePaused = true;
+		clearTimeout( autoSlideTimeout );
+
+		if( autoSlidePlayer ) {
+			autoSlidePlayer.setPlaying( false );
+		}
+
+	}
+
+	function resumeAutoSlide() {
+
+		autoSlidePaused = false;
+		cueAutoSlide();
+
+	}
+
+	function navigateLeft() {
+
+		// Reverse for RTL
+		if( config.rtl ) {
+			if( ( isOverview() || nextFragment() === false ) && availableRoutes().left ) {
+				slide( indexh + 1 );
+			}
+		}
+		// Normal navigation
+		else if( ( isOverview() || previousFragment() === false ) && availableRoutes().left ) {
+			slide( indexh - 1 );
+		}
+
+	}
+
+	function navigateRight() {
+
+		// Reverse for RTL
+		if( config.rtl ) {
+			if( ( isOverview() || previousFragment() === false ) && availableRoutes().right ) {
+				slide( indexh - 1 );
+			}
+		}
+		// Normal navigation
+		else if( ( isOverview() || nextFragment() === false ) && availableRoutes().right ) {
+			slide( indexh + 1 );
+		}
+
+	}
+
+	function navigateUp() {
+
+		// Prioritize hiding fragments
+		if( ( isOverview() || previousFragment() === false ) && availableRoutes().up ) {
+			slide( indexh, indexv - 1 );
+		}
+
+	}
+
+	function navigateDown() {
+
+		// Prioritize revealing fragments
+		if( ( isOverview() || nextFragment() === false ) && availableRoutes().down ) {
+			slide( indexh, indexv + 1 );
+		}
+
+	}
+
+	/**
+	 * Navigates backwards, prioritized in the following order:
+	 * 1) Previous fragment
+	 * 2) Previous vertical slide
+	 * 3) Previous horizontal slide
+	 */
+	function navigatePrev() {
+
+		// Prioritize revealing fragments
+		if( previousFragment() === false ) {
+			if( availableRoutes().up ) {
+				navigateUp();
+			}
+			else {
+				// Fetch the previous horizontal slide, if there is one
+				var previousSlide = document.querySelector( HORIZONTAL_SLIDES_SELECTOR + '.past:nth-child(' + indexh + ')' );
+
+				if( previousSlide ) {
+					var v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined;
+					var h = indexh - 1;
+					slide( h, v );
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * Same as #navigatePrev() but navigates forwards.
+	 */
+	function navigateNext() {
+
+		// Prioritize revealing fragments
+		if( nextFragment() === false ) {
+			availableRoutes().down ? navigateDown() : navigateRight();
+		}
+
+		// If auto-sliding is enabled we need to cue up
+		// another timeout
+		cueAutoSlide();
+
+	}
+
+
+	// --------------------------------------------------------------------//
+	// ----------------------------- EVENTS -------------------------------//
+	// --------------------------------------------------------------------//
+
+	/**
+	 * Called by all event handlers that are based on user
+	 * input.
+	 */
+	function onUserInput( event ) {
+
+		if( config.autoSlideStoppable ) {
+			pauseAutoSlide();
+		}
+
+	}
+
+	/**
+	 * Handler for the document level 'keydown' event.
+	 */
+	function onDocumentKeyDown( event ) {
+
+		onUserInput( event );
+
+		// Check if there's a focused element that could be using
+		// the keyboard
+		var activeElement = document.activeElement;
+		var hasFocus = !!( document.activeElement && ( document.activeElement.type || document.activeElement.href || document.activeElement.contentEditable !== 'inherit' ) );
+
+		// Disregard the event if there's a focused element or a
+		// keyboard modifier key is present
+		if( hasFocus || (event.shiftKey && event.keyCode !== 32) || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		// While paused only allow "unpausing" keyboard events (b and .)
+		if( isPaused() && [66,190,191].indexOf( event.keyCode ) === -1 ) {
+			return false;
+		}
+
+		var triggered = false;
+
+		// 1. User defined key bindings
+		if( typeof config.keyboard === 'object' ) {
+
+			for( var key in config.keyboard ) {
+
+				// Check if this binding matches the pressed key
+				if( parseInt( key, 10 ) === event.keyCode ) {
+
+					var value = config.keyboard[ key ];
+
+					// Callback function
+					if( typeof value === 'function' ) {
+						value.apply( null, [ event ] );
+					}
+					// String shortcuts to reveal.js API
+					else if( typeof value === 'string' && typeof Reveal[ value ] === 'function' ) {
+						Reveal[ value ].call();
+					}
+
+					triggered = true;
+
+				}
+
+			}
+
+		}
+
+		// 2. System defined key bindings
+		if( triggered === false ) {
+
+			// Assume true and try to prove false
+			triggered = true;
+
+			switch( event.keyCode ) {
+				// p, page up
+				case 80: case 33: navigatePrev(); break;
+				// n, page down
+				case 78: case 34: navigateNext(); break;
+				// h, left
+				case 72: case 37: navigateLeft(); break;
+				// l, right
+				case 76: case 39: navigateRight(); break;
+				// k, up
+				case 75: case 38: navigateUp(); break;
+				// j, down
+				case 74: case 40: navigateDown(); break;
+				// home
+				case 36: slide( 0 ); break;
+				// end
+				case 35: slide( Number.MAX_VALUE ); break;
+				// space
+				case 32: isOverview() ? deactivateOverview() : event.shiftKey ? navigatePrev() : navigateNext(); break;
+				// return
+				case 13: isOverview() ? deactivateOverview() : triggered = false; break;
+				// b, period, Logitech presenter tools "black screen" button
+				case 66: case 190: case 191: togglePause(); break;
+				// f
+				case 70: enterFullscreen(); break;
+				default:
+					triggered = false;
+			}
+
+		}
+
+		// If the input resulted in a triggered action we should prevent
+		// the browsers default behavior
+		if( triggered ) {
+			event.preventDefault();
+		}
+		// ESC or O key
+		else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && features.transforms3d ) {
+			if( dom.preview ) {
+				closePreview();
+			}
+			else {
+				toggleOverview();
+			}
+
+			event.preventDefault();
+		}
+
+		// If auto-sliding is enabled we need to cue up
+		// another timeout
+		cueAutoSlide();
+
+	}
+
+	/**
+	 * Handler for the 'touchstart' event, enables support for
+	 * swipe and pinch gestures.
+	 */
+	function onTouchStart( event ) {
+
+		touch.startX = event.touches[0].clientX;
+		touch.startY = event.touches[0].clientY;
+		touch.startCount = event.touches.length;
+
+		// If there's two touches we need to memorize the distance
+		// between those two points to detect pinching
+		if( event.touches.length === 2 && config.overview ) {
+			touch.startSpan = distanceBetween( {
+				x: event.touches[1].clientX,
+				y: event.touches[1].clientY
+			}, {
+				x: touch.startX,
+				y: touch.startY
+			} );
+		}
+
+	}
+
+	/**
+	 * Handler for the 'touchmove' event.
+	 */
+	function onTouchMove( event ) {
+
+		// Each touch should only trigger one action
+		if( !touch.captured ) {
+			onUserInput( event );
+
+			var currentX = event.touches[0].clientX;
+			var currentY = event.touches[0].clientY;
+
+			// If the touch started with two points and still has
+			// two active touches; test for the pinch gesture
+			if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) {
+
+				// The current distance in pixels between the two touch points
+				var currentSpan = distanceBetween( {
+					x: event.touches[1].clientX,
+					y: event.touches[1].clientY
+				}, {
+					x: touch.startX,
+					y: touch.startY
+				} );
+
+				// If the span is larger than the desire amount we've got
+				// ourselves a pinch
+				if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
+					touch.captured = true;
+
+					if( currentSpan < touch.startSpan ) {
+						activateOverview();
+					}
+					else {
+						deactivateOverview();
+					}
+				}
+
+				event.preventDefault();
+
+			}
+			// There was only one touch point, look for a swipe
+			else if( event.touches.length === 1 && touch.startCount !== 2 ) {
+
+				var deltaX = currentX - touch.startX,
+					deltaY = currentY - touch.startY;
+
+				if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					touch.captured = true;
+					navigateLeft();
+				}
+				else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					touch.captured = true;
+					navigateRight();
+				}
+				else if( deltaY > touch.threshold ) {
+					touch.captured = true;
+					navigateUp();
+				}
+				else if( deltaY < -touch.threshold ) {
+					touch.captured = true;
+					navigateDown();
+				}
+
+				// If we're embedded, only block touch events if they have
+				// triggered an action
+				if( config.embedded ) {
+					if( touch.captured || isVerticalSlide( currentSlide ) ) {
+						event.preventDefault();
+					}
+				}
+				// Not embedded? Block them all to avoid needless tossing
+				// around of the viewport in iOS
+				else {
+					event.preventDefault();
+				}
+
+			}
+		}
+		// There's a bug with swiping on some Android devices unless
+		// the default action is always prevented
+		else if( navigator.userAgent.match( /android/gi ) ) {
+			event.preventDefault();
+		}
+
+	}
+
+	/**
+	 * Handler for the 'touchend' event.
+	 */
+	function onTouchEnd( event ) {
+
+		touch.captured = false;
+
+	}
+
+	/**
+	 * Convert pointer down to touch start.
+	 */
+	function onPointerDown( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			onTouchStart( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer move to touch move.
+	 */
+	function onPointerMove( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			onTouchMove( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer up to touch end.
+	 */
+	function onPointerUp( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			onTouchEnd( event );
+		}
+
+	}
+
+	/**
+	 * Handles mouse wheel scrolling, throttled to avoid skipping
+	 * multiple slides.
+	 */
+	function onDocumentMouseScroll( event ) {
+
+		if( Date.now() - lastMouseWheelStep > 600 ) {
+
+			lastMouseWheelStep = Date.now();
+
+			var delta = event.detail || -event.wheelDelta;
+			if( delta > 0 ) {
+				navigateNext();
+			}
+			else {
+				navigatePrev();
+			}
+
+		}
+
+	}
+
+	/**
+	 * Clicking on the progress bar results in a navigation to the
+	 * closest approximate horizontal slide using this equation:
+	 *
+	 * ( clickX / presentationWidth ) * numberOfSlides
+	 */
+	function onProgressClicked( event ) {
+
+		onUserInput( event );
+
+		event.preventDefault();
+
+		var slidesTotal = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).length;
+		var slideIndex = Math.floor( ( event.clientX / dom.wrapper.offsetWidth ) * slidesTotal );
+
+		slide( slideIndex );
+
+	}
+
+	/**
+	 * Event handler for navigation control buttons.
+	 */
+	function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); navigateLeft(); }
+	function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); navigateRight(); }
+	function onNavigateUpClicked( event ) { event.preventDefault(); onUserInput(); navigateUp(); }
+	function onNavigateDownClicked( event ) { event.preventDefault(); onUserInput(); navigateDown(); }
+	function onNavigatePrevClicked( event ) { event.preventDefault(); onUserInput(); navigatePrev(); }
+	function onNavigateNextClicked( event ) { event.preventDefault(); onUserInput(); navigateNext(); }
+
+	/**
+	 * Handler for the window level 'hashchange' event.
+	 */
+	function onWindowHashChange( event ) {
+
+		readURL();
+
+	}
+
+	/**
+	 * Handler for the window level 'resize' event.
+	 */
+	function onWindowResize( event ) {
+
+		layout();
+
+	}
+
+	/**
+	 * Handle for the window level 'visibilitychange' event.
+	 */
+	function onPageVisibilityChange( event ) {
+
+		var isHidden =  document.webkitHidden ||
+						document.msHidden ||
+						document.hidden;
+
+		// If, after clicking a link or similar and we're coming back,
+		// focus the document.body to ensure we can use keyboard shortcuts
+		if( isHidden === false && document.activeElement !== document.body ) {
+			document.activeElement.blur();
+			document.body.focus();
+		}
+
+	}
+
+	/**
+	 * Invoked when a slide is and we're in the overview.
+	 */
+	function onOverviewSlideClicked( event ) {
+
+		// TODO There's a bug here where the event listeners are not
+		// removed after deactivating the overview.
+		if( eventsAreBound && isOverview() ) {
+			event.preventDefault();
+
+			var element = event.target;
+
+			while( element && !element.nodeName.match( /section/gi ) ) {
+				element = element.parentNode;
+			}
+
+			if( element && !element.classList.contains( 'disabled' ) ) {
+
+				deactivateOverview();
+
+				if( element.nodeName.match( /section/gi ) ) {
+					var h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),
+						v = parseInt( element.getAttribute( 'data-index-v' ), 10 );
+
+					slide( h, v );
+				}
+
+			}
+		}
+
+	}
+
+	/**
+	 * Handles clicks on links that are set to preview in the
+	 * iframe overlay.
+	 */
+	function onPreviewLinkClicked( event ) {
+
+		var url = event.target.getAttribute( 'href' );
+		if( url ) {
+			openPreview( url );
+			event.preventDefault();
+		}
+
+	}
+
+	/**
+	 * Handles click on the auto-sliding controls element.
+	 */
+	function onAutoSlidePlayerClick( event ) {
+
+		// Replay
+		if( Reveal.isLastSlide() && config.loop === false ) {
+			slide( 0, 0 );
+			resumeAutoSlide();
+		}
+		// Resume
+		else if( autoSlidePaused ) {
+			resumeAutoSlide();
+		}
+		// Pause
+		else {
+			pauseAutoSlide();
+		}
+
+	}
+
+
+	// --------------------------------------------------------------------//
+	// ------------------------ PLAYBACK COMPONENT ------------------------//
+	// --------------------------------------------------------------------//
+
+
+	/**
+	 * Constructor for the playback component, which displays
+	 * play/pause/progress controls.
+	 *
+	 * @param {HTMLElement} container The component will append
+	 * itself to this
+	 * @param {Function} progressCheck A method which will be
+	 * called frequently to get the current progress on a range
+	 * of 0-1
+	 */
+	function Playback( container, progressCheck ) {
+
+		// Cosmetics
+		this.diameter = 50;
+		this.thickness = 3;
+
+		// Flags if we are currently playing
+		this.playing = false;
+
+		// Current progress on a 0-1 range
+		this.progress = 0;
+
+		// Used to loop the animation smoothly
+		this.progressOffset = 1;
+
+		this.container = container;
+		this.progressCheck = progressCheck;
+
+		this.canvas = document.createElement( 'canvas' );
+		this.canvas.className = 'playback';
+		this.canvas.width = this.diameter;
+		this.canvas.height = this.diameter;
+		this.context = this.canvas.getContext( '2d' );
+
+		this.container.appendChild( this.canvas );
+
+		this.render();
+
+	}
+
+	Playback.prototype.setPlaying = function( value ) {
+
+		var wasPlaying = this.playing;
+
+		this.playing = value;
+
+		// Start repainting if we weren't already
+		if( !wasPlaying && this.playing ) {
+			this.animate();
+		}
+		else {
+			this.render();
+		}
+
+	};
+
+	Playback.prototype.animate = function() {
+
+		var progressBefore = this.progress;
+
+		this.progress = this.progressCheck();
+
+		// When we loop, offset the progress so that it eases
+		// smoothly rather than immediately resetting
+		if( progressBefore > 0.8 && this.progress < 0.2 ) {
+			this.progressOffset = this.progress;
+		}
+
+		this.render();
+
+		if( this.playing ) {
+			features.requestAnimationFrameMethod.call( window, this.animate.bind( this ) );
+		}
+
+	};
+
+	/**
+	 * Renders the current progress and playback state.
+	 */
+	Playback.prototype.render = function() {
+
+		var progress = this.playing ? this.progress : 0,
+			radius = ( this.diameter / 2 ) - this.thickness,
+			x = this.diameter / 2,
+			y = this.diameter / 2,
+			iconSize = 14;
+
+		// Ease towards 1
+		this.progressOffset += ( 1 - this.progressOffset ) * 0.1;
+
+		var endAngle = ( - Math.PI / 2 ) + ( progress * ( Math.PI * 2 ) );
+		var startAngle = ( - Math.PI / 2 ) + ( this.progressOffset * ( Math.PI * 2 ) );
+
+		this.context.save();
+		this.context.clearRect( 0, 0, this.diameter, this.diameter );
+
+		// Solid background color
+		this.context.beginPath();
+		this.context.arc( x, y, radius + 2, 0, Math.PI * 2, false );
+		this.context.fillStyle = 'rgba( 0, 0, 0, 0.4 )';
+		this.context.fill();
+
+		// Draw progress track
+		this.context.beginPath();
+		this.context.arc( x, y, radius, 0, Math.PI * 2, false );
+		this.context.lineWidth = this.thickness;
+		this.context.strokeStyle = '#666';
+		this.context.stroke();
+
+		if( this.playing ) {
+			// Draw progress on top of track
+			this.context.beginPath();
+			this.context.arc( x, y, radius, startAngle, endAngle, false );
+			this.context.lineWidth = this.thickness;
+			this.context.strokeStyle = '#fff';
+			this.context.stroke();
+		}
+
+		this.context.translate( x - ( iconSize / 2 ), y - ( iconSize / 2 ) );
+
+		// Draw play/pause icons
+		if( this.playing ) {
+			this.context.fillStyle = '#fff';
+			this.context.fillRect( 0, 0, iconSize / 2 - 2, iconSize );
+			this.context.fillRect( iconSize / 2 + 2, 0, iconSize / 2 - 2, iconSize );
+		}
+		else {
+			this.context.beginPath();
+			this.context.translate( 2, 0 );
+			this.context.moveTo( 0, 0 );
+			this.context.lineTo( iconSize - 2, iconSize / 2 );
+			this.context.lineTo( 0, iconSize );
+			this.context.fillStyle = '#fff';
+			this.context.fill();
+		}
+
+		this.context.restore();
+
+	};
+
+	Playback.prototype.on = function( type, listener ) {
+		this.canvas.addEventListener( type, listener, false );
+	};
+
+	Playback.prototype.off = function( type, listener ) {
+		this.canvas.removeEventListener( type, listener, false );
+	};
+
+	Playback.prototype.destroy = function() {
+
+		this.playing = false;
+
+		if( this.canvas.parentNode ) {
+			this.container.removeChild( this.canvas );
+		}
+
+	};
+
+
+	// --------------------------------------------------------------------//
+	// ------------------------------- API --------------------------------//
+	// --------------------------------------------------------------------//
+
+
+	return {
+		initialize: initialize,
+		configure: configure,
+		sync: sync,
+
+		// Navigation methods
+		slide: slide,
+		left: navigateLeft,
+		right: navigateRight,
+		up: navigateUp,
+		down: navigateDown,
+		prev: navigatePrev,
+		next: navigateNext,
+
+		// Fragment methods
+		navigateFragment: navigateFragment,
+		prevFragment: previousFragment,
+		nextFragment: nextFragment,
+
+		// Deprecated aliases
+		navigateTo: slide,
+		navigateLeft: navigateLeft,
+		navigateRight: navigateRight,
+		navigateUp: navigateUp,
+		navigateDown: navigateDown,
+		navigatePrev: navigatePrev,
+		navigateNext: navigateNext,
+
+		// Forces an update in slide layout
+		layout: layout,
+
+		// Returns an object with the available routes as booleans (left/right/top/bottom)
+		availableRoutes: availableRoutes,
+
+		// Returns an object with the available fragments as booleans (prev/next)
+		availableFragments: availableFragments,
+
+		// Toggles the overview mode on/off
+		toggleOverview: toggleOverview,
+
+		// Toggles the "black screen" mode on/off
+		togglePause: togglePause,
+
+		// State checks
+		isOverview: isOverview,
+		isPaused: isPaused,
+
+		// Adds or removes all internal event listeners (such as keyboard)
+		addEventListeners: addEventListeners,
+		removeEventListeners: removeEventListeners,
+
+		// Returns the indices of the current, or specified, slide
+		getIndices: getIndices,
+
+		// Returns the slide at the specified index, y is optional
+		getSlide: function( x, y ) {
+			var horizontalSlide = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR )[ x ];
+			var verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' );
+
+			if( typeof y !== 'undefined' ) {
+				return verticalSlides ? verticalSlides[ y ] : undefined;
+			}
+
+			return horizontalSlide;
+		},
+
+		// Returns the previous slide element, may be null
+		getPreviousSlide: function() {
+			return previousSlide;
+		},
+
+		// Returns the current slide element
+		getCurrentSlide: function() {
+			return currentSlide;
+		},
+
+		// Returns the current scale of the presentation content
+		getScale: function() {
+			return scale;
+		},
+
+		// Returns the current configuration object
+		getConfig: function() {
+			return config;
+		},
+
+		// Helper method, retrieves query string as a key/value hash
+		getQueryHash: function() {
+			var query = {};
+
+			location.search.replace( /[A-Z0-9]+?=([\w\.%-]*)/gi, function(a) {
+				query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
+			} );
+
+			// Basic deserialization
+			for( var i in query ) {
+				var value = query[ i ];
+
+				query[ i ] = unescape( value );
+
+				if( value === 'null' ) query[ i ] = null;
+				else if( value === 'true' ) query[ i ] = true;
+				else if( value === 'false' ) query[ i ] = false;
+				else if( value.match( /^\d+$/ ) ) query[ i ] = parseFloat( value );
+			}
+
+			return query;
+		},
+
+		// Returns true if we're currently on the first slide
+		isFirstSlide: function() {
+			return document.querySelector( SLIDES_SELECTOR + '.past' ) == null ? true : false;
+		},
+
+		// Returns true if we're currently on the last slide
+		isLastSlide: function() {
+			if( currentSlide ) {
+				// Does this slide has next a sibling?
+				if( currentSlide.nextElementSibling ) return false;
+
+				// If it's vertical, does its parent have a next sibling?
+				if( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false;
+
+				return true;
+			}
+
+			return false;
+		},
+
+		// Checks if reveal.js has been loaded and is ready for use
+		isReady: function() {
+			return loaded;
+		},
+
+		// Forward event binding to the reveal DOM element
+		addEventListener: function( type, listener, useCapture ) {
+			if( 'addEventListener' in window ) {
+				( dom.wrapper || document.querySelector( '.reveal' ) ).addEventListener( type, listener, useCapture );
+			}
+		},
+		removeEventListener: function( type, listener, useCapture ) {
+			if( 'addEventListener' in window ) {
+				( dom.wrapper || document.querySelector( '.reveal' ) ).removeEventListener( type, listener, useCapture );
+			}
+		}
+	};
+
+})();
diff --git a/docs/slides/IHP14/_support/reveal.js/js/reveal.min.js b/docs/slides/IHP14/_support/reveal.js/js/reveal.min.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/js/reveal.min.js
@@ -0,0 +1,9 @@
+/*!
+ * reveal.js 2.6.1 (2014-03-13, 09:22)
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2014 Hakim El Hattab, http://hakim.se
+ */
+var Reveal=function(){"use strict";function a(a){if(b(),!ec.transforms2d&&!ec.transforms3d)return document.body.setAttribute("class","no-transforms"),void 0;window.addEventListener("load",A,!1);var d=Reveal.getQueryHash();"undefined"!=typeof d.dependencies&&delete d.dependencies,k(_b,a),k(_b,d),r(),c()}function b(){ec.transforms3d="WebkitPerspective"in document.body.style||"MozPerspective"in document.body.style||"msPerspective"in document.body.style||"OPerspective"in document.body.style||"perspective"in document.body.style,ec.transforms2d="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style,ec.requestAnimationFrameMethod=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame,ec.requestAnimationFrame="function"==typeof ec.requestAnimationFrameMethod,ec.canvas=!!document.createElement("canvas").getContext,Vb=navigator.userAgent.match(/(iphone|ipod|android)/gi)}function c(){function a(){e.length&&head.js.apply(null,e),d()}function b(b){head.ready(b.src.match(/([\w\d_\-]*)\.?js$|[^\\\/]*$/i)[0],function(){"function"==typeof b.callback&&b.callback.apply(this),0===--f&&a()})}for(var c=[],e=[],f=0,g=0,h=_b.dependencies.length;h>g;g++){var i=_b.dependencies[g];(!i.condition||i.condition())&&(i.async?e.push(i.src):c.push(i.src),b(i))}c.length?(f=c.length,head.js.apply(null,c)):a()}function d(){e(),Q(),h(),cb(),X(!0),setTimeout(function(){dc.slides.classList.remove("no-transition"),ac=!0,t("ready",{indexh:Qb,indexv:Rb,currentSlide:Tb})},1)}function e(){dc.theme=document.querySelector("#theme"),dc.wrapper=document.querySelector(".reveal"),dc.slides=document.querySelector(".reveal .slides"),dc.slides.classList.add("no-transition"),dc.background=f(dc.wrapper,"div","backgrounds",null),dc.progress=f(dc.wrapper,"div","progress","<span></span>"),dc.progressbar=dc.progress.querySelector("span"),f(dc.wrapper,"aside","controls",'<div class="navigate-left"></div><div class="navigate-right"></div><div class="navigate-up"></div><div class="navigate-down"></div>'),dc.slideNumber=f(dc.wrapper,"div","slide-number",""),f(dc.wrapper,"div","state-background",null),f(dc.wrapper,"div","pause-overlay",null),dc.controls=document.querySelector(".reveal .controls"),dc.controlsLeft=l(document.querySelectorAll(".navigate-left")),dc.controlsRight=l(document.querySelectorAll(".navigate-right")),dc.controlsUp=l(document.querySelectorAll(".navigate-up")),dc.controlsDown=l(document.querySelectorAll(".navigate-down")),dc.controlsPrev=l(document.querySelectorAll(".navigate-prev")),dc.controlsNext=l(document.querySelectorAll(".navigate-next"))}function f(a,b,c,d){var e=a.querySelector("."+c);return e||(e=document.createElement(b),e.classList.add(c),null!==d&&(e.innerHTML=d),a.appendChild(e)),e}function g(){function a(a,b){var c={background:a.getAttribute("data-background"),backgroundSize:a.getAttribute("data-background-size"),backgroundImage:a.getAttribute("data-background-image"),backgroundColor:a.getAttribute("data-background-color"),backgroundRepeat:a.getAttribute("data-background-repeat"),backgroundPosition:a.getAttribute("data-background-position"),backgroundTransition:a.getAttribute("data-background-transition")},d=document.createElement("div");return d.className="slide-background",c.background&&(/^(http|file|\/\/)/gi.test(c.background)||/\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test(c.background)?d.style.backgroundImage="url("+c.background+")":d.style.background=c.background),(c.background||c.backgroundColor||c.backgroundImage)&&d.setAttribute("data-background-hash",c.background+c.backgroundSize+c.backgroundImage+c.backgroundColor+c.backgroundRepeat+c.backgroundPosition+c.backgroundTransition),c.backgroundSize&&(d.style.backgroundSize=c.backgroundSize),c.backgroundImage&&(d.style.backgroundImage='url("'+c.backgroundImage+'")'),c.backgroundColor&&(d.style.backgroundColor=c.backgroundColor),c.backgroundRepeat&&(d.style.backgroundRepeat=c.backgroundRepeat),c.backgroundPosition&&(d.style.backgroundPosition=c.backgroundPosition),c.backgroundTransition&&d.setAttribute("data-background-transition",c.backgroundTransition),b.appendChild(d),d}q()&&document.body.classList.add("print-pdf"),dc.background.innerHTML="",dc.background.classList.add("no-transition"),l(document.querySelectorAll(Yb)).forEach(function(b){var c;c=q()?a(b,b):a(b,dc.background),l(b.querySelectorAll("section")).forEach(function(b){q()?a(b,b):a(b,c)})}),_b.parallaxBackgroundImage?(dc.background.style.backgroundImage='url("'+_b.parallaxBackgroundImage+'")',dc.background.style.backgroundSize=_b.parallaxBackgroundSize,setTimeout(function(){dc.wrapper.classList.add("has-parallax-background")},1)):(dc.background.style.backgroundImage="",dc.wrapper.classList.remove("has-parallax-background"))}function h(a){var b=document.querySelectorAll(Xb).length;if(dc.wrapper.classList.remove(_b.transition),"object"==typeof a&&k(_b,a),ec.transforms3d===!1&&(_b.transition="linear"),dc.wrapper.classList.add(_b.transition),dc.wrapper.setAttribute("data-transition-speed",_b.transitionSpeed),dc.wrapper.setAttribute("data-background-transition",_b.backgroundTransition),dc.controls.style.display=_b.controls?"block":"none",dc.progress.style.display=_b.progress?"block":"none",_b.rtl?dc.wrapper.classList.add("rtl"):dc.wrapper.classList.remove("rtl"),_b.center?dc.wrapper.classList.add("center"):dc.wrapper.classList.remove("center"),_b.mouseWheel?(document.addEventListener("DOMMouseScroll",Bb,!1),document.addEventListener("mousewheel",Bb,!1)):(document.removeEventListener("DOMMouseScroll",Bb,!1),document.removeEventListener("mousewheel",Bb,!1)),_b.rollingLinks?u():v(),_b.previewLinks?w():(x(),w("[data-preview-link]")),b>1&&_b.autoSlide&&_b.autoSlideStoppable&&ec.canvas&&ec.requestAnimationFrame?(Wb=new Pb(dc.wrapper,function(){return Math.min(Math.max((Date.now()-mc)/kc,0),1)}),Wb.on("click",Ob),nc=!1):Wb&&(Wb.destroy(),Wb=null),_b.theme&&dc.theme){var c=dc.theme.getAttribute("href"),d=/[^\/]*?(?=\.css)/,e=c.match(d)[0];_b.theme!==e&&(c=c.replace(d,_b.theme),dc.theme.setAttribute("href",c))}P()}function i(){if(jc=!0,window.addEventListener("hashchange",Jb,!1),window.addEventListener("resize",Kb,!1),_b.touch&&(dc.wrapper.addEventListener("touchstart",vb,!1),dc.wrapper.addEventListener("touchmove",wb,!1),dc.wrapper.addEventListener("touchend",xb,!1),window.navigator.msPointerEnabled&&(dc.wrapper.addEventListener("MSPointerDown",yb,!1),dc.wrapper.addEventListener("MSPointerMove",zb,!1),dc.wrapper.addEventListener("MSPointerUp",Ab,!1))),_b.keyboard&&document.addEventListener("keydown",ub,!1),_b.progress&&dc.progress&&dc.progress.addEventListener("click",Cb,!1),_b.focusBodyOnPageVisiblityChange){var a;"hidden"in document?a="visibilitychange":"msHidden"in document?a="msvisibilitychange":"webkitHidden"in document&&(a="webkitvisibilitychange"),a&&document.addEventListener(a,Lb,!1)}["touchstart","click"].forEach(function(a){dc.controlsLeft.forEach(function(b){b.addEventListener(a,Db,!1)}),dc.controlsRight.forEach(function(b){b.addEventListener(a,Eb,!1)}),dc.controlsUp.forEach(function(b){b.addEventListener(a,Fb,!1)}),dc.controlsDown.forEach(function(b){b.addEventListener(a,Gb,!1)}),dc.controlsPrev.forEach(function(b){b.addEventListener(a,Hb,!1)}),dc.controlsNext.forEach(function(b){b.addEventListener(a,Ib,!1)})})}function j(){jc=!1,document.removeEventListener("keydown",ub,!1),window.removeEventListener("hashchange",Jb,!1),window.removeEventListener("resize",Kb,!1),dc.wrapper.removeEventListener("touchstart",vb,!1),dc.wrapper.removeEventListener("touchmove",wb,!1),dc.wrapper.removeEventListener("touchend",xb,!1),window.navigator.msPointerEnabled&&(dc.wrapper.removeEventListener("MSPointerDown",yb,!1),dc.wrapper.removeEventListener("MSPointerMove",zb,!1),dc.wrapper.removeEventListener("MSPointerUp",Ab,!1)),_b.progress&&dc.progress&&dc.progress.removeEventListener("click",Cb,!1),["touchstart","click"].forEach(function(a){dc.controlsLeft.forEach(function(b){b.removeEventListener(a,Db,!1)}),dc.controlsRight.forEach(function(b){b.removeEventListener(a,Eb,!1)}),dc.controlsUp.forEach(function(b){b.removeEventListener(a,Fb,!1)}),dc.controlsDown.forEach(function(b){b.removeEventListener(a,Gb,!1)}),dc.controlsPrev.forEach(function(b){b.removeEventListener(a,Hb,!1)}),dc.controlsNext.forEach(function(b){b.removeEventListener(a,Ib,!1)})})}function k(a,b){for(var c in b)a[c]=b[c]}function l(a){return Array.prototype.slice.call(a)}function m(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)}function n(a,b){a.style.WebkitTransform=b,a.style.MozTransform=b,a.style.msTransform=b,a.style.OTransform=b,a.style.transform=b}function o(a){var b=0;if(a){var c=0;l(a.childNodes).forEach(function(a){"number"==typeof a.offsetTop&&a.style&&("absolute"===a.style.position&&(c+=1),b=Math.max(b,a.offsetTop+a.offsetHeight))}),0===c&&(b=a.offsetHeight)}return b}function p(a,b){if(b=b||0,a){var c=a.parentNode,d=c.childNodes;l(d).forEach(function(c){if("number"==typeof c.offsetHeight&&c!==a){var d=window.getComputedStyle(c),e=parseInt(d.marginTop,10),f=parseInt(d.marginBottom,10);b-=c.offsetHeight+e+f}});var e=window.getComputedStyle(a);b-=parseInt(e.marginTop,10)+parseInt(e.marginBottom,10)}return b}function q(){return/print-pdf/gi.test(window.location.search)}function r(){_b.hideAddressBar&&Vb&&(window.addEventListener("load",s,!1),window.addEventListener("orientationchange",s,!1))}function s(){setTimeout(function(){window.scrollTo(0,1)},10)}function t(a,b){var c=document.createEvent("HTMLEvents",1,2);c.initEvent(a,!0,!0),k(c,b),dc.wrapper.dispatchEvent(c)}function u(){if(ec.transforms3d&&!("msPerspective"in document.body.style))for(var a=document.querySelectorAll(Xb+" a:not(.image)"),b=0,c=a.length;c>b;b++){var d=a[b];if(!(!d.textContent||d.querySelector("*")||d.className&&d.classList.contains(d,"roll"))){var e=document.createElement("span");e.setAttribute("data-title",d.text),e.innerHTML=d.innerHTML,d.classList.add("roll"),d.innerHTML="",d.appendChild(e)}}}function v(){for(var a=document.querySelectorAll(Xb+" a.roll"),b=0,c=a.length;c>b;b++){var d=a[b],e=d.querySelector("span");e&&(d.classList.remove("roll"),d.innerHTML=e.innerHTML)}}function w(a){var b=l(document.querySelectorAll(a?a:"a"));b.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.addEventListener("click",Nb,!1)})}function x(){var a=l(document.querySelectorAll("a"));a.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.removeEventListener("click",Nb,!1)})}function y(a){z(),dc.preview=document.createElement("div"),dc.preview.classList.add("preview-link-overlay"),dc.wrapper.appendChild(dc.preview),dc.preview.innerHTML=["<header>",'<a class="close" href="#"><span class="icon"></span></a>','<a class="external" href="'+a+'" target="_blank"><span class="icon"></span></a>',"</header>",'<div class="spinner"></div>','<div class="viewport">','<iframe src="'+a+'"></iframe>',"</div>"].join(""),dc.preview.querySelector("iframe").addEventListener("load",function(){dc.preview.classList.add("loaded")},!1),dc.preview.querySelector(".close").addEventListener("click",function(a){z(),a.preventDefault()},!1),dc.preview.querySelector(".external").addEventListener("click",function(){z()},!1),setTimeout(function(){dc.preview.classList.add("visible")},1)}function z(){dc.preview&&(dc.preview.setAttribute("src",""),dc.preview.parentNode.removeChild(dc.preview),dc.preview=null)}function A(){if(dc.wrapper&&!q()){var a=dc.wrapper.offsetWidth,b=dc.wrapper.offsetHeight;a-=b*_b.margin,b-=b*_b.margin;var c=_b.width,d=_b.height,e=20;B(_b.width,_b.height,e),"string"==typeof c&&/%$/.test(c)&&(c=parseInt(c,10)/100*a),"string"==typeof d&&/%$/.test(d)&&(d=parseInt(d,10)/100*b),dc.slides.style.width=c+"px",dc.slides.style.height=d+"px",cc=Math.min(a/c,b/d),cc=Math.max(cc,_b.minScale),cc=Math.min(cc,_b.maxScale),"undefined"==typeof dc.slides.style.zoom||navigator.userAgent.match(/(iphone|ipod|ipad|android)/gi)?n(dc.slides,"translate(-50%, -50%) scale("+cc+") translate(50%, 50%)"):dc.slides.style.zoom=cc;for(var f=l(document.querySelectorAll(Xb)),g=0,h=f.length;h>g;g++){var i=f[g];"none"!==i.style.display&&(i.style.top=_b.center||i.classList.contains("center")?i.classList.contains("stack")?0:Math.max(-(o(i)/2)-e,-d/2)+"px":"")}U(),Y()}}function B(a,b,c){l(dc.slides.querySelectorAll("section > .stretch")).forEach(function(d){var e=p(d,b-2*c);if(/(img|video)/gi.test(d.nodeName)){var f=d.naturalWidth||d.videoWidth,g=d.naturalHeight||d.videoHeight,h=Math.min(a/f,e/g);d.style.width=f*h+"px",d.style.height=g*h+"px"}else d.style.width=a+"px",d.style.height=e+"px"})}function C(a,b){"object"==typeof a&&"function"==typeof a.setAttribute&&a.setAttribute("data-previous-indexv",b||0)}function D(a){if("object"==typeof a&&"function"==typeof a.setAttribute&&a.classList.contains("stack")){var b=a.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(a.getAttribute(b)||0,10)}return 0}function E(){if(_b.overview){kb();var a=dc.wrapper.classList.contains("overview"),b=window.innerWidth<400?1e3:2500;dc.wrapper.classList.add("overview"),dc.wrapper.classList.remove("overview-deactivating"),clearTimeout(hc),clearTimeout(ic),hc=setTimeout(function(){for(var c=document.querySelectorAll(Yb),d=0,e=c.length;e>d;d++){var f=c[d],g=_b.rtl?-105:105;if(f.setAttribute("data-index-h",d),n(f,"translateZ(-"+b+"px) translate("+(d-Qb)*g+"%, 0%)"),f.classList.contains("stack"))for(var h=f.querySelectorAll("section"),i=0,j=h.length;j>i;i++){var k=d===Qb?Rb:D(f),l=h[i];l.setAttribute("data-index-h",d),l.setAttribute("data-index-v",i),n(l,"translate(0%, "+105*(i-k)+"%)"),l.addEventListener("click",Mb,!0)}else f.addEventListener("click",Mb,!0)}T(),A(),a||t("overviewshown",{indexh:Qb,indexv:Rb,currentSlide:Tb})},10)}}function F(){_b.overview&&(clearTimeout(hc),clearTimeout(ic),dc.wrapper.classList.remove("overview"),dc.wrapper.classList.add("overview-deactivating"),ic=setTimeout(function(){dc.wrapper.classList.remove("overview-deactivating")},1),l(document.querySelectorAll(Xb)).forEach(function(a){n(a,""),a.removeEventListener("click",Mb,!0)}),O(Qb,Rb),jb(),t("overviewhidden",{indexh:Qb,indexv:Rb,currentSlide:Tb}))}function G(a){"boolean"==typeof a?a?E():F():H()?F():E()}function H(){return dc.wrapper.classList.contains("overview")}function I(a){return a=a?a:Tb,a&&a.parentNode&&!!a.parentNode.nodeName.match(/section/i)}function J(){var a=document.body,b=a.requestFullScreen||a.webkitRequestFullscreen||a.webkitRequestFullScreen||a.mozRequestFullScreen||a.msRequestFullScreen;b&&b.apply(a)}function K(){var a=dc.wrapper.classList.contains("paused");kb(),dc.wrapper.classList.add("paused"),a===!1&&t("paused")}function L(){var a=dc.wrapper.classList.contains("paused");dc.wrapper.classList.remove("paused"),jb(),a&&t("resumed")}function M(){N()?L():K()}function N(){return dc.wrapper.classList.contains("paused")}function O(a,b,c,d){Sb=Tb;var e=document.querySelectorAll(Yb);void 0===b&&(b=D(e[a])),Sb&&Sb.parentNode&&Sb.parentNode.classList.contains("stack")&&C(Sb.parentNode,Rb);var f=bc.concat();bc.length=0;var g=Qb||0,h=Rb||0;Qb=S(Yb,void 0===a?Qb:a),Rb=S(Zb,void 0===b?Rb:b),T(),A();a:for(var i=0,j=bc.length;j>i;i++){for(var k=0;k<f.length;k++)if(f[k]===bc[i]){f.splice(k,1);continue a}document.documentElement.classList.add(bc[i]),t(bc[i])}for(;f.length;)document.documentElement.classList.remove(f.pop());H()&&E();var m=e[Qb],n=m.querySelectorAll("section");Tb=n[Rb]||m,"undefined"!=typeof c&&gb(c);var o=Qb!==g||Rb!==h;o?t("slidechanged",{indexh:Qb,indexv:Rb,previousSlide:Sb,currentSlide:Tb,origin:d}):Sb=null,Sb&&(Sb.classList.remove("present"),document.querySelector($b).classList.contains("present")&&setTimeout(function(){var a,b=l(document.querySelectorAll(Yb+".stack"));for(a in b)b[a]&&C(b[a],0)},0)),o&&(ab(Sb),_(Tb)),W(),U(),X(),Y(),V(),db(),jb()}function P(){j(),i(),A(),kc=_b.autoSlide,jb(),g(),R(),W(),U(),X(!0),V()}function Q(){var a=l(document.querySelectorAll(Yb));a.forEach(function(a){var b=l(a.querySelectorAll("section"));b.forEach(function(a,b){b>0&&(a.classList.remove("present"),a.classList.remove("past"),a.classList.add("future"))})})}function R(){var a=l(document.querySelectorAll(Yb));a.forEach(function(a){var b=l(a.querySelectorAll("section"));b.forEach(function(a){fb(a.querySelectorAll(".fragment"))}),0===b.length&&fb(a.querySelectorAll(".fragment"))})}function S(a,b){var c=l(document.querySelectorAll(a)),d=c.length;if(d){_b.loop&&(b%=d,0>b&&(b=d+b)),b=Math.max(Math.min(b,d-1),0);for(var e=0;d>e;e++){var f=c[e],g=_b.rtl&&!I(f);if(f.classList.remove("past"),f.classList.remove("present"),f.classList.remove("future"),f.setAttribute("hidden",""),b>e){f.classList.add(g?"future":"past");for(var h=l(f.querySelectorAll(".fragment"));h.length;){var i=h.pop();i.classList.add("visible"),i.classList.remove("current-fragment")}}else if(e>b){f.classList.add(g?"past":"future");for(var j=l(f.querySelectorAll(".fragment.visible"));j.length;){var k=j.pop();k.classList.remove("visible"),k.classList.remove("current-fragment")}}f.querySelector("section")&&f.classList.add("stack")}c[b].classList.add("present"),c[b].removeAttribute("hidden");var m=c[b].getAttribute("data-state");m&&(bc=bc.concat(m.split(" ")))}else b=0;return b}function T(){var a,b,c=l(document.querySelectorAll(Yb)),d=c.length;if(d){var e=H()?10:_b.viewDistance;Vb&&(e=H()?6:1);for(var f=0;d>f;f++){var g=c[f],h=l(g.querySelectorAll("section")),i=h.length;if(a=Math.abs((Qb-f)%(d-e))||0,g.style.display=a>e?"none":"block",i)for(var j=D(g),k=0;i>k;k++){var m=h[k];b=f===Qb?Math.abs(Rb-k):Math.abs(k-j),m.style.display=a+b>e?"none":"block"}}}}function U(){if(_b.progress&&dc.progress){var a=l(document.querySelectorAll(Yb)),b=document.querySelectorAll(Xb+":not(.stack)").length,c=0;a:for(var d=0;d<a.length;d++){for(var e=a[d],f=l(e.querySelectorAll("section")),g=0;g<f.length;g++){if(f[g].classList.contains("present"))break a;c++}if(e.classList.contains("present"))break;e.classList.contains("stack")===!1&&c++}dc.progressbar.style.width=c/(b-1)*window.innerWidth+"px"}}function V(){if(_b.slideNumber&&dc.slideNumber){var a=Qb;Rb>0&&(a+=" - "+Rb),dc.slideNumber.innerHTML=a}}function W(){var a=Z(),b=$();dc.controlsLeft.concat(dc.controlsRight).concat(dc.controlsUp).concat(dc.controlsDown).concat(dc.controlsPrev).concat(dc.controlsNext).forEach(function(a){a.classList.remove("enabled"),a.classList.remove("fragmented")}),a.left&&dc.controlsLeft.forEach(function(a){a.classList.add("enabled")}),a.right&&dc.controlsRight.forEach(function(a){a.classList.add("enabled")}),a.up&&dc.controlsUp.forEach(function(a){a.classList.add("enabled")}),a.down&&dc.controlsDown.forEach(function(a){a.classList.add("enabled")}),(a.left||a.up)&&dc.controlsPrev.forEach(function(a){a.classList.add("enabled")}),(a.right||a.down)&&dc.controlsNext.forEach(function(a){a.classList.add("enabled")}),Tb&&(b.prev&&dc.controlsPrev.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsNext.forEach(function(a){a.classList.add("fragmented","enabled")}),I(Tb)?(b.prev&&dc.controlsUp.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsDown.forEach(function(a){a.classList.add("fragmented","enabled")})):(b.prev&&dc.controlsLeft.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsRight.forEach(function(a){a.classList.add("fragmented","enabled")})))}function X(a){var b=null,c=_b.rtl?"future":"past",d=_b.rtl?"past":"future";if(l(dc.background.childNodes).forEach(function(e,f){Qb>f?e.className="slide-background "+c:f>Qb?e.className="slide-background "+d:(e.className="slide-background present",b=e),(a||f===Qb)&&l(e.childNodes).forEach(function(a,c){Rb>c?a.className="slide-background past":c>Rb?a.className="slide-background future":(a.className="slide-background present",f===Qb&&(b=a))})}),b){var e=Ub?Ub.getAttribute("data-background-hash"):null,f=b.getAttribute("data-background-hash");f&&f===e&&b!==Ub&&dc.background.classList.add("no-transition"),Ub=b}setTimeout(function(){dc.background.classList.remove("no-transition")},1)}function Y(){if(_b.parallaxBackgroundImage){var a,b,c=document.querySelectorAll(Yb),d=document.querySelectorAll(Zb),e=dc.background.style.backgroundSize.split(" ");1===e.length?a=b=parseInt(e[0],10):(a=parseInt(e[0],10),b=parseInt(e[1],10));var f=dc.background.offsetWidth,g=c.length,h=-(a-f)/(g-1)*Qb,i=dc.background.offsetHeight,j=d.length,k=j>0?-(b-i)/(j-1)*Rb:0;dc.background.style.backgroundPosition=h+"px "+k+"px"}}function Z(){var a=document.querySelectorAll(Yb),b=document.querySelectorAll(Zb),c={left:Qb>0||_b.loop,right:Qb<a.length-1||_b.loop,up:Rb>0,down:Rb<b.length-1};if(_b.rtl){var d=c.left;c.left=c.right,c.right=d}return c}function $(){if(Tb&&_b.fragments){var a=Tb.querySelectorAll(".fragment"),b=Tb.querySelectorAll(".fragment:not(.visible)");return{prev:a.length-b.length>0,next:!!b.length}}return{prev:!1,next:!1}}function _(a){a&&!bb()&&(l(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&a.play()}),l(a.querySelectorAll("iframe")).forEach(function(a){a.contentWindow.postMessage("slide:start","*")}),l(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-autoplay")&&a.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*")}))}function ab(a){a&&(l(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-ignore")||a.pause()}),l(a.querySelectorAll("iframe")).forEach(function(a){a.contentWindow.postMessage("slide:stop","*")}),l(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-ignore")||"function"!=typeof a.contentWindow.postMessage||a.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")}))}function bb(){return!!window.location.search.match(/receiver/gi)}function cb(){var a=window.location.hash,b=a.slice(2).split("/"),c=a.replace(/#|\//gi,"");if(isNaN(parseInt(b[0],10))&&c.length){var d=document.querySelector("#"+c);if(d){var e=Reveal.getIndices(d);O(e.h,e.v)}else O(Qb||0,Rb||0)}else{var f=parseInt(b[0],10)||0,g=parseInt(b[1],10)||0;(f!==Qb||g!==Rb)&&O(f,g)}}function db(a){if(_b.history)if(clearTimeout(gc),"number"==typeof a)gc=setTimeout(db,a);else{var b="/";Tb&&"string"==typeof Tb.getAttribute("id")?b="/"+Tb.getAttribute("id"):((Qb>0||Rb>0)&&(b+=Qb),Rb>0&&(b+="/"+Rb)),window.location.hash=b}}function eb(a){var b,c=Qb,d=Rb;if(a){var e=I(a),f=e?a.parentNode:a,g=l(document.querySelectorAll(Yb));c=Math.max(g.indexOf(f),0),e&&(d=Math.max(l(a.parentNode.querySelectorAll("section")).indexOf(a),0))}if(!a&&Tb){var h=Tb.querySelectorAll(".fragment").length>0;if(h){var i=Tb.querySelectorAll(".fragment.visible");b=i.length-1}}return{h:c,v:d,f:b}}function fb(a){a=l(a);var b=[],c=[],d=[];a.forEach(function(a){if(a.hasAttribute("data-fragment-index")){var d=parseInt(a.getAttribute("data-fragment-index"),10);b[d]||(b[d]=[]),b[d].push(a)}else c.push([a])}),b=b.concat(c);var e=0;return b.forEach(function(a){a.forEach(function(a){d.push(a),a.setAttribute("data-fragment-index",e)}),e++}),d}function gb(a,b){if(Tb&&_b.fragments){var c=fb(Tb.querySelectorAll(".fragment"));if(c.length){if("number"!=typeof a){var d=fb(Tb.querySelectorAll(".fragment.visible")).pop();a=d?parseInt(d.getAttribute("data-fragment-index")||0,10):-1}"number"==typeof b&&(a+=b);var e=[],f=[];return l(c).forEach(function(b,c){b.hasAttribute("data-fragment-index")&&(c=parseInt(b.getAttribute("data-fragment-index"),10)),a>=c?(b.classList.contains("visible")||e.push(b),b.classList.add("visible"),b.classList.remove("current-fragment"),c===a&&b.classList.add("current-fragment")):(b.classList.contains("visible")&&f.push(b),b.classList.remove("visible"),b.classList.remove("current-fragment"))}),f.length&&t("fragmenthidden",{fragment:f[0],fragments:f}),e.length&&t("fragmentshown",{fragment:e[0],fragments:e}),W(),!(!e.length&&!f.length)}}return!1}function hb(){return gb(null,1)}function ib(){return gb(null,-1)}function jb(){if(kb(),Tb){var a=Tb.parentNode?Tb.parentNode.getAttribute("data-autoslide"):null,b=Tb.getAttribute("data-autoslide");kc=b?parseInt(b,10):a?parseInt(a,10):_b.autoSlide,l(Tb.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&kc&&1e3*a.duration>kc&&(kc=1e3*a.duration+1e3)}),!kc||nc||N()||H()||Reveal.isLastSlide()&&_b.loop!==!0||(lc=setTimeout(sb,kc),mc=Date.now()),Wb&&Wb.setPlaying(-1!==lc)}}function kb(){clearTimeout(lc),lc=-1}function lb(){nc=!0,clearTimeout(lc),Wb&&Wb.setPlaying(!1)}function mb(){nc=!1,jb()}function nb(){_b.rtl?(H()||hb()===!1)&&Z().left&&O(Qb+1):(H()||ib()===!1)&&Z().left&&O(Qb-1)}function ob(){_b.rtl?(H()||ib()===!1)&&Z().right&&O(Qb-1):(H()||hb()===!1)&&Z().right&&O(Qb+1)}function pb(){(H()||ib()===!1)&&Z().up&&O(Qb,Rb-1)}function qb(){(H()||hb()===!1)&&Z().down&&O(Qb,Rb+1)}function rb(){if(ib()===!1)if(Z().up)pb();else{var a=document.querySelector(Yb+".past:nth-child("+Qb+")");if(a){var b=a.querySelectorAll("section").length-1||void 0,c=Qb-1;O(c,b)}}}function sb(){hb()===!1&&(Z().down?qb():ob()),jb()}function tb(){_b.autoSlideStoppable&&lb()}function ub(a){tb(a),document.activeElement;var b=!(!document.activeElement||!document.activeElement.type&&!document.activeElement.href&&"inherit"===document.activeElement.contentEditable);if(!(b||a.shiftKey&&32!==a.keyCode||a.altKey||a.ctrlKey||a.metaKey)){if(N()&&-1===[66,190,191].indexOf(a.keyCode))return!1;var c=!1;if("object"==typeof _b.keyboard)for(var d in _b.keyboard)if(parseInt(d,10)===a.keyCode){var e=_b.keyboard[d];"function"==typeof e?e.apply(null,[a]):"string"==typeof e&&"function"==typeof Reveal[e]&&Reveal[e].call(),c=!0}if(c===!1)switch(c=!0,a.keyCode){case 80:case 33:rb();break;case 78:case 34:sb();break;case 72:case 37:nb();break;case 76:case 39:ob();break;case 75:case 38:pb();break;case 74:case 40:qb();break;case 36:O(0);break;case 35:O(Number.MAX_VALUE);break;case 32:H()?F():a.shiftKey?rb():sb();break;case 13:H()?F():c=!1;break;case 66:case 190:case 191:M();break;case 70:J();break;default:c=!1}c?a.preventDefault():27!==a.keyCode&&79!==a.keyCode||!ec.transforms3d||(dc.preview?z():G(),a.preventDefault()),jb()}}function vb(a){oc.startX=a.touches[0].clientX,oc.startY=a.touches[0].clientY,oc.startCount=a.touches.length,2===a.touches.length&&_b.overview&&(oc.startSpan=m({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:oc.startX,y:oc.startY}))}function wb(a){if(oc.captured)navigator.userAgent.match(/android/gi)&&a.preventDefault();else{tb(a);var b=a.touches[0].clientX,c=a.touches[0].clientY;if(2===a.touches.length&&2===oc.startCount&&_b.overview){var d=m({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:oc.startX,y:oc.startY});Math.abs(oc.startSpan-d)>oc.threshold&&(oc.captured=!0,d<oc.startSpan?E():F()),a.preventDefault()}else if(1===a.touches.length&&2!==oc.startCount){var e=b-oc.startX,f=c-oc.startY;e>oc.threshold&&Math.abs(e)>Math.abs(f)?(oc.captured=!0,nb()):e<-oc.threshold&&Math.abs(e)>Math.abs(f)?(oc.captured=!0,ob()):f>oc.threshold?(oc.captured=!0,pb()):f<-oc.threshold&&(oc.captured=!0,qb()),_b.embedded?(oc.captured||I(Tb))&&a.preventDefault():a.preventDefault()}}}function xb(){oc.captured=!1}function yb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],vb(a))}function zb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],wb(a))}function Ab(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],xb(a))}function Bb(a){if(Date.now()-fc>600){fc=Date.now();var b=a.detail||-a.wheelDelta;b>0?sb():rb()}}function Cb(a){tb(a),a.preventDefault();var b=l(document.querySelectorAll(Yb)).length,c=Math.floor(a.clientX/dc.wrapper.offsetWidth*b);O(c)}function Db(a){a.preventDefault(),tb(),nb()}function Eb(a){a.preventDefault(),tb(),ob()}function Fb(a){a.preventDefault(),tb(),pb()}function Gb(a){a.preventDefault(),tb(),qb()}function Hb(a){a.preventDefault(),tb(),rb()}function Ib(a){a.preventDefault(),tb(),sb()}function Jb(){cb()}function Kb(){A()}function Lb(){var a=document.webkitHidden||document.msHidden||document.hidden;a===!1&&document.activeElement!==document.body&&(document.activeElement.blur(),document.body.focus())}function Mb(a){if(jc&&H()){a.preventDefault();for(var b=a.target;b&&!b.nodeName.match(/section/gi);)b=b.parentNode;if(b&&!b.classList.contains("disabled")&&(F(),b.nodeName.match(/section/gi))){var c=parseInt(b.getAttribute("data-index-h"),10),d=parseInt(b.getAttribute("data-index-v"),10);O(c,d)}}}function Nb(a){var b=a.target.getAttribute("href");b&&(y(b),a.preventDefault())}function Ob(){Reveal.isLastSlide()&&_b.loop===!1?(O(0,0),mb()):nc?mb():lb()}function Pb(a,b){this.diameter=50,this.thickness=3,this.playing=!1,this.progress=0,this.progressOffset=1,this.container=a,this.progressCheck=b,this.canvas=document.createElement("canvas"),this.canvas.className="playback",this.canvas.width=this.diameter,this.canvas.height=this.diameter,this.context=this.canvas.getContext("2d"),this.container.appendChild(this.canvas),this.render()}var Qb,Rb,Sb,Tb,Ub,Vb,Wb,Xb=".reveal .slides section",Yb=".reveal .slides>section",Zb=".reveal .slides>section.present>section",$b=".reveal .slides>section:first-of-type",_b={width:960,height:700,margin:.1,minScale:.2,maxScale:1,controls:!0,progress:!0,slideNumber:!1,history:!1,keyboard:!0,overview:!0,center:!0,touch:!0,loop:!1,rtl:!1,fragments:!0,embedded:!1,autoSlide:0,autoSlideStoppable:!0,mouseWheel:!1,rollingLinks:!1,hideAddressBar:!0,previewLinks:!1,focusBodyOnPageVisiblityChange:!0,theme:null,transition:"default",transitionSpeed:"default",backgroundTransition:"default",parallaxBackgroundImage:"",parallaxBackgroundSize:"",viewDistance:3,dependencies:[]},ac=!1,bc=[],cc=1,dc={},ec={},fc=0,gc=0,hc=0,ic=0,jc=!1,kc=0,lc=0,mc=-1,nc=!1,oc={startX:0,startY:0,startSpan:0,startCount:0,captured:!1,threshold:40};return Pb.prototype.setPlaying=function(a){var b=this.playing;this.playing=a,!b&&this.playing?this.animate():this.render()},Pb.prototype.animate=function(){var a=this.progress;this.progress=this.progressCheck(),a>.8&&this.progress<.2&&(this.progressOffset=this.progress),this.render(),this.playing&&ec.requestAnimationFrameMethod.call(window,this.animate.bind(this))},Pb.prototype.render=function(){var a=this.playing?this.progress:0,b=this.diameter/2-this.thickness,c=this.diameter/2,d=this.diameter/2,e=14;this.progressOffset+=.1*(1-this.progressOffset);var f=-Math.PI/2+a*2*Math.PI,g=-Math.PI/2+this.progressOffset*2*Math.PI;this.context.save(),this.context.clearRect(0,0,this.diameter,this.diameter),this.context.beginPath(),this.context.arc(c,d,b+2,0,2*Math.PI,!1),this.context.fillStyle="rgba( 0, 0, 0, 0.4 )",this.context.fill(),this.context.beginPath(),this.context.arc(c,d,b,0,2*Math.PI,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#666",this.context.stroke(),this.playing&&(this.context.beginPath(),this.context.arc(c,d,b,g,f,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#fff",this.context.stroke()),this.context.translate(c-e/2,d-e/2),this.playing?(this.context.fillStyle="#fff",this.context.fillRect(0,0,e/2-2,e),this.context.fillRect(e/2+2,0,e/2-2,e)):(this.context.beginPath(),this.context.translate(2,0),this.context.moveTo(0,0),this.context.lineTo(e-2,e/2),this.context.lineTo(0,e),this.context.fillStyle="#fff",this.context.fill()),this.context.restore()},Pb.prototype.on=function(a,b){this.canvas.addEventListener(a,b,!1)},Pb.prototype.off=function(a,b){this.canvas.removeEventListener(a,b,!1)},Pb.prototype.destroy=function(){this.playing=!1,this.canvas.parentNode&&this.container.removeChild(this.canvas)},{initialize:a,configure:h,sync:P,slide:O,left:nb,right:ob,up:pb,down:qb,prev:rb,next:sb,navigateFragment:gb,prevFragment:ib,nextFragment:hb,navigateTo:O,navigateLeft:nb,navigateRight:ob,navigateUp:pb,navigateDown:qb,navigatePrev:rb,navigateNext:sb,layout:A,availableRoutes:Z,availableFragments:$,toggleOverview:G,togglePause:M,isOverview:H,isPaused:N,addEventListeners:i,removeEventListeners:j,getIndices:eb,getSlide:function(a,b){var c=document.querySelectorAll(Yb)[a],d=c&&c.querySelectorAll("section");
+return"undefined"!=typeof b?d?d[b]:void 0:c},getPreviousSlide:function(){return Sb},getCurrentSlide:function(){return Tb},getScale:function(){return cc},getConfig:function(){return _b},getQueryHash:function(){var a={};location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi,function(b){a[b.split("=").shift()]=b.split("=").pop()});for(var b in a){var c=a[b];a[b]=unescape(c),"null"===c?a[b]=null:"true"===c?a[b]=!0:"false"===c?a[b]=!1:c.match(/^\d+$/)&&(a[b]=parseFloat(c))}return a},isFirstSlide:function(){return null==document.querySelector(Xb+".past")?!0:!1},isLastSlide:function(){return Tb?Tb.nextElementSibling?!1:I(Tb)&&Tb.parentNode.nextElementSibling?!1:!0:!1},isReady:function(){return ac},addEventListener:function(a,b,c){"addEventListener"in window&&(dc.wrapper||document.querySelector(".reveal")).addEventListener(a,b,c)},removeEventListener:function(a,b,c){"addEventListener"in window&&(dc.wrapper||document.querySelector(".reveal")).removeEventListener(a,b,c)}}}();
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/css/zenburn.css b/docs/slides/IHP14/_support/reveal.js/lib/css/zenburn.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/lib/css/zenburn.css
@@ -0,0 +1,114 @@
+/*
+
+Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
+based on dark.css by Ivan Sagalaev
+
+*/
+
+pre code {
+  display: block; padding: 0.5em;
+  background: #3F3F3F;
+  color: #DCDCDC;
+}
+
+pre .keyword,
+pre .tag,
+pre .css .class,
+pre .css .id,
+pre .lisp .title,
+pre .nginx .title,
+pre .request,
+pre .status,
+pre .clojure .attribute {
+  color: #E3CEAB;
+}
+
+pre .django .template_tag,
+pre .django .variable,
+pre .django .filter .argument {
+  color: #DCDCDC;
+}
+
+pre .number,
+pre .date {
+  color: #8CD0D3;
+}
+
+pre .dos .envvar,
+pre .dos .stream,
+pre .variable,
+pre .apache .sqbracket {
+  color: #EFDCBC;
+}
+
+pre .dos .flow,
+pre .diff .change,
+pre .python .exception,
+pre .python .built_in,
+pre .literal,
+pre .tex .special {
+  color: #EFEFAF;
+}
+
+pre .diff .chunk,
+pre .subst {
+  color: #8F8F8F;
+}
+
+pre .dos .keyword,
+pre .python .decorator,
+pre .title,
+pre .haskell .type,
+pre .diff .header,
+pre .ruby .class .parent,
+pre .apache .tag,
+pre .nginx .built_in,
+pre .tex .command,
+pre .prompt {
+    color: #efef8f;
+}
+
+pre .dos .winutils,
+pre .ruby .symbol,
+pre .ruby .symbol .string,
+pre .ruby .string {
+  color: #DCA3A3;
+}
+
+pre .diff .deletion,
+pre .string,
+pre .tag .value,
+pre .preprocessor,
+pre .built_in,
+pre .sql .aggregate,
+pre .javadoc,
+pre .smalltalk .class,
+pre .smalltalk .localvars,
+pre .smalltalk .array,
+pre .css .rules .value,
+pre .attr_selector,
+pre .pseudo,
+pre .apache .cbracket,
+pre .tex .formula {
+  color: #CC9393;
+}
+
+pre .shebang,
+pre .diff .addition,
+pre .comment,
+pre .java .annotation,
+pre .template_comment,
+pre .pi,
+pre .doctype {
+  color: #7F9F7F;
+}
+
+pre .coffeescript .javascript,
+pre .javascript .xml,
+pre .tex .formula,
+pre .xml .javascript,
+pre .xml .vbscript,
+pre .xml .css,
+pre .xml .cdata {
+  opacity: 0.5;
+}
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.eot b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.eot
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.eot differ
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.svg b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.svg
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.svg
@@ -0,0 +1,230 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="LeagueGothicRegular" horiz-adv-x="724" >
+<font-face units-per-em="2048" ascent="1505" descent="-543" />
+<missing-glyph horiz-adv-x="315" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="2048" />
+<glyph unicode="&#xd;" horiz-adv-x="682" />
+<glyph unicode=" "  horiz-adv-x="315" />
+<glyph unicode="&#x09;" horiz-adv-x="315" />
+<glyph unicode="&#xa0;" horiz-adv-x="315" />
+<glyph unicode="!" horiz-adv-x="387" d="M74 1505h239l-55 -1099h-129zM86 0v227h215v-227h-215z" />
+<glyph unicode="&#x22;" horiz-adv-x="329" d="M57 1505h215l-30 -551h-154z" />
+<glyph unicode="#" horiz-adv-x="1232" d="M49 438l27 195h198l37 258h-196l26 194h197l57 420h197l-57 -420h260l57 420h197l-58 -420h193l-27 -194h-192l-37 -258h190l-26 -195h-191l-59 -438h-197l60 438h-261l-59 -438h-197l60 438h-199zM471 633h260l37 258h-260z" />
+<glyph unicode="$" horiz-adv-x="692" d="M37 358l192 13q12 -186 129 -187q88 0 93 185q0 74 -61 175q-21 36 -34 53l-40 55q-28 38 -65.5 90t-70.5 101.5t-70.5 141.5t-37.5 170q4 293 215 342v131h123v-125q201 -23 235 -282l-192 -25q-14 129 -93 125q-80 -2 -84 -162q0 -102 94 -227l41 -59q30 -42 37 -52 t33 -48l37 -52q41 -57 68 -109l26 -55q43 -94 43 -186q-4 -338 -245 -369v-217h-123v221q-236 41 -250 352z" />
+<glyph unicode="%" horiz-adv-x="1001" d="M55 911v437q0 110 82 156q33 18 90.5 18t97.5 -44t44 -87l4 -43v-437q0 -107 -81 -157q-32 -19 -77 -19q-129 0 -156 135zM158 0l553 1505h131l-547 -1505h-137zM178 911q-4 -55 37 -55q16 0 25.5 14.5t9.5 26.5v451q2 55 -35 55q-18 0 -27.5 -13.5t-9.5 -27.5v-451z M631 158v436q0 108 81 156q33 20 79 20q125 0 153 -135l4 -41v-436q0 -110 -80 -156q-32 -18 -90.5 -18t-98.5 43t-44 88zM754 158q-4 -57 37 -58q37 0 34 58v436q2 55 -34 55q-18 0 -27.5 -13t-9.5 -28v-450z" />
+<glyph unicode="&#x26;" horiz-adv-x="854" d="M49 304q0 126 44 225.5t126 222.5q-106 225 -106 442v18q0 94 47 180q70 130 223 130q203 0 252 -215q14 -61 12 -113q0 -162 -205 -434q76 -174 148 -285q33 96 47 211l176 -33q-16 -213 -92 -358q55 -63 92 -76v-235q-23 0 -86 37.5t-123 101.5q-123 -139 -252 -139 t-216 97t-87 223zM263 325.5q1 -65.5 28.5 -107.5t78.5 -42t117 86q-88 139 -174 295q-18 -30 -34.5 -98t-15.5 -133.5zM305 1194q0 -111 55 -246q101 156 101 252q-2 2 0 15.5t-2 36t-11 42.5q-19 52 -61.5 52t-62 -38t-19.5 -75v-39z" />
+<glyph unicode="'" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="(" horiz-adv-x="561" d="M66 645q0 143 29.5 292.5t73.5 261.5q92 235 159 343l30 47l162 -84q-38 -53 -86.5 -148t-82.5 -189.5t-61.5 -238t-27.5 -284.5t26.5 -282.5t64.5 -240.5q80 -207 141 -296l26 -39l-162 -84q-41 61 -96 173t-94 217.5t-70.5 257t-31.5 294.5z" />
+<glyph unicode=")" horiz-adv-x="561" d="M41 -213q36 50 85.5 147t83.5 190t61.5 236.5t27.5 284.5t-26.5 282.5t-64.5 240.5q-78 205 -140 298l-27 39l162 84q41 -61 96 -173.5t94 -217t71 -257.5t32 -296t-30 -292.5t-74 -260.5q-92 -233 -159 -342l-30 -47z" />
+<glyph unicode="*" horiz-adv-x="677" d="M74 1251l43 148l164 -70l-19 176h154l-19 -176l164 70l43 -148l-172 -34l115 -138l-131 -80l-78 152l-76 -152l-131 80l115 138z" />
+<glyph unicode="+" horiz-adv-x="1060" d="M74 649v172h370v346h172v-346h371v-172h-371v-346h-172v346h-370z" />
+<glyph unicode="," horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="-" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="." horiz-adv-x="321" d="M53 0v227h215v-227h-215z" />
+<glyph unicode="/" horiz-adv-x="720" d="M8 -147l543 1652h162l-537 -1652h-168z" />
+<glyph unicode="0" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="1" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="2" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="3" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="4" horiz-adv-x="684" d="M25 328v194l323 983h221v-983h103v-194h-103v-328h-202v328h-342zM213 522h154v516h-13z" />
+<glyph unicode="5" horiz-adv-x="704" d="M74 438h221v-59q0 -115 14.5 -159t52 -44t53 45t15.5 156v336q0 111 -70 110q-33 0 -59.5 -40t-26.5 -70h-186v792h535v-219h-344v-313q74 55 127 51q78 0 133 -40t77 -100q35 -98 35 -171v-336q0 -393 -289 -393q-78 0 -133 29.5t-84.5 71.5t-46.5 109q-24 98 -24 244z " />
+<glyph unicode="6" horiz-adv-x="700" d="M66 309v856q0 356 288.5 356.5t288.5 -356.5v-94h-221q0 162 -11.5 210t-53.5 48t-56 -37t-14 -127v-268q59 37 124.5 37t119 -36t75.5 -93q37 -92 37 -189v-307q0 -90 -42 -187q-26 -61 -89 -99.5t-157.5 -38.5t-158 38.5t-88.5 99.5q-42 98 -42 187zM287 244 q0 -20 17.5 -44t49 -24t50 24.5t18.5 43.5v450q0 18 -18.5 43t-49 25t-48 -20.5t-19.5 -41.5v-456z" />
+<glyph unicode="7" horiz-adv-x="589" d="M8 1286v219h557v-221l-221 -1284h-229l225 1286h-332z" />
+<glyph unicode="8" horiz-adv-x="696" d="M53 322v176q0 188 115 297q-102 102 -102 276v127q0 213 147 293q57 31 135 31t135.5 -31t84 -71t42.5 -93q21 -66 21 -129v-127q0 -174 -103 -276q115 -109 115 -297v-176q0 -222 -153 -306q-60 -32 -142 -32t-141.5 32.5t-88 73.5t-44.5 96q-21 69 -21 136zM269 422 q1 -139 16.5 -187.5t57.5 -48.5t59.5 30t21.5 71t4 158t-13.5 174t-66.5 57t-66.5 -57.5t-12.5 -196.5zM284 1116q-1 -123 11 -173t53 -50t53.5 50t12.5 170t-12.5 167t-51.5 47t-52 -44t-14 -167z" />
+<glyph unicode="9" horiz-adv-x="700" d="M57 340v94h222q0 -162 11 -210t53 -48t56.5 37t14.5 127v283q-59 -37 -125 -37t-119 35.5t-76 92.5q-37 96 -37 189v293q0 87 43 188q25 60 88.5 99t157.5 39t157.5 -39t88.5 -99q43 -101 43 -188v-856q0 -356 -289 -356t-289 356zM279 825q0 -18 18 -42.5t49 -24.5 t48.5 20.5t19.5 40.5v443q0 20 -17.5 43.5t-49.5 23.5t-50 -24.5t-18 -42.5v-437z" />
+<glyph unicode=":" horiz-adv-x="362" d="M74 0v227h215v-227h-215zM74 893v227h215v-227h-215z" />
+<glyph unicode=";" horiz-adv-x="362" d="M74 0v227h215v-227l-113 -266h-102l71 266h-71zM74 893v227h215v-227h-215z" />
+<glyph unicode="&#x3c;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="=" horiz-adv-x="1058" d="M74 477v172h911v-172h-911zM74 864v172h911v-172h-911z" />
+<glyph unicode="&#x3e;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="?" horiz-adv-x="645" d="M25 1260q24 67 78 131q105 128 235 122q82 -2 138 -33.5t82 -81.5q46 -88 46 -170.5t-80 -219.5l-57 -96q-18 -32 -42 -106.5t-24 -143.5v-256h-190v256q0 102 24.5 195t48 140t65.5 118t50 105t-9 67.5t-60 34.5t-78 -48t-49 -98zM199 0h215v227h-215v-227z" />
+<glyph unicode="@" horiz-adv-x="872" d="M66 303v889q0 97 73 200q39 56 117 93t184.5 37t184 -37t116.5 -93q74 -105 74 -200v-793h-164l-20 56q-14 -28 -46 -48t-67 -20q-145 0 -145 172v485q0 170 145 170q71 0 113 -67v45q0 51 -45 104.5t-145.5 53.5t-145.5 -53.5t-45 -104.5v-889q0 -53 44 -103t153.5 -50 t160.5 63l152 -86q-109 -143 -320 -143q-106 0 -184 35.5t-117 90.5q-73 102 -73 193zM535 573q0 -53 48 -53t48 53v455q0 53 -48 53t-48 -53v-455z" />
+<glyph unicode="A" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="B" horiz-adv-x="745" d="M82 0v1505h194q205 0 304.5 -91t99.5 -308q0 -106 -29.5 -175t-107.5 -136q14 -5 47 -38.5t54 -71.5q52 -97 52 -259q0 -414 -342 -426h-272zM303 219q74 0 109 31q55 56 55 211t-63 195q-42 26 -93 26h-8v-463zM303 885q87 0 119 39q45 55 45 138t-14.5 124t-30.5 60.5 t-45 28.5q-35 11 -74 11v-401z" />
+<glyph unicode="C" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175z" />
+<glyph unicode="D" horiz-adv-x="761" d="M82 0v1505h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174zM303 221q117 0 140.5 78t23.5 399v111q0 322 -23.5 398.5t-140.5 76.5v-1063z" />
+<glyph unicode="E" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506z" />
+<glyph unicode="F" horiz-adv-x="616" d="M82 0v1505h526v-227h-305v-395h205v-228h-205v-655h-221z" />
+<glyph unicode="G" horiz-adv-x="737" d="M67 271.5q0 26.5 1 37.5v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-231h-221v231q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-905q0 -46 19.5 -78.5t54 -32.5t53 28t18.5 54l2 29v272h-88v187h309v-750h-131l-26 72 q-70 -88 -172 -88q-203 0 -250 213q-11 48 -11 74.5z" />
+<glyph unicode="H" horiz-adv-x="778" d="M82 0v1505h221v-622h172v622h221v-1505h-221v655h-172v-655h-221z" />
+<glyph unicode="I" horiz-adv-x="385" d="M82 0v1505h221v-1505h-221z" />
+<glyph unicode="J" horiz-adv-x="423" d="M12 -14v217q4 0 12.5 -1t29 2t35.5 12t28.5 34.5t13.5 62.5v1192h221v-1226q0 -137 -74 -216q-74 -78 -223 -78h-4q-19 0 -39 1z" />
+<glyph unicode="K" horiz-adv-x="768" d="M82 0v1505h221v-526h8l195 526h215l-203 -495l230 -1010h-216l-153 655l-6 31h-6l-64 -154v-532h-221z" />
+<glyph unicode="L" horiz-adv-x="604" d="M82 0v1505h221v-1300h293v-205h-514z" />
+<glyph unicode="M" horiz-adv-x="991" d="M82 0v1505h270l131 -688l11 -80h4l10 80l131 688h270v-1505h-204v1010h-13l-149 -1010h-94l-142 946l-8 64h-12v-1010h-205z" />
+<glyph unicode="N" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203z" />
+<glyph unicode="O" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="P" horiz-adv-x="720" d="M82 0v1505h221q166 0 277.5 -105.5t111.5 -345t-111.5 -346t-277.5 -106.5v-602h-221zM303 827q102 0 134 45.5t32 175.5t-33 181t-133 51v-453z" />
+<glyph unicode="Q" horiz-adv-x="729" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -94 -45 -182q33 -43 88 -53v-189q-160 0 -227 117q-55 -18 -125 -18t-130 33.5t-88 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887 q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="R" horiz-adv-x="739" d="M82 0v1505h221q377 0 377 -434q0 -258 -123 -342l141 -729h-221l-115 635h-59v-635h-221zM303 840q117 0 149 98q15 49 15 125t-15.5 125t-45.5 68q-44 30 -103 30v-446z" />
+<glyph unicode="S" horiz-adv-x="702" d="M37 422l217 20q0 -256 104 -256q90 0 91 166q0 59 -32 117.5t-45 79.5l-54 79q-40 58 -77 113t-73.5 117t-68 148.5t-31.5 162.5q0 139 71.5 245t216.5 108h10q88 0 152 -36t94 -100q54 -120 54 -264l-217 -20q0 217 -89 217q-75 -2 -75 -146q0 -59 23 -105 q32 -66 58 -104l197 -296q31 -49 67 -139.5t36 -166.5q0 -378 -306 -378h-2q-229 0 -290 188q-31 99 -31 250z" />
+<glyph unicode="T" horiz-adv-x="647" d="M4 1278v227h639v-227h-209v-1278h-221v1278h-209z" />
+<glyph unicode="U" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175z" />
+<glyph unicode="V" horiz-adv-x="716" d="M18 1505h215l111 -827l8 -64h13l118 891h215l-229 -1505h-221z" />
+<glyph unicode="W" horiz-adv-x="1036" d="M25 1505h204l88 -782l5 -49h16l100 831h160l100 -831h17l92 831h205l-203 -1505h-172l-115 801h-8l-115 -801h-172z" />
+<glyph unicode="X" horiz-adv-x="737" d="M16 0l244 791l-240 714h218l120 -381l7 -18h8l127 399h217l-240 -714l244 -791h-217l-127 449l-4 18h-8l-132 -467h-217z" />
+<glyph unicode="Y" horiz-adv-x="700" d="M14 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641z" />
+<glyph unicode="Z" horiz-adv-x="626" d="M20 0v238l347 1048h-297v219h536v-219l-352 -1067h352v-219h-586z" />
+<glyph unicode="[" horiz-adv-x="538" d="M82 -213v1718h399v-196h-202v-1325h202v-197h-399z" />
+<glyph unicode="\" horiz-adv-x="792" d="M8 1692h162l614 -1872h-168z" />
+<glyph unicode="]" horiz-adv-x="538" d="M57 -16h203v1325h-203v196h400v-1718h-400v197z" />
+<glyph unicode="^" horiz-adv-x="1101" d="M53 809l381 696h234l381 -696h-199l-299 543l-299 -543h-199z" />
+<glyph unicode="_" horiz-adv-x="1210" d="M74 -154h1063v-172h-1063v172z" />
+<glyph unicode="`" horiz-adv-x="1024" d="M293 1489h215l106 -184h-159z" />
+<glyph unicode="a" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="b" horiz-adv-x="686" d="M82 0v1505h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-74h-207zM289 246q0 -29 19.5 -48.5t42 -19.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -21.5t-19.5 -46.5v-628z" />
+<glyph unicode="c" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331z" />
+<glyph unicode="d" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v458h207v-1505h-207v74q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 19.5t19.5 48.5v628q0 25 -19.5 46.5t-42 21.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="e" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="f" horiz-adv-x="475" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-65 0 -65 -175v-5v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="g" horiz-adv-x="700" d="M12 -184q0 94 162 170q-125 35 -125 149q0 45 40 93t89 75q-51 35 -80.5 95.5t-34.5 105.5l-4 43v305q0 35 16.5 91t41 94t79 69t126.5 31q135 0 206 -103q102 102 170 103v-185q-72 0 -120 -24l10 -70v-317q0 -37 -17.5 -90.5t-42 -90t-79 -66.5t-104.5 -30t-62 2 q-29 -25 -29 -46t11 -33.5t42 -20.5t45.5 -10t65.5 -10.5t95 -21.5t89 -41q96 -60 96 -205t-103 -212q-100 -65 -250 -65h-9q-156 2 -240 50t-84 165zM213 -150q0 -77 132 -77h3q59 0 108.5 19t49.5 54t-20.5 52.5t-90.5 29.5l-106 21q-76 -43 -76 -99zM262 509 q0 -17 15.5 -45t44.5 -28q63 6 63 101v307q-2 0 0 10q1 3 1 7q0 8 -3 19q-4 15 -9 30q-11 36 -46 36t-50.5 -25.5t-15.5 -52.5v-359z" />
+<glyph unicode="h" horiz-adv-x="690" d="M82 0v1505h207v-479l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="i" horiz-adv-x="370" d="M82 0v1120h207v-1120h-207zM82 1298v207h207v-207h-207z" />
+<glyph unicode="j" horiz-adv-x="364" d="M-45 -182q29 -8 57 -8q64 0 64 142v1168h207v-1149q0 -186 -51 -266q-23 -35 -71 -62.5t-115 -27.5t-91 12v191zM76 1298v207h207v-207h-207z" />
+<glyph unicode="k" horiz-adv-x="641" d="M82 0v1505h207v-714h10l113 329h186l-149 -364l188 -756h-199l-102 453l-4 16h-10l-33 -82v-387h-207z" />
+<glyph unicode="l" horiz-adv-x="370" d="M82 0v1505h207v-1505h-207z" />
+<glyph unicode="m" horiz-adv-x="1021" d="M82 0v1120h207v-94q2 0 33 30q80 81 139 81q100 0 139 -125q125 125 194.5 125t109.5 -69t40 -150v-918h-194v887q-1 49 -56 49q-41 0 -78 -53v-883h-194v887q0 49 -55 49q-41 0 -78 -53v-883h-207z" />
+<glyph unicode="n" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="o" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="p" horiz-adv-x="686" d="M82 -385v1505h207v-73q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="q" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v73h207v-1505h-207v459q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 21.5t19.5 46.5v628q0 29 -19.5 48.5t-42 19.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="r" horiz-adv-x="503" d="M82 0v1120h207v-125q8 41 58.5 91.5t148.5 50.5v-230q-34 11 -77 11t-86.5 -39t-43.5 -101v-778h-207z" />
+<glyph unicode="s" horiz-adv-x="630" d="M37 326h192q0 -170 97 -170q71 0 71 131q0 78 -129 202q-68 66 -98.5 99t-64 101.5t-33.5 134t12 114.5t39 95q59 100 201 104h11q161 0 211 -105q42 -86 42 -198h-193q0 131 -67 131q-63 -2 -64 -131q0 -33 23.5 -73t45 -62.5t66.5 -65.5q190 -182 191 -342 q0 -123 -64.5 -215t-199.5 -92q-197 0 -260 170q-29 76 -29 172z" />
+<glyph unicode="t" horiz-adv-x="501" d="M20 934v186h105v277h207v-277h141v-186h-141v-557q0 -184 65 -184l76 8v-203q-45 -14 -112 -14t-114.5 28.5t-70 64.5t-34.5 96q-17 79 -17 187v574h-105z" />
+<glyph unicode="u" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5z" />
+<glyph unicode="v" horiz-adv-x="602" d="M16 1120h201l68 -649l8 -72h16l76 721h201l-183 -1120h-204z" />
+<glyph unicode="w" horiz-adv-x="905" d="M20 1120h189l65 -585l9 -64h12l96 649h123l86 -585l10 -64h13l73 649h189l-166 -1120h-172l-80 535l-10 63h-8l-91 -598h-172z" />
+<glyph unicode="x" horiz-adv-x="618" d="M16 0l193 578l-176 542h194l74 -262l6 -31h4l6 31l74 262h195l-176 -542l192 -578h-201l-84 283l-6 30h-4l-6 -30l-84 -283h-201z" />
+<glyph unicode="y" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5z" />
+<glyph unicode="z" horiz-adv-x="532" d="M12 0v168l285 764h-240v188h459v-168l-285 -764h285v-188h-504z" />
+<glyph unicode="{" horiz-adv-x="688" d="M61 453v163q72 0 102 49.5t30 90.5v397q0 223 96 298t342 71v-172q-135 2 -188.5 -38t-53.5 -159v-397q0 -143 -127 -221q127 -82 127 -222v-397q0 -119 53.5 -159t188.5 -38v-172q-246 -4 -342 71t-96 298v397q0 57 -41 97.5t-91 42.5z" />
+<glyph unicode="|" horiz-adv-x="356" d="M82 -512v2204h192v-2204h-192z" />
+<glyph unicode="}" horiz-adv-x="688" d="M57 -281q135 -2 188.5 38t53.5 159v397q0 139 127 222q-127 78 -127 221v397q0 119 -53 159t-189 38v172q246 4 342.5 -71t96.5 -298v-397q0 -63 41 -101.5t90 -38.5v-163q-72 -4 -101.5 -52.5t-29.5 -87.5v-397q0 -223 -96.5 -298t-342.5 -71v172z" />
+<glyph unicode="~" horiz-adv-x="1280" d="M113 1352q35 106 115 200q34 41 94.5 74t121 33t116.5 -18.5t82 -33t83 -51.5q106 -72 174 -71q109 0 178 153l13 29l135 -57q-63 -189 -206 -276q-56 -34 -120 -34q-121 0 -272 101q-115 74 -178.5 74t-113.5 -45.5t-69 -90.5l-18 -45z" />
+<glyph unicode="&#xa1;" horiz-adv-x="387" d="M74 -385l55 1100h129l55 -1100h-239zM86 893v227h215v-227h-215z" />
+<glyph unicode="&#xa2;" horiz-adv-x="636" d="M66 508v489q0 297 208 328v242h123v-244q98 -16 144.5 -88t46.5 -227v-88h-189v135q0 90 -72.5 90t-72.5 -90v-604q0 -90 72 -91q74 0 73 91v155h189v-108q0 -156 -46 -228.5t-145 -89.5v-303h-123v301q-209 31 -208 330z" />
+<glyph unicode="&#xa3;" horiz-adv-x="817" d="M4 63q8 20 23.5 53.5t70 91.5t117.5 68q37 111 37 189t-31 184h-188v137h147l-6 21q-78 254 -78 333t15.5 140t48.5 116q72 122 231 126q190 4 267 -126q65 -108 65 -276h-213q0 201 -115 197q-47 -2 -68.5 -51t-21.5 -139.5t70 -315.5l6 -25h211v-137h-174 q25 -100 24.5 -189t-57.5 -204q16 -8 44 -24q59 -35 89 -35q74 4 82 190l188 -22q-12 -182 -81.5 -281.5t-169.5 -99.5q-51 0 -143.5 51t-127.5 51t-63.5 -25.5t-40.5 -52.5l-12 -24z" />
+<glyph unicode="&#xa5;" horiz-adv-x="720" d="M25 1505h217l110 -481l6 -14h4l7 14l110 481h217l-196 -753h147v-138h-176v-137h176v-137h-176v-340h-221v340h-176v137h176v137h-176v138h147z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1024" d="M272 1305v200h191v-200h-191zM561 1305v200h191v-200h-191z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM627 487v531q0 122 97 174q40 22 95 22 q147 0 182 -147l7 -49v-125h-138v142q0 11 -12 28.5t-37 17.5q-47 -2 -49 -63v-531q0 -63 49 -63q53 2 49 63v125h138v-125q0 -68 -40 -127q-18 -26 -57 -47.5t-108.5 -21.5t-117.5 49t-54 98z" />
+<glyph unicode="&#xaa;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xad;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#xae;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM625 313v879h196q231 0 232 -258 q0 -76 -16.5 -125t-71.5 -96l106 -400h-151l-95 365h-55v-365h-145zM770 805h45q43 0 65.5 21.5t27.5 45t5 61.5t-5 62.5t-27.5 46t-65.5 21.5h-45v-258z" />
+<glyph unicode="&#xaf;" horiz-adv-x="1024" d="M313 1315v162h398v-162h-398z" />
+<glyph unicode="&#xb2;" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="&#xb3;" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="&#xb4;" horiz-adv-x="1024" d="M410 1305l106 184h215l-162 -184h-159z" />
+<glyph unicode="&#xb7;" horiz-adv-x="215" d="M0 649v228h215v-228h-215z" />
+<glyph unicode="&#xb8;" horiz-adv-x="1024" d="M426 -111h172v-141l-45 -133h-104l40 133h-63v141z" />
+<glyph unicode="&#xb9;" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="&#xba;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="&#xbf;" horiz-adv-x="645" d="M41 -106q0 82 80 219l57 95q18 32 42 106.5t24 144.5v256h190v-256q0 -102 -24.5 -195.5t-48 -140.5t-65.5 -118t-50 -104.5t9 -67.5t60 -35t78 48.5t49 98.5l179 -84q-24 -66 -78 -132q-104 -126 -236 -122q-163 4 -220 115q-46 90 -46 172zM231 893v227h215v-227h-215z " />
+<glyph unicode="&#xc0;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM141 1823h215l107 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc1;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM293 1638l106 185h215l-161 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc2;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM133 1638l141 185h220l141 -185h-189l-63 72l-61 -72h-189zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc3;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM184 1632v152q49 39 95.5 39t104.5 -18.5t100.5 -19.5t97.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-98 19.5t-102 -33zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc4;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM143 1638v201h191v-201h-191zM307 541h152l-64 475l-6 39h-12zM432 1638v201h191v-201h-191z" />
+<glyph unicode="&#xc5;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM231 1761.5q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM307 541h152l-64 475l-6 39h-12zM309 1761.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50 t-23.5 50t-52.5 21.5t-52.5 -21.5t-23.5 -50z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1099" d="M16 0l420 1505h623v-227h-285v-395h205v-242h-205v-414h285v-227h-506v307h-227l-90 -307h-220zM393 541h160v514h-10z" />
+<glyph unicode="&#xc7;" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM268 -111v-141h64l-41 -133h104l45 133v141h-172z" />
+<glyph unicode="&#xc8;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM111 1823h215l106 -185h-160z" />
+<glyph unicode="&#xc9;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM236 1638l106 185h215l-162 -185h-159z" />
+<glyph unicode="&#xca;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM84 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xcb;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM94 1638v201h191v-201h-191zM383 1638v201h190v-201h-190z" />
+<glyph unicode="&#xcc;" horiz-adv-x="401" d="M-6 1823h215l106 -185h-159zM98 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcd;" horiz-adv-x="401" d="M82 0v1505h221v-1505h-221zM86 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xce;" horiz-adv-x="370" d="M-66 1638l142 185h219l141 -185h-188l-64 72l-61 -72h-189zM74 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcf;" horiz-adv-x="372" d="M-53 1638v201h190v-201h-190zM76 0v1505h221v-1505h-221zM236 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd0;" horiz-adv-x="761" d="M20 655v228h62v622h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174v655h-62zM303 221q117 0 141.5 81t22.5 452q2 371 -22.5 450.5t-141.5 79.5v-401h84v-228h-84v-434z " />
+<glyph unicode="&#xd1;" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203zM207 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39t-102.5 19.5t-100 19.5t-99.5 -33z" />
+<glyph unicode="&#xd2;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM121 1823h215l106 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd3;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM285 1638l106 185h215l-162 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5 t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd4;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM113 1638l141 185h219l141 -185h-188l-64 72l-61 -72h-188zM289 309q0 -46 19.5 -78 t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd5;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM164 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39 t-102.5 19.5t-100 19.5t-99.5 -33zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd6;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM123 1638v201h190v-201h-190zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887zM412 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd8;" d="M59 -20l47 157q-36 74 -36 148l-2 24v887q0 42 17 106t45 107t88.5 78t148 35t153.5 -43l15 47h122l-45 -150q43 -84 43 -155l2 -25v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-150.5 -34.5t-153 43l-15 -47h-129zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v488zM289 727l147 479q-8 100 -74 101q-35 0 -53 -28t-18 -54l-2 -29v-469z" />
+<glyph unicode="&#xd9;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM145 1823h215l107 -185h-160z" />
+<glyph unicode="&#xda;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM307 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xdb;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM125 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xdc;" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175zM135 1638v201h191v-201h-191zM424 1638v201h190v-201h-190z" />
+<glyph unicode="&#xdd;" horiz-adv-x="704" d="M16 1505l226 -864v-641h221v641l225 864h-217l-111 -481l-6 -14h-4l-6 14l-111 481h-217zM254 1638l106 185h215l-161 -185h-160z" />
+<glyph unicode="&#xde;" d="M82 0v1505h219v-241h2q166 0 277.5 -105.5t111.5 -345.5t-111.5 -346.5t-277.5 -106.5v-360h-221zM303 586q102 0 134 45t32 175t-33 181t-133 51v-452z" />
+<glyph unicode="&#xdf;" horiz-adv-x="733" d="M66 0v1235q0 123 70.5 205t206.5 82t204.5 -81t68.5 -197t-88 -181q152 -88 152 -488q0 -362 -87 -475q-46 -59 -102.5 -79.5t-144.5 -20.5v193q45 0 70 25q57 57 57 357q0 316 -57 377q-25 27 -70 27v141q35 0 60.5 33t25.5 84q0 100 -86 100q-74 0 -74 -102v-1235h-206 z" />
+<glyph unicode="&#xe0;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1489h215 l107 -184h-160zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe1;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xe2;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM90 1305 l141 184h220l141 -184h-189l-63 71l-61 -71h-189zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe3;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM143 1305v151 q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe4;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1305v200 h191v-200h-191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM391 1305v200h191v-200h-191z" />
+<glyph unicode="&#xe5;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM188 1421.5 q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM266 1421.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50t-23.5 50t-52.5 21.5t-52.5 -21.5 t-23.5 -50z" />
+<glyph unicode="&#xe6;" horiz-adv-x="989" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t197.5 88q84 0 152 -52q66 51 162 52q199 0 251 -197q14 -51 15 -92v-326h-342v-256q0 -60 38 -88q17 -12 38 -12q70 10 73 113v122h193v-129 q0 -37 -16.5 -93t-41 -95t-80 -69.5t-130.5 -30.5q-158 0 -226 131q-102 -131 -221 -131q-59 0 -112.5 60t-53.5 191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM588 684h149v158q0 48 -19.5 81t-53 33t-53 -28.5t-21.5 -57.5l-2 -28v-158z " />
+<glyph unicode="&#xe7;" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331zM238 -111v-141h63l-41 -133h105l45 133v141h-172z " />
+<glyph unicode="&#xe8;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM102 1489h215l107 -184 h-160zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xe9;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xea;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM80 1305l141 184h219 l142 -184h-189l-63 71l-62 -71h-188zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xeb;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM90 1305v200h191v-200 h-191zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xec;" horiz-adv-x="370" d="M-33 1489h215l107 -184h-160zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xed;" horiz-adv-x="370" d="M82 0h207v1120h-207v-1120zM82 1305l106 184h215l-161 -184h-160z" />
+<glyph unicode="&#xee;" horiz-adv-x="370" d="M-66 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xef;" horiz-adv-x="372" d="M-53 1305v200h190v-200h-190zM82 0v1120h207v-1120h-207zM236 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf0;" horiz-adv-x="673" d="M76 279v579q0 279 172 279q63 0 155 -78q-12 109 -51 203l-82 -72l-55 63l100 88l-45 66l109 100q25 -27 53 -61l94 82l56 -66l-101 -88q125 -201 125 -446v-656q0 -102 -56 -188q-26 -39 -80 -69.5t-129 -30.5t-130 30.5t-80 73.5q-53 91 -53 160zM270 267.5 q-2 -11.5 2 -29t10 -34.5q16 -38 58 -38q70 10 72 113v563q-2 0 0 11t-2 28.5t-10 34.5q-16 40 -60 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf1;" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207zM147 1305v151q49 39 95.5 39t105 -18.5t97 -19.5t100.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#xf2;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM98 1489h215l107 -184h-160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf3;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5 t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM260 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xf4;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM78 1305l141 184h219l142 -184h-189l-63 71l-62 -71h-188zM258 267.5q-2 -11.5 2 -29 t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf5;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM131 1305v151q49 39 95.5 39t104.5 -18.5t98.5 -19.5t98.5 32v-152q-51 -39 -95 -39 t-102 19.5t-101 19.5t-99 -32zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf6;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM90 1305v200h191v-200h-191zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf8;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t118 32t117.5 -19l21 80h75l-30 -121q88 -84 94 -229v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-120.5 -30.5t-112 16l-20 -78h-80l31 121q-41 39 -64.5 97.5t-25.5 97.5zM258 436l125 486q-18 35 -55 34q-68 -10 -70 -114 v-406zM274 197q17 -31 54 -31q70 10 71 113v403z" />
+<glyph unicode="&#xf9;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM113 1489h215l106 -184h-160z" />
+<glyph unicode="&#xfa;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM274 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfb;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM94 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189z" />
+<glyph unicode="&#xfc;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM106 1305v200h191v-200h-191zM395 1305v200h191v-200h-191z" />
+<glyph unicode="&#xfd;" horiz-adv-x="634" d="M25 1120l190 -1153q0 -68 -36 -123t-97 -61l-49 4v-184q70 -4 92 -4q115 0 192.5 95t94.5 222l198 1204h-202l-82 -688l-4 -57h-9l-4 57l-82 688h-202zM231 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfe;" horiz-adv-x="686" d="M82 -385v1890h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="&#xff;" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5zM78 1305v200h190v-200h-190zM367 1305v200h190v-200h-190z" />
+<glyph unicode="&#x152;" horiz-adv-x="983" d="M68 309v887q0 41 17 101.5t45 100.5t88.5 73.5t143.5 33.5h580v-227h-285v-395h205v-242h-205v-414h285v-227h-580q-84 0 -144 31.5t-88 78.5q-55 91 -60 169zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v901q-6 96 -74 97q-35 0 -53 -28t-18 -54l-2 -29 v-887z" />
+<glyph unicode="&#x153;" horiz-adv-x="995" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t145.5 32t156 -60q66 59 170 60q199 0 252 -197q14 -51 14 -92v-326h-342v-250q0 -46 22.5 -76t53.5 -30q70 10 73 113v122h193v-129q0 -37 -16.5 -93t-41 -95t-80 -69.5t-146 -30.5t-154.5 57q-68 -57 -156 -57t-143.5 30.5 t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM594 684h149v158q0 48 -19 81t-58 33t-55.5 -37.5t-16.5 -70.5v-164z" />
+<glyph unicode="&#x178;" horiz-adv-x="704" d="M16 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641zM113 1638v201h190v-201h-190zM401 1638v201h191v-201h-191z" />
+<glyph unicode="&#x2c6;" horiz-adv-x="1021" d="M260 1305l141 184h220l141 -184h-189l-63 71l-61 -71h-189z" />
+<glyph unicode="&#x2dc;" horiz-adv-x="1024" d="M313 1305v151q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#x2000;" horiz-adv-x="952" />
+<glyph unicode="&#x2001;" horiz-adv-x="1905" />
+<glyph unicode="&#x2002;" horiz-adv-x="952" />
+<glyph unicode="&#x2003;" horiz-adv-x="1905" />
+<glyph unicode="&#x2004;" horiz-adv-x="635" />
+<glyph unicode="&#x2005;" horiz-adv-x="476" />
+<glyph unicode="&#x2006;" horiz-adv-x="317" />
+<glyph unicode="&#x2007;" horiz-adv-x="317" />
+<glyph unicode="&#x2008;" horiz-adv-x="238" />
+<glyph unicode="&#x2009;" horiz-adv-x="381" />
+<glyph unicode="&#x200a;" horiz-adv-x="105" />
+<glyph unicode="&#x2010;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2011;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2012;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2013;" horiz-adv-x="806" d="M74 649v195h659v-195h-659z" />
+<glyph unicode="&#x2014;" horiz-adv-x="972" d="M74 649v195h825v-195h-825z" />
+<glyph unicode="&#x2018;" horiz-adv-x="309" d="M49 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x2019;" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="&#x201a;" horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="&#x201c;" horiz-adv-x="624" d="M53 1012v227l113 266h102l-71 -266h71v-227h-215zM356 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x201d;" horiz-adv-x="624" d="M53 1012l72 266h-72v227h215v-227l-112 -266h-103zM356 1012l72 266h-72v227h215v-227l-112 -266h-103z" />
+<glyph unicode="&#x201e;" horiz-adv-x="624" d="M53 0v227h215v-227l-112 -266h-103l72 266h-72zM356 0v227h215v-227l-112 -266h-103l72 266h-72z" />
+<glyph unicode="&#x2022;" horiz-adv-x="663" d="M82 815q0 104 72.5 177t177 73t177.5 -72.5t73 -177t-73 -177.5t-177 -73t-177 73t-73 177z" />
+<glyph unicode="&#x2026;" horiz-adv-x="964" d="M53 0v227h215v-227h-215zM375 0v227h215v-227h-215zM696 0v227h215v-227h-215z" />
+<glyph unicode="&#x202f;" horiz-adv-x="381" />
+<glyph unicode="&#x2039;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="&#x203a;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="&#x205f;" horiz-adv-x="476" />
+<glyph unicode="&#x20ac;" horiz-adv-x="813" d="M53 547v137h107v137h-107v137h107v238q0 42 17.5 106t45 107t88 78t144.5 35t144 -34t88 -81q53 -90 61 -178l2 -33v-84h-207v84q-2 0 0 11.5t-3 27.5t-12 33q-18 39 -69 39q-70 -10 -78 -111v-238h233v-137h-233v-137h233v-137h-233v-238q0 -43 21.5 -76.5t59.5 -33.5 t58.5 27.5t20.5 56.5l2 26v84h207v-84q0 -38 -17.5 -104t-45.5 -109t-88 -77.5t-144 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175l-2 35v238h-107z" />
+<glyph unicode="&#x2122;" horiz-adv-x="937" d="M74 1401v104h321v-104h-104v-580h-113v580h-104zM440 821v684h138l67 -319h6l68 319h137v-684h-104v449l-78 -449h-51l-80 449v-449h-103z" />
+<glyph unicode="&#xe000;" horiz-adv-x="1120" d="M0 0v1120h1120v-1120h-1120z" />
+<glyph unicode="&#xfb01;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2v-184q-41 12 -91 12t-69.5 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h358v-1120h-207v934h-151v-934h-207v934h-105z" />
+<glyph unicode="&#xfb02;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2h164v-1505h-207v1329q-37 4 -67.5 4t-50 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="&#xfb03;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1120h207v-1120h-207zM1032 1298v207h207v-207h-207z" />
+<glyph unicode="&#xfb04;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1505h207v-1505h-207z" />
+</font>
+</defs></svg> 
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.ttf b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.ttf differ
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.woff b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.woff
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic-webfont.woff differ
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic_license b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic_license
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/lib/font/league_gothic_license
@@ -0,0 +1,2 @@
+SIL Open Font License (OFL)
+http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/js/classList.js b/docs/slides/IHP14/_support/reveal.js/lib/js/classList.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/lib/js/classList.js
@@ -0,0 +1,2 @@
+/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
+if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.className),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.className=this.toString()}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(o){o+="";if(g(this,o)===-1){this.push(o);this._updateClassName()}};e.remove=function(p){p+="";var o=g(this,p);if(o!==-1){this.splice(o,1);this._updateClassName()}};e.toggle=function(o){o+="";if(g(this,o)===-1){this.add(o)}else{this.remove(o)}};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/js/head.min.js b/docs/slides/IHP14/_support/reveal.js/lib/js/head.min.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/lib/js/head.min.js
@@ -0,0 +1,8 @@
+/**
+    Head JS     The only script in your <HEAD>
+    Copyright   Tero Piirainen (tipiirai)
+    License     MIT / http://bit.ly/mit-license
+    Version     0.96
+
+    http://headjs.com
+*/(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c<a.length;c++)b.call(a,a[c],c)}}function r(a){var b;if(typeof a=="object")for(var c in a)a[c]&&(b={name:c,url:a[c]});else b={name:q(a),url:a};var d=h[b.name];if(d&&d.url===b.url)return d;h[b.name]=b;return b}function q(a){var b=a.split("/"),c=b[b.length-1],d=c.indexOf("?");return d!=-1?c.substring(0,d):c}function p(a){a._done||(a(),a._done=1)}var b=a.documentElement,c,d,e=[],f=[],g={},h={},i=a.createElement("script").async===!0||"MozAppearance"in a.documentElement.style||window.opera,j=window.head_conf&&head_conf.head||"head",k=window[j]=window[j]||function(){k.ready.apply(null,arguments)},l=1,m=2,n=3,o=4;i?k.js=function(){var a=arguments,b=a[a.length-1],c={};t(b)||(b=null),s(a,function(d,e){d!=b&&(d=r(d),c[d.name]=d,x(d,b&&e==a.length-2?function(){u(c)&&p(b)}:null))});return k}:k.js=function(){var a=arguments,b=[].slice.call(a,1),d=b[0];if(!c){f.push(function(){k.js.apply(null,a)});return k}d?(s(b,function(a){t(a)||w(r(a))}),x(r(a[0]),t(d)?d:function(){k.js.apply(null,b)})):x(r(a[0]));return k},k.ready=function(b,c){if(b==a){d?p(c):e.push(c);return k}t(b)&&(c=b,b="ALL");if(typeof b!="string"||!t(c))return k;var f=h[b];if(f&&f.state==o||b=="ALL"&&u()&&d){p(c);return k}var i=g[b];i?i.push(c):i=g[b]=[c];return k},k.ready(a,function(){u()&&s(g.ALL,function(a){p(a)}),k.feature&&k.feature("domloaded",!0)});if(window.addEventListener)a.addEventListener("DOMContentLoaded",z,!1),window.addEventListener("load",z,!1);else if(window.attachEvent){a.attachEvent("onreadystatechange",function(){a.readyState==="complete"&&z()});var A=1;try{A=window.frameElement}catch(B){}!A&&b.doScroll&&function(){try{b.doScroll("left"),z()}catch(a){setTimeout(arguments.callee,1);return}}(),window.attachEvent("onload",z)}!a.readyState&&a.addEventListener&&(a.readyState="loading",a.addEventListener("DOMContentLoaded",handler=function(){a.removeEventListener("DOMContentLoaded",handler,!1),a.readyState="complete"},!1)),setTimeout(function(){c=!0,s(f,function(a){a()})},300)})(document)
diff --git a/docs/slides/IHP14/_support/reveal.js/lib/js/html5shiv.js b/docs/slides/IHP14/_support/reveal.js/lib/js/html5shiv.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/lib/js/html5shiv.js
@@ -0,0 +1,7 @@
+document.createElement('header');
+document.createElement('nav');
+document.createElement('section');
+document.createElement('article');
+document.createElement('aside');
+document.createElement('footer');
+document.createElement('hgroup');
diff --git a/docs/slides/IHP14/_support/reveal.js/package.json b/docs/slides/IHP14/_support/reveal.js/package.json
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/package.json
@@ -0,0 +1,46 @@
+{
+  "name": "reveal.js",
+  "version": "2.6.2",
+  "description": "The HTML Presentation Framework",
+  "homepage": "http://lab.hakim.se/reveal-js",
+  "subdomain": "revealjs",
+  "scripts": {
+    "test": "grunt test",
+    "start": ""
+  },
+  "author": {
+    "name": "Hakim El Hattab",
+    "email": "hakim.elhattab@gmail.com",
+    "web": "http://hakim.se"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/hakimel/reveal.js.git"
+  },
+  "engines": {
+    "node": "~0.8.0"
+  },
+  "dependencies": {
+    "underscore": "~1.5.1",
+    "express": "~2.5.9",
+    "mustache": "~0.7.2",
+    "socket.io": "~0.9.13"
+  },
+  "devDependencies": {
+    "grunt-contrib-qunit": "~0.2.2",
+    "grunt-contrib-jshint": "~0.6.4",
+    "grunt-contrib-cssmin": "~0.4.1",
+    "grunt-contrib-uglify": "~0.2.4",
+    "grunt-contrib-watch": "~0.5.3",
+    "grunt-contrib-sass": "~0.5.0",
+    "grunt-contrib-connect": "~0.4.1",
+    "grunt-zip": "~0.7.0",
+    "grunt": "~0.4.0"
+  },
+  "licenses": [
+    {
+      "type": "MIT",
+      "url": "https://github.com/hakimel/reveal.js/blob/master/LICENSE"
+    }
+  ]
+}
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/highlight/highlight.js b/docs/slides/IHP14/_support/reveal.js/plugin/highlight/highlight.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/highlight/highlight.js
@@ -0,0 +1,32 @@
+// START CUSTOM REVEAL.JS INTEGRATION
+(function() {
+	if( typeof window.addEventListener === 'function' ) {
+		var hljs_nodes = document.querySelectorAll( 'pre code' );
+
+		for( var i = 0, len = hljs_nodes.length; i < len; i++ ) {
+			var element = hljs_nodes[i];
+
+			// trim whitespace if data-trim attribute is present
+			if( element.hasAttribute( 'data-trim' ) && typeof element.innerHTML.trim === 'function' ) {
+				element.innerHTML = element.innerHTML.trim();
+			}
+
+			// Now escape html unless prevented by author
+			if( ! element.hasAttribute( 'data-noescape' )) {
+				element.innerHTML = element.innerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;");
+			}
+
+			// re-highlight when focus is lost (for edited code)
+			element.addEventListener( 'focusout', function( event ) {
+				hljs.highlightBlock( event.currentTarget );
+			}, false );
+		}
+	}
+})();
+// END CUSTOM REVEAL.JS INTEGRATION
+
+// highlight.js build includes support for:
+// All languages in master + fsharp
+
+
+var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName=="CODE"){return o}if(!(o.nodeType==3&&o.nodeValue.match(/\s+/))){break}}}function h(p,o){return Array.prototype.map.call(p.childNodes,function(q){if(q.nodeType==3){return o?q.nodeValue.replace(/\n/g,""):q.nodeValue}if(q.nodeName=="BR"){return"\n"}return h(q,o)}).join("")}function a(q){var p=(q.className+" "+(q.parentNode?q.parentNode.className:"")).split(/\s+/);p=p.map(function(r){return r.replace(/^language-/,"")});for(var o=0;o<p.length;o++){if(e[p[o]]||p[o]=="no-highlight"){return p[o]}}}function c(q){var o=[];(function p(r,s){for(var t=r.firstChild;t;t=t.nextSibling){if(t.nodeType==3){s+=t.nodeValue.length}else{if(t.nodeName=="BR"){s+=1}else{if(t.nodeType==1){o.push({event:"start",offset:s,node:t});s=p(t,s);o.push({event:"stop",offset:s,node:t})}}}}return s})(q,0);return o}function j(x,v,w){var p=0;var y="";var r=[];function t(){if(x.length&&v.length){if(x[0].offset!=v[0].offset){return(x[0].offset<v[0].offset)?x:v}else{return v[0].event=="start"?x:v}}else{return x.length?x:v}}function s(A){function z(B){return" "+B.nodeName+'="'+l(B.value)+'"'}return"<"+A.nodeName+Array.prototype.map.call(A.attributes,z).join("")+">"}while(x.length||v.length){var u=t().splice(0,1)[0];y+=l(w.substr(p,u.offset-p));p=u.offset;if(u.event=="start"){y+=s(u.node);r.push(u.node)}else{if(u.event=="stop"){var o,q=r.length;do{q--;o=r[q];y+=("</"+o.nodeName.toLowerCase()+">")}while(o!=u.node);r.splice(q,1);while(q<r.length){y+=s(r[q]);q++}}}}return y+l(w.substr(p))}function f(r){function o(s){return(s&&s.source)||s}function p(t,s){return RegExp(o(t),"m"+(r.cI?"i":"")+(s?"g":""))}function q(z,x){if(z.compiled){return}z.compiled=true;var u=[];if(z.k){var s={};function A(B,t){t.split(" ").forEach(function(C){var D=C.split("|");s[D[0]]=[B,D[1]?Number(D[1]):1];u.push(D[0])})}z.lR=p(z.l||hljs.IR+"(?!\\.)",true);if(typeof z.k=="string"){A("keyword",z.k)}else{for(var y in z.k){if(!z.k.hasOwnProperty(y)){continue}A(y,z.k[y])}}z.k=s}if(x){if(z.bWK){z.b="\\b("+u.join("|")+")\\b(?!\\.)\\s*"}z.bR=p(z.b?z.b:"\\B|\\b");if(!z.e&&!z.eW){z.e="\\B|\\b"}if(z.e){z.eR=p(z.e)}z.tE=o(z.e)||"";if(z.eW&&x.tE){z.tE+=(z.e?"|":"")+x.tE}}if(z.i){z.iR=p(z.i)}if(z.r===undefined){z.r=1}if(!z.c){z.c=[]}for(var w=0;w<z.c.length;w++){if(z.c[w]=="self"){z.c[w]=z}q(z.c[w],z)}if(z.starts){q(z.starts,x)}var v=[];for(var w=0;w<z.c.length;w++){v.push(o(z.c[w].b))}if(z.tE){v.push(o(z.tE))}if(z.i){v.push(o(z.i))}z.t=v.length?p(v.join("|"),true):{exec:function(t){return null}}}q(r)}function d(E,F,C){function o(r,N){for(var M=0;M<N.c.length;M++){var L=N.c[M].bR.exec(r);if(L&&L.index==0){return N.c[M]}}}function s(L,r){if(L.e&&L.eR.test(r)){return L}if(L.eW){return s(L.parent,r)}}function t(r,L){return !C&&L.i&&L.iR.test(r)}function y(M,r){var L=G.cI?r[0].toLowerCase():r[0];return M.k.hasOwnProperty(L)&&M.k[L]}function H(){var L=l(w);if(!A.k){return L}var r="";var O=0;A.lR.lastIndex=0;var M=A.lR.exec(L);while(M){r+=L.substr(O,M.index-O);var N=y(A,M);if(N){v+=N[1];r+='<span class="'+N[0]+'">'+M[0]+"</span>"}else{r+=M[0]}O=A.lR.lastIndex;M=A.lR.exec(L)}return r+L.substr(O)}function z(){if(A.sL&&!e[A.sL]){return l(w)}var r=A.sL?d(A.sL,w):g(w);if(A.r>0){v+=r.keyword_count;B+=r.r}return'<span class="'+r.language+'">'+r.value+"</span>"}function K(){return A.sL!==undefined?z():H()}function J(M,r){var L=M.cN?'<span class="'+M.cN+'">':"";if(M.rB){x+=L;w=""}else{if(M.eB){x+=l(r)+L;w=""}else{x+=L;w=r}}A=Object.create(M,{parent:{value:A}})}function D(L,r){w+=L;if(r===undefined){x+=K();return 0}var N=o(r,A);if(N){x+=K();J(N,r);return N.rB?0:r.length}var O=s(A,r);if(O){var M=A;if(!(M.rE||M.eE)){w+=r}x+=K();do{if(A.cN){x+="</span>"}B+=A.r;A=A.parent}while(A!=O.parent);if(M.eE){x+=l(r)}w="";if(O.starts){J(O.starts,"")}return M.rE?0:r.length}if(t(r,A)){throw new Error('Illegal lexem "'+r+'" for mode "'+(A.cN||"<unnamed>")+'"')}w+=r;return r.length||1}var G=e[E];f(G);var A=G;var w="";var B=0;var v=0;var x="";try{var u,q,p=0;while(true){A.t.lastIndex=p;u=A.t.exec(F);if(!u){break}q=D(F.substr(p,u.index-p),u[0]);p=u.index+q}D(F.substr(p));return{r:B,keyword_count:v,value:x,language:E}}catch(I){if(I.message.indexOf("Illegal")!=-1){return{r:0,keyword_count:0,value:l(F)}}else{throw I}}}function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p in e){if(!e.hasOwnProperty(p)){continue}var r=d(p,s,false);r.language=p;if(r.keyword_count+r.r>q.keyword_count+q.r){q=r}if(r.keyword_count+r.r>o.keyword_count+o.r){q=o;o=r}}if(q.language){o.second_best=q}return o}function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\t)+)/gm,function(r,v,u,t){return v.replace(/\t/g,p)})}if(o){q=q.replace(/\n/g,"<br>")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}var w=t?d(t,v,true):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match("(\\s|^)(language-)?"+t+"(\\s|$)")){s=s?(s+" "+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagName("pre"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener("DOMContentLoaded",n,false);window.addEventListener("load",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES["1c"]=function(b){var f="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*";var c="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт";var e="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку  стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон";var a={cN:"dquote",b:'""'};var d={cN:"string",b:'"',e:'"|$',c:[a],r:0};var g={cN:"string",b:"\\|",e:'"|$',c:[a]};return{cI:true,l:f,k:{keyword:c,built_in:e},c:[b.CLCM,b.NM,d,g,{cN:"function",b:"(процедура|функция)",e:"$",l:f,k:"процедура функция",c:[{cN:"title",b:f},{cN:"tail",eW:true,c:[{cN:"params",b:"\\(",e:"\\)",l:f,k:"знач",c:[d,g]},{cN:"export",b:"экспорт",eW:true,l:f,k:"экспорт",c:[b.CLCM]}]},b.CLCM]},{cN:"preprocessor",b:"#",e:"$"},{cN:"date",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}}(hljs);hljs.LANGUAGES.actionscript=function(a){var d="[a-zA-Z_$][a-zA-Z0-9_$]*";var c="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";var e={cN:"rest_arg",b:"[.]{3}",e:d,r:10};var b={cN:"title",b:d};return{k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{cN:"package",bWK:true,e:"{",k:"package",c:[b]},{cN:"class",bWK:true,e:"{",k:"class interface",c:[{bWK:true,k:"extends implements"},b]},{cN:"preprocessor",bWK:true,e:";",k:"import include"},{cN:"function",bWK:true,e:"[{;]",k:"function",i:"\\S",c:[b,{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,e]},{cN:"type",b:":",e:c,r:10}]}]}}(hljs);hljs.LANGUAGES.apache=function(a){var b={cN:"number",b:"[\\$%]\\d+"};return{cI:true,k:{keyword:"acceptfilter acceptmutex acceptpathinfo accessfilename action addalt addaltbyencoding addaltbytype addcharset adddefaultcharset adddescription addencoding addhandler addicon addiconbyencoding addiconbytype addinputfilter addlanguage addmoduleinfo addoutputfilter addoutputfilterbytype addtype alias aliasmatch allow allowconnect allowencodedslashes allowoverride anonymous anonymous_logemail anonymous_mustgiveemail anonymous_nouserid anonymous_verifyemail authbasicauthoritative authbasicprovider authdbduserpwquery authdbduserrealmquery authdbmgroupfile authdbmtype authdbmuserfile authdefaultauthoritative authdigestalgorithm authdigestdomain authdigestnccheck authdigestnonceformat authdigestnoncelifetime authdigestprovider authdigestqop authdigestshmemsize authgroupfile authldapbinddn authldapbindpassword authldapcharsetconfig authldapcomparednonserver authldapdereferencealiases authldapgroupattribute authldapgroupattributeisdn authldapremoteuserattribute authldapremoteuserisdn authldapurl authname authnprovideralias authtype authuserfile authzdbmauthoritative authzdbmtype authzdefaultauthoritative authzgroupfileauthoritative authzldapauthoritative authzownerauthoritative authzuserauthoritative balancermember browsermatch browsermatchnocase bufferedlogs cachedefaultexpire cachedirlength cachedirlevels cachedisable cacheenable cachefile cacheignorecachecontrol cacheignoreheaders cacheignorenolastmod cacheignorequerystring cachelastmodifiedfactor cachemaxexpire cachemaxfilesize cacheminfilesize cachenegotiateddocs cacheroot cachestorenostore cachestoreprivate cgimapextension charsetdefault charsetoptions charsetsourceenc checkcaseonly checkspelling chrootdir contentdigest cookiedomain cookieexpires cookielog cookiename cookiestyle cookietracking coredumpdirectory customlog dav davdepthinfinity davgenericlockdb davlockdb davmintimeout dbdexptime dbdkeep dbdmax dbdmin dbdparams dbdpersist dbdpreparesql dbdriver defaulticon defaultlanguage defaulttype deflatebuffersize deflatecompressionlevel deflatefilternote deflatememlevel deflatewindowsize deny directoryindex directorymatch directoryslash documentroot dumpioinput dumpiologlevel dumpiooutput enableexceptionhook enablemmap enablesendfile errordocument errorlog example expiresactive expiresbytype expiresdefault extendedstatus extfilterdefine extfilteroptions fileetag filterchain filterdeclare filterprotocol filterprovider filtertrace forcelanguagepriority forcetype forensiclog gracefulshutdowntimeout group header headername hostnamelookups identitycheck identitychecktimeout imapbase imapdefault imapmenu include indexheadinsert indexignore indexoptions indexorderdefault indexstylesheet isapiappendlogtoerrors isapiappendlogtoquery isapicachefile isapifakeasync isapilognotsupported isapireadaheadbuffer keepalive keepalivetimeout languagepriority ldapcacheentries ldapcachettl ldapconnectiontimeout ldapopcacheentries ldapopcachettl ldapsharedcachefile ldapsharedcachesize ldaptrustedclientcert ldaptrustedglobalcert ldaptrustedmode ldapverifyservercert limitinternalrecursion limitrequestbody limitrequestfields limitrequestfieldsize limitrequestline limitxmlrequestbody listen listenbacklog loadfile loadmodule lockfile logformat loglevel maxclients maxkeepaliverequests maxmemfree maxrequestsperchild maxrequestsperthread maxspareservers maxsparethreads maxthreads mcachemaxobjectcount mcachemaxobjectsize mcachemaxstreamingbuffer mcacheminobjectsize mcacheremovalalgorithm mcachesize metadir metafiles metasuffix mimemagicfile minspareservers minsparethreads mmapfile mod_gzip_on mod_gzip_add_header_count mod_gzip_keep_workfiles mod_gzip_dechunk mod_gzip_min_http mod_gzip_minimum_file_size mod_gzip_maximum_file_size mod_gzip_maximum_inmem_size mod_gzip_temp_dir mod_gzip_item_include mod_gzip_item_exclude mod_gzip_command_version mod_gzip_can_negotiate mod_gzip_handle_methods mod_gzip_static_suffix mod_gzip_send_vary mod_gzip_update_static modmimeusepathinfo multiviewsmatch namevirtualhost noproxy nwssltrustedcerts nwsslupgradeable options order passenv pidfile protocolecho proxybadheader proxyblock proxydomain proxyerroroverride proxyftpdircharset proxyiobuffersize proxymaxforwards proxypass proxypassinterpolateenv proxypassmatch proxypassreverse proxypassreversecookiedomain proxypassreversecookiepath proxypreservehost proxyreceivebuffersize proxyremote proxyremotematch proxyrequests proxyset proxystatus proxytimeout proxyvia readmename receivebuffersize redirect redirectmatch redirectpermanent redirecttemp removecharset removeencoding removehandler removeinputfilter removelanguage removeoutputfilter removetype requestheader require rewritebase rewritecond rewriteengine rewritelock rewritelog rewriteloglevel rewritemap rewriteoptions rewriterule rlimitcpu rlimitmem rlimitnproc satisfy scoreboardfile script scriptalias scriptaliasmatch scriptinterpretersource scriptlog scriptlogbuffer scriptloglength scriptsock securelisten seerequesttail sendbuffersize serveradmin serveralias serverlimit servername serverpath serverroot serversignature servertokens setenv setenvif setenvifnocase sethandler setinputfilter setoutputfilter ssienableaccess ssiendtag ssierrormsg ssistarttag ssitimeformat ssiundefinedecho sslcacertificatefile sslcacertificatepath sslcadnrequestfile sslcadnrequestpath sslcarevocationfile sslcarevocationpath sslcertificatechainfile sslcertificatefile sslcertificatekeyfile sslciphersuite sslcryptodevice sslengine sslhonorciperorder sslmutex ssloptions sslpassphrasedialog sslprotocol sslproxycacertificatefile sslproxycacertificatepath sslproxycarevocationfile sslproxycarevocationpath sslproxyciphersuite sslproxyengine sslproxymachinecertificatefile sslproxymachinecertificatepath sslproxyprotocol sslproxyverify sslproxyverifydepth sslrandomseed sslrequire sslrequiressl sslsessioncache sslsessioncachetimeout sslusername sslverifyclient sslverifydepth startservers startthreads substitute suexecusergroup threadlimit threadsperchild threadstacksize timeout traceenable transferlog typesconfig unsetenv usecanonicalname usecanonicalphysicalport user userdir virtualdocumentroot virtualdocumentrootip virtualscriptalias virtualscriptaliasip win32disableacceptex xbithack",literal:"on off"},c:[a.HCM,{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",b]},b,{cN:"tag",b:"</?",e:">"},a.QSM]}}(hljs);hljs.LANGUAGES.applescript=function(a){var b=a.inherit(a.QSM,{i:""});var e={cN:"title",b:a.UIR};var d={cN:"params",b:"\\(",e:"\\)",c:["self",a.CNM,b]};var c=[{cN:"comment",b:"--",e:"$",},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",{b:"--",e:"$"}]},a.HCM];return{k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[b,a.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bWK:true,k:"on",i:"[${=;\\n]",c:[e,d]}].concat(c),i:"//"}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);hljs.LANGUAGES.asciidoc=function(a){return{c:[{cN:"comment",b:"^/{4,}\\n",e:"\\n/{4,}$",r:10},{cN:"comment",b:"^//",e:"$",r:0},{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"header",b:"^(={1,5}) .+?( \\1)?$",r:10},{cN:"header",b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$",r:10},{cN:"attribute",b:"^:.+?:",e:"\\s",eE:true,r:10},{cN:"attribute",b:"^\\[.+?\\]$",r:0},{cN:"blockquote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"label",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{cN:"horizontal_rule",b:"^'{4,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:true,c:[{b:"(link|image:?):",r:0},{cN:"link_url",b:"\\w",e:"[^\\[]+",r:0},{cN:"link_label",b:"\\[",e:"\\]",eB:true,eE:true,r:0}],r:10}]}}(hljs);hljs.LANGUAGES.avrasm=function(a){return{cI:true,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf"},c:[a.CBLCLM,{cN:"comment",b:";",e:"$"},a.CNM,a.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"label",b:"^[A-Za-z0-9_.$]+:"},{cN:"preprocessor",b:"#",e:"$"},{cN:"preprocessor",b:"\\.[a-zA-Z]+"},{cN:"localvars",b:"@[0-9]+"}]}}(hljs);hljs.LANGUAGES.axapta=function(a){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"{",i:":",k:"class interface",c:[{cN:"inheritance",bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]}]}}(hljs);hljs.LANGUAGES.bash=function(a){var c={cN:"variable",b:/\$[\w\d#@][\w\d_]*/};var b={cN:"variable",b:/\$\{(.*?)\}/};var e={cN:"string",b:/"/,e:/"/,c:[a.BE,c,b,{cN:"variable",b:/\$\(/,e:/\)/,c:a.BE}],r:0};var d={cN:"string",b:/'/,e:/'/,r:0};return{l:/-?[a-z]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[{cN:"title",b:/\w[\w\d_]*/}],r:0},a.HCM,a.NM,e,d,c,b]}}(hljs);hljs.LANGUAGES.brainfuck=function(a){return{c:[{cN:"comment",b:"[^\\[\\]\\.,\\+\\-<> \r\n]",eE:true,e:"[\\[\\]\\.,\\+\\-<> \r\n]",r:0},{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]"},{cN:"literal",b:"[\\+\\-]"}]}}(hljs);hljs.LANGUAGES.clojure=function(l){var e={built_in:"def cond apply if-not if-let if not not= = &lt; < > &lt;= <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for doseq dosync dotimes and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import intern refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! import use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if throw printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time ns assert re-find re-groups rand-int rand mod locking assert-valid-fdecl alias namespace resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! memfn to-array future future-call into-array aset gen-class reduce merge map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"};var f="[a-zA-Z_0-9\\!\\.\\?\\-\\+\\*\\/\\<\\=\\>\\&\\#\\$';]+";var a="[\\s:\\(\\{]+\\d+(\\.\\d+)?";var d={cN:"number",b:a,r:0};var j={cN:"string",b:'"',e:'"',c:[l.BE],r:0};var o={cN:"comment",b:";",e:"$",r:0};var n={cN:"collection",b:"[\\[\\{]",e:"[\\]\\}]"};var c={cN:"comment",b:"\\^"+f};var b={cN:"comment",b:"\\^\\{",e:"\\}"};var h={cN:"attribute",b:"[:]"+f};var m={cN:"list",b:"\\(",e:"\\)"};var g={eW:true,k:{literal:"true false nil"},r:0};var i={k:e,l:f,cN:"title",b:f,starts:g};m.c=[{cN:"comment",b:"comment"},i];g.c=[m,j,c,b,o,h,n,d];n.c=[m,j,c,o,h,n,d];return{i:"\\S",c:[o,m]}}(hljs);hljs.LANGUAGES.cmake=function(a){return{cI:true,k:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file",c:[{cN:"envvar",b:"\\${",e:"}"},a.HCM,a.QSM,a.NM]}}(hljs);hljs.LANGUAGES.coffeescript=function(c){var b={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module exports global window document"};var a="[A-Za-z$_][0-9A-Za-z$_]*";var f={cN:"title",b:a};var e={cN:"subst",b:"#\\{",e:"}",k:b,};var d=[c.BNM,c.inherit(c.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",b:"'''",e:"'''",c:[c.BE]},{cN:"string",b:"'",e:"'",c:[c.BE],r:0},{cN:"string",b:'"""',e:'"""',c:[c.BE,e]},{cN:"string",b:'"',e:'"',c:[c.BE,e],r:0},{cN:"regexp",b:"///",e:"///",c:[c.HCM]},{cN:"regexp",b:"//[gim]*",r:0},{cN:"regexp",b:"/\\S(\\\\.|[^\\n])*?/[gim]*(?=\\s|\\W|$)"},{cN:"property",b:"@"+a},{b:"`",e:"`",eB:true,eE:true,sL:"javascript"}];e.c=d;return{k:b,c:d.concat([{cN:"comment",b:"###",e:"###"},c.HCM,{cN:"function",b:"("+a+"\\s*=\\s*)?(\\(.*\\))?\\s*[-=]>",e:"[-=]>",rB:true,c:[f,{cN:"params",b:"\\(",rB:true,c:[{b:/\(/,e:/\)/,k:b,c:["self"].concat(d)}]}]},{cN:"class",bWK:true,k:"class",e:"$",i:"[:\\[\\]]",c:[{bWK:true,k:"extends",eW:true,i:":",c:[f]},f]},{cN:"attribute",b:a+":",e:":",rB:true,eE:true}])}}(hljs);hljs.LANGUAGES.cpp=function(a){var b={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long throw volatile static protected bool template mutable if public friend do return goto auto void enum else break new extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'\\\\?.",e:"'",i:"."},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},a.CNM,{cN:"preprocessor",b:"#",e:"$",c:[{b:"<",e:">",i:"\\n"},a.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,r:10,c:["self"]}]}}(hljs);hljs.LANGUAGES.cs=function(a){return{k:"abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async await ascending descending from get group into join let orderby partial select set value var where yield",c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"}]},a.CLCM,a.CBLCLM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},a.ASM,a.QSM,a.CNM]}}(hljs);hljs.LANGUAGES.css=function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.NM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}}(hljs);hljs.LANGUAGES.d=function(x){var b={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"};var c="(0|[1-9][\\d_]*)",q="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",h="0[bB][01_]+",v="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",y="0[xX]"+v,p="([eE][+-]?"+q+")",o="("+q+"(\\.\\d*|"+p+")|\\d+\\."+q+q+"|\\."+c+p+"?)",k="(0[xX]("+v+"\\."+v+"|\\.?"+v+")[pP][+-]?"+q+")",l="("+c+"|"+h+"|"+y+")",n="("+k+"|"+o+")";var z="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};";var m={cN:"number",b:"\\b"+l+"(L|u|U|Lu|LU|uL|UL)?",r:0};var j={cN:"number",b:"\\b("+n+"([fF]|L|i|[fF]i|Li)?|"+l+"(i|[fF]i|Li))",r:0};var s={cN:"string",b:"'("+z+"|.)",e:"'",i:"."};var r={b:z,r:0};var w={cN:"string",b:'"',c:[r],e:'"[cwd]?',r:0};var f={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5};var u={cN:"string",b:"`",e:"`[cwd]?"};var i={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10};var t={cN:"string",b:'q"\\{',e:'\\}"'};var e={cN:"shebang",b:"^#!",e:"$",r:5};var g={cN:"preprocessor",b:"#(line)",e:"$",r:5};var d={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"};var a={cN:"comment",b:"\\/\\+",c:["self"],e:"\\+\\/",r:10};return{l:x.UIR,k:b,c:[x.CLCM,x.CBLCLM,a,i,w,f,u,t,j,m,s,e,g,d]}}(hljs);hljs.LANGUAGES.delphi=function(b){var f="and safecall cdecl then string exports library not pascal set virtual file in array label packed end. index while const raise for to implementation with except overload destructor downto finally program exit unit inherited override if type until function do begin repeat goto nil far initialization object else var uses external resourcestring interface end finalization class asm mod case on shr shl of register xorwrite threadvar try record near stored constructor stdcall inline div out or procedure";var e="safecall stdcall pascal stored const implementation finalization except to finally program inherited override then exports string read not mod shr try div shl set library message packed index for near overload label downto exit public goto interface asm on of constructor or private array unit raise destructor var type until function else external with case default record while protected property procedure published and cdecl do threadvar file in if end virtual write far out begin repeat nil initialization object uses resourcestring class register xorwrite inline static";var a={cN:"comment",b:"{",e:"}",r:0};var g={cN:"comment",b:"\\(\\*",e:"\\*\\)",r:10};var c={cN:"string",b:"'",e:"'",c:[{b:"''"}],r:0};var d={cN:"string",b:"(#\\d+)+"};var h={cN:"function",bWK:true,e:"[:;]",k:"function constructor|10 destructor|10 procedure|10",c:[{cN:"title",b:b.IR},{cN:"params",b:"\\(",e:"\\)",k:f,c:[c,d]},a,g]};return{cI:true,k:f,i:'("|\\$[G-Zg-z]|\\/\\*|</)',c:[a,g,b.CLCM,c,d,b.NM,h,{cN:"class",b:"=\\bclass\\b",e:"end;",k:e,c:[c,d,a,g,b.CLCM,h]}]}}(hljs);hljs.LANGUAGES.diff=function(a){return{c:[{cN:"chunk",b:"^\\@\\@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +\\@\\@$",r:10},{cN:"chunk",b:"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$",r:10},{cN:"chunk",b:"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$",r:10},{cN:"header",b:"Index: ",e:"$"},{cN:"header",b:"=====",e:"=====$"},{cN:"header",b:"^\\-\\-\\-",e:"$"},{cN:"header",b:"^\\*{3} ",e:"$"},{cN:"header",b:"^\\+\\+\\+",e:"$"},{cN:"header",b:"\\*{5}",e:"\\*{5}$"},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}(hljs);hljs.LANGUAGES.django=function(c){function e(h,g){return(g==undefined||(!h.cN&&g.cN=="tag")||h.cN=="value")}function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}if(e(l,k)){m=b.concat(m)}if(m.length){g.c=m}}return g}var d={cN:"filter",b:"\\|[A-Za-z]+\\:?",k:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone",c:[{cN:"argument",b:'"',e:'"'}]};var b=[{cN:"template_comment",b:"{%\\s*comment\\s*%}",e:"{%\\s*endcomment\\s*%}"},{cN:"template_comment",b:"{#",e:"#}"},{cN:"template_tag",b:"{%",e:"%}",k:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor in ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup by as ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim",c:[d]},{cN:"variable",b:"{{",e:"}}",c:[d]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.dos=function(a){return{cI:true,k:{flow:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",keyword:"shift cd dir echo setlocal endlocal set pause copy",stream:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux",winutils:"ping net ipconfig taskkill xcopy ren del"},c:[{cN:"envvar",b:"%%[^ ]"},{cN:"envvar",b:"%[^ ]+?%"},{cN:"envvar",b:"![^ ]+?!"},{cN:"number",b:"\\b\\d+",r:0},{cN:"comment",b:"@?rem",e:"$"}]}}(hljs);hljs.LANGUAGES["erlang-repl"]=function(a){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},{cN:"comment",b:"%",e:"$"},{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a.ASM,a.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}}(hljs);hljs.LANGUAGES.erlang=function(i){var c="[a-z'][a-zA-Z0-9_']*";var o="("+c+":"+c+"|"+c+")";var f={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun let not of orelse|10 query receive rem try when xor",literal:"false true"};var l={cN:"comment",b:"%",e:"$",r:0};var e={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0};var g={b:"fun\\s+"+c+"/\\d+"};var n={b:o+"\\(",e:"\\)",rB:true,r:0,c:[{cN:"function_name",b:o,r:0},{b:"\\(",e:"\\)",eW:true,rE:true,r:0}]};var h={cN:"tuple",b:"{",e:"}",r:0};var a={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0};var m={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0};var b={b:"#",e:"}",i:".",r:0,rB:true,c:[{cN:"record_name",b:"#"+i.UIR,r:0},{b:"{",eW:true,r:0}]};var k={k:f,b:"(fun|receive|if|try|case)",e:"end"};k.c=[l,g,i.inherit(i.ASM,{cN:""}),k,n,i.QSM,e,h,a,m,b];var j=[l,g,k,n,i.QSM,e,h,a,m,b];n.c[1].c=j;h.c=j;b.c[1].c=j;var d={cN:"params",b:"\\(",e:"\\)",c:j};return{k:f,i:"(</|\\*=|\\+=|-=|/=|/\\*|\\*/|\\(\\*|\\*\\))",c:[{cN:"function",b:"^"+c+"\\s*\\(",e:"->",rB:true,i:"\\(|#|//|/\\*|\\\\|:",c:[d,{cN:"title",b:c}],starts:{e:";|\\.",k:f,c:j}},l,{cN:"pp",b:"^-",e:"\\.",r:0,eE:true,rB:true,l:"-"+i.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior",c:[d]},e,i.QSM,b,a,m,h]}}(hljs);hljs.LANGUAGES.fsharp=function(a){var b="'[a-zA-Z0-9_]+";return{k:"yield! return! let! do!abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun|10 function global if in inherit inline interface internal lazy let match member module mutable|10 namespace new null of open or override private public rec|10 return sig static struct then to true try type upcast use val void when while with yield",c:[{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},{cN:"comment",b:"//",e:"$",rB:true},{cN:"comment",b:"\\(\\*",e:"\\*\\)"},{cN:"class",bWK:true,e:"\\(|=|$",k:"type",c:[{cN:"title",b:a.UIR}]},{cN:"annotation",b:"\\[<",e:">\\]",r:10},{cN:"typeparam",b:"<",e:">",c:[{cN:"title",b:b}]},a.CLCM,a.CBLCLM,a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),a.CNM]}}(hljs);hljs.LANGUAGES.glsl=function(a){return{k:{keyword:"atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly",built_in:"gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffsetgl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse",literal:"true false"},i:'"',c:[a.CLCM,a.CBLCLM,a.CNM,{cN:"preprocessor",b:"#",e:"$"}]}}(hljs);hljs.LANGUAGES.go=function(a){var b={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer",constant:"true false iota nil",typename:"bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"string",b:"`",e:"`"},{cN:"number",b:"[^a-zA-Z_0-9](\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?",r:0},a.CNM]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.haml=function(a){return{cI:true,c:[{cN:"doctype",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},{cN:"comment",b:"^\\s*(-#|/).*$",r:0},{b:"^\\s*-(?!#)",starts:{e:"\\n",sL:"ruby"},r:0},{cN:"tag",b:"^\\s*%",c:[{cN:"title",b:"\\w+",r:0},{cN:"value",b:"[#\\.]\\w+",r:0},{b:"{\\s*",e:"\\s*}",eE:true,c:[{b:":\\w+\\s*=>",e:",\\s+",rB:true,eW:true,r:0,c:[{cN:"symbol",b:":\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0},{b:"\\(\\s*",e:"\\s*\\)",eE:true,c:[{b:"\\w+\\s*=",e:"\\s+",rB:true,eW:true,r:0,c:[{cN:"attribute",b:"\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0}],r:10},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"},r:0}]}}(hljs);hljs.LANGUAGES.handlebars=function(c){function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}m=d.concat(m);if(m.length){g.c=m}}return g}var b="each in with if else unless bindattr action collection debugger log outlet template unbound view yield";var e={cN:"variable",b:"[a-zA-Z.]+",k:b};var d=[{cN:"expression",b:"{{",e:"}}",c:[{cN:"begin-block",b:"#[a-zA-Z .]+",k:b},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z .]+",k:b},{cN:"variable",b:"[a-zA-Z.]+",k:b}]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.haskell=function(a){var d={cN:"type",b:"\\b[A-Z][\\w']*",r:0};var c={cN:"container",b:"\\(",e:"\\)",i:'"',c:[{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},{cN:"title",b:"[_a-z][\\w']*"}]};var b={cN:"container",b:"{",e:"}",c:c.c};return{k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance not as foreign ccall safe unsafe",c:[{cN:"comment",b:"--",e:"$"},{cN:"preprocessor",b:"{-#",e:"#-}"},{cN:"comment",c:["self"],b:"{-",e:"-}"},{cN:"string",b:"\\s+'",e:"'",c:[a.BE],r:0},a.QSM,{cN:"import",b:"\\bimport",e:"$",k:"import qualified as hiding",c:[c],i:"\\W\\.|;"},{cN:"module",b:"\\bmodule",e:"where",k:"module where",c:[c],i:"\\W\\.|;"},{cN:"class",b:"\\b(class|instance)",e:"where",k:"class where instance",c:[d]},{cN:"typedef",b:"\\b(data|(new)?type)",e:"$",k:"data type newtype deriving",c:[d,c,b]},a.CNM,{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},d,{cN:"title",b:"^[_a-z][\\w']*"},{b:"->|<-"}]}}(hljs);hljs.LANGUAGES.http=function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}}(hljs);hljs.LANGUAGES.ini=function(a){return{cI:true,i:"[^\\s]",c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:"on off true false yes no",c:[a.QSM,a.NM],r:0}]}]}}(hljs);hljs.LANGUAGES.java=function(a){return{k:"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,{cN:"class",bWK:true,e:"{",k:"class interface",eE:true,i:":",c:[{bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]},a.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}}(hljs);hljs.LANGUAGES.javascript=function(a){return{k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const",literal:"true false null undefined NaN Infinity"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,a.REGEXP_MODE,{b:/</,e:/>;/,sL:"xml"}],r:0},{cN:"function",bWK:true,e:/{/,k:"function",c:[{cN:"title",b:/[A-Za-z$_][0-9A-Za-z$_]*/},{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBLCLM],i:/["'\(]/}],i:/\[|%/}]}}(hljs);hljs.LANGUAGES.json=function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}}(hljs);hljs.LANGUAGES.lasso=function(b){var a="[a-zA-Z_][a-zA-Z0-9_.]*|&[lg]t;";var c="<\\?(lasso(script)?|=)";return{cI:true,l:a,k:{literal:"true false none minimal full all infinity nan and or not bw ew cn lt lte gt gte eq neq ft rx nrx",built_in:"array date decimal duration integer map pair string tag xml null list queue set stack staticarray local var variable data global self inherited void",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require skip split_thread sum take thread to trait type where with yield"},c:[{cN:"preprocessor",b:"\\]|\\?>",r:0,starts:{cN:"markup",e:"\\[|"+c,rE:true}},{cN:"preprocessor",b:"\\[noprocess\\]",starts:{cN:"markup",e:"\\[/noprocess\\]",rE:true}},{cN:"preprocessor",b:"\\[no_square_brackets|\\[/noprocess|"+c},{cN:"preprocessor",b:"\\[",r:0},{cN:"shebang",b:"^#!.+lasso9\\b",r:10},b.CLCM,{cN:"javadoc",b:"/\\*\\*!",e:"\\*/"},b.CBLCLM,b.CNM,b.inherit(b.ASM,{i:null}),b.inherit(b.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{cN:"variable",b:"#\\d+|[#$]"+a},{cN:"tag",b:"::",e:a},{cN:"attribute",b:"\\.\\.\\.|-"+b.UIR},{cN:"class",bWK:true,k:"define",eE:true,e:"\\(|=>",c:[{cN:"title",b:b.UIR+"=?"}]}]}}(hljs);hljs.LANGUAGES.lisp=function(i){var l="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*";var m="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?";var k={cN:"shebang",b:"^#!",e:"$"};var a={cN:"literal",b:"\\b(t{1}|nil)\\b"};var d=[{cN:"number",b:m},{cN:"number",b:"#b[0-1]+(/[0-1]+)?"},{cN:"number",b:"#o[0-7]+(/[0-7]+)?"},{cN:"number",b:"#x[0-9a-f]+(/[0-9a-f]+)?"},{cN:"number",b:"#c\\("+m+" +"+m,e:"\\)"}];var h={cN:"string",b:'"',e:'"',c:[i.BE],r:0};var n={cN:"comment",b:";",e:"$"};var g={cN:"variable",b:"\\*",e:"\\*"};var o={cN:"keyword",b:"[:&]"+l};var b={b:"\\(",e:"\\)",c:["self",a,h].concat(d)};var e={cN:"quoted",b:"['`]\\(",e:"\\)",c:d.concat([h,g,o,b])};var c={cN:"quoted",b:"\\(quote ",e:"\\)",k:{title:"quote"},c:d.concat([h,g,o,b])};var j={cN:"list",b:"\\(",e:"\\)"};var f={eW:true,r:0};j.c=[{cN:"title",b:l},f];f.c=[e,c,j,a].concat(d).concat([h,n,g,o]);return{i:"[^\\s]",c:d.concat([k,a,h,n,e,c,j])}}(hljs);hljs.LANGUAGES.lua=function(b){var a="\\[=*\\[";var e="\\]=*\\]";var c={b:a,e:e,c:["self"]};var d=[{cN:"comment",b:"--(?!"+a+")",e:"$"},{cN:"comment",b:"--"+a,e:e,c:[c],r:10}];return{l:b.UIR,k:{keyword:"and break do else elseif end false for if in local nil not or repeat return then true until while",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},c:d.concat([{cN:"function",bWK:true,e:"\\)",k:"function",c:[{cN:"title",b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"},{cN:"params",b:"\\(",eW:true,c:d}].concat(d)},b.CNM,b.ASM,b.QSM,{cN:"string",b:a,e:e,c:[c],r:10}])}}(hljs);hljs.LANGUAGES.markdown=function(a){return{c:[{cN:"header",b:"^#{1,3}",e:"$"},{cN:"header",b:"^.+?\\n[=-]{2,}$"},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",b:"\\*.+?\\*"},{cN:"emphasis",b:"_.+?_",r:0},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",b:"`.+?`"},{cN:"code",b:"^    ",e:"$",r:0},{cN:"horizontal_rule",b:"^-{3,}",e:"$"},{b:"\\[.+?\\]\\(.+?\\)",rB:true,c:[{cN:"link_label",b:"\\[.+\\]"},{cN:"link_url",b:"\\(",e:"\\)",eB:true,eE:true}]}]}}(hljs);hljs.LANGUAGES.matlab=function(a){var b=[a.CNM,{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0}];return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bWK:true,e:"$",k:"function",c:[{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)"},{cN:"params",b:"\\[",e:"\\]"}]},{cN:"transposed_variable",b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:""},{cN:"matrix",b:"\\[",e:"\\]'*[\\.']*",c:b},{cN:"cell",b:"\\{",e:"\\}'*[\\.']*",c:b},{cN:"comment",b:"\\%",e:"$"}].concat(b)}}(hljs);hljs.LANGUAGES.mel=function(a){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:"</",c:[a.CNM,a.ASM,a.QSM,{cN:"string",b:"`",e:"`",c:[a.BE]},{cN:"variable",b:"\\$\\d",r:5},{cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+|[^\\s\\w{]|{\\w+}|\\w+)"},a.CLCM,a.CBLCLM]}}(hljs);hljs.LANGUAGES.mizar=function(a){return{k:["environ vocabularies notations constructors definitions registrations theorems schemes requirements","begin end definition registration cluster existence pred func defpred deffunc theorem proof","let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from","be being by means equals implies iff redefine define now not or attr is mode suppose per cases set","thesis contradiction scheme reserve struct","correctness compatibility coherence symmetry assymetry reflexivity irreflexivity","connectedness uniqueness commutativity idempotence involutiveness projectivity"].join(" "),c:[{cN:"comment",b:"::",e:"$"}]}}(hljs);hljs.LANGUAGES.nginx=function(b){var c=[{cN:"variable",b:"\\$\\d+"},{cN:"variable",b:"\\${",e:"}"},{cN:"variable",b:"[\\$\\@]"+b.UIR}];var a={eW:true,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[b.HCM,{cN:"string",b:'"',e:'"',c:[b.BE].concat(c),r:0},{cN:"string",b:"'",e:"'",c:[b.BE].concat(c),r:0},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:true,eE:true},{cN:"regexp",b:"\\s\\^",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"~\\*?\\s+",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"\\*(\\.[a-z\\-]+)+",c:[b.BE].concat(c)},{cN:"regexp",b:"([a-z\\-]+\\.)+\\*",c:[b.BE].concat(c)},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0}].concat(c)};return{c:[b.HCM,{b:b.UIR+"\\s",e:";|{",rB:true,c:[{cN:"title",b:b.UIR,starts:a}],r:0}],i:"[^\\s\\}]"}}(hljs);hljs.LANGUAGES.objectivec=function(a){var b={keyword:"int float while private char catch export sizeof typedef const struct for union unsigned long volatile static protected bool mutable if public do return goto void enum else break extern asm case short default double throw register explicit signed typename try this switch continue wchar_t inline readonly assign property self synchronized end synthesize id optional required nonatomic super unichar finally dynamic IBOutlet IBAction selector strong weak readonly",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection UIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.CNM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"preprocessor",b:"#import",e:"$",c:[{cN:"title",b:'"',e:'"'},{cN:"title",b:"<",e:">"}]},{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"({|$)",k:"interface class protocol implementation",c:[{cN:"id",b:a.UIR}]},{cN:"variable",b:"\\."+a.UIR,r:0}]}}(hljs);hljs.LANGUAGES.parser3=function(a){return{sL:"xml",r:0,c:[{cN:"comment",b:"^#",e:"$"},{cN:"comment",b:"\\^rem{",e:"}",r:10,c:[{b:"{",e:"}",c:["self"]}]},{cN:"preprocessor",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},a.CNM]}}(hljs);hljs.LANGUAGES.perl=function(e){var a="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when";var d={cN:"subst",b:"[$@]\\{",e:"\\}",k:a,r:10};var b={cN:"variable",b:"\\$\\d"};var i={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var f=[e.BE,d,b,i];var h={b:"->",c:[{b:e.IR},{b:"{",e:"}"}]};var g={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5};var c=[b,i,e.HCM,g,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:true},h,{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:f,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:f,r:5},{cN:"string",b:"'",e:"'",c:[e.BE],r:0},{cN:"string",b:'"',e:'"',c:f,r:0},{cN:"string",b:"`",e:"`",c:[e.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"("+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,g,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bWK:true,e:"(\\s*\\(.*?\\))?[;{]",k:"sub",r:5},{cN:"operator",b:"-\\w\\b",r:0}];d.c=c;h.c[1].c=c;return{k:a,c:c}}(hljs);hljs.LANGUAGES.php=function(a){var e={cN:"variable",b:"\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"};var b=[a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),{cN:"string",b:'b"',e:'"',c:[a.BE]},{cN:"string",b:"b'",e:"'",c:[a.BE]}];var c=[a.BNM,a.CNM];var d={cN:"title",b:a.UIR};return{cI:true,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return implements parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception php_user_filter default die require __FUNCTION__ enddeclare final try this switch continue endfor endif declare unset true false namespace trait goto instanceof insteadof __DIR__ __NAMESPACE__ __halt_compiler",c:[a.CLCM,a.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"}]},{cN:"comment",eB:true,b:"__halt_compiler.+?;",eW:true},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[a.BE]},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"},e,{cN:"function",bWK:true,e:"{",k:"function",i:"\\$|\\[|%",c:[d,{cN:"params",b:"\\(",e:"\\)",c:["self",e,a.CBLCLM].concat(b).concat(c)}]},{cN:"class",bWK:true,e:"{",k:"class",i:"[:\\(\\$]",c:[{bWK:true,eW:true,k:"extends",c:[d]},d]},{b:"=>"}].concat(b).concat(c)}}(hljs);hljs.LANGUAGES.profile=function(a){return{c:[a.CNM,{cN:"built_in",b:"{",e:"}$",eB:true,eE:true,c:[a.ASM,a.QSM],r:0},{cN:"filename",b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:true},{cN:"header",b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{cN:"summary",b:"function calls",e:"$",c:[a.CNM],r:10},a.ASM,a.QSM,{cN:"function",b:"\\(",e:"\\)$",c:[{cN:"title",b:a.UIR,r:0}],r:0}]}}(hljs);hljs.LANGUAGES.python=function(a){var f={cN:"prompt",b:/^(>>>|\.\.\.) /};var c=[{cN:"string",b:/(u|b)?r?'''/,e:/'''/,c:[f],r:10},{cN:"string",b:/(u|b)?r?"""/,e:/"""/,c:[f],r:10},{cN:"string",b:/(u|r|ur)'/,e:/'/,c:[a.BE],r:10},{cN:"string",b:/(u|r|ur)"/,e:/"/,c:[a.BE],r:10},{cN:"string",b:/(b|br)'/,e:/'/,c:[a.BE]},{cN:"string",b:/(b|br)"/,e:/"/,c:[a.BE]}].concat([a.ASM,a.QSM]);var e={cN:"title",b:a.UIR};var d={cN:"params",b:/\(/,e:/\)/,c:["self",a.CNM,f].concat(c)};var b={bWK:true,e:/:/,i:/[${=;\n]/,c:[e,d],r:10};return{k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10",built_in:"None True False Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:c.concat([f,a.HCM,a.inherit(b,{cN:"function",k:"def"}),a.inherit(b,{cN:"class",k:"class"}),a.CNM,{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}])}}(hljs);hljs.LANGUAGES.r=function(a){var b="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[a.HCM,{b:b,l:b,k:{keyword:"function if in break next repeat else for return switch while try tryCatch|10 stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...|10",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",b:'"',e:'"',c:[a.BE],r:0},{cN:"string",b:"'",e:"'",c:[a.BE],r:0}]}}(hljs);hljs.LANGUAGES.rib=function(a){return{k:"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd",i:"</",c:[a.HCM,a.CNM,a.ASM,a.QSM]}}(hljs);hljs.LANGUAGES.rsl=function(a){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,a.ASM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"shader",bWK:true,e:"\\(",k:"surface displacement light volume imager"},{cN:"shading",bWK:true,e:"\\(",k:"illuminate illuminance gather"}]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.ruleslanguage=function(a){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEMASK|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN DELETE SAVE SAVE_UPDATE CLEAR DETERMINANT LABEL REPORT REVENUE ABORT CALL DONE LEAVE EACH IN LIST NOVALUE FROM TOTAL CHARGE BLOCK AND OR CSV_FILE BILL_PERIOD RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM ABORT WARN NUMDAYS RATE_CODE READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}}(hljs);hljs.LANGUAGES.rust=function(b){var d={cN:"title",b:b.UIR};var c={cN:"number",b:"\\b(0[xb][A-Za-z0-9_]+|[0-9_]+(\\.[0-9_]+)?([uif](8|16|32|64)?)?)",r:0};var a="assert bool break char check claim comm const cont copy dir do drop else enum extern export f32 f64 fail false float fn for i16 i32 i64 i8 if impl int let log loop match mod move mut priv pub pure ref return self static str struct task true trait type u16 u32 u64 u8 uint unsafe use vec while";return{k:a,i:"</",c:[b.CLCM,b.CBLCLM,b.inherit(b.QSM,{i:null}),b.ASM,c,{cN:"function",bWK:true,e:"(\\(|<)",k:"fn",c:[d]},{cN:"preprocessor",b:"#\\[",e:"\\]"},{bWK:true,e:"(=|<)",k:"type",c:[d],i:"\\S"},{bWK:true,e:"({|<)",k:"trait enum",c:[d],i:"\\S"}]}}(hljs);hljs.LANGUAGES.scala=function(a){var c={cN:"annotation",b:"@[A-Za-z]+"};var b={cN:"string",b:'u?r?"""',e:'"""',r:10};return{k:"type yield lazy override def with val var false true sealed abstract private trait object null if for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,b,{cN:"class",b:"((case )?class |object |trait )",e:"({|$)",i:":",k:"case class trait object",c:[{bWK:true,k:"extends with",r:10},{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,b,c]}]},a.CNM,c]}}(hljs);hljs.LANGUAGES.scss=function(a){var c="[a-zA-Z-][a-zA-Z0-9_-]*";var d={cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};var b={cN:"hexcolor",b:"#[0-9A-Fa-f]+"};var e={cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[d,b,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"important",b:"!important"}]}};return{cI:true,i:"[=/|']",c:[a.CLCM,a.CBLCLM,{cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]},{cN:"id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{cN:"pseudo",b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{cN:"pseudo",b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{cN:"value",b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{cN:"value",b:":",e:";",c:[b,a.NM,a.QSM,a.ASM,{cN:"important",b:"!important"}]},{cN:"at_rule",b:"@",e:"[{;]",k:"mixin include for extend charset import media page font-face namespace",c:[d,a.QSM,a.ASM,b,a.NM,{cN:"preprocessor",b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}}(hljs);hljs.LANGUAGES.smalltalk=function(a){var b="[a-z][a-zA-Z0-9_]*";var d={cN:"char",b:"\\$.{1}"};var c={cN:"symbol",b:"#"+a.UIR};return{k:"self super nil true false thisContext",c:[{cN:"comment",b:'"',e:'"',r:0},a.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:b+":"},a.CNM,c,d,{cN:"localvars",b:"\\|\\s*"+b+"(\\s+"+b+")*\\s*\\|"},{cN:"array",b:"\\#\\(",e:"\\)",c:[a.ASM,d,a.CNM,c]}]}}(hljs);hljs.LANGUAGES.sql=function(a){return{cI:true,c:[{cN:"operator",b:"(begin|end|start|commit|rollback|savepoint|lock|alter|create|drop|rename|call|delete|do|handler|insert|load|replace|select|truncate|update|set|show|pragma|grant)\\b(?!:)",e:";",eW:true,k:{keyword:"all partial global month current_timestamp using go revoke smallint indicator end-exec disconnect zone with character assertion to add current_user usage input local alter match collate real then rollback get read timestamp session_user not integer bit unique day minute desc insert execute like ilike|2 level decimal drop continue isolation found where constraints domain right national some module transaction relative second connect escape close system_user for deferred section cast current sqlstate allocate intersect deallocate numeric public preserve full goto initially asc no key output collation group by union session both last language constraint column of space foreign deferrable prior connection unknown action commit view or first into float year primary cascaded except restrict set references names table outer open select size are rows from prepare distinct leading create only next inner authorization schema corresponding option declare precision immediate else timezone_minute external varying translation true case exception join hour default double scroll value cursor descriptor values dec fetch procedure delete and false int is describe char as at in varchar null trailing any absolute current_time end grant privileges when cross check write current_date pad begin temporary exec time update catalog user sql date on identity timezone_hour natural whenever interval work order cascade diagnostics nchar having left call do handler load replace truncate start lock show pragma exists number trigger if before after each row",aggregate:"count sum min max avg"},c:[{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0},{cN:"string",b:'"',e:'"',c:[a.BE,{b:'""'}],r:0},{cN:"string",b:"`",e:"`",c:[a.BE]},a.CNM]},a.CBLCLM,{cN:"comment",b:"--",e:"$"}]}}(hljs);hljs.LANGUAGES.tex=function(a){var d={cN:"command",b:"\\\\[a-zA-Zа-яА-я]+[\\*]?"};var c={cN:"command",b:"\\\\[^a-zA-Zа-яА-я0-9]"};var b={cN:"special",b:"[{}\\[\\]\\&#~]",r:0};return{c:[{b:"\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",rB:true,c:[d,c,{cN:"number",b:" *=",e:"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",eB:true}],r:10},d,c,b,{cN:"formula",b:"\\$\\$",e:"\\$\\$",c:[d,c,b],r:0},{cN:"formula",b:"\\$",e:"\\$",c:[d,c,b],r:0},{cN:"comment",b:"%",e:"$",r:0}]}}(hljs);hljs.LANGUAGES.vala=function(a){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object",literal:"false true null"},c:[{cN:"class",bWK:true,e:"{",k:"class interface delegate namespace",i:"[^,:\\n\\s\\.]",c:[{cN:"title",b:a.UIR}]},a.CLCM,a.CBLCLM,{cN:"string",b:'"""',e:'"""',r:5},a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"^#",e:"$",r:2},{cN:"constant",b:" [A-Z_]+ ",r:0}]}}(hljs);hljs.LANGUAGES.vbnet=function(a){return{cI:true,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"(//|endif|gosub|variant|wend)",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"'''|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"},]},a.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end region externalsource"},]}}(hljs);hljs.LANGUAGES.vbscript=function(a){return{cI:true,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$"},a.CNM]}}(hljs);hljs.LANGUAGES.vhdl=function(a){return{cI:true,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",typename:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[a.CBLCLM,{cN:"comment",b:"--",e:"$"},a.QSM,a.CNM,{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[a.BE]},{cN:"attribute",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[a.BE]}]}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/leap/leap.js b/docs/slides/IHP14/_support/reveal.js/plugin/leap/leap.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/leap/leap.js
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2013, Leap Motion, Inc.
+ * 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 HOLDER 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.
+ *
+ * Version 0.2.0 - http://js.leapmotion.com/0.2.0/leap.min.js
+ * Grab latest versions from http://js.leapmotion.com/
+ */
+
+!function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i}({1:[function(require,module,exports){var chooseProtocol=require("./protocol").chooseProtocol,EventEmitter=require("events").EventEmitter,_=require("underscore");var BaseConnection=module.exports=function(opts){this.opts=_.defaults(opts||{},{host:"127.0.0.1",enableGestures:false,port:6437,enableHeartbeat:true,heartbeatInterval:100,requestProtocolVersion:3});this.host=opts.host;this.port=opts.port;this.on("ready",function(){this.enableGestures(this.opts.enableGestures);if(this.opts.enableHeartbeat)this.startHeartbeat()});this.on("disconnect",function(){if(this.opts.enableHeartbeat)this.stopHeartbeat()});this.heartbeatTimer=null};BaseConnection.prototype.getUrl=function(){return"ws://"+this.host+":"+this.port+"/v"+this.opts.requestProtocolVersion+".json"};BaseConnection.prototype.sendHeartbeat=function(){if(this.protocol){this.setHeartbeatState(true);this.protocol.sendHeartbeat(this)}};BaseConnection.prototype.handleOpen=function(){this.emit("connect")};BaseConnection.prototype.enableGestures=function(enabled){this.gesturesEnabled=enabled?true:false;this.send(this.protocol.encode({enableGestures:this.gesturesEnabled}))};BaseConnection.prototype.handleClose=function(){this.disconnect();this.startReconnection()};BaseConnection.prototype.startReconnection=function(){var connection=this;setTimeout(function(){connection.connect()},1e3)};BaseConnection.prototype.disconnect=function(){if(!this.socket)return;this.socket.close();delete this.socket;delete this.protocol;this.emit("disconnect")};BaseConnection.prototype.handleData=function(data){var message=JSON.parse(data);var messageEvent;if(this.protocol===undefined){messageEvent=this.protocol=chooseProtocol(message);this.emit("ready")}else{messageEvent=this.protocol(message)}this.emit(messageEvent.type,messageEvent)};BaseConnection.prototype.connect=function(){if(this.socket)return;this.socket=this.setupSocket();return true};BaseConnection.prototype.send=function(data){this.socket.send(data)};BaseConnection.prototype.stopHeartbeat=function(){if(!this.heartbeatTimer)return;clearInterval(this.heartbeatTimer);delete this.heartbeatTimer;this.setHeartbeatState(false)};BaseConnection.prototype.setHeartbeatState=function(state){if(this.heartbeatState===state)return;this.heartbeatState=state;this.emit(this.heartbeatState?"focus":"blur")};_.extend(BaseConnection.prototype,EventEmitter.prototype)},{"./protocol":12,events:17,underscore:20}],2:[function(require,module,exports){var CircularBuffer=module.exports=function(size){this.pos=0;this._buf=[];this.size=size};CircularBuffer.prototype.get=function(i){if(i==undefined)i=0;if(i>=this.size)return undefined;if(i>=this._buf.length)return undefined;return this._buf[(this.pos-i-1)%this.size]};CircularBuffer.prototype.push=function(o){this._buf[this.pos%this.size]=o;return this.pos++}},{}],3:[function(require,module,exports){var Connection=module.exports=require("./base_connection");Connection.prototype.setupSocket=function(){var connection=this;var socket=new WebSocket(this.getUrl());socket.onopen=function(){connection.handleOpen()};socket.onmessage=function(message){connection.handleData(message.data)};socket.onclose=function(){connection.handleClose()};return socket};Connection.prototype.startHeartbeat=function(){if(!this.protocol.sendHeartbeat||this.heartbeatTimer)return;var connection=this;var propertyName=null;if(typeof document.hidden!=="undefined"){propertyName="hidden"}else if(typeof document.mozHidden!=="undefined"){propertyName="mozHidden"}else if(typeof document.msHidden!=="undefined"){propertyName="msHidden"}else if(typeof document.webkitHidden!=="undefined"){propertyName="webkitHidden"}else{propertyName=undefined}var windowVisible=true;var focusListener=window.addEventListener("focus",function(e){windowVisible=true});var blurListener=window.addEventListener("blur",function(e){windowVisible=false});this.on("disconnect",function(){if(connection.heartbeatTimer){clearTimeout(connection.heartbeatTimer);delete connection.heartbeatTimer}window.removeEventListener(focusListener);window.removeEventListener(blurListener)});this.heartbeatTimer=setInterval(function(){var isVisible=propertyName===undefined?true:document[propertyName]===false;if(isVisible&&windowVisible){connection.sendHeartbeat()}else{connection.setHeartbeatState(false)}},this.opts.heartbeatInterval)}},{"./base_connection":1}],4:[function(require,module,exports){!function(process){var Frame=require("./frame"),CircularBuffer=require("./circular_buffer"),Pipeline=require("./pipeline"),EventEmitter=require("events").EventEmitter,gestureListener=require("./gesture").gestureListener,_=require("underscore");var Controller=module.exports=function(opts){var inNode=typeof process!=="undefined"&&process.title==="node";opts=_.defaults(opts||{},{inNode:inNode});this.inNode=opts.inNode;opts=_.defaults(opts||{},{frameEventName:this.useAnimationLoop()?"animationFrame":"deviceFrame",supressAnimationLoop:false});this.supressAnimationLoop=opts.supressAnimationLoop;this.frameEventName=opts.frameEventName;this.history=new CircularBuffer(200);this.lastFrame=Frame.Invalid;this.lastValidFrame=Frame.Invalid;this.lastConnectionFrame=Frame.Invalid;this.accumulatedGestures=[];if(opts.connectionType===undefined){this.connectionType=this.inBrowser()?require("./connection"):require("./node_connection")}else{this.connectionType=opts.connectionType}this.connection=new this.connectionType(opts);this.setupConnectionEvents()};Controller.prototype.gesture=function(type,cb){var creator=gestureListener(this,type);if(cb!==undefined){creator.stop(cb)}return creator};Controller.prototype.inBrowser=function(){return!this.inNode};Controller.prototype.useAnimationLoop=function(){return this.inBrowser()&&typeof chrome==="undefined"};Controller.prototype.connect=function(){var controller=this;if(this.connection.connect()&&this.inBrowser()&&!controller.supressAnimationLoop){var callback=function(){controller.emit("animationFrame",controller.lastConnectionFrame);window.requestAnimFrame(callback)};window.requestAnimFrame(callback)}};Controller.prototype.disconnect=function(){this.connection.disconnect()};Controller.prototype.frame=function(num){return this.history.get(num)||Frame.Invalid};Controller.prototype.loop=function(callback){switch(callback.length){case 1:this.on(this.frameEventName,callback);break;case 2:var controller=this;var scheduler=null;var immediateRunnerCallback=function(frame){callback(frame,function(){if(controller.lastFrame!=frame){immediateRunnerCallback(controller.lastFrame)}else{controller.once(controller.frameEventName,immediateRunnerCallback)}})};this.once(this.frameEventName,immediateRunnerCallback);break}this.connect()};Controller.prototype.addStep=function(step){if(!this.pipeline)this.pipeline=new Pipeline(this);this.pipeline.addStep(step)};Controller.prototype.processFrame=function(frame){if(frame.gestures){this.accumulatedGestures=this.accumulatedGestures.concat(frame.gestures)}if(this.pipeline){frame=this.pipeline.run(frame);if(!frame)frame=Frame.Invalid}this.lastConnectionFrame=frame;this.emit("deviceFrame",frame)};Controller.prototype.processFinishedFrame=function(frame){this.lastFrame=frame;if(frame.valid){this.lastValidFrame=frame}frame.controller=this;frame.historyIdx=this.history.push(frame);if(frame.gestures){frame.gestures=this.accumulatedGestures;this.accumulatedGestures=[];for(var gestureIdx=0;gestureIdx!=frame.gestures.length;gestureIdx++){this.emit("gesture",frame.gestures[gestureIdx],frame)}}this.emit("frame",frame)};Controller.prototype.setupConnectionEvents=function(){var controller=this;this.connection.on("frame",function(frame){controller.processFrame(frame)});this.on(this.frameEventName,function(frame){controller.processFinishedFrame(frame)});this.connection.on("disconnect",function(){controller.emit("disconnect")});this.connection.on("ready",function(){controller.emit("ready")});this.connection.on("connect",function(){controller.emit("connect")});this.connection.on("focus",function(){controller.emit("focus")});this.connection.on("blur",function(){controller.emit("blur")});this.connection.on("protocol",function(protocol){controller.emit("protocol",protocol)});this.connection.on("deviceConnect",function(evt){controller.emit(evt.state?"deviceConnected":"deviceDisconnected")})};_.extend(Controller.prototype,EventEmitter.prototype)}(require("__browserify_process"))},{"./circular_buffer":2,"./connection":3,"./frame":5,"./gesture":6,"./node_connection":16,"./pipeline":10,__browserify_process:18,events:17,underscore:20}],5:[function(require,module,exports){var Hand=require("./hand"),Pointable=require("./pointable"),createGesture=require("./gesture").createGesture,glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,InteractionBox=require("./interaction_box"),_=require("underscore");var Frame=module.exports=function(data){this.valid=true;this.id=data.id;this.timestamp=data.timestamp;this.hands=[];this.handsMap={};this.pointables=[];this.tools=[];this.fingers=[];if(data.interactionBox){this.interactionBox=new InteractionBox(data.interactionBox)}this.gestures=[];this.pointablesMap={};this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.data=data;this.type="frame";this.currentFrameRate=data.currentFrameRate;var handMap={};for(var handIdx=0,handCount=data.hands.length;handIdx!=handCount;handIdx++){var hand=new Hand(data.hands[handIdx]);hand.frame=this;this.hands.push(hand);this.handsMap[hand.id]=hand;handMap[hand.id]=handIdx}for(var pointableIdx=0,pointableCount=data.pointables.length;pointableIdx!=pointableCount;pointableIdx++){var pointable=new Pointable(data.pointables[pointableIdx]);pointable.frame=this;this.pointables.push(pointable);this.pointablesMap[pointable.id]=pointable;(pointable.tool?this.tools:this.fingers).push(pointable);if(pointable.handId!==undefined&&handMap.hasOwnProperty(pointable.handId)){var hand=this.hands[handMap[pointable.handId]];hand.pointables.push(pointable);(pointable.tool?hand.tools:hand.fingers).push(pointable)}}if(data.gestures){for(var gestureIdx=0,gestureCount=data.gestures.length;gestureIdx!=gestureCount;gestureIdx++){this.gestures.push(createGesture(data.gestures[gestureIdx]))}}};Frame.prototype.tool=function(id){var pointable=this.pointable(id);return pointable.tool?pointable:Pointable.Invalid};Frame.prototype.pointable=function(id){return this.pointablesMap[id]||Pointable.Invalid};Frame.prototype.finger=function(id){var pointable=this.pointable(id);return!pointable.tool?pointable:Pointable.Invalid};Frame.prototype.hand=function(id){return this.handsMap[id]||Hand.Invalid};Frame.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Frame.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceFrame._rotation[5],this._rotation[2]-sinceFrame._rotation[6],this._rotation[3]-sinceFrame._rotation[1]])};Frame.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);return mat3.multiply(mat3.create(),sinceFrame._rotation,transpose)};Frame.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;return Math.exp(this._scaleFactor-sinceFrame._scaleFactor)};Frame.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.subtract(vec3.create(),this._translation,sinceFrame._translation)};Frame.prototype.toString=function(){var str="Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")";if(this.gestures)str+=" | Gesture count:("+this.gestures.length+")";str+=" ]";return str};Frame.prototype.dump=function(){var out="";out+="Frame Info:<br/>";out+=this.toString();out+="<br/><br/>Hands:<br/>";for(var handIdx=0,handCount=this.hands.length;handIdx!=handCount;handIdx++){out+="  "+this.hands[handIdx].toString()+"<br/>"}out+="<br/><br/>Pointables:<br/>";for(var pointableIdx=0,pointableCount=this.pointables.length;pointableIdx!=pointableCount;pointableIdx++){out+="  "+this.pointables[pointableIdx].toString()+"<br/>"}if(this.gestures){out+="<br/><br/>Gestures:<br/>";for(var gestureIdx=0,gestureCount=this.gestures.length;gestureIdx!=gestureCount;gestureIdx++){out+="  "+this.gestures[gestureIdx].toString()+"<br/>"}}out+="<br/><br/>Raw JSON:<br/>";out+=JSON.stringify(this.data);return out};Frame.Invalid={valid:false,hands:[],fingers:[],tools:[],gestures:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},hand:function(){return Hand.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"gl-matrix":19,underscore:20}],6:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3,EventEmitter=require("events").EventEmitter,_=require("underscore");var createGesture=exports.createGesture=function(data){var gesture;switch(data.type){case"circle":gesture=new CircleGesture(data);break;case"swipe":gesture=new SwipeGesture(data);break;case"screenTap":gesture=new ScreenTapGesture(data);break;case"keyTap":gesture=new KeyTapGesture(data);break;default:throw"unkown gesture type"}gesture.id=data.id;gesture.handIds=data.handIds;gesture.pointableIds=data.pointableIds;gesture.duration=data.duration;gesture.state=data.state;gesture.type=data.type;return gesture};var gestureListener=exports.gestureListener=function(controller,type){var handlers={};var gestureMap={};var gestureCreator=function(){var candidateGesture=gestureMap[gesture.id];if(candidateGesture!==undefined)gesture.update(gesture,frame);if(gesture.state=="start"||gesture.state=="stop"){if(type==gesture.type&&gestureMap[gesture.id]===undefined){gestureMap[gesture.id]=new Gesture(gesture,frame);gesture.update(gesture,frame)}if(gesture.state=="stop"){delete gestureMap[gesture.id]}}};controller.on("gesture",function(gesture,frame){if(gesture.type==type){if(gesture.state=="start"||gesture.state=="stop"){if(gestureMap[gesture.id]===undefined){var gestureTracker=new Gesture(gesture,frame);gestureMap[gesture.id]=gestureTracker;_.each(handlers,function(cb,name){gestureTracker.on(name,cb)})}}gestureMap[gesture.id].update(gesture,frame);if(gesture.state=="stop"){delete gestureMap[gesture.id]}}});var builder={start:function(cb){handlers["start"]=cb;return builder},stop:function(cb){handlers["stop"]=cb;return builder},complete:function(cb){handlers["stop"]=cb;return builder},update:function(cb){handlers["update"]=cb;return builder}};return builder};var Gesture=exports.Gesture=function(gesture,frame){this.gestures=[gesture];this.frames=[frame]};Gesture.prototype.update=function(gesture,frame){this.gestures.push(gesture);this.frames.push(frame);this.emit(gesture.state,this)};_.extend(Gesture.prototype,EventEmitter.prototype);var CircleGesture=function(data){this.center=data.center;this.normal=data.normal;this.progress=data.progress;this.radius=data.radius};CircleGesture.prototype.toString=function(){return"CircleGesture ["+JSON.stringify(this)+"]"};var SwipeGesture=function(data){this.startPosition=data.startPosition;this.position=data.position;this.direction=data.direction;this.speed=data.speed};SwipeGesture.prototype.toString=function(){return"SwipeGesture ["+JSON.stringify(this)+"]"};var ScreenTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};ScreenTapGesture.prototype.toString=function(){return"ScreenTapGesture ["+JSON.stringify(this)+"]"};var KeyTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};KeyTapGesture.prototype.toString=function(){return"KeyTapGesture ["+JSON.stringify(this)+"]"}},{events:17,"gl-matrix":19,underscore:20}],7:[function(require,module,exports){var Pointable=require("./pointable"),glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,_=require("underscore");var Hand=module.exports=function(data){this.id=data.id;this.palmPosition=data.palmPosition;this.direction=data.direction;this.palmVelocity=data.palmVelocity;this.palmNormal=data.palmNormal;this.sphereCenter=data.sphereCenter;this.sphereRadius=data.sphereRadius;this.valid=true;this.pointables=[];this.fingers=[];this.tools=[];this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.timeVisible=data.timeVisible;this.stabilizedPalmPosition=data.stabilizedPalmPosition};Hand.prototype.finger=function(id){var finger=this.frame.finger(id);return finger&&finger.handId==this.id?finger:Pointable.Invalid};Hand.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Hand.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceHand._rotation[5],this._rotation[2]-sinceHand._rotation[6],this._rotation[3]-sinceHand._rotation[1]])};Hand.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);var m=mat3.multiply(mat3.create(),sinceHand._rotation,transpose);return m};Hand.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 1;return Math.exp(this._scaleFactor-sinceHand._scaleFactor)};Hand.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return[this._translation[0]-sinceHand._translation[0],this._translation[1]-sinceHand._translation[1],this._translation[2]-sinceHand._translation[2]]};Hand.prototype.toString=function(){return"Hand [ id: "+this.id+" | palm velocity:"+this.palmVelocity+" | sphere center:"+this.sphereCenter+" ] "};Hand.Invalid={valid:false,fingers:[],tools:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./pointable":11,"gl-matrix":19,underscore:20}],8:[function(require,module,exports){!function(){module.exports={Controller:require("./controller"),Frame:require("./frame"),Gesture:require("./gesture"),Hand:require("./hand"),Pointable:require("./pointable"),InteractionBox:require("./interaction_box"),Connection:require("./connection"),CircularBuffer:require("./circular_buffer"),UI:require("./ui"),glMatrix:require("gl-matrix"),mat3:require("gl-matrix").mat3,vec3:require("gl-matrix").vec3,loopController:undefined,loop:function(opts,callback){if(callback===undefined){callback=opts;opts={}}if(!this.loopController)this.loopController=new this.Controller(opts);this.loopController.loop(callback)}}}()},{"./circular_buffer":2,"./connection":3,"./controller":4,"./frame":5,"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"./ui":13,"gl-matrix":19}],9:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var InteractionBox=module.exports=function(data){this.valid=true;this.center=data.center;this.size=data.size;this.width=data.size[0];this.height=data.size[1];this.depth=data.size[2]};InteractionBox.prototype.denormalizePoint=function(normalizedPosition){return vec3.fromValues((normalizedPosition[0]-.5)*this.size[0]+this.center[0],(normalizedPosition[1]-.5)*this.size[1]+this.center[1],(normalizedPosition[2]-.5)*this.size[2]+this.center[2])};InteractionBox.prototype.normalizePoint=function(position,clamp){var vec=vec3.fromValues((position[0]-this.center[0])/this.size[0]+.5,(position[1]-this.center[1])/this.size[1]+.5,(position[2]-this.center[2])/this.size[2]+.5);if(clamp){vec[0]=Math.min(Math.max(vec[0],0),1);vec[1]=Math.min(Math.max(vec[1],0),1);vec[2]=Math.min(Math.max(vec[2],0),1)}return vec};InteractionBox.prototype.toString=function(){return"InteractionBox [ width:"+this.width+" | height:"+this.height+" | depth:"+this.depth+" ]"};InteractionBox.Invalid={valid:false}},{"gl-matrix":19}],10:[function(require,module,exports){var Pipeline=module.exports=function(){this.steps=[]};Pipeline.prototype.addStep=function(step){this.steps.push(step)};Pipeline.prototype.run=function(frame){var stepsLength=this.steps.length;for(var i=0;i!=stepsLength;i++){if(!frame)break;frame=this.steps[i](frame)}return frame}},{}],11:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var Pointable=module.exports=function(data){this.valid=true;this.id=data.id;this.handId=data.handId;this.length=data.length;this.tool=data.tool;this.width=data.width;this.direction=data.direction;this.stabilizedTipPosition=data.stabilizedTipPosition;this.tipPosition=data.tipPosition;this.tipVelocity=data.tipVelocity;this.touchZone=data.touchZone;this.touchDistance=data.touchDistance;this.timeVisible=data.timeVisible};Pointable.prototype.toString=function(){if(this.tool==true){return"Pointable [ id:"+this.id+" "+this.length+"mmx | with:"+this.width+"mm | direction:"+this.direction+" ]"}else{return"Pointable [ id:"+this.id+" "+this.length+"mmx | direction: "+this.direction+" ]"}};Pointable.Invalid={valid:false}},{"gl-matrix":19}],12:[function(require,module,exports){var Frame=require("./frame");var Event=function(data){this.type=data.type;this.state=data.state};var chooseProtocol=exports.chooseProtocol=function(header){var protocol;switch(header.version){case 1:protocol=JSONProtocol(1,function(data){return new Frame(data)});break;case 2:protocol=JSONProtocol(2,function(data){return new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;case 3:protocol=JSONProtocol(3,function(data){return data.event?new Event(data.event):new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;default:throw"unrecognized version"}return protocol};var JSONProtocol=function(version,cb){var protocol=cb;protocol.encode=function(message){return JSON.stringify(message)};protocol.version=version;protocol.versionLong="Version "+version;protocol.type="protocol";return protocol}},{"./frame":5}],13:[function(require,module,exports){exports.UI={Region:require("./ui/region"),Cursor:require("./ui/cursor")}},{"./ui/cursor":14,"./ui/region":15}],14:[function(require,module,exports){var Cursor=module.exports=function(){return function(frame){var pointable=frame.pointables.sort(function(a,b){return a.z-b.z})[0];if(pointable&&pointable.valid){frame.cursorPosition=pointable.tipPosition}return frame}}},{}],15:[function(require,module,exports){var EventEmitter=require("events").EventEmitter,_=require("underscore");var Region=module.exports=function(start,end){this.start=new Vector(start);this.end=new Vector(end);this.enteredFrame=null};Region.prototype.hasPointables=function(frame){for(var i=0;i!=frame.pointables.length;i++){var position=frame.pointables[i].tipPosition;if(position.x>=this.start.x&&position.x<=this.end.x&&position.y>=this.start.y&&position.y<=this.end.y&&position.z>=this.start.z&&position.z<=this.end.z){return true}}return false};Region.prototype.listener=function(opts){var region=this;if(opts&&opts.nearThreshold)this.setupNearRegion(opts.nearThreshold);return function(frame){return region.updatePosition(frame)}};Region.prototype.clipper=function(){var region=this;return function(frame){region.updatePosition(frame);return region.enteredFrame?frame:null}};Region.prototype.setupNearRegion=function(distance){var nearRegion=this.nearRegion=new Region([this.start.x-distance,this.start.y-distance,this.start.z-distance],[this.end.x+distance,this.end.y+distance,this.end.z+distance]);var region=this;nearRegion.on("enter",function(frame){region.emit("near",frame)});nearRegion.on("exit",function(frame){region.emit("far",frame)});region.on("exit",function(frame){region.emit("near",frame)})};Region.prototype.updatePosition=function(frame){if(this.nearRegion)this.nearRegion.updatePosition(frame);if(this.hasPointables(frame)&&this.enteredFrame==null){this.enteredFrame=frame;this.emit("enter",this.enteredFrame)}else if(!this.hasPointables(frame)&&this.enteredFrame!=null){this.enteredFrame=null;this.emit("exit",this.enteredFrame)}return frame};Region.prototype.normalize=function(position){return new Vector([(position.x-this.start.x)/(this.end.x-this.start.x),(position.y-this.start.y)/(this.end.y-this.start.y),(position.z-this.start.z)/(this.end.z-this.start.z)])};Region.prototype.mapToXY=function(position,width,height){var normalized=this.normalize(position);var x=normalized.x,y=normalized.y;if(x>1)x=1;else if(x<-1)x=-1;if(y>1)y=1;else if(y<-1)y=-1;return[(x+1)/2*width,(1-y)/2*height,normalized.z]};_.extend(Region.prototype,EventEmitter.prototype)},{events:17,underscore:20}],16:[function(require,module,exports){},{}],17:[function(require,module,exports){!function(process){if(!process.EventEmitter)process.EventEmitter=function(){};var EventEmitter=exports.EventEmitter=process.EventEmitter;var isArray=typeof Array.isArray==="function"?Array.isArray:function(xs){return Object.prototype.toString.call(xs)==="[object Array]"};function indexOf(xs,x){if(xs.indexOf)return xs.indexOf(x);for(var i=0;i<xs.length;i++){if(x===xs[i])return i}return-1}var defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!this._events)this._events={};this._events.maxListeners=n};EventEmitter.prototype.emit=function(type){if(type==="error"){if(!this._events||!this._events.error||isArray(this._events.error)&&!this._events.error.length){if(arguments[1]instanceof Error){throw arguments[1]}else{throw new Error("Uncaught, unspecified 'error' event.")}return false}}if(!this._events)return false;var handler=this._events[type];if(!handler)return false;if(typeof handler=="function"){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:var args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}return true}else if(isArray(handler)){var args=Array.prototype.slice.call(arguments,1);var listeners=handler.slice();for(var i=0,l=listeners.length;i<l;i++){listeners[i].apply(this,args)}return true}else{return false}};EventEmitter.prototype.addListener=function(type,listener){if("function"!==typeof listener){throw new Error("addListener only takes instances of Function")}if(!this._events)this._events={};this.emit("newListener",type,listener);if(!this._events[type]){this._events[type]=listener}else if(isArray(this._events[type])){if(!this._events[type].warned){var m;if(this._events.maxListeners!==undefined){m=this._events.maxListeners}else{m=defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);console.trace()}}this._events[type].push(listener)}else{this._events[type]=[this._events[type],listener]}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){var self=this;self.on(type,function g(){self.removeListener(type,g);listener.apply(this,arguments)});return this};EventEmitter.prototype.removeListener=function(type,listener){if("function"!==typeof listener){throw new Error("removeListener only takes instances of Function")}if(!this._events||!this._events[type])return this;var list=this._events[type];if(isArray(list)){var i=indexOf(list,listener);if(i<0)return this;list.splice(i,1);if(list.length==0)delete this._events[type]}else if(this._events[type]===listener){delete this._events[type]}return this};EventEmitter.prototype.removeAllListeners=function(type){if(arguments.length===0){this._events={};return this}if(type&&this._events&&this._events[type])this._events[type]=null;return this};EventEmitter.prototype.listeners=function(type){if(!this._events)this._events={};if(!this._events[type])this._events[type]=[];if(!isArray(this._events[type])){this._events[type]=[this._events[type]]}return this._events[type]}}(require("__browserify_process"))},{__browserify_process:18}],18:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){if(ev.source===window&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}],19:[function(require,module,exports){!function(){!function(){"use strict";var shim={};if(typeof exports==="undefined"){if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){shim.exports={};define(function(){return shim.exports})}else{shim.exports=window}}else{shim.exports=exports}!function(exports){var vec2={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec2.create=function(){return new Float32Array(2)};vec2.clone=function(a){var out=new Float32Array(2);out[0]=a[0];out[1]=a[1];return out};vec2.fromValues=function(x,y){var out=new Float32Array(2);out[0]=x;out[1]=y;return out};vec2.copy=function(out,a){out[0]=a[0];out[1]=a[1];return out};vec2.set=function(out,x,y){out[0]=x;out[1]=y;return out};vec2.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];return out};vec2.sub=vec2.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];return out};vec2.mul=vec2.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];return out};vec2.div=vec2.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];return out};vec2.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);
+out[1]=Math.min(a[1],b[1]);return out};vec2.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);return out};vec2.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;return out};vec2.dist=vec2.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return Math.sqrt(x*x+y*y)};vec2.sqrDist=vec2.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return x*x+y*y};vec2.len=vec2.length=function(a){var x=a[0],y=a[1];return Math.sqrt(x*x+y*y)};vec2.sqrLen=vec2.squaredLength=function(a){var x=a[0],y=a[1];return x*x+y*y};vec2.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];return out};vec2.normalize=function(out,a){var x=a[0],y=a[1];var len=x*x+y*y;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len}return out};vec2.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]};vec2.cross=function(out,a,b){var z=a[0]*b[1]-a[1]*b[0];out[0]=out[1]=0;out[2]=z;return out};vec2.lerp=function(out,a,b,t){var ax=a[0],ay=a[1];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);return out};vec2.transformMat2=function(out,a,m){var x=a[0],y=a[1];out[0]=x*m[0]+y*m[1];out[1]=x*m[2]+y*m[3];return out};vec2.forEach=function(){var vec=new Float32Array(2);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=2}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1]}return a}}();vec2.str=function(a){return"vec2("+a[0]+", "+a[1]+")"};if(typeof exports!=="undefined"){exports.vec2=vec2}var vec3={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec3.create=function(){return new Float32Array(3)};vec3.clone=function(a){var out=new Float32Array(3);out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.fromValues=function(x,y,z){var out=new Float32Array(3);out[0]=x;out[1]=y;out[2]=z;return out};vec3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.set=function(out,x,y,z){out[0]=x;out[1]=y;out[2]=z;return out};vec3.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];return out};vec3.sub=vec3.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];return out};vec3.mul=vec3.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];return out};vec3.div=vec3.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];return out};vec3.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);return out};vec3.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);return out};vec3.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;return out};vec3.dist=vec3.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrDist=vec3.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return x*x+y*y+z*z};vec3.len=vec3.length=function(a){var x=a[0],y=a[1],z=a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrLen=vec3.squaredLength=function(a){var x=a[0],y=a[1],z=a[2];return x*x+y*y+z*z};vec3.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];return out};vec3.normalize=function(out,a){var x=a[0],y=a[1],z=a[2];var len=x*x+y*y+z*z;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len}return out};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};vec3.cross=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2];out[0]=ay*bz-az*by;out[1]=az*bx-ax*bz;out[2]=ax*by-ay*bx;return out};vec3.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);return out};vec3.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12];out[1]=m[1]*x+m[5]*y+m[9]*z+m[13];out[2]=m[2]*x+m[6]*y+m[10]*z+m[14];return out};vec3.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec3.forEach=function(){var vec=new Float32Array(3);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=3}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2]}return a}}();vec3.str=function(a){return"vec3("+a[0]+", "+a[1]+", "+a[2]+")"};if(typeof exports!=="undefined"){exports.vec3=vec3}var vec4={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec4.create=function(){return new Float32Array(4)};vec4.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.fromValues=function(x,y,z,w){var out=new Float32Array(4);out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.set=function(out,x,y,z,w){out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];out[3]=a[3]+b[3];return out};vec4.sub=vec4.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];out[3]=a[3]-b[3];return out};vec4.mul=vec4.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];out[3]=a[3]*b[3];return out};vec4.div=vec4.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];out[3]=a[3]/b[3];return out};vec4.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);out[3]=Math.min(a[3],b[3]);return out};vec4.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);out[3]=Math.max(a[3],b[3]);return out};vec4.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;out[3]=a[3]*b;return out};vec4.dist=vec4.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrDist=vec4.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return x*x+y*y+z*z+w*w};vec4.len=vec4.length=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrLen=vec4.squaredLength=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return x*x+y*y+z*z+w*w};vec4.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=-a[3];return out};vec4.normalize=function(out,a){var x=a[0],y=a[1],z=a[2],w=a[3];var len=x*x+y*y+z*z+w*w;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len;out[3]=a[3]*len}return out};vec4.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]};vec4.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);out[3]=aw+t*(b[3]-aw);return out};vec4.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2],w=a[3];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12]*w;out[1]=m[1]*x+m[5]*y+m[9]*z+m[13]*w;out[2]=m[2]*x+m[6]*y+m[10]*z+m[14]*w;out[3]=m[3]*x+m[7]*y+m[11]*z+m[15]*w;return out};vec4.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec4.forEach=function(){var vec=new Float32Array(4);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=4}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];vec[3]=a[i+3];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2];a[i+3]=vec[3]}return a}}();vec4.str=function(a){return"vec4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.vec4=vec4}var mat2={};var mat2Identity=new Float32Array([1,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat2.create=function(){return new Float32Array(mat2Identity)};mat2.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=1;return out};mat2.transpose=function(out,a){if(out===a){var a1=a[1];out[1]=a[2];out[2]=a1}else{out[0]=a[0];out[1]=a[2];out[2]=a[1];out[3]=a[3]}return out};mat2.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],det=a0*a3-a2*a1;if(!det){return null}det=1/det;out[0]=a3*det;out[1]=-a1*det;out[2]=-a2*det;out[3]=a0*det;return out};mat2.adjoint=function(out,a){var a0=a[0];out[0]=a[3];out[1]=-a[1];out[2]=-a[2];out[3]=a0;return out};mat2.determinant=function(a){return a[0]*a[3]-a[2]*a[1]};mat2.mul=mat2.multiply=function(out,a,b){var a0=a[0],a1=a[1],a2=a[2],a3=a[3];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=a0*b0+a1*b2;out[1]=a0*b1+a1*b3;out[2]=a2*b0+a3*b2;out[3]=a2*b1+a3*b3;return out};mat2.rotate=function(out,a,rad){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],s=Math.sin(rad),c=Math.cos(rad);out[0]=a0*c+a1*s;out[1]=a0*-s+a1*c;out[2]=a2*c+a3*s;out[3]=a2*-s+a3*c;return out};mat2.scale=function(out,a,v){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],v0=v[0],v1=v[1];out[0]=a0*v0;out[1]=a1*v1;out[2]=a2*v0;out[3]=a3*v1;return out};mat2.str=function(a){return"mat2("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.mat2=mat2}var mat3={};var mat3Identity=new Float32Array([1,0,0,0,1,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat3.create=function(){return new Float32Array(mat3Identity)};mat3.clone=function(a){var out=new Float32Array(9);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=1;out[5]=0;out[6]=0;out[7]=0;out[8]=1;return out};mat3.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a12=a[5];out[1]=a[3];out[2]=a[6];out[3]=a01;out[5]=a[7];out[6]=a02;out[7]=a12}else{out[0]=a[0];out[1]=a[3];out[2]=a[6];out[3]=a[1];out[4]=a[4];out[5]=a[7];out[6]=a[2];out[7]=a[5];out[8]=a[8]}return out};mat3.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b01=a22*a11-a12*a21,b11=-a22*a10+a12*a20,b21=a21*a10-a11*a20,det=a00*b01+a01*b11+a02*b21;if(!det){return null}det=1/det;out[0]=b01*det;out[1]=(-a22*a01+a02*a21)*det;out[2]=(a12*a01-a02*a11)*det;out[3]=b11*det;out[4]=(a22*a00-a02*a20)*det;out[5]=(-a12*a00+a02*a10)*det;out[6]=b21*det;out[7]=(-a21*a00+a01*a20)*det;out[8]=(a11*a00-a01*a10)*det;return out};mat3.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];out[0]=a11*a22-a12*a21;out[1]=a02*a21-a01*a22;out[2]=a01*a12-a02*a11;out[3]=a12*a20-a10*a22;out[4]=a00*a22-a02*a20;out[5]=a02*a10-a00*a12;out[6]=a10*a21-a11*a20;out[7]=a01*a20-a00*a21;out[8]=a00*a11-a01*a10;return out};mat3.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];return a00*(a22*a11-a12*a21)+a01*(-a22*a10+a12*a20)+a02*(a21*a10-a11*a20)};mat3.mul=mat3.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b00=b[0],b01=b[1],b02=b[2],b10=b[3],b11=b[4],b12=b[5],b20=b[6],b21=b[7],b22=b[8];out[0]=b00*a00+b01*a10+b02*a20;out[1]=b00*a01+b01*a11+b02*a21;out[2]=b00*a02+b01*a12+b02*a22;out[3]=b10*a00+b11*a10+b12*a20;out[4]=b10*a01+b11*a11+b12*a21;out[5]=b10*a02+b11*a12+b12*a22;out[6]=b20*a00+b21*a10+b22*a20;out[7]=b20*a01+b21*a11+b22*a21;out[8]=b20*a02+b21*a12+b22*a22;return out};mat3.str=function(a){return"mat3("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+")"};if(typeof exports!=="undefined"){exports.mat3=mat3}var mat4={};var mat4Identity=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat4.create=function(){return new Float32Array(mat4Identity)};mat4.clone=function(a){var out=new Float32Array(16);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=1;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=1;out[11]=0;out[12]=0;out[13]=0;out[14]=0;out[15]=1;return out};mat4.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a03=a[3],a12=a[6],a13=a[7],a23=a[11];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a01;out[6]=a[9];out[7]=a[13];out[8]=a02;out[9]=a12;out[11]=a[14];out[12]=a03;out[13]=a13;out[14]=a23}else{out[0]=a[0];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a[1];out[5]=a[5];out[6]=a[9];out[7]=a[13];out[8]=a[2];out[9]=a[6];out[10]=a[10];out[11]=a[14];out[12]=a[3];out[13]=a[7];out[14]=a[11];out[15]=a[15]}return out};mat4.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32,det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;if(!det){return null}det=1/det;out[0]=(a11*b11-a12*b10+a13*b09)*det;out[1]=(a02*b10-a01*b11-a03*b09)*det;out[2]=(a31*b05-a32*b04+a33*b03)*det;out[3]=(a22*b04-a21*b05-a23*b03)*det;out[4]=(a12*b08-a10*b11-a13*b07)*det;out[5]=(a00*b11-a02*b08+a03*b07)*det;out[6]=(a32*b02-a30*b05-a33*b01)*det;out[7]=(a20*b05-a22*b02+a23*b01)*det;out[8]=(a10*b10-a11*b08+a13*b06)*det;out[9]=(a01*b08-a00*b10-a03*b06)*det;out[10]=(a30*b04-a31*b02+a33*b00)*det;out[11]=(a21*b02-a20*b04-a23*b00)*det;out[12]=(a11*b07-a10*b09-a12*b06)*det;out[13]=(a00*b09-a01*b07+a02*b06)*det;out[14]=(a31*b01-a30*b03-a32*b00)*det;out[15]=(a20*b03-a21*b01+a22*b00)*det;return out};mat4.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];out[0]=a11*(a22*a33-a23*a32)-a21*(a12*a33-a13*a32)+a31*(a12*a23-a13*a22);out[1]=-(a01*(a22*a33-a23*a32)-a21*(a02*a33-a03*a32)+a31*(a02*a23-a03*a22));out[2]=a01*(a12*a33-a13*a32)-a11*(a02*a33-a03*a32)+a31*(a02*a13-a03*a12);out[3]=-(a01*(a12*a23-a13*a22)-a11*(a02*a23-a03*a22)+a21*(a02*a13-a03*a12));out[4]=-(a10*(a22*a33-a23*a32)-a20*(a12*a33-a13*a32)+a30*(a12*a23-a13*a22));out[5]=a00*(a22*a33-a23*a32)-a20*(a02*a33-a03*a32)+a30*(a02*a23-a03*a22);out[6]=-(a00*(a12*a33-a13*a32)-a10*(a02*a33-a03*a32)+a30*(a02*a13-a03*a12));out[7]=a00*(a12*a23-a13*a22)-a10*(a02*a23-a03*a22)+a20*(a02*a13-a03*a12);out[8]=a10*(a21*a33-a23*a31)-a20*(a11*a33-a13*a31)+a30*(a11*a23-a13*a21);out[9]=-(a00*(a21*a33-a23*a31)-a20*(a01*a33-a03*a31)+a30*(a01*a23-a03*a21));out[10]=a00*(a11*a33-a13*a31)-a10*(a01*a33-a03*a31)+a30*(a01*a13-a03*a11);out[11]=-(a00*(a11*a23-a13*a21)-a10*(a01*a23-a03*a21)+a20*(a01*a13-a03*a11));out[12]=-(a10*(a21*a32-a22*a31)-a20*(a11*a32-a12*a31)+a30*(a11*a22-a12*a21));out[13]=a00*(a21*a32-a22*a31)-a20*(a01*a32-a02*a31)+a30*(a01*a22-a02*a21);out[14]=-(a00*(a11*a32-a12*a31)-a10*(a01*a32-a02*a31)+a30*(a01*a12-a02*a11));out[15]=a00*(a11*a22-a12*a21)-a10*(a01*a22-a02*a21)+a20*(a01*a12-a02*a11);return out};mat4.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32;return b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06};mat4.mul=mat4.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=b0*a00+b1*a10+b2*a20+b3*a30;out[1]=b0*a01+b1*a11+b2*a21+b3*a31;out[2]=b0*a02+b1*a12+b2*a22+b3*a32;out[3]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[4];b1=b[5];b2=b[6];b3=b[7];out[4]=b0*a00+b1*a10+b2*a20+b3*a30;out[5]=b0*a01+b1*a11+b2*a21+b3*a31;out[6]=b0*a02+b1*a12+b2*a22+b3*a32;out[7]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[8];b1=b[9];b2=b[10];b3=b[11];out[8]=b0*a00+b1*a10+b2*a20+b3*a30;out[9]=b0*a01+b1*a11+b2*a21+b3*a31;out[10]=b0*a02+b1*a12+b2*a22+b3*a32;out[11]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[12];b1=b[13];b2=b[14];b3=b[15];out[12]=b0*a00+b1*a10+b2*a20+b3*a30;out[13]=b0*a01+b1*a11+b2*a21+b3*a31;out[14]=b0*a02+b1*a12+b2*a22+b3*a32;out[15]=b0*a03+b1*a13+b2*a23+b3*a33;return out};mat4.translate=function(out,a,v){var x=v[0],y=v[1],z=v[2],a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23;if(a===out){out[12]=a[0]*x+a[4]*y+a[8]*z+a[12];out[13]=a[1]*x+a[5]*y+a[9]*z+a[13];out[14]=a[2]*x+a[6]*y+a[10]*z+a[14];out[15]=a[3]*x+a[7]*y+a[11]*z+a[15]}else{a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];out[0]=a00;out[1]=a01;out[2]=a02;out[3]=a03;out[4]=a10;out[5]=a11;out[6]=a12;out[7]=a13;out[8]=a20;out[9]=a21;out[10]=a22;out[11]=a23;out[12]=a00*x+a10*y+a20*z+a[12];out[13]=a01*x+a11*y+a21*z+a[13];out[14]=a02*x+a12*y+a22*z+a[14];out[15]=a03*x+a13*y+a23*z+a[15]}return out};mat4.scale=function(out,a,v){var x=v[0],y=v[1],z=v[2];out[0]=a[0]*x;out[1]=a[1]*x;out[2]=a[2]*x;out[3]=a[3]*x;out[4]=a[4]*y;out[5]=a[5]*y;out[6]=a[6]*y;out[7]=a[7]*y;out[8]=a[8]*z;out[9]=a[9]*z;out[10]=a[10]*z;out[11]=a[11]*z;out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.rotate=function(out,a,rad,axis){var x=axis[0],y=axis[1],z=axis[2],len=Math.sqrt(x*x+y*y+z*z),s,c,t,a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23,b00,b01,b02,b10,b11,b12,b20,b21,b22;if(Math.abs(len)<GLMAT_EPSILON){return null}len=1/len;x*=len;y*=len;z*=len;s=Math.sin(rad);c=Math.cos(rad);t=1-c;a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];b00=x*x*t+c;b01=y*x*t+z*s;b02=z*x*t-y*s;b10=x*y*t-z*s;b11=y*y*t+c;b12=z*y*t+x*s;b20=x*z*t+y*s;b21=y*z*t-x*s;b22=z*z*t+c;out[0]=a00*b00+a10*b01+a20*b02;out[1]=a01*b00+a11*b01+a21*b02;out[2]=a02*b00+a12*b01+a22*b02;out[3]=a03*b00+a13*b01+a23*b02;out[4]=a00*b10+a10*b11+a20*b12;out[5]=a01*b10+a11*b11+a21*b12;out[6]=a02*b10+a12*b11+a22*b12;out[7]=a03*b10+a13*b11+a23*b12;out[8]=a00*b20+a10*b21+a20*b22;out[9]=a01*b20+a11*b21+a21*b22;out[10]=a02*b20+a12*b21+a22*b22;out[11]=a03*b20+a13*b21+a23*b22;if(a!==out){out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}return out};mat4.rotateX=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[4]=a10*c+a20*s;out[5]=a11*c+a21*s;out[6]=a12*c+a22*s;out[7]=a13*c+a23*s;out[8]=a20*c-a10*s;out[9]=a21*c-a11*s;out[10]=a22*c-a12*s;out[11]=a23*c-a13*s;return out};mat4.rotateY=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c-a20*s;out[1]=a01*c-a21*s;out[2]=a02*c-a22*s;out[3]=a03*c-a23*s;out[8]=a00*s+a20*c;out[9]=a01*s+a21*c;out[10]=a02*s+a22*c;out[11]=a03*s+a23*c;return out};mat4.rotateZ=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7];if(a!==out){out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c+a10*s;out[1]=a01*c+a11*s;out[2]=a02*c+a12*s;out[3]=a03*c+a13*s;out[4]=a10*c-a00*s;out[5]=a11*c-a01*s;out[6]=a12*c-a02*s;out[7]=a13*c-a03*s;return out};mat4.fromRotationTranslation=function(out,q,v){var x=q[0],y=q[1],z=q[2],w=q[3],x2=x+x,y2=y+y,z2=z+z,xx=x*x2,xy=x*y2,xz=x*z2,yy=y*y2,yz=y*z2,zz=z*z2,wx=w*x2,wy=w*y2,wz=w*z2;out[0]=1-(yy+zz);out[1]=xy+wz;out[2]=xz-wy;out[3]=0;out[4]=xy-wz;out[5]=1-(xx+zz);out[6]=yz+wx;out[7]=0;out[8]=xz+wy;out[9]=yz-wx;out[10]=1-(xx+yy);out[11]=0;out[12]=v[0];out[13]=v[1];out[14]=v[2];out[15]=1;return out};mat4.frustum=function(out,left,right,bottom,top,near,far){var rl=1/(right-left),tb=1/(top-bottom),nf=1/(near-far);out[0]=near*2*rl;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=near*2*tb;out[6]=0;out[7]=0;out[8]=(right+left)*rl;out[9]=(top+bottom)*tb;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=far*near*2*nf;out[15]=0;return out};mat4.perspective=function(out,fovy,aspect,near,far){var f=1/Math.tan(fovy/2),nf=1/(near-far);out[0]=f/aspect;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=f;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=2*far*near*nf;out[15]=0;return out};mat4.ortho=function(out,left,right,bottom,top,near,far){var lr=1/(left-right),bt=1/(bottom-top),nf=1/(near-far);out[0]=-2*lr;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=-2*bt;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=2*nf;out[11]=0;out[12]=(left+right)*lr;out[13]=(top+bottom)*bt;out[14]=(far+near)*nf;out[15]=1;return out};mat4.lookAt=function(out,eye,center,up){var x0,x1,x2,y0,y1,y2,z0,z1,z2,len,eyex=eye[0],eyey=eye[1],eyez=eye[2],upx=up[0],upy=up[1],upz=up[2],centerx=center[0],centery=center[1],centerz=center[2];if(Math.abs(eyex-centerx)<GLMAT_EPSILON&&Math.abs(eyey-centery)<GLMAT_EPSILON&&Math.abs(eyez-centerz)<GLMAT_EPSILON){return mat4.identity(out)}z0=eyex-centerx;z1=eyey-centery;z2=eyez-centerz;len=1/Math.sqrt(z0*z0+z1*z1+z2*z2);z0*=len;z1*=len;z2*=len;x0=upy*z2-upz*z1;x1=upz*z0-upx*z2;x2=upx*z1-upy*z0;len=Math.sqrt(x0*x0+x1*x1+x2*x2);if(!len){x0=0;x1=0;x2=0}else{len=1/len;x0*=len;x1*=len;x2*=len}y0=z1*x2-z2*x1;y1=z2*x0-z0*x2;y2=z0*x1-z1*x0;len=Math.sqrt(y0*y0+y1*y1+y2*y2);if(!len){y0=0;y1=0;y2=0}else{len=1/len;y0*=len;y1*=len;y2*=len}out[0]=x0;out[1]=y0;out[2]=z0;out[3]=0;out[4]=x1;out[5]=y1;out[6]=z1;out[7]=0;out[8]=x2;out[9]=y2;out[10]=z2;out[11]=0;out[12]=-(x0*eyex+x1*eyey+x2*eyez);out[13]=-(y0*eyex+y1*eyey+y2*eyez);out[14]=-(z0*eyex+z1*eyey+z2*eyez);out[15]=1;return out};mat4.str=function(a){return"mat4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+")"};if(typeof exports!=="undefined"){exports.mat4=mat4}var quat={};var quatIdentity=new Float32Array([0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}quat.create=function(){return new Float32Array(quatIdentity)};quat.clone=vec4.clone;quat.fromValues=vec4.fromValues;quat.copy=vec4.copy;quat.set=vec4.set;quat.identity=function(out){out[0]=0;out[1]=0;out[2]=0;out[3]=1;return out};quat.setAxisAngle=function(out,axis,rad){rad=rad*.5;var s=Math.sin(rad);out[0]=s*axis[0];out[1]=s*axis[1];out[2]=s*axis[2];out[3]=Math.cos(rad);return out};quat.add=vec4.add;quat.mul=quat.multiply=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=b[3];out[0]=ax*bw+aw*bx+ay*bz-az*by;out[1]=ay*bw+aw*by+az*bx-ax*bz;out[2]=az*bw+aw*bz+ax*by-ay*bx;out[3]=aw*bw-ax*bx-ay*by-az*bz;return out};quat.scale=vec4.scale;quat.rotateX=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+aw*bx;out[1]=ay*bw+az*bx;out[2]=az*bw-ay*bx;out[3]=aw*bw-ax*bx;return out};quat.rotateY=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],by=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw-az*by;out[1]=ay*bw+aw*by;out[2]=az*bw+ax*by;out[3]=aw*bw-ay*by;return out};quat.rotateZ=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bz=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+ay*bz;out[1]=ay*bw-ax*bz;out[2]=az*bw+aw*bz;out[3]=aw*bw-az*bz;return out};quat.calculateW=function(out,a){var x=a[0],y=a[1],z=a[2];out[0]=x;out[1]=y;out[2]=z;out[3]=-Math.sqrt(Math.abs(1-x*x-y*y-z*z));return out};quat.dot=vec4.dot;quat.lerp=vec4.lerp;quat.slerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=a[3];var cosHalfTheta=ax*bx+ay*by+az*bz+aw*bw,halfTheta,sinHalfTheta,ratioA,ratioB;if(Math.abs(cosHalfTheta)>=1){if(out!==a){out[0]=ax;out[1]=ay;out[2]=az;out[3]=aw}return out}halfTheta=Math.acos(cosHalfTheta);sinHalfTheta=Math.sqrt(1-cosHalfTheta*cosHalfTheta);if(Math.abs(sinHalfTheta)<.001){out[0]=ax*.5+bx*.5;out[1]=ay*.5+by*.5;out[2]=az*.5+bz*.5;out[3]=aw*.5+bw*.5;return out}ratioA=Math.sin((1-t)*halfTheta)/sinHalfTheta;ratioB=Math.sin(t*halfTheta)/sinHalfTheta;out[0]=ax*ratioA+bx*ratioB;out[1]=ay*ratioA+by*ratioB;out[2]=az*ratioA+bz*ratioB;out[3]=aw*ratioA+bw*ratioB;return out};quat.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],dot=a0*a0+a1*a1+a2*a2+a3*a3,invDot=dot?1/dot:0;out[0]=-a0*invDot;out[1]=-a1*invDot;out[2]=-a2*invDot;out[3]=a3*invDot;return out};quat.conjugate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=a[3];return out};quat.len=quat.length=vec4.length;quat.sqrLen=quat.squaredLength=vec4.squaredLength;quat.normalize=vec4.normalize;quat.str=function(a){return"quat("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.quat=quat}}(shim.exports)}()}()},{}],20:[function(require,module,exports){!function(){!function(){var root=this;var previousUnderscore=root._;var breaker={};var ArrayProto=Array.prototype,ObjProto=Object.prototype,FuncProto=Function.prototype;var push=ArrayProto.push,slice=ArrayProto.slice,concat=ArrayProto.concat,toString=ObjProto.toString,hasOwnProperty=ObjProto.hasOwnProperty;var nativeForEach=ArrayProto.forEach,nativeMap=ArrayProto.map,nativeReduce=ArrayProto.reduce,nativeReduceRight=ArrayProto.reduceRight,nativeFilter=ArrayProto.filter,nativeEvery=ArrayProto.every,nativeSome=ArrayProto.some,nativeIndexOf=ArrayProto.indexOf,nativeLastIndexOf=ArrayProto.lastIndexOf,nativeIsArray=Array.isArray,nativeKeys=Object.keys,nativeBind=FuncProto.bind;var _=function(obj){if(obj instanceof _)return obj;if(!(this instanceof _))return new _(obj);this._wrapped=obj};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=_}exports._=_}else{root._=_}_.VERSION="1.4.4";var each=_.each=_.forEach=function(obj,iterator,context){if(obj==null)return;if(nativeForEach&&obj.forEach===nativeForEach){obj.forEach(iterator,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){if(iterator.call(context,obj[i],i,obj)===breaker)return}}else{for(var key in obj){if(_.has(obj,key)){if(iterator.call(context,obj[key],key,obj)===breaker)return}}}};_.map=_.collect=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeMap&&obj.map===nativeMap)return obj.map(iterator,context);each(obj,function(value,index,list){results[results.length]=iterator.call(context,value,index,list)});return results};var reduceError="Reduce of empty array with no initial value";_.reduce=_.foldl=_.inject=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduce&&obj.reduce===nativeReduce){if(context)iterator=_.bind(iterator,context);return initial?obj.reduce(iterator,memo):obj.reduce(iterator)}each(obj,function(value,index,list){if(!initial){memo=value;initial=true}else{memo=iterator.call(context,memo,value,index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.reduceRight=_.foldr=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduceRight&&obj.reduceRight===nativeReduceRight){if(context)iterator=_.bind(iterator,context);return initial?obj.reduceRight(iterator,memo):obj.reduceRight(iterator)}var length=obj.length;if(length!==+length){var keys=_.keys(obj);length=keys.length}each(obj,function(value,index,list){index=keys?keys[--length]:--length;if(!initial){memo=obj[index];initial=true}else{memo=iterator.call(context,memo,obj[index],index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.find=_.detect=function(obj,iterator,context){var result;any(obj,function(value,index,list){if(iterator.call(context,value,index,list)){result=value;return true}});return result};_.filter=_.select=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeFilter&&obj.filter===nativeFilter)return obj.filter(iterator,context);each(obj,function(value,index,list){if(iterator.call(context,value,index,list))results[results.length]=value});return results};_.reject=function(obj,iterator,context){return _.filter(obj,function(value,index,list){return!iterator.call(context,value,index,list)},context)};_.every=_.all=function(obj,iterator,context){iterator||(iterator=_.identity);var result=true;if(obj==null)return result;if(nativeEvery&&obj.every===nativeEvery)return obj.every(iterator,context);each(obj,function(value,index,list){if(!(result=result&&iterator.call(context,value,index,list)))return breaker});return!!result};var any=_.some=_.any=function(obj,iterator,context){iterator||(iterator=_.identity);var result=false;if(obj==null)return result;if(nativeSome&&obj.some===nativeSome)return obj.some(iterator,context);each(obj,function(value,index,list){if(result||(result=iterator.call(context,value,index,list)))return breaker});return!!result};_.contains=_.include=function(obj,target){if(obj==null)return false;if(nativeIndexOf&&obj.indexOf===nativeIndexOf)return obj.indexOf(target)!=-1;return any(obj,function(value){return value===target})};_.invoke=function(obj,method){var args=slice.call(arguments,2);var isFunc=_.isFunction(method);return _.map(obj,function(value){return(isFunc?method:value[method]).apply(value,args)})};_.pluck=function(obj,key){return _.map(obj,function(value){return value[key]})};_.where=function(obj,attrs,first){if(_.isEmpty(attrs))return first?null:[];return _[first?"find":"filter"](obj,function(value){for(var key in attrs){if(attrs[key]!==value[key])return false}return true})};_.findWhere=function(obj,attrs){return _.where(obj,attrs,true)};_.max=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.max.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return-Infinity;var result={computed:-Infinity,value:-Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed>=result.computed&&(result={value:value,computed:computed})});return result.value};_.min=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.min.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return Infinity;var result={computed:Infinity,value:Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed<result.computed&&(result={value:value,computed:computed})});return result.value};_.shuffle=function(obj){var rand;var index=0;var shuffled=[];each(obj,function(value){rand=_.random(index++);shuffled[index-1]=shuffled[rand];shuffled[rand]=value});return shuffled};var lookupIterator=function(value){return _.isFunction(value)?value:function(obj){return obj[value]}};_.sortBy=function(obj,value,context){var iterator=lookupIterator(value);return _.pluck(_.map(obj,function(value,index,list){return{value:value,index:index,criteria:iterator.call(context,value,index,list)}}).sort(function(left,right){var a=left.criteria;
+var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)return-1}return left.index<right.index?-1:1}),"value")};var group=function(obj,value,context,behavior){var result={};var iterator=lookupIterator(value||_.identity);each(obj,function(value,index){var key=iterator.call(context,value,index,obj);behavior(result,key,value)});return result};_.groupBy=function(obj,value,context){return group(obj,value,context,function(result,key,value){(_.has(result,key)?result[key]:result[key]=[]).push(value)})};_.countBy=function(obj,value,context){return group(obj,value,context,function(result,key){if(!_.has(result,key))result[key]=0;result[key]++})};_.sortedIndex=function(array,obj,iterator,context){iterator=iterator==null?_.identity:lookupIterator(iterator);var value=iterator.call(context,obj);var low=0,high=array.length;while(low<high){var mid=low+high>>>1;iterator.call(context,array[mid])<value?low=mid+1:high=mid}return low};_.toArray=function(obj){if(!obj)return[];if(_.isArray(obj))return slice.call(obj);if(obj.length===+obj.length)return _.map(obj,_.identity);return _.values(obj)};_.size=function(obj){if(obj==null)return 0;return obj.length===+obj.length?obj.length:_.keys(obj).length};_.first=_.head=_.take=function(array,n,guard){if(array==null)return void 0;return n!=null&&!guard?slice.call(array,0,n):array[0]};_.initial=function(array,n,guard){return slice.call(array,0,array.length-(n==null||guard?1:n))};_.last=function(array,n,guard){if(array==null)return void 0;if(n!=null&&!guard){return slice.call(array,Math.max(array.length-n,0))}else{return array[array.length-1]}};_.rest=_.tail=_.drop=function(array,n,guard){return slice.call(array,n==null||guard?1:n)};_.compact=function(array){return _.filter(array,_.identity)};var flatten=function(input,shallow,output){each(input,function(value){if(_.isArray(value)){shallow?push.apply(output,value):flatten(value,shallow,output)}else{output.push(value)}});return output};_.flatten=function(array,shallow){return flatten(array,shallow,[])};_.without=function(array){return _.difference(array,slice.call(arguments,1))};_.uniq=_.unique=function(array,isSorted,iterator,context){if(_.isFunction(isSorted)){context=iterator;iterator=isSorted;isSorted=false}var initial=iterator?_.map(array,iterator,context):array;var results=[];var seen=[];each(initial,function(value,index){if(isSorted?!index||seen[seen.length-1]!==value:!_.contains(seen,value)){seen.push(value);results.push(array[index])}});return results};_.union=function(){return _.uniq(concat.apply(ArrayProto,arguments))};_.intersection=function(array){var rest=slice.call(arguments,1);return _.filter(_.uniq(array),function(item){return _.every(rest,function(other){return _.indexOf(other,item)>=0})})};_.difference=function(array){var rest=concat.apply(ArrayProto,slice.call(arguments,1));return _.filter(array,function(value){return!_.contains(rest,value)})};_.zip=function(){var args=slice.call(arguments);var length=_.max(_.pluck(args,"length"));var results=new Array(length);for(var i=0;i<length;i++){results[i]=_.pluck(args,""+i)}return results};_.object=function(list,values){if(list==null)return{};var result={};for(var i=0,l=list.length;i<l;i++){if(values){result[list[i]]=values[i]}else{result[list[i][0]]=list[i][1]}}return result};_.indexOf=function(array,item,isSorted){if(array==null)return-1;var i=0,l=array.length;if(isSorted){if(typeof isSorted=="number"){i=isSorted<0?Math.max(0,l+isSorted):isSorted}else{i=_.sortedIndex(array,item);return array[i]===item?i:-1}}if(nativeIndexOf&&array.indexOf===nativeIndexOf)return array.indexOf(item,isSorted);for(;i<l;i++)if(array[i]===item)return i;return-1};_.lastIndexOf=function(array,item,from){if(array==null)return-1;var hasIndex=from!=null;if(nativeLastIndexOf&&array.lastIndexOf===nativeLastIndexOf){return hasIndex?array.lastIndexOf(item,from):array.lastIndexOf(item)}var i=hasIndex?from:array.length;while(i--)if(array[i]===item)return i;return-1};_.range=function(start,stop,step){if(arguments.length<=1){stop=start||0;start=0}step=arguments[2]||1;var len=Math.max(Math.ceil((stop-start)/step),0);var idx=0;var range=new Array(len);while(idx<len){range[idx++]=start;start+=step}return range};_.bind=function(func,context){if(func.bind===nativeBind&&nativeBind)return nativeBind.apply(func,slice.call(arguments,1));var args=slice.call(arguments,2);return function(){return func.apply(context,args.concat(slice.call(arguments)))}};_.partial=function(func){var args=slice.call(arguments,1);return function(){return func.apply(this,args.concat(slice.call(arguments)))}};_.bindAll=function(obj){var funcs=slice.call(arguments,1);if(funcs.length===0)funcs=_.functions(obj);each(funcs,function(f){obj[f]=_.bind(obj[f],obj)});return obj};_.memoize=function(func,hasher){var memo={};hasher||(hasher=_.identity);return function(){var key=hasher.apply(this,arguments);return _.has(memo,key)?memo[key]:memo[key]=func.apply(this,arguments)}};_.delay=function(func,wait){var args=slice.call(arguments,2);return setTimeout(function(){return func.apply(null,args)},wait)};_.defer=function(func){return _.delay.apply(_,[func,1].concat(slice.call(arguments,1)))};_.throttle=function(func,wait){var context,args,timeout,result;var previous=0;var later=function(){previous=new Date;timeout=null;result=func.apply(context,args)};return function(){var now=new Date;var remaining=wait-(now-previous);context=this;args=arguments;if(remaining<=0){clearTimeout(timeout);timeout=null;previous=now;result=func.apply(context,args)}else if(!timeout){timeout=setTimeout(later,remaining)}return result}};_.debounce=function(func,wait,immediate){var timeout,result;return function(){var context=this,args=arguments;var later=function(){timeout=null;if(!immediate)result=func.apply(context,args)};var callNow=immediate&&!timeout;clearTimeout(timeout);timeout=setTimeout(later,wait);if(callNow)result=func.apply(context,args);return result}};_.once=function(func){var ran=false,memo;return function(){if(ran)return memo;ran=true;memo=func.apply(this,arguments);func=null;return memo}};_.wrap=function(func,wrapper){return function(){var args=[func];push.apply(args,arguments);return wrapper.apply(this,args)}};_.compose=function(){var funcs=arguments;return function(){var args=arguments;for(var i=funcs.length-1;i>=0;i--){args=[funcs[i].apply(this,args)]}return args[0]}};_.after=function(times,func){if(times<=0)return func();return function(){if(--times<1){return func.apply(this,arguments)}}};_.keys=nativeKeys||function(obj){if(obj!==Object(obj))throw new TypeError("Invalid object");var keys=[];for(var key in obj)if(_.has(obj,key))keys[keys.length]=key;return keys};_.values=function(obj){var values=[];for(var key in obj)if(_.has(obj,key))values.push(obj[key]);return values};_.pairs=function(obj){var pairs=[];for(var key in obj)if(_.has(obj,key))pairs.push([key,obj[key]]);return pairs};_.invert=function(obj){var result={};for(var key in obj)if(_.has(obj,key))result[obj[key]]=key;return result};_.functions=_.methods=function(obj){var names=[];for(var key in obj){if(_.isFunction(obj[key]))names.push(key)}return names.sort()};_.extend=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){obj[prop]=source[prop]}}});return obj};_.pick=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));each(keys,function(key){if(key in obj)copy[key]=obj[key]});return copy};_.omit=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));for(var key in obj){if(!_.contains(keys,key))copy[key]=obj[key]}return copy};_.defaults=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){if(obj[prop]==null)obj[prop]=source[prop]}}});return obj};_.clone=function(obj){if(!_.isObject(obj))return obj;return _.isArray(obj)?obj.slice():_.extend({},obj)};_.tap=function(obj,interceptor){interceptor(obj);return obj};var eq=function(a,b,aStack,bStack){if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;if(a instanceof _)a=a._wrapped;if(b instanceof _)b=b._wrapped;var className=toString.call(a);if(className!=toString.call(b))return false;switch(className){case"[object String]":return a==String(b);case"[object Number]":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case"[object Date]":case"[object Boolean]":return+a==+b;case"[object RegExp]":return a.source==b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return false;var length=aStack.length;while(length--){if(aStack[length]==a)return bStack[length]==b}aStack.push(a);bStack.push(b);var size=0,result=true;if(className=="[object Array]"){size=a.length;result=size==b.length;if(result){while(size--){if(!(result=eq(a[size],b[size],aStack,bStack)))break}}}else{var aCtor=a.constructor,bCtor=b.constructor;if(aCtor!==bCtor&&!(_.isFunction(aCtor)&&aCtor instanceof aCtor&&_.isFunction(bCtor)&&bCtor instanceof bCtor)){return false}for(var key in a){if(_.has(a,key)){size++;if(!(result=_.has(b,key)&&eq(a[key],b[key],aStack,bStack)))break}}if(result){for(key in b){if(_.has(b,key)&&!size--)break}result=!size}}aStack.pop();bStack.pop();return result};_.isEqual=function(a,b){return eq(a,b,[],[])};_.isEmpty=function(obj){if(obj==null)return true;if(_.isArray(obj)||_.isString(obj))return obj.length===0;for(var key in obj)if(_.has(obj,key))return false;return true};_.isElement=function(obj){return!!(obj&&obj.nodeType===1)};_.isArray=nativeIsArray||function(obj){return toString.call(obj)=="[object Array]"};_.isObject=function(obj){return obj===Object(obj)};each(["Arguments","Function","String","Number","Date","RegExp"],function(name){_["is"+name]=function(obj){return toString.call(obj)=="[object "+name+"]"}});if(!_.isArguments(arguments)){_.isArguments=function(obj){return!!(obj&&_.has(obj,"callee"))}}if(typeof/./!=="function"){_.isFunction=function(obj){return typeof obj==="function"}}_.isFinite=function(obj){return isFinite(obj)&&!isNaN(parseFloat(obj))};_.isNaN=function(obj){return _.isNumber(obj)&&obj!=+obj};_.isBoolean=function(obj){return obj===true||obj===false||toString.call(obj)=="[object Boolean]"};_.isNull=function(obj){return obj===null};_.isUndefined=function(obj){return obj===void 0};_.has=function(obj,key){return hasOwnProperty.call(obj,key)};_.noConflict=function(){root._=previousUnderscore;return this};_.identity=function(value){return value};_.times=function(n,iterator,context){var accum=Array(n);for(var i=0;i<n;i++)accum[i]=iterator.call(context,i);return accum};_.random=function(min,max){if(max==null){max=min;min=0}return min+Math.floor(Math.random()*(max-min+1))};var entityMap={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};entityMap.unescape=_.invert(entityMap.escape);var entityRegexes={escape:new RegExp("["+_.keys(entityMap.escape).join("")+"]","g"),unescape:new RegExp("("+_.keys(entityMap.unescape).join("|")+")","g")};_.each(["escape","unescape"],function(method){_[method]=function(string){if(string==null)return"";return(""+string).replace(entityRegexes[method],function(match){return entityMap[method][match]})}});_.result=function(object,property){if(object==null)return null;var value=object[property];return _.isFunction(value)?value.call(object):value};_.mixin=function(obj){each(_.functions(obj),function(name){var func=_[name]=obj[name];_.prototype[name]=function(){var args=[this._wrapped];push.apply(args,arguments);return result.call(this,func.apply(_,args))}})};var idCounter=0;_.uniqueId=function(prefix){var id=++idCounter+"";return prefix?prefix+id:id};_.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var noMatch=/(.)^/;var escapes={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"};var escaper=/\\|'|\r|\n|\t|\u2028|\u2029/g;_.template=function(text,data,settings){var render;settings=_.defaults({},settings,_.templateSettings);var matcher=new RegExp([(settings.escape||noMatch).source,(settings.interpolate||noMatch).source,(settings.evaluate||noMatch).source].join("|")+"|$","g");var index=0;var source="__p+='";text.replace(matcher,function(match,escape,interpolate,evaluate,offset){source+=text.slice(index,offset).replace(escaper,function(match){return"\\"+escapes[match]});if(escape){source+="'+\n((__t=("+escape+"))==null?'':_.escape(__t))+\n'"}if(interpolate){source+="'+\n((__t=("+interpolate+"))==null?'':__t)+\n'"}if(evaluate){source+="';\n"+evaluate+"\n__p+='"}index=offset+match.length;return match});source+="';\n";if(!settings.variable)source="with(obj||{}){\n"+source+"}\n";source="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+source+"return __p;\n";try{render=new Function(settings.variable||"obj","_",source)}catch(e){e.source=source;throw e}if(data)return render(data,_);var template=function(data){return render.call(this,data,_)};template.source="function("+(settings.variable||"obj")+"){\n"+source+"}";return template};_.chain=function(obj){return _(obj).chain()};var result=function(obj){return this._chain?_(obj).chain():obj};_.mixin(_);each(["pop","push","reverse","shift","sort","splice","unshift"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){var obj=this._wrapped;method.apply(obj,arguments);if((name=="shift"||name=="splice")&&obj.length===0)delete obj[0];return result.call(this,obj)}});each(["concat","join","slice"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){return result.call(this,method.apply(this._wrapped,arguments))}});_.extend(_.prototype,{chain:function(){this._chain=true;return this},value:function(){return this._wrapped}})}.call(this)}()},{}],21:[function(require,module,exports){window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){window.setTimeout(callback,1e3/60)}}();Leap=require("../lib/index")},{"../lib/index":8}]},{},[21]);
+
+/*
+ * Leap Motion integration for Reveal.js.
+ * James Sun  [sun16]
+ * Rory Hardy [gneatgeek]
+ */
+
+(function () {
+  var body        = document.body,
+      controller  = new Leap.Controller({ enableGestures: true }),
+      lastGesture = 0,
+      leapConfig  = Reveal.getConfig().leap,
+      pointer     = document.createElement( 'div' ),
+      config      = {
+        autoCenter       : true,      // Center pointer around detected position.
+        gestureDelay     : 500,       // How long to delay between gestures.
+        naturalSwipe     : true,      // Swipe as if it were a touch screen.
+        pointerColor     : '#00aaff', // Default color of the pointer.
+        pointerOpacity   : 0.7,       // Default opacity of the pointer.
+        pointerSize      : 15,        // Default minimum height/width of the pointer.
+        pointerTolerance : 120        // Bigger = slower pointer.
+      },
+      entered, enteredPosition, now, size, tipPosition; // Other vars we need later, but don't need to redeclare.
+
+      // Merge user defined settings with defaults
+      if( leapConfig ) {
+        for( key in leapConfig ) {
+          config[key] = leapConfig[key];
+        }
+      }
+
+      pointer.id = 'leap';
+
+      pointer.style.position        = 'absolute';
+      pointer.style.visibility      = 'hidden';
+      pointer.style.zIndex          = 50;
+      pointer.style.opacity         = config.pointerOpacity;
+      pointer.style.backgroundColor = config.pointerColor;
+
+      body.appendChild( pointer );
+
+  // Leap's loop
+  controller.on( 'frame', function ( frame ) {
+    // Timing code to rate limit gesture execution
+    now = new Date().getTime();
+
+    // Pointer: 1 to 2 fingers. Strictly one finger works but may cause innaccuracies.
+    // The innaccuracies were observed on a development model and may not be an issue with consumer models.
+    if( frame.fingers.length > 0 && frame.fingers.length < 3 ) {
+      // Invert direction and multiply by 3 for greater effect.
+      size = -3 * frame.fingers[0].tipPosition[2];
+
+      if( size < config.pointerSize ) {
+        size = config.pointerSize;
+      }
+
+      pointer.style.width        = size     + 'px';
+      pointer.style.height       = size     + 'px';
+      pointer.style.borderRadius = size - 5 + 'px';
+      pointer.style.visibility   = 'visible';
+
+      if( config.autoCenter ) {
+        tipPosition = frame.fingers[0].tipPosition;
+
+        // Check whether the finger has entered the z range of the Leap Motion. Used for the autoCenter option.
+        if( !entered ) {
+          entered         = true;
+          enteredPosition = frame.fingers[0].tipPosition;
+        }
+
+        pointer.style.top =
+          (-1 * (( tipPosition[1] - enteredPosition[1] ) * body.offsetHeight / config.pointerTolerance )) +
+            ( body.offsetHeight / 2 ) + 'px';
+
+        pointer.style.left =
+          (( tipPosition[0] - enteredPosition[0] ) * body.offsetWidth / config.pointerTolerance ) +
+            ( body.offsetWidth / 2 ) + 'px';
+      }
+      else {
+        pointer.style.top  = ( 1 - (( tipPosition[1] - 50) / config.pointerTolerance )) *
+          body.offsetHeight + 'px';
+
+        pointer.style.left = ( tipPosition[0] * body.offsetWidth / config.pointerTolerance ) +
+          ( body.offsetWidth / 2 ) + 'px';
+      }
+    }
+    else {
+      // Hide pointer on exit
+      entered                  = false;
+      pointer.style.visibility = 'hidden';
+    }
+
+    // Gestures
+    if( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) {
+      var gesture = frame.gestures[0];
+
+      // One hand gestures
+      if( frame.hands.length === 1 ) {
+        // Swipe gestures. 3+ fingers.
+        if( frame.fingers.length > 2 && gesture.type === 'swipe' ) {
+          // Define here since some gestures will throw undefined for these.
+          var x = gesture.direction[0],
+              y = gesture.direction[1];
+
+          // Left/right swipe gestures
+          if( Math.abs( x ) > Math.abs( y )) {
+            if( x > 0 ) {
+              config.naturalSwipe ? Reveal.left() : Reveal.right();
+            }
+            else {
+              config.naturalSwipe ? Reveal.right() : Reveal.left();
+            }
+          }
+          // Up/down swipe gestures
+          else {
+            if( y > 0 ) {
+              config.naturalSwipe ? Reveal.down() : Reveal.up();
+            }
+            else {
+              config.naturalSwipe ? Reveal.up() : Reveal.down();
+            }
+          }
+
+          lastGesture = now;
+        }
+      }
+      // Two hand gestures
+      else if( frame.hands.length === 2 ) {
+        // Upward two hand swipe gesture
+        if( gesture.direction[1] > 0 && gesture.type === 'swipe' ) {
+          Reveal.toggleOverview();
+        }
+
+        lastGesture = now;
+      }
+    }
+  });
+
+  controller.connect();
+})();
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/markdown/example.html b/docs/slides/IHP14/_support/reveal.js/plugin/markdown/example.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/markdown/example.html
@@ -0,0 +1,129 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Markdown Demo</title>
+
+		<link rel="stylesheet" href="../../css/reveal.css">
+		<link rel="stylesheet" href="../../css/theme/default.css" id="theme">
+
+        <link rel="stylesheet" href="../../lib/css/zenburn.css">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+                <!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
+                <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section>
+
+                <!-- Slides are separated by three dashes (quick 'n dirty regular expression) -->
+                <section data-markdown data-separator="---">
+                    <script type="text/template">
+                        ## Demo 1
+                        Slide 1
+                        ---
+                        ## Demo 1
+                        Slide 2
+                        ---
+                        ## Demo 1
+                        Slide 3
+                    </script>
+                </section>
+
+                <!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
+                <section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$">
+                    <script type="text/template">
+                        ## Demo 2
+                        Slide 1.1
+
+                        --
+
+                        ## Demo 2
+                        Slide 1.2
+
+                        ---
+
+                        ## Demo 2
+                        Slide 2
+                    </script>
+                </section>
+
+                <!-- No "extra" slides, since there are no separators defined (so they'll become horizontal rulers) -->
+                <section data-markdown>
+                    <script type="text/template">
+                        A
+
+                        ---
+
+                        B
+
+                        ---
+
+                        C
+                    </script>
+                </section>
+
+                <!-- Slide attributes -->
+                <section data-markdown>
+                    <script type="text/template">
+                        <!-- .slide: data-background="#000000" -->
+                        ## Slide attributes
+                    </script>
+                </section>
+
+                <!-- Element attributes -->
+                <section data-markdown>
+                    <script type="text/template">
+                        ## Element attributes
+                        - Item 1 <!-- .element: class="fragment" data-fragment-index="2" -->
+                        - Item 2 <!-- .element: class="fragment" data-fragment-index="1" -->
+                    </script>
+                </section>
+
+                <!-- Code -->
+                <section data-markdown>
+                    <script type="text/template">
+                        ```php
+                        public function foo()
+                        {
+                            $foo = array(
+                                'bar' => 'bar'
+                            )
+                        }
+                        ```
+                    </script>
+                </section>
+
+            </div>
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.js"></script>
+
+		<script>
+
+			Reveal.initialize({
+				controls: true,
+				progress: true,
+				history: true,
+				center: true,
+
+				// Optional libraries used to extend on reveal.js
+				dependencies: [
+					{ src: '../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
+					{ src: 'marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                    { src: 'markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                    { src: '../highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+					{ src: '../notes/notes.js' }
+				]
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/markdown/example.md b/docs/slides/IHP14/_support/reveal.js/plugin/markdown/example.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/markdown/example.md
@@ -0,0 +1,31 @@
+# Markdown Demo
+
+
+
+## External 1.1
+
+Content 1.1
+
+Note: This will only appear in the speaker notes window.
+
+
+## External 1.2
+
+Content 1.2
+
+
+
+## External 2
+
+Content 2.1
+
+
+
+## External 3.1
+
+Content 3.1
+
+
+## External 3.2
+
+Content 3.2
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/markdown/markdown.js b/docs/slides/IHP14/_support/reveal.js/plugin/markdown/markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/markdown/markdown.js
@@ -0,0 +1,392 @@
+/**
+ * The reveal.js markdown plugin. Handles parsing of
+ * markdown inside of presentations as well as loading
+ * of external markdown documents.
+ */
+(function( root, factory ) {
+	if( typeof exports === 'object' ) {
+		module.exports = factory( require( './marked' ) );
+	}
+	else {
+		// Browser globals (root is window)
+		root.RevealMarkdown = factory( root.marked );
+		root.RevealMarkdown.initialize();
+	}
+}( this, function( marked ) {
+
+	if( typeof marked === 'undefined' ) {
+		throw 'The reveal.js Markdown plugin requires marked to be loaded';
+	}
+
+	if( typeof hljs !== 'undefined' ) {
+		marked.setOptions({
+			highlight: function( lang, code ) {
+				return hljs.highlightAuto( lang, code ).value;
+			}
+		});
+	}
+
+	var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$',
+		DEFAULT_NOTES_SEPARATOR = 'note:',
+		DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
+		DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
+
+
+	/**
+	 * Retrieves the markdown contents of a slide section
+	 * element. Normalizes leading tabs/whitespace.
+	 */
+	function getMarkdownFromSlide( section ) {
+
+		var template = section.querySelector( 'script' );
+
+		// strip leading whitespace so it isn't evaluated as code
+		var text = ( template || section ).textContent;
+
+		var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
+			leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
+
+		if( leadingTabs > 0 ) {
+			text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+		}
+		else if( leadingWs > 1 ) {
+			text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+		}
+
+		return text;
+
+	}
+
+	/**
+	 * Given a markdown slide section element, this will
+	 * return all arguments that aren't related to markdown
+	 * parsing. Used to forward any other user-defined arguments
+	 * to the output markdown slide.
+	 */
+	function getForwardedAttributes( section ) {
+
+		var attributes = section.attributes;
+		var result = [];
+
+		for( var i = 0, len = attributes.length; i < len; i++ ) {
+			var name = attributes[i].name,
+				value = attributes[i].value;
+
+			// disregard attributes that are used for markdown loading/parsing
+			if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
+
+			if( value ) {
+				result.push( name + '=' + value );
+			}
+			else {
+				result.push( name );
+			}
+		}
+
+		return result.join( ' ' );
+
+	}
+
+	/**
+	 * Inspects the given options and fills out default
+	 * values for what's not defined.
+	 */
+	function getSlidifyOptions( options ) {
+
+		options = options || {};
+		options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
+		options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
+		options.attributes = options.attributes || '';
+
+		return options;
+
+	}
+
+	/**
+	 * Helper function for constructing a markdown slide.
+	 */
+	function createMarkdownSlide( content, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
+
+		if( notesMatch.length === 2 ) {
+			content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
+		}
+
+		return '<script type="text/template">' + content + '</script>';
+
+	}
+
+	/**
+	 * Parses a data string into multiple slides based
+	 * on the passed in separator arguments.
+	 */
+	function slidify( markdown, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
+			horizontalSeparatorRegex = new RegExp( options.separator );
+
+		var matches,
+			lastIndex = 0,
+			isHorizontal,
+			wasHorizontal = true,
+			content,
+			sectionStack = [];
+
+		// iterate until all blocks between separators are stacked up
+		while( matches = separatorRegex.exec( markdown ) ) {
+			notes = null;
+
+			// determine direction (horizontal by default)
+			isHorizontal = horizontalSeparatorRegex.test( matches[0] );
+
+			if( !isHorizontal && wasHorizontal ) {
+				// create vertical stack
+				sectionStack.push( [] );
+			}
+
+			// pluck slide content from markdown input
+			content = markdown.substring( lastIndex, matches.index );
+
+			if( isHorizontal && wasHorizontal ) {
+				// add to horizontal stack
+				sectionStack.push( content );
+			}
+			else {
+				// add to vertical stack
+				sectionStack[sectionStack.length-1].push( content );
+			}
+
+			lastIndex = separatorRegex.lastIndex;
+			wasHorizontal = isHorizontal;
+		}
+
+		// add the remaining slide
+		( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
+
+		var markdownSections = '';
+
+		// flatten the hierarchical stack, and insert <section data-markdown> tags
+		for( var i = 0, len = sectionStack.length; i < len; i++ ) {
+			// vertical
+			if( sectionStack[i] instanceof Array ) {
+				markdownSections += '<section '+ options.attributes +'>';
+
+				sectionStack[i].forEach( function( child ) {
+					markdownSections += '<section data-markdown>' +  createMarkdownSlide( child, options ) + '</section>';
+				} );
+
+				markdownSections += '</section>';
+			}
+			else {
+				markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
+			}
+		}
+
+		return markdownSections;
+
+	}
+
+	/**
+	 * Parses any current data-markdown slides, splits
+	 * multi-slide markdown into separate sections and
+	 * handles loading of external markdown.
+	 */
+	function processSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]'),
+			section;
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			section = sections[i];
+
+			if( section.getAttribute( 'data-markdown' ).length ) {
+
+				var xhr = new XMLHttpRequest(),
+					url = section.getAttribute( 'data-markdown' );
+
+				datacharset = section.getAttribute( 'data-charset' );
+
+				// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
+				if( datacharset != null && datacharset != '' ) {
+					xhr.overrideMimeType( 'text/html; charset=' + datacharset );
+				}
+
+				xhr.onreadystatechange = function() {
+					if( xhr.readyState === 4 ) {
+						if ( xhr.status >= 200 && xhr.status < 300 ) {
+
+							section.outerHTML = slidify( xhr.responseText, {
+								separator: section.getAttribute( 'data-separator' ),
+								verticalSeparator: section.getAttribute( 'data-vertical' ),
+								notesSeparator: section.getAttribute( 'data-notes' ),
+								attributes: getForwardedAttributes( section )
+							});
+
+						}
+						else {
+
+							section.outerHTML = '<section data-state="alert">' +
+								'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
+								'Check your browser\'s JavaScript console for more details.' +
+								'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
+								'</section>';
+
+						}
+					}
+				};
+
+				xhr.open( 'GET', url, false );
+
+				try {
+					xhr.send();
+				}
+				catch ( e ) {
+					alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
+				}
+
+			}
+			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) {
+
+				section.outerHTML = slidify( getMarkdownFromSlide( section ), {
+					separator: section.getAttribute( 'data-separator' ),
+					verticalSeparator: section.getAttribute( 'data-vertical' ),
+					notesSeparator: section.getAttribute( 'data-notes' ),
+					attributes: getForwardedAttributes( section )
+				});
+
+			}
+			else {
+				section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
+			}
+		}
+
+	}
+
+	/**
+	 * Check if a node value has the attributes pattern.
+	 * If yes, extract it and add that value as one or several attributes
+	 * the the terget element.
+	 *
+	 * You need Cache Killer on Chrome to see the effect on any FOM transformation
+	 * directly on refresh (F5)
+	 * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
+	 */
+	function addAttributeInElement( node, elementTarget, separator ) {
+
+		var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
+		var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
+		var nodeValue = node.nodeValue;
+		if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
+
+			var classes = matches[1];
+			nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
+			node.nodeValue = nodeValue;
+			while( matchesClass = mardownClassRegex.exec( classes ) ) {
+				elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Add attributes to the parent element of a text node,
+	 * or the element of an attribute node.
+	 */
+	function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
+
+		if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
+			previousParentElement = element;
+			for( var i = 0; i < element.childNodes.length; i++ ) {
+				childElement = element.childNodes[i];
+				if ( i > 0 ) {
+					j = i - 1;
+					while ( j >= 0 ) {
+						aPreviousChildElement = element.childNodes[j];
+						if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
+							previousParentElement = aPreviousChildElement;
+							break;
+						}
+						j = j - 1;
+					}
+				}
+				parentSection = section;
+				if( childElement.nodeName ==  "section" ) {
+					parentSection = childElement ;
+					previousParentElement = childElement ;
+				}
+				if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
+					addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
+				}
+			}
+		}
+
+		if ( element.nodeType == Node.COMMENT_NODE ) {
+			if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
+				addAttributeInElement( element, section, separatorSectionAttributes );
+			}
+		}
+	}
+
+	/**
+	 * Converts any current data-markdown slides in the
+	 * DOM to HTML.
+	 */
+	function convertSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]');
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			var section = sections[i];
+
+			// Only parse the same slide once
+			if( !section.getAttribute( 'data-markdown-parsed' ) ) {
+
+				section.setAttribute( 'data-markdown-parsed', true )
+
+				var notes = section.querySelector( 'aside.notes' );
+				var markdown = getMarkdownFromSlide( section );
+
+				section.innerHTML = marked( markdown );
+				addAttributes( 	section, section, null, section.getAttribute( 'data-element-attributes' ) ||
+								section.parentNode.getAttribute( 'data-element-attributes' ) ||
+								DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
+								section.getAttribute( 'data-attributes' ) ||
+								section.parentNode.getAttribute( 'data-attributes' ) ||
+								DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
+
+				// If there were notes, we need to re-add them after
+				// having overwritten the section's HTML
+				if( notes ) {
+					section.appendChild( notes );
+				}
+
+			}
+
+		}
+
+	}
+
+	// API
+	return {
+
+		initialize: function() {
+			processSlides();
+			convertSlides();
+		},
+
+		// TODO: Do these belong in the API?
+		processSlides: processSlides,
+		convertSlides: convertSlides,
+		slidify: slidify
+
+	};
+
+}));
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/markdown/marked.js b/docs/slides/IHP14/_support/reveal.js/plugin/markdown/marked.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/markdown/marked.js
@@ -0,0 +1,37 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){3,} *\n*/,blockquote:/^( *>[^\n]+(\n[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr",/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";block.html=replace(block.html)("comment",/\x3c!--[\s\S]*?--\x3e/)("closed",
+/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1",
+"\\2")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm)if(this.options.tables)this.rules=block.tables;else this.rules=block.gfm}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};
+Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1)this.tokens.push({type:"space"})}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,
+"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,
+"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]="center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].split(/ *\| */);this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=
+src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);
+bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+
+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item[item.length-1]==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:cap[1]==="pre"||cap[1]==="script",text:cap[0]});continue}if(top&&
+(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]=
+"center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */);this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1][cap[1].length-1]==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",
+text:cap[0]});continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^\x3c!--[\s\S]*?--\x3e|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;
+if(!this.links)throw new Error("Tokens array requires a `links` property.");if(this.options.gfm)if(this.options.breaks)this.rules=inline.breaks;else this.rules=inline.gfm;else if(this.options.pedantic)this.rules=inline.pedantic}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);
+out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1][6]===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.url.exec(src)){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.tag.exec(src)){src=src.substring(cap[0].length);
+out+=this.options.sanitize?escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);out+=this.outputLink(cap,{href:cap[2],title:cap[3]});continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0][0];src=cap[0].substring(1)+src;continue}out+=this.outputLink(cap,link);continue}if(cap=this.rules.strong.exec(src)){src=
+src.substring(cap[0].length);out+="<strong>"+this.output(cap[2]||cap[1])+"</strong>";continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+="<em>"+this.output(cap[2]||cap[1])+"</em>";continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+="<code>"+escape(cap[2],true)+"</code>";continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+="<br>";continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+="<del>"+
+this.output(cap[1])+"</del>";continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=escape(cap[0]);continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return out};InlineLexer.prototype.outputLink=function(cap,link){if(cap[0][0]!=="!")return'<a href="'+escape(link.href)+'"'+(link.title?' title="'+escape(link.title)+'"':"")+">"+this.output(cap[1])+"</a>";else return'<img src="'+escape(link.href)+'" alt="'+escape(cap[1])+'"'+(link.title?' title="'+
+escape(link.title)+'"':"")+">"};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/--/g,"\u2014").replace(/'([^']*)'/g,"\u2018$1\u2019").replace(/"([^"]*)"/g,"\u201c$1\u201d").replace(/\.{3}/g,"\u2026")};InlineLexer.prototype.mangle=function(text){var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>0.5)ch="x"+ch.toString(16);out+="&#"+ch+";"}return out};function Parser(options){this.tokens=[];this.token=null;
+this.options=options||marked.defaults}Parser.parse=function(src,options){var parser=new Parser(options);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options);this.tokens=src.reverse();var out="";while(this.next())out+=this.tok();return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;
+while(this.peek().type==="text")body+="\n"+this.next().text;return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case "space":return"";case "hr":return"<hr>\n";case "heading":return"<h"+this.token.depth+">"+this.inline.output(this.token.text)+"</h"+this.token.depth+">\n";case "code":if(this.options.highlight){var code=this.options.highlight(this.token.text,this.token.lang);if(code!=null&&code!==this.token.text){this.token.escaped=true;this.token.text=code}}if(!this.token.escaped)this.token.text=
+escape(this.token.text,true);return"<pre><code"+(this.token.lang?' class="'+this.options.langPrefix+this.token.lang+'"':"")+">"+this.token.text+"</code></pre>\n";case "table":var body="",heading,i,row,cell,j;body+="<thead>\n<tr>\n";for(i=0;i<this.token.header.length;i++){heading=this.inline.output(this.token.header[i]);body+=this.token.align[i]?'<th align="'+this.token.align[i]+'">'+heading+"</th>\n":"<th>"+heading+"</th>\n"}body+="</tr>\n</thead>\n";body+="<tbody>\n";for(i=0;i<this.token.cells.length;i++){row=
+this.token.cells[i];body+="<tr>\n";for(j=0;j<row.length;j++){cell=this.inline.output(row[j]);body+=this.token.align[j]?'<td align="'+this.token.align[j]+'">'+cell+"</td>\n":"<td>"+cell+"</td>\n"}body+="</tr>\n"}body+="</tbody>\n";return"<table>\n"+body+"</table>\n";case "blockquote_start":var body="";while(this.next().type!=="blockquote_end")body+=this.tok();return"<blockquote>\n"+body+"</blockquote>\n";case "list_start":var type=this.token.ordered?"ol":"ul",body="";while(this.next().type!=="list_end")body+=
+this.tok();return"<"+type+">\n"+body+"</"+type+">\n";case "list_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.token.type==="text"?this.parseText():this.tok();return"<li>"+body+"</li>\n";case "loose_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.tok();return"<li>"+body+"</li>\n";case "html":return!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;case "paragraph":return"<p>"+this.inline.output(this.token.text)+
+"</p>\n";case "text":return"<p>"+this.parseText()+"</p>\n"}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=
+1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target)if(Object.prototype.hasOwnProperty.call(target,key))obj[key]=target[key]}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}if(opt)opt=merge({},marked.defaults,opt);var tokens=Lexer.lex(tokens,opt),highlight=opt.highlight,pending=0,l=tokens.length,i=0;if(!highlight||highlight.length<3)return callback(null,Parser.parse(tokens,opt));var done=function(){delete opt.highlight;
+var out=Parser.parse(tokens,opt);opt.highlight=highlight;return callback(null,out)};for(;i<l;i++)(function(token){if(token.type!=="code")return;pending++;return highlight(token.text,token.lang,function(err,code){if(code==null||code===token.text)return--pending||done();token.text=code;token.escaped=true;--pending||done()})})(tokens[i]);return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";
+if((opt||marked.defaults).silent)return"<p>An error occured:</p><pre>"+escape(e.message+"",true)+"</pre>";throw e;}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,smartLists:false,silent:false,highlight:null,langPrefix:""};marked.Parser=Parser;marked.parser=Parser.parse;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;
+marked.parse=marked;if(typeof exports==="object")module.exports=marked;else if(typeof define==="function"&&define.amd)define(function(){return marked});else this.marked=marked}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/math/math.js b/docs/slides/IHP14/_support/reveal.js/plugin/math/math.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/math/math.js
@@ -0,0 +1,64 @@
+/**
+ * A plugin which enables rendering of math equations inside
+ * of reveal.js slides. Essentially a thin wrapper for MathJax.
+ *
+ * @author Hakim El Hattab
+ */
+var RevealMath = window.RevealMath || (function(){
+
+	var options = Reveal.getConfig().math || {};
+	options.mathjax = options.mathjax || 'http://cdn.mathjax.org/mathjax/latest/MathJax.js';
+	options.config = options.config || 'TeX-AMS_HTML-full';
+
+	loadScript( options.mathjax + '?config=' + options.config, function() {
+
+		MathJax.Hub.Config({
+			messageStyle: 'none',
+			tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] },
+			skipStartupTypeset: true
+		});
+
+		// Typeset followed by an immediate reveal.js layout since
+		// the typesetting process could affect slide height
+		MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
+		MathJax.Hub.Queue( Reveal.layout );
+
+		// Reprocess equations in slides when they turn visible
+		Reveal.addEventListener( 'slidechanged', function( event ) {
+
+			MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
+
+		} );
+
+	} );
+
+	function loadScript( url, callback ) {
+
+		var head = document.querySelector( 'head' );
+		var script = document.createElement( 'script' );
+		script.type = 'text/javascript';
+		script.src = url;
+
+		// Wrapper for callback to make sure it only fires once
+		var finish = function() {
+			if( typeof callback === 'function' ) {
+				callback.call();
+				callback = null;
+			}
+		}
+
+		script.onload = finish;
+
+		// IE
+		script.onreadystatechange = function() {
+			if ( this.readyState === 'loaded' ) {
+				finish();
+			}
+		}
+
+		// Normal browsers
+		head.appendChild( script );
+
+	}
+
+})();
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/client.js b/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/client.js
@@ -0,0 +1,13 @@
+(function() {
+	var multiplex = Reveal.getConfig().multiplex;
+	var socketId = multiplex.id;
+	var socket = io.connect(multiplex.url);
+
+	socket.on(multiplex.id, function(data) {
+		// ignore data from sockets that aren't ours
+		if (data.socketId !== socketId) { return; }
+		if( window.location.host === 'localhost:1947' ) return;
+
+		Reveal.slide(data.indexh, data.indexv, data.indexf, 'remote');
+	});
+}());
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/index.js b/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/index.js
@@ -0,0 +1,56 @@
+var express		= require('express');
+var fs			= require('fs');
+var io			= require('socket.io');
+var crypto		= require('crypto');
+
+var app			= express.createServer();
+var staticDir	= express.static;
+
+io				= io.listen(app);
+
+var opts = {
+	port: 1948,
+	baseDir : __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		if (typeof slideData.secret == 'undefined' || slideData.secret == null || slideData.secret === '') return;
+		if (createHash(slideData.secret) === slideData.socketId) {
+			slideData.secret = null;
+			socket.broadcast.emit(slideData.socketId, slideData);
+		};
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/token", function(req,res) {
+	var ts = new Date().getTime();
+	var rand = Math.floor(Math.random()*9999999);
+	var secret = ts.toString() + rand.toString();
+	res.send({secret: secret, socketId: createHash(secret)});
+});
+
+var createHash = function(secret) {
+	var cipher = crypto.createCipher('blowfish', secret);
+	return(cipher.final('hex'));
+};
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset );
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/master.js b/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/master.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/multiplex/master.js
@@ -0,0 +1,51 @@
+(function() {
+	// Don't emit events from inside of notes windows
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var multiplex = Reveal.getConfig().multiplex;
+
+	var socket = io.connect(multiplex.url);
+
+	var notify = function( slideElement, indexh, indexv, origin ) {
+		if( typeof origin === 'undefined' && origin !== 'remote' ) {
+			var nextindexh;
+			var nextindexv;
+
+			var fragmentindex = Reveal.getIndices().f;
+			if (typeof fragmentindex == 'undefined') {
+				fragmentindex = 0;
+			}
+
+			if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+				nextindexh = indexh;
+				nextindexv = indexv + 1;
+			} else {
+				nextindexh = indexh + 1;
+				nextindexv = 0;
+			}
+
+			var slideData = {
+				indexh : indexh,
+				indexv : indexv,
+				indexf : fragmentindex,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				secret: multiplex.secret,
+				socketId : multiplex.id
+			};
+
+			socket.emit('slidechanged', slideData);
+		}
+	}
+
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		notify( event.currentSlide, event.indexh, event.indexv, event.origin );
+	} );
+
+	var fragmentNotify = function( event ) {
+		notify( Reveal.getCurrentSlide(), Reveal.getIndices().h, Reveal.getIndices().v, event.origin );
+	};
+
+	Reveal.addEventListener( 'fragmentshown', fragmentNotify );
+	Reveal.addEventListener( 'fragmenthidden', fragmentNotify );
+}());
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/client.js b/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/client.js
@@ -0,0 +1,57 @@
+(function() {
+	// don't emit events from inside the previews themselves
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var socket = io.connect(window.location.origin);
+	var socketId = Math.random().toString().slice(2);
+	
+	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
+	window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId);
+
+	// Fires when a fragment is shown
+	Reveal.addEventListener( 'fragmentshown', function( event ) {
+		var fragmentData = {
+			fragment : 'next',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when a fragment is hidden
+	Reveal.addEventListener( 'fragmenthidden', function( event ) {
+		var fragmentData = {
+			fragment : 'previous',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when slide is changed
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		var nextindexh;
+		var nextindexv;
+		var slideElement = event.currentSlide;
+
+		if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+			nextindexh = event.indexh;
+			nextindexv = event.indexv + 1;
+		} else {
+			nextindexh = event.indexh + 1;
+			nextindexv = 0;
+		}
+
+		var notes = slideElement.querySelector('aside.notes');
+		var slideData = {
+			notes : notes ? notes.innerHTML : '',
+			indexh : event.indexh,
+			indexv : event.indexv,
+			nextindexh : nextindexh,
+			nextindexv : nextindexv,
+			socketId : socketId,
+			markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false
+
+		};
+
+		socket.emit('slidechanged', slideData);
+	} );
+}());
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/index.js b/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/index.js
@@ -0,0 +1,59 @@
+var express   = require('express');
+var fs        = require('fs');
+var io        = require('socket.io');
+var _         = require('underscore');
+var Mustache  = require('mustache');
+
+var app       = express.createServer();
+var staticDir = express.static;
+
+io            = io.listen(app);
+
+var opts = {
+	port :      1947,
+	baseDir :   __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		socket.broadcast.emit('slidedata', slideData);
+	});
+	socket.on('fragmentchanged', function(fragmentData) {
+		socket.broadcast.emit('fragmentdata', fragmentData);
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/notes/:socketId", function(req, res) {
+
+	fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) {
+		res.send(Mustache.to_html(data.toString(), {
+			socketId : req.params.socketId
+		}));
+	});
+	// fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res);
+});
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
+
+console.log( brown + "reveal.js - Speaker Notes" + reset );
+console.log( "1. Open the slides at " + green + slidesLocation + reset );
+console.log( "2. Click on the link your JS console to go to the notes page" );
+console.log( "3. Advance through your slides and your notes will advance automatically" );
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/notes.html b/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/notes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/notes-server/notes.html
@@ -0,0 +1,142 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+
+		<meta name="viewport" content="width=1150">
+
+		<title>reveal.js - Slide Notes</title>
+
+		<style>
+			body {
+				font-family: Helvetica;
+			}
+
+			#notes {
+				font-size: 24px;
+				width: 640px;
+				margin-top: 5px;
+				clear: left;
+			}
+
+			#wrap-current-slide {
+				width: 640px;
+				height: 512px;
+				float: left;
+				overflow: hidden;
+			}
+
+			#current-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+				    -ms-transform-origin: 0 0;
+				     -o-transform-origin: 0 0;
+				        transform-origin: 0 0;
+
+				-webkit-transform: scale(0.5);
+				   -moz-transform: scale(0.5);
+				    -ms-transform: scale(0.5);
+				     -o-transform: scale(0.5);
+				        transform: scale(0.5);
+			}
+
+			#wrap-next-slide {
+				width: 448px;
+				height: 358px;
+				float: left;
+				margin: 0 0 0 10px;
+				overflow: hidden;
+			}
+
+			#next-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+				    -ms-transform-origin: 0 0;
+				     -o-transform-origin: 0 0;
+				        transform-origin: 0 0;
+
+				-webkit-transform: scale(0.35);
+				   -moz-transform: scale(0.35);
+				    -ms-transform: scale(0.35);
+				     -o-transform: scale(0.35);
+				        transform: scale(0.35);
+			}
+
+			.slides {
+				position: relative;
+				margin-bottom: 10px;
+				border: 1px solid black;
+				border-radius: 2px;
+				background: rgb(28, 30, 32);
+			}
+
+			.slides span {
+				position: absolute;
+				top: 3px;
+				left: 3px;
+				font-weight: bold;
+				font-size: 14px;
+				color: rgba( 255, 255, 255, 0.9 );
+			}
+		</style>
+	</head>
+
+	<body>
+
+		<div id="wrap-current-slide" class="slides">
+			<iframe src="/?receiver" width="1280" height="1024" id="current-slide"></iframe>
+		</div>
+
+		<div id="wrap-next-slide" class="slides">
+			<iframe src="/?receiver" width="640" height="512" id="next-slide"></iframe>
+			<span>UPCOMING:</span>
+		</div>
+		<div id="notes"></div>
+
+		<script src="/socket.io/socket.io.js"></script>
+		<script src="/plugin/markdown/marked.js"></script>
+
+		<script>
+		var socketId = '{{socketId}}';
+		var socket = io.connect(window.location.origin);
+		var notes = document.getElementById('notes');
+		var currentSlide = document.getElementById('current-slide');
+		var nextSlide = document.getElementById('next-slide');
+
+		socket.on('slidedata', function(data) {
+			// ignore data from sockets that aren't ours
+			if (data.socketId !== socketId) { return; }
+
+			if (data.markdown) {
+				notes.innerHTML = marked(data.notes);
+			}
+			else {
+				notes.innerHTML = data.notes;
+			}
+
+			currentSlide.contentWindow.Reveal.slide(data.indexh, data.indexv);
+			nextSlide.contentWindow.Reveal.slide(data.nextindexh, data.nextindexv);
+		});
+		socket.on('fragmentdata', function(data) {
+			// ignore data from sockets that aren't ours
+			if (data.socketId !== socketId) { return; }
+
+			if (data.fragment === 'next') {
+				currentSlide.contentWindow.Reveal.nextFragment();
+			}
+			else if (data.fragment === 'previous') {
+				currentSlide.contentWindow.Reveal.prevFragment();
+			}
+		});
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/notes/notes.html b/docs/slides/IHP14/_support/reveal.js/plugin/notes/notes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/notes/notes.html
@@ -0,0 +1,267 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Slide Notes</title>
+
+		<style>
+			body {
+				font-family: Helvetica;
+			}
+
+			#notes {
+				font-size: 24px;
+				width: 640px;
+				margin-top: 5px;
+				clear: left;
+			}
+
+			#wrap-current-slide {
+				width: 640px;
+				height: 512px;
+				float: left;
+				overflow: hidden;
+			}
+
+			#current-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+					-ms-transform-origin: 0 0;
+					 -o-transform-origin: 0 0;
+						transform-origin: 0 0;
+
+				-webkit-transform: scale(0.5);
+				   -moz-transform: scale(0.5);
+					-ms-transform: scale(0.5);
+					 -o-transform: scale(0.5);
+						transform: scale(0.5);
+			}
+
+			#wrap-next-slide {
+				width: 448px;
+				height: 358px;
+				float: left;
+				margin: 0 0 0 10px;
+				overflow: hidden;
+			}
+
+			#next-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+					-ms-transform-origin: 0 0;
+					 -o-transform-origin: 0 0;
+						transform-origin: 0 0;
+
+				-webkit-transform: scale(0.35);
+				   -moz-transform: scale(0.35);
+					-ms-transform: scale(0.35);
+					 -o-transform: scale(0.35);
+						transform: scale(0.35);
+			}
+
+			.slides {
+				position: relative;
+				margin-bottom: 10px;
+				border: 1px solid black;
+				border-radius: 2px;
+				background: rgb(28, 30, 32);
+			}
+
+			.slides span {
+				position: absolute;
+				top: 3px;
+				left: 3px;
+				font-weight: bold;
+				font-size: 14px;
+				color: rgba( 255, 255, 255, 0.9 );
+			}
+
+			.error {
+				font-weight: bold;
+				color: red;
+				font-size: 1.5em;
+				text-align: center;
+				margin-top: 10%;
+			}
+
+			.error code {
+				font-family: monospace;
+			}
+
+			.time {
+				width: 448px;
+				margin: 30px 0 0 10px;
+				float: left;
+				text-align: center;
+				opacity: 0;
+
+				-webkit-transition: opacity 0.4s;
+				   -moz-transition: opacity 0.4s;
+				     -o-transition: opacity 0.4s;
+				        transition: opacity 0.4s;
+			}
+
+			.elapsed,
+			.clock {
+				color: #333;
+				font-size: 2em;
+				text-align: center;
+				display: inline-block;
+				padding: 0.5em;
+				background-color: #eee;
+				border-radius: 10px;
+			}
+
+			.elapsed h2,
+			.clock h2 {
+				font-size: 0.8em;
+				line-height: 100%;
+				margin: 0;
+				color: #aaa;
+			}
+
+			.elapsed .mute {
+				color: #ddd;
+			}
+
+		</style>
+	</head>
+
+	<body>
+
+		<script>
+			function getNotesURL( controls ) {
+				return window.opener.location.protocol + '//' + window.opener.location.host + window.opener.location.pathname + '?receiver&controls='+ ( controls || 'false' ) +'&progress=false&overview=false' + window.opener.location.hash;
+			}
+			var notesCurrentSlideURL = getNotesURL( true );
+			var notesNextSlideURL = getNotesURL( false );
+		</script>
+
+		<div id="wrap-current-slide" class="slides">
+			<script>document.write( '<iframe width="1280" height="1024" id="current-slide" src="'+ notesCurrentSlideURL +'"></iframe>' );</script>
+		</div>
+
+		<div id="wrap-next-slide" class="slides">
+			<script>document.write( '<iframe width="640" height="512" id="next-slide" src="'+ notesNextSlideURL +'"></iframe>' );</script>
+			<span>UPCOMING:</span>
+		</div>
+
+		<div class="time">
+			<div class="clock">
+				<h2>Time</h2>
+				<span id="clock">0:00:00 AM</span>
+			</div>
+			<div class="elapsed">
+				<h2>Elapsed</h2>
+				<span id="hours">00</span><span id="minutes">:00</span><span id="seconds">:00</span>
+			</div>
+		</div>
+
+		<div id="notes"></div>
+
+		<script src="../../plugin/markdown/marked.js"></script>
+		<script>
+
+			window.addEventListener( 'load', function() {
+
+				if( window.opener && window.opener.location && window.opener.location.href ) {
+
+					var notes = document.getElementById( 'notes' ),
+						currentSlide = document.getElementById( 'current-slide' ),
+						nextSlide = document.getElementById( 'next-slide' ),
+						silenced = false;
+
+					window.addEventListener( 'message', function( event ) {
+						var data = JSON.parse( event.data );
+
+						// No need for updating the notes in case of fragment changes
+						if ( data.notes !== undefined) {
+							if( data.markdown ) {
+								notes.innerHTML = marked( data.notes );
+							}
+							else {
+								notes.innerHTML = data.notes;
+							}
+						}
+
+						silenced = true;
+
+						// Update the note slides
+						currentSlide.contentWindow.Reveal.slide( data.indexh, data.indexv, data.indexf );
+						nextSlide.contentWindow.Reveal.slide( data.nextindexh, data.nextindexv );
+
+						silenced = false;
+
+					}, false );
+
+					var start = new Date(),
+						timeEl = document.querySelector( '.time' ),
+						clockEl = document.getElementById( 'clock' ),
+						hoursEl = document.getElementById( 'hours' ),
+						minutesEl = document.getElementById( 'minutes' ),
+						secondsEl = document.getElementById( 'seconds' );
+
+					setInterval( function() {
+
+						timeEl.style.opacity = 1;
+
+						var diff, hours, minutes, seconds,
+							now = new Date();
+
+						diff = now.getTime() - start.getTime();
+						hours = Math.floor( diff / ( 1000 * 60 * 60 ) );
+						minutes = Math.floor( ( diff / ( 1000 * 60 ) ) % 60 );
+						seconds = Math.floor( ( diff / 1000 ) % 60 );
+
+						clockEl.innerHTML = now.toLocaleTimeString();
+						hoursEl.innerHTML = zeroPadInteger( hours );
+						hoursEl.className = hours > 0 ? "" : "mute";
+						minutesEl.innerHTML = ":" + zeroPadInteger( minutes );
+						minutesEl.className = minutes > 0 ? "" : "mute";
+						secondsEl.innerHTML = ":" + zeroPadInteger( seconds );
+
+					}, 1000 );
+
+					// Broadcasts the state of the notes window to synchronize
+					// the main window
+					function synchronizeMainWindow() {
+
+						if( !silenced ) {
+							var indices = currentSlide.contentWindow.Reveal.getIndices();
+							window.opener.Reveal.slide( indices.h, indices.v, indices.f );
+						}
+
+					}
+
+					// Navigate the main window when the notes slide changes
+					currentSlide.contentWindow.Reveal.addEventListener( 'slidechanged', synchronizeMainWindow );
+					currentSlide.contentWindow.Reveal.addEventListener( 'fragmentshown', synchronizeMainWindow );
+					currentSlide.contentWindow.Reveal.addEventListener( 'fragmenthidden', synchronizeMainWindow );
+
+				}
+				else {
+
+					document.body.innerHTML =  '<p class="error">Unable to access <code>window.opener.location</code>.<br>Make sure the presentation is running on a web server.</p>';
+
+				}
+
+
+			}, false );
+
+			function zeroPadInteger( num ) {
+				var str = "00" + parseInt( num );
+				return str.substring( str.length - 2 );
+			}
+
+		</script>
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/notes/notes.js b/docs/slides/IHP14/_support/reveal.js/plugin/notes/notes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/notes/notes.js
@@ -0,0 +1,78 @@
+/**
+ * Handles opening of and synchronization with the reveal.js
+ * notes window.
+ */
+var RevealNotes = (function() {
+
+	function openNotes() {
+		var jsFileLocation = document.querySelector('script[src$="notes.js"]').src;  // this js file path
+		jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, '');   // the js folder path
+		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' );
+
+		// Fires when slide is changed
+		Reveal.addEventListener( 'slidechanged', post );
+
+		// Fires when a fragment is shown
+		Reveal.addEventListener( 'fragmentshown', post );
+
+		// Fires when a fragment is hidden
+		Reveal.addEventListener( 'fragmenthidden', post );
+
+		/**
+		 * Posts the current slide data to the notes window
+		 */
+		function post() {
+			var slideElement = Reveal.getCurrentSlide(),
+				slideIndices = Reveal.getIndices(),
+				messageData;
+
+			var notes = slideElement.querySelector( 'aside.notes' ),
+				nextindexh,
+				nextindexv;
+
+			if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
+				nextindexh = slideIndices.h;
+				nextindexv = slideIndices.v + 1;
+			} else {
+				nextindexh = slideIndices.h + 1;
+				nextindexv = 0;
+			}
+
+			messageData = {
+				notes : notes ? notes.innerHTML : '',
+				indexh : slideIndices.h,
+				indexv : slideIndices.v,
+				indexf : slideIndices.f,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
+			};
+
+			notesPopup.postMessage( JSON.stringify( messageData ), '*' );
+		}
+
+		// Navigate to the current slide when the notes are loaded
+		notesPopup.addEventListener( 'load', function( event ) {
+			post();
+		}, false );
+	}
+
+	// If the there's a 'notes' query set, open directly
+	if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
+		openNotes();
+	}
+
+	// Open the notes when the 's' key is hit
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openNotes();
+		}
+	}, false );
+
+	return { open: openNotes };
+})();
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/postmessage/example.html b/docs/slides/IHP14/_support/reveal.js/plugin/postmessage/example.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/postmessage/example.html
@@ -0,0 +1,39 @@
+<html>
+	<body>
+
+		<iframe id="reveal" src="../../index.html" style="border: 0;" width="500" height="500"></iframe>
+
+		<div>
+			<input id="back" type="button" value="go back"/>
+			<input id="ahead" type="button" value="go ahead"/>
+			<input id="slideto" type="button" value="slideto 2-2"/>
+		</div>
+
+		<script>
+
+			(function (){
+
+				var back = document.getElementById( 'back' ),
+						ahead = document.getElementById( 'ahead' ),
+						slideto = document.getElementById( 'slideto' ),
+						reveal =  window.frames[0];
+
+					back.addEventListener( 'click', function () {
+						
+					reveal.postMessage( JSON.stringify({method: 'prev', args: []}), '*' );
+				}, false );
+
+				ahead.addEventListener( 'click', function (){
+					reveal.postMessage( JSON.stringify({method: 'next', args: []}), '*' );
+				}, false );
+
+				slideto.addEventListener( 'click', function (){
+					reveal.postMessage( JSON.stringify({method: 'slide', args: [2,2]}), '*' );
+				}, false );
+
+			}());
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/postmessage/postmessage.js b/docs/slides/IHP14/_support/reveal.js/plugin/postmessage/postmessage.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/postmessage/postmessage.js
@@ -0,0 +1,42 @@
+/*
+
+	simple postmessage plugin
+
+	Useful when a reveal slideshow is inside an iframe.
+	It allows to call reveal methods from outside.
+
+	Example:
+		 var reveal =  window.frames[0];
+
+		 // Reveal.prev(); 
+		 reveal.postMessage(JSON.stringify({method: 'prev', args: []}), '*');
+		 // Reveal.next(); 
+		 reveal.postMessage(JSON.stringify({method: 'next', args: []}), '*');
+		 // Reveal.slide(2, 2); 
+		 reveal.postMessage(JSON.stringify({method: 'slide', args: [2,2]}), '*');
+
+	Add to the slideshow:
+
+		dependencies: [
+			...
+			{ src: 'plugin/postmessage/postmessage.js', async: true, condition: function() { return !!document.body.classList; } }
+		]
+
+*/
+
+(function (){
+
+	window.addEventListener( "message", function ( event ) {
+		var data = JSON.parse( event.data ),
+				method = data.method,
+				args = data.args;
+
+		if( typeof Reveal[method] === 'function' ) {
+			Reveal[method].apply( Reveal, data.args );
+		}
+	}, false);
+
+}());
+
+
+
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/print-pdf/print-pdf.js b/docs/slides/IHP14/_support/reveal.js/plugin/print-pdf/print-pdf.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/print-pdf/print-pdf.js
@@ -0,0 +1,44 @@
+/**
+ * phantomjs script for printing presentations to PDF.
+ *
+ * Example:
+ * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf
+ *
+ * By Manuel Bieh (https://github.com/manuelbieh)
+ */
+
+// html2pdf.js
+var page = new WebPage();
+var system = require( 'system' );
+
+page.viewportSize  = {
+	width: 1024,
+	height: 768
+};
+
+page.paperSize = {
+	format: 'letter',
+	orientation: 'landscape',
+	margin: {
+		left: '0',
+		right: '0',
+		top: '0',
+		bottom: '0'
+	}
+};
+
+var revealFile = system.args[1] || 'index.html?print-pdf';
+var slideFile = system.args[2] || 'slides.pdf';
+
+if( slideFile.match( /\.pdf$/gi ) === null ) {
+	slideFile += '.pdf';
+}
+
+console.log( 'Printing PDF...' );
+
+page.open( revealFile, function( status ) {
+	console.log( 'Printed succesfully' );
+	page.render( slideFile );
+	phantom.exit();
+} );
+
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/remotes/remotes.js b/docs/slides/IHP14/_support/reveal.js/plugin/remotes/remotes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/remotes/remotes.js
@@ -0,0 +1,39 @@
+/**
+ * Touch-based remote controller for your presentation courtesy 
+ * of the folks at http://remotes.io
+ */
+
+(function(window){
+
+    /**
+     * Detects if we are dealing with a touch enabled device (with some false positives)
+     * Borrowed from modernizr: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touch.js   
+     */
+    var hasTouch  = (function(){
+        return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
+    })();
+
+    /**
+     * Detects if notes are enable and the current page is opened inside an /iframe
+     * this prevents loading Remotes.io several times
+     */
+    var isNotesAndIframe = (function(){
+        return window.RevealNotes && !(self == top);
+    })();
+
+    if(!hasTouch && !isNotesAndIframe){
+        head.ready( 'remotes.ne.min.js', function() {
+            new Remotes("preview")
+                .on("swipe-left", function(e){ Reveal.right(); })
+                .on("swipe-right", function(e){ Reveal.left(); })
+                .on("swipe-up", function(e){ Reveal.down(); })
+                .on("swipe-down", function(e){ Reveal.up(); })
+                .on("tap", function(e){ Reveal.next(); })
+                .on("zoom-out", function(e){ Reveal.toggleOverview(true); })
+                .on("zoom-in", function(e){ Reveal.toggleOverview(false); })
+            ;
+        } );
+
+        head.js('https://hakim-static.s3.amazonaws.com/reveal-js/remotes.ne.min.js');
+    }
+})(window);
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/search/search.js b/docs/slides/IHP14/_support/reveal.js/plugin/search/search.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/search/search.js
@@ -0,0 +1,196 @@
+/*
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
+ * by navigatating to that slide and highlighting it.
+ *
+ * By Jon Snyder <snyder.jon@gmail.com>, February 2013
+ */
+
+var RevealSearch = (function() {
+
+	var matchedSlides;
+	var currentMatchedIndex;
+	var searchboxDirty;
+	var myHilitor;
+
+// Original JavaScript code by Chirp Internet: www.chirp.com.au
+// Please acknowledge use of this code by including this header.
+// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
+
+function Hilitor(id, tag)
+{
+
+  var targetNode = document.getElementById(id) || document.body;
+  var hiliteTag = tag || "EM";
+  var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
+  var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
+  var wordColor = [];
+  var colorIdx = 0;
+  var matchRegex = "";
+  var matchingSlides = [];
+
+  this.setRegex = function(input)
+  {
+    input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
+    matchRegex = new RegExp("(" + input + ")","i");
+  }
+
+  this.getRegex = function()
+  {
+    return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
+  }
+
+  // recursively apply word highlighting
+  this.hiliteWords = function(node)
+  {
+    if(node == undefined || !node) return;
+    if(!matchRegex) return;
+    if(skipTags.test(node.nodeName)) return;
+
+    if(node.hasChildNodes()) {
+      for(var i=0; i < node.childNodes.length; i++)
+        this.hiliteWords(node.childNodes[i]);
+    }
+    if(node.nodeType == 3) { // NODE_TEXT
+      if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
+      	//find the slide's section element and save it in our list of matching slides
+      	var secnode = node.parentNode;
+      	while (secnode.nodeName != 'SECTION') {
+      		secnode = secnode.parentNode;
+      	}
+      	
+      	var slideIndex = Reveal.getIndices(secnode);
+      	var slidelen = matchingSlides.length;
+      	var alreadyAdded = false;
+      	for (var i=0; i < slidelen; i++) {
+      		if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
+      			alreadyAdded = true;
+      		}
+      	}
+      	if (! alreadyAdded) {
+      		matchingSlides.push(slideIndex);
+      	}
+      	
+        if(!wordColor[regs[0].toLowerCase()]) {
+          wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
+        }
+
+        var match = document.createElement(hiliteTag);
+        match.appendChild(document.createTextNode(regs[0]));
+        match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
+        match.style.fontStyle = "inherit";
+        match.style.color = "#000";
+
+        var after = node.splitText(regs.index);
+        after.nodeValue = after.nodeValue.substring(regs[0].length);
+        node.parentNode.insertBefore(match, after);
+      }
+    }
+  };
+
+  // remove highlighting
+  this.remove = function()
+  {
+    var arr = document.getElementsByTagName(hiliteTag);
+    while(arr.length && (el = arr[0])) {
+      el.parentNode.replaceChild(el.firstChild, el);
+    }
+  };
+
+  // start highlighting at target node
+  this.apply = function(input)
+  {
+    if(input == undefined || !input) return;
+    this.remove();
+    this.setRegex(input);
+    this.hiliteWords(targetNode);
+    return matchingSlides;
+  };
+
+}
+
+	function openSearch() {
+		//ensure the search term input dialog is visible and has focus:
+		var inputbox = document.getElementById("searchinput");
+		inputbox.style.display = "inline";
+		inputbox.focus();
+		inputbox.select();
+	}
+
+	function toggleSearch() {
+		var inputbox = document.getElementById("searchinput");
+		if (inputbox.style.display !== "inline") {
+			openSearch();
+		}
+		else {
+			inputbox.style.display = "none";
+			myHilitor.remove();
+		}
+	}
+
+	function doSearch() {
+		//if there's been a change in the search term, perform a new search:
+		if (searchboxDirty) {
+			var searchstring = document.getElementById("searchinput").value;
+
+			//find the keyword amongst the slides
+			myHilitor = new Hilitor("slidecontent");
+			matchedSlides = myHilitor.apply(searchstring);
+			currentMatchedIndex = 0;
+		}
+
+		//navigate to the next slide that has the keyword, wrapping to the first if necessary
+		if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
+			currentMatchedIndex = 0;
+		}
+		if (matchedSlides.length > currentMatchedIndex) {
+			Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
+			currentMatchedIndex++;
+		}
+	}
+
+	var dom = {};
+	dom.wrapper = document.querySelector( '.reveal' );
+
+	if( !dom.wrapper.querySelector( '.searchbox' ) ) {
+			var searchElement = document.createElement( 'div' );
+			searchElement.id = "searchinputdiv";
+			searchElement.classList.add( 'searchdiv' );
+      searchElement.style.position = 'absolute';
+      searchElement.style.top = '10px';
+      searchElement.style.left = '10px';
+      //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
+			searchElement.innerHTML = '<span><input type="search" id="searchinput" class="searchinput" style="vertical-align: top;"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJiSURBVHjatFZNaxNBGH5md+Mmu92NVdKDRipSAyqCghgQD4L4cRe86UUtAQ+eFCxoa4/25EXBFi8eBE+eRPoDhB6KgiiixdAPCEkx2pjvTXadd9yNsflwuyUDD/O+u8PzzDPvzOwyx3EwyCZhwG3gAkp7MnpjgbopjsltcD4gjuXZZKeAR348MYLYTm3LzOs/y3j3JTfZxgXWXmTuwPHIc4VmoOmv5IrI53+AO2DdHLjkDWQ3GoEEVFXtXQOvkSnPWcyUceviLhwbDYv8/XIVj97kse7TodLvZXxYxrPUHkQ1ufXs3FEdybEIxucySOesoNvUgWU1cP3MkCBfTFdw9fGaAMVmRELq7LBw2Q3/FaAxxWIRpw+ZIr/7IouPqzUBiqmdHAv7EuhRAwf1er2Vy4x1jW3b2d5Jfvu5IPp7l2LYbcgCFFNb+FoJ7oBqEAqFMPNqFcmEgVMJDfMT+1tvN0pNjERlMS6QA5pFOKxiKVPFhakPeL3It+WGJUDxt2wFR+JhzI7v5ctkd8DXOZAkCYYxhO+lKm4+Xfqz/rIixBuNBl7eOYzkQQNzqX249mRl6zUgEcYkaJrGhUwBinVdh6IouPzwE6/DL5w4oLkH8y981aDf+uq6hlKpJESiUdNfDZi7/ehG9K6KfiA3pml0PLcsq+cSMTj2NL9ukc4UOmz7AZ3+crkC4mHujFvXNaMFB3bEr8xPS6p5O+jXxq4VZtaen7/PwzrntjcLUE0iHPS1Ud1cdiEJl/8WivZk0wXd7zWOMkeF8s0CcAmkNrC2nvXZDbbbN73ccYnZoH9bfgswAFzAe9/h3dbKAAAAAElFTkSuQmCC" id="searchbutton" class="searchicon" style="vertical-align: top; margin-top: -1px;"/></span>';
+			dom.wrapper.appendChild( searchElement );
+	}
+
+	document.getElementById("searchbutton").addEventListener( 'click', function(event) {
+		doSearch();
+	}, false );
+
+	document.getElementById("searchinput").addEventListener( 'keyup', function( event ) {
+		switch (event.keyCode) {
+			case 13:
+				event.preventDefault();
+				doSearch();
+				searchboxDirty = false;
+				break;
+			default:
+				searchboxDirty = true;
+		}
+	}, false );
+
+	// Open the search when the 's' key is hit (yes, this conflicts with the notes plugin, disabling for now)
+	/*
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openSearch();
+		}
+	}, false );
+*/
+	return { open: openSearch };
+})();
diff --git a/docs/slides/IHP14/_support/reveal.js/plugin/zoom-js/zoom.js b/docs/slides/IHP14/_support/reveal.js/plugin/zoom-js/zoom.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/plugin/zoom-js/zoom.js
@@ -0,0 +1,258 @@
+// Custom reveal.js integration
+(function(){
+	var isEnabled = true;
+
+	document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) {
+		var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key';
+
+		if( event[ modifier ] && isEnabled ) {
+			event.preventDefault();
+			zoom.to({ element: event.target, pan: false });
+		}
+	} );
+
+	Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
+	Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
+})();
+
+/*!
+ * zoom.js 0.2 (modified version for use with reveal.js)
+ * http://lab.hakim.se/zoom-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var zoom = (function(){
+
+	// The current zoom level (scale)
+	var level = 1;
+
+	// The current mouse position, used for panning
+	var mouseX = 0,
+		mouseY = 0;
+
+	// Timeout before pan is activated
+	var panEngageTimeout = -1,
+		panUpdateInterval = -1;
+
+	var currentOptions = null;
+
+	// Check for transform support so that we can fallback otherwise
+	var supportsTransforms = 	'WebkitTransform' in document.body.style ||
+								'MozTransform' in document.body.style ||
+								'msTransform' in document.body.style ||
+								'OTransform' in document.body.style ||
+								'transform' in document.body.style;
+
+	if( supportsTransforms ) {
+		// The easing that will be applied when we zoom in/out
+		document.body.style.transition = 'transform 0.8s ease';
+		document.body.style.OTransition = '-o-transform 0.8s ease';
+		document.body.style.msTransition = '-ms-transform 0.8s ease';
+		document.body.style.MozTransition = '-moz-transform 0.8s ease';
+		document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
+	}
+
+	// Zoom out if the user hits escape
+	document.addEventListener( 'keyup', function( event ) {
+		if( level !== 1 && event.keyCode === 27 ) {
+			zoom.out();
+		}
+	}, false );
+
+	// Monitor mouse movement for panning
+	document.addEventListener( 'mousemove', function( event ) {
+		if( level !== 1 ) {
+			mouseX = event.clientX;
+			mouseY = event.clientY;
+		}
+	}, false );
+
+	/**
+	 * Applies the CSS required to zoom in, prioritizes use of CSS3
+	 * transforms but falls back on zoom for IE.
+	 *
+	 * @param {Number} pageOffsetX
+	 * @param {Number} pageOffsetY
+	 * @param {Number} elementOffsetX
+	 * @param {Number} elementOffsetY
+	 * @param {Number} scale
+	 */
+	function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) {
+
+		if( supportsTransforms ) {
+			var origin = pageOffsetX +'px '+ pageOffsetY +'px',
+				transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')';
+
+			document.body.style.transformOrigin = origin;
+			document.body.style.OTransformOrigin = origin;
+			document.body.style.msTransformOrigin = origin;
+			document.body.style.MozTransformOrigin = origin;
+			document.body.style.WebkitTransformOrigin = origin;
+
+			document.body.style.transform = transform;
+			document.body.style.OTransform = transform;
+			document.body.style.msTransform = transform;
+			document.body.style.MozTransform = transform;
+			document.body.style.WebkitTransform = transform;
+		}
+		else {
+			// Reset all values
+			if( scale === 1 ) {
+				document.body.style.position = '';
+				document.body.style.left = '';
+				document.body.style.top = '';
+				document.body.style.width = '';
+				document.body.style.height = '';
+				document.body.style.zoom = '';
+			}
+			// Apply scale
+			else {
+				document.body.style.position = 'relative';
+				document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px';
+				document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px';
+				document.body.style.width = ( scale * 100 ) + '%';
+				document.body.style.height = ( scale * 100 ) + '%';
+				document.body.style.zoom = scale;
+			}
+		}
+
+		level = scale;
+
+		if( level !== 1 && document.documentElement.classList ) {
+			document.documentElement.classList.add( 'zoomed' );
+		}
+		else {
+			document.documentElement.classList.remove( 'zoomed' );
+		}
+	}
+
+	/**
+	 * Pan the document when the mosue cursor approaches the edges
+	 * of the window.
+	 */
+	function pan() {
+		var range = 0.12,
+			rangeX = window.innerWidth * range,
+			rangeY = window.innerHeight * range,
+			scrollOffset = getScrollOffset();
+
+		// Up
+		if( mouseY < rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
+		}
+		// Down
+		else if( mouseY > window.innerHeight - rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
+		}
+
+		// Left
+		if( mouseX < rangeX ) {
+			window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
+		}
+		// Right
+		else if( mouseX > window.innerWidth - rangeX ) {
+			window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
+		}
+	}
+
+	function getScrollOffset() {
+		return {
+			x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
+			y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset
+		}
+	}
+
+	return {
+		/**
+		 * Zooms in on either a rectangle or HTML element.
+		 *
+		 * @param {Object} options
+		 *   - element: HTML element to zoom in on
+		 *   OR
+		 *   - x/y: coordinates in non-transformed space to zoom in on
+		 *   - width/height: the portion of the screen to zoom in on
+		 *   - scale: can be used instead of width/height to explicitly set scale
+		 */
+		to: function( options ) {
+			// Due to an implementation limitation we can't zoom in
+			// to another element without zooming out first
+			if( level !== 1 ) {
+				zoom.out();
+			}
+			else {
+				options.x = options.x || 0;
+				options.y = options.y || 0;
+
+				// If an element is set, that takes precedence
+				if( !!options.element ) {
+					// Space around the zoomed in element to leave on screen
+					var padding = 20;
+
+					options.width = options.element.getBoundingClientRect().width + ( padding * 2 );
+					options.height = options.element.getBoundingClientRect().height + ( padding * 2 );
+					options.x = options.element.getBoundingClientRect().left - padding;
+					options.y = options.element.getBoundingClientRect().top - padding;
+				}
+
+				// If width/height values are set, calculate scale from those values
+				if( options.width !== undefined && options.height !== undefined ) {
+					options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
+				}
+
+				if( options.scale > 1 ) {
+					options.x *= options.scale;
+					options.y *= options.scale;
+
+					var scrollOffset = getScrollOffset();
+
+					if( options.element ) {
+						scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2;
+					}
+
+					magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale );
+
+					if( options.pan !== false ) {
+
+						// Wait with engaging panning as it may conflict with the
+						// zoom transition
+						panEngageTimeout = setTimeout( function() {
+							panUpdateInterval = setInterval( pan, 1000 / 60 );
+						}, 800 );
+
+					}
+				}
+
+				currentOptions = options;
+			}
+		},
+
+		/**
+		 * Resets the document zoom state to its default.
+		 */
+		out: function() {
+			clearTimeout( panEngageTimeout );
+			clearInterval( panUpdateInterval );
+
+			var scrollOffset = getScrollOffset();
+
+			if( currentOptions && currentOptions.element ) {
+				scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2;
+			}
+
+			magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 );
+
+			level = 1;
+		},
+
+		// Alias
+		magnify: function( options ) { this.to( options ) },
+		reset: function() { this.out() },
+
+		zoomLevel: function() {
+			return level;
+		}
+	}
+
+})();
+
diff --git a/docs/slides/IHP14/_support/reveal.js/test/examples/assets/image1.png b/docs/slides/IHP14/_support/reveal.js/test/examples/assets/image1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/_support/reveal.js/test/examples/assets/image1.png differ
diff --git a/docs/slides/IHP14/_support/reveal.js/test/examples/assets/image2.png b/docs/slides/IHP14/_support/reveal.js/test/examples/assets/image2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/_support/reveal.js/test/examples/assets/image2.png differ
diff --git a/docs/slides/IHP14/_support/reveal.js/test/examples/barebones.html b/docs/slides/IHP14/_support/reveal.js/test/examples/barebones.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/examples/barebones.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Barebones</title>
+
+		<link rel="stylesheet" href="../../css/reveal.min.css">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+				<section>
+					<h2>Barebones Presentation</h2>
+					<p>This example contains the bare minimum includes and markup required to run a reveal.js presentation.</p>
+				</section>
+
+				<section>
+					<h2>No Theme</h2>
+					<p>There's no theme included, so it will fall back on browser defaults.</p>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../../js/reveal.min.js"></script>
+
+		<script>
+
+			Reveal.initialize();
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/test/examples/embedded-media.html b/docs/slides/IHP14/_support/reveal.js/test/examples/embedded-media.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/examples/embedded-media.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Embedded Media</title>
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/theme/default.css" id="theme">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+				<section>
+					<h2>Embedded Media Test</h2>
+				</section>
+
+				<section>
+					<iframe data-autoplay width="420" height="345" src="http://www.youtube.com/embed/l3RQZ4mcr1c"></iframe>
+				</section>
+
+				<section>
+					<h2>Empty Slide</h2>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.min.js"></script>
+
+		<script>
+
+			Reveal.initialize({
+				transition: 'linear'
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/test/examples/math.html b/docs/slides/IHP14/_support/reveal.js/test/examples/math.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/examples/math.html
@@ -0,0 +1,185 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Math Plugin</title>
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/theme/night.css" id="theme">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+				<section>
+					<h2>reveal.js Math Plugin</h2>
+					<p>A thin wrapper for MathJax</p>
+				</section>
+
+				<section>
+					<h3>The Lorenz Equations</h3>
+
+					\[\begin{aligned}
+					\dot{x} &amp; = \sigma(y-x) \\
+					\dot{y} &amp; = \rho x - y - xz \\
+					\dot{z} &amp; = -\beta z + xy
+					\end{aligned} \]
+				</section>
+
+				<section>
+					<h3>The Cauchy-Schwarz Inequality</h3>
+
+					<script type="math/tex; mode=display">
+						\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
+					</script>
+				</section>
+
+				<section>
+					<h3>A Cross Product Formula</h3>
+
+					\[\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix}
+					\mathbf{i} &amp; \mathbf{j} &amp; \mathbf{k} \\
+					\frac{\partial X}{\partial u} &amp;  \frac{\partial Y}{\partial u} &amp; 0 \\
+					\frac{\partial X}{\partial v} &amp;  \frac{\partial Y}{\partial v} &amp; 0
+					\end{vmatrix}  \]
+				</section>
+
+				<section>
+					<h3>The probability of getting \(k\) heads when flipping \(n\) coins is</h3>
+
+					\[P(E)   = {n \choose k} p^k (1-p)^{ n-k} \]
+				</section>
+
+				<section>
+					<h3>An Identity of Ramanujan</h3>
+
+					\[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} =
+					1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
+					{1+\frac{e^{-8\pi}} {1+\ldots} } } } \]
+				</section>
+
+				<section>
+					<h3>A Rogers-Ramanujan Identity</h3>
+
+					\[  1 +  \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots =
+					\prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}\]
+				</section>
+
+				<section>
+					<h3>Maxwell&#8217;s Equations</h3>
+
+					\[  \begin{aligned}
+					\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\   \nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\
+					\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\
+					\nabla \cdot \vec{\mathbf{B}} &amp; = 0 \end{aligned}
+					\]
+				</section>
+
+				<section>
+					<section>
+						<h3>The Lorenz Equations</h3>
+
+						<div class="fragment">
+							\[\begin{aligned}
+							\dot{x} &amp; = \sigma(y-x) \\
+							\dot{y} &amp; = \rho x - y - xz \\
+							\dot{z} &amp; = -\beta z + xy
+							\end{aligned} \]
+						</div>
+					</section>
+
+					<section>
+						<h3>The Cauchy-Schwarz Inequality</h3>
+
+						<div class="fragment">
+							\[ \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \]
+						</div>
+					</section>
+
+					<section>
+						<h3>A Cross Product Formula</h3>
+
+						<div class="fragment">
+							\[\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix}
+							\mathbf{i} &amp; \mathbf{j} &amp; \mathbf{k} \\
+							\frac{\partial X}{\partial u} &amp;  \frac{\partial Y}{\partial u} &amp; 0 \\
+							\frac{\partial X}{\partial v} &amp;  \frac{\partial Y}{\partial v} &amp; 0
+							\end{vmatrix}  \]
+						</div>
+					</section>
+
+					<section>
+						<h3>The probability of getting \(k\) heads when flipping \(n\) coins is</h3>
+
+						<div class="fragment">
+							\[P(E)   = {n \choose k} p^k (1-p)^{ n-k} \]
+						</div>
+					</section>
+
+					<section>
+						<h3>An Identity of Ramanujan</h3>
+
+						<div class="fragment">
+							\[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} =
+							1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
+							{1+\frac{e^{-8\pi}} {1+\ldots} } } } \]
+						</div>
+					</section>
+
+					<section>
+						<h3>A Rogers-Ramanujan Identity</h3>
+
+						<div class="fragment">
+							\[  1 +  \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots =
+							\prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}\]
+						</div>
+					</section>
+
+					<section>
+						<h3>Maxwell&#8217;s Equations</h3>
+
+						<div class="fragment">
+							\[  \begin{aligned}
+							\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\   \nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\
+							\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\
+							\nabla \cdot \vec{\mathbf{B}} &amp; = 0 \end{aligned}
+							\]
+						</div>
+					</section>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.min.js"></script>
+
+		<script>
+
+			Reveal.initialize({
+				history: true,
+				transition: 'linear',
+
+				math: {
+					// mathjax: 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
+					config: 'TeX-AMS_HTML-full'
+				},
+
+				dependencies: [
+					{ src: '../../lib/js/classList.js' },
+					{ src: '../../plugin/math/math.js', async: true }
+				]
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/test/examples/slide-backgrounds.html b/docs/slides/IHP14/_support/reveal.js/test/examples/slide-backgrounds.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/examples/slide-backgrounds.html
@@ -0,0 +1,122 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Slide Backgrounds</title>
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/theme/serif.css" id="theme">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+				<section data-background="#00ffff">
+					<h2>data-background: #00ffff</h2>
+				</section>
+
+				<section data-background="#bb00bb">
+					<h2>data-background: #bb00bb</h2>
+				</section>
+
+				<section>
+					<section data-background="#ff0000">
+						<h2>data-background: #ff0000</h2>
+					</section>
+					<section data-background="rgba(0, 0, 0, 0.2)">
+						<h2>data-background: rgba(0, 0, 0, 0.2)</h2>
+					</section>
+					<section data-background="salmon">
+						<h2>data-background: salmon</h2>
+					</section>
+				</section>
+
+				<section data-background="rgba(0, 100, 100, 0.2)">
+					<section>
+						<h2>Background applied to stack</h2>
+					</section>
+					<section>
+						<h2>Background applied to stack</h2>
+					</section>
+					<section data-background="rgba(100, 0, 0, 0.2)">
+						<h2>Background applied to slide inside of stack</h2>
+					</section>
+				</section>
+
+				<section data-background-transition="slide" data-background="assets/image1.png" style="background: rgba(255,255,255,0.9)">
+					<h2>Background image</h2>
+				</section>
+
+				<section>
+					<section data-background-transition="slide" data-background="assets/image1.png" style="background: rgba(255,255,255,0.9)">
+						<h2>Background image</h2>
+					</section>
+					<section data-background-transition="slide" data-background="assets/image1.png" style="background: rgba(255,255,255,0.9)">
+						<h2>Background image</h2>
+					</section>
+				</section>
+
+				<section data-background="assets/image2.png" data-background-size="100px" data-background-repeat="repeat" data-background-color="#111" style="background: rgba(255,255,255,0.9)">
+					<h2>Background image</h2>
+					<pre>data-background-size="100px" data-background-repeat="repeat" data-background-color="#111"</pre>
+				</section>
+
+				<section data-background="#888888">
+					<h2>Same background twice (1/2)</h2>
+				</section>
+				<section data-background="#888888">
+					<h2>Same background twice (2/2)</h2>
+				</section>
+
+				<section>
+					<section data-background="#417203">
+						<h2>Same background twice vertical (1/2)</h2>
+					</section>
+					<section data-background="#417203">
+						<h2>Same background twice vertical (2/2)</h2>
+					</section>
+				</section>
+
+				<section data-background="#934f4d">
+					<h2>Same background from horizontal to vertical (1/3)</h2>
+				</section>
+				<section>
+					<section data-background="#934f4d">
+						<h2>Same background from horizontal to vertical (2/3)</h2>
+					</section>
+					<section data-background="#934f4d">
+						<h2>Same background from horizontal to vertical (3/3)</h2>
+					</section>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.min.js"></script>
+
+		<script>
+
+			// Full list of configuration options available here:
+			// https://github.com/hakimel/reveal.js#configuration
+			Reveal.initialize({
+				center: true,
+				// rtl: true,
+
+				transition: 'linear',
+				// transitionSpeed: 'slow',
+				// backgroundTransition: 'slide'
+			});
+
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/test/qunit-1.12.0.css b/docs/slides/IHP14/_support/reveal.js/test/qunit-1.12.0.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/qunit-1.12.0.css
@@ -0,0 +1,244 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+	margin: 0;
+	padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+	padding: 0.5em 0 0.5em 1em;
+
+	color: #8699a4;
+	background-color: #0d3349;
+
+	font-size: 1.5em;
+	line-height: 1em;
+	font-weight: normal;
+
+	border-radius: 5px 5px 0 0;
+	-moz-border-radius: 5px 5px 0 0;
+	-webkit-border-top-right-radius: 5px;
+	-webkit-border-top-left-radius: 5px;
+}
+
+#qunit-header a {
+	text-decoration: none;
+	color: #c2ccd1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+	color: #fff;
+}
+
+#qunit-testrunner-toolbar label {
+	display: inline-block;
+	padding: 0 .5em 0 .1em;
+}
+
+#qunit-banner {
+	height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+	padding: 0.5em 0 0.5em 2em;
+	color: #5E740B;
+	background-color: #eee;
+	overflow: hidden;
+}
+
+#qunit-userAgent {
+	padding: 0.5em 0 0.5em 2.5em;
+	background-color: #2b81af;
+	color: #fff;
+	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+#qunit-modulefilter-container {
+	float: right;
+}
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+	list-style-position: inside;
+}
+
+#qunit-tests li {
+	padding: 0.4em 0.5em 0.4em 2.5em;
+	border-bottom: 1px solid #fff;
+	list-style-position: inside;
+}
+
+#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
+	display: none;
+}
+
+#qunit-tests li strong {
+	cursor: pointer;
+}
+
+#qunit-tests li a {
+	padding: 0.5em;
+	color: #c2ccd1;
+	text-decoration: none;
+}
+#qunit-tests li a:hover,
+#qunit-tests li a:focus {
+	color: #000;
+}
+
+#qunit-tests li .runtime {
+	float: right;
+	font-size: smaller;
+}
+
+.qunit-assert-list {
+	margin-top: 0.5em;
+	padding: 0.5em;
+
+	background-color: #fff;
+
+	border-radius: 5px;
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+}
+
+.qunit-collapsed {
+	display: none;
+}
+
+#qunit-tests table {
+	border-collapse: collapse;
+	margin-top: .2em;
+}
+
+#qunit-tests th {
+	text-align: right;
+	vertical-align: top;
+	padding: 0 .5em 0 0;
+}
+
+#qunit-tests td {
+	vertical-align: top;
+}
+
+#qunit-tests pre {
+	margin: 0;
+	white-space: pre-wrap;
+	word-wrap: break-word;
+}
+
+#qunit-tests del {
+	background-color: #e0f2be;
+	color: #374e0c;
+	text-decoration: none;
+}
+
+#qunit-tests ins {
+	background-color: #ffcaca;
+	color: #500;
+	text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts                       { color: black; }
+#qunit-tests b.passed                       { color: #5E740B; }
+#qunit-tests b.failed                       { color: #710909; }
+
+#qunit-tests li li {
+	padding: 5px;
+	background-color: #fff;
+	border-bottom: none;
+	list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+	color: #3c510c;
+	background-color: #fff;
+	border-left: 10px solid #C6E746;
+}
+
+#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name               { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected           { color: #999999; }
+
+#qunit-banner.qunit-pass                    { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+	color: #710909;
+	background-color: #fff;
+	border-left: 10px solid #EE5757;
+	white-space: pre;
+}
+
+#qunit-tests > li:last-child {
+	border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-webkit-border-bottom-right-radius: 5px;
+	-webkit-border-bottom-left-radius: 5px;
+}
+
+#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name             { color: #000000; }
+
+#qunit-tests .fail .test-actual             { color: #EE5757; }
+#qunit-tests .fail .test-expected           { color: green;   }
+
+#qunit-banner.qunit-fail                    { background-color: #EE5757; }
+
+
+/** Result */
+
+#qunit-testresult {
+	padding: 0.5em 0.5em 0.5em 2.5em;
+
+	color: #2b81af;
+	background-color: #D2E0E6;
+
+	border-bottom: 1px solid white;
+}
+#qunit-testresult .module-name {
+	font-weight: bold;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+	position: absolute;
+	top: -10000px;
+	left: -10000px;
+	width: 1000px;
+	height: 1000px;
+}
diff --git a/docs/slides/IHP14/_support/reveal.js/test/qunit-1.12.0.js b/docs/slides/IHP14/_support/reveal.js/test/qunit-1.12.0.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/qunit-1.12.0.js
@@ -0,0 +1,2212 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * https://jquery.org/license/
+ */
+
+(function( window ) {
+
+var QUnit,
+	assert,
+	config,
+	onErrorFnPrev,
+	testId = 0,
+	fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	// Keep a local reference to Date (GH-283)
+	Date = window.Date,
+	setTimeout = window.setTimeout,
+	defined = {
+		setTimeout: typeof window.setTimeout !== "undefined",
+		sessionStorage: (function() {
+			var x = "qunit-test-string";
+			try {
+				sessionStorage.setItem( x, x );
+				sessionStorage.removeItem( x );
+				return true;
+			} catch( e ) {
+				return false;
+			}
+		}())
+	},
+	/**
+	 * Provides a normalized error string, correcting an issue
+	 * with IE 7 (and prior) where Error.prototype.toString is
+	 * not properly implemented
+	 *
+	 * Based on http://es5.github.com/#x15.11.4.4
+	 *
+	 * @param {String|Error} error
+	 * @return {String} error message
+	 */
+	errorString = function( error ) {
+		var name, message,
+			errorString = error.toString();
+		if ( errorString.substring( 0, 7 ) === "[object" ) {
+			name = error.name ? error.name.toString() : "Error";
+			message = error.message ? error.message.toString() : "";
+			if ( name && message ) {
+				return name + ": " + message;
+			} else if ( name ) {
+				return name;
+			} else if ( message ) {
+				return message;
+			} else {
+				return "Error";
+			}
+		} else {
+			return errorString;
+		}
+	},
+	/**
+	 * Makes a clone of an object using only Array or Object as base,
+	 * and copies over the own enumerable properties.
+	 *
+	 * @param {Object} obj
+	 * @return {Object} New object with only the own properties (recursively).
+	 */
+	objectValues = function( obj ) {
+		// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
+		/*jshint newcap: false */
+		var key, val,
+			vals = QUnit.is( "array", obj ) ? [] : {};
+		for ( key in obj ) {
+			if ( hasOwn.call( obj, key ) ) {
+				val = obj[key];
+				vals[key] = val === Object(val) ? objectValues(val) : val;
+			}
+		}
+		return vals;
+	};
+
+function Test( settings ) {
+	extend( this, settings );
+	this.assertions = [];
+	this.testNumber = ++Test.count;
+}
+
+Test.count = 0;
+
+Test.prototype = {
+	init: function() {
+		var a, b, li,
+			tests = id( "qunit-tests" );
+
+		if ( tests ) {
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml;
+
+			// `a` initialized at top of scope
+			a = document.createElement( "a" );
+			a.innerHTML = "Rerun";
+			a.href = QUnit.url({ testNumber: this.testNumber });
+
+			li = document.createElement( "li" );
+			li.appendChild( b );
+			li.appendChild( a );
+			li.className = "running";
+			li.id = this.id = "qunit-test-output" + testId++;
+
+			tests.appendChild( li );
+		}
+	},
+	setup: function() {
+		if (
+			// Emit moduleStart when we're switching from one module to another
+			this.module !== config.previousModule ||
+				// They could be equal (both undefined) but if the previousModule property doesn't
+				// yet exist it means this is the first test in a suite that isn't wrapped in a
+				// module, in which case we'll just emit a moduleStart event for 'undefined'.
+				// Without this, reporters can get testStart before moduleStart  which is a problem.
+				!hasOwn.call( config, "previousModule" )
+		) {
+			if ( hasOwn.call( config, "previousModule" ) ) {
+				runLoggingCallbacks( "moduleDone", QUnit, {
+					name: config.previousModule,
+					failed: config.moduleStats.bad,
+					passed: config.moduleStats.all - config.moduleStats.bad,
+					total: config.moduleStats.all
+				});
+			}
+			config.previousModule = this.module;
+			config.moduleStats = { all: 0, bad: 0 };
+			runLoggingCallbacks( "moduleStart", QUnit, {
+				name: this.module
+			});
+		}
+
+		config.current = this;
+
+		this.testEnvironment = extend({
+			setup: function() {},
+			teardown: function() {}
+		}, this.moduleTestEnvironment );
+
+		this.started = +new Date();
+		runLoggingCallbacks( "testStart", QUnit, {
+			name: this.testName,
+			module: this.module
+		});
+
+		/*jshint camelcase:false */
+
+
+		/**
+		 * Expose the current test environment.
+		 *
+		 * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
+		 */
+		QUnit.current_testEnvironment = this.testEnvironment;
+
+		/*jshint camelcase:true */
+
+		if ( !config.pollution ) {
+			saveGlobal();
+		}
+		if ( config.notrycatch ) {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+			return;
+		}
+		try {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+		} catch( e ) {
+			QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+		}
+	},
+	run: function() {
+		config.current = this;
+
+		var running = id( "qunit-testresult" );
+
+		if ( running ) {
+			running.innerHTML = "Running: <br/>" + this.nameHtml;
+		}
+
+		if ( this.async ) {
+			QUnit.stop();
+		}
+
+		this.callbackStarted = +new Date();
+
+		if ( config.notrycatch ) {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+			return;
+		}
+
+		try {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+		} catch( e ) {
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+
+			QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
+			// else next test will carry the responsibility
+			saveGlobal();
+
+			// Restart the tests if they're blocking
+			if ( config.blocking ) {
+				QUnit.start();
+			}
+		}
+	},
+	teardown: function() {
+		config.current = this;
+		if ( config.notrycatch ) {
+			if ( typeof this.callbackRuntime === "undefined" ) {
+				this.callbackRuntime = +new Date() - this.callbackStarted;
+			}
+			this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			return;
+		} else {
+			try {
+				this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			} catch( e ) {
+				QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+			}
+		}
+		checkPollution();
+	},
+	finish: function() {
+		config.current = this;
+		if ( config.requireExpects && this.expected === null ) {
+			QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
+		} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
+			QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
+		} else if ( this.expected === null && !this.assertions.length ) {
+			QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
+		}
+
+		var i, assertion, a, b, time, li, ol,
+			test = this,
+			good = 0,
+			bad = 0,
+			tests = id( "qunit-tests" );
+
+		this.runtime = +new Date() - this.started;
+		config.stats.all += this.assertions.length;
+		config.moduleStats.all += this.assertions.length;
+
+		if ( tests ) {
+			ol = document.createElement( "ol" );
+			ol.className = "qunit-assert-list";
+
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				assertion = this.assertions[i];
+
+				li = document.createElement( "li" );
+				li.className = assertion.result ? "pass" : "fail";
+				li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
+				ol.appendChild( li );
+
+				if ( assertion.result ) {
+					good++;
+				} else {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+
+			// store result when possible
+			if ( QUnit.config.reorder && defined.sessionStorage ) {
+				if ( bad ) {
+					sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
+				} else {
+					sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
+				}
+			}
+
+			if ( bad === 0 ) {
+				addClass( ol, "qunit-collapsed" );
+			}
+
+			// `b` initialized at top of scope
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+
+			addEvent(b, "click", function() {
+				var next = b.parentNode.lastChild,
+					collapsed = hasClass( next, "qunit-collapsed" );
+				( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
+			});
+
+			addEvent(b, "dblclick", function( e ) {
+				var target = e && e.target ? e.target : window.event.srcElement;
+				if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
+					target = target.parentNode;
+				}
+				if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
+					window.location = QUnit.url({ testNumber: test.testNumber });
+				}
+			});
+
+			// `time` initialized at top of scope
+			time = document.createElement( "span" );
+			time.className = "runtime";
+			time.innerHTML = this.runtime + " ms";
+
+			// `li` initialized at top of scope
+			li = id( this.id );
+			li.className = bad ? "fail" : "pass";
+			li.removeChild( li.firstChild );
+			a = li.firstChild;
+			li.appendChild( b );
+			li.appendChild( a );
+			li.appendChild( time );
+			li.appendChild( ol );
+
+		} else {
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				if ( !this.assertions[i].result ) {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+		}
+
+		runLoggingCallbacks( "testDone", QUnit, {
+			name: this.testName,
+			module: this.module,
+			failed: bad,
+			passed: this.assertions.length - bad,
+			total: this.assertions.length,
+			duration: this.runtime
+		});
+
+		QUnit.reset();
+
+		config.current = undefined;
+	},
+
+	queue: function() {
+		var bad,
+			test = this;
+
+		synchronize(function() {
+			test.init();
+		});
+		function run() {
+			// each of these can by async
+			synchronize(function() {
+				test.setup();
+			});
+			synchronize(function() {
+				test.run();
+			});
+			synchronize(function() {
+				test.teardown();
+			});
+			synchronize(function() {
+				test.finish();
+			});
+		}
+
+		// `bad` initialized at top of scope
+		// defer when previous test run passed, if storage is available
+		bad = QUnit.config.reorder && defined.sessionStorage &&
+						+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
+
+		if ( bad ) {
+			run();
+		} else {
+			synchronize( run, true );
+		}
+	}
+};
+
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+QUnit = {
+
+	// call on start of module test to prepend name to all tests
+	module: function( name, testEnvironment ) {
+		config.currentModule = name;
+		config.currentModuleTestEnvironment = testEnvironment;
+		config.modules[name] = true;
+	},
+
+	asyncTest: function( testName, expected, callback ) {
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		QUnit.test( testName, expected, callback, true );
+	},
+
+	test: function( testName, expected, callback, async ) {
+		var test,
+			nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
+
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		if ( config.currentModule ) {
+			nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
+		}
+
+		test = new Test({
+			nameHtml: nameHtml,
+			testName: testName,
+			expected: expected,
+			async: async,
+			callback: callback,
+			module: config.currentModule,
+			moduleTestEnvironment: config.currentModuleTestEnvironment,
+			stack: sourceFromStacktrace( 2 )
+		});
+
+		if ( !validTest( test ) ) {
+			return;
+		}
+
+		test.queue();
+	},
+
+	// Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
+	expect: function( asserts ) {
+		if (arguments.length === 1) {
+			config.current.expected = asserts;
+		} else {
+			return config.current.expected;
+		}
+	},
+
+	start: function( count ) {
+		// QUnit hasn't been initialized yet.
+		// Note: RequireJS (et al) may delay onLoad
+		if ( config.semaphore === undefined ) {
+			QUnit.begin(function() {
+				// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+				setTimeout(function() {
+					QUnit.start( count );
+				});
+			});
+			return;
+		}
+
+		config.semaphore -= count || 1;
+		// don't start until equal number of stop-calls
+		if ( config.semaphore > 0 ) {
+			return;
+		}
+		// ignore if start is called more often then stop
+		if ( config.semaphore < 0 ) {
+			config.semaphore = 0;
+			QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
+			return;
+		}
+		// A slight delay, to avoid any current callbacks
+		if ( defined.setTimeout ) {
+			setTimeout(function() {
+				if ( config.semaphore > 0 ) {
+					return;
+				}
+				if ( config.timeout ) {
+					clearTimeout( config.timeout );
+				}
+
+				config.blocking = false;
+				process( true );
+			}, 13);
+		} else {
+			config.blocking = false;
+			process( true );
+		}
+	},
+
+	stop: function( count ) {
+		config.semaphore += count || 1;
+		config.blocking = true;
+
+		if ( config.testTimeout && defined.setTimeout ) {
+			clearTimeout( config.timeout );
+			config.timeout = setTimeout(function() {
+				QUnit.ok( false, "Test timed out" );
+				config.semaphore = 1;
+				QUnit.start();
+			}, config.testTimeout );
+		}
+	}
+};
+
+// `assert` initialized at top of scope
+// Assert helpers
+// All of these must either call QUnit.push() or manually do:
+// - runLoggingCallbacks( "log", .. );
+// - config.current.assertions.push({ .. });
+// We attach it to the QUnit object *after* we expose the public API,
+// otherwise `assert` will become a global variable in browsers (#341).
+assert = {
+	/**
+	 * Asserts rough true-ish result.
+	 * @name ok
+	 * @function
+	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+	 */
+	ok: function( result, msg ) {
+		if ( !config.current ) {
+			throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+		result = !!result;
+		msg = msg || (result ? "okay" : "failed" );
+
+		var source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: msg
+			};
+
+		msg = "<span class='test-message'>" + escapeText( msg ) + "</span>";
+
+		if ( !result ) {
+			source = sourceFromStacktrace( 2 );
+			if ( source ) {
+				details.source = source;
+				msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
+			}
+		}
+		runLoggingCallbacks( "log", QUnit, details );
+		config.current.assertions.push({
+			result: result,
+			message: msg
+		});
+	},
+
+	/**
+	 * Assert that the first two arguments are equal, with an optional message.
+	 * Prints out both actual and expected values.
+	 * @name equal
+	 * @function
+	 * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
+	 */
+	equal: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected == actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notEqual
+	 * @function
+	 */
+	notEqual: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected != actual, actual, expected, message );
+	},
+
+	/**
+	 * @name propEqual
+	 * @function
+	 */
+	propEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notPropEqual
+	 * @function
+	 */
+	notPropEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name deepEqual
+	 * @function
+	 */
+	deepEqual: function( actual, expected, message ) {
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notDeepEqual
+	 * @function
+	 */
+	notDeepEqual: function( actual, expected, message ) {
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name strictEqual
+	 * @function
+	 */
+	strictEqual: function( actual, expected, message ) {
+		QUnit.push( expected === actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notStrictEqual
+	 * @function
+	 */
+	notStrictEqual: function( actual, expected, message ) {
+		QUnit.push( expected !== actual, actual, expected, message );
+	},
+
+	"throws": function( block, expected, message ) {
+		var actual,
+			expectedOutput = expected,
+			ok = false;
+
+		// 'expected' is optional
+		if ( typeof expected === "string" ) {
+			message = expected;
+			expected = null;
+		}
+
+		config.current.ignoreGlobalErrors = true;
+		try {
+			block.call( config.current.testEnvironment );
+		} catch (e) {
+			actual = e;
+		}
+		config.current.ignoreGlobalErrors = false;
+
+		if ( actual ) {
+			// we don't want to validate thrown error
+			if ( !expected ) {
+				ok = true;
+				expectedOutput = null;
+			// expected is a regexp
+			} else if ( QUnit.objectType( expected ) === "regexp" ) {
+				ok = expected.test( errorString( actual ) );
+			// expected is a constructor
+			} else if ( actual instanceof expected ) {
+				ok = true;
+			// expected is a validation function which returns true is validation passed
+			} else if ( expected.call( {}, actual ) === true ) {
+				expectedOutput = null;
+				ok = true;
+			}
+
+			QUnit.push( ok, actual, expectedOutput, message );
+		} else {
+			QUnit.pushFailure( message, null, "No exception was thrown." );
+		}
+	}
+};
+
+/**
+ * @deprecated since 1.8.0
+ * Kept assertion helpers in root for backwards compatibility.
+ */
+extend( QUnit, assert );
+
+/**
+ * @deprecated since 1.9.0
+ * Kept root "raises()" for backwards compatibility.
+ * (Note that we don't introduce assert.raises).
+ */
+QUnit.raises = assert[ "throws" ];
+
+/**
+ * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
+ * Kept to avoid TypeErrors for undefined methods.
+ */
+QUnit.equals = function() {
+	QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
+};
+QUnit.same = function() {
+	QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
+};
+
+// We want access to the constructor's prototype
+(function() {
+	function F() {}
+	F.prototype = QUnit;
+	QUnit = new F();
+	// Make F QUnit's constructor so that we can add to the prototype later
+	QUnit.constructor = F;
+}());
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+	// The queue of tests to run
+	queue: [],
+
+	// block until document ready
+	blocking: true,
+
+	// when enabled, show only failing tests
+	// gets persisted through sessionStorage and can be changed in UI via checkbox
+	hidepassed: false,
+
+	// by default, run previously failed tests first
+	// very useful in combination with "Hide passed tests" checked
+	reorder: true,
+
+	// by default, modify document.title when suite is done
+	altertitle: true,
+
+	// when enabled, all tests must call expect()
+	requireExpects: false,
+
+	// add checkboxes that are persisted in the query-string
+	// when enabled, the id is set to `true` as a `QUnit.config` property
+	urlConfig: [
+		{
+			id: "noglobals",
+			label: "Check for Globals",
+			tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
+		},
+		{
+			id: "notrycatch",
+			label: "No try-catch",
+			tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
+		}
+	],
+
+	// Set of all modules.
+	modules: {},
+
+	// logging callback queues
+	begin: [],
+	done: [],
+	log: [],
+	testStart: [],
+	testDone: [],
+	moduleStart: [],
+	moduleDone: []
+};
+
+// Export global variables, unless an 'exports' object exists,
+// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
+if ( typeof exports === "undefined" ) {
+	extend( window, QUnit.constructor.prototype );
+
+	// Expose QUnit object
+	window.QUnit = QUnit;
+}
+
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+	var i,
+		location = window.location || { search: "", protocol: "file:" },
+		params = location.search.slice( 1 ).split( "&" ),
+		length = params.length,
+		urlParams = {},
+		current;
+
+	if ( params[ 0 ] ) {
+		for ( i = 0; i < length; i++ ) {
+			current = params[ i ].split( "=" );
+			current[ 0 ] = decodeURIComponent( current[ 0 ] );
+			// allow just a key to turn on a flag, e.g., test.html?noglobals
+			current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
+			urlParams[ current[ 0 ] ] = current[ 1 ];
+		}
+	}
+
+	QUnit.urlParams = urlParams;
+
+	// String search anywhere in moduleName+testName
+	config.filter = urlParams.filter;
+
+	// Exact match of the module name
+	config.module = urlParams.module;
+
+	config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
+
+	// Figure out if we're running the tests from a server or not
+	QUnit.isLocal = location.protocol === "file:";
+}());
+
+// Extend QUnit object,
+// these after set here because they should not be exposed as global functions
+extend( QUnit, {
+	assert: assert,
+
+	config: config,
+
+	// Initialize the configuration options
+	init: function() {
+		extend( config, {
+			stats: { all: 0, bad: 0 },
+			moduleStats: { all: 0, bad: 0 },
+			started: +new Date(),
+			updateRate: 1000,
+			blocking: false,
+			autostart: true,
+			autorun: false,
+			filter: "",
+			queue: [],
+			semaphore: 1
+		});
+
+		var tests, banner, result,
+			qunit = id( "qunit" );
+
+		if ( qunit ) {
+			qunit.innerHTML =
+				"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+				"<h2 id='qunit-banner'></h2>" +
+				"<div id='qunit-testrunner-toolbar'></div>" +
+				"<h2 id='qunit-userAgent'></h2>" +
+				"<ol id='qunit-tests'></ol>";
+		}
+
+		tests = id( "qunit-tests" );
+		banner = id( "qunit-banner" );
+		result = id( "qunit-testresult" );
+
+		if ( tests ) {
+			tests.innerHTML = "";
+		}
+
+		if ( banner ) {
+			banner.className = "";
+		}
+
+		if ( result ) {
+			result.parentNode.removeChild( result );
+		}
+
+		if ( tests ) {
+			result = document.createElement( "p" );
+			result.id = "qunit-testresult";
+			result.className = "result";
+			tests.parentNode.insertBefore( result, tests );
+			result.innerHTML = "Running...<br/>&nbsp;";
+		}
+	},
+
+	// Resets the test setup. Useful for tests that modify the DOM.
+	/*
+	DEPRECATED: Use multiple tests instead of resetting inside a test.
+	Use testStart or testDone for custom cleanup.
+	This method will throw an error in 2.0, and will be removed in 2.1
+	*/
+	reset: function() {
+		var fixture = id( "qunit-fixture" );
+		if ( fixture ) {
+			fixture.innerHTML = config.fixture;
+		}
+	},
+
+	// Trigger an event on an element.
+	// @example triggerEvent( document.body, "click" );
+	triggerEvent: function( elem, type, event ) {
+		if ( document.createEvent ) {
+			event = document.createEvent( "MouseEvents" );
+			event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+				0, 0, 0, 0, 0, false, false, false, false, 0, null);
+
+			elem.dispatchEvent( event );
+		} else if ( elem.fireEvent ) {
+			elem.fireEvent( "on" + type );
+		}
+	},
+
+	// Safe object type checking
+	is: function( type, obj ) {
+		return QUnit.objectType( obj ) === type;
+	},
+
+	objectType: function( obj ) {
+		if ( typeof obj === "undefined" ) {
+				return "undefined";
+		// consider: typeof null === object
+		}
+		if ( obj === null ) {
+				return "null";
+		}
+
+		var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+			type = match && match[1] || "";
+
+		switch ( type ) {
+			case "Number":
+				if ( isNaN(obj) ) {
+					return "nan";
+				}
+				return "number";
+			case "String":
+			case "Boolean":
+			case "Array":
+			case "Date":
+			case "RegExp":
+			case "Function":
+				return type.toLowerCase();
+		}
+		if ( typeof obj === "object" ) {
+			return "object";
+		}
+		return undefined;
+	},
+
+	push: function( result, actual, expected, message ) {
+		if ( !config.current ) {
+			throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
+		}
+
+		var output, source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: message,
+				actual: actual,
+				expected: expected
+			};
+
+		message = escapeText( message ) || ( result ? "okay" : "failed" );
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		if ( !result ) {
+			expected = escapeText( QUnit.jsDump.parse(expected) );
+			actual = escapeText( QUnit.jsDump.parse(actual) );
+			output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
+
+			if ( actual !== expected ) {
+				output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
+				output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
+			}
+
+			source = sourceFromStacktrace();
+
+			if ( source ) {
+				details.source = source;
+				output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+			}
+
+			output += "</table>";
+		}
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: !!result,
+			message: output
+		});
+	},
+
+	pushFailure: function( message, source, actual ) {
+		if ( !config.current ) {
+			throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+
+		var output,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: false,
+				message: message
+			};
+
+		message = escapeText( message ) || "error";
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		output += "<table>";
+
+		if ( actual ) {
+			output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
+		}
+
+		if ( source ) {
+			details.source = source;
+			output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+		}
+
+		output += "</table>";
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: false,
+			message: output
+		});
+	},
+
+	url: function( params ) {
+		params = extend( extend( {}, QUnit.urlParams ), params );
+		var key,
+			querystring = "?";
+
+		for ( key in params ) {
+			if ( hasOwn.call( params, key ) ) {
+				querystring += encodeURIComponent( key ) + "=" +
+					encodeURIComponent( params[ key ] ) + "&";
+			}
+		}
+		return window.location.protocol + "//" + window.location.host +
+			window.location.pathname + querystring.slice( 0, -1 );
+	},
+
+	extend: extend,
+	id: id,
+	addEvent: addEvent,
+	addClass: addClass,
+	hasClass: hasClass,
+	removeClass: removeClass
+	// load, equiv, jsDump, diff: Attached later
+});
+
+/**
+ * @deprecated: Created for backwards compatibility with test runner that set the hook function
+ * into QUnit.{hook}, instead of invoking it and passing the hook function.
+ * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
+ * Doing this allows us to tell if the following methods have been overwritten on the actual
+ * QUnit object.
+ */
+extend( QUnit.constructor.prototype, {
+
+	// Logging callbacks; all receive a single argument with the listed properties
+	// run test/logs.html for any related changes
+	begin: registerLoggingCallback( "begin" ),
+
+	// done: { failed, passed, total, runtime }
+	done: registerLoggingCallback( "done" ),
+
+	// log: { result, actual, expected, message }
+	log: registerLoggingCallback( "log" ),
+
+	// testStart: { name }
+	testStart: registerLoggingCallback( "testStart" ),
+
+	// testDone: { name, failed, passed, total, duration }
+	testDone: registerLoggingCallback( "testDone" ),
+
+	// moduleStart: { name }
+	moduleStart: registerLoggingCallback( "moduleStart" ),
+
+	// moduleDone: { name, failed, passed, total }
+	moduleDone: registerLoggingCallback( "moduleDone" )
+});
+
+if ( typeof document === "undefined" || document.readyState === "complete" ) {
+	config.autorun = true;
+}
+
+QUnit.load = function() {
+	runLoggingCallbacks( "begin", QUnit, {} );
+
+	// Initialize the config, saving the execution queue
+	var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
+		urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
+		numModules = 0,
+		moduleNames = [],
+		moduleFilterHtml = "",
+		urlConfigHtml = "",
+		oldconfig = extend( {}, config );
+
+	QUnit.init();
+	extend(config, oldconfig);
+
+	config.blocking = false;
+
+	len = config.urlConfig.length;
+
+	for ( i = 0; i < len; i++ ) {
+		val = config.urlConfig[i];
+		if ( typeof val === "string" ) {
+			val = {
+				id: val,
+				label: val,
+				tooltip: "[no tooltip available]"
+			};
+		}
+		config[ val.id ] = QUnit.urlParams[ val.id ];
+		urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
+			"' name='" + escapeText( val.id ) +
+			"' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
+			" title='" + escapeText( val.tooltip ) +
+			"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
+			"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
+	}
+	for ( i in config.modules ) {
+		if ( config.modules.hasOwnProperty( i ) ) {
+			moduleNames.push(i);
+		}
+	}
+	numModules = moduleNames.length;
+	moduleNames.sort( function( a, b ) {
+		return a.localeCompare( b );
+	});
+	moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+		( config.module === undefined  ? "selected='selected'" : "" ) +
+		">< All Modules ></option>";
+
+
+	for ( i = 0; i < numModules; i++) {
+			moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " +
+				( config.module === moduleNames[i] ? "selected='selected'" : "" ) +
+				">" + escapeText(moduleNames[i]) + "</option>";
+	}
+	moduleFilterHtml += "</select>";
+
+	// `userAgent` initialized at top of scope
+	userAgent = id( "qunit-userAgent" );
+	if ( userAgent ) {
+		userAgent.innerHTML = navigator.userAgent;
+	}
+
+	// `banner` initialized at top of scope
+	banner = id( "qunit-header" );
+	if ( banner ) {
+		banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
+	}
+
+	// `toolbar` initialized at top of scope
+	toolbar = id( "qunit-testrunner-toolbar" );
+	if ( toolbar ) {
+		// `filter` initialized at top of scope
+		filter = document.createElement( "input" );
+		filter.type = "checkbox";
+		filter.id = "qunit-filter-pass";
+
+		addEvent( filter, "click", function() {
+			var tmp,
+				ol = document.getElementById( "qunit-tests" );
+
+			if ( filter.checked ) {
+				ol.className = ol.className + " hidepass";
+			} else {
+				tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
+				ol.className = tmp.replace( / hidepass /, " " );
+			}
+			if ( defined.sessionStorage ) {
+				if (filter.checked) {
+					sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+				} else {
+					sessionStorage.removeItem( "qunit-filter-passed-tests" );
+				}
+			}
+		});
+
+		if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
+			filter.checked = true;
+			// `ol` initialized at top of scope
+			ol = document.getElementById( "qunit-tests" );
+			ol.className = ol.className + " hidepass";
+		}
+		toolbar.appendChild( filter );
+
+		// `label` initialized at top of scope
+		label = document.createElement( "label" );
+		label.setAttribute( "for", "qunit-filter-pass" );
+		label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
+		label.innerHTML = "Hide passed tests";
+		toolbar.appendChild( label );
+
+		urlConfigCheckboxesContainer = document.createElement("span");
+		urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
+		urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
+		// For oldIE support:
+		// * Add handlers to the individual elements instead of the container
+		// * Use "click" instead of "change"
+		// * Fallback from event.target to event.srcElement
+		addEvents( urlConfigCheckboxes, "click", function( event ) {
+			var params = {},
+				target = event.target || event.srcElement;
+			params[ target.name ] = target.checked ? true : undefined;
+			window.location = QUnit.url( params );
+		});
+		toolbar.appendChild( urlConfigCheckboxesContainer );
+
+		if (numModules > 1) {
+			moduleFilter = document.createElement( "span" );
+			moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+			moduleFilter.innerHTML = moduleFilterHtml;
+			addEvent( moduleFilter.lastChild, "change", function() {
+				var selectBox = moduleFilter.getElementsByTagName("select")[0],
+					selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+				window.location = QUnit.url({
+					module: ( selectedModule === "" ) ? undefined : selectedModule,
+					// Remove any existing filters
+					filter: undefined,
+					testNumber: undefined
+				});
+			});
+			toolbar.appendChild(moduleFilter);
+		}
+	}
+
+	// `main` initialized at top of scope
+	main = id( "qunit-fixture" );
+	if ( main ) {
+		config.fixture = main.innerHTML;
+	}
+
+	if ( config.autostart ) {
+		QUnit.start();
+	}
+};
+
+addEvent( window, "load", QUnit.load );
+
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will suppress the default browser handler,
+// returning false will let it run.
+window.onerror = function ( error, filePath, linerNr ) {
+	var ret = false;
+	if ( onErrorFnPrev ) {
+		ret = onErrorFnPrev( error, filePath, linerNr );
+	}
+
+	// Treat return value as window.onerror itself does,
+	// Only do our handling if not suppressed.
+	if ( ret !== true ) {
+		if ( QUnit.config.current ) {
+			if ( QUnit.config.current.ignoreGlobalErrors ) {
+				return true;
+			}
+			QUnit.pushFailure( error, filePath + ":" + linerNr );
+		} else {
+			QUnit.test( "global failure", extend( function() {
+				QUnit.pushFailure( error, filePath + ":" + linerNr );
+			}, { validTest: validTest } ) );
+		}
+		return false;
+	}
+
+	return ret;
+};
+
+function done() {
+	config.autorun = true;
+
+	// Log the last module results
+	if ( config.currentModule ) {
+		runLoggingCallbacks( "moduleDone", QUnit, {
+			name: config.currentModule,
+			failed: config.moduleStats.bad,
+			passed: config.moduleStats.all - config.moduleStats.bad,
+			total: config.moduleStats.all
+		});
+	}
+	delete config.previousModule;
+
+	var i, key,
+		banner = id( "qunit-banner" ),
+		tests = id( "qunit-tests" ),
+		runtime = +new Date() - config.started,
+		passed = config.stats.all - config.stats.bad,
+		html = [
+			"Tests completed in ",
+			runtime,
+			" milliseconds.<br/>",
+			"<span class='passed'>",
+			passed,
+			"</span> assertions of <span class='total'>",
+			config.stats.all,
+			"</span> passed, <span class='failed'>",
+			config.stats.bad,
+			"</span> failed."
+		].join( "" );
+
+	if ( banner ) {
+		banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
+	}
+
+	if ( tests ) {
+		id( "qunit-testresult" ).innerHTML = html;
+	}
+
+	if ( config.altertitle && typeof document !== "undefined" && document.title ) {
+		// show ✖ for good, ✔ for bad suite result in title
+		// use escape sequences in case file gets loaded with non-utf-8-charset
+		document.title = [
+			( config.stats.bad ? "\u2716" : "\u2714" ),
+			document.title.replace( /^[\u2714\u2716] /i, "" )
+		].join( " " );
+	}
+
+	// clear own sessionStorage items if all tests passed
+	if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
+		// `key` & `i` initialized at top of scope
+		for ( i = 0; i < sessionStorage.length; i++ ) {
+			key = sessionStorage.key( i++ );
+			if ( key.indexOf( "qunit-test-" ) === 0 ) {
+				sessionStorage.removeItem( key );
+			}
+		}
+	}
+
+	// scroll back to top to show results
+	if ( window.scrollTo ) {
+		window.scrollTo(0, 0);
+	}
+
+	runLoggingCallbacks( "done", QUnit, {
+		failed: config.stats.bad,
+		passed: passed,
+		total: config.stats.all,
+		runtime: runtime
+	});
+}
+
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+	var include,
+		filter = config.filter && config.filter.toLowerCase(),
+		module = config.module && config.module.toLowerCase(),
+		fullName = (test.module + ": " + test.testName).toLowerCase();
+
+	// Internally-generated tests are always valid
+	if ( test.callback && test.callback.validTest === validTest ) {
+		delete test.callback.validTest;
+		return true;
+	}
+
+	if ( config.testNumber ) {
+		return test.testNumber === config.testNumber;
+	}
+
+	if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
+		return false;
+	}
+
+	if ( !filter ) {
+		return true;
+	}
+
+	include = filter.charAt( 0 ) !== "!";
+	if ( !include ) {
+		filter = filter.slice( 1 );
+	}
+
+	// If the filter matches, we need to honour include
+	if ( fullName.indexOf( filter ) !== -1 ) {
+		return include;
+	}
+
+	// Otherwise, do the opposite
+	return !include;
+}
+
+// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
+// Later Safari and IE10 are supposed to support error.stack as well
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+	offset = offset === undefined ? 3 : offset;
+
+	var stack, include, i;
+
+	if ( e.stacktrace ) {
+		// Opera
+		return e.stacktrace.split( "\n" )[ offset + 3 ];
+	} else if ( e.stack ) {
+		// Firefox, Chrome
+		stack = e.stack.split( "\n" );
+		if (/^error$/i.test( stack[0] ) ) {
+			stack.shift();
+		}
+		if ( fileName ) {
+			include = [];
+			for ( i = offset; i < stack.length; i++ ) {
+				if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+					break;
+				}
+				include.push( stack[ i ] );
+			}
+			if ( include.length ) {
+				return include.join( "\n" );
+			}
+		}
+		return stack[ offset ];
+	} else if ( e.sourceURL ) {
+		// Safari, PhantomJS
+		// hopefully one day Safari provides actual stacktraces
+		// exclude useless self-reference for generated Error objects
+		if ( /qunit.js$/.test( e.sourceURL ) ) {
+			return;
+		}
+		// for actual exceptions, this is useful
+		return e.sourceURL + ":" + e.line;
+	}
+}
+function sourceFromStacktrace( offset ) {
+	try {
+		throw new Error();
+	} catch ( e ) {
+		return extractStacktrace( e, offset );
+	}
+}
+
+/**
+ * Escape text for attribute or text content.
+ */
+function escapeText( s ) {
+	if ( !s ) {
+		return "";
+	}
+	s = s + "";
+	// Both single quotes and double quotes (for attributes)
+	return s.replace( /['"<>&]/g, function( s ) {
+		switch( s ) {
+			case "'":
+				return "&#039;";
+			case "\"":
+				return "&quot;";
+			case "<":
+				return "&lt;";
+			case ">":
+				return "&gt;";
+			case "&":
+				return "&amp;";
+		}
+	});
+}
+
+function synchronize( callback, last ) {
+	config.queue.push( callback );
+
+	if ( config.autorun && !config.blocking ) {
+		process( last );
+	}
+}
+
+function process( last ) {
+	function next() {
+		process( last );
+	}
+	var start = new Date().getTime();
+	config.depth = config.depth ? config.depth + 1 : 1;
+
+	while ( config.queue.length && !config.blocking ) {
+		if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
+			config.queue.shift()();
+		} else {
+			setTimeout( next, 13 );
+			break;
+		}
+	}
+	config.depth--;
+	if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+		done();
+	}
+}
+
+function saveGlobal() {
+	config.pollution = [];
+
+	if ( config.noglobals ) {
+		for ( var key in window ) {
+			if ( hasOwn.call( window, key ) ) {
+				// in Opera sometimes DOM element ids show up here, ignore them
+				if ( /^qunit-test-output/.test( key ) ) {
+					continue;
+				}
+				config.pollution.push( key );
+			}
+		}
+	}
+}
+
+function checkPollution() {
+	var newGlobals,
+		deletedGlobals,
+		old = config.pollution;
+
+	saveGlobal();
+
+	newGlobals = diff( config.pollution, old );
+	if ( newGlobals.length > 0 ) {
+		QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
+	}
+
+	deletedGlobals = diff( old, config.pollution );
+	if ( deletedGlobals.length > 0 ) {
+		QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
+	}
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+	var i, j,
+		result = a.slice();
+
+	for ( i = 0; i < result.length; i++ ) {
+		for ( j = 0; j < b.length; j++ ) {
+			if ( result[i] === b[j] ) {
+				result.splice( i, 1 );
+				i--;
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+function extend( a, b ) {
+	for ( var prop in b ) {
+		if ( hasOwn.call( b, prop ) ) {
+			// Avoid "Member not found" error in IE8 caused by messing with window.constructor
+			if ( !( prop === "constructor" && a === window ) ) {
+				if ( b[ prop ] === undefined ) {
+					delete a[ prop ];
+				} else {
+					a[ prop ] = b[ prop ];
+				}
+			}
+		}
+	}
+
+	return a;
+}
+
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+	// Standards-based browsers
+	if ( elem.addEventListener ) {
+		elem.addEventListener( type, fn, false );
+	// IE
+	} else {
+		elem.attachEvent( "on" + type, fn );
+	}
+}
+
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+	var i = elems.length;
+	while ( i-- ) {
+		addEvent( elems[i], type, fn );
+	}
+}
+
+function hasClass( elem, name ) {
+	return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
+}
+
+function addClass( elem, name ) {
+	if ( !hasClass( elem, name ) ) {
+		elem.className += (elem.className ? " " : "") + name;
+	}
+}
+
+function removeClass( elem, name ) {
+	var set = " " + elem.className + " ";
+	// Class name may appear multiple times
+	while ( set.indexOf(" " + name + " ") > -1 ) {
+		set = set.replace(" " + name + " " , " ");
+	}
+	// If possible, trim it for prettiness, but not necessarily
+	elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
+}
+
+function id( name ) {
+	return !!( typeof document !== "undefined" && document && document.getElementById ) &&
+		document.getElementById( name );
+}
+
+function registerLoggingCallback( key ) {
+	return function( callback ) {
+		config[key].push( callback );
+	};
+}
+
+// Supports deprecated method of completely overwriting logging callbacks
+function runLoggingCallbacks( key, scope, args ) {
+	var i, callbacks;
+	if ( QUnit.hasOwnProperty( key ) ) {
+		QUnit[ key ].call(scope, args );
+	} else {
+		callbacks = config[ key ];
+		for ( i = 0; i < callbacks.length; i++ ) {
+			callbacks[ i ].call( scope, args );
+		}
+	}
+}
+
+// Test for equality any JavaScript type.
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = (function() {
+
+	// Call the o related callback with the given arguments.
+	function bindCallbacks( o, callbacks, args ) {
+		var prop = QUnit.objectType( o );
+		if ( prop ) {
+			if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
+				return callbacks[ prop ].apply( callbacks, args );
+			} else {
+				return callbacks[ prop ]; // or undefined
+			}
+		}
+	}
+
+	// the real equiv function
+	var innerEquiv,
+		// stack to decide between skip/abort functions
+		callers = [],
+		// stack to avoiding loops from circular referencing
+		parents = [],
+		parentsB = [],
+
+		getProto = Object.getPrototypeOf || function ( obj ) {
+			/*jshint camelcase:false */
+			return obj.__proto__;
+		},
+		callbacks = (function () {
+
+			// for string, boolean, number and null
+			function useStrictEquality( b, a ) {
+				/*jshint eqeqeq:false */
+				if ( b instanceof a.constructor || a instanceof b.constructor ) {
+					// to catch short annotation VS 'new' annotation of a
+					// declaration
+					// e.g. var i = 1;
+					// var j = new Number(1);
+					return a == b;
+				} else {
+					return a === b;
+				}
+			}
+
+			return {
+				"string": useStrictEquality,
+				"boolean": useStrictEquality,
+				"number": useStrictEquality,
+				"null": useStrictEquality,
+				"undefined": useStrictEquality,
+
+				"nan": function( b ) {
+					return isNaN( b );
+				},
+
+				"date": function( b, a ) {
+					return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
+				},
+
+				"regexp": function( b, a ) {
+					return QUnit.objectType( b ) === "regexp" &&
+						// the regex itself
+						a.source === b.source &&
+						// and its modifiers
+						a.global === b.global &&
+						// (gmi) ...
+						a.ignoreCase === b.ignoreCase &&
+						a.multiline === b.multiline &&
+						a.sticky === b.sticky;
+				},
+
+				// - skip when the property is a method of an instance (OOP)
+				// - abort otherwise,
+				// initial === would have catch identical references anyway
+				"function": function() {
+					var caller = callers[callers.length - 1];
+					return caller !== Object && typeof caller !== "undefined";
+				},
+
+				"array": function( b, a ) {
+					var i, j, len, loop, aCircular, bCircular;
+
+					// b could be an object literal here
+					if ( QUnit.objectType( b ) !== "array" ) {
+						return false;
+					}
+
+					len = a.length;
+					if ( len !== b.length ) {
+						// safe and faster
+						return false;
+					}
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+					for ( i = 0; i < len; i++ ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									parents.pop();
+									parentsB.pop();
+									return false;
+								}
+							}
+						}
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							parents.pop();
+							parentsB.pop();
+							return false;
+						}
+					}
+					parents.pop();
+					parentsB.pop();
+					return true;
+				},
+
+				"object": function( b, a ) {
+					/*jshint forin:false */
+					var i, j, loop, aCircular, bCircular,
+						// Default to true
+						eq = true,
+						aProperties = [],
+						bProperties = [];
+
+					// comparing constructors is more strict than using
+					// instanceof
+					if ( a.constructor !== b.constructor ) {
+						// Allow objects with no prototype to be equivalent to
+						// objects with Object as their constructor.
+						if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
+							( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
+								return false;
+						}
+					}
+
+					// stack constructor before traversing properties
+					callers.push( a.constructor );
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+
+					// be strict: don't ensure hasOwnProperty and go deep
+					for ( i in a ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									eq = false;
+									break;
+								}
+							}
+						}
+						aProperties.push(i);
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							eq = false;
+							break;
+						}
+					}
+
+					parents.pop();
+					parentsB.pop();
+					callers.pop(); // unstack, we are done
+
+					for ( i in b ) {
+						bProperties.push( i ); // collect b's properties
+					}
+
+					// Ensures identical properties name
+					return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
+				}
+			};
+		}());
+
+	innerEquiv = function() { // can take multiple arguments
+		var args = [].slice.apply( arguments );
+		if ( args.length < 2 ) {
+			return true; // end transition
+		}
+
+		return (function( a, b ) {
+			if ( a === b ) {
+				return true; // catch the most you can
+			} else if ( a === null || b === null || typeof a === "undefined" ||
+					typeof b === "undefined" ||
+					QUnit.objectType(a) !== QUnit.objectType(b) ) {
+				return false; // don't lose time with error prone cases
+			} else {
+				return bindCallbacks(a, callbacks, [ b, a ]);
+			}
+
+			// apply transition with (1..n) arguments
+		}( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) );
+	};
+
+	return innerEquiv;
+}());
+
+/**
+ * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
+ * http://flesler.blogspot.com Licensed under BSD
+ * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
+ *
+ * @projectDescription Advanced and extensible data dumping for Javascript.
+ * @version 1.0.0
+ * @author Ariel Flesler
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
+ */
+QUnit.jsDump = (function() {
+	function quote( str ) {
+		return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
+	}
+	function literal( o ) {
+		return o + "";
+	}
+	function join( pre, arr, post ) {
+		var s = jsDump.separator(),
+			base = jsDump.indent(),
+			inner = jsDump.indent(1);
+		if ( arr.join ) {
+			arr = arr.join( "," + s + inner );
+		}
+		if ( !arr ) {
+			return pre + post;
+		}
+		return [ pre, inner + arr, base + post ].join(s);
+	}
+	function array( arr, stack ) {
+		var i = arr.length, ret = new Array(i);
+		this.up();
+		while ( i-- ) {
+			ret[i] = this.parse( arr[i] , undefined , stack);
+		}
+		this.down();
+		return join( "[", ret, "]" );
+	}
+
+	var reName = /^function (\w+)/,
+		jsDump = {
+			// type is used mostly internally, you can fix a (custom)type in advance
+			parse: function( obj, type, stack ) {
+				stack = stack || [ ];
+				var inStack, res,
+					parser = this.parsers[ type || this.typeOf(obj) ];
+
+				type = typeof parser;
+				inStack = inArray( obj, stack );
+
+				if ( inStack !== -1 ) {
+					return "recursion(" + (inStack - stack.length) + ")";
+				}
+				if ( type === "function" )  {
+					stack.push( obj );
+					res = parser.call( this, obj, stack );
+					stack.pop();
+					return res;
+				}
+				return ( type === "string" ) ? parser : this.parsers.error;
+			},
+			typeOf: function( obj ) {
+				var type;
+				if ( obj === null ) {
+					type = "null";
+				} else if ( typeof obj === "undefined" ) {
+					type = "undefined";
+				} else if ( QUnit.is( "regexp", obj) ) {
+					type = "regexp";
+				} else if ( QUnit.is( "date", obj) ) {
+					type = "date";
+				} else if ( QUnit.is( "function", obj) ) {
+					type = "function";
+				} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
+					type = "window";
+				} else if ( obj.nodeType === 9 ) {
+					type = "document";
+				} else if ( obj.nodeType ) {
+					type = "node";
+				} else if (
+					// native arrays
+					toString.call( obj ) === "[object Array]" ||
+					// NodeList objects
+					( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
+				) {
+					type = "array";
+				} else if ( obj.constructor === Error.prototype.constructor ) {
+					type = "error";
+				} else {
+					type = typeof obj;
+				}
+				return type;
+			},
+			separator: function() {
+				return this.multiline ?	this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
+			},
+			// extra can be a number, shortcut for increasing-calling-decreasing
+			indent: function( extra ) {
+				if ( !this.multiline ) {
+					return "";
+				}
+				var chr = this.indentChar;
+				if ( this.HTML ) {
+					chr = chr.replace( /\t/g, "   " ).replace( / /g, "&nbsp;" );
+				}
+				return new Array( this.depth + ( extra || 0 ) ).join(chr);
+			},
+			up: function( a ) {
+				this.depth += a || 1;
+			},
+			down: function( a ) {
+				this.depth -= a || 1;
+			},
+			setParser: function( name, parser ) {
+				this.parsers[name] = parser;
+			},
+			// The next 3 are exposed so you can use them
+			quote: quote,
+			literal: literal,
+			join: join,
+			//
+			depth: 1,
+			// This is the list of parsers, to modify them, use jsDump.setParser
+			parsers: {
+				window: "[Window]",
+				document: "[Document]",
+				error: function(error) {
+					return "Error(\"" + error.message + "\")";
+				},
+				unknown: "[Unknown]",
+				"null": "null",
+				"undefined": "undefined",
+				"function": function( fn ) {
+					var ret = "function",
+						// functions never have name in IE
+						name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
+
+					if ( name ) {
+						ret += " " + name;
+					}
+					ret += "( ";
+
+					ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
+					return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
+				},
+				array: array,
+				nodelist: array,
+				"arguments": array,
+				object: function( map, stack ) {
+					/*jshint forin:false */
+					var ret = [ ], keys, key, val, i;
+					QUnit.jsDump.up();
+					keys = [];
+					for ( key in map ) {
+						keys.push( key );
+					}
+					keys.sort();
+					for ( i = 0; i < keys.length; i++ ) {
+						key = keys[ i ];
+						val = map[ key ];
+						ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
+					}
+					QUnit.jsDump.down();
+					return join( "{", ret, "}" );
+				},
+				node: function( node ) {
+					var len, i, val,
+						open = QUnit.jsDump.HTML ? "&lt;" : "<",
+						close = QUnit.jsDump.HTML ? "&gt;" : ">",
+						tag = node.nodeName.toLowerCase(),
+						ret = open + tag,
+						attrs = node.attributes;
+
+					if ( attrs ) {
+						for ( i = 0, len = attrs.length; i < len; i++ ) {
+							val = attrs[i].nodeValue;
+							// IE6 includes all attributes in .attributes, even ones not explicitly set.
+							// Those have values like undefined, null, 0, false, "" or "inherit".
+							if ( val && val !== "inherit" ) {
+								ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
+							}
+						}
+					}
+					ret += close;
+
+					// Show content of TextNode or CDATASection
+					if ( node.nodeType === 3 || node.nodeType === 4 ) {
+						ret += node.nodeValue;
+					}
+
+					return ret + open + "/" + tag + close;
+				},
+				// function calls it internally, it's the arguments part of the function
+				functionArgs: function( fn ) {
+					var args,
+						l = fn.length;
+
+					if ( !l ) {
+						return "";
+					}
+
+					args = new Array(l);
+					while ( l-- ) {
+						// 97 is 'a'
+						args[l] = String.fromCharCode(97+l);
+					}
+					return " " + args.join( ", " ) + " ";
+				},
+				// object calls it internally, the key part of an item in a map
+				key: quote,
+				// function calls it internally, it's the content of the function
+				functionCode: "[code]",
+				// node calls it internally, it's an html attribute value
+				attribute: quote,
+				string: quote,
+				date: quote,
+				regexp: literal,
+				number: literal,
+				"boolean": literal
+			},
+			// if true, entities are escaped ( <, >, \t, space and \n )
+			HTML: false,
+			// indentation unit
+			indentChar: "  ",
+			// if true, items in a collection, are separated by a \n, else just a space.
+			multiline: true
+		};
+
+	return jsDump;
+}());
+
+// from jquery.js
+function inArray( elem, array ) {
+	if ( array.indexOf ) {
+		return array.indexOf( elem );
+	}
+
+	for ( var i = 0, length = array.length; i < length; i++ ) {
+		if ( array[ i ] === elem ) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/*
+ * Javascript Diff Algorithm
+ *  By John Resig (http://ejohn.org/)
+ *  Modified by Chu Alan "sprite"
+ *
+ * Released under the MIT license.
+ *
+ * More Info:
+ *  http://ejohn.org/projects/javascript-diff-algorithm/
+ *
+ * Usage: QUnit.diff(expected, actual)
+ *
+ * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
+ */
+QUnit.diff = (function() {
+	/*jshint eqeqeq:false, eqnull:true */
+	function diff( o, n ) {
+		var i,
+			ns = {},
+			os = {};
+
+		for ( i = 0; i < n.length; i++ ) {
+			if ( !hasOwn.call( ns, n[i] ) ) {
+				ns[ n[i] ] = {
+					rows: [],
+					o: null
+				};
+			}
+			ns[ n[i] ].rows.push( i );
+		}
+
+		for ( i = 0; i < o.length; i++ ) {
+			if ( !hasOwn.call( os, o[i] ) ) {
+				os[ o[i] ] = {
+					rows: [],
+					n: null
+				};
+			}
+			os[ o[i] ].rows.push( i );
+		}
+
+		for ( i in ns ) {
+			if ( hasOwn.call( ns, i ) ) {
+				if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
+					n[ ns[i].rows[0] ] = {
+						text: n[ ns[i].rows[0] ],
+						row: os[i].rows[0]
+					};
+					o[ os[i].rows[0] ] = {
+						text: o[ os[i].rows[0] ],
+						row: ns[i].rows[0]
+					};
+				}
+			}
+		}
+
+		for ( i = 0; i < n.length - 1; i++ ) {
+			if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
+						n[ i + 1 ] == o[ n[i].row + 1 ] ) {
+
+				n[ i + 1 ] = {
+					text: n[ i + 1 ],
+					row: n[i].row + 1
+				};
+				o[ n[i].row + 1 ] = {
+					text: o[ n[i].row + 1 ],
+					row: i + 1
+				};
+			}
+		}
+
+		for ( i = n.length - 1; i > 0; i-- ) {
+			if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
+						n[ i - 1 ] == o[ n[i].row - 1 ]) {
+
+				n[ i - 1 ] = {
+					text: n[ i - 1 ],
+					row: n[i].row - 1
+				};
+				o[ n[i].row - 1 ] = {
+					text: o[ n[i].row - 1 ],
+					row: i - 1
+				};
+			}
+		}
+
+		return {
+			o: o,
+			n: n
+		};
+	}
+
+	return function( o, n ) {
+		o = o.replace( /\s+$/, "" );
+		n = n.replace( /\s+$/, "" );
+
+		var i, pre,
+			str = "",
+			out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
+			oSpace = o.match(/\s+/g),
+			nSpace = n.match(/\s+/g);
+
+		if ( oSpace == null ) {
+			oSpace = [ " " ];
+		}
+		else {
+			oSpace.push( " " );
+		}
+
+		if ( nSpace == null ) {
+			nSpace = [ " " ];
+		}
+		else {
+			nSpace.push( " " );
+		}
+
+		if ( out.n.length === 0 ) {
+			for ( i = 0; i < out.o.length; i++ ) {
+				str += "<del>" + out.o[i] + oSpace[i] + "</del>";
+			}
+		}
+		else {
+			if ( out.n[0].text == null ) {
+				for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
+					str += "<del>" + out.o[n] + oSpace[n] + "</del>";
+				}
+			}
+
+			for ( i = 0; i < out.n.length; i++ ) {
+				if (out.n[i].text == null) {
+					str += "<ins>" + out.n[i] + nSpace[i] + "</ins>";
+				}
+				else {
+					// `pre` initialized at top of scope
+					pre = "";
+
+					for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
+						pre += "<del>" + out.o[n] + oSpace[n] + "</del>";
+					}
+					str += " " + out.n[i].text + nSpace[i] + pre;
+				}
+			}
+		}
+
+		return str;
+	};
+}());
+
+// for CommonJS environments, export everything
+if ( typeof exports !== "undefined" ) {
+	extend( exports, QUnit.constructor.prototype );
+}
+
+// get at whatever the global object is, like window in browsers
+}( (function() {return this;}.call()) ));
diff --git a/docs/slides/IHP14/_support/reveal.js/test/test-markdown-element-attributes.html b/docs/slides/IHP14/_support/reveal.js/test/test-markdown-element-attributes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/test-markdown-element-attributes.html
@@ -0,0 +1,134 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test Markdown Element Attributes</title>
+
+		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+
+				<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
+				<section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$" data-element-attributes="{_\s*?([^}]+?)}">>
+					<script type="text/template">
+						## Slide 1.1
+						<!-- {_class="fragment fade-out" data-fragment-index="1"} -->
+
+						--
+
+						## Slide 1.2
+						<!-- {_class="fragment shrink"} -->
+
+						Paragraph 1
+						<!-- {_class="fragment grow"} -->
+
+						Paragraph 2
+						<!-- {_class="fragment grow"} -->
+
+						- list item 1 <!-- {_class="fragment roll-in"} -->
+						- list item 2 <!-- {_class="fragment roll-in"} -->
+						- list item 3 <!-- {_class="fragment roll-in"} -->
+
+
+						---
+
+						## Slide 2
+
+
+						Paragraph 1.2  
+						multi-line <!-- {_class="fragment highlight-red"} -->
+
+						Paragraph 2.2 <!-- {_class="fragment highlight-red"} -->
+
+						Paragraph 2.3 <!-- {_class="fragment highlight-red"} -->
+
+						Paragraph 2.4 <!-- {_class="fragment highlight-red"} -->
+
+						- list item 1 <!-- {_class="fragment highlight-green"} -->
+						- list item 2<!-- {_class="fragment highlight-green"} -->
+						- list item 3<!-- {_class="fragment highlight-green"} -->
+						- list item 4
+						<!-- {_class="fragment highlight-green"} -->
+						- list item 5<!-- {_class="fragment highlight-green"} -->
+
+						Test
+
+						![Example Picture](examples/assets/image2.png)
+						<!-- {_class="reveal stretch"} -->
+
+					</script>
+				</section>
+
+
+
+				<section 	data-markdown data-separator="^\n\n\n"
+									data-vertical="^\n\n"
+									data-notes="^Note:"
+									data-charset="utf-8">
+					<script type="text/template">
+						# Test attributes in Markdown with default separator
+						## Slide 1 Def <!-- .element: class="fragment highlight-red" data-fragment-index="1" -->
+
+
+						## Slide 2 Def
+						<!-- .element: class="fragment highlight-red" -->
+
+					</script>
+				</section>
+
+				<section data-markdown>
+				  <script type="text/template">
+					## Hello world
+					A paragraph
+					<!-- .element: class="fragment highlight-blue" -->
+				  </script>
+				</section>
+
+				<section data-markdown>
+				  <script type="text/template">
+					## Hello world
+
+					Multiple  
+					Line
+					<!-- .element: class="fragment highlight-blue" -->
+				  </script>
+				</section>
+
+				<section data-markdown>
+				  <script type="text/template">
+					## Hello world
+
+					Test<!-- .element: class="fragment highlight-blue" -->
+
+					More Test
+				  </script>
+				</section>
+
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.min.js"></script>
+		<script src="../plugin/markdown/marked.js"></script>
+		<script src="../plugin/markdown/markdown.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test-markdown-element-attributes.js"></script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/test/test-markdown-element-attributes.js b/docs/slides/IHP14/_support/reveal.js/test/test-markdown-element-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/test-markdown-element-attributes.js
@@ -0,0 +1,46 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
+	});
+
+
+	test( 'Attributes on element header in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
+	});
+
+	test( 'Attributes on element paragraphs in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
+	});
+
+	test( 'Attributes on element list items in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.roll-in' ).length, 3, 'found a vertical slide with three list items with class fragment.roll-in' );
+	});
+
+	test( 'Attributes on element paragraphs in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
+	});
+
+	test( 'Attributes on elements in vertical slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
+	});
+
+	test( 'Attributes on elements in single slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/IHP14/_support/reveal.js/test/test-markdown-slide-attributes.html b/docs/slides/IHP14/_support/reveal.js/test/test-markdown-slide-attributes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/test-markdown-slide-attributes.html
@@ -0,0 +1,128 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test Markdown Attributes</title>
+
+		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+
+				<!-- Slides are separated by three lines, vertical slides by two lines, attributes are one any line starting with (spaces and) two dashes -->
+				<section 	data-markdown data-separator="^\n\n\n"
+									data-vertical="^\n\n"
+									data-notes="^Note:"
+									data-attributes="--\s(.*?)$"
+									data-charset="utf-8">
+					<script type="text/template">
+						# Test attributes in Markdown
+						## Slide 1
+
+
+
+						## Slide 2
+						<!-- -- id="slide2" data-transition="zoom" data-background="#A0C66B" -->
+
+
+						## Slide 2.1
+						<!-- -- data-background="#ff0000" data-transition="fade" -->
+
+
+						## Slide 2.2
+						[Link to Slide2](#/slide2)
+
+
+
+						## Slide 3
+						<!-- -- data-transition="zoom" data-background="#C6916B" -->
+
+
+
+						## Slide 4
+					</script>
+				</section>
+
+				<section 	data-markdown data-separator="^\n\n\n"
+									data-vertical="^\n\n"
+									data-notes="^Note:"
+									data-charset="utf-8">
+					<script type="text/template">
+						# Test attributes in Markdown with default separator
+						## Slide 1 Def
+
+
+
+						## Slide 2 Def
+						<!-- .slide: id="slide2def" data-transition="concave" data-background="#A7C66B" -->
+
+
+						## Slide 2.1 Def
+						<!-- .slide: data-background="#f70000" data-transition="page" -->
+
+
+						## Slide 2.2 Def
+						[Link to Slide2](#/slide2def)
+
+
+
+						## Slide 3 Def
+						<!-- .slide: data-transition="concave" data-background="#C7916B" -->
+
+
+
+						## Slide 4
+					</script>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						<!-- .slide: data-background="#ff0000" -->
+						## Hello world
+					</script>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						## Hello world
+						<!-- .slide: data-background="#ff0000" -->
+					</script>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						## Hello world
+
+						Test
+						<!-- .slide: data-background="#ff0000" -->
+
+						More Test
+					</script>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.min.js"></script>
+		<script src="../plugin/markdown/marked.js"></script>
+		<script src="../plugin/markdown/markdown.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test-markdown-slide-attributes.js"></script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/test/test-markdown-slide-attributes.js b/docs/slides/IHP14/_support/reveal.js/test/test-markdown-slide-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/test-markdown-slide-attributes.js
@@ -0,0 +1,47 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' );
+	});
+
+	test( 'Id on slide', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' );
+	});
+
+	test( 'data-background attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-background attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-transition attributes with inline content', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/IHP14/_support/reveal.js/test/test-markdown.html b/docs/slides/IHP14/_support/reveal.js/test/test-markdown.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/test-markdown.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test Markdown</title>
+
+		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+  		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+
+				<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
+				<section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$">
+					<script type="text/template">
+						## Slide 1.1
+
+						--
+
+						## Slide 1.2
+
+						---
+
+						## Slide 2
+					</script>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.min.js"></script>
+		<script src="../plugin/markdown/marked.js"></script>
+		<script src="../plugin/markdown/markdown.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test-markdown.js"></script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/test/test-markdown.js b/docs/slides/IHP14/_support/reveal.js/test/test-markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/test-markdown.js
@@ -0,0 +1,15 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/IHP14/_support/reveal.js/test/test.html b/docs/slides/IHP14/_support/reveal.js/test/test.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/test.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Tests</title>
+
+		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+  		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<section>
+					<h1>1</h1>
+				</section>
+
+				<section>
+					<section>
+						<h1>2.1</h1>
+					</section>
+					<section>
+						<h1>2.2</h1>
+					</section>
+					<section>
+						<h1>2.3</h1>
+					</section>
+				</section>
+
+				<section id="fragment-slides">
+					<section>
+						<h1>3.1</h1>
+						<ul>
+							<li class="fragment">4.1</li>
+							<li class="fragment">4.2</li>
+							<li class="fragment">4.3</li>
+						</ul>
+					</section>
+
+					<section>
+						<h1>3.2</h1>
+						<ul>
+							<li class="fragment" data-fragment-index="0">4.1</li>
+							<li class="fragment" data-fragment-index="0">4.2</li>
+						</ul>
+					</section>
+
+					<section>
+						<h1>3.3</h1>
+						<ul>
+							<li class="fragment" data-fragment-index="1">3.3.1</li>
+							<li class="fragment" data-fragment-index="4">3.3.2</li>
+							<li class="fragment" data-fragment-index="4">3.3.3</li>
+						</ul>
+					</section>
+				</section>
+
+				<section>
+					<h1>4</h1>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.min.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test.js"></script>
+
+	</body>
+</html>
diff --git a/docs/slides/IHP14/_support/reveal.js/test/test.js b/docs/slides/IHP14/_support/reveal.js/test/test.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/reveal.js/test/test.js
@@ -0,0 +1,438 @@
+
+// These tests expect the DOM to contain a presentation
+// with the following slide structure:
+//
+// 1
+// 2 - Three sub-slides
+// 3 - Three fragment elements
+// 3 - Two fragments with same data-fragment-index
+// 4
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	// ---------------------------------------------------------------
+	// DOM TESTS
+
+	QUnit.module( 'DOM' );
+
+	test( 'Initial slides classes', function() {
+		var horizontalSlides = document.querySelectorAll( '.reveal .slides>section' )
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.past' ).length, 0, 'no .past slides' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section.present' ).length, 1, 'one .present slide' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section.future' ).length, horizontalSlides.length - 1, 'remaining horizontal slides are .future' );
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.stack' ).length, 2, 'two .stacks' );
+
+		ok( document.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length > 0, 'vertical slides are given .future' );
+	});
+
+	// ---------------------------------------------------------------
+	// API TESTS
+
+	QUnit.module( 'API' );
+
+	test( 'Reveal.isReady', function() {
+		strictEqual( Reveal.isReady(), true, 'returns true' );
+	});
+
+	test( 'Reveal.isOverview', function() {
+		strictEqual( Reveal.isOverview(), false, 'false by default' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), true, 'true after toggling on' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), false, 'false after toggling off' );
+	});
+
+	test( 'Reveal.isPaused', function() {
+		strictEqual( Reveal.isPaused(), false, 'false by default' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), true, 'true after pausing' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), false, 'false after resuming' );
+	});
+
+	test( 'Reveal.isFirstSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+
+		Reveal.slide( 1, 0 );
+		strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.isLastSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+
+		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
+
+		Reveal.slide( lastSlideIndex, 0 );
+		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( ', 0+ lastSlideIndex +' )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.getIndices', function() {
+		var indices = Reveal.getIndices();
+
+		ok( typeof indices.hasOwnProperty( 'h' ), 'h exists' );
+		ok( typeof indices.hasOwnProperty( 'v' ), 'v exists' );
+		ok( typeof indices.hasOwnProperty( 'f' ), 'f exists' );
+
+		Reveal.slide( 1, 0 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 0, 'h 1, v 0' );
+
+		Reveal.slide( 1, 2 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 2, 'h 1, v 2' );
+
+		Reveal.slide( 0, 0 );
+	});
+
+	test( 'Reveal.getSlide', function() {
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+
+		equal( Reveal.getSlide( 0 ), firstSlide, 'gets correct first slide' );
+
+		strictEqual( Reveal.getSlide( 100 ), undefined, 'returns undefined when slide can\'t be found' );
+	});
+
+	test( 'Reveal.getPreviousSlide/getCurrentSlide', function() {
+		Reveal.slide( 0, 0 );
+		Reveal.slide( 1, 0 );
+
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+		var secondSlide = document.querySelector( '.reveal .slides>section:nth-child(2)>section' );
+
+		equal( Reveal.getPreviousSlide(), firstSlide, 'previous is slide #0' );
+		equal( Reveal.getCurrentSlide(), secondSlide, 'current is slide #1' );
+	});
+
+	test( 'Reveal.getScale', function() {
+		ok( typeof Reveal.getScale() === 'number', 'has scale' );
+	});
+
+	test( 'Reveal.getConfig', function() {
+		ok( typeof Reveal.getConfig() === 'object', 'has config' );
+	});
+
+	test( 'Reveal.configure', function() {
+		strictEqual( Reveal.getConfig().loop, false, '"loop" is false to start with' );
+
+		Reveal.configure({ loop: true });
+		strictEqual( Reveal.getConfig().loop, true, '"loop" has changed to true' );
+
+		Reveal.configure({ loop: false, customTestValue: 1 });
+		strictEqual( Reveal.getConfig().customTestValue, 1, 'supports custom values' );
+	});
+
+	test( 'Reveal.availableRoutes', function() {
+		Reveal.slide( 0, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: false, up: false, down: false, right: true }, 'correct for first slide' );
+
+		Reveal.slide( 1, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: true, up: false, down: true, right: true }, 'correct for vertical slide' );
+	});
+
+	test( 'Reveal.next', function() {
+		Reveal.slide( 0, 0 );
+
+		// Step through vertical child slides
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 1, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } );
+
+		// Step through fragments
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } );
+	});
+
+	test( 'Reveal.next at end', function() {
+		Reveal.slide( 3 );
+
+		// We're at the end, this should have no effect
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+	});
+
+
+	// ---------------------------------------------------------------
+	// FRAGMENT TESTS
+
+	QUnit.module( 'Fragments' );
+
+	test( 'Sliding to fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'Reveal.slide( 2, 0, -1 )' );
+
+		Reveal.slide( 2, 0, 0 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'Reveal.slide( 2, 0, 0 )' );
+
+		Reveal.slide( 2, 0, 2 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'Reveal.slide( 2, 0, 2 )' );
+
+		Reveal.slide( 2, 0, 1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'Reveal.slide( 2, 0, 1 )' );
+	});
+
+	test( 'Hiding all fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' );
+
+		Reveal.slide( 2, 0, -1 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index is -1' );
+	});
+
+	test( 'Current fragment', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 1, 'one current fragment at index 0' );
+
+		Reveal.slide( 1, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
+	});
+
+	test( 'Stepping through fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+
+		// forwards:
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'next() goes to next fragment' );
+
+		Reveal.right();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'right() goes to next fragment' );
+
+		Reveal.down();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'down() goes to next fragment' );
+
+		Reveal.down(); // moves to f #3
+
+		// backwards:
+
+		Reveal.prev();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'prev() goes to prev fragment' );
+
+		Reveal.left();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'left() goes to prev fragment' );
+
+		Reveal.up();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'up() goes to prev fragment' );
+	});
+
+	test( 'Stepping past fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 0, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 3, 'all fragments visible when on future slide' );
+	});
+
+	test( 'Fragment indices', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(2)' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 2, 'both fragments of same index are shown' );
+	});
+
+	test( 'Index generation', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		// These have no indices defined to start with
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' );
+	});
+
+	test( 'Index normalization', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(3)' );
+
+		// These start out as 1-4-4 and should normalize to 0-1-1
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' );
+	});
+
+	asyncTest( 'fragmentshown event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmentshown', _onEvent );
+
+		Reveal.slide( 2, 0 );
+		Reveal.slide( 2, 0 ); // should do nothing
+		Reveal.slide( 2, 0, 0 ); // should do nothing
+		Reveal.next();
+		Reveal.next();
+		Reveal.prev(); // shouldn't fire fragmentshown
+
+		start();
+
+		Reveal.removeEventListener( 'fragmentshown', _onEvent );
+	});
+
+	asyncTest( 'fragmenthidden event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmenthidden', _onEvent );
+
+		Reveal.slide( 2, 0, 2 );
+		Reveal.slide( 2, 0, 2 ); // should do nothing
+		Reveal.prev();
+		Reveal.prev();
+		Reveal.next(); // shouldn't fire fragmenthidden
+
+		start();
+
+		Reveal.removeEventListener( 'fragmenthidden', _onEvent );
+	});
+
+
+	// ---------------------------------------------------------------
+	// CONFIGURATION VALUES
+
+	QUnit.module( 'Configuration' );
+
+	test( 'Controls', function() {
+		var controlsElement = document.querySelector( '.reveal>.controls' );
+
+		Reveal.configure({ controls: false });
+		equal( controlsElement.style.display, 'none', 'controls are hidden' );
+
+		Reveal.configure({ controls: true });
+		equal( controlsElement.style.display, 'block', 'controls are visible' );
+	});
+
+	test( 'Progress', function() {
+		var progressElement = document.querySelector( '.reveal>.progress' );
+
+		Reveal.configure({ progress: false });
+		equal( progressElement.style.display, 'none', 'progress are hidden' );
+
+		Reveal.configure({ progress: true });
+		equal( progressElement.style.display, 'block', 'progress are visible' );
+	});
+
+	test( 'Loop', function() {
+		Reveal.configure({ loop: true });
+
+		Reveal.slide( 0, 0 );
+
+		Reveal.left();
+		notEqual( Reveal.getIndices().h, 0, 'looped from start to end' );
+
+		Reveal.right();
+		equal( Reveal.getIndices().h, 0, 'looped from end to start' );
+
+		Reveal.configure({ loop: false });
+	});
+
+
+	// ---------------------------------------------------------------
+	// EVENT TESTS
+
+	QUnit.module( 'Events' );
+
+	asyncTest( 'slidechanged', function() {
+		expect( 3 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'slidechanged', _onEvent );
+
+		Reveal.slide( 1, 0 ); // should trigger
+		Reveal.slide( 1, 0 ); // should do nothing
+		Reveal.next(); // should trigger
+		Reveal.slide( 3, 0 ); // should trigger
+		Reveal.next(); // should do nothing
+
+		start();
+
+		Reveal.removeEventListener( 'slidechanged', _onEvent );
+
+	});
+
+	asyncTest( 'paused', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'paused', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'paused', _onEvent );
+	});
+
+	asyncTest( 'resumed', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'resumed', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'resumed', _onEvent );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/IHP14/_support/template.reveal b/docs/slides/IHP14/_support/template.reveal
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/_support/template.reveal
@@ -0,0 +1,122 @@
+<!doctype html>  
+<html lang="en">
+	
+<head>
+<meta charset="utf-8">
+
+<title>Liquid Types</title>
+
+<meta name="description" content="Liquid Types IHP 2014">
+<meta name="author" content="Ranjit Jhala">
+
+<meta name="apple-mobile-web-app-capable" content="yes" />
+
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+
+<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
+
+<link rel="stylesheet" href="$reveal$/css/reveal.css">
+<link rel="stylesheet" href="$reveal$/css/theme/seminar.css" id="theme">
+<!-- <link rel="stylesheet" href="$reveal$/css/print/pdf.css"> -->
+<link rel="stylesheet" href="../_support/liquidhaskell.css">
+
+<!-- For syntax highlighting -->
+<link rel="stylesheet" href="$reveal$/lib/css/zenburn.css">
+
+<script>
+	// If the query includes 'print-pdf' we'll use the PDF print sheet
+	document.write( '<link rel="stylesheet" href="$reveal$/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
+</script>
+
+<!--[if lt IE 9]>
+<script src="lib/js/html5shiv.js"></script>
+<![endif]-->
+</head>
+<body>
+
+\(
+\require{color}
+\definecolor{kvcol}{RGB}{203,23,206}
+\definecolor{tycol}{RGB}{5,177,93}
+\definecolor{refcol}{RGB}{18,110,213}
+
+\newcommand{\quals}{\mathbb{Q}}
+\newcommand{\defeq}{\ \doteq\ }
+\newcommand{\subty}{\preceq}
+\newcommand{\True}{\mathit{True}}
+\newcommand{\Int}{\mathtt{Int}}
+\newcommand{\Nat}{\mathtt{Nat}}
+\newcommand{\Zero}{\mathtt{Zero}}
+\newcommand{\foo}[4]{{#1}^{#4} + {#2}^{#4} = {#3}^{#4}}
+\newcommand{\reft}[3]{\{\bindx{#1}{#2} \mid {#3}\}}
+\newcommand{\ereft}[3]{\bindx{#1}{\{#2 \mid #3\}}}
+\newcommand{\bindx}[2]{{#1}\!:\!{#2}}
+\newcommand{\reftx}[2]{\{{#1}\mid{#2}\}}
+\newcommand{\inferrule}[3][]{\frac{#2}{#3}\;{#1}}
+\newcommand{\kvar}[1]{\color{kvcol}{\mathbf{\kappa_{#1}}}}
+\newcommand{\llen}[1]{\mathtt{llen}(#1)}
+\)
+
+<div class="reveal">
+<!-- 
+Used to fade in a background when a specific slide state is reached
+-->
+<div class="state-background"></div>
+
+<!-- Slides
+Any section element inside of this "slides" container is displayed as a slide
+-->
+<div class="slides">
+<!-- Pandoc -->
+$if(title)$
+<section class="titlepage">
+<h1 class="title">$title$</h1>
+$for(author)$
+<h2 class="author">$author$</h2>
+$endfor$
+<h3 class="date">$date$</h3>
+</section>
+$endif$
+$body$
+<!-- End Pandoc -->
+
+</div>
+<!-- End Slides -->
+
+<!-- Presentation progress bar -->
+<div class="progress"><span></span></div>
+</div>
+
+<!-- Initialize reveal.js :: make settings changes here -->
+<script src="$reveal$/lib/js/head.min.js"></script>
+<script src="$reveal$/js/reveal.js"></script>
+
+<script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+
+
+<script>		
+	// Full list of configuration options available here:
+	// https://github.com/hakimel/reveal.js#configuration
+	Reveal.initialize({
+		controls: true,
+		progress: true,
+		history: true,
+		center: false,
+        rollingLinks: false,
+        theme: Reveal.getQueryHash().theme || 'seminar', // available themes are in /css/theme
+		transition: Reveal.getQueryHash().transition || 'fade', // default/cube/page/concave/linear(2d)
+
+		// Optional libraries used to extend on reveal.js
+		dependencies: [
+			//{ src: '$reveal$/lib/js/highlight.js', async: true, callback: function() { window.hljs.initHighlightingOnLoad(); } },
+			{ src: '$reveal$/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+			{ src: '$reveal$/lib/js/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/lib/js/data-markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/socket.io/socket.io.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+			{ src: '$reveal$/plugin/speakernotes/client.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+		]
+	});
+</script>
+
+</body>
+</html>
diff --git a/docs/slides/IHP14/cleanup b/docs/slides/IHP14/cleanup
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/cleanup
@@ -0,0 +1,1 @@
+find . | grep -E -e '\.(smt2|bak|json|css|md|hi|out|fqout|fq|o|err|annot|log|html|cgi|liquid)$' | xargs rm -rf
diff --git a/docs/slides/IHP14/img/RedBlack.png b/docs/slides/IHP14/img/RedBlack.png
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/img/RedBlack.png differ
diff --git a/docs/slides/IHP14/img/tension0.png b/docs/slides/IHP14/img/tension0.png
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/img/tension0.png differ
diff --git a/docs/slides/IHP14/img/tension1.png b/docs/slides/IHP14/img/tension1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/img/tension1.png differ
diff --git a/docs/slides/IHP14/img/tension2.png b/docs/slides/IHP14/img/tension2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/img/tension2.png differ
diff --git a/docs/slides/IHP14/img/tension3.png b/docs/slides/IHP14/img/tension3.png
new file mode 100644
Binary files /dev/null and b/docs/slides/IHP14/img/tension3.png differ
diff --git a/docs/slides/IHP14/lhs/00_Motivation_GoWrong.lhs b/docs/slides/IHP14/lhs/00_Motivation_GoWrong.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/00_Motivation_GoWrong.lhs
@@ -0,0 +1,176 @@
+Well-Typed Programs Can Go Wrong
+================================
+
+ {#asd}
+-------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+Division By Zero
+----------------
+
+
+
+
+<div class="fragment"> 
+\begin{code} <div/> 
+λ> let average xs = sum xs `div` length xs
+
+λ> average [1,2,3]
+2
+\end{code}
+</div>
+
+<div class="fragment"> 
+
+\begin{code} <br> 
+λ> average []
+*** Exception: divide by zero
+\end{code}
+
+</div>
+
+Missing Keys
+------------
+
+<div class="fragment"> 
+\begin{code} <div/> 
+λ> :m +Data.Map 
+λ> let m = fromList [ ("haskell", "lazy")
+                    , ("ocaml"  , "eager")]
+
+λ> m ! "haskell"
+"lazy"
+\end{code}
+</div>
+
+<div class="fragment"> 
+\begin{code} <br> 
+λ> m ! "javascript"
+"*** Exception: key is not in the map
+\end{code}
+</div>
+
+Segmentation Faults
+-------------------
+
+<div class="fragment"> 
+\begin{code} <div/> 
+λ> :m +Data.Vector 
+λ> let v = fromList ["haskell", "ocaml"]
+λ> unsafeIndex v 0
+"haskell"
+\end{code}
+</div>
+
+<div class="fragment"> 
+\begin{code} <br> 
+λ> V.unsafeIndex v 3
+
+
+'ghci' terminated by signal SIGSEGV ...
+\end{code}
+</div>
+
+
+"HeartBleeds"
+-------------
+
+\begin{code} <div/>
+λ> :m + Data.Text Data.Text.Unsafe 
+λ> let t = pack "Kanazawa"
+λ> takeWord16 5 t
+"Kanaz"
+\end{code}
+
+<br>
+
+<div class="fragment"> 
+Memory overflows **leaking secrets**...
+
+<br>
+
+\begin{code} <div/>
+λ> takeWord16 20 t
+"Kanazawa\1912\3148\SOH\NUL\15928\2486\SOH\NUL"
+\end{code}
+</div>
+
+Goal
+----
+
+Extend Hindley-Milner To Prevent More Errors
+
+Liquid Types for Haskell
+========================
+
+LiquidHaskell
+-------------
+
+<br>
+<br>
+
+<div class="fragment">Refine **types** with **predicates**</div>
+
+<br>
+<br>
+
+<div class="fragment">**Expressive** specification & **Automatic** verification</div>
+
+
+Automatic
+---------
+
+[Liquid Types, PLDI 08](http://goto.ucsd.edu/~rjhala/liquid/liquid_types.pdf)
+
+<br>
+
++ Abstract Interpretation (covered briefly...) 
+
++ SMT Solvers 
+
+Expressive
+----------
+
+<br>
+<br>
+
+This talk ...
+
+Try Yourself
+------------
+
+<br>
+
+**google: ** `"liquidhaskell demo"` 
+
+ {#zog} 
+--------
+
+<br>
+<br>
+<br>
+<br>
+
+[[continue]](01_SimpleRefinements.lhs.slides.html)
+
+
+Plan 
+----
+
++ <a href="01_SimpleRefinements.lhs.slides.html" target="_blank">Refinements</a>
++ <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
++ <div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target= "_blank">Higher-Order Functions</a></div>
++ <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements:</a> <a href="06_Inductive.lhs.slides.html" target="_blank">Code</a>, <a href="08_Recursive.lhs.slides.html" target= "_blank">Data</a>,<a href="07_Array.lhs.slides.html" target= "_blank">...</a>,<a href="05_Composition.lhs.slides.html" target= "_blank">...</a></div>
++ <div class="fragment"><a href="09_Laziness.lhs.slides.html" target="_blank">Lazy Evaluation</a></div>
++ <div class="fragment"><a href="10_Termination.lhs.slides.html" target="_blank">Termination</a></div>
++ <div class="fragment"><a href="11_Evaluation.lhs.slides.html" target="_blank">Evaluation</a></div>
++ <div class="fragment"><a href="12_Conclusion.lhs.slides.html" target="_blank">Conclusion</a></div>
+
diff --git a/docs/slides/IHP14/lhs/00_Motivation_Logic.lhs b/docs/slides/IHP14/lhs/00_Motivation_Logic.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/00_Motivation_Logic.lhs
@@ -0,0 +1,136 @@
+ {#asds}
+========
+
+Algorithmic Verification 
+------------------------
+
+
+<br>
+<br>
+
+**Goal**
+
+<br>
+
+Proving program properties *without* writing proofs!
+
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+Algorithmic Verification
+========================
+
+Tension
+-------
+
+<img src="../img/tension0.png" height=300px>
+
+Automation vs. Expressiveness
+
+Tension
+-------
+
+<img src="../img/tension1.png" height=300px>
+
+Extremes: Hindley-Milner vs. CoC
+
+Tension
+-------
+
+<img src="../img/tension2.png" height=300px>
+
+Trading off Automation for Expressiveness
+
+Tension
+-------
+
+<img src="../img/tension3.png" height=300px>
+
+**Goal:** Find a sweet spot?
+
+Program Logics
+--------------
+
+<br>
+
+**Floyd-Hoare** (ESC, Dafny, SLAM/BLAST,...)
+
+<br>
+
++ **Properties:**   Assertions & Pre- and Post-conditions
+
++ **Proofs:**       Verification Conditions proved by SMT
+
++ **Inference:**    Abstract Interpretation
+
+<br>
+
+<div class="fragment"> Automatic but **not** Expressive </div>
+
+
+Program Logics
+--------------
+
+<br>
+
+Automatic but **not** Expressive
+
+<br>
+
++ Rich Data Types ?
+
++ Higher-order functions ?
+
++ Polymorphism ?
+
+
+Liquid Types
+------------
+
+<br>
+
+Generalize Floyd-Hoare Logic with Types
+
+<div class="fragment"> 
+<br>
+
++ **Properties:**  Types + Predicates
+
++ **Proofs:**      Subtyping + Verification Conditions
+
++ **Inference:**   Hindley-Milner + Abstract Interpretation
+
+</div>
+
+<div class="fragment"> 
+  <br>
+  Towards reconciling Automation and Expressiveness
+</div>
+
+Liquid Types
+------------
+
+<br>
+<br>
+
+[[continue]](01_SimpleRefinements.lhs.slides.html)
+
+
+Plan 
+----
+
++ <a href="01_SimpleRefinements.lhs.slides.html" target="_blank">Refinements</a>
++ <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
++ <div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target= "_blank">Higher-Order Functions</a></div>
++ <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements:</a> <a href="06_Inductive.lhs.slides.html" target="_blank">Code</a>, <a href="08_Recursive.lhs.slides.html" target= "_blank">Data</a>,<a href="07_Array.lhs.slides.html" target= "_blank">...</a>,<a href="05_Composition.lhs.slides.html" target= "_blank">...</a></div>
++ <div class="fragment"><a href="09_Laziness.lhs.slides.html" target="_blank">Lazy Evaluation</a></div>
++ <div class="fragment"><a href="10_Termination.lhs.slides.html" target="_blank">Termination</a></div>
++ <div class="fragment"><a href="11_Evaluation.lhs.slides.html" target="_blank">Evaluation</a></div>
++ <div class="fragment"><a href="12_Conclusion.lhs.slides.html" target="_blank">Conclusion</a></div>
+
diff --git a/docs/slides/IHP14/lhs/01_SimpleRefinements.lhs b/docs/slides/IHP14/lhs/01_SimpleRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/01_SimpleRefinements.lhs
@@ -0,0 +1,850 @@
+ {#simplerefinements}
+=======================
+
+Simple Refinement Types
+-----------------------
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+module SimpleRefinements where
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (abs, max)
+
+-- boring haskell type sigs
+zero    :: Int
+zero'   :: Int
+safeDiv :: Int -> Int -> Int
+abs     :: Int -> Int
+nats    :: L Int
+evens   :: L Int
+odds    :: L Int
+range   :: Int -> Int -> L Int
+\end{code}
+
+</div>
+
+
+Simple Refinement Types
+=======================
+
+
+Types + Predicates 
+------------------
+
+
+Example: Integers equal to `0`
+------------------------------
+
+<br>
+
+\begin{code}
+{-@ type Zero = {v:Int | v = 0} @-}
+
+{-@ zero :: Zero @-}
+zero     =  0
+\end{code}
+
+<br>
+
+<div class="fragment">
+Refinement types via special comments `{-@ ... @-}` 
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo</a> 
+</div>
+
+
+
+Refinements Are Predicates
+==========================
+
+From A Decidable Logic
+----------------------
+
+<br> 
+
+1. Expressions
+
+2. Predicates
+
+<br>
+
+<div class="fragment">
+
+**Refinement Logic: QF-UFLIA**
+
+Quant.-Free. Uninterpreted Functions and Linear Arithmetic 
+
+</div>
+
+
+Expressions
+-----------
+
+<br>
+
+\begin{code} <div/> 
+e := x, y, z,...    -- variable
+   | 0, 1, 2,...    -- constant
+   | (e + e)        -- addition
+   | (e - e)        -- subtraction
+   | (c * e)        -- linear multiplication
+   | (f e1 ... en)  -- uninterpreted function
+\end{code}
+
+Predicates
+----------
+
+<br>
+
+\begin{code} <div/>
+p := e           -- atom 
+   | e1 == e2    -- equality
+   | e1 <  e2    -- ordering 
+   | (p && p)    -- and
+   | (p || p)    -- or
+   | (not p)     -- negation
+\end{code}
+
+<br>
+
+
+Refinement Types
+----------------
+
+
+<br>
+
+\begin{code}<div/>
+b := Int 
+   | Bool 
+   | ...         -- base types
+   | a, b, c     -- type variables
+
+t := {x:b | p}   -- refined base 
+   | x:t -> t    -- refined function  
+\end{code}
+
+
+Subtyping Judgment 
+------------------
+
+<br>
+
+$$\boxed{\Gamma \vdash t_1 \preceq t_2}$$
+
+<div class="fragment">
+
+<br>
+
+Where **environment** $\Gamma$ is a sequence of binders
+
+<br>
+
+$$\Gamma \defeq \overline{\bindx{x_i}{t_i}}$$
+
+</div>
+
+Subtyping is Implication
+------------------------
+
+[PVS' Predicate Subtyping](http://pvs.csl.sri.com/papers/subtypes98/tse98.pdf)
+
+<br>
+
+(For **Base** Types ...)
+
+
+
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+$$
+\begin{array}{rl}
+{\mathbf{If\ VC\ is\ Valid}}   & \bigwedge_i P_i \Rightarrow  Q  \Rightarrow R \\
+                & \\
+{\mathbf{Then}} & \overline{\bindx{x_i}{P_i}} \vdash \reft{v}{b}{Q} \subty \reft{v}{v}{R} \\
+\end{array}
+$$ 
+
+
+Example: Natural Numbers
+------------------------
+
+<br>
+
+\begin{code} <div/>  
+        type Nat = {v:Int | 0 <= v}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+$$
+\begin{array}{rcrccll}
+\mathbf{VC\ is\ Valid:} & \True     & \Rightarrow &  v = 0   & \Rightarrow &  0 \leq v & \mbox{(by SMT)} \\
+%                &           &             &          &             &           \\
+\mathbf{So:}      & \emptyset & \vdash      & \Zero  & \subty      & \Nat   &   \\
+\end{array}
+$$
+</div>
+
+<br>
+
+<div class="fragment">
+
+Hence, we can type:
+
+\begin{code}
+{-@ zero' :: Nat @-}
+zero'     =  zero   -- zero :: Zero <: Nat
+\end{code}
+</div>
+
+Contracts: Function Types
+=========================
+
+ {#as}
+------
+
+Pre-Conditions
+--------------
+
+
+<br>
+
+\begin{code}
+safeDiv n d = n `div` d   -- crashes if d==0
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Requires** non-zero input divisor `d`
+
+\begin{code}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+\end{code}
+</div>
+
+<br>
+
+
+<div class="fragment">
+Specify pre-condition as **input type** 
+
+\begin{code}
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{code}
+
+</div>
+
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{code} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{code}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code}
+{-@ bad :: Nat -> Int @-}
+bad n   = 10 `safeDiv` n
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Rejected As** 
+
+$$\bindx{n}{\Nat} \vdash \reftx{v}{v = n} \not \subty \reftx{v}{v \not = 0}$$
+
+</div>
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{code} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{code}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code}
+{-@ ok  :: Nat -> Int @-}
+ok n    = 10 `safeDiv` (n+1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Verifies As** 
+
+$\bindx{n}{\Nat} \vdash \reftx{v}{v = n+1} \subty \reftx{v}{v \not = 0}$
+</div>
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{code} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{code}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code} <div/>
+{-@ ok  :: Nat -> Int @-}
+ok n    = 10 `safeDiv` (n+1)
+\end{code}
+
+<br>
+
+**Verifies As**
+
+$$(0 \leq n) \Rightarrow (v = n+1) \Rightarrow (v \not = 0)$$
+
+
+
+Post-Conditions
+---------------
+
+**Ensures** output is a `Nat` greater than input `x`.
+
+\begin{code}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{code}
+
+<br>
+
+<div class="fragment">
+Specify post-condition as **output type**
+
+\begin{code}
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+**Dependent Function Types**
+
+Outputs *refer to* inputs
+</div>
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{code} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{code}
+
+<br>
+
+Postcondition is checked at **return-site**
+
+<br>
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{code} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{code}
+
+<br>
+
+**Verified As**
+
+<br>
+
+$$\begin{array}{rll}
+\bindx{x}{\Int},\bindx{\_}{0 \leq x}      & \vdash \reftx{v}{v = x}     & \subty \reftx{v}{0 \leq v \wedge x \leq v} \\
+\bindx{x}{\Int},\bindx{\_}{0 \not \leq x} & \vdash \reftx{v}{v = 0 - x} & \subty \reftx{v}{0 \leq v \wedge x \leq v} \\
+\end{array}$$
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{code} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{code}
+
+<br>
+
+**Verified As**
+
+<br>
+
+$$\begin{array}{rll}
+(0 \leq x)      & \Rightarrow (v = x)     & \Rightarrow (0 \leq v \wedge x \leq v) \\
+(0 \not \leq x) & \Rightarrow (v = 0 - x) & \Rightarrow (0 \leq v \wedge x \leq v) \\
+\end{array}$$
+
+
+ {#inference}
+=============
+
+From Checking To Inference
+--------------------------
+
+**So far**
+
+How to **check** code against given signature
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+How to **synthesize** signatures from code
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**2-Phase Process**
+
+1. H-M to synthesize *types*
+2. A-I to synthesize *refinements*  
+
+</div>
+
+<br>
+
+<div class="fragment">Lets quickly look at 2. </div>
+
+
+
+From Checking To Inference
+==========================
+
+
+Recipe
+------
+
+<br>
+
+<div class="fragment">
+
+**Step 1. Templates**
+
+Types with variables $\kvar{}$ for *unknown* refinements
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Step 2. Constraints**
+
+Typecheck templates: VCs $\rightarrow$ Horn constraints over $\kvar{}$
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Step 3. Solve**
+
+Via least-fixpoint over suitable abstract domain
+
+</div>
+
+Step 1. Templates (`abs`)
+-------------------------
+
+<br>
+
+<div class="fragment">
+**Type**
+
+$$\bindx{x}{\Int} \rightarrow \Int$$
+</div>
+
+<br>
+
+<div class="fragment">
+**Template**
+
+$$\ereft{x}{\Int}{\kvar{1}} \rightarrow \reft{v}{\Int}{\kvar{2}}$$
+</div>
+
+Step 2. Constraints (`abs`)
+-------------------------
+
+<br>
+
+Step 2. Constraints (`abs`)
+-------------------------
+
+<br>
+
+**Subtyping Queries**
+
+<br>
+
+$$
+\begin{array}{rll}
+\bindx{x}{\kvar{1}},\bindx{\_}{0 \leq x}      & \vdash \reftx{v}{v = x}     & \subty \reftx{v}{\kvar{2}} \\
+\bindx{x}{\kvar{1}},\bindx{\_}{0 \not \leq x} & \vdash \reftx{v}{v = 0 - x} & \subty \reftx{v}{\kvar{2}} \\
+\end{array}
+$$
+
+Step 2. Constraints (`abs`)
+-------------------------
+
+<br>
+
+**Verification Conditions**
+
+<br>
+
+$$\begin{array}{rll}
+{\kvar{1}} \wedge (0 \leq x)      & \Rightarrow (v = x)     & \Rightarrow \kvar{2} \\
+{\kvar{1}} \wedge (0 \not \leq x) & \Rightarrow (v = 0 - x) & \Rightarrow \kvar{2} \\
+\end{array}$$
+
+
+Step 2. Constraints (`abs`)
+-------------------------
+
+<br>
+
+**Horn Constraints** over $\kvar{}$
+
+<br>
+
+$$\begin{array}{rll}
+{\kvar{1}} \wedge (0 \leq x)      & \Rightarrow (v = x)     & \Rightarrow \kvar{2} \\
+{\kvar{1}} \wedge (0 \not \leq x) & \Rightarrow (v = 0 - x) & \Rightarrow \kvar{2} \\
+\end{array}$$
+
+<br>
+<br>
+
+**Note:** $\kvar{}$ occur positively, hence constraints are monotone.
+
+Step 3. Solve (`abs`)
+---------------------
+
+Least-fixpoint over abstract domain 
+
+<br>
+
+
+<div class="fragment">
+**Predicate Abstraction**
+
+Conjunction of predicates from (finite) ground set $\quals$
+</div>
+
+<br>
+
+<div class="fragment">
+$$\mbox{e.g.}\ \quals \defeq \{ c \sim X \}$$
+
+<br>
+
+$$\begin{array}{ccll}
+  c     & \in & \{0,1,\ldots   \}                & \mbox{program constants} \\
+  X     & \in & \{n,x,v,\ldots \}                & \mbox{program variables} \\
+  \sim  & \in & \{<, \leq, >, \geq, =, \not =\}  & \mbox{comparisons}       \\
+  \end{array}$$
+
+</div>
+
+Step 3. Solve (`abs`)
+---------------------
+
+Least-fixpoint over abstract domain 
+
+<br>
+
+**Predicate Abstraction**
+
+Conjunction of predicates from (finite) ground set $\quals$
+
+<br>
+
++ Obtain $\quals$ via CEGAR
++ Or use other domains
+
+<br>
+
+[[Rybalchenko et al., CAV 2011]](http://goto.ucsd.edu/~rjhala/papers/hmc.html)
+
+
+Recipe Scales Up
+----------------
+
+<br>
+
+**1. Templates** $\rightarrow$ **2. Horn Constraints** $\rightarrow$ **3. Fixpoint**
+
+<br>
+
+<div class="fragment">
++ Define type checker, get inference for free 
+
++ Scales to Data types, HO functions, Polymorphism
+
+</div>
+<br>
+
+<div class="fragment">
+**Key Requirement** 
+
+Refinements belong in abstract domain, e.g. QF-UFLIA
+</div>
+
+
+
+ {#universalinvariants}
+=======================
+
+Types = Universal Invariants
+----------------------------
+
+(Notoriously hard with *pure* SMT)
+
+Types Yield Universal Invariants
+================================
+
+Example: Lists
+--------------
+
+
+<div class="hidden">
+\begin{code}
+infixr `C`
+\end{code}
+</div>
+
+
+<br>
+<br>
+<br>
+
+
+\begin{code}
+data L a = N          -- Empty 
+         | C a (L a)  -- Cons 
+\end{code}
+
+
+<br>
+
+<div class="fragment">
+
+How to **specify** every element in `nats` is non-negative?
+
+\begin{code}
+nats     =  0 `C` 1 `C` 3 `C` N
+\end{code}
+</div>
+
+
+Example: Lists
+--------------
+
+How to **specify** every element in `nats` is non-negative?
+
+\begin{code} <div/>
+nats     =  0 `C` 1 `C` 2 `C` N
+\end{code}
+
+<br>
+
+**Logic**
+
+$$\forall x \in \mathtt{nats}. 0 \leq x$$
+
+<br>
+
+<div class="fragment">
+VCs over **quantified formulas** ... *terrible* for SMT
+</div>
+
+
+Example: Lists
+--------------
+
+How to **specify** every element in `nats` is non-negative?
+
+\begin{code} <div/>
+nats     =  0 `C` 1 `C` 2 `C` N
+\end{code}
+
+<br>
+
+**Refinement Types**
+
+\begin{code}
+{-@ nats :: L Nat @-}
+\end{code}
+
+<br>
+
++ <div class="fragment">Type *implicitly* has quantification</div>
++ <div class="fragment">Sub-typing *eliminates* quantifiers</div>
++ <div class="fragment">Robust verification via *quantifier-free* VCs</div>
+
+Example: Lists
+--------------
+
+How to **verify** ? 
+
+\begin{code} <div/>
+{-@ nats :: L Nat @-}
+nats   = l0
+  where
+    l0 = 0 `C` l1  -- Nat `C` L Nat >>> L Nat
+    l1 = 1 `C` l2  -- Nat `C` L Nat >>> L Nat
+    l2 = 2 `C` l3  -- Nat `C` L Nat >>> L Nat
+    l3 = N         -- L Nat
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if `nats` contained `-2`? 
+
+</div>
+
+<!--
+
+Example: Even/Odd Lists
+-----------------------
+
+\begin{code}
+{-@ type Even = {v:Int | v mod 2 =  0} @-}
+{-@ type Odd  = {v:Int | v mod 2 /= 0} @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ evens :: L Even @-}
+evens     =  0 `C` 2 `C` 4 `C` N
+
+{-@ odds  :: L Odd  @-}
+odds      =  1 `C` 3 `C` 5 `C` N 
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if `evens` contained `1`? 
+</div>
+
+-->
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s **between** `i` and `j`
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s **between** `i` and `j`
+
+<br>
+
+\begin{code}
+{-@ type Btwn I J = {v:_ | (I<=v && v<J)} @-}
+\end{code}
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+<br>
+
+\begin{code}
+{-@ range :: i:Int -> j:Int -> L (Btwn i j) @-}
+range i j            = go i
+  where
+    go n | n < j     = n `C` go (n + 1)  
+         | otherwise = N
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Note:** Type of `go` is automatically inferred
+</div>
+
+
+Example: Indexing Into List
+---------------------------
+
+\begin{code} 
+(!)          :: L a -> Int -> a
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "Oops!"
+\end{code}
+
+<br>
+
+<div class="fragment">(Mouseover to view type of `liquidError`)</div>
+
+<br>
+
+<div class="fragment">To ensure safety, *require* `i` between `0` and list **length**</div>
+
+<br>
+
+<div class="fragment">Need way to **measure** the length of a list [[continue...]](02_Measures.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/IHP14/lhs/02_Measures.lhs b/docs/slides/IHP14/lhs/02_Measures.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/02_Measures.lhs
@@ -0,0 +1,470 @@
+
+ {#measures}
+============
+
+Measuring Data Types
+--------------------
+
+<div class="hidden">
+
+\begin{code}
+module Measures where
+import Prelude hiding ((!!), length)
+import Language.Haskell.Liquid.Prelude
+
+length      :: L a -> Int
+(!)         :: L a -> Int -> a
+insert      :: Ord a => a -> L a -> L a
+insertSort  :: Ord a => [a] -> L a
+
+infixr `C`
+\end{code}
+
+</div>
+
+
+Measuring Data Types 
+====================
+
+Recap
+-----
+
+1. <div class="fragment">**Refinements:** Types + Predicates</div>
+2. <div class="fragment">**Subtyping:** SMT Implication</div>
+
+
+Example: Length of a List 
+-------------------------
+
+Given a type for lists:
+
+<br>
+
+\begin{code}
+data L a = N | C a (L a)
+\end{code}
+
+<div class="fragment">
+<br>
+
+We can define the **length** as:
+
+<br>
+
+\begin{code}
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+\end{code}
+
+</div>
+
+Example: Length of a List 
+-------------------------
+
+\begin{code} <div/>
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+\end{code}
+
+<br>
+
+We **strengthen** data constructor types
+
+<br>
+
+\begin{code} <div/>
+data L a where 
+  N :: {v: L a | (llen v) = 0}
+  C :: a -> t:_ -> {v:_| llen v = 1 + llen t}
+\end{code}
+
+Measures Are Uninterpreted
+--------------------------
+
+\begin{code} <br>
+data L a where 
+  N :: {v: L a | (llen v) = 0}
+  C :: a -> t:_ -> {v:_| llen v = 1 + llen t}
+\end{code}
+
+<br>
+
+`llen` is an **uninterpreted function** in SMT logic
+
+Measures Are Uninterpreted
+--------------------------
+
+<br>
+
+In SMT, [uninterpreted function](http://fm.csl.sri.com/SSFT12/smt-euf-arithmetic.pdf) $f$ obeys **congruence** axiom:
+
+<br>
+
+$$\forall \overline{x}, \overline{y}. \overline{x} = \overline{y} \Rightarrow
+f(\overline{x}) = f(\overline{y})$$
+
+<br>
+
+<div class="fragment">
+Other properties of `llen` asserted when typing **fold** & **unfold**
+</div>
+
+<br>
+
+<div class="fragment">
+Crucial for *efficient*, *decidable* and *predictable* verification.
+</div>
+
+Measures Are Uninterpreted
+--------------------------
+
+Other properties of `llen` asserted when typing **fold** & **unfold**
+
+<br>
+
+<div class="fragment">
+\begin{code}**Fold**<br>
+z = C x y     -- z :: {v | llen v = 1 + llen y}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{code}**Unfold**<br>
+case z of 
+  N     -> e1 -- z :: {v | llen v = 0}
+  C x y -> e2 -- z :: {v | llen v = 1 + llen y}
+\end{code}
+</div>
+
+
+Measured Refinements
+--------------------
+
+Now, we can verify:
+
+<br>
+
+\begin{code}
+{-@ length      :: xs:L a -> (EqLen xs) @-}
+length N        = 0
+length (C _ xs) = 1 + length xs
+\end{code}
+
+<div class="fragment">
+
+<br>
+
+Where `EqLen` is a type alias:
+
+\begin{code}
+{-@ type EqLen Xs = {v:Nat | v = (llen Xs)} @-}
+\end{code}
+
+</div>
+
+List Indexing Redux
+-------------------
+
+We can type list lookup:
+
+\begin{code}
+{-@ (!)      :: xs:L a -> (LtLen xs) -> a @-}
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "never happens!"
+\end{code}
+
+<br>
+
+<div class="fragment">
+Where `LtLen` is a type alias:
+
+\begin{code}
+{-@ type LtLen Xs = {v:Nat | v < (llen Xs)} @-}
+\end{code}
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellMeasure.hs" target= "_blank">Demo:</a> 
+&nbsp; What if we *remove* the precondition?
+
+</div>
+
+Multiple Measures
+-----------------
+
+<br>
+
+Support **many** measures on a type ...
+
+<br>
+
+<div class="fragment">
+... by **conjoining** the constructor refinements.
+</div>
+
+[[Skip...]](#/refined-data-cons)
+
+
+<!--
+
+Multiple Measures
+=================
+
+ {#adasd}
+---------
+
+We allow *many* measures for a type
+
+Ex: List Emptiness 
+------------------
+
+Measure describing whether a `List` is empty 
+
+\begin{code}
+{-@ measure isNull :: (L a) -> Prop
+    isNull (N)      = true
+    isNull (C x xs) = false           @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+We **strengthen** data constructors
+
+\begin{code} <div/> 
+data L a where 
+  N :: {v : L a | (isNull v)}
+  C :: a -> L a -> {v:(L a) | not (isNull v)}
+\end{code}
+
+</div>
+
+Conjoining Refinements
+----------------------
+
+Data constructor refinements are **conjoined** 
+
+\begin{code} <br>
+data L a where 
+  N :: {v:L a |  (llen v) = 0 
+              && (isNull v) }
+  C :: a 
+    -> xs:L a 
+    -> {v:L a |  (llen v) = 1 + (llen xs) 
+              && not (isNull v)          }
+\end{code}
+
+-->
+
+Multiple Measures: Red-Black Trees
+==================================
+
+ {#rbtree}
+----------
+
+<img src="../img/RedBlack.png" height=300px>
+
++ <div class="fragment">**Color:** `Red` nodes have `Black` children</div>
++ <div class="fragment">**Height:** Number of `Black` nodes equal on *all paths*</div>
+<br>
+
+[[Skip...]](#/refined-data-cons)
+
+Basic Type 
+----------
+
+\begin{code} <br>
+data Tree a = Leaf 
+            | Node Color a (Tree a) (Tree a)
+
+data Color  = Red 
+            | Black
+\end{code}
+
+Color Invariant 
+---------------
+
+`Red` nodes have `Black` children
+
+<div class="fragment">
+\begin{code} <br>
+measure isRB        :: Tree a -> Prop
+isRB (Leaf)         = true
+isRB (Node c x l r) = c=Red => (isB l && isB r)
+                      && isRB l && isRB r
+\end{code}
+</div>
+
+<div class="fragment">
+\begin{code} where <br>
+measure isB         :: Tree a -> Prop 
+isB (Leaf)          = true
+isB (Node c x l r)  = c == Black 
+\end{code}
+</div>
+
+*Almost* Color Invariant 
+------------------------
+
+<br>
+
+Color Invariant **except** at root. 
+
+<br>
+
+<div class="fragment">
+\begin{code} <br>
+measure isAlmost        :: Tree a -> Prop
+isAlmost (Leaf)         = true
+isAlmost (Node c x l r) = isRB l && isRB r
+\end{code}
+</div>
+
+
+Height Invariant
+----------------
+
+Number of `Black` nodes equal on **all paths**
+
+<div class="fragment">
+\begin{code} <br>
+measure isBH        :: RBTree a -> Prop
+isBH (Leaf)         =  true
+isBH (Node c x l r) =  bh l = bh r 
+                    && isBH l && isBH r 
+\end{code}
+</div>
+
+<div class="fragment">
+\begin{code} where <br>
+measure bh        :: RBTree a -> Int
+bh (Leaf)         = 0
+bh (Node c x l r) = bh l 
+                  + if c = Red then 0 else 1
+\end{code}
+</div>
+
+Refined Type 
+------------
+
+\begin{code} <br>
+-- Red-Black Trees
+type RBT a  = {v:Tree a | isRB v && isBH v}
+
+-- Almost Red-Black Trees
+type ARBT a = {v:Tree a | isAlmost v && isBH v}
+\end{code}
+
+<br>
+
+[Details](https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/pos/RBTree.hs)
+
+<!--
+
+Measures vs. Index Types
+========================
+
+Decouple Property & Type 
+------------------------
+
+Unlike [indexed types](http://dl.acm.org/citation.cfm?id=270793) ...
+
+<br>
+
+<div class="fragment">
+
++ Measures **decouple** properties from structures
+
++ Support **multiple** properties over structures 
+
++ Enable  **reuse** of structures in different contexts                 
+
+</div>
+
+<br>
+
+<div class="fragment">Invaluable in practice!</div>
+
+-->
+
+Refined Data Constructors
+=========================
+
+ {#refined-data-cons}
+---------------------
+
+Can encode invariants **inside constructors**
+
+<div class="fragment">
+
+<br>
+
+\begin{code}
+{-@ data L a = N
+             | C { x  :: a 
+                 , xs :: L {v:a| x <= v} } @-}
+\end{code}
+</div>
+<br>
+
+<div class="fragment">
+Head `x` is less than **every** element of tail `xs`
+</div>
+
+<br>
+
+<div class="fragment">
+i.e. specifies **increasing** Lists 
+</div>
+
+Increasing Lists 
+----------------
+
+\begin{code} <br>
+data L a where
+  N :: L a
+  C :: x:a -> xs: L {v:a | x <= v} -> L a
+\end{code}
+
+<br>
+
+- <div class="fragment">We **check** property when **folding** `C`</div>
+- <div class="fragment">We **assume** property when **unfolding** `C`</div>
+
+Increasing Lists 
+----------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellInsertSort.hs" target= "_blank">Demo: Insertion Sort</a> (hover for inferred types) 
+
+<br>
+
+\begin{code}
+insertSort = foldr insert N
+
+insert y (x `C` xs) 
+  | y <= x    = y `C` (x `C` xs)
+  | otherwise = x `C` insert y xs
+insert y N    = y `C` N    
+\end{code}
+
+<br>
+
+<div class="fragment">**Problem 1:** What if we need [increasing & decreasing lists](http://web.cecs.pdx.edu/~sheard/Code/QSort.html)?</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. **Measures:** Strengthened Constructors
+    - <div class="fragment">**Decouple** property from structure</div>
+    <!-- - <div class="fragment">**Reuse** structure across *different* properties</div> -->
+
+<br>
+
+<div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target="_blank">[continue]</a></div>
diff --git a/docs/slides/IHP14/lhs/03_HigherOrderFunctions.lhs b/docs/slides/IHP14/lhs/03_HigherOrderFunctions.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/03_HigherOrderFunctions.lhs
@@ -0,0 +1,233 @@
+  {#hofs}
+=========
+
+<div class="hidden">
+\begin{code}
+module Loop (
+    listSum
+  , sumNats
+  ) where
+
+import Prelude
+
+{-@ LIQUID "--no-termination"@-}
+sumNats  :: [Int] -> Int
+add         :: Int -> Int -> Int
+\end{code}
+</div>
+
+Higher-Order Specifications
+---------------------------
+
+Types scale to *Higher-Order* Specifications
+
+<br>
+
+<div class="fragment">
+
++ map
++ fold
++ visitors
++ callbacks
++ ...
+
+</div>
+
+<br>
+
+<div class="fragment">Very difficult with *first-order program logics*</div>
+
+
+Higher Order Specifications
+===========================
+
+Example: Higher Order Loop
+--------------------------
+
+<br>
+
+\begin{code}
+loop :: Int -> Int -> α -> (Int -> α -> α) -> α
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+By subtyping, we infer `f` called with values `(Btwn lo hi)`
+
+
+Example: Summing Lists
+----------------------
+
+\begin{code}
+listSum     :: [Int] -> Int
+listSum xs  = loop 0 n 0 body 
+  where 
+    body    = \i acc -> acc + (xs !! i)
+    n       = length xs
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Function Subtyping** 
+
++ `body` called with `i :: Btwn 0 (llen xs)`
+
++ Hence, indexing with `!!` is safe.
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Loop.hs" target= "_blank">Demo:</a> Tweak `loop` exit condition? 
+</div>
+
+Polymorphic Instantiation
+=========================
+
+ {#poly}
+--------
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{code}
+{-@ sumNats :: [Nat] -> Nat @-}
+sumNats xs  = foldl (+) 0 xs 
+\end{code}
+
+<br>
+
+<div class="fragment">
+\begin{code} Recall 
+foldl :: (α -> β -> α) -> α -> [β] -> α
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+How to **instantiate** `α` and `β` ?
+</div>
+
+Function Subtyping
+------------------
+
+\begin{code}<div/>
+(+) ::  x:Int -> y:Int -> {v:Int|v=x+y} 
+    <:  Nat   -> Nat   -> Nat
+\end{code}
+
+<br>
+
+<div class="fragment">
+Because,
+
+\begin{code}<div/>
+               |- Nat       <: Int  -- Contra
+  x:Nat, y:Nat |- {v = x+y} <: Nat  -- Co
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+Because,
+
+\begin{code}<div/>
+  0<=x && 0<=y && v = x+y   => 0 <= v
+\end{code}
+</div>
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{code} <div/> 
+{-@ sumNats :: [Nat] -> Nat @-}
+sumNats xs  = foldl (+) 0 xs 
+\end{code}
+
+<br>
+
+\begin{code} Where:
+foldl :: (α -> β -> α) -> α -> [β] -> α
+(+)   :: Nat -> Nat -> Nat
+\end{code}
+
+<br>
+
+<div class="fragment">
+Hence, `sumNats` verified by **instantiating** `α,β := Nat`
+</div>
+
+<br>
+
+<div class="fragment">
+`α` is **loop invariant**, instantiation is invariant **synthesis**
+</div>
+
+Instantiation And Inference
+---------------------------
+
+Polymorphism ubiquitous, so inference is critical!
+
+<br>
+
+<div class="fragment">
+**Step 1. Templates** 
+Instantiate with unknown refinements
+
+$$
+\begin{array}{rcl}
+\alpha & \defeq & \reft{v}{\Int}{\kvar{\alpha}}\\
+\beta  & \defeq & \reft{v}{\Int}{\kvar{\beta}}\\
+\end{array}
+$$
+</div>
+
+<br>
+<div class="fragment">
+**Step 2. Horn-Constraints** 
+By type checking the templates
+</div>
+
+<br>
+<div class="fragment">
+**Step 3. Fixpoint** 
+Abstract interpretatn. to get solution for $\kvar{}$
+</div>
+
+
+Iteration Dependence
+--------------------
+
+**Problem:** Cannot use parametric polymorphism to verify
+
+<br>
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+As property only holds after **last iteration** ...
+
+<br>
+
+... cannot instantiate $\alpha \defeq \reft{v}{\Int}{v = n + m}$
+</div>
+
+<br>
+
+<div class="fragment">
+**Problem:** *Iteration-dependent* invariants...? &nbsp; &nbsp; [[Continue]](04_AbstractRefinements.lhs.slides.html)
+</div>
+
diff --git a/docs/slides/IHP14/lhs/04_AbstractRefinements.lhs b/docs/slides/IHP14/lhs/04_AbstractRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/04_AbstractRefinements.lhs
@@ -0,0 +1,385 @@
+  {#abstractrefinements}
+========================
+
+<div class="hidden">
+
+\begin{code}
+module AbstractRefinements where
+
+import Prelude 
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+o, no        :: Int
+maxInt       :: Int -> Int -> Int
+\end{code}
+</div>
+
+
+
+Abstract Refinements
+--------------------
+
+
+
+Abstract Refinements
+====================
+
+Two Problems
+------------
+
+<br>
+<br>
+
+<div class="fragment">
+
+**Problem 1:** 
+
+How to specify increasing *and* decreasing lists?
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Problem 2:** 
+
+How to specify *iteration-dependence* in higher-order functions?
+
+</div>
+
+
+Problem Is Pervasive
+--------------------
+
+Lets distill it to a simple example...
+
+<div class="fragment">
+
+<br>
+
+(First, a few aliases)
+
+<br>
+
+\begin{code}
+{-@ type Odd  = {v:Int | (v mod 2) = 1} @-}
+{-@ type Even = {v:Int | (v mod 2) = 0} @-}
+\end{code}
+
+</div>
+
+
+Example: `maxInt` 
+-----------------
+
+Compute the larger of two `Int`s:
+
+\begin{code} <br> 
+maxInt     :: Int -> Int -> Int 
+maxInt x y = if y <= x then x else y
+\end{code}
+
+
+
+Example: `maxInt` 
+-----------------
+
+Has **many incomparable** refinement types
+
+\begin{code}<br>
+maxInt :: Nat  -> Nat  -> Nat
+maxInt :: Even -> Even -> Even
+maxInt :: Odd  -> Odd  -> Odd 
+\end{code}
+
+<br>
+
+<div class="fragment">Oh no! **Which** one should we use?</div>
+
+
+Refinement Polymorphism 
+-----------------------
+
+`maxInt` returns *one of* its two inputs `x` and `y` 
+
+<div class="fragment">
+
+<div align="center">
+
+<br>
+
+---------   ---   -------------------------------------------
+   **If**    :    the *inputs* satisfy a property  
+
+ **Then**    :    the *output* satisfies that property
+---------   ---   -------------------------------------------
+
+<br>
+
+</div>
+</div>
+
+<div class="fragment">Above holds *for all properties*!</div>
+
+<br>
+
+<div class="fragment"> 
+
+**Need to abstract properties over types**
+
+</div>
+
+<!--
+
+By Type Polymorphism?
+---------------------
+
+\begin{code} <br> 
+max     :: α -> α -> α 
+max x y = if y <= x then x else y
+\end{code}
+
+<div class="fragment"> 
+
+Instantiate `α` at callsites
+
+\begin{code}
+{-@ o :: Odd  @-}
+o = maxInt 3 7     -- α := Odd
+
+{-@ e :: Even @-}
+e = maxInt 2 8     -- α := Even
+\end{code}
+
+</div>
+
+By Type Polymorphism?
+---------------------
+
+\begin{code} <br> 
+max     :: α -> α -> α 
+max x y = if y <= x then x else y
+\end{code}
+
+<br>
+
+But there is a fly in the ointment ...
+
+Polymorphic `max` in Haskell
+----------------------------
+
+\begin{code} In Haskell the type of max is
+max :: (Ord α) => α -> α -> α
+\end{code}
+
+<br>
+
+\begin{code} Could *ignore* the class constraints, instantiate as before...
+{-@ o :: Odd @-}
+o     = max 3 7  -- α := Odd 
+\end{code}
+
+
+Polymorphic `(+)` in Haskell
+----------------------------
+
+\begin{code} ... but this is *unsound*!
+max :: (Ord α) => α -> α -> α
+(+) :: (Num α) => α -> α -> α
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+*Ignoring* class constraints would let us "prove":
+
+\begin{code}
+{-@ no :: Odd @-}
+no     = 3 + 7    -- α := Odd !
+\end{code}
+
+</div>
+
+Type Polymorphism? No.
+----------------------
+
+<div class="fragment">Need to try a bit harder...</div>
+
+-->
+
+Parametric Refinements 
+----------------------
+
+Enable *quantification over refinements* ...
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">Type says: **for any** `p` that is a property of `Int`, </div>
+
+- <div class="fragment">`max` **takes** two `Int`s that satisfy `p`,</div>
+
+- <div class="fragment">`max` **returns** an `Int` that satisfies `p`.</div>
+
+Parametric Refinements 
+----------------------
+
+Enable *quantification over refinements* ...
+
+<br>
+
+\begin{code}<div/>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+[Key idea: ](http://goto.ucsd.edu/~rjhala/papers/abstract_refinement_types.html)
+&nbsp; `Int<p>` &nbsp; is just  &nbsp; $\reft{v}{\Int}{p(v)}$ 
+
+<br>
+
+Abstract Refinement is **uninterpreted function** in SMT logic
+
+Parametric Refinements 
+----------------------
+
+\begin{code}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+**Check Implementation via SMT**
+
+Parametric Refinements 
+----------------------
+
+\begin{code}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+**Check Implementation via SMT**
+
+<br>
+
+$$\begin{array}{rll}
+\ereft{x}{\Int}{p(x)},\ereft{y}{\Int}{p(y)} & \vdash \reftx{v}{v = y} & \subty \reftx{v}{p(v)} \\
+\ereft{x}{\Int}{p(x)},\ereft{y}{\Int}{p(y)} & \vdash \reftx{v}{v = x} & \subty \reftx{v}{p(v)} \\
+\end{array}$$
+
+Parametric Refinements 
+----------------------
+
+\begin{code}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+**Check Implementation via SMT**
+
+<br>
+
+$$\begin{array}{rll}
+{p(x)} \wedge {p(y)} & \Rightarrow {v = y} & \Rightarrow {p(v)} \\
+{p(x)} \wedge {p(y)} & \Rightarrow {v = x} & \Rightarrow {p(v)} \\
+\end{array}$$
+
+
+Using Abstract Refinements
+--------------------------
+
+- <div class="fragment">**When** we call `maxInt` with args with some refinement,</div>
+
+- <div class="fragment">**Then** `p` instantiated with *same* refinement,</div>
+
+- <div class="fragment">**Result** of call will also have *same* concrete refinement.</div>
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ o' :: Odd  @-}
+o' = maxInt 3 7     -- p := \v -> Odd v 
+
+{-@ e' :: Even @-}
+e' = maxInt 2 8     -- p := \v -> Even v 
+\end{code}
+
+</div>
+
+<br>
+
+<div class="fragment">
+Infer **Instantiation** by Liquid Typing 
+
+At call-site, instantiate `p` with unknown $\kvar{p}$ and solve!
+</div>
+
+
+<!--
+
+Using Abstract Refinements
+--------------------------
+
+Or any other property ...
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type RGB = {v:_ | (0 <= v && v < 256)} @-}
+
+{-@ rgb :: RGB @-}
+rgb = maxInt 56 8   -- p := \v -> 0 <= v < 256
+\end{code}
+
+</div>
+
+-->
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. **Abstract Refinements** over Types
+
+<br>
+<br>
+
+<div class="fragment">
+  Abstract Refinements are *very* expressive ... <a href="06_Inductive.lhs.slides.html" target="_blank">[continue]</a>
+</div>
+
diff --git a/docs/slides/IHP14/lhs/05_Composition.lhs b/docs/slides/IHP14/lhs/05_Composition.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/05_Composition.lhs
@@ -0,0 +1,161 @@
+Abstract Refinements {#composition}
+===================================
+
+Very General Mechanism 
+----------------------
+
+**Next:** Lets add parameters...
+
+<div class="hidden">
+\begin{code}
+module Composition where
+
+import Prelude hiding ((.))
+
+plus     :: Int -> Int -> Int
+plus3'   :: Int -> Int
+\end{code}
+</div>
+
+
+Example: `plus`
+---------------
+
+\begin{code}
+{-@ plus :: x:_ -> y:_ -> {v:_ | v=x+y} @-}
+plus x y = x + y
+\end{code}
+
+
+Example: `plus 3` 
+-----------------
+
+<br>
+
+\begin{code}
+{-@ plus3' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3'     = plus 3
+\end{code}
+
+<br>
+
+Easily verified by LiquidHaskell
+
+A Composed Variant
+------------------
+
+Lets define `plus3` by *composition*
+
+A Composition Operator 
+----------------------
+
+\begin{code}
+(#) :: (b -> c) -> (a -> b) -> a -> c
+(#) f g x = f (g x)
+\end{code}
+
+
+`plus3` By Composition
+-----------------------
+
+\begin{code}
+{-@ plus3'' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3''     = plus 1 # plus 2
+\end{code}
+
+<br>
+
+Yikes! Verification *fails*. But why?
+
+<br>
+
+<div class="fragment">(Hover mouse over `#` for a clue)</div>
+
+How to type compose (#) ? 
+-------------------------
+
+This specification is *too weak* <br>
+
+\begin{code} <br>
+(#) :: (b -> c) -> (a -> b) -> (a -> c)
+\end{code}
+
+<br>
+
+Output type does not *relate* `c` with `a`!
+
+How to type compose (.) ?
+-------------------------
+
+Write specification with abstract refinement type:
+
+<br>
+
+\begin{code}
+{-@ (.) :: forall <p :: b->c->Prop, 
+                   q :: a->b->Prop>.
+             f:(x:b -> c<p x>) 
+          -> g:(x:a -> b<q x>) 
+          -> y:a -> exists[z:b<q y>].c<p z>
+ @-}
+(.) f g y = f (g y)
+\end{code}
+
+Using (.) Operator 
+------------------
+
+<br>
+
+\begin{code}
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br>
+
+<div class="fragment">*Verifies!*</div>
+
+
+Using (.) Operator 
+------------------
+
+\begin{code} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br>
+
+LiquidHaskell *instantiates*
+
+- `p` with `\x -> v = x + 1`
+- `q` with `\x -> v = x + 2`
+
+Using (.) Operator 
+------------------
+
+\begin{code} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br> To *infer* that output of `plus3` has type: 
+
+`exists [z:{v = y + 2}].{v = z + 1}`
+
+<div class="fragment">
+
+`<:`
+
+`{v:Int|v=3}`
+</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract:** Refinements over Type Signatures
+    + <div class="fragment">*Dependencies* using refinement parameters</div>
diff --git a/docs/slides/IHP14/lhs/06_Inductive.lhs b/docs/slides/IHP14/lhs/06_Inductive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/06_Inductive.lhs
@@ -0,0 +1,459 @@
+Abstract Refinements {#induction}
+=================================
+
+Induction
+---------
+
+Encoding *induction* with Abstract refinements
+
+<div class="hidden">
+
+\begin{code}
+module Loop where
+import Prelude hiding ((!!), foldr, length, (++))
+-- import Measures
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+
+size  :: L a -> Int
+add   :: Int -> Int -> Int
+loop  :: Int -> Int -> α -> (Int -> α -> α) -> α
+foldr :: (L a -> a -> b -> b) -> b -> L a -> b
+\end{code}
+</div>
+
+Induction
+=========
+
+Example: `loop` redux 
+---------------------
+
+Recall the *higher-order* `loop` 
+
+<br>
+
+\begin{code}
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+**Problem**
+
+- As property only holds after *last* loop iteration...
+
+- ... cannot instantiate `α` with `{v:Int | v = n + m}`
+
+</div>
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+**Problem** 
+
+Need invariant relating *iteration* `i` with *accumulator* `acc`
+
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+**Solution** 
+
+- Abstract Refinement `p :: Int -> a -> Prop`
+
+- `(p i acc)` relates *iteration* `i` with *accumulator* `acc`
+
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+<div class="fragment">
+<div align="center">
+
+------------  ---   ----------------------------
+  **Assume**   :    `out = loop lo hi base f` 
+
+   **Prove**   :    `(p hi out)`
+------------  ---   ----------------------------
+
+</div>
+</div>
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**Base Case:** &nbsp; Initial accumulator `base` satisfies invariant
+
+
+`(p lo base)`   
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**Inductive Step:** &nbsp; `f` *preserves* invariant at `i`
+
+
+`(p i acc) => (p (i+1) (f i acc))`
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**"By Induction"** &nbsp; `out` satisfies invariant at `hi` 
+
+`(p hi out)`
+
+
+Induction in `loop` (by type)
+-----------------------------
+
+Induction is an **abstract refinement type** for `loop` 
+
+<br>
+
+\begin{code}
+{-@ loop :: forall a <p :: Int -> a -> Prop>.
+        lo:Int
+     -> hi:{Int | lo <= hi}
+     -> base:a<p lo>                      
+     -> f:(i:Int -> a<p i> -> a<p (i+1)>) 
+     -> a<p hi>                           @-}
+\end{code}
+
+<br>
+
+Induction in `loop` (by type)
+-----------------------------
+
+`p` is the *index dependent* invariant!
+
+
+\begin{code}<br> 
+p    :: Int -> a -> Prop             -- invt 
+base :: a<p lo>                      -- base 
+f    :: i:Int -> a<p i> -> a<p(i+1)> -- step
+out  :: a<p hi>                      -- goal
+\end{code}
+
+
+
+Using Induction
+---------------
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br>
+
+**Verified** by *instantiating* the abstract refinement of `loop`
+
+`p := \i acc -> acc = i + n`
+
+
+<!--
+
+Using Induction
+---------------
+
+\begin{code} <div/>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br>
+
+Verified by instantiating `p := \i acc -> acc = i + n`
+
+- <div class="fragment">**Base:**  `n = 0 + n`</div>
+
+- <div class="fragment">**Step:**  `acc = i + n  =>  acc + 1 = (i + 1) + n`</div>
+
+- <div class="fragment">**Goal:**  `out = m + n`</div>
+
+-->
+
+Generalizes To Structures 
+-------------------------
+
+Same idea applies for induction over *structures* ...
+
+
+Structural Induction
+====================
+
+Example: Lists
+--------------
+
+<br>
+
+\begin{code}
+data L a = N 
+         | C a (L a)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets write a generic loop over such lists ...
+</div>
+
+Example: `foldr`
+----------------
+
+\begin{code} <br>
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets brace ourselves for the type...
+</div>
+
+Example: `foldr`
+----------------
+
+\begin{code}
+{-@ foldr :: 
+    forall a b <p :: L a -> b -> Prop>. 
+      (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
+    -> b<p N> 
+    -> ys:L a
+    -> b<p ys>                            @-}
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets step through the type...
+</div>
+
+
+`foldr`: Abstract Refinement
+----------------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  ::  b<p ys>                            
+\end{code}
+
+<br>
+
+`(p xs b)` relates `b` with **folded** `xs`
+
+`p :: L a -> b -> Prop`
+
+
+`foldr`: Base Case
+------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+`base` is related to **empty** list `N`
+
+`base :: b<p N>` 
+
+
+
+`foldr`: Ind. Step 
+------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+`step` **extends** relation from `xs` to `C x xs`
+
+`step :: xs:_ -> x:_ -> b<p xs> -> b<p (C x xs)>`
+
+
+`foldr`: Output
+---------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+Hence, relation holds between `out` and **entire input** list `ys`
+
+`out :: b<p ys>`
+
+Using `foldr`: Size
+-------------------
+
+We can now verify <br>
+
+\begin{code}
+{-@ size :: xs:_ -> {v:Int| v = (llen xs)} @-}
+size     = foldr (\_ _ n -> n + 1) 0
+\end{code}
+
+<br>
+
+<div class="fragment">
+by *automatically instantiating*
+
+`p := \xs acc -> acc = (llen xs)`
+</div>
+
+Using `foldr`: Append
+---------------------
+
+We can now verify <br>
+
+\begin{code}
+{-@ (++) :: xs:_ -> ys:_ -> (Cat a xs ys) @-} 
+xs ++ ys = foldr (\_ -> C) ys xs 
+\end{code}
+
+<br>
+
+<div class="fragment">
+where 
+
+\begin{code}
+{-@ type Cat a X Y = 
+    {v:_|(llen v) = (llen X) + (llen Y)} @-}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+By automatically instantiating 
+
+`p := \xs acc -> llen acc = llen xs + llen ys`
+
+</div>
+
+Recap
+-----
+
+Abstract refinements *decouple* **invariant** from **traversal**
+
+<br>
+
+<div class="fragment">**Reusable** specifications for higher-order functions.</div>
+
+<br>
+
+<div class="fragment">**Automatic** checking and instantiation by SMT.</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over Type Signatures
+    + <div class="fragment">**Functions**</div>
+    + <div class="fragment">**Data** <a href="08_Recursive.lhs.slides.html" target="_blank">[continue]</a></div>
+
diff --git a/docs/slides/IHP14/lhs/07_Array.lhs b/docs/slides/IHP14/lhs/07_Array.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/07_Array.lhs
@@ -0,0 +1,405 @@
+Abstract Refinements {#data}
+============================
+
+Recap
+-----
+
+**So far**
+
+Decouple invariants from *functions*
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+Decouple invariants from *data structures*
+</div>
+
+Decouple Invariants From Data {#vector} 
+=======================================
+
+Example: Vectors 
+----------------
+
+<div class="hidden">
+\begin{code}
+module LiquidArray where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume, liquidError)
+
+{-@ LIQUID "--no-termination" @-}
+
+fibMemo   :: Vec Int -> Int -> (Vec Int, Int)
+fastFib   :: Int -> Int
+idv       :: Int -> Vec Int
+axiom_fib :: Int -> Bool
+axiom_fib = undefined
+
+{-@ predicate AxFib I = (fib I) == (if I <= 1 then 1 else fib(I-1) + fib(I-2)) @-}
+\end{code}
+</div>
+
+<div class="fragment">
+
+Implemented as maps from `Int` to `a` 
+
+<br>
+
+\begin{code}
+data Vec a = V (Int -> a)
+\end{code}
+
+</div>
+
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Parameterize type with *two* abstract refinements:
+
+<br>
+
+\begin{code}
+{-@ data Vec a < dom :: Int -> Prop,
+                 rng :: Int -> a -> Prop >
+      = V {a :: i:Int<dom> -> a <rng i>}  @-}
+\end{code}
+
+<br>
+
+- `dom`: *domain* on which `Vec` is *defined* 
+
+- `rng`: *range*  and relationship with *index*
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Diverse `Vec`tors by *instantiating* `dom` and `rng`
+
+<br>
+
+<div class="fragment">
+
+A quick alias for *segments* between `I` and `J`
+
+<br>
+
+\begin{code}
+{-@ predicate Seg V I J = (I <= V && V < J) @-}
+\end{code}
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type IdVec N = Vec <{\v -> (Seg v 0 N)}, 
+                        {\k v -> v=k}> 
+                       Int                  @-}
+\end{code}
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+\begin{code}
+{-@ idv :: n:Nat -> (IdVec n) @-}
+idv n   = V (\k -> if 0 < k && k < n 
+                     then k 
+                     else liquidError "eeks")
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>Whats the problem? How can we fix it?
+</div>
+
+Ex: Zero-Terminated Vectors
+---------------------------
+
+Defined between `[0..N)`, with *last* element equal to `0`:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type ZeroTerm N = 
+     Vec <{\v -> (Seg v 0 N)}, 
+          {\k v -> (k = N-1 => v = 0)}> 
+          Int                             @-}
+\end{code}
+
+</div>
+
+
+Ex: Fibonacci Table 
+-------------------
+
+A vector whose value at index `k` is either 
+
+- `0` (undefined), or, 
+
+- `k`th fibonacci number 
+
+\begin{code}
+{-@ type FibV =  
+     Vec <{\v -> true}, 
+          {\k v -> (v = 0 || v = (fib k))}> 
+          Int                               @-}
+\end{code}
+
+
+Accessing Vectors
+-----------------
+
+Next: lets *abstractly* type `Vec`tor operations, *e.g.* 
+
+<br>
+
+- `empty`
+
+- `set`
+
+- `get`
+
+
+Ex: Empty Vectors
+-----------------
+
+`empty` returns Vector whose domain is `false`
+
+<br>
+
+\begin{code}
+{-@ empty :: forall <p :: Int -> a -> Prop>. 
+               Vec <{v:Int|false}, p> a     @-}
+
+empty     = V $ \_ -> error "empty vector!"
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+What would happen if we changed `false` to `true`?
+</div>
+
+Ex: `get` Key's Value 
+---------------------
+
+- *Input* `key` in *domain*
+
+- *Output* value in *range* related with `k`
+
+\begin{code}
+{-@ get :: forall a <d :: Int -> Prop,  
+                     r :: Int -> a -> Prop>.
+           key:Int <d>
+        -> vec:Vec <d, r> a
+        -> a<r key>                        @-}
+
+get k (V f) = f k
+\end{code}
+
+
+Ex: `set` Key's Value 
+---------------------
+
+- <div class="fragment">Input `key` in *domain*</div>
+
+- <div class="fragment">Input `val` in *range* related with `key`</div>
+
+- <div class="fragment">Input `vec` defined at *domain except at* `key`</div>
+
+- <div class="fragment">Output domain *includes* `key`</div>
+
+Ex: `set` Key's Value 
+---------------------
+
+\begin{code}
+{-@ set :: forall a <d :: Int -> Prop,
+                     r :: Int -> a -> Prop>.
+           key: Int<d> -> val: a<r key>
+        -> vec: Vec<{v:Int<d>| v /= key},r> a
+        -> Vec <d, r> a                     @-}
+set key val (V f) = V $ \k -> if k == key 
+                                then val 
+                                else f key
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+Help! Can you spot and fix the errors? 
+</div>
+
+<!-- INSERT tests/pos/vecloop.lhs here AFTER FIXED -->
+
+Using the Vector API
+--------------------
+
+Memoized Fibonacci
+------------------
+
+Use `Vec` API to write a *memoized* fibonacci function
+
+<br>
+
+<div class="fragment">
+\begin{code} Using the fibonacci table:
+type FibV =  
+     Vec <{\v -> true}, 
+          {\k v -> (v = 0 || v = (fib k))}> 
+          Int                              
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+But wait, what is `fib` ?
+</div>
+
+
+Specifying Fibonacci
+--------------------
+
+`fib` is *uninterpreted* in the refinement logic  
+
+<br>
+
+\begin{code}
+{-@ measure fib :: Int -> Int @-}
+\end{code}
+
+<br>
+
+Specifying Fibonacci
+--------------------
+
+We *axiomatize* the definition of `fib` in SMT ...
+
+\begin{code}<br>
+predicate AxFib I = 
+  (fib I) == if I <= 1 
+               then 1 
+               else fib(I-1) + fib(I-2)
+\end{code}
+
+Specifying Fibonacci
+--------------------
+
+Finally, lift axiom into LiquidHaskell as *ghost function*
+
+<br>
+
+\begin{code}
+{-@ axiom_fib :: 
+      i:_ -> {v:_|((Prop v) <=> (AxFib i))} @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Note:** Recipe for *escaping* SMT limitations
+
+1. *Prove* fact externally
+2. *Use* as ghost function call
+</div>
+
+
+Fast Fibonacci
+--------------
+
+An efficient fibonacci function
+
+<br>
+
+\begin{code}
+{-@ fastFib :: n:Int -> {v:_ | v = (fib n)} @-}
+fastFib n   = snd $ fibMemo (V (\_ -> 0)) n
+\end{code}
+
+<br>
+
+<div class="fragment">
+- `fibMemo` *takes* a table initialized with `0`
+
+- `fibMemo` *returns* a table with `fib` values upto `n`.
+</div>
+
+
+Memoized Fibonacci 
+------------------
+
+\begin{code}
+fibMemo t i 
+  | i <= 1    
+  = (t, liquidAssume (axiom_fib i) 1)
+  | otherwise 
+  = case get i t of   
+     0 -> let (t1,n1) = fibMemo t  (i-1)
+              (t2,n2) = fibMemo t1 (i-2)
+              n       = liquidAssume 
+                        (axiom_fib i) (n1+n2)
+          in (set i n t2,  n)
+     n -> (t, n)
+\end{code}
+
+Memoized Fibonacci 
+------------------
+
+- `fibMemo` *takes* a table initialized with `0`
+- `fibMemo` *returns* a table with `fib` values upto `n`.
+
+<br>
+
+\begin{code}
+{-@ fibMemo :: FibV 
+            -> i:Int 
+            -> (FibV,{v:Int | v = (fib i)}) @-}
+\end{code}
+
+
+Recap
+-----
+
+Created a `Vec` container 
+
+Decoupled *domain* and *range* invariants from *data*
+
+<br>
+
+<div class="fragment">
+
+Previous, special purpose program analyses 
+
+- [Gopan-Reps-Sagiv, POPL 05](link)
+- [J.-McMillan, CAV 07](link)
+- [Logozzo-Cousot-Cousot, POPL 11](link)
+- [Dillig-Dillig, POPL 12](link) 
+- ...
+
+Encoded as instance of abstract refinement types!
+</div>
+
+
+
+
diff --git a/docs/slides/IHP14/lhs/08_Recursive.lhs b/docs/slides/IHP14/lhs/08_Recursive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/08_Recursive.lhs
@@ -0,0 +1,546 @@
+Decouple Invariants From Data {#recursive} 
+==========================================
+
+ {#asd}
+-------
+
+Recursive Structures 
+--------------------
+
+Lets see another example of decoupling...
+
+<div class="hidden">
+\begin{code}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+
+module List (insertSort) where
+
+{-@ LIQUID "--no-termination" @-}
+
+mergeSort     :: Ord a => [a] -> [a]
+insertSort :: (Ord a) => [a] -> L a 
+slist :: L Int
+slist' :: L Int
+iGoUp, iGoDn, iDiff :: [Int]
+infixr `C`
+\end{code}
+</div>
+
+Decouple Invariants From Recursive Data
+=======================================
+
+Recall: Lists
+-------------
+
+\begin{code}
+data L a = N 
+         | C { hd :: a, tl :: L a }
+\end{code}
+
+
+Recall: Refined Constructors 
+----------------------------
+
+Define **increasing** Lists with strengthened constructors:
+
+\begin{code} <br>
+data L a where
+  N :: L a
+  C :: hd:a -> tl: L {v:a | hd <= v} -> L a
+\end{code}
+
+Problem: Decreasing Lists?
+--------------------------
+
+What if we need *both* [increasing *and* decreasing lists?](http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Data-List.html#sort)
+
+<br>
+
+<div class="fragment">
+[Separate (indexed) types](http://web.cecs.pdx.edu/~sheard/Code/QSort.html) get quite complicated ...
+</div>
+
+Abstract That Refinement!
+-------------------------
+
+\begin{code}
+{-@ data L a <p :: a -> a -> Prop>
+      = N 
+      | C { hd :: a, tl :: L <p> a<p hd> } @-}
+\end{code}
+
+<br>
+
+<div class="fragment"> `p` is a **binary relation** between two `a` values</div>
+
+<br>
+
+<div class="fragment"> Definition relates `hd` with **all** the elements of `tl`</div>
+
+<br>
+
+<div class="fragment"> Recursive: `p` holds for **every pair** of elements!</div>
+
+Example
+-------
+
+Consider a list with *three* or more elements 
+
+\begin{code} <br>
+x1 `C` x2 `C` x3 `C` rest :: L <p> a 
+\end{code}
+
+Example: Unfold Once
+--------------------
+
+\begin{code} <br> 
+x1                 :: a
+x2 `C` x3 `C` rest :: L <p> a<p x1> 
+\end{code}
+
+Example: Unfold Twice
+---------------------
+
+\begin{code} <br> 
+x1          :: a
+x2          :: a<p x1>  
+x3 `C` rest :: L <p> a<p x1 && p x2> 
+\end{code}
+
+Example: Unfold Thrice
+----------------------
+
+\begin{code} <br> 
+x1   :: a
+x2   :: a<p x1>  
+x3   :: a<p x1 && p x2>  
+rest :: L <p> a<p x1 && p x2 && p x3> 
+\end{code}
+
+<br>
+
+<div class="fragment">
+Note how `p` holds between **every pair** of elements in the list. 
+</div>
+
+A Concrete Example
+------------------
+
+That was a rather *abstract*!
+
+<br>
+
+How can we *use* fact that `p` holds between *every pair*?
+
+<br>
+
+<div class="fragment">**Instantiate** `p` with a *concrete* refinement</div>
+
+
+Example: Increasing Lists
+-------------------------
+
+**Instantiate** `p` with a *concrete* refinement
+
+<br>
+
+\begin{code}
+{-@ type IncL a = L <{\hd v -> hd <= v}> a @-}
+\end{code}
+
+<br>
+
+<div class="fragment"> Refinement says: &nbsp; `hd` less than **every** `v` in tail,</div>
+
+<br>
+
+<div class="fragment"> i.e., `IncL` denotes **increasing** lists. </div>
+
+Example: Increasing Lists
+-------------------------
+
+LiquidHaskell *verifies* that `slist` is indeed increasing...
+
+\begin{code}
+{-@ slist :: IncL Int @-}
+slist     = 1 `C` 6 `C` 12 `C` N
+\end{code}
+
+<br> 
+
+<div class="fragment">
+
+... and *protests* that `slist'` is not: 
+
+\begin{code}
+{-@ slist' :: IncL Int @-}
+slist' = 6 `C` 1 `C` 12 `C` N
+\end{code}
+</div>
+
+Insertion Sort
+--------------
+
+\begin{code}
+{-@ insertSort :: (Ord a) => [a] -> IncL a @-}
+insertSort     = foldr insert N
+
+insert y N          = y `C` N
+insert y (x `C` xs) 
+  | y < x           = y `C` (x `C` xs)
+  | otherwise       = x `C` insert y xs
+\end{code}
+
+<br>
+
+(Mouseover `insert` to see inferred type.)
+
+Checking GHC Lists
+------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target= "_blank">Demo:</a> 
+Above applies to GHC's List definition:
+
+\begin{code} <br> 
+data [a] <p :: a -> a -> Prop>
+  = [] 
+  | (:) { h :: a, tl :: [a<p h>]<p> }
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Increasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Incs a = [a]<{\h v -> h <= v}> @-}
+
+{-@ iGoUp :: Incs Int @-}
+iGoUp     = [1,2,3]
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Decreasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Decs a = [a]<{\h v -> h >= v}> @-}
+
+{-@ iGoDn :: Decs Int @-}
+iGoDn     = [3,2,1]
+\end{code}
+
+
+Checking GHC Lists
+------------------
+
+Duplicate-free Lists
+
+<br>
+
+\begin{code}
+{-@ type Difs a = [a]<{\h v -> h /= v}> @-}
+
+{-@ iDiff :: Difs Int @-}
+iDiff     = [1,3,2]
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Now we can check all the usual list sorting algorithms 
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target="_blank">Demo:</a> List Sorting
+
+<!-- 
+
+Example: `mergeSort` [1/2]
+--------------------------
+
+\begin{code}
+{-@ mergeSort  :: (Ord a) => [a] -> Incs a @-}
+mergeSort []   = []
+mergeSort [x]  = [x]
+mergeSort xs   = merge xs1' xs2' 
+  where 
+   (xs1, xs2)  = split xs
+   xs1'        = mergeSort xs1
+   xs2'        = mergeSort xs2
+\end{code}
+
+Example: `mergeSort` [2/2]
+--------------------------
+
+\begin{code}
+split (x:y:zs) = (x:xs, y:ys) 
+  where 
+    (xs, ys)   = split zs
+split xs       = (xs, [])
+
+merge xs []    = xs
+merge [] ys    = ys
+merge (x:xs) (y:ys) 
+  | x <= y     = x : merge xs (y:ys)
+  | otherwise  = y : merge (x:xs) ys
+\end{code}
+
+
+
+Example: `Data.List.sort` 
+-------------------------
+
+<br>
+
+GHC's "official" list sorting routine
+
+<br>
+
+Juggling lists of increasing & decreasing lists
+
+
+
+
+Ex: `Data.List.sort` [1/5]
+--------------------------
+
+**Step 1.** Make sequences of increasing & decreasing lists
+
+<br>
+
+\begin{code}
+sequences (a:b:xs)
+  | a `compare` b == GT = descending b [a]  xs
+  | otherwise           = ascending  b (a:) xs
+sequences [x]           = [[x]]
+sequences []            = [[]]
+\end{code}
+
+Ex: `Data.List.sort` [2/5]
+--------------------------
+
+**Step 1.** Make sequences of increasing & decreasing lists
+
+<br>
+
+\begin{code}
+descending a as (b:bs)
+  | a `compare` b == GT 
+  = descending b (a:as) bs
+descending a as bs      
+  = (a:as): sequences bs
+\end{code}
+
+Ex: `Data.List.sort` [3/5]
+--------------------------
+
+**Step 1.** Make sequences of increasing & decreasing lists
+
+<br>
+
+
+\begin{code}
+ascending a as (b:bs)
+  | a `compare` b /= GT 
+  = ascending b (\ys -> as (a:ys)) bs
+ascending a as bs      
+  = as [a]: sequences bs
+\end{code}
+
+Ex: `Data.List.sort` [4/5]
+--------------------------
+
+**Step 2.** Merge sequences
+
+<br>
+
+\begin{code}
+mergeAll [x]        = x
+mergeAll xs         = mergeAll (mergePairs xs)
+
+mergePairs (a:b:xs) = merge a b: mergePairs xs
+mergePairs [x]      = [x]
+mergePairs []       = []
+\end{code}
+
+
+Ex: `Data.List.sort` [5/5]
+--------------------------
+
+Put it all together
+
+<br>
+
+\begin{code}
+{-@ sort :: (Ord a) => [a] -> Incs a  @-}
+sort = mergeAll . sequences
+\end{code}
+
+<br>
+
+<div class="fragment">No other hints or annotations required.</div>
+
+-->
+
+Phew!
+-----
+
+Lets see one last example...
+
+<br>
+<br>
+<br>
+<br>
+
+[[Skip]](#/1/32)
+
+
+Example: Binary Trees
+---------------------
+
+... `Map` from keys of type `k` to values of type `a` 
+
+<br>
+
+<div class="fragment">
+
+Implemented, in `Data.Map` as a binary tree:
+
+<br>
+
+\begin{code}
+data Map k a = Tip
+             | Bin Size k a (Map k a) (Map k a)
+
+type Size    = Int
+\end{code}
+</div>
+
+Two Abstract Refinements
+------------------------
+
+- `l` : relates root `key` with `left`-subtree keys
+- `r` : relates root `key` with `right`-subtree keys
+
+<br>
+
+\begin{code}
+{-@ data Map k a < l :: k -> k -> Prop
+                 , r :: k -> k -> Prop >
+    = Tip
+    | Bin (sz :: Size) (key :: k) (val :: a)
+          (left  :: Map <l,r> (k<l key>) a)
+          (right :: Map <l,r> (k<r key>) a) @-}
+\end{code}
+
+
+Ex: Binary Search Trees
+-----------------------
+
+Keys are *Binary-Search* Ordered
+
+<br>
+
+\begin{code}
+{-@ type BST k a = 
+      Map <{\r v -> v < r }, 
+           {\r v -> v > r }> 
+          k a                   @-}
+\end{code}
+
+Ex: Minimum Heaps 
+-----------------
+
+Root contains *minimum* value
+
+<br>
+
+\begin{code}
+{-@ type MinHeap k a = 
+      Map <{\r v -> r <= v}, 
+           {\r v -> r <= v}> 
+           k a               @-}
+\end{code}
+
+Ex: Maximum Heaps 
+-----------------
+
+Root contains *maximum* value
+
+<br>
+
+\begin{code}
+{-@ type MaxHeap k a = 
+      Map <{\r v -> r >= v}, 
+           {\r v -> r >= v}> 
+           k a               @-}
+\end{code}
+
+
+Example: Data.Map
+-----------------
+
+Standard Key-Value container
+
+<br>
+
+- <div class="fragment">1300+ non-comment lines</div>
+
+- <div class="fragment">`insert`, `split`, `merge`,...</div>
+
+- <div class="fragment">Rotation, Rebalance,...</div>
+
+<br>
+
+<div class="fragment">
+SMT & inference crucial for [verification](https://github.com/ucsd-progsys/liquidhaskell/blob/master/benchmarks/esop2013-submission/Base.hs)
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Map.hs" target="_blank">Demo:</a> Binary Search Maps
+</div>
+
+Recap: Abstract Refinements
+---------------------------
+
+<div class="fragment">
+
+Decouple invariants from **functions**
+
++ `max`
++ `loop`
++ `foldr`
+
+</div>
+
+<div class="fragment">
+Decouple invariants from **data**
+
++ `Vector`
++ `List`
++ `Tree`
+
+</div>
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. **Abstract:** Refinements over functions and data
+5. <div class="fragment">Er, what about Haskell's **lazy evaluation**?</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](09_Laziness.lhs.slides.html)</div>
diff --git a/docs/slides/IHP14/lhs/09_Laziness.lhs b/docs/slides/IHP14/lhs/09_Laziness.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/09_Laziness.lhs
@@ -0,0 +1,272 @@
+ {#laziness}
+============
+
+<div class="hidden">
+\begin{code}
+module Laziness where
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short"          @-}
+
+
+safeDiv :: Int -> Int -> Int
+foo     :: Int -> Int
+-- zero    :: Int 
+-- diverge :: a -> b
+\end{code}
+</div>
+
+
+Lazy Evaluation?
+----------------
+
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+
+
+[[Skip]](11_Evaluation.lhs.slides.html)
+
+Lazy Evaluation
+===============
+
+SMT based Verification
+----------------------
+
+Techniques developed for **strict** languages
+
+<br>
+
+<div class="fragment">
+
+-----------------------   ---   ------------------------------------------
+        **Floyd-Hoare**    :    `ESCJava`, `SpecSharp` ...
+     **Model Checkers**    :    `Slam`, `Blast` ...
+   **Refinement Types**    :    `DML`, `Stardust`, `Sage`, `F7`, `F*`, ...
+-----------------------   ---   ------------------------------------------
+
+</div>
+
+<br>
+
+<div class="fragment">
+Surely soundness carries over to Haskell, right?
+</div>
+
+
+Back To the Beginning
+---------------------
+
+\begin{code}
+{-@ safeDiv :: Int -> {v:Int|v /= 0} -> Int @-}
+safeDiv n 0 = liquidError "div-by-zero!"
+safeDiv n d = n `div` d
+\end{code}
+
+<br>
+
+<div class="fragment">
+Should only call `safeDiv` with **non-zero** values
+</div>
+
+An Innocent Function
+--------------------
+
+`foo` returns a value **strictly less than** input.
+
+<br>
+
+\begin{code} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+\end{code}
+
+LiquidHaskell Lies! 
+-------------------
+
+\begin{code}
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0    
+              a = foo z
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+<div class="fragment">
+Why is this program **deemed safe**?! 
+</div>
+
+
+*Safe* With Eager Eval
+----------------------
+
+\begin{code} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Safe** in Java, ML: program spins away, **never hits** divide-by-zero 
+</div>
+
+*Unsafe* With Lazy Eval
+-----------------------
+
+\begin{code} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+**Unsafe** in Haskell: program skips `foo z` and **hits** divide-by-zero!
+
+Problem: Divergence
+-------------------
+
+What is denoted by:
+
+`e :: {v:Int | P}`
+
+
+<br>
+
+<div class="fragment">
+`e` evaluates to `Int` satisfying `P`  
+</div>
+
+<div class="fragment">
+or
+
+**diverges**! 
+</div>
+
+<div class="fragment">
+<br>
+
+Classical Floyd-Hoare notion of [partial correctness](http://en.wikipedia.org/wiki/Hoare_logic#Partial_and_total_correctness)
+
+</div>
+
+
+
+Problem: Divergence
+-------------------
+
+\begin{code} **Consider** <div/> 
+        {-@ e :: {v : Int | P} @-}
+
+        let x = e in body 
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Eager Evaluation** 
+
+*Can* assume `P(x)` when checking `body`
+</div>
+
+<br>
+
+<div class="fragment">
+**Lazy Evaluation** 
+
+*Cannot* assume `P(x)` when checking `body`
+</div>
+
+Eager vs. Lazy Binders 
+----------------------
+
+\begin{code} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+Inconsistent refinement for `a` is sound for **eager**, unsound for **lazy**
+
+
+Panic! Now what?
+---------------
+
+<div class="fragment">
+**Solution** 
+
+Assign *non-trivial* refinements to *non-diverging* terms!
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Require A Termination Analysis**
+
+Don't worry, its easy...
+
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=TellingLies.hs" target="_blank">Demo:</a> &nbsp; Disable `"--no-termination"` and see what happens!
+</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. **Lazy Evaluation:** Requires Termination
+6. <div class="fragment">**Termination:** via Refinements!</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](10_Termination.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/IHP14/lhs/10_Termination.lhs b/docs/slides/IHP14/lhs/10_Termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/10_Termination.lhs
@@ -0,0 +1,314 @@
+Termination {#termination}
+==========================
+
+
+<div class="hidden">
+\begin{code}
+module Termination where
+
+import Prelude hiding (gcd, mod, map)
+fib :: Int -> Int
+gcd :: Int -> Int -> Int
+infixr `C`
+
+data L a = N | C a (L a)
+
+{-@ invariant {v: (L a) | 0 <= (llen v)} @-}
+
+mod :: Int -> Int -> Int
+mod a b | a - b >  b = mod (a - b) b
+        | a - b <  b = a - b
+        | a - b == b = 0
+
+merge :: Ord a => L a -> L a -> L a
+\end{code}
+</div>
+
+<!--
+
+Dependent != Refinement
+-----------------------
+
+<div class="fragment">**Dependent Types**</div>
+
++ <div class="fragment">*Arbitrary terms* appear inside types</div> 
++ <div class="fragment">Termination ensures well-defined</div>
+
+<br>
+
+<div class="fragment">**Refinement Types**</div>
+
++ <div class="fragment">*Restricted refinements* appear in types</div>
++ <div class="fragment">Termination *not* required ...</div> 
++ <div class="fragment">... except, alas, with *lazy* evaluation!</div>
+
+-->
+
+Refinements & Termination
+-------------------------
+
+<div class="fragment">
+Fortunately, we can ensure termination **using refinements**
+</div>
+
+
+Main Idea
+---------
+
+Recursive calls must be on **smaller** inputs
+
+<br>
+
++ [Turing](http://classes.soe.ucsc.edu/cmps210/Winter11/Papers/turing-1936.pdf)
++ [Sized Types](http://dl.acm.org/citation.cfm?id=240882)
++ [DML](http://dl.acm.org/citation.cfm?id=609232)
++ [Size Change Principle](http://dl.acm.org/citation.cfm?id=360210)
+
+Recur On *Smaller* `Nat` 
+------------------------
+
+<div class="fragment">
+
+**To ensure termination of**
+
+\begin{code} <div/>
+foo   :: Nat -> T
+foo x =  body
+\end{code}
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:Nat | v < x} -> T`
+
+<br>
+
+*i.e.* require recursive calls have `Nat` inputs *smaller than* `x`
+</div>
+
+
+
+Ex: Recur On *Smaller* `Nat` 
+----------------------------
+
+\begin{code}
+{-@ fib  :: Nat -> Nat @-}
+fib 0    = 1
+fib 1    = 1
+fib n    = fib (n-1) + fib (n-2)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Terminates, as both `n-1` and `n-2` are `< n`
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=GCD.hs" target="_blank">Demo:</a> &nbsp; What if we drop the `fib 1` equation? 
+</div>
+
+Refinements Are Essential!
+--------------------------
+
+\begin{code}
+{-@ gcd :: a:Nat -> {b:Nat | b < a} -> Int @-}
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Need refinements to prove `(a mod b) < b` at *recursive* call!
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ mod :: a:Nat 
+        -> b:{v:Nat|(0 < v && v < a)} 
+        -> {v:Nat| v < b}                 @-}
+\end{code}
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{code}<div/>
+foo   :: S -> T
+foo x = body
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Reduce** to `Nat` case...
+</div>
+
+<br>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{code}<div/>
+foo   :: S -> T
+foo x = body
+\end{code}
+
+<br>
+
+Specify a **default measure** `mS :: S -> Int`
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:s | 0 <= (mS v) < (mS x)} -> T`
+</div>
+
+
+Ex: Recur on *smaller* `List`
+-----------------------------
+
+\begin{code} 
+map f N        = N
+map f (C x xs) = (f x) `C` (map f xs) 
+\end{code}
+
+<br>
+
+Terminates using **default** measure `llen` 
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ data L [llen] a = N 
+                    | C { x::a, xs :: L a} @-}
+
+{-@ measure llen :: L a -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)   @-}
+\end{code}
+</div>
+
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of smallness spread across **multiple inputs**?
+
+<br>
+
+\begin{code}
+merge xs@(x `C` xs') ys@(y `C` ys')
+  | x < y     = x `C` merge xs' ys
+  | otherwise = y `C` merge xs ys'
+\end{code}
+
+<br>
+
+<div class="fragment">
+Neither input decreases, but their **sum** does.
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+Neither input decreases, but their **sum** does.
+
+<br>
+
+\begin{code}
+{-@ merge :: Ord a => xs:_ -> ys:_ -> _ 
+          /  [(llen xs) + (llen ys)]     @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+Synthesize **ghost** parameter equal to `[...]`
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+... thereby reducing to decreasing **single parameter** case. 
+
+</div>
+
+Important Extensions 
+--------------------
+
+<br>
+
+<div class="fragment">**Mutual** recursion</div>
+
+<br>
+
+<div class="fragment">**Lexicographic** ordering</div>
+
+<br>
+
+<div class="fragment">Fit easily into our framework ...</div>
+
+Recap
+-----
+
+Main idea: Recursive calls on **smaller** inputs
+
+<br>
+
+<div class="fragment">Use refinements to **check** smaller</div>
+
+<br>
+
+<div class="fragment">Use refinements to **establish** smaller</div>
+
+
+A Curious Circularity
+---------------------
+
+<div class="fragment">Refinements require termination ...</div> 
+
+<br>
+
+<div class="fragment">... Termination requires refinements!</div>
+
+<br>
+
+<div class="fragment"> Meta-theory is tricky, but all ends well.</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. Lazy Evaluation: Requires Termination
+6. **Termination:** via Refinements!
+7. <div class="fragment">**Evaluation:** How good is this in practice?</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](11_Evaluation.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/IHP14/lhs/11_Evaluation.lhs b/docs/slides/IHP14/lhs/11_Evaluation.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/11_Evaluation.lhs
@@ -0,0 +1,92 @@
+ {#ASda}
+========
+
+Evaluation
+----------
+
+
+
+Evaluation
+==========
+
+LiquidHaskell Is For Real
+-------------------------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+<br>
+
+Substantial code bases.
+
+<br>
+
+Complex properties.
+
+<br>
+
+<div class="fragment">Inference is crucial.</div>
+
+
+
+Numbers
+-------
+
+<div align="center">
+
+**Library**                     **LOC**
+---------------------------   ---------
+`Data.List`                         814
+`Data.Set.Splay`                    149
+`Data.Vector.Algorithms`           1219
+`Data.Map.Base`                    1396
+`Data.Text`                        3125
+`Data.Bytestring`                  3501 
+**Total**                     **10224**
+---------------------------   ---------
+
+</div>
+
+Numbers
+-------
+
+<div align="center">
+
+**Library**                     **LOC**     **Time**
+---------------------------   ---------   ----------
+`Data.List`                         814          52s
+`Data.Set.Splay`                    149          26s
+`Data.Vector.Algorithms`           1219         196s 
+`Data.Map.Base`                    1396         247s
+`Data.Text`                        3125         809s
+`Data.Bytestring`                  3501         549s
+**Total**                     **10224**    **1880s**
+---------------------------   ---------   ----------
+
+</div>
+
+
+Termination
+-----------
+
+Proving termination is **easy in practice**.
+
+<br>
+
+- <div class="fragment">`503` recursive functions</div>
+- <div class="fragment">`67%` automatically proved</div>
+- <div class="fragment">`30%` need *witnesses* `/[...]`</div>
+- <div class="fragment">`1`   witness per `100` lines of code</div>
+- <div class="fragment">`20`  *not proven* to terminate</div>
+- <div class="fragment">`12`  *do not* terminate (e.g. top-level `IO` loops)</div>
+- <div class="fragment">`8`   currently *outside scope* of LiquidHaskell</div>
+
+
+<div class="fragment">[[continue...]](12_Conclusion.lhs.slides.html)</div>
+
diff --git a/docs/slides/IHP14/lhs/12_Conclusion.lhs b/docs/slides/IHP14/lhs/12_Conclusion.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/12_Conclusion.lhs
@@ -0,0 +1,127 @@
+ {#ASda}
+========
+
+Conclusion
+----------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+Conclusion
+==========
+
+
+Liquid Types 
+------------
+
+Generalize Program **Logics** via **Types**
+
+<br>
+
+<div class="fragment">Expressive *and* Automatic</div>
+
+
+Liquid Types 
+------------
+
+Generalize Program **Logics** via **Types**
+
+<br>
+
+Expressive *and* Automatic
+
+<br>
+
+**Take Home 1: Inference**
+
++ Typecheck "templates" 
+
++ Abstract Interpretation
+ 
+Liquid Types 
+------------
+
+Generalize Program **Logics** via **Types**
+
+<br>
+
+Expressive *and* Automatic
+
+<br>
+
+**Take Home 2: Uninterpreted Functions**
+
++ Measures for Datatype properties
+
++ Abstract Refinements 
+ 
+Liquid Types 
+------------
+
+Generalize Program **Logics** via **Types**
+
+<br>
+
+Expressive *and* Automatic
+
+<br>
+
+**Take Home 3: Laziness breaks *partial* correctness**
+ 
++ Use refinements prove termination
+
++ Use termination to prove refinements
+
+<!--
+
+Take Home Messages
+------------------
+
+1. <div class="fragment"> **Inference**
+    + Typecheck "templates" 
+    + Abstract Interpretation
+   </div>
+
+
+2. <div class="fragment">**Uninterpreted functions**
+    + Measures for Datatype properties
+    + Abstract Refinements 
+   </div>
+
+3. <div class="fragment">**Laziness breaks *partial* correctness**
+    + Use refinements prove termination
+    + Use termination to prove refinements
+   </div>
+
+
+Future Work
+-----------
+
+<br>
+<br>
+
+- <div class="fragment">Speed</div>
+
+- <div class="fragment">Case Studies</div>
+
+- <div class="fragment">**Error Feedback**</div>
+
+-->
+
+ {#asd}
+=======
+
+Thank You!
+----------
+
+<br>
+
+[`http://goto.ucsd.edu/liquid`](http://goto.ucsd.edu/liquid)
+
+<br>
+
diff --git a/docs/slides/IHP14/lhs/Index.lhs b/docs/slides/IHP14/lhs/Index.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/IHP14/lhs/Index.lhs
@@ -0,0 +1,51 @@
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+
+ {#ASD}
+=======
+
+Liquid Types For Haskell
+------------------------
+
+
+<br>
+<br>
+
+**Ranjit Jhala**
+
+University of California, San Diego
+
+<br>
+<br>
+
+Joint work with: 
+
+N. Vazou, E. Seidel, P. Rondon, D. Vytiniotis, S. Peyton-Jones
+
+<br>
+
+<div class="fragment">
+[[continue]](00_Motivation_Logic.lhs.slides.html)
+</div>
+
+
+Plan 
+----
+
+
++ <a href="00_Motivation_Logic.lhs.slides.html" target="_blank">Motivation</a>
++ <div class="fragment"><a href="01_SimpleRefinements.lhs.slides.html" target="_blank">Refinements</a></div>
++ <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
++ <div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target= "_blank">Higher-Order Functions</a></div>
++ <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements:</a> <a href="06_Inductive.lhs.slides.html" target="_blank">Code</a>, <a href="08_Recursive.lhs.slides.html" target= "_blank">Data</a>,<a href="07_Array.lhs.slides.html" target= "_blank">...</a>,<a href="05_Composition.lhs.slides.html" target= "_blank">...</a></div>
++ <div class="fragment"><a href="09_Laziness.lhs.slides.html" target="_blank">Laziness</a> and <a href="10_Termination.lhs.slides.html" target="_blank">Termination</a></div>
++ <div class="fragment"><a href="11_Evaluation.lhs.slides.html" target="_blank">Evaluation</a></div>
++ <div class="fragment"><a href="12_Conclusion.lhs.slides.html" target="_blank">Conclusion</a></div>
+
diff --git a/docs/slides/LambdaConf15/lhs/01_SimpleRefinements.lhs b/docs/slides/LambdaConf15/lhs/01_SimpleRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/LambdaConf15/lhs/01_SimpleRefinements.lhs
@@ -0,0 +1,457 @@
+ {#simplerefinements}
+=======================
+
+Simple Refinement Types
+-----------------------
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+module SimpleRefinements where
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (abs, max)
+
+-- boring haskell type sigs
+zero    :: Int
+zero'   :: Int
+safeDiv :: Int -> Int -> Int
+abs     :: Int -> Int
+\end{code}
+
+</div>
+
+
+Simple Refinement Types
+=======================
+
+
+Types + Predicates 
+------------------
+
+
+Example: Integers equal to `0`
+------------------------------
+
+<br>
+
+\begin{code}
+{-@ type Zero = {v:Int | v = 0} @-}
+
+{-@ zero :: Zero @-}
+zero     =  0
+\end{code}
+
+<br>
+
+<div class="fragment">
+Refinement types via special comments `{-@ ... @-}` 
+
+<br>
+
+<div class="fragment">
+[DEMO](../hs/000_Refinements.hs)
+
+
+<!-- BEGIN CUT
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo</a> 
+-->
+
+</div>
+
+Refinements Are Predicates
+==========================
+
+From A Decidable Logic
+----------------------
+
+<br> 
+
+1. Expressions
+
+2. Predicates
+
+<br>
+
+<div class="fragment">
+
+**Refinement Logic: QF-UFLIA**
+
+Quant.-Free. Uninterpreted Functions and Linear Arithmetic 
+
+</div>
+
+
+Expressions
+-----------
+
+<br>
+
+\begin{spec} <div/> 
+e := x, y, z,...    -- variable
+   | 0, 1, 2,...    -- constant
+   | (e + e)        -- addition
+   | (e - e)        -- subtraction
+   | (c * e)        -- linear multiplication
+   | (f e1 ... en)  -- uninterpreted function
+\end{spec}
+
+Predicates
+----------
+
+<br>
+
+\begin{spec} <div/>
+p := e           -- atom 
+   | e1 == e2    -- equality
+   | e1 <  e2    -- ordering 
+   | (p && p)    -- and
+   | (p || p)    -- or
+   | (not p)     -- negation
+\end{spec}
+
+<br>
+
+
+Refinement Types
+----------------
+
+
+<br>
+
+\begin{spec}<div/>
+b := Int 
+   | Bool 
+   | ...         -- base types
+   | a, b, c     -- type variables
+
+t := {x:b | p}   -- refined base 
+   | x:t -> t    -- refined function  
+\end{spec}
+
+
+Subtyping Judgment 
+------------------
+
+<br>
+
+$$\boxed{\Gamma \vdash t_1 \preceq t_2}$$
+
+<div class="fragment">
+
+<br>
+
+Where **environment** $\Gamma$ is a sequence of binders
+
+<br>
+
+$$\Gamma \defeq \overline{\bindx{x_i}{t_i}}$$
+
+</div>
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+$$\boxed{\Gamma \vdash t_1 \preceq t_2}$$
+
+
+<br>
+
+[PVS' Predicate Subtyping](http://pvs.csl.sri.com/papers/subtypes98/tse98.pdf)
+
+<br>
+
+(For **Base** Types ...)
+
+
+
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+$$\boxed{\Gamma \vdash t_1 \preceq t_2}$$
+
+
+<br>
+
+$$
+\begin{array}{rl}
+{\mathbf{If\ VC\ is\ Valid}}   & \bigwedge_i P_i \Rightarrow  Q  \Rightarrow R \\
+                & \\
+{\mathbf{Then}} & \overline{\bindx{x_i}{P_i}} \vdash \reft{v}{b}{Q} \subty \reft{v}{b}{R} \\
+\end{array}
+$$ 
+
+
+Example: Natural Numbers
+------------------------
+
+<br>
+
+\begin{spec} <div/>  
+        type Nat = {v:Int | 0 <= v}
+\end{spec}
+
+<br>
+
+<div class="fragment">
+
+$$
+\begin{array}{rcrccll}
+\mathbf{VC\ is\ Valid:} & \True     & \Rightarrow &  v = 0   & \Rightarrow &  0 \leq v & \mbox{(by SMT)} \\
+%                &           &             &          &             &           \\
+\mathbf{So:}      & \emptyset & \vdash      & \Zero  & \subty      & \Nat   &   \\
+\end{array}
+$$
+</div>
+
+<br>
+
+<div class="fragment">
+
+Hence, we can type:
+
+\begin{code}
+{-@ zero' :: Nat @-}
+zero'     =  zero   -- zero :: Zero <: Nat
+\end{code}
+</div>
+
+Contracts: Function Types
+=========================
+
+ {#as}
+------
+
+Pre-Conditions
+--------------
+
+
+<br>
+
+\begin{code}
+safeDiv n d = n `div` d   -- crashes if d==0
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Requires** non-zero input divisor `d`
+
+\begin{code}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+\end{code}
+</div>
+
+<br>
+
+
+<div class="fragment">
+Specify pre-condition as **input type** 
+
+\begin{code}
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{code}
+
+</div>
+
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code}
+{-@ bad :: Nat -> Int @-}
+bad n   = 10 `safeDiv` n
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Rejected As** 
+
+$$\bindx{n}{\Nat} \vdash \reftx{v}{v = n} \not \subty \reftx{v}{v \not = 0}$$
+
+</div>
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{code}
+{-@ ok  :: Nat -> Int @-}
+ok n    = 10 `safeDiv` (n+1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Verifies As** 
+
+$\bindx{n}{\Nat} \vdash \reftx{v}{v = n+1} \subty \reftx{v}{v \not = 0}$
+</div>
+
+Precondition: `safeDiv`
+-----------------------
+
+Specify pre-condition as **input type** 
+
+\begin{spec} <div/>
+{-@ safeDiv :: n:Int -> d:NonZero -> Int @-}
+\end{spec}
+
+<br>
+
+Precondition is checked at **call-site**
+
+\begin{spec} <div/>
+{-@ ok  :: Nat -> Int @-}
+ok n    = 10 `safeDiv` (n+1)
+\end{spec}
+
+<br>
+
+**Verifies As**
+
+$$(0 \leq n) \Rightarrow (v = n+1) \Rightarrow (v \not = 0)$$
+
+
+
+Post-Conditions
+---------------
+
+**Ensures** output is a `Nat` greater than input `x`.
+
+\begin{code}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{code}
+
+<br>
+
+<div class="fragment">
+Specify post-condition as **output type**
+
+\begin{code}
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+**Dependent Function Types**
+
+Outputs *refer to* inputs
+</div>
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+Postcondition is checked at **return-site**
+
+<br>
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+**Verified As**
+
+<br>
+
+$$\begin{array}{rll}
+\bindx{x}{\Int},\bindx{\_}{0 \leq x}      & \vdash \reftx{v}{v = x}     & \subty \reftx{v}{0 \leq v \wedge x \leq v} \\
+\bindx{x}{\Int},\bindx{\_}{0 \not \leq x} & \vdash \reftx{v}{v = 0 - x} & \subty \reftx{v}{0 \leq v \wedge x \leq v} \\
+\end{array}$$
+
+Postcondition: `abs`
+--------------------
+
+Specify post-condition as **output type** 
+
+\begin{spec} <div/>
+{-@ abs :: x:Int -> {v:Nat | x <= v} @-}
+abs x | 0 <= x    = x 
+      | otherwise = 0 - x
+\end{spec}
+
+<br>
+
+**Verified As**
+
+<br>
+
+$$\begin{array}{rll}
+(0 \leq x)      & \Rightarrow (v = x)     & \Rightarrow (0 \leq v \wedge x \leq v) \\
+(0 \not \leq x) & \Rightarrow (v = 0 - x) & \Rightarrow (0 \leq v \wedge x \leq v) \\
+\end{array}$$
+
+
+Recipe Scales Up
+----------------
+
+<br>
+
+<div class="fragment">
+Define type *checker* and get *inference* for free [[PLDI 08]](http://goto.ucsd.edu/~rjhala/papers/liquid_types.pdf)
+</div>
+
+<br>
+
+<div class="fragment">
+Scales to Collections, HOFs, Polymorphism ...
+</div>
+
+<br>
+
+<div class="fragment">
+[DEMO](../hs/001_Refinements.hs)
+
+<br>
+
+[[continue...]](02_Measures.lhs.slides.html)
+
+</div>
diff --git a/docs/slides/NEU14/00_Refinements-blank.hs b/docs/slides/NEU14/00_Refinements-blank.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/00_Refinements-blank.hs
@@ -0,0 +1,182 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module Refinements where
+
+import Prelude hiding (map, foldr, foldr1)
+
+
+-----------------------------------------------------------------------
+-- | 1. Simple Refinement Types
+-----------------------------------------------------------------------
+
+-- Nat
+{-@ type Nat = {v: Int | v >= 0} @-}
+
+-- Pos
+{-@ type Pos = {v: Int | v > 0} @-}
+
+
+-----------------------------------------------------------------------
+-- | 2. Function Contracts: Preconditions & Dead Code 
+-----------------------------------------------------------------------
+
+
+{-@ dead :: {v:String | false} -> a @-}
+dead :: String -> a 
+dead = undefined
+
+-----------------------------------------------------------------------
+-- | 3. Function Contracts: Safe Division 
+-----------------------------------------------------------------------
+
+{-@ divide :: Int -> Pos -> Int @-}
+divide :: Int -> Int -> Int
+divide n 0 = dead "dbz"
+divide n k = n `div` k
+
+
+
+
+-----------------------------------------------------------------------
+-- | 4. Dividing Safely
+-----------------------------------------------------------------------
+
+{-@ foo :: Int -> Nat -> Int @-}
+foo     :: Int -> Int -> Int
+foo x y = if y == 0 then foo x y else divide x y
+
+
+
+-----------------------------------------------------------------------
+-- | 4. Data Types
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+
+
+ 
+-----------------------------------------------------------------------
+-- | 4. A few Higher-Order Functions
+-----------------------------------------------------------------------
+
+{-@ map :: (a -> b) -> xs:_ -> {v:_ | size v = size xs} @-}
+map f N = N
+map f (C x xs) = f x `C` (map f xs)
+
+
+
+-- foldr
+foldr f b N        = b
+foldr f b (C x xs) = f x (foldr f b xs)
+
+-- foldr1
+{-@ foldr1 :: (a -> a -> a) -> {v:List a | size v > 0} -> a @-}
+foldr1 f (C x xs) = foldr f x xs
+foldr1 _ N        = dead "EMPTY!!!"
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 5. Measuring the Size of Data
+-----------------------------------------------------------------------
+
+{-@ measure size @-}
+size :: List a -> Int
+size N        = 0
+size (C x xs) = 1 + size xs 
+
+
+
+-- measures = strengthened constructors
+
+
+
+
+-- data List a where
+--   N :: forall a. {List a | size v = 0}...
+--   C :: forall a. x:a -> xs:List a -> {v:List a | size v = 1 + size xs}
+
+
+
+
+-----------------------------------------------------------------------
+-- | 5. Weighted-Averages 
+-----------------------------------------------------------------------
+
+
+{-@ wtAverage :: {v:List (Pos, Int) | size v > 0} -> Int @-}
+wtAverage :: List (Int, Int) -> Int
+wtAverage wxs = total `divide` weights
+  where
+    total     = foldr1 (+) (map (\(w,x) -> w * x) wxs) 
+    weights   = foldr1 (+) (map (\(w,_) -> w)     wxs) 
+    
+
+
+
+
+
+
+-- Exercise: How would you modify the types to get output `Pos` above? 
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 5. Ordered Lists: Take 1
+-----------------------------------------------------------------------
+
+-- You can do a lot with strengthened constructors
+
+
+-- Ordered Lists
+
+
+{-@ data List a = N | C {x :: a, xs :: List {v:a | x <= v}} @-}
+okList = 1 `C` 2 `C` 4 `C` N
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 6. Sorting Lists 
+-----------------------------------------------------------------------
+
+
+insert x N        = x `C` N
+insert x (C y ys)
+  | x < y         = x `C` (y `C` ys)
+  | otherwise     = y `C` (insert x ys)
+
+
+insertSort []     = N
+insertSort (x:xs) = insert x (insertSort xs)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-- Note that adding ordering BREAKS `map`, but ...
+
+
diff --git a/docs/slides/NEU14/00_Refinements.hs b/docs/slides/NEU14/00_Refinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/00_Refinements.hs
@@ -0,0 +1,124 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--diffcheck"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module Refinements where
+
+import Prelude hiding (map, foldr, foldr1)
+
+
+wtAverage :: List (Int, Int) -> Int
+
+
+-----------------------------------------------------------------------
+-- | 1. Simple Refinement Types
+-----------------------------------------------------------------------
+
+{-@ type Nat = {v:Int | v >= 0} @-}
+{-@ type Pos = {v:Int | v >  0} @-}
+
+
+-----------------------------------------------------------------------
+-- | 2. Function Contracts: Preconditions & Dead Code 
+-----------------------------------------------------------------------
+
+{-@ dead :: {v:_ | false} -> a @-}
+dead msg = error msg
+
+-----------------------------------------------------------------------
+-- | 3. Function Contracts: Safe Division 
+-----------------------------------------------------------------------
+
+
+
+{-@ divide :: _ -> {v:_ | v > 0 } -> Int @-}
+divide     :: Int -> Int -> Int
+divide x 0 = dead 12  -- "divide-by-zero"
+divide x n = x `div` n
+
+
+
+-----------------------------------------------------------------------
+-- | 4. Dividing Safely
+-----------------------------------------------------------------------
+
+
+
+-----------------------------------------------------------------------
+-- | 4. Data Types
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+ 
+-----------------------------------------------------------------------
+-- | 4. Measuring the Size of Data
+-----------------------------------------------------------------------
+
+{-@ measure size @-}
+size          :: List a -> Int
+size (C x xs) = 1 + size xs 
+size N        = 0
+
+-- data List a where
+--   N :: forall a. {v: List a | size v = 0}
+--   C :: forall a. x:a -> xs:List a -> {v: List a | size v = 1 + size xs}
+                
+-----------------------------------------------------------------------
+-- | 5. A few Higher-Order Functions
+-----------------------------------------------------------------------
+
+{-@ map              :: (a -> b) -> xs:List a -> {v: List b | size v = size xs} @-}
+map f (N)            = N
+map f (C x xs)       = C (f x) (map f xs) 
+
+{-@ foldr1           :: (a -> a -> a) -> {v: List a | 0 < size v } -> a @-}
+foldr1 f (C x xs)    = foldr f x xs
+foldr1 f N           = dead "foldr1"
+
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+ 
+
+-----------------------------------------------------------------------
+-- | 5. Weighted-Averages 
+-----------------------------------------------------------------------
+
+{-@ wtAverage :: {v : List (Pos, Pos) | size v > 0} -> Int @-}
+wtAverage wxs = total `divide` weights
+  where
+    total     = sum $ map (\(w, x) -> w * x) wxs
+    weights   = sum $ map (\(w, _) -> w    ) wxs
+    sum       = foldr1 (+)
+
+
+-- | Exercise: How would you modify the types to get output `Pos` above? 
+
+-----------------------------------------------------------------------
+-- | 5. Ordered Lists: Take 1
+-----------------------------------------------------------------------
+
+{- data List a = N | C {x :: a, xs :: List {v:a | x <= v}} @-}
+
+okList :: List Int
+okList = 1 `C` 2 `C` 4 `C` N
+
+-- Note that adding ordering BREAKS `map`...
+
+
+
+{-@ insert         :: _ -> xs:_ -> {v:_ | size v = 1 + size xs} @-}
+insert x N         = x `C` N
+insert x (C y ys)
+  | x <= y         = x `C` y `C` ys
+  | otherwise      = y `C` insert x ys 
+
+
+
+
+{-@ insertSort     :: (Ord a) => xs:[a] -> {v:List a | size v = len xs} @-}
+insertSort []      = N
+insertSort (x:xs)  = insert x (insertSort xs)
diff --git a/docs/slides/NEU14/01_AbstractRefinements-blank.hs b/docs/slides/NEU14/01_AbstractRefinements-blank.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/01_AbstractRefinements-blank.hs
@@ -0,0 +1,212 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module AbstractRefinements (
+    listMax
+  , insertSort
+  , insertSort'
+  ) where
+
+
+import Data.Set hiding (insert, foldr,size) 
+import Prelude hiding (map, foldr)
+
+
+
+-----------------------------------------------------------------------
+-- | 0. Abstract Refinements 
+-----------------------------------------------------------------------
+
+
+-- Warmup: How shall we type listMax?
+
+{-@ listMax  :: forall <p :: Int -> Prop>. {v:[Int<p>] | len v > 0}
+             -> Int<p> @-}
+listMax     :: [Int] -> Int
+listMax xs  = foldr1 max xs 
+
+
+
+-- Lets define a few different subsets of Int
+
+{-@ type Even = {v: Int | v mod 2 = 0} @-}
+{-@ type Odd  = {v: Int | v mod 2 /= 0} @-}
+{-@ type RGB  = {v: Int | 0 <= v && v <= 255}  @-}
+
+
+-- compute the largest of some lists
+
+{-@ xE :: Even @-}
+xE = listMax [0, 1] 
+
+
+
+{-@ xO :: Odd @-}
+xO = listMax [1, 21, 4001, 961] 
+
+
+
+{-@ xR :: RGB @-}
+xR = listMax [1, 21, 41, 61] 
+
+
+-- Why do we get the errors? How do we fix it?
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 1. Abstract Refinement from List's Type 
+-----------------------------------------------------------------------
+
+{-@ data List a <p :: a -> a -> Prop> =
+        N
+      | C { x :: a, xs :: List<p> (a<p x>) }
+  @-}
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 2. Instantiating Abstract Refinements 
+-----------------------------------------------------------------------
+
+
+{-@ type IncrList a = List <{\x1 x2 -> x1 <= x2}> a@-} 
+{-@ type DecrList a = List <{\x1 x2 -> x1 >= x2}> a@-} 
+{-@ type DiffList a = List <{\x1 x2 -> x1 /= x2}> a@-} 
+
+ups, downs  :: List Int
+
+{-@ ups :: IncrList Int @-}
+ups   = 1 `C` 2 `C` 3 `C` N
+
+{-@ downs :: DecrList Int @-}
+downs = 10 `C` 8 `C` 6 `C` N
+
+
+
+
+-----------------------------------------------------------------------
+-- | 3. Insertion Sort: Revisited
+-----------------------------------------------------------------------
+
+{-@ insert         :: _ -> xs:_ -> {v:_ | size v = 1 + size xs} @-}
+insert x N         = x `C` N
+insert x (C y ys)
+  | x <= y         = x `C` y `C` ys
+  | otherwise      = y `C` insert x ys 
+
+
+
+{-@ insertSort      :: xs:List a -> {v:IncrList a | EqSize v xs} @-}
+insertSort N        = N
+insertSort (C x xs) = insert x (insertSort xs)
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 3. Insertion Sort: using a `foldr` 
+-----------------------------------------------------------------------
+
+
+{-@ insertSort' :: xs:List a -> {v:IncrList a | true } @-}
+insertSort' xs = foldr insert N xs 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 4. But, there are limits...
+-----------------------------------------------------------------------
+
+-- how big is the list returned by insertSort' ?
+
+
+-- Hmm. Thats a bummer... How do we type `foldr` to verify the above?
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 5. Induction, as an Abstract Refinement 
+-----------------------------------------------------------------------
+
+
+ifoldr = undefined
+
+{- insertSort' :: xs:List a -> {v:IncrList a | size v = size xs} -}
+
+
+
+
+
+
+
+-----------------------------------------------------------------------
+-- | 6. But can you prove that you've permuted the input?
+-----------------------------------------------------------------------
+
+
+-- Lets reason about the set of elements in a container
+
+-- measure elems
+
+{-@ predicate EqSize X Y = size X = size Y @-}
+
+-- predicate EqElems
+
+
+-----------------------------------------------------------------------
+-- | Old definitions from 00_Refinements.hs
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+{-@ measure size @-}
+size          :: List a -> Int
+size (C x xs) = 1 + size xs 
+size N        = 0
+
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+ 
diff --git a/docs/slides/NEU14/01_AbstractRefinements.hs b/docs/slides/NEU14/01_AbstractRefinements.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/01_AbstractRefinements.hs
@@ -0,0 +1,169 @@
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--no-warnings"    @-}
+{-@ LIQUID "--no-termination" @-}
+
+module AbstractRefinements (
+    listMax
+  , insertSort
+  , insertSort'
+  , insertSort''
+  , insertSort'''
+  ) where
+
+import Data.Set hiding (insert, foldr,size) 
+import Prelude hiding (map, foldr)
+
+listMax     :: [Int] -> Int
+
+-----------------------------------------------------------------------
+-- | 0. Abstract Refinements 
+-----------------------------------------------------------------------
+
+{-@ listMax :: forall <p :: Int -> Prop>. {v:[Int<p>] | len v > 0} -> Int<p> @-} 
+listMax xs  = foldr1 max xs 
+
+
+-- Lets define a few different subsets of Int
+
+{-@ type Even = {v:Int | v mod 2 == 0}      @-}
+{-@ type Odd  = {v:Int | v mod 2 /= 0}      @-}
+{-@ type RGB  = {v:Int | 0 <= v && v < 256} @-}
+
+
+
+{-@ xE :: Even @-}
+xE = listMax [0, 200, 4000, 60] 
+
+
+{-@ xO :: Odd @-}
+xO = listMax [1, 21, 4001, 961] 
+
+
+{-@ xR :: RGB @-}
+xR = listMax [1, 21, 41, 61] 
+
+
+
+-----------------------------------------------------------------------
+-- | 1. Abstract Refinement from List's Type 
+-----------------------------------------------------------------------
+
+
+
+{-@ data List a <p :: a -> a -> Prop> 
+     = N | C {x :: a, xs :: List<p> a<p x>} @-}
+
+
+
+-----------------------------------------------------------------------
+-- | 2. Instantiating Abstract Refinements 
+-----------------------------------------------------------------------
+
+
+
+
+{-@ type IncrList a = List <{\x y -> x <= y}> a @-} 
+{-@ type DecrList a = List <{\x y -> x >= y}> a @-} 
+{-@ type DiffList a = List <{\x y -> x /= y}> a @-} 
+
+{-@ ups   :: IncrList Integer @-}
+ups       = 1 `C` 2 `C` 4 `C` N
+
+{-@ downs :: DecrList Integer @-}
+downs     = 100 `C` 20 `C` 4 `C` N
+
+{-@ diffs :: DiffList Integer @-}
+diffs     = 100 `C` 1000 `C` 10 `C` 1 `C`  N
+
+
+
+-----------------------------------------------------------------------
+-- | 3. Insertion Sort: Revisited
+-----------------------------------------------------------------------
+
+{-@ insert         :: x:_ -> xs:_ -> {v:_ | AddElt v x xs && size v = 1 + size xs} @-}
+insert x N         = x `C` N
+insert x (C y ys)
+  | x <= y         = x `C` y `C` ys
+  | otherwise      = y `C` insert x ys 
+
+
+
+{-@ insertSort      :: xs:List a -> {v:IncrList a | size v = size xs} @-}
+insertSort N        = N
+insertSort (C x xs) = insert x (insertSort xs)
+
+
+
+-----------------------------------------------------------------------
+-- | 3. Insertion Sort: using a `foldr` 
+-----------------------------------------------------------------------
+
+
+
+{-@ insertSort' :: xs:List a -> IncrList a @-}
+insertSort' xs = foldr insert N xs
+
+
+
+
+-----------------------------------------------------------------------
+-- | 4. But, there are limits...
+-----------------------------------------------------------------------
+
+-- but why is this not ok?
+
+{-@ insertSort'' :: xs:List a -> {v:IncrList a | EqSize v xs && EqElem v xs} @-}
+insertSort'' xs   = foldr insert N xs
+
+
+-- Hmm. Thats a bummer... How do we type `foldr` to verify the above?
+
+
+-----------------------------------------------------------------------
+-- | 5. Induction, as an Abstract Refinement 
+-----------------------------------------------------------------------
+
+
+{-@ ifoldr :: forall a b <p :: List a -> b -> Prop>. 
+                 (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
+               -> b<p N> 
+               -> ys:List a
+               -> b<p ys>                            @-}
+ifoldr :: (List a -> a -> b -> b) -> b -> List a -> b
+ifoldr f b N        = b
+ifoldr f b (C x xs) = f xs x (ifoldr f b xs)
+
+
+{-@ insertSort''' :: xs:List a -> {v:IncrList a | EqSize v xs && EqElem v xs} @-}
+insertSort''' xs = ifoldr (\_ -> insert) N xs
+
+
+
+
+-----------------------------------------------------------------------
+-- | Old definitions from 00_Refinements.hs
+-----------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+infixr 9 `C`
+
+{-@ measure size @-}
+size          :: List a -> Int
+size (C x xs) = 1 + size xs 
+size N        = 0
+
+foldr f acc N        = acc
+foldr f acc (C x xs) = f x (foldr f acc xs)
+
+
+{-@ predicate EqSize X Y = size X  = size Y @-}
+{-@ predicate EqElem X Y = elems X = elems Y @-}
+
+{-@ predicate AddElt V X Xs = elems V = Set_cup (Set_sng X) (elems Xs) @-}
+ 
+{-@ measure elems ::List a -> (Set a)
+    elems (N)      = (Set_empty 0)
+    elems (C x xs) = (Set_cup (Set_sng x) (elems xs))
+  @-}
diff --git a/docs/slides/NEU14/02_Termination-blank.hs b/docs/slides/NEU14/02_Termination-blank.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/02_Termination-blank.hs
@@ -0,0 +1,187 @@
+module Termination (fac, tailFac, map, merge) where
+
+import Prelude hiding (gcd, mod, map, repeat, take)
+import Language.Haskell.Liquid.Prelude
+
+
+
+-------------------------------------------------------------------------
+-- | Simple Termination
+-------------------------------------------------------------------------
+
+fac   :: Int -> Int
+fac   = undefined
+
+
+
+
+
+
+
+
+
+
+-------------------------------------------------------------------------
+-- | Semantic Termination
+-------------------------------------------------------------------------
+
+gcd :: Int -> Int -> Int
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+
+
+mod :: Int -> Int -> Int
+mod a b
+  | a - b >  b = mod (a - b) b
+  | a - b <  b = a - b
+  | a - b == b = 0
+
+-------------------------------------------------------------------------
+-- Explicit Metrics #1 
+-------------------------------------------------------------------------
+
+tailFac   :: Int -> Int
+tailFac n = loop 1 n
+
+loop      :: Int -> Int -> Int
+loop      = undefined
+
+         
+
+
+-------------------------------------------------------------------------
+-- Explicit Metrics #2 
+-------------------------------------------------------------------------
+
+range :: Int -> Int -> [Int]
+range lo hi = undefined
+
+
+
+-------------------------------------------------------------------------
+-- | Structural Recursion 
+-------------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+map :: (a -> b) -> List a -> List b
+map = undefined
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{-@ measure size :: List a -> Int
+    size (N)      = 0  
+    size (C x xs) = (1 + size xs)
+  @-}
+
+
+
+
+-------------------------------------------------------------------------
+-- | Default Metrics
+-------------------------------------------------------------------------
+
+
+{-@ data List [size] a = N | C {x :: a, xs :: List a } @-}
+
+
+
+-------------------------------------------------------------------------
+-- | Termination Expressions Metrics
+-------------------------------------------------------------------------
+
+merge :: (Ord a) => List a -> List a -> List a
+merge (C x xs) (C y ys)
+  | x < y      = x `C` merge xs (y `C` ys)
+  | otherwise  = y `C` merge (x `C` xs) ys
+merge _   ys   = ys
+
+
+
+
+
+
+
+
+
+-------------------------------------------------------------------------
+-- | Infinite Streams
+-------------------------------------------------------------------------
+
+{- data List [sz] a <p :: List a -> Prop>
+      = N | C { x  :: a
+              , xs :: List <p> a <<p>>
+              }
+  -}
+
+
+{-@ measure emp  :: (List a) -> Prop
+    emp (N)      = true
+    emp (C x xs) = false
+  @-}
+
+{- type Stream a = {xs: List <{\v -> not (emp v)}> a | not (emp xs)} @-}
+
+{- Lazy repeat @-}
+                 
+{- repeat :: a -> Stream a @-}
+-- repeat   :: a -> List a
+-- repeat x = x `C` repeat x
+
+
+{- take :: Nat -> Stream a -> List a @-}
+-- take  :: Int -> List a -> List a
+-- take 0 _        = N
+-- take n (C x xs) = x `C` take (n-1) xs
+-- take _ N        = liquidError "never happens"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------
+
+
+{-@ invariant {v : List a | 0 <= size v} @-}
+
+
+
+
+
+
+
diff --git a/docs/slides/NEU14/02_Termination.hs b/docs/slides/NEU14/02_Termination.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/02_Termination.hs
@@ -0,0 +1,178 @@
+module Termination where
+
+import Prelude hiding (gcd, mod, map, repeat, take)
+import Language.Haskell.Liquid.Prelude
+
+fac   :: Int -> Int
+tfac  :: Int -> Int -> Int
+map   :: (a -> b) -> List a -> List b
+merge :: (Ord a) => List a -> List a -> List a
+
+
+-------------------------------------------------------------------------
+-- | Simple Termination
+-------------------------------------------------------------------------
+
+{-@ fac :: Nat -> Nat @-}
+fac 0 = 1
+fac 1 = 1
+fac n = n * fac (n-1)
+
+
+
+
+-------------------------------------------------------------------------
+-- | Semantic Termination
+-------------------------------------------------------------------------
+
+{-@ gcd :: a:Nat -> b:{v:Nat | v < a} -> Int @-}
+gcd :: Int -> Int -> Int
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+
+
+{-@ mod :: a:Nat -> b:{v:Nat| ((v < a) && (v > 0))} -> {v:Nat | v < b} @-}
+mod :: Int -> Int -> Int
+mod a b | a - b >  b = mod (a - b) b
+        | a - b <  b = a - b
+        | a - b == b = 0
+
+-------------------------------------------------------------------------
+-- Explicit Metrics #1 
+-------------------------------------------------------------------------
+
+{-@ tfac :: Nat -> n:Nat -> Nat / [n] @-}
+tfac acc 0 = acc
+tfac acc n = tfac (n * acc) (n-1)
+
+
+
+
+-------------------------------------------------------------------------
+-- Explicit Metrics #2 
+-------------------------------------------------------------------------
+
+{-@ range :: lo:Nat -> hi:Nat -> [Nat] / [hi-lo] @-}
+range :: Int -> Int -> [Int]
+range lo hi
+  | lo < hi   = lo : range (lo + 1) hi
+  | otherwise = []
+
+
+
+-------------------------------------------------------------------------
+-- | Structural Recursion 
+-------------------------------------------------------------------------
+
+data List a = N | C a (List a)
+
+{-@ measure sz  :: List a -> Int 
+    sz (C x xs) = 1 + (sz xs)
+    sz (N)      = 0
+  @-}
+
+{-@ map :: (a -> b) -> xs:List a -> (List b) / [sz xs] @-}
+map _ N        = N
+map f (C x xs) = f x `C` map f xs
+
+
+
+-------------------------------------------------------------------------
+-- | Default Metrics
+-------------------------------------------------------------------------
+
+{-@ data List [sz] a = N | C {x :: a, xs :: List a } @-}
+
+map' _ N        = N
+map' f (C x xs) = f x `C` map' f xs
+
+
+
+-------------------------------------------------------------------------
+-- | Termination Expressions Metrics
+-------------------------------------------------------------------------
+
+{-@ merge :: xs:_ -> ys:_ -> _ / [sz xs + sz ys] @-}
+
+merge (C x xs) (C y ys)
+  | x < y      = x `C` merge xs (y `C` ys)
+  | otherwise  = y `C` merge (x `C` xs) ys
+merge _   ys   = ys
+
+
+
+
+
+
+
+
+
+-------------------------------------------------------------------------
+-- | Infinite Streams
+-------------------------------------------------------------------------
+
+{- data List [sz] a <p :: List a -> Prop>
+      = N | C { x  :: a
+              , xs :: List <p> a <<p>>
+              }
+  -}
+
+
+{-@ measure emp  :: (List a) -> Prop
+    emp (N)      = true
+    emp (C x xs) = false
+  @-}
+
+{- type Stream a = {xs: List <{\v -> not (emp v)}> a | not (emp xs)} @-}
+
+{- Lazy repeat @-}
+                 
+{- repeat :: a -> Stream a @-}
+-- repeat   :: a -> List a
+-- repeat x = x `C` repeat x
+
+
+{- take :: Nat -> Stream a -> List a @-}
+-- take  :: Int -> List a -> List a
+-- take 0 _        = N
+-- take n (C x xs) = x `C` take (n-1) xs
+-- take _ N        = liquidError "never happens"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----------------------------------------------------
+
+
+{-@ invariant {v : List a | 0 <= sz v} @-}
+
+
+
+
+
+
+
+
diff --git a/docs/slides/NEU14/AlphaConvert.hs b/docs/slides/NEU14/AlphaConvert.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/AlphaConvert.hs
@@ -0,0 +1,145 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{-@ LIQUID "--fullcheck"      @-}
+{-@ LIQUID "--maxparams=3"    @-}
+
+-- | An example from "A Relational Framework for Higher-Order Shape Analysis",
+--   by Gowtham Kaki Suresh Jagannathan, ICFP 2014.
+
+module AlphaConvert (subst, alpha) where
+
+import Prelude hiding ((++), elem)
+import Data.Set (Set (..))
+import Language.Haskell.Liquid.Prelude   
+
+alpha  :: [Bndr] -> Expr -> Expr 
+subst  :: Expr -> Bndr -> Expr -> Expr
+maxs   :: [Int] -> Int 
+lemma1 :: Int -> [Int] -> Bool
+fresh  :: [Bndr] -> Bndr
+free   :: Expr -> [Bndr]
+
+---------------------------------------------------------------------
+-- | Datatype Definition --------------------------------------------
+---------------------------------------------------------------------
+
+type Bndr 
+  = Int
+
+data Expr 
+  = Var Bndr  
+  | Abs Bndr Expr
+  | App Expr Expr
+
+{-@ measure fv       :: Expr -> (Set Bndr)
+    fv (Var x)       = (Set_sng x)
+    fv (Abs x e)     = (Set_dif (fv e) (Set_sng x))
+    fv (App e a)     = (Set_cup (fv e) (fv a)) 
+  @-}
+
+{-@ measure isAbs    :: Expr -> Prop
+    isAbs (Var v)    = false
+    isAbs (Abs v e)  = true
+    isAbs (App e a)  = false             
+  @-}
+
+{-@ predicate AddV E E2 X E1   = fv E = Set_cup (Set_dif (fv E2) (Set_sng X)) (fv E1) @-}
+{-@ predicate EqV E1 E2        = fv E1 = fv E2                                        @-}
+{-@ predicate Occ X E          = Set_mem X (fv E)                                     @-}
+{-@ predicate Subst E E1 X E2  = if (Occ X E2) then (AddV E E2 X E1) else (EqV E E2)  @-}
+
+----------------------------------------------------------------------------
+-- | Part 5: Capture Avoiding Substitution ---------------------------------
+----------------------------------------------------------------------------
+{-@ subst :: e1:Expr -> x:Bndr -> e2:Expr -> {e:Expr | Subst e e1 x e2} @-} 
+----------------------------------------------------------------------------
+
+subst e1 x e2@(Var y)
+  | x == y                = e1
+  | otherwise             = e2
+
+subst e1 x (App ea eb)    = App ea' eb'
+  where
+    ea'                   = subst e1 x ea
+    eb'                   = subst e1 x eb
+
+subst e1 x e2@(Abs y e)  
+  | x == y                = e2
+  | y `elem` xs           = subst e1 x (alpha xs e2) 
+  | otherwise             = Abs y      (subst e1 x e)
+     where
+      xs                  = free e1 
+
+----------------------------------------------------------------------------
+-- | Part 4: Alpha Conversion ----------------------------------------------
+----------------------------------------------------------------------------
+{-@ alpha :: ys:[Bndr] -> e:{Expr | isAbs e} -> {v:Expr | EqV v e} @-}
+----------------------------------------------------------------------------
+alpha ys (Abs x e) = Abs x' (subst (Var x') x e)
+  where 
+    xs             = free e
+    x'             = fresh (x : ys ++ xs)
+
+alpha _  _         = liquidError "never"
+
+
+----------------------------------------------------------------------------
+-- | Part 3: Fresh Variables -----------------------------------------------
+----------------------------------------------------------------------------
+{-@ fresh :: xs:[Bndr] -> {v:Bndr | NotElem v xs} @-}
+----------------------------------------------------------------------------
+fresh bs = liquidAssert (lemma1 n bs) n
+  where 
+    n    = 1 + maxs bs
+
+{-@ maxs :: xs:_ -> {v:_ | v = maxs xs} @-}
+maxs ([])   = 0
+maxs (x:xs) = if (x > maxs xs) then x else (maxs xs) 
+ 
+ 
+{-@ measure maxs :: [Int] -> Int 
+    maxs ([])   = 0
+    maxs (x:xs) = if (x > maxs xs) then x else (maxs xs) 
+  @-}
+
+{-@ lemma1 :: x:Int -> xs:{[Int] | x > maxs xs} -> {v:Bool | Prop v && NotElem x xs} @-}
+lemma1 _ []     = True 
+lemma1 x (_:ys) = lemma1 x ys 
+
+
+----------------------------------------------------------------------------
+-- | Part 2: Free Variables ------------------------------------------------
+----------------------------------------------------------------------------
+
+----------------------------------------------------------------------------
+{-@ free         :: e:Expr -> {v:[Bndr] | elts v = fv e} @-}
+----------------------------------------------------------------------------
+free (Var x)     = [x]
+free (App e e')  = free e ++ free e'
+free (Abs x e)   = free e \\ x
+
+
+----------------------------------------------------------------------------
+-- | Part I: Sets with Lists -----------------------------------------------
+----------------------------------------------------------------------------
+
+{-@ predicate IsCup X Y Z  = elts X = Set_cup (elts Y) (elts Z)    @-}
+{-@ predicate IsDel X Y Z  = elts X = Set_dif (elts Y) (Set_sng Z) @-}
+{-@ predicate Elem  X Ys   = Set_mem X (elts Ys)                   @-}
+{-@ predicate NotElem X Ys = not (Elem X Ys)                       @-}
+
+{-@ (++)      :: xs:[a] -> ys:[a] -> {v:[a] | IsCup v xs ys}  @-}
+[]     ++ ys  = ys
+(x:xs) ++ ys  = x : (xs ++ ys)
+
+{-@ (\\)      :: (Eq a) => xs:[a] -> y:a -> {v:[a] | IsDel v xs y} @-}
+xs   \\ y     = [x | x <- xs, x /= y]
+
+{-@ elem      :: (Eq a) => x:a -> ys:[a] -> {v:Bool | Prop v <=> Elem x ys} @-}
+elem x []     = False
+elem x (y:ys) = x == y || elem x ys
+ 
+{-@ measure elts :: [a] -> (Set a) 
+    elts ([])    = {v | Set_emp v}
+    elts (x:xs)  = {v | v = Set_cup (Set_sng x) (elts xs) }
+  @-}
diff --git a/docs/slides/NEU14/Eval.hs b/docs/slides/NEU14/Eval.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/Eval.hs
@@ -0,0 +1,51 @@
+{-@ LIQUID "--no-termination" @-}
+
+module Eval (eval) where
+
+import Language.Haskell.Liquid.Prelude (liquidError)
+import Prelude hiding (lookup)
+import Data.Set (Set (..))
+
+type Val  = Int
+
+type Bndr = String 
+
+data Expr = Const Int
+          | Var   Bndr
+          | Plus  Expr Expr
+          | Let   Bndr Expr Expr
+
+type Env  = [(Bndr, Val)]
+
+------------------------------------------------------------------
+{-@ lookup :: x:Bndr -> {v:Env | Set_mem x (vars v)} -> Val @-}
+lookup :: Bndr -> Env -> Val
+---------------------  -------------------------------------------
+lookup x ((y,v):env)   
+  | x == y             = v
+  | otherwise          = lookup x env
+lookup x []            = liquidError "Unbound Variable"
+
+------------------------------------------------------------------
+{-@ eval :: g:Env -> ClosedExpr g -> Val @-}
+------------------------------------------------------------------
+eval env (Const i)     = i
+eval env (Var x)       = lookup x env 
+eval env (Plus e1 e2)  = eval env e1 + eval env e2 
+eval env (Let x e1 e2) = eval env' e2 
+  where 
+    env'               = (x, eval env e1) : env
+
+{-@ type ClosedExpr G  = {v:Expr | Set_sub (free v) (vars G)} @-}
+
+{-@ measure vars :: Env -> (Set Bndr)
+    vars ([])    = (Set_empty 0)
+    vars (b:env) = (Set_cup (Set_sng (fst b)) (vars env))
+  @-}
+
+{-@ measure free       :: Expr -> (Set Bndr) 
+    free (Const i)     = (Set_empty 0)
+    free (Var x)       = (Set_sng x) 
+    free (Plus e1 e2)  = (Set_cup (free e1) (free e2))
+    free (Let x e1 e2) = (Set_cup (free e1) (Set_dif (free e2) (Set_sng x)))
+  @-}
diff --git a/docs/slides/NEU14/RBTree.hs b/docs/slides/NEU14/RBTree.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/NEU14/RBTree.hs
@@ -0,0 +1,209 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--diff"           @-}
+
+module Foo where
+
+import Language.Haskell.Liquid.Prelude
+
+data RBTree a = Leaf 
+              | Node Color a !(RBTree a) !(RBTree a)
+              deriving (Show)
+
+data Color = B -- ^ Black
+           | R -- ^ Red
+           deriving (Eq,Show)
+
+---------------------------------------------------------------------------
+-- | Add an element -------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ add :: (Ord a) => a -> RBT a -> RBT a @-}
+add x s = makeBlack (ins x s)
+
+{-@ ins :: (Ord a) => a -> t:RBT a -> {v: ARBTN a {bh t} | IsB t => isRB v} @-}
+ins kx Leaf             = Node R kx Leaf Leaf
+ins kx s@(Node B x l r) = case compare kx x of
+                            LT -> let t = lbal x (ins kx l) r in t 
+                            GT -> let t = rbal x l (ins kx r) in t 
+                            EQ -> s
+ins kx s@(Node R x l r) = case compare kx x of
+                            LT -> Node R x (ins kx l) r
+                            GT -> Node R x l (ins kx r)
+                            EQ -> s
+
+---------------------------------------------------------------------------
+-- | Delete an element ----------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ remove :: (Ord a) => a -> RBT a -> RBT a @-}
+remove x t = makeBlack (del x t)
+
+{-@ predicate HDel T V = bh V = if (isB T) then (bh T) - 1 else bh T @-}
+
+{-@ del              :: (Ord a) => a -> t:RBT a -> {v:ARBT a | HDel t v && (isB t || isRB v)} @-}
+del x Leaf           = Leaf
+del x (Node _ y a b) = case compare x y of
+   EQ -> append y a b 
+   LT -> case a of
+           Leaf         -> Node R y Leaf b
+           Node B _ _ _ -> lbalS y (del x a) b
+           _            -> let t = Node R y (del x a) b in t 
+   GT -> case b of
+           Leaf         -> Node R y a Leaf 
+           Node B _ _ _ -> rbalS y a (del x b)
+           _            -> Node R y a (del x b)
+
+{-@ append :: y:a -> l:RBT {v:a | v < y} -> r:RBTN {v:a | y < v} {bh l} -> ARBT2 a l r @-}
+append :: a -> RBTree a -> RBTree a -> RBTree a
+append _ Leaf r                               = r
+append _ l Leaf                               = l
+append piv (Node R lx ll lr) (Node R rx rl rr)  = case append piv lr rl of 
+                                                    Node R x lr' rl' -> Node R x (Node R lx ll lr') (Node R rx rl' rr)
+                                                    lrl              -> Node R lx ll (Node R rx lrl rr)
+append piv (Node B lx ll lr) (Node B rx rl rr)  = case append piv lr rl of 
+                                                    Node R x lr' rl' -> Node R x (Node B lx ll lr') (Node B rx rl' rr)
+                                                    lrl              -> lbalS lx ll (Node B rx lrl rr)
+append piv l@(Node B _ _ _) (Node R rx rl rr)   = Node R rx (append piv l rl) rr
+append piv l@(Node R lx ll lr) r@(Node B _ _ _) = Node R lx ll (append piv lr r)
+
+---------------------------------------------------------------------------
+-- | Delete Minimum Element -----------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ deleteMin            :: RBT a -> RBT a @-}
+deleteMin (Leaf)         = Leaf
+deleteMin (Node _ x l r) = makeBlack t
+  where 
+    (_, t)               = deleteMin' x l r
+
+
+{-@ deleteMin'                   :: k:a -> l:RBT {v:a | v < k} -> r:RBTN {v:a | k < v} {bh l} -> (a, ARBT2 a l r) @-}
+deleteMin' k Leaf r              = (k, r)
+deleteMin' x (Node R lx ll lr) r = (k, Node R x l' r)   where (k, l') = deleteMin' lx ll lr 
+deleteMin' x (Node B lx ll lr) r = (k, lbalS x l' r )   where (k, l') = deleteMin' lx ll lr 
+
+---------------------------------------------------------------------------
+-- | Rotations ------------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ lbalS                             :: k:a -> l:ARBT {v:a | v < k} -> r:RBTN {v:a | k < v} {1 + bh l} -> {v: ARBTN a {1 + bh l} | IsB r => isRB v} @-}
+lbalS k (Node R x a b) r              = Node R k (Node B x a b) r
+lbalS k l (Node B y a b)              = let t = rbal k l (Node R y a b) in t 
+lbalS k l (Node R z (Node B y a b) c) = Node R y (Node B k l a) (rbal z b (makeRed c))
+lbalS k l r                           = liquidError "nein"
+
+{-@ rbalS                             :: k:a -> l:RBT {v:a | v < k} -> r:ARBTN {v:a | k < v} {bh l - 1} -> {v: ARBTN a {bh l} | IsB l => isRB v} @-}
+rbalS k l (Node R y b c)              = Node R k l (Node B y b c)
+rbalS k (Node B x a b) r              = let t = lbal k (Node R x a b) r  in t 
+rbalS k (Node R x a (Node B y b c)) r = Node R y (lbal x (makeRed a) b) (Node B k c r)
+rbalS k l r                           = liquidError "nein"
+
+{-@ lbal                              :: k:a -> l:ARBT {v:a | v < k} -> RBTN {v:a | k < v} {bh l} -> RBTN a {1 + bh l} @-}
+lbal k (Node R y (Node R x a b) c) r  = Node R y (Node B x a b) (Node B k c r)
+lbal k (Node R x a (Node R y b c)) r  = Node R y (Node B x a b) (Node B k c r)
+lbal k l r                            = Node B k l r
+
+{-@ rbal                              :: k:a -> l:RBT {v:a | v < k} -> ARBTN {v:a | k < v} {bh l} -> RBTN a {1 + bh l} @-}
+rbal x a (Node R y b (Node R z c d))  = Node R y (Node B x a b) (Node B z c d)
+rbal x a (Node R z (Node R y b c) d)  = Node R y (Node B x a b) (Node B z c d)
+rbal x l r                            = Node B x l r
+
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-@ type BlackRBT a = {v: RBT a | IsB v && bh v > 0} @-}
+
+{-@ makeRed :: l:BlackRBT a -> ARBTN a {bh l - 1} @-}
+makeRed (Node B x l r) = Node R x l r
+makeRed _              = liquidError "nein"
+
+{-@ makeBlack :: ARBT a -> RBT a @-}
+makeBlack Leaf           = Leaf
+makeBlack (Node _ x l r) = Node B x l r
+
+---------------------------------------------------------------------------
+-- | Specifications -------------------------------------------------------
+---------------------------------------------------------------------------
+
+-- | Red-Black Trees
+
+{-@ type RBT a    = {v: ORBT a | isRB v && isBH v } @-}
+{-@ type RBTN a N = {v: RBT a  | bh v = N }         @-}
+
+-- | Invariant 1: Binary Search Ordering 
+
+{-@ data RBTree a <l :: a -> a -> Prop, r :: a -> a -> Prop>
+            = Leaf
+            | Node (c    :: Color)
+                   (key  :: a)
+                   (left :: RBTree <l, r> (a <l key>))
+                   (left :: RBTree <l, r> (a <r key>))
+  @-}
+
+{-@ type ORBT a = RBTree <{\root v -> v < root }, {\root v -> v > root}> a @-}
+
+-- | Invariant 2: Black Height Same on All Paths 
+
+{-@ measure isBH        :: RBTree a -> Prop
+    isBH (Leaf)         = true
+    isBH (Node c x l r) = (isBH l && isBH r && bh l = bh r)
+  @-}
+
+{-@ measure bh        :: RBTree a -> Int
+    bh (Leaf)         = 0
+    bh (Node c x l r) = bh l + if (c == R) then 0 else 1 
+  @-}
+
+-- | Invariant 3: Red Nodes have Black Children
+
+{-@ measure isRB        :: RBTree a -> Prop
+    isRB (Leaf)         = true
+    isRB (Node c x l r) = isRB l && isRB r && (c == R => (IsB l && IsB r))
+  @-}
+
+{-@ measure col         :: RBTree a -> Color
+    col (Node c x l r)  = c
+    col (Leaf)          = B
+  @-}
+
+{-@ measure isB        :: RBTree a -> Prop
+    isB (Leaf)         = false
+    isB (Node c x l r) = c == B 
+  @-}
+
+{-@ predicate IsB T = not (col T == R) @-}
+
+--------------------------------------------------------------------------
+-- | Auxiliary Specifications --------------------------------------------
+--------------------------------------------------------------------------
+
+-- | Almost Red-Black Trees
+
+{-@ measure isARB        :: (RBTree a) -> Prop
+    isARB (Leaf)         = true 
+    isARB (Node c x l r) = (isRB l && isRB r)
+  @-}
+
+
+-- | Conditionally Red-Black Tree
+
+{-@ type ARBT2 a L R = {v:ARBTN a {bh L} | (IsB L && IsB R) => isRB v} @-}
+{-@ type ARBT a      = {v: ORBT a | isARB v && isBH v} @-}
+{-@ type ARBTN a N   = {v: ARBT a | bh v = N }         @-}
+
+
+-------------------------------------------------------------------------------
+-- Auxiliary Invariants -------------------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ predicate Invs V = Inv1 V && Inv2 V && Inv3 V   @-}
+{-@ predicate Inv1 V = (isARB V && IsB V) => isRB V @-}
+{-@ predicate Inv2 V = isRB v => isARB v            @-}
+{-@ predicate Inv3 V = 0 <= bh v                    @-}
+{-@ invariant {v: Color | v = R || v = B}           @-}
+{-@ invariant {v: RBTree a | Invs v}                @-}
+
+{-@ inv :: RBTree a -> {v:RBTree a | Invs v}        @-}
+inv Leaf           = Leaf
+inv (Node c x l r) = Node c x (inv l) (inv r)
diff --git a/docs/slides/flops14/Makefile b/docs/slides/flops14/Makefile
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/Makefile
@@ -0,0 +1,73 @@
+####################################################################
+SERVERHOME=nvazou@goto.ucsd.edu:~/public_html/liquidtutorial/
+RJSERVER=rjhala@goto.ucsd.edu:~/public_html/liquid/haskell/plpv/lhs/
+####################################################################
+
+# REVEAL=$(PANDOC) -t revealjs -V revealjs-url=../_support/reveal -V theme=serif
+
+REVEAL=pandoc \
+	   --from=markdown\
+	   --to=html5                           \
+	   --standalone                         \
+	   --mathjax \
+	   --section-divs                       \
+	   --template=_support/template.reveal  \
+	   --variable reveal=../_support/reveal
+
+PANDOC=pandoc --columns=80  -s --mathjax --slide-level=2
+SLIDY=$(PANDOC) -t slidy
+DZSLIDES=$(PANDOC) --highlight-style tango --css=slides.css -w dzslides
+HANDOUT=$(PANDOC) --highlight-style tango --css=text.css -w html5
+WEBTEX=$(PANDOC) -s --webtex -i -t slidy
+BEAMER=pandoc -t beamer
+LIQUID=liquid --short-names 
+
+mdObjects   := $(patsubst %.lhs,%.lhs.markdown,$(wildcard lhs/*.lhs))
+htmlObjects := $(patsubst %.lhs,%.lhs.slides.html,$(wildcard lhs/*.lhs))
+pdfObjects  := $(patsubst %.lhs,%.lhs.slides.pdf,$(wildcard lhs/*.lhs))
+
+####################################################################
+
+
+all: slides 
+
+one: $(mdObjects)
+	$(REVEAL) lhs/.liquid/00_Index.lhs.markdown > lhs/index.html
+
+tut: $(mdObjects)
+	$(REVEAL) lhs/.liquid/*.markdown > lhs/tutorial.html 
+
+
+slides: $(htmlObjects)
+
+
+pdfslides: $(pdfObjects)
+
+plpv: slides
+	scp lhs/*.html $(RJSERVER)
+
+lhs/.liquid/%.lhs.markdown: lhs/%.lhs
+	-$(LIQUID) $?
+
+lhs/%.lhs.slides.html: lhs/.liquid/%.lhs.markdown
+	$(REVEAL) $? -o $@ 
+
+lhs/%.lhs.slides.pdf: lhs/.liquid/%.lhs.markdown
+	$(BEAMER) $? -o $@
+
+
+copy:
+	cp lhs/*lhs.html html/
+	cp lhs/*lhs.slides.html html/
+	cp css/*.css html/
+	cp -r fonts html/
+	cp index.html html/
+	cp Benchmarks.html html/
+
+clean:
+	cd lhs/ && ../cleanup && cd ../
+#	cd html/ && rm -rf * && cd ../
+#	cp index.html html/
+
+upload: 
+	scp -r html/* $(SERVERHOME)
diff --git a/docs/slides/flops14/TODO.md b/docs/slides/flops14/TODO.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/TODO.md
@@ -0,0 +1,21 @@
+Timing
+------
+
+[4]  Motivation 
+                        <------------------ 4 
+[8]  Refinements
+                        <------------------ 12 
+[8]  Measures
+                        <------------------ 20 
+[8]  Higher-Order Functions
+                        <------------------ 28 
+[5] Abstract Refinements: 
+[8]   Code, 
+[8]   Data,...,...
+                        <------------------ 49
+[4] Lazy Evaluation
+[5] Termination
+                        <------------------ 58 
+[3] Evaluation
+                        <------------------ 61 
+
diff --git a/docs/slides/flops14/_support/liquid.css b/docs/slides/flops14/_support/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/liquid.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/flops14/_support/reveal/LICENSE b/docs/slides/flops14/_support/reveal/LICENSE
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/docs/slides/flops14/_support/reveal/README.md b/docs/slides/flops14/_support/reveal/README.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/README.md
@@ -0,0 +1,226 @@
+# reveal.js
+
+A framework for easily creating beautiful presentations using HTML. [Check out the live demo](http://lab.hakim.se/reveal-js/).
+
+reveal.js comes with a broad range of features including [nested slides](https://github.com/hakimel/reveal.js#markup), [markdown contents](https://github.com/hakimel/reveal.js#markdown), [PDF export](https://github.com/hakimel/reveal.js#pdf-export), [speaker notes](https://github.com/hakimel/reveal.js#speaker-notes) and a [JavaScript API](https://github.com/hakimel/reveal.js#api). It's best viewed in a browser with support for CSS 3D transforms but [fallbacks](https://github.com/hakimel/reveal.js/wiki/Browser-Support) are available to make sure your presentation can still be viewed elsewhere.
+
+
+#### More reading in the Wiki:
+- [Changelog](https://github.com/hakimel/reveal.js/wiki/Changelog): Up-to-date version history.
+- [Examples](https://github.com/hakimel/reveal.js/wiki/Example-Presentations): Presentations created with reveal.js, add your own!
+- [Browser Support](https://github.com/hakimel/reveal.js/wiki/Changelog): Explanation of browser support and fallbacks.
+
+
+The framework is and will remain free. Donations are available as an optional way of supporting the project. Proceeds go towards futher development, hosting and domain costs for the GUI editor which will be out shortly.
+
+[![Click here to lend your support to: reveal.js and make a donation at www.pledgie.com !](http://www.pledgie.com/campaigns/18182.png?skin_name=chrome)](http://www.pledgie.com/campaigns/18182)
+
+
+## Instructions
+
+### Markup
+
+Markup heirarchy needs to be ``<div class="reveal"> <div class="slides"> <section>`` where the ``<section>`` represents one slide and can be repeated indefinitely. If you place multiple ``<section>``'s inside of another ``<section>`` they will be shown as vertical slides. The first of the vertical slides is the "root" of the others (at the top), and it will be included in the horizontal sequence. For example:
+
+```html
+<div class="reveal">
+	<div class="slides"> 
+		<section>Single Horizontal Slide</section>
+		<section>
+			<section>Vertical Slide 1</section>
+			<section>Vertical Slide 2</section>
+		</section>
+	</div>
+</div>
+```
+
+### Markdown
+
+It's possible to write your slides using Markdown. To enable Markdown simply add the ```data-markdown``` attribute to your ```<section>``` elements and reveal.js will automatically load the JavaScript parser. 
+
+This is based on [data-markdown](https://gist.github.com/1343518) from [Paul Irish](https://github.com/paulirish) which in turn uses [showdown](https://github.com/coreyti/showdown/). This is sensitive to indentation (avoid mixing tabs and spaces) and line breaks (avoid consecutive breaks). Updates to come.
+
+```html
+<section data-markdown>
+	## Page title
+	
+	A paragraph with some text and a [link](http://hakim.se).
+</section>
+```
+
+
+### Configuration
+
+At the end of your page you need to initialize reveal by running the following code. Note that all config values are optional and will default as specified below.
+
+```javascript
+Reveal.initialize({
+	// Display controls in the bottom right corner
+	controls: true,
+
+	// Display a presentation progress bar
+	progress: true,
+
+	// Push each slide change to the browser history
+	history: false,
+
+	// Enable keyboard shortcuts for navigation
+	keyboard: true,
+
+	// Loop the presentation
+	loop: false,
+
+	// Number of milliseconds between automatically proceeding to the 
+	// next slide, disabled when set to 0
+	autoSlide: 0,
+
+	// Enable slide navigation via mouse wheel
+	mouseWheel: true,
+
+	// Apply a 3D roll to links on hover
+	rollingLinks: true,
+
+	// Transition style
+	transition: 'default' // default/cube/page/concave/linear(2d)
+});
+```
+
+### Dependencies
+
+Reveal.js doesn't _rely_ on any third party scripts to work but a few optional libraries are included by default. These libraries are loaded as dependencies in the order they appear, for example:
+
+```javascript
+Reveal.initialize({
+	dependencies: [
+		// Syntax highlight for <code> elements
+		{ src: 'lib/js/highlight.js', async: true, callback: function() { window.hljs.initHighlightingOnLoad(); } },
+		// Cross-browser shim that fully implements classList - https://github.com/eligrey/classList.js/
+		{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } }
+		// Interpret Markdown in <section> elements
+		{ src: 'lib/js/data-markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+		{ src: 'lib/js/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+		// Speaker notes support
+		{ src: 'plugin/speakernotes/client.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+		{ src: '/socket.io/socket.io.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+	]
+});
+```
+
+You can add your own extensions using the same syntax. The following properties are available for each dependency object:
+- **src**: Path to the script to load
+- **async**: [optional] Flags if the script should load after reveal.js has started, defaults to false
+- **callback**: [optional] Function to execute when the script has loaded
+- **condition**: [optional] Function which must return true for the script to be loaded
+
+
+### API
+
+The Reveal class provides a minimal JavaScript API for controlling navigation and reading state:
+
+```javascript
+// Navigation
+Reveal.navigateTo( indexh, indexv );
+Reveal.navigateLeft();
+Reveal.navigateRight();
+Reveal.navigateUp();
+Reveal.navigateDown();
+Reveal.navigatePrev();
+Reveal.navigateNext();
+Reveal.toggleOverview();
+
+// Retrieves the previous and current slide elements
+Reveal.getPreviousSlide();
+Reveal.getCurrentSlide();
+
+Reveal.getIndices(); // { h: 0, v: 0 } }
+```
+
+### States
+
+If you set ``data-state="somestate"`` on a slide ``<section>``, "somestate" will be applied as a class on the document element when that slide is opened. This allows you to apply broad style changes to the page based on the active slide.
+
+Furthermore you can also listen to these changes in state via JavaScript:
+
+```javascript
+Reveal.addEventListener( 'somestate', function() {
+	// TODO: Sprinkle magic
+}, false );
+```
+
+### Slide change event
+
+An 'slidechanged' event is fired each time the slide is changed (regardless of state). The event object holds the index values of the current slide as well as a reference to the previous and current slide HTML nodes.
+
+```javascript
+Reveal.addEventListener( 'slidechanged', function( event ) {
+	// event.previousSlide, event.currentSlide, event.indexh, event.indexv
+} );
+```
+
+### Fragment events
+
+When a slide fragment is either shown or hidden reveal.js will dispatch an event.
+
+```javascript
+Reveal.addEventListener( 'fragmentshown', function( event ) {
+	// event.fragment = the fragment DOM element
+} );
+Reveal.addEventListener( 'fragmenthidden', function( event ) {
+	// event.fragment = the fragment DOM element
+} );
+```
+
+### Internal links
+
+It's easy to link between slides. The first example below targets the index of another slide whereas the second targets a slide with an ID attribute (```<section id="some-slide">```):
+
+```html
+<a href="#/2/2">Link</a>
+<a href="#/some-slide">Link</a>
+```
+
+## PDF Export
+
+Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome). 
+Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-13872948.
+
+1. Open the desired presentation with *print-pdf* anywhere in the query, for example: [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf)
+2. Open the in-browser print dialog (CMD+P).
+3. Change the **Destination** setting to **Save as PDF**.
+4. Change the **Layout** to **Landscape**.
+5. Change the **Margins** to **None**.
+6. Click **Save**.
+
+![Chrome Print Settings](https://s3.amazonaws.com/hakim-static/reveal-js/pdf-print-settings.png)
+
+## Speaker Notes
+
+If you're interested in using speaker notes, reveal.js comes with a Node server that allows you to deliver your presentation in one browser while viewing speaker notes in another. 
+
+To include speaker notes in your presentation, simply add an `<aside class="notes">` element to any slide. These notes will be hidden in the main presentation view.
+
+You'll also need to [install Node.js](http://nodejs.org/); then, install the server dependencies by running `npm install`.
+
+Once Node.js and the dependencies are installed, run the following command from the root directory:
+
+		node plugin/speakernotes
+
+By default, the slides will be served at [localhost:1947](http://localhost:1947).
+
+You can change the appearance of the speaker notes by editing the file at `plugin/speakernotes/notes.html`.	
+
+### Known Issues
+
+- The notes page is supposed to show the current slide and the next slide, but when it first starts, it always shows the first slide in both positions. 
+
+## Folder Structure
+- **css/** Core styles without which the project does not function
+- **js/** Like above but for JavaScript
+- **plugin/** Components that have been developed as extensions to reveal.js
+- **lib/** All other third party assets (JavaScript, CSS, fonts)
+
+## License
+
+MIT licensed
+
+Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
diff --git a/docs/slides/flops14/_support/reveal/css/liquidhaskell.css b/docs/slides/flops14/_support/reveal/css/liquidhaskell.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/liquidhaskell.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/flops14/_support/reveal/css/main.css b/docs/slides/flops14/_support/reveal/css/main.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/main.css
@@ -0,0 +1,925 @@
+@charset "UTF-8";
+
+/**
+ * reveal.js
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+.reveal a {
+  color: #8b7c69;
+  text-decoration: none;
+}
+
+/*********************************************
+ * RESET STYLES
+ *********************************************/
+
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed, 
+figure, figcaption, footer, header, hgroup, 
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font-size: 100%;
+	font: inherit;
+	vertical-align: baseline;
+}
+
+article, aside, details, figcaption, figure, 
+footer, header, hgroup, menu, nav, section {
+	display: block;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+html, 
+body {
+	padding: 0;
+	margin: 0;
+	width: 100%;
+	height: 100%;
+	min-height: 600px;
+	overflow: hidden;
+}
+
+body {
+	position: relative;
+	line-height: 1;
+}
+
+@media screen and (max-width: 1024px) {
+	body {
+		font-size: 30px;
+	}
+}
+
+::selection { 
+	background:#FF5E99; 
+	color:#fff; 
+	text-shadow: none; 
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1 { font-size: 0.77em; }
+.reveal h2 { font-size: 2.11em;	}
+.reveal h3 { font-size: 1.55em;	}
+.reveal h4 { font-size: 1em;	}
+
+
+/*********************************************
+ * VIEW FRAGMENTS
+ *********************************************/
+
+.reveal .slides section .fragment {
+	opacity: 0;
+
+	-webkit-transition: all .2s ease;
+	   -moz-transition: all .2s ease;
+	    -ms-transition: all .2s ease;
+	     -o-transition: all .2s ease;
+	        transition: all .2s ease;
+}
+	.reveal .slides section .fragment.visible {
+		opacity: 1;
+	}
+
+
+/*********************************************
+ * DEFAULT ELEMENT STYLES
+ *********************************************/
+
+.reveal .slides section {
+	line-height: 1.2em;
+	font-weight: normal;
+}
+
+.reveal img {
+	/* preserve aspect ratio and scale image so it's bound within the section */
+	max-width: 100%;
+	max-height: 100%;
+} 
+
+.reveal strong, 
+.reveal b {
+	font-weight: bold;
+}
+
+.reveal em, 
+.reveal i {
+	font-style: italic;
+}
+
+.reveal ol, 
+.reveal ul {
+	display: inline-block;
+
+	text-align: left;
+	margin: 0 0 0 .7em;
+}
+
+.reveal ol {
+	list-style-type: decimal;
+}
+
+.reveal ul {
+	list-style-type: disc;
+	padding-bottom: 0.8em;
+}
+
+.reveal ul ul {
+	list-style-type: circle;
+}
+
+.reveal ul ul ul {
+	list-style-type: square;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+	display: block;
+	margin-left: 0;
+}
+
+.reveal p {
+	margin-bottom: 10px;
+	line-height: 1.2em;
+}
+
+.reveal q,
+.reveal blockquote {
+	quotes: none;
+}
+
+
+.reveal blockquote {
+	display: block;
+	position: relative;
+	width: 70%;
+	margin: 5px auto;
+	padding: 5px;
+	
+	font-size: 80%;
+	font-style: italic;
+	background: rgba(255, 255, 255, 0.05);
+	box-shadow: 0px 0px 2px rgba(0,0,0,0.2);
+}
+
+
+
+/*--DW-- disable funky quote marks for blockquotes*/
+/*
+.reveal blockquote:before {
+	content: '“';
+}
+.reveal blockquote:after {
+	content: '”';
+}
+*/
+
+.reveal q {	
+	font-style: italic;
+}
+	.reveal q:before {
+		content: '“';
+	}
+	.reveal q:after {
+		content: '”';
+	}
+
+.reveal pre {
+	display: block;
+	position: relative;
+	width: 90%;
+	margin: 10px auto;
+
+	text-align: left;
+	font-size: 0.85em;
+	font-family: monospace;
+	line-height: 1.2em;
+
+	word-wrap: break-word;
+
+	box-shadow: 0px 0px 6px rgba(0,0,0,0.3);
+}
+
+.reveal code {
+	font-family: monospace;
+	overflow-x: auto;
+}
+
+.reveal table th, 
+.reveal table td {
+	text-align: left;
+	padding-right: .3em;
+}
+
+.reveal table th {
+	text-shadow: rgb(255,255,255) 1px 1px 2px;
+}
+
+.reveal sup { 
+	vertical-align: super;
+}
+.reveal sub { 
+	vertical-align: sub;
+}
+
+.reveal small {
+	display: inline-block;
+	font-size: 0.6em;
+	line-height: 1.2em;
+	vertical-align: top;
+}
+
+.reveal small * {
+	vertical-align: top;
+}
+
+
+/*********************************************
+ * CONTROLS
+ *********************************************/
+
+.reveal .controls {
+	display: none;
+	position: fixed;
+	width: 100px;
+	height: 100px;
+	z-index: 30;
+
+	right: 0;
+	bottom: 0;
+}
+	
+	.reveal .controls a {
+		font-family: Arial;
+		font-size: 0.83em;
+		position: absolute;
+		opacity: 0.1;
+	}
+		.reveal .controls a.enabled {
+			opacity: 0.6;
+		}
+		.reveal .controls a.enabled:active {
+			margin-top: 1px;
+		}
+
+	.reveal .controls .left {
+		top: 30px;
+	}
+
+	.reveal .controls .right {
+		left: 60px;
+		top: 30px;
+	}
+
+	.reveal .controls .up {
+		left: 30px;
+	}
+
+	.reveal .controls .down {
+		left: 30px;
+		top: 60px;
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	position: fixed;
+	display: none;
+	height: 3px;
+	width: 100%;
+	bottom: 0;
+	left: 0;
+}
+	
+	.reveal .progress span {
+		display: block;
+		height: 100%;
+		width: 0px;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+/*********************************************
+ * ROLLING LINKS
+ *********************************************/
+
+.reveal .roll {
+	display: inline-block;
+	line-height: 1.2;
+	overflow: hidden;
+
+	vertical-align: top;
+
+	-webkit-perspective: 400px;
+	   -moz-perspective: 400px;
+	    -ms-perspective: 400px;
+	        perspective: 400px;
+
+	-webkit-perspective-origin: 50% 50%;
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+	.reveal .roll:hover {
+		background: none;
+		text-shadow: none;
+	}
+.reveal .roll span {
+	display: block;
+	position: relative;
+	padding: 0 2px;
+
+	pointer-events: none;
+
+	-webkit-transition: all 400ms ease;
+	   -moz-transition: all 400ms ease;
+	    -ms-transition: all 400ms ease;
+	        transition: all 400ms ease;
+
+	-webkit-transform-origin: 50% 0%;
+	   -moz-transform-origin: 50% 0%;
+	    -ms-transform-origin: 50% 0%;
+	        transform-origin: 50% 0%;
+
+	-webkit-transform-style: preserve-3d;
+	   -moz-transform-style: preserve-3d;
+	    -ms-transform-style: preserve-3d;
+	        transform-style: preserve-3d;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	        backface-visibility: hidden;
+}
+	.reveal .roll:hover span {
+	    background: rgba(0,0,0,0.5);
+
+	    -webkit-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	       -moz-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	        -ms-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	            transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	}
+.reveal .roll span:after {
+	content: attr(data-title);
+
+	display: block;
+	position: absolute;
+	left: 0;
+	top: 0;
+	padding: 0 2px;
+
+	-webkit-transform-origin: 50% 0%;
+	   -moz-transform-origin: 50% 0%;
+	    -ms-transform-origin: 50% 0%;
+	        transform-origin: 50% 0%;
+
+	-webkit-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	   -moz-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	    -ms-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	        transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+}
+
+
+/*********************************************
+ * SLIDES
+ *********************************************/
+
+.reveal .slides {
+	position: absolute;
+	max-width: 1024px;
+	width: 100%;
+	height: 80%;
+	left: 50%;
+	top: 50%;
+	margin-top: -320px;
+	padding: 20px 0px;
+	overflow: visible;
+	
+	text-align: center;
+
+	-webkit-transition: -webkit-perspective .4s ease;
+	   -moz-transition: -moz-perspective .4s ease;
+	    -ms-transition: -ms-perspective .4s ease;
+	     -o-transition: -o-perspective .4s ease;
+	        transition: perspective .4s ease;
+	
+	-webkit-perspective: 600px;
+	   -moz-perspective: 600px;
+	    -ms-perspective: 600px;
+	        perspective: 600px;
+
+	-webkit-perspective-origin: 0% 25%;
+	   -moz-perspective-origin: 0% 25%;
+	    -ms-perspective-origin: 0% 25%;
+	        perspective-origin: 0% 25%;
+}
+
+.reveal .slides>section,
+.reveal .slides>section>section {
+	display: none;
+	position: absolute;
+	width: 100%;
+	min-height: 600px;
+
+	z-index: 10;
+	
+	-webkit-transform-style: preserve-3d;
+	   -moz-transform-style: preserve-3d;
+	    -ms-transform-style: preserve-3d;
+	        transform-style: preserve-3d;
+	
+	-webkit-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	   -moz-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	    -ms-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	     -o-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	        transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+}
+
+.reveal .slides>section.present {
+	display: block;
+	z-index: 11;
+	opacity: 1;
+}
+
+.reveal .slides>section {
+	margin-left: -50%;
+}
+
+
+/*********************************************
+ * DEFAULT TRANSITION
+ *********************************************/
+
+.reveal .slides>section.past {
+	display: block;
+	opacity: 0;
+	
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+}
+.reveal .slides>section.future {
+	display: block;
+	opacity: 0;
+	
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+}
+
+.reveal .slides>section>section.past {
+	display: block;
+	opacity: 0;
+	
+	-webkit-transform: translate3d(0, -50%, 0) rotateX(70deg) translate3d(0, -50%, 0);
+	   -moz-transform: translate3d(0, -50%, 0) rotateX(70deg) translate3d(0, -50%, 0);
+	    -ms-transform: translate3d(0, -50%, 0) rotateX(70deg) translate3d(0, -50%, 0);
+	        transform: translate3d(0, -50%, 0) rotateX(70deg) translate3d(0, -50%, 0);
+}
+.reveal .slides>section>section.future {
+	display: block;
+	opacity: 0;
+	
+	-webkit-transform: translate3d(0, 50%, 0) rotateX(-70deg) translate3d(0, 50%, 0);
+	   -moz-transform: translate3d(0, 50%, 0) rotateX(-70deg) translate3d(0, 50%, 0);
+	    -ms-transform: translate3d(0, 50%, 0) rotateX(-70deg) translate3d(0, 50%, 0);
+	        transform: translate3d(0, 50%, 0) rotateX(-70deg) translate3d(0, 50%, 0);
+}
+
+
+/*********************************************
+ * CONCAVE TRANSITION
+ *********************************************/
+
+.reveal.concave  .slides>section.past {
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+}
+.reveal.concave  .slides>section.future {
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+}
+
+.reveal.concave  .slides>section>section.past {
+	-webkit-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	   -moz-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	    -ms-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	        transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+}
+.reveal.concave  .slides>section>section.future {
+	-webkit-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	   -moz-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	    -ms-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	        transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+}
+
+
+/*********************************************
+ * LINEAR TRANSITION
+ *********************************************/
+
+.reveal.linear .slides>section.past {
+	-webkit-transform: translate(-150%, 0);
+	   -moz-transform: translate(-150%, 0);
+	    -ms-transform: translate(-150%, 0);
+	     -o-transform: translate(-150%, 0);
+	        transform: translate(-150%, 0);
+}
+.reveal.linear .slides>section.future {
+	-webkit-transform: translate(150%, 0);
+	   -moz-transform: translate(150%, 0);
+	    -ms-transform: translate(150%, 0);
+	     -o-transform: translate(150%, 0);
+	        transform: translate(150%, 0);
+}
+
+.reveal.linear .slides>section>section.past {
+	-webkit-transform: translate(0, -150%);
+	   -moz-transform: translate(0, -150%);
+	    -ms-transform: translate(0, -150%);
+	     -o-transform: translate(0, -150%);
+	        transform: translate(0, -150%);
+}
+.reveal.linear .slides>section>section.future {
+	-webkit-transform: translate(0, 150%);
+	   -moz-transform: translate(0, 150%);
+	    -ms-transform: translate(0, 150%);
+	     -o-transform: translate(0, 150%);
+	        transform: translate(0, 150%);
+}
+
+/*********************************************
+ * BOX TRANSITION
+ *********************************************/
+
+.reveal.cube .slides {
+	margin-top: -350px;
+
+	-webkit-perspective-origin: 50% 25%;
+	   -moz-perspective-origin: 50% 25%;
+	    -ms-perspective-origin: 50% 25%;
+	        perspective-origin: 50% 25%;
+
+	-webkit-perspective: 1300px;
+	   -moz-perspective: 1300px;
+	    -ms-perspective: 1300px;
+	        perspective: 1300px;
+}
+
+.reveal.cube .slides section {
+	padding: 30px;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	    -ms-backface-visibility: hidden;
+	        backface-visibility: hidden;
+	
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+	.reveal.cube .slides section:not(.stack):before {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+		background: #232628;
+		border-radius: 4px;
+
+		-webkit-transform: translateZ( -20px );
+		   -moz-transform: translateZ( -20px );
+		    -ms-transform: translateZ( -20px );
+		     -o-transform: translateZ( -20px );
+		        transform: translateZ( -20px );
+	}
+	.reveal.cube .slides section:not(.stack):after {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 90%;
+		height: 30px;
+		left: 5%;
+		bottom: 0;
+		background: none;
+		z-index: 1;
+
+		border-radius: 4px;
+		box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ(-90px) rotateX( 65deg );
+		   -moz-transform: translateZ(-90px) rotateX( 65deg );
+		    -ms-transform: translateZ(-90px) rotateX( 65deg );
+		     -o-transform: translateZ(-90px) rotateX( 65deg );
+		        transform: translateZ(-90px) rotateX( 65deg );
+	}
+
+.reveal.cube .slides>section.stack {
+	padding: 0;
+	background: none;
+}
+
+.reveal.cube .slides>section.past {
+	-webkit-transform-origin: 100% 0%;
+	   -moz-transform-origin: 100% 0%;
+	    -ms-transform-origin: 100% 0%;
+	        transform-origin: 100% 0%;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+}
+
+.reveal.cube .slides>section.future {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg);
+}
+
+.reveal.cube .slides>section>section.past {
+	-webkit-transform-origin: 0% 100%;
+	   -moz-transform-origin: 0% 100%;
+	    -ms-transform-origin: 0% 100%;
+	        transform-origin: 0% 100%;
+
+	-webkit-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	   -moz-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	    -ms-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	        transform: translate3d(0, -100%, 0) rotateX(90deg);
+}
+
+.reveal.cube .slides>section>section.future {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	   -moz-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	    -ms-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	        transform: translate3d(0, 100%, 0) rotateX(-90deg);
+}
+
+
+/*********************************************
+ * PAGE TRANSITION
+ *********************************************/
+
+.reveal.page .slides {
+	margin-top: -350px;
+
+	-webkit-perspective-origin: 50% 50%;
+ 	   -moz-perspective-origin: 50% 50%;
+ 	    -ms-perspective-origin: 50% 50%;
+ 	        perspective-origin: 50% 50%;
+
+	-webkit-perspective: 3000px;
+	   -moz-perspective: 3000px;
+	    -ms-perspective: 3000px;
+	        perspective: 3000px;
+}
+
+.reveal.page .slides section {
+	padding: 30px;
+
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+	.reveal.page .slides section.past {
+		z-index: 12;
+	}
+	.reveal.page .slides section:not(.stack):before {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+		background: rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ( -20px );
+		   -moz-transform: translateZ( -20px );
+		    -ms-transform: translateZ( -20px );
+		     -o-transform: translateZ( -20px );
+		        transform: translateZ( -20px );
+	}
+	.reveal.page .slides section:not(.stack):after {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 90%;
+		height: 30px;
+		left: 5%;
+		bottom: 0;
+		background: none;
+		z-index: 1;
+
+		border-radius: 4px;
+		box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ(-90px) rotateX( 65deg );
+	}
+
+.reveal.page .slides>section.stack {
+	padding: 0;
+	background: none;
+}
+
+.reveal.page .slides>section.past {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	   -moz-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	    -ms-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	        transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+}
+
+.reveal.page .slides>section.future {
+	-webkit-transform-origin: 100% 0%;
+	   -moz-transform-origin: 100% 0%;
+	    -ms-transform-origin: 100% 0%;
+	        transform-origin: 100% 0%;
+
+	-webkit-transform: translate3d(0, 0, 0);
+	   -moz-transform: translate3d(0, 0, 0);
+	    -ms-transform: translate3d(0, 0, 0);
+	        transform: translate3d(0, 0, 0);
+}
+
+.reveal.page .slides>section>section.past {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	   -moz-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	    -ms-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	        transform: translate3d(0, -40%, 0) rotateX(80deg);
+}
+
+.reveal.page .slides>section>section.future {
+	-webkit-transform-origin: 0% 100%;
+	   -moz-transform-origin: 0% 100%;
+	    -ms-transform-origin: 0% 100%;
+	        transform-origin: 0% 100%;
+
+	-webkit-transform: translate3d(0, 0, 0);
+	   -moz-transform: translate3d(0, 0, 0);
+	    -ms-transform: translate3d(0, 0, 0);
+	        transform: translate3d(0, 0, 0);
+}
+
+
+/*********************************************
+ * OVERVIEW
+ *********************************************/
+
+.reveal.overview .slides {
+	-webkit-perspective: 700px;
+	   -moz-perspective: 700px;
+	    -ms-perspective: 700px;
+	        perspective: 700px;
+}
+
+.reveal.overview .slides section {
+	padding: 20px 0;
+	max-height: 600px;
+	overflow: hidden;	
+	opacity: 1;
+	cursor: pointer;
+	background: rgba(0,0,0,0.1);
+}
+.reveal.overview .slides section .fragment {
+	opacity: 1;
+}
+.reveal.overview .slides section:after,
+.reveal.overview .slides section:before {
+	display: none !important;
+}
+.reveal.overview .slides section>section {
+	opacity: 1;
+	cursor: pointer;
+}
+	.reveal.overview .slides section:hover {
+		background: rgba(0,0,0,0.3);
+	}
+
+	.reveal.overview .slides section.present {
+		background: rgba(0,0,0,0.3);
+	}
+.reveal.overview .slides>section.stack {
+	background: none;
+	padding: 0;
+	overflow: visible;
+}
+
+
+/*********************************************
+ * FALLBACK
+ *********************************************/
+
+.no-transforms {
+	overflow-y: auto;
+}
+
+.no-transforms .slides section {
+	display: block!important;
+	opacity: 1!important;
+	position: relative!important;
+	height: auto;
+	min-height: auto;
+	margin-bottom: 100px;
+
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	        transform: none;
+}
+
+
+/*********************************************
+ * DEFAULT STATES
+ *********************************************/
+
+.state-background {
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	background: rgba( 0, 0, 0, 0 );
+
+	-webkit-transition: background 800ms ease;
+	   -moz-transition: background 800ms ease;
+	    -ms-transition: background 800ms ease;
+	     -o-transition: background 800ms ease;
+	        transition: background 800ms ease;
+}
+.alert .state-background {
+	background: rgba( 200, 50, 30, 0.6 );
+}
+.soothe .state-background {
+	background: rgba( 50, 200, 90, 0.4 );
+}
+.blackout .state-background {
+	background: rgba( 0, 0, 0, 0.6 );
+}
+
+
+/*********************************************
+ * SPEAKER NOTES
+ *********************************************/
+
+.reveal aside.notes {
+	display: none;
+}
+
diff --git a/docs/slides/flops14/_support/reveal/css/print/paper.css b/docs/slides/flops14/_support/reveal/css/print/paper.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/print/paper.css
@@ -0,0 +1,170 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and 
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending 
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+body {
+	background: #fff;
+	font-size: 13pt;
+	width: auto;
+	height: auto;
+	border: 0;
+	margin: 0 5%;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+}
+html {
+	background: #fff;
+	width: auto;
+	height: auto;
+	overflow: visible;
+}
+
+/* SECTION 2: Remove any elements not needed in print. 
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow, 
+.controls a, 
+.reveal .progress, 
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display:none;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div, a {
+	font-size: 13pt;
+	font-family: Georgia, "Times New Roman", Times, serif !important;
+	color: #000; 
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Diffrentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	color: #000!important;
+	height: auto;
+	line-height: normal;
+	font-family: Georgia, "Times New Roman", Times, serif !important;
+	text-shadow: 0 0 0 #000 !important;
+	text-align: left;
+	letter-spacing: normal;
+}
+/* Need to reduce the size of the fonts for printing */
+h1 { font-size: 26pt !important;  }
+h2 { font-size: 22pt !important; }
+h3 { font-size: 20pt !important; }
+h4 { font-size: 20pt !important; font-variant: small-caps; }
+h5 { font-size: 19pt !important; }
+h6 { font-size: 18pt !important; font-style: italic; }
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link, 
+a:visited {
+	color: #000 !important;
+	font-weight: bold;
+	text-decoration: underline;
+}
+.reveal a:link:after, 
+.reveal a:visited:after {
+	content: " (" attr(href) ") ";
+	color: #222 !important;
+	font-size: 90%;
+}
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+	text-align: left !important;
+}
+.reveal .slides {
+	position: static;
+	width: auto;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin-left: auto;
+	margin-top: auto;
+	padding: auto;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides>section, .reveal .slides>section>section, 
+.reveal .slides>section.past, .reveal .slides>section.future,
+.reveal.linear .slides>section, .reveal.linear .slides>section>section,
+.reveal.linear .slides>section.past, .reveal.linear .slides>section.future {
+	
+	visibility: visible;
+	position: static;
+	width: 90%;
+	height: auto;
+	display: block;
+	overflow: visible;
+
+	left: 0%;
+	top: 0%;
+	margin-left: 0px;
+	margin-top: 0px;
+	padding: 20px 0px;
+
+	opacity: 1;
+
+	-webkit-transform-style: flat;
+	   -moz-transform-style: flat;
+	    -ms-transform-style: flat;
+	        transform-style: flat;
+
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	        transform: none;
+}
+.reveal section {
+	page-break-after: always !important; 
+	display: block !important;
+}
+.reveal section.stack {
+	page-break-after: avoid !important; 
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+}
+.reveal section img {
+	display: block;
+	margin: 15px 0px;
+	background: rgba(255,255,255,1);
+	border: 1px solid #666;
+	box-shadow: none;
+}
diff --git a/docs/slides/flops14/_support/reveal/css/print/pdf.css b/docs/slides/flops14/_support/reveal/css/print/pdf.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/print/pdf.css
@@ -0,0 +1,158 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and 
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending 
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+* {
+	-webkit-print-color-adjust: exact; 
+}
+
+body {
+	font-size: 22pt;
+	width: auto;
+	height: auto;
+	border: 0;
+	margin: 0 5%;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+	background: #333;
+}
+
+html {
+	width: auto;
+	height: auto;
+	overflow: visible;
+}
+
+/* SECTION 2: Remove any elements not needed in print. 
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow, 
+.controls a, 
+.reveal .progress, 
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display:none;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div, a {
+	font-size: 22pt;
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Diffrentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	text-shadow: 0 0 0 #000 !important;
+}
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link, 
+a:visited {
+	font-weight: bold;
+	text-decoration: underline;
+}
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+}
+.reveal .slides {
+	position: static;
+	width: 100%;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin-left: auto;
+	margin-top: auto;
+	padding: auto;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides>section, .reveal .slides>section>section, 
+.reveal .slides>section.past, .reveal .slides>section.future,
+.reveal.linear .slides>section, .reveal.linear .slides>section>section,
+.reveal.linear .slides>section.past, .reveal.linear .slides>section.future {
+	
+	visibility: visible;
+	position: static;
+	width: 100%;
+	height: auto;
+	min-height: initial;
+	display: block;
+	overflow: visible;
+
+	left: 0%;
+	top: 0%;
+	margin-left: 0px;
+	margin-top: 50px;
+	padding: 20px 0px;
+
+	opacity: 1;
+
+	-webkit-transform-style: flat;
+	   -moz-transform-style: flat;
+	    -ms-transform-style: flat;
+	        transform-style: flat;
+
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	        transform: none;
+}
+.reveal section {
+	page-break-after: always !important; 
+	display: block !important;
+}
+.reveal section.stack {
+	margin: 0px !important;
+	padding: 0px !important;
+	page-break-after: avoid !important; 
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+}
+.reveal img {
+	box-shadow: none;
+}
+.reveal .roll {
+	overflow: visible;
+	line-height: 1em;
+}
+
+.reveal small a {
+	font-size: 16pt !important;
+}
diff --git a/docs/slides/flops14/_support/reveal/css/theme/beige.css b/docs/slides/flops14/_support/reveal/css/theme/beige.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/theme/beige.css
@@ -0,0 +1,179 @@
+/**
+ * A beige theme for reveal.js presentations, similar 
+ * to the default theme.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'Lato', Times, 'Times New Roman', serif;
+	font-size: 36px;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #333;
+
+	background: #f7f3de;
+	background: -moz-radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%, rgba(247,242,211,1) 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(247,242,211,1)));
+	background: -webkit-radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%,rgba(247,242,211,1) 100%);
+	background: -o-radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%,rgba(247,242,211,1) 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%,rgba(247,242,211,1) 100%);
+	background: radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%,rgba(247,242,211,1) 100%);
+}
+
+::-moz-selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+::-webkit-selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+::selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2, 
+.reveal h3, 
+.reveal h4, 
+.reveal h5, 
+.reveal h6 {
+	margin: 0 0 20px 0;
+	color: #333;
+	font-family: 'League Gothic', Impact, sans-serif;
+	line-height: 0.9em;
+	letter-spacing: 0.02em;
+	
+	text-transform: uppercase;
+}
+
+.reveal h1 {
+	text-shadow: 	0 1px 0 #ccc,
+					0 2px 0 #c9c9c9,
+					0 3px 0 #bbb,
+					0 4px 0 #b9b9b9,
+					0 5px 0 #aaa,
+					0 6px 1px rgba(0,0,0,.1),
+					0 0 5px rgba(0,0,0,.1),
+					0 1px 3px rgba(0,0,0,.3),
+					0 3px 5px rgba(0,0,0,.2),
+					0 5px 10px rgba(0,0,0,.25),
+					0 20px 20px rgba(0,0,0,.15);
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: #8b743d;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		text-shadow: none;
+		border: none;
+		border-radius: 2px;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: #8b743d;
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 30px 0 0 0;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid #eee;
+	
+	-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: #8b743d;
+		
+		-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		color: #8b743d;
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: #8b743d;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/flops14/_support/reveal/css/theme/default.css b/docs/slides/flops14/_support/reveal/css/theme/default.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/theme/default.css
@@ -0,0 +1,223 @@
+/**
+ * The default theme for reveal.js presentations.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@font-face {
+		font-family: 'PTSansNarrow';
+        src: url('../../lib/font/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+@font-face {
+		font-family: 'OpenSans';
+        src: url('../../lib/font/OpenSans-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'Lato', Times, 'Times New Roman', serif;
+	font-size: 36;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #eee;
+
+	background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM1NTVhNWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMWMxZTIwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+	background-color: #2b2b2b;
+	background: -moz-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%, rgba(28,30,32,1) 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(85,90,95,1)), color-stop(100%,rgba(28,30,32,1)));
+	background: -webkit-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -o-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+}
+
+
+/*********************************************
+ * main.css OVERIDES
+ *********************************************/
+
+
+/* Undo globally centered text from main.css*/
+.reveal .slides {
+	text-align: left;
+}
+
+.reveal li {
+	padding-bottom: 0.7em;
+	line-height: 1em;
+}
+
+.reveal p + ul {
+	padding-left: 4%
+}
+
+
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2 {
+	margin: 0 0 20px 0;
+	color: #eee;
+	font-family: 'League Gothic', Impact, sans-serif;
+	line-height: 0.9em;
+	letter-spacing: 0.02em;
+	
+	text-align: center;
+	text-transform: uppercase;
+	text-shadow: 0px 1px 0px rgba(0,0,0,1);
+}
+
+.reveal h1 {
+	padding-top: 3%%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	color: rgba(255,255,255,0.5);
+}
+
+.reveal h2 {
+	font-family: 'PTSansNarrow';
+	font-size: 130%;
+}
+
+.reveal .titlepage h1,
+.reveal h1.topic {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: hsl(185, 85%, 50%);
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		color: hsl(185, 85%, 70%);
+		
+		text-shadow: none;
+		border: none;
+		border-radius: 2px;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: hsl(185, 60%, 35%);
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 30px 0 0 0;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid #eee;
+	
+	-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: #13DAEC;
+		
+		-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		color: hsl(185, 85%, 70%);
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: hsl(185, 85%, 50%);
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/flops14/_support/reveal/css/theme/seminar.css b/docs/slides/flops14/_support/reveal/css/theme/seminar.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/theme/seminar.css
@@ -0,0 +1,196 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb; }
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 40px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	// :color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.05em 0.05em 0.25em blue;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+/*
+.reveal a:not(.image) {
+  line-height: 1.3em; }
+
+
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c; }
+
+*/
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #51483d; }
diff --git a/docs/slides/flops14/_support/reveal/css/theme/seminar.orig.css b/docs/slides/flops14/_support/reveal/css/theme/seminar.orig.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/theme/seminar.orig.css
@@ -0,0 +1,301 @@
+/**
+ * The default theme for reveal.js presentations.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.ttf') format('truetype');
+	font-weight: normal;
+	font-style: normal;
+}
+
+@font-face {
+		font-family: 'PTSansNarrow';
+        src: url('../../lib/font/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+@font-face {
+		font-family: 'OpenSans';
+        src: url('../../lib/font/OpenSans-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'OpenSans', Times, 'Times New Roman', serif;
+	font-size: 36;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #eee;
+
+	background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM1NTVhNWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMWMxZTIwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+	background-color: #2b2b2b;
+	background: -moz-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%, rgba(28,30,32,1) 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(85,90,95,1)), color-stop(100%,rgba(28,30,32,1)));
+	background: -webkit-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -o-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+}
+
+
+/*********************************************
+ * main.css OVERIDES
+ *********************************************/
+
+
+/*--DW-- uncomment below to undo globally centered text from main.css*/
+
+/*.reveal .slides {
+	text-align: left;
+}
+
+.reveal li {
+	padding-bottom: 0.7em;
+	line-height: 1em;
+}
+.reveal ul ul {
+	padding-left: 8%;
+	padding-top: 0.7em;
+	font-size: 85%;
+}*/
+
+/*--DW--
+* override list width to make multiline list items
+* a bit more manageable
+*/
+.reveal ul {
+	max-width: 80%;
+}
+
+.reveal li {
+	padding-bottom: 0.3em;
+}
+
+/*--DW-- uncenter pararagraph blocks*/
+.reveal .slides p {
+	text-align: left
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2 {
+	margin: 0 0 20px 0;
+	color: #eee;
+	font-family: 'League Gothic', Impact, sans-serif;
+	line-height: 0.9em;
+	letter-spacing: 0.02em;
+	
+	text-align: center;
+	text-transform: uppercase;
+	text-shadow: 0px 1px 0px rgba(0,0,0,1);
+}
+
+.reveal h2 {
+	font-family: 'PTSansNarrow';
+	font-size: 130%;
+}
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+
+
+/*********************************************
+ * BLOCKQUOTES
+ *********************************************/
+
+/*--DW--*/
+.reveal blockquote
+{   background: rgba(255,255,255, .2);
+    font-size: 75%;
+    text-align: justify;
+    width: 70%;
+    padding: 0.5em 5% 0.2em;
+    margin: 0 10%;
+    border: 2px solid rgba(255, 255, 255, .1);
+    -webkit-box-shadow: .1em .1em .5em black inset;
+    -moz-box-shadow: .1em .1em .5em black inset;
+    box-shadow: .1em .1em .5em black inset;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: hsl(185, 85%, 50%);
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+.reveal a:not(.image):hover {
+	color: hsl(185, 85%, 70%);
+	
+	text-shadow: none;
+	border: none;
+	border-radius: 2px;
+}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: hsl(185, 60%, 35%);
+}
+
+
+/*********************************************
+ * IMAGES AND FIGURES
+ *********************************************/
+
+/*--DW-- added figures; changed img styling*/
+/*pandoc*/
+.reveal figure {
+	margin-left: auto;
+	margin-right: auto;
+}
+
+/*pandoc*/
+.reveal figcaption {
+	text-align: center;
+	font-size: 75%;
+	font-style: italic;
+}
+.reveal section img,
+.reveal section embed {
+/*	width: 80%;
+	height: 80%;
+*/	display: block;
+	margin-left: auto;
+	margin-right: auto;
+	padding: 15px;
+	background: rgba(255,255,255, .75);
+    border: 2px solid rgba(255, 255, 255, .1);
+    -webkit-box-shadow: .1em .1em .5em black inset;
+       -moz-box-shadow: .1em .1em .5em black inset;
+            box-shadow: .1em .1em .5em black inset;
+
+/*--DW-- original image box styling*/
+/*
+-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+
+-webkit-transition: all .2s linear;
+   -moz-transition: all .2s linear;
+    -ms-transition: all .2s linear;
+     -o-transition: all .2s linear;
+        transition: all .2s linear;
+*/
+}
+
+.reveal a:hover img {
+	background: rgba(255,255,255,0.2);
+	border-color: #13DAEC;
+	
+	-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		/*color: hsl(185, 85%, 70%);*/
+		color: rgba(138, 201, 85, 0.60);
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		/*background: hsl(185, 85%, 50%);*/
+		background: rgba(138, 201, 85, 0.60);
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/flops14/_support/reveal/css/theme/serif.css b/docs/slides/flops14/_support/reveal/css/theme/serif.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/theme/serif.css
@@ -0,0 +1,190 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+.reveal a:not(.image) {
+  line-height: 1.3em; 
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb; }
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 40px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.05em 0.05em 0.25em blue;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #51483d; }
diff --git a/docs/slides/flops14/_support/reveal/css/theme/simple.css b/docs/slides/flops14/_support/reveal/css/theme/simple.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/theme/simple.css
@@ -0,0 +1,150 @@
+/**
+ * A simple theme for reveal.js presentations, similar 
+ * to the default theme. The accent color is darkblue; 
+ * do a find-replace to change it.
+ * 
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se; so is the theme - beige.css - that this is based off of.
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@import url(http://fonts.googleapis.com/css?family=News+Cycle:400,700);
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'Lato', Times, 'Times New Roman', serif;
+	font-size: 36px;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: black !important;
+
+	background: white;
+}
+
+::-moz-selection {
+    background:rgba(0, 0, 0, 0.99);
+	color: white; 
+}
+::-webkit-selection {
+    background:rgba(0, 0, 0, 0.99);
+	color: white; 
+}
+::selection {
+    background:rgba(0, 0, 0, 0.99);
+	color: white; 
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2, 
+.reveal h3, 
+.reveal h4, 
+.reveal h5, 
+.reveal h6 {
+	margin: 0 0 20px 0;
+	color: black;
+	font-family: 'News Cycle', Impact, sans-serif;
+	line-height: 0.9em;
+	
+	text-transform: uppercase;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: darkblue;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		text-shadow: none;
+		border: none;
+		border-radius: 2px;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: darkblue;
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 30px 0 0 0;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid #eee;
+	
+	-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: darkblue;
+		
+		-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: black;
+}
+	.reveal .controls a.enabled {
+		color: darkblue;
+		opacity: 1;
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: darkblue;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/flops14/_support/reveal/css/theme/sky.css b/docs/slides/flops14/_support/reveal/css/theme/sky.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/css/theme/sky.css
@@ -0,0 +1,165 @@
+/**
+ * Sky theme for reveal.js presentations.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@import url(http://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'Open Sans', sans-serif;
+	font-size: 36px;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #333;
+
+	background: #f7fbfc;
+	background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmN2ZiZmMiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjYWRkOWU0IiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+	background: -moz-radial-gradient(center, ellipse cover,  #f7fbfc 0%, #add9e4 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#f7fbfc), color-stop(100%,#add9e4));
+	background: -webkit-radial-gradient(center, ellipse cover,  #f7fbfc 0%,#add9e4 100%);
+	background: -o-radial-gradient(center, ellipse cover,  #f7fbfc 0%,#add9e4 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  #f7fbfc 0%,#add9e4 100%);
+	background: radial-gradient(ellipse at center,  #f7fbfc 0%,#add9e4 100%);
+}
+
+::-moz-selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+::-webkit-selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+::selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2, 
+.reveal h3, 
+.reveal h4, 
+.reveal h5, 
+.reveal h6 {
+	margin: 0 0 20px 0;
+	color: #333;
+	font-family: 'Quicksand', sans-serif;
+	line-height: 0.9em;
+	letter-spacing: -0.08em;
+	
+	text-transform: uppercase;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: #3b759e;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		text-shadow: none;
+		border: none;
+		border-radius: 2px;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: #3b759e;
+}
+
+
+/*********************************************
+ * MISC
+ *********************************************/
+
+.reveal section img {
+	margin: 30px 0 0 0;
+	background: rgba(255,255,255,0.12);
+	border: 1px solid #ddd;
+	
+	-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: #3b759e;
+		
+		-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+.reveal blockquote {
+	background: rgba(255, 255, 255, 0.4);
+}
+
+.reveal p {
+	margin-bottom: 20px;
+}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		color: #3b759e;
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: #3b759e;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/flops14/_support/reveal/js/.reveal.js.swo b/docs/slides/flops14/_support/reveal/js/.reveal.js.swo
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/_support/reveal/js/.reveal.js.swo differ
diff --git a/docs/slides/flops14/_support/reveal/js/.reveal.js.swp b/docs/slides/flops14/_support/reveal/js/.reveal.js.swp
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/_support/reveal/js/.reveal.js.swp differ
diff --git a/docs/slides/flops14/_support/reveal/js/.reveal.min.js.swo b/docs/slides/flops14/_support/reveal/js/.reveal.min.js.swo
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/_support/reveal/js/.reveal.min.js.swo differ
diff --git a/docs/slides/flops14/_support/reveal/js/.reveal.min.js.swp b/docs/slides/flops14/_support/reveal/js/.reveal.min.js.swp
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/_support/reveal/js/.reveal.min.js.swp differ
diff --git a/docs/slides/flops14/_support/reveal/js/reveal.js b/docs/slides/flops14/_support/reveal/js/reveal.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/js/reveal.js
@@ -0,0 +1,1149 @@
+/*!
+ * reveal.js 2.0 r22
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var Reveal = (function(){
+	
+	var HORIZONTAL_SLIDES_SELECTOR = '.reveal .slides>section',
+		VERTICAL_SLIDES_SELECTOR = '.reveal .slides>section.present>section',
+
+		IS_TOUCH_DEVICE = !!( 'ontouchstart' in window ),
+
+		// Configurations defaults, can be overridden at initialization time 
+		config = {
+			// Display controls in the bottom right corner
+			controls: true,
+
+			// Display a presentation progress bar
+			progress: true,
+
+			// Push each slide change to the browser history
+			history: false,
+
+			// Enable keyboard shortcuts for navigation
+			keyboard: true,
+
+			// Loop the presentation
+			loop: false,
+
+			// Number of milliseconds between automatically proceeding to the 
+			// next slide, disabled when set to 0
+			autoSlide: 0,
+
+			// Enable slide navigation via mouse wheel
+			mouseWheel: true,
+
+			// Apply a 3D roll to links on hover
+			rollingLinks: true,
+
+			// Transition style (see /css/theme)
+			theme: 'default', 
+
+			// Transition style
+			transition: 'default', // default/cube/page/concave/linear(2d),
+
+			// Script dependencies to load
+			dependencies: []
+		},
+
+		// The horizontal and verical index of the currently active slide
+		indexh = 0,
+		indexv = 0,
+
+		// The previous and current slide HTML elements
+		previousSlide,
+		currentSlide,
+
+		// Slides may hold a data-state attribute which we pick up and apply 
+		// as a class to the body. This list contains the combined state of 
+		// all current slides.
+		state = [],
+
+		// Cached references to DOM elements
+		dom = {},
+
+		// Detect support for CSS 3D transforms
+		supports3DTransforms =  'WebkitPerspective' in document.body.style ||
+                        		'MozPerspective' in document.body.style ||
+                        		'msPerspective' in document.body.style ||
+                        		'OPerspective' in document.body.style ||
+                        		'perspective' in document.body.style,
+        
+        supports2DTransforms =  'WebkitTransform' in document.body.style ||
+                        		'MozTransform' in document.body.style ||
+                        		'msTransform' in document.body.style ||
+                        		'OTransform' in document.body.style ||
+                        		'transform' in document.body.style,
+		
+		// Throttles mouse wheel navigation
+		mouseWheelTimeout = 0,
+
+		// An interval used to automatically move on to the next slide
+		autoSlideTimeout = 0,
+
+		// Delays updates to the URL due to a Chrome thumbnailer bug
+		writeURLTimeout = 0,
+
+		// Holds information about the currently ongoing touch input
+		touch = {
+			startX: 0,
+			startY: 0,
+			startSpan: 0,
+			startCount: 0,
+			handled: false,
+			threshold: 40
+		};
+	
+	
+	/**
+	 * Starts up the presentation if the client is capable.
+	 */
+	function initialize( options ) {
+		if( ( !supports2DTransforms && !supports3DTransforms ) ) {
+			document.body.setAttribute( 'class', 'no-transforms' );
+
+			// If the browser doesn't support core features we won't be 
+			// using JavaScript to control the presentation
+			return;
+		}
+
+		// Copy options over to our config object
+		extend( config, options );
+
+		// Cache references to DOM elements
+		dom.theme = document.querySelector( '#theme' );
+		dom.wrapper = document.querySelector( '.reveal' );
+		dom.progress = document.querySelector( '.reveal .progress' );
+		dom.progressbar = document.querySelector( '.reveal .progress span' );
+
+		if ( config.controls ) {
+			dom.controls = document.querySelector( '.reveal .controls' );
+			dom.controlsLeft = document.querySelector( '.reveal .controls .left' );
+			dom.controlsRight = document.querySelector( '.reveal .controls .right' );
+			dom.controlsUp = document.querySelector( '.reveal .controls .up' );
+			dom.controlsDown = document.querySelector( '.reveal .controls .down' );
+		}
+
+		// Loads the dependencies and continues to #start() once done
+		load();
+
+		// Set up hiding of the browser address bar
+		if( navigator.userAgent.match( /(iphone|ipod|android)/i ) ) {
+			// Give the page some scrollable overflow
+			document.documentElement.style.overflow = 'scroll';
+			document.body.style.height = '120%';
+
+			// Events that should trigger the address bar to hide
+			window.addEventListener( 'load', removeAddressBar, false );
+			window.addEventListener( 'orientationchange', removeAddressBar, false );
+		}
+		
+	}
+
+	/**
+	 * Loads the dependencies of reveal.js. Dependencies are 
+	 * defined via the configuration option 'dependencies' 
+	 * and will be loaded prior to starting/binding reveal.js. 
+	 * Some dependencies may have an 'async' flag, if so they 
+	 * will load after reveal.js has been started up.
+	 */
+	function load() {
+		var scripts = [],
+			scriptsAsync = [];
+
+		for( var i = 0, len = config.dependencies.length; i < len; i++ ) {
+			var s = config.dependencies[i];
+
+			// Load if there's no condition or the condition is truthy
+			if( !s.condition || s.condition() ) {
+				if( s.async ) {
+					scriptsAsync.push( s.src );
+				}
+				else {
+					scripts.push( s.src );
+				}
+
+				// Extension may contain callback functions
+				if( typeof s.callback === 'function' ) {
+					head.ready( s.src.match( /([\w\d_-]*)\.?[^\\\/]*$/i )[0], s.callback );
+				}
+			}
+		}
+
+		// Called once synchronous scritps finish loading
+		function proceed() {
+			// Load asynchronous scripts
+			head.js.apply( null, scriptsAsync );
+			
+			start();
+		}
+
+		if( scripts.length ) {
+			head.ready( proceed );
+
+			// Load synchronous scripts
+			head.js.apply( null, scripts );
+		}
+		else {
+			proceed();
+		}
+	}
+
+	/**
+	 * Starts up reveal.js by binding input events and navigating 
+	 * to the current URL deeplink if there is one.
+	 */
+	function start() {
+		// Subscribe to input
+		addEventListeners();
+
+		// Updates the presentation to match the current configuration values
+		configure();
+
+		// Read the initial hash
+		readURL();
+
+		// Start auto-sliding if it's enabled
+		cueAutoSlide();
+	}
+
+	/**
+	 * Applies the configuration settings from the config object.
+	 */
+	function configure() {
+		if( supports3DTransforms === false ) {
+			config.transition = 'linear';
+		}
+
+		if( config.controls && dom.controls ) {
+			dom.controls.style.display = 'block';
+		}
+
+		if( config.progress && dom.progress ) {
+			dom.progress.style.display = 'block';
+		}
+
+		// Load the theme in the config, if it's not already loaded
+		if( config.theme && dom.theme ) {
+			var themeURL = dom.theme.getAttribute( 'href' );
+			var themeFinder = /[^/]*?(?=\.css)/;
+			var themeName = themeURL.match(themeFinder)[0];
+			if(  config.theme !== themeName ) {
+				themeURL = themeURL.replace(themeFinder, config.theme);
+				dom.theme.setAttribute( 'href', themeURL );
+			}
+		}
+
+
+		if( config.transition !== 'default' ) {
+			dom.wrapper.classList.add( config.transition );
+		}
+
+		if( config.mouseWheel ) {
+			document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
+			document.addEventListener( 'mousewheel', onDocumentMouseScroll, false );
+		}
+
+		if( config.rollingLinks ) {
+			// Add some 3D magic to our anchors
+			linkify();
+		}
+	}
+
+	function addEventListeners() {
+		document.addEventListener( 'touchstart', onDocumentTouchStart, false );
+		document.addEventListener( 'touchmove', onDocumentTouchMove, false );
+		document.addEventListener( 'touchend', onDocumentTouchEnd, false );
+		window.addEventListener( 'hashchange', onWindowHashChange, false );
+
+		if( config.keyboard ) {
+			document.addEventListener( 'keydown', onDocumentKeyDown, false );
+		}
+
+		if ( config.controls && dom.controls ) {
+			dom.controlsLeft.addEventListener( 'click', preventAndForward( navigateLeft ), false );
+			dom.controlsRight.addEventListener( 'click', preventAndForward( navigateRight ), false );
+			dom.controlsUp.addEventListener( 'click', preventAndForward( navigateUp ), false );
+			dom.controlsDown.addEventListener( 'click', preventAndForward( navigateDown ), false );	
+		}
+	}
+
+	function removeEventListeners() {
+		document.removeEventListener( 'keydown', onDocumentKeyDown, false );
+		document.removeEventListener( 'touchstart', onDocumentTouchStart, false );
+		document.removeEventListener( 'touchmove', onDocumentTouchMove, false );
+		document.removeEventListener( 'touchend', onDocumentTouchEnd, false );
+		window.removeEventListener( 'hashchange', onWindowHashChange, false );
+		
+		if ( config.controls && dom.controls ) {
+			dom.controlsLeft.removeEventListener( 'click', preventAndForward( navigateLeft ), false );
+			dom.controlsRight.removeEventListener( 'click', preventAndForward( navigateRight ), false );
+			dom.controlsUp.removeEventListener( 'click', preventAndForward( navigateUp ), false );
+			dom.controlsDown.removeEventListener( 'click', preventAndForward( navigateDown ), false );
+		}
+	}
+
+	/**
+	 * Extend object a with the properties of object b. 
+	 * If there's a conflict, object b takes precedence.
+	 */
+	function extend( a, b ) {
+		for( var i in b ) {
+			a[ i ] = b[ i ];
+		}
+	}
+
+	/**
+	 * Measures the distance in pixels between point a
+	 * and point b. 
+	 * 
+	 * @param {Object} a point with x/y properties
+	 * @param {Object} b point with x/y properties
+	 */
+	function distanceBetween( a, b ) {
+		var dx = a.x - b.x,
+			dy = a.y - b.y;
+
+		return Math.sqrt( dx*dx + dy*dy );
+	}
+
+	/**
+	 * Prevents an events defaults behavior calls the 
+	 * specified delegate.
+	 * 
+	 * @param {Function} delegate The method to call 
+	 * after the wrapper has been executed
+	 */
+	function preventAndForward( delegate ) {
+		return function( event ) {
+			event.preventDefault();
+			delegate.call();
+		}
+	}
+
+	/**
+	 * Causes the address bar to hide on mobile devices, 
+	 * more vertical space ftw.
+	 */
+	function removeAddressBar() {
+		setTimeout( function() {
+			window.scrollTo( 0, 1 );
+		}, 0 );
+	}
+	
+	/**
+	 * Handler for the document level 'keydown' event.
+	 * 
+	 * @param {Object} event
+	 */
+	function onDocumentKeyDown( event ) {
+		// FFT: Use document.querySelector( ':focus' ) === null 
+		// instead of checking contentEditable?
+
+		// Disregard the event if the target is editable or a 
+		// modifier is present
+		if ( event.target.contentEditable != 'inherit' || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+				
+		var triggered = false;
+
+		switch( event.keyCode ) {
+			// p, page up
+			case 80: case 33: navigatePrev(); triggered = true; break; 
+			// n, page down
+			case 78: case 34: navigateNext(); triggered = true; break;
+			// h, left
+			case 72: case 37: navigateLeft(); triggered = true; break;
+			// l, right
+			case 76: case 39: navigateRight(); triggered = true; break;
+			// k, up
+			case 75: case 38: navigateUp(); triggered = true; break;
+			// j, down
+			case 74: case 40: navigateDown(); triggered = true; break;
+			// home
+			case 36: navigateTo( 0 ); triggered = true; break;
+			// end
+			case 35: navigateTo( Number.MAX_VALUE ); triggered = true; break;
+			// space
+			case 32: overviewIsActive() ? deactivateOverview() : navigateNext(); triggered = true; break;
+			// return
+			case 13: if( overviewIsActive() ) { deactivateOverview(); triggered = true; } break;
+		}
+
+		// If the input resulted in a triggered action we should prevent 
+		// the browsers default behavior
+		if( triggered ) {
+			event.preventDefault();
+		}
+		else if ( event.keyCode === 27 && supports3DTransforms ) {
+			toggleOverview();
+	
+			event.preventDefault();
+		}
+
+		// If auto-sliding is enabled we need to cue up 
+		// another timeout
+		cueAutoSlide();
+
+	}
+
+	/**
+	 * Handler for the document level 'touchstart' event,
+	 * enables support for swipe and pinch gestures.
+	 */
+	function onDocumentTouchStart( event ) {
+		touch.startX = event.touches[0].clientX;
+		touch.startY = event.touches[0].clientY;
+		touch.startCount = event.touches.length;
+
+		// If there's two touches we need to memorize the distance 
+		// between those two points to detect pinching
+		if( event.touches.length === 2 ) {
+			touch.startSpan = distanceBetween( {
+				x: event.touches[1].clientX,
+				y: event.touches[1].clientY
+			}, {
+				x: touch.startX,
+				y: touch.startY
+			} );
+		}
+	}
+	
+	/**
+	 * Handler for the document level 'touchmove' event.
+	 */
+	function onDocumentTouchMove( event ) {
+		// Each touch should only trigger one action
+		if( !touch.handled ) {
+			var currentX = event.touches[0].clientX;
+			var currentY = event.touches[0].clientY;
+
+			// If the touch started off with two points and still has 
+			// two active touches; test for the pinch gesture
+			if( event.touches.length === 2 && touch.startCount === 2 ) {
+
+				// The current distance in pixels between the two touch points
+				var currentSpan = distanceBetween( {
+					x: event.touches[1].clientX,
+					y: event.touches[1].clientY
+				}, {
+					x: touch.startX,
+					y: touch.startY
+				} );
+
+				// If the span is larger than the desire amount we've got 
+				// ourselves a pinch
+				if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
+					touch.handled = true;
+
+					if( currentSpan < touch.startSpan ) {
+						activateOverview();
+					}
+					else {
+						deactivateOverview();
+					}
+				}
+
+			}
+			// There was only one touch point, look for a swipe
+			else if( event.touches.length === 1 ) {
+				var deltaX = currentX - touch.startX,
+					deltaY = currentY - touch.startY;
+
+				if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					touch.handled = true;
+					navigateLeft();
+				} 
+				else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					touch.handled = true;
+					navigateRight();
+				} 
+				else if( deltaY > touch.threshold ) {
+					touch.handled = true;
+					navigateUp();
+				} 
+				else if( deltaY < -touch.threshold ) {
+					touch.handled = true;
+					navigateDown();
+				}
+			}
+
+			event.preventDefault();
+		}
+	}
+
+	/**
+	 * Handler for the document level 'touchend' event.
+	 */
+	function onDocumentTouchEnd( event ) {
+		touch.handled = false;
+	}
+
+	/**
+	 * Handles mouse wheel scrolling, throttled to avoid 
+	 * skipping multiple slides.
+	 */
+	function onDocumentMouseScroll( event ){
+		clearTimeout( mouseWheelTimeout );
+
+		mouseWheelTimeout = setTimeout( function() {
+			var delta = event.detail || -event.wheelDelta;
+			if( delta > 0 ) {
+				navigateNext();
+			}
+			else {
+				navigatePrev();
+			}
+		}, 100 );
+	}
+	
+	/**
+	 * Handler for the window level 'hashchange' event.
+	 * 
+	 * @param {Object} event
+	 */
+	function onWindowHashChange( event ) {
+		readURL();
+	}
+
+	/**
+	 * Wrap all links in 3D goodness.
+	 */
+	function linkify() {
+		if( supports3DTransforms && !( 'msPerspective' in document.body.style ) ) {
+        	var nodes = document.querySelectorAll( '.reveal .slides section a:not(.image)' );
+
+	        for( var i = 0, len = nodes.length; i < len; i++ ) {
+	            var node = nodes[i];
+	            
+	            if( node.textContent && !node.querySelector( 'img' ) && ( !node.className || !node.classList.contains( node, 'roll' ) ) ) {
+	                node.classList.add( 'roll' );
+	                node.innerHTML = '<span data-title="'+ node.text +'">' + node.innerHTML + '</span>';
+	            }
+	        };
+        }
+	}
+
+	/**
+	 * Displays the overview of slides (quick nav) by 
+	 * scaling down and arranging all slide elements.
+	 * 
+	 * Experimental feature, might be dropped if perf 
+	 * can't be improved.
+	 */
+	function activateOverview() {
+		
+		dom.wrapper.classList.add( 'overview' );
+
+		var horizontalSlides = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+
+		for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
+			var hslide = horizontalSlides[i],
+				htransform = 'translateZ(-2500px) translate(' + ( ( i - indexh ) * 105 ) + '%, 0%)';
+			
+			hslide.setAttribute( 'data-index-h', i );
+			hslide.style.display = 'block';
+			hslide.style.WebkitTransform = htransform;
+			hslide.style.MozTransform = htransform;
+			hslide.style.msTransform = htransform;
+			hslide.style.OTransform = htransform;
+			hslide.style.transform = htransform;
+		
+			if( !hslide.classList.contains( 'stack' ) ) {
+				// Navigate to this slide on click
+				hslide.addEventListener( 'click', onOverviewSlideClicked, true );
+			}
+	
+			var verticalSlides = Array.prototype.slice.call( hslide.querySelectorAll( 'section' ) );
+
+			for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
+				var vslide = verticalSlides[j],
+					vtransform = 'translate(0%, ' + ( ( j - ( i === indexh ? indexv : 0 ) ) * 105 ) + '%)';
+
+				vslide.setAttribute( 'data-index-h', i );
+				vslide.setAttribute( 'data-index-v', j );
+				vslide.style.display = 'block';
+				vslide.style.WebkitTransform = vtransform;
+				vslide.style.MozTransform = vtransform;
+				vslide.style.msTransform = vtransform;
+				vslide.style.OTransform = vtransform;
+				vslide.style.transform = vtransform;
+
+				// Navigate to this slide on click
+				vslide.addEventListener( 'click', onOverviewSlideClicked, true );
+			}
+			
+		}
+	}
+	
+	/**
+	 * Exits the slide overview and enters the currently
+	 * active slide.
+	 */
+	function deactivateOverview() {
+		dom.wrapper.classList.remove( 'overview' );
+
+		var slides = Array.prototype.slice.call( document.querySelectorAll( '.reveal .slides section' ) );
+
+		for( var i = 0, len = slides.length; i < len; i++ ) {
+			var element = slides[i];
+
+			// Resets all transforms to use the external styles
+			element.style.WebkitTransform = '';
+			element.style.MozTransform = '';
+			element.style.msTransform = '';
+			element.style.OTransform = '';
+			element.style.transform = '';
+
+			element.removeEventListener( 'click', onOverviewSlideClicked );
+		}
+
+		slide();
+	}
+
+	/**
+	 * Checks if the overview is currently active.
+	 * 
+	 * @return {Boolean} true if the overview is active,
+	 * false otherwise
+	 */
+	function overviewIsActive() {
+		return dom.wrapper.classList.contains( 'overview' );
+	}
+
+	/**
+	 * Invoked when a slide is and we're in the overview.
+	 */
+	function onOverviewSlideClicked( event ) {
+		// TODO There's a bug here where the event listeners are not 
+		// removed after deactivating the overview.
+		if( overviewIsActive() ) {
+			event.preventDefault();
+
+			deactivateOverview();
+
+			indexh = this.getAttribute( 'data-index-h' );
+			indexv = this.getAttribute( 'data-index-v' );
+
+			slide();
+		}
+	}
+
+	/**
+	 * Updates one dimension of slides by showing the slide
+	 * with the specified index.
+	 * 
+	 * @param {String} selector A CSS selector that will fetch
+	 * the group of slides we are working with
+	 * @param {Number} index The index of the slide that should be
+	 * shown
+	 * 
+	 * @return {Number} The index of the slide that is now shown,
+	 * might differ from the passed in index if it was out of 
+	 * bounds.
+	 */
+	function updateSlides( selector, index ) {
+		
+		// Select all slides and convert the NodeList result to
+		// an array
+		var slides = Array.prototype.slice.call( document.querySelectorAll( selector ) ),
+			slidesLength = slides.length;
+		
+		if( slidesLength ) {
+
+			// Should the index loop?
+			if( config.loop ) {
+				index %= slidesLength;
+
+				if( index < 0 ) {
+					index = slidesLength + index;
+				}
+			}
+			
+			// Enforce max and minimum index bounds
+			index = Math.max( Math.min( index, slidesLength - 1 ), 0 );
+			
+			for( var i = 0; i < slidesLength; i++ ) {
+				var slide = slides[i];
+
+				// Optimization; hide all slides that are three or more steps 
+				// away from the present slide
+				if( overviewIsActive() === false ) {
+					// The distance loops so that it measures 1 between the first
+					// and last slides
+					var distance = Math.abs( ( index - i ) % ( slidesLength - 3 ) ) || 0;
+
+					slide.style.display = distance > 3 ? 'none' : 'block';
+				}
+
+				slides[i].classList.remove( 'past' );
+				slides[i].classList.remove( 'present' );
+				slides[i].classList.remove( 'future' );
+
+				if( i < index ) {
+					// Any element previous to index is given the 'past' class
+					slides[i].classList.add( 'past' );
+				}
+				else if( i > index ) {
+					// Any element subsequent to index is given the 'future' class
+					slides[i].classList.add( 'future' );
+				}
+
+				// If this element contains vertical slides
+				if( slide.querySelector( 'section' ) ) {
+					slides[i].classList.add( 'stack' );
+				}
+			}
+
+			// Mark the current slide as present
+			slides[index].classList.add( 'present' );
+
+			// If this slide has a state associated with it, add it
+			// onto the current state of the deck
+			var slideState = slides[index].getAttribute( 'data-state' );
+			if( slideState ) {
+				state = state.concat( slideState.split( ' ' ) );
+			}
+		}
+		else {
+			// Since there are no slides we can't be anywhere beyond the 
+			// zeroth index
+			index = 0;
+		}
+		
+		return index;
+		
+	}
+	
+	/**
+	 * Updates the visual slides to represent the currently
+	 * set indices. 
+	 */
+	function slide( h, v ) {
+		// Remember where we were at before
+		previousSlide = currentSlide;
+
+		// Remember the state before this slide
+		var stateBefore = state.concat();
+
+		// Reset the state array
+		state.length = 0;
+
+		var indexhBefore = indexh,
+			indexvBefore = indexv;
+
+		// Activate and transition to the new slide
+		indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
+		indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
+
+		// Apply the new state
+		stateLoop: for( var i = 0, len = state.length; i < len; i++ ) {
+			// Check if this state existed on the previous slide. If it 
+			// did, we will avoid adding it repeatedly.
+			for( var j = 0; j < stateBefore.length; j++ ) {
+				if( stateBefore[j] === state[i] ) {
+					stateBefore.splice( j, 1 );
+					continue stateLoop;
+				}
+			}
+
+			document.documentElement.classList.add( state[i] );
+
+			// Dispatch custom event matching the state's name
+			dispatchEvent( state[i] );
+		}
+
+		// Clean up the remaints of the previous state
+		while( stateBefore.length ) {
+			document.documentElement.classList.remove( stateBefore.pop() );
+		}
+
+		// Update progress if enabled
+		if( config.progress && dom.progress ) {
+			dom.progressbar.style.width = ( indexh / ( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length - 1 ) ) * window.innerWidth + 'px';
+		}
+
+		// Close the overview if it's active
+		if( overviewIsActive() ) {
+			activateOverview();
+		}
+
+		updateControls();
+		
+		clearTimeout( writeURLTimeout );
+		writeURLTimeout = setTimeout( writeURL, 1500 );
+
+		// Query all horizontal slides in the deck
+		var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+
+		// Find the current horizontal slide and any possible vertical slides
+		// within it
+		var currentHorizontalSlide = horizontalSlides[ indexh ],
+			currentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' );
+
+		// Store references to the previous and current slides
+		currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;
+
+		// Dispatch an event if the slide changed
+		if( indexh !== indexhBefore || indexv !== indexvBefore ) {
+			dispatchEvent( 'slidechanged', {
+				'indexh': indexh, 
+				'indexv': indexv,
+				'previousSlide': previousSlide,
+				'currentSlide': currentSlide
+			} );
+		}
+		else {
+			// Ensure that the previous slide is never the same as the current
+			previousSlide = null;
+		}
+
+		// Solves an edge case where the previous slide maintains the 
+		// 'present' class when navigating between adjacent vertical 
+		// stacks
+		if( previousSlide ) {
+			previousSlide.classList.remove( 'present' );
+		}
+	}
+
+	/**
+	 * Updates the state and link pointers of the controls.
+	 */
+	function updateControls() {
+		if ( !config.controls || !dom.controls ) {
+			return;
+		}
+		
+		var routes = availableRoutes();
+
+		// Remove the 'enabled' class from all directions
+		[ dom.controlsLeft, dom.controlsRight, dom.controlsUp, dom.controlsDown ].forEach( function( node ) {
+			node.classList.remove( 'enabled' );
+		} )
+
+		if( routes.left ) dom.controlsLeft.classList.add( 'enabled' );
+		if( routes.right ) dom.controlsRight.classList.add( 'enabled' );
+		if( routes.up ) dom.controlsUp.classList.add( 'enabled' );
+		if( routes.down ) dom.controlsDown.classList.add( 'enabled' );
+	}
+
+	/**
+	 * Determine what available routes there are for navigation.
+	 * 
+	 * @return {Object} containing four booleans: left/right/up/down
+	 */
+	function availableRoutes() {
+		var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+		var verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
+
+		return {
+			left: indexh > 0,
+			right: indexh < horizontalSlides.length - 1,
+			up: indexv > 0,
+			down: indexv < verticalSlides.length - 1
+		};
+	}
+	
+	/**
+	 * Reads the current URL (hash) and navigates accordingly.
+	 */
+	function readURL() {
+		var hash = window.location.hash;
+
+		// Attempt to parse the hash as either an index or name
+		var bits = hash.slice( 2 ).split( '/' ),
+			name = hash.replace( /#|\//gi, '' );
+
+		// If the first bit is invalid and there is a name we can 
+		// assume that this is a named link
+		if( isNaN( parseInt( bits[0] ) ) && name.length ) {
+			// Find the slide with the specified name
+			var slide = document.querySelector( '#' + name );
+
+			if( slide ) {
+				// Find the position of the named slide and navigate to it
+				var indices = Reveal.getIndices( slide );
+				navigateTo( indices.h, indices.v );
+			}
+			// If the slide doesn't exist, navigate to the current slide
+			else {
+				navigateTo( indexh, indexv );
+			}
+		}
+		else {
+			// Read the index components of the hash
+			var h = parseInt( bits[0] ) || 0,
+				v = parseInt( bits[1] ) || 0;
+
+			navigateTo( h, v );
+		}
+	}
+	
+	/**
+	 * Updates the page URL (hash) to reflect the current
+	 * state. 
+	 */
+	function writeURL() {
+		if( config.history ) {
+			var url = '/';
+			
+			// Only include the minimum possible number of components in
+			// the URL
+			if( indexh > 0 || indexv > 0 ) url += indexh;
+			if( indexv > 0 ) url += '/' + indexv;
+			
+			window.location.hash = url;
+		}
+	}
+
+	/**
+	 * Dispatches an event of the specified type from the 
+	 * reveal DOM element.
+	 */
+	function dispatchEvent( type, properties ) {
+		var event = document.createEvent( "HTMLEvents", 1, 2 );
+		event.initEvent( type, true, true );
+		extend( event, properties );
+		dom.wrapper.dispatchEvent( event );
+	}
+
+	/**
+	 * Navigate to the next slide fragment.
+	 * 
+	 * @return {Boolean} true if there was a next fragment,
+	 * false otherwise
+	 */
+	function nextFragment() {
+		// Vertical slides:
+		if( document.querySelector( VERTICAL_SLIDES_SELECTOR + '.present' ) ) {
+			var verticalFragments = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR + '.present .fragment:not(.visible)' );
+			if( verticalFragments.length ) {
+				verticalFragments[0].classList.add( 'visible' );
+
+				// Notify subscribers of the change
+				dispatchEvent( 'fragmentshown', { fragment: verticalFragments[0] } );
+				return true;
+			}
+		}
+		// Horizontal slides:
+		else {
+			var horizontalFragments = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.present .fragment:not(.visible)' );
+			if( horizontalFragments.length ) {
+				horizontalFragments[0].classList.add( 'visible' );
+
+				// Notify subscribers of the change
+				dispatchEvent( 'fragmentshown', { fragment: horizontalFragments[0] } );
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Navigate to the previous slide fragment.
+	 * 
+	 * @return {Boolean} true if there was a previous fragment,
+	 * false otherwise
+	 */
+	function previousFragment() {
+		// Vertical slides:
+		if( document.querySelector( VERTICAL_SLIDES_SELECTOR + '.present' ) ) {
+			var verticalFragments = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR + '.present .fragment.visible' );
+			if( verticalFragments.length ) {
+				verticalFragments[ verticalFragments.length - 1 ].classList.remove( 'visible' );
+
+				// Notify subscribers of the change
+				dispatchEvent( 'fragmenthidden', { fragment: verticalFragments[ verticalFragments.length - 1 ] } );
+				return true;
+			}
+		}
+		// Horizontal slides:
+		else {
+			var horizontalFragments = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.present .fragment.visible' );
+			if( horizontalFragments.length ) {
+				horizontalFragments[ horizontalFragments.length - 1 ].classList.remove( 'visible' );
+
+				// Notify subscribers of the change
+				dispatchEvent( 'fragmenthidden', { fragment: horizontalFragments[ horizontalFragments.length - 1 ] } );
+				return true;
+			}
+		}
+		
+		return false;
+	}
+
+	function cueAutoSlide() {
+		clearTimeout( autoSlideTimeout );
+
+		// Cue the next auto-slide if enabled
+		if( config.autoSlide ) {
+			autoSlideTimeout = setTimeout( navigateNext, config.autoSlide );
+		}
+	}
+	
+	/**
+	 * Triggers a navigation to the specified indices.
+	 * 
+	 * @param {Number} h The horizontal index of the slide to show
+	 * @param {Number} v The vertical index of the slide to show
+	 */
+	function navigateTo( h, v ) {
+		slide( h, v );
+	}
+	
+	function navigateLeft() {
+		// Prioritize hiding fragments
+		if( overviewIsActive() || previousFragment() === false ) {
+			slide( indexh - 1, 0 );
+		}
+	}
+	function navigateRight() {
+		// Prioritize revealing fragments
+		if( overviewIsActive() || nextFragment() === false ) {
+			slide( indexh + 1, 0 );
+		}
+	}
+	function navigateUp() {
+		// Prioritize hiding fragments
+		if( overviewIsActive() || previousFragment() === false ) {
+			slide( indexh, indexv - 1 );
+		}
+	}
+	function navigateDown() {
+		// Prioritize revealing fragments
+		if( overviewIsActive() || nextFragment() === false ) {
+			slide( indexh, indexv + 1 );
+		}
+	}
+
+	/**
+	 * Navigates backwards, prioritized in the following order:
+	 * 1) Previous fragment
+	 * 2) Previous vertical slide
+	 * 3) Previous horizontal slide
+	 */
+	function navigatePrev() {
+		// Prioritize revealing fragments
+		if( previousFragment() === false ) {
+			if( availableRoutes().up ) {
+				navigateUp();
+			}
+			else {
+				// Fetch the previous horizontal slide, if there is one
+				var previousSlide = document.querySelector( '.reveal .slides>section.past:nth-child(' + indexh + ')' );
+
+				if( previousSlide ) {
+					indexv = ( previousSlide.querySelectorAll('section').length + 1 ) || 0;
+					indexh --;
+					slide();
+				}
+			}
+		}
+	}
+
+	/**
+	 * Same as #navigatePrev() but navigates forwards.
+	 */
+	function navigateNext() {
+		// Prioritize revealing fragments
+		if( nextFragment() === false ) {
+			availableRoutes().down ? navigateDown() : navigateRight();
+		}
+
+		// If auto-sliding is enabled we need to cue up 
+		// another timeout
+		cueAutoSlide();
+	}
+
+	/**
+	 * Toggles the slide overview mode on and off.
+	 */
+	function toggleOverview() {
+		if( overviewIsActive() ) {
+			deactivateOverview();
+		}
+		else {
+			activateOverview();
+		}
+	}
+	
+	// Expose some methods publicly
+	return {
+		initialize: initialize,
+		navigateTo: navigateTo,
+		navigateLeft: navigateLeft,
+		navigateRight: navigateRight,
+		navigateUp: navigateUp,
+		navigateDown: navigateDown,
+		navigatePrev: navigatePrev,
+		navigateNext: navigateNext,
+		toggleOverview: toggleOverview,
+
+		// Adds or removes all internal event listeners (such as keyboard)
+		addEventListeners: addEventListeners,
+		removeEventListeners: removeEventListeners,
+
+		// Returns the indices of the current, or specified, slide
+		getIndices: function( slide ) {
+			// By default, return the current indices
+			var h = indexh,
+				v = indexv;
+
+			// If a slide is specified, return the indices of that slide
+			if( slide ) {
+				var isVertical = !!slide.parentNode.nodeName.match( /section/gi );
+				var slideh = isVertical ? slide.parentNode : slide;
+
+				// Select all horizontal slides
+				var horizontalSlides = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+
+				// Now that we know which the horizontal slide is, get its index
+				h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
+
+				// If this is a vertical slide, grab the vertical index
+				if( isVertical ) {
+					v = Math.max( Array.prototype.slice.call( slide.parentNode.children ).indexOf( slide ), 0 );
+				}
+			}
+
+			return { h: h, v: v };
+		},
+
+		// Returns the previous slide element, may be null
+		getPreviousSlide: function() {
+			return previousSlide
+		},
+
+		// Returns the current slide element
+		getCurrentSlide: function() {
+			return currentSlide
+		},
+
+		// Helper method, retrieves query string as a key/value hash
+		getQueryHash: function() {
+			var query = {};
+
+			location.search.replace( /[A-Z0-9]+?=(\w*)/gi, function(a) {
+				query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
+			} );
+
+			return query;
+		},
+
+		// Forward event binding to the reveal DOM element
+		addEventListener: function( type, listener, useCapture ) {
+			if( 'addEventListener' in window ) {
+				( dom.wrapper || document.querySelector( '.reveal' ) ).addEventListener( type, listener, useCapture );
+			}
+		},
+		removeEventListener: function( type, listener, useCapture ) {
+			if( 'addEventListener' in window ) {
+				( dom.wrapper || document.querySelector( '.reveal' ) ).removeEventListener( type, listener, useCapture );
+			}
+		}
+	};
+	
+})();
diff --git a/docs/slides/flops14/_support/reveal/js/reveal.min.js b/docs/slides/flops14/_support/reveal/js/reveal.min.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/js/reveal.min.js
@@ -0,0 +1,8 @@
+/*!
+ * reveal.js 2.0 r22
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var Reveal=(function(){var k=".reveal .slides>section",b=".reveal .slides>section.present>section",e=!!("ontouchstart" in window),N={controls:true,progress:true,history:false,keyboard:true,loop:false,autoSlide:0,mouseWheel:true,rollingLinks:true,theme:"default",transition:"default",dependencies:[]},l=0,c=0,w,E,ac=[],d={},P="WebkitPerspective" in document.body.style||"MozPerspective" in document.body.style||"msPerspective" in document.body.style||"OPerspective" in document.body.style||"perspective" in document.body.style,m="WebkitTransform" in document.body.style||"MozTransform" in document.body.style||"msTransform" in document.body.style||"OTransform" in document.body.style||"transform" in document.body.style,x=0,j=0,B=0,W={startX:0,startY:0,startSpan:0,startCount:0,handled:false,threshold:40};function h(ad){if((!m&&!P)){document.body.setAttribute("class","no-transforms");return}r(N,ad);d.theme=document.querySelector("#theme");d.wrapper=document.querySelector(".reveal");d.progress=document.querySelector(".reveal .progress");d.progressbar=document.querySelector(".reveal .progress span");if(N.controls){d.controls=document.querySelector(".reveal .controls");d.controlsLeft=document.querySelector(".reveal .controls .left");d.controlsRight=document.querySelector(".reveal .controls .right");d.controlsUp=document.querySelector(".reveal .controls .up");d.controlsDown=document.querySelector(".reveal .controls .down")}R();if(navigator.userAgent.match(/(iphone|ipod|android)/i)){document.documentElement.style.overflow="scroll";document.body.style.height="120%";window.addEventListener("load",X,false);window.addEventListener("orientationchange",X,false)}}function R(){var ae=[],ai=[];for(var af=0,ad=N.dependencies.length;af<ad;af++){var ag=N.dependencies[af];if(!ag.condition||ag.condition()){if(ag.async){ai.push(ag.src)}else{ae.push(ag.src)}if(typeof ag.callback==="function"){head.ready(ag.src.match(/([\w\d_-]*)\.?[^\\\/]*$/i)[0],ag.callback)}}}function ah(){head.js.apply(null,ai);F()}if(ae.length){head.ready(ah);head.js.apply(null,ae)}else{ah()}}function F(){C();I();H();K()}function I(){if(P===false){N.transition="linear"}if(N.controls&&d.controls){d.controls.style.display="block"}if(N.progress&&d.progress){d.progress.style.display="block"}if(N.theme&&d.theme){var af=d.theme.getAttribute("href");var ad=/[^/]*?(?=\.css)/;var ae=af.match(ad)[0];if(N.theme!==ae){af=af.replace(ad,N.theme);d.theme.setAttribute("href",af)}}if(N.transition!=="default"){d.wrapper.classList.add(N.transition)}if(N.mouseWheel){document.addEventListener("DOMMouseScroll",n,false);document.addEventListener("mousewheel",n,false)}if(N.rollingLinks){J()}}function C(){document.addEventListener("touchstart",y,false);document.addEventListener("touchmove",Z,false);document.addEventListener("touchend",S,false);window.addEventListener("hashchange",u,false);if(N.keyboard){document.addEventListener("keydown",aa,false)}if(N.controls&&d.controls){d.controlsLeft.addEventListener("click",o(z),false);d.controlsRight.addEventListener("click",o(i),false);d.controlsUp.addEventListener("click",o(s),false);d.controlsDown.addEventListener("click",o(D),false)}}function Q(){document.removeEventListener("keydown",aa,false);document.removeEventListener("touchstart",y,false);document.removeEventListener("touchmove",Z,false);document.removeEventListener("touchend",S,false);window.removeEventListener("hashchange",u,false);if(N.controls&&d.controls){d.controlsLeft.removeEventListener("click",o(z),false);d.controlsRight.removeEventListener("click",o(i),false);d.controlsUp.removeEventListener("click",o(s),false);d.controlsDown.removeEventListener("click",o(D),false)}}function r(ae,ad){for(var af in ad){ae[af]=ad[af]}}function O(af,ad){var ag=af.x-ad.x,ae=af.y-ad.y;return Math.sqrt(ag*ag+ae*ae)}function o(ad){return function(ae){ae.preventDefault();ad.call()}}function X(){setTimeout(function(){window.scrollTo(0,1)},0)}function aa(ae){if(ae.target.contentEditable!="inherit"||ae.shiftKey||ae.altKey||ae.ctrlKey||ae.metaKey){return}var ad=false;switch(ae.keyCode){case 80:case 33:U();ad=true;break;case 78:case 34:v();ad=true;break;case 72:case 37:z();ad=true;break;case 76:case 39:i();ad=true;break;case 75:case 38:s();ad=true;break;case 74:case 40:D();ad=true;break;case 36:L(0);ad=true;break;case 35:L(Number.MAX_VALUE);ad=true;break;case 32:V()?Y():v();ad=true;break;case 13:if(V()){Y();ad=true}break}if(ad){ae.preventDefault()}else{if(ae.keyCode===27&&P){T();ae.preventDefault()}}K()}function y(ad){W.startX=ad.touches[0].clientX;W.startY=ad.touches[0].clientY;W.startCount=ad.touches.length;if(ad.touches.length===2){W.startSpan=O({x:ad.touches[1].clientX,y:ad.touches[1].clientY},{x:W.startX,y:W.startY})}}function Z(ai){if(!W.handled){var ag=ai.touches[0].clientX;var af=ai.touches[0].clientY;if(ai.touches.length===2&&W.startCount===2){var ah=O({x:ai.touches[1].clientX,y:ai.touches[1].clientY},{x:W.startX,y:W.startY});if(Math.abs(W.startSpan-ah)>W.threshold){W.handled=true;if(ah<W.startSpan){G()}else{Y()}}}else{if(ai.touches.length===1){var ae=ag-W.startX,ad=af-W.startY;if(ae>W.threshold&&Math.abs(ae)>Math.abs(ad)){W.handled=true;z()}else{if(ae<-W.threshold&&Math.abs(ae)>Math.abs(ad)){W.handled=true;i()}else{if(ad>W.threshold){W.handled=true;s()}else{if(ad<-W.threshold){W.handled=true;D()}}}}}}ai.preventDefault()}}function S(ad){W.handled=false}function n(ad){clearTimeout(x);x=setTimeout(function(){var ae=ad.detail||-ad.wheelDelta;if(ae>0){v()}else{U()}},100)}function u(ad){H()}function J(){if(P&&!("msPerspective" in document.body.style)){var ae=document.querySelectorAll(".reveal .slides section a:not(.image)");for(var af=0,ad=ae.length;af<ad;af++){var ag=ae[af];if(ag.textContent&&!ag.querySelector("img")&&(!ag.className||!ag.classList.contains(ag,"roll"))){ag.classList.add("roll");ag.innerHTML='<span data-title="'+ag.text+'">'+ag.innerHTML+"</span>"}}}}function G(){d.wrapper.classList.add("overview");var ad=Array.prototype.slice.call(document.querySelectorAll(k));for(var ai=0,ag=ad.length;ai<ag;ai++){var af=ad[ai],am="translateZ(-2500px) translate("+((ai-l)*105)+"%, 0%)";af.setAttribute("data-index-h",ai);af.style.display="block";af.style.WebkitTransform=am;af.style.MozTransform=am;af.style.msTransform=am;af.style.OTransform=am;af.style.transform=am;if(!af.classList.contains("stack")){af.addEventListener("click",A,true)}var al=Array.prototype.slice.call(af.querySelectorAll("section"));for(var ah=0,ae=al.length;ah<ae;ah++){var ak=al[ah],aj="translate(0%, "+((ah-(ai===l?c:0))*105)+"%)";ak.setAttribute("data-index-h",ai);ak.setAttribute("data-index-v",ah);ak.style.display="block";ak.style.WebkitTransform=aj;ak.style.MozTransform=aj;ak.style.msTransform=aj;ak.style.OTransform=aj;ak.style.transform=aj;ak.addEventListener("click",A,true)}}}function Y(){d.wrapper.classList.remove("overview");var ag=Array.prototype.slice.call(document.querySelectorAll(".reveal .slides section"));for(var af=0,ad=ag.length;af<ad;af++){var ae=ag[af];ae.style.WebkitTransform="";ae.style.MozTransform="";ae.style.msTransform="";ae.style.OTransform="";ae.style.transform="";ae.removeEventListener("click",A)}a()}function V(){return d.wrapper.classList.contains("overview")}function A(ad){if(V()){ad.preventDefault();Y();l=this.getAttribute("data-index-h");c=this.getAttribute("data-index-v");a()}}function ab(ae,ag){var ai=Array.prototype.slice.call(document.querySelectorAll(ae)),aj=ai.length;if(aj){if(N.loop){ag%=aj;if(ag<0){ag=aj+ag}}ag=Math.max(Math.min(ag,aj-1),0);for(var ah=0;ah<aj;ah++){var ad=ai[ah];if(V()===false){var ak=Math.abs((ag-ah)%(aj-3))||0;ad.style.display=ak>3?"none":"block"}ai[ah].classList.remove("past");ai[ah].classList.remove("present");ai[ah].classList.remove("future");if(ah<ag){ai[ah].classList.add("past")}else{if(ah>ag){ai[ah].classList.add("future")}}if(ad.querySelector("section")){ai[ah].classList.add("stack")}}ai[ag].classList.add("present");var af=ai[ag].getAttribute("data-state");if(af){ac=ac.concat(af.split(" "))}}else{ag=0}return ag}function a(aj,an){w=E;var ag=ac.concat();ac.length=0;var am=l,ae=c;l=ab(k,aj===undefined?l:aj);c=ab(b,an===undefined?c:an);stateLoop:for(var ah=0,ak=ac.length;ah<ak;ah++){for(var af=0;af<ag.length;af++){if(ag[af]===ac[ah]){ag.splice(af,1);continue stateLoop}}document.documentElement.classList.add(ac[ah]);p(ac[ah])}while(ag.length){document.documentElement.classList.remove(ag.pop())}if(N.progress&&d.progress){d.progressbar.style.width=(l/(document.querySelectorAll(k).length-1))*window.innerWidth+"px"}if(V()){G()}q();clearTimeout(B);B=setTimeout(g,1500);var ad=document.querySelectorAll(k);var al=ad[l],ai=al.querySelectorAll("section");E=ai[c]||al;if(l!==am||c!==ae){p("slidechanged",{indexh:l,indexv:c,previousSlide:w,currentSlide:E})}else{w=null}if(w){w.classList.remove("present")}}function q(){if(!N.controls||!d.controls){return}var ad=f();[d.controlsLeft,d.controlsRight,d.controlsUp,d.controlsDown].forEach(function(ae){ae.classList.remove("enabled")});if(ad.left){d.controlsLeft.classList.add("enabled")}if(ad.right){d.controlsRight.classList.add("enabled")}if(ad.up){d.controlsUp.classList.add("enabled")}if(ad.down){d.controlsDown.classList.add("enabled")}}function f(){var ad=document.querySelectorAll(k);var ae=document.querySelectorAll(b);return{left:l>0,right:l<ad.length-1,up:c>0,down:c<ae.length-1}}function H(){var ai=window.location.hash;var ah=ai.slice(2).split("/"),af=ai.replace(/#|\//gi,"");if(isNaN(parseInt(ah[0]))&&af.length){var ad=document.querySelector("#"+af);if(ad){var aj=Reveal.getIndices(ad);L(aj.h,aj.v)}else{L(l,c)}}else{var ag=parseInt(ah[0])||0,ae=parseInt(ah[1])||0;L(ag,ae)}}function g(){if(N.history){var ad="/";if(l>0||c>0){ad+=l}if(c>0){ad+="/"+c}window.location.hash=ad}}function p(ae,ad){var af=document.createEvent("HTMLEvents",1,2);af.initEvent(ae,true,true);r(af,ad);d.wrapper.dispatchEvent(af)}function t(){if(document.querySelector(b+".present")){var ae=document.querySelectorAll(b+".present .fragment:not(.visible)");if(ae.length){ae[0].classList.add("visible");p("fragmentshown",{fragment:ae[0]});return true}}else{var ad=document.querySelectorAll(k+".present .fragment:not(.visible)");if(ad.length){ad[0].classList.add("visible");p("fragmentshown",{fragment:ad[0]});return true}}return false}function M(){if(document.querySelector(b+".present")){var ae=document.querySelectorAll(b+".present .fragment.visible");if(ae.length){ae[ae.length-1].classList.remove("visible");p("fragmenthidden",{fragment:ae[ae.length-1]});return true}}else{var ad=document.querySelectorAll(k+".present .fragment.visible");if(ad.length){ad[ad.length-1].classList.remove("visible");p("fragmenthidden",{fragment:ad[ad.length-1]});return true}}return false}function K(){clearTimeout(j);if(N.autoSlide){j=setTimeout(v,N.autoSlide)}}function L(ae,ad){a(ae,ad)}function z(){if(V()||M()===false){a(l-1,0)}}function i(){if(V()||t()===false){a(l+1,0)}}function s(){if(V()||M()===false){a(l,c-1)}}function D(){if(V()||t()===false){a(l,c+1)}}function U(){if(M()===false){if(f().up){s()}else{var ad=document.querySelector(".reveal .slides>section.past:nth-child("+l+")");if(ad){c=(ad.querySelectorAll("section").length+1)||0;l--;a()}}}}function v(){if(t()===false){f().down?D():i()}K()}function T(){if(V()){Y()}else{G()}}return{initialize:h,navigateTo:L,navigateLeft:z,navigateRight:i,navigateUp:s,navigateDown:D,navigatePrev:U,navigateNext:v,toggleOverview:T,addEventListeners:C,removeEventListeners:Q,getIndices:function(ad){var ah=l,af=c;if(ad){var ai=!!ad.parentNode.nodeName.match(/section/gi);var ag=ai?ad.parentNode:ad;var ae=Array.prototype.slice.call(document.querySelectorAll(k));ah=Math.max(ae.indexOf(ag),0);if(ai){af=Math.max(Array.prototype.slice.call(ad.parentNode.children).indexOf(ad),0)}}return{h:ah,v:af}},getPreviousSlide:function(){return w},getCurrentSlide:function(){return E},getQueryHash:function(){var ad={};location.search.replace(/[A-Z0-9]+?=(\w*)/gi,function(ae){ad[ae.split("=").shift()]=ae.split("=").pop()});return ad},addEventListener:function(ae,af,ad){if("addEventListener" in window){(d.wrapper||document.querySelector(".reveal")).addEventListener(ae,af,ad)}},removeEventListener:function(ae,af,ad){if("addEventListener" in window){(d.wrapper||document.querySelector(".reveal")).removeEventListener(ae,af,ad)}}}})();
diff --git a/docs/slides/flops14/_support/reveal/lib/css/zenburn.css b/docs/slides/flops14/_support/reveal/lib/css/zenburn.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/lib/css/zenburn.css
@@ -0,0 +1,115 @@
+/*
+
+Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
+based on dark.css by Ivan Sagalaev
+
+*/
+
+pre code {
+  display: block; padding: 0.5em;
+  background: #3F3F3F;
+  color: #DCDCDC;
+}
+
+pre .keyword,
+pre .tag,
+pre .django .tag,
+pre .django .keyword,
+pre .css .class,
+pre .css .id,
+pre .lisp .title {
+  color: #E3CEAB;
+}
+
+pre .django .template_tag,
+pre .django .variable,
+pre .django .filter .argument {
+  color: #DCDCDC;
+}
+
+pre .number,
+pre .date {
+  color: #8CD0D3;
+}
+
+pre .dos .envvar,
+pre .dos .stream,
+pre .variable,
+pre .apache .sqbracket {
+  color: #EFDCBC;
+}
+
+pre .dos .flow,
+pre .diff .change,
+pre .python .exception,
+pre .python .built_in,
+pre .literal,
+pre .tex .special {
+  color: #EFEFAF;
+}
+
+pre .diff .chunk,
+pre .ruby .subst {
+  color: #8F8F8F;
+}
+
+pre .dos .keyword,
+pre .python .decorator,
+pre .class .title,
+pre .haskell .label,
+pre .function .title,
+pre .ini .title,
+pre .diff .header,
+pre .ruby .class .parent,
+pre .apache .tag,
+pre .nginx .built_in,
+pre .tex .command,
+pre .input_number {
+    color: #efef8f;
+}
+
+pre .dos .winutils,
+pre .ruby .symbol,
+pre .ruby .symbol .string,
+pre .ruby .symbol .keyword,
+pre .ruby .symbol .keymethods,
+pre .ruby .string,
+pre .ruby .instancevar {
+  color: #DCA3A3;
+}
+
+pre .diff .deletion,
+pre .string,
+pre .tag .value,
+pre .preprocessor,
+pre .built_in,
+pre .sql .aggregate,
+pre .javadoc,
+pre .smalltalk .class,
+pre .smalltalk .localvars,
+pre .smalltalk .array,
+pre .css .rules .value,
+pre .attr_selector,
+pre .pseudo,
+pre .apache .cbracket,
+pre .tex .formula {
+  color: #CC9393;
+}
+
+pre .shebang,
+pre .diff .addition,
+pre .comment,
+pre .java .annotation,
+pre .template_comment,
+pre .pi,
+pre .doctype {
+  color: #7F9F7F;
+}
+
+pre .xml .css,
+pre .xml .javascript,
+pre .xml .vbscript,
+pre .tex .formula {
+  opacity: 0.5;
+}
+
diff --git a/docs/slides/flops14/_support/reveal/lib/font/OpenSans-Regular.ttf b/docs/slides/flops14/_support/reveal/lib/font/OpenSans-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/_support/reveal/lib/font/OpenSans-Regular.ttf differ
diff --git a/docs/slides/flops14/_support/reveal/lib/font/PT_Sans-Narrow-Web-Regular.ttf b/docs/slides/flops14/_support/reveal/lib/font/PT_Sans-Narrow-Web-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/_support/reveal/lib/font/PT_Sans-Narrow-Web-Regular.ttf differ
diff --git a/docs/slides/flops14/_support/reveal/lib/font/league_gothic-webfont.ttf b/docs/slides/flops14/_support/reveal/lib/font/league_gothic-webfont.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/_support/reveal/lib/font/league_gothic-webfont.ttf differ
diff --git a/docs/slides/flops14/_support/reveal/lib/js/classList.js b/docs/slides/flops14/_support/reveal/lib/js/classList.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/lib/js/classList.js
@@ -0,0 +1,2 @@
+/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
+if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.className),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.className=this.toString()}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(o){o+="";if(g(this,o)===-1){this.push(o);this._updateClassName()}};e.remove=function(p){p+="";var o=g(this,p);if(o!==-1){this.splice(o,1);this._updateClassName()}};e.toggle=function(o){o+="";if(g(this,o)===-1){this.add(o)}else{this.remove(o)}};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
diff --git a/docs/slides/flops14/_support/reveal/lib/js/data-markdown.js b/docs/slides/flops14/_support/reveal/lib/js/data-markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/lib/js/data-markdown.js
@@ -0,0 +1,27 @@
+// From https://gist.github.com/1343518
+// Modified by Hakim to handle markdown indented with tabs
+(function(){
+
+    var slides = document.querySelectorAll('[data-markdown]');
+
+    for( var i = 0, len = slides.length; i < len; i++ ) {
+        var elem = slides[i];
+
+        // strip leading whitespace so it isn't evaluated as code
+        var text = elem.innerHTML;
+
+        var leadingWs = text.match(/^\n?(\s*)/)[1].length,
+            leadingTabs = text.match(/^\n?(\t*)/)[1].length;
+
+        if( leadingTabs > 0 ) {
+            text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+        }
+        else if( leadingWs > 1 ) {
+            text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+        }
+
+        // here, have sum HTML
+        elem.innerHTML = (new Showdown.converter()).makeHtml(text);
+    }
+
+})();
diff --git a/docs/slides/flops14/_support/reveal/lib/js/head.min.js b/docs/slides/flops14/_support/reveal/lib/js/head.min.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/lib/js/head.min.js
@@ -0,0 +1,8 @@
+/**
+    Head JS     The only script in your <HEAD>
+    Copyright   Tero Piirainen (tipiirai)
+    License     MIT / http://bit.ly/mit-license
+    Version     0.96
+
+    http://headjs.com
+*/(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c<a.length;c++)b.call(a,a[c],c)}}function r(a){var b;if(typeof a=="object")for(var c in a)a[c]&&(b={name:c,url:a[c]});else b={name:q(a),url:a};var d=h[b.name];if(d&&d.url===b.url)return d;h[b.name]=b;return b}function q(a){var b=a.split("/"),c=b[b.length-1],d=c.indexOf("?");return d!=-1?c.substring(0,d):c}function p(a){a._done||(a(),a._done=1)}var b=a.documentElement,c,d,e=[],f=[],g={},h={},i=a.createElement("script").async===!0||"MozAppearance"in a.documentElement.style||window.opera,j=window.head_conf&&head_conf.head||"head",k=window[j]=window[j]||function(){k.ready.apply(null,arguments)},l=1,m=2,n=3,o=4;i?k.js=function(){var a=arguments,b=a[a.length-1],c={};t(b)||(b=null),s(a,function(d,e){d!=b&&(d=r(d),c[d.name]=d,x(d,b&&e==a.length-2?function(){u(c)&&p(b)}:null))});return k}:k.js=function(){var a=arguments,b=[].slice.call(a,1),d=b[0];if(!c){f.push(function(){k.js.apply(null,a)});return k}d?(s(b,function(a){t(a)||w(r(a))}),x(r(a[0]),t(d)?d:function(){k.js.apply(null,b)})):x(r(a[0]));return k},k.ready=function(b,c){if(b==a){d?p(c):e.push(c);return k}t(b)&&(c=b,b="ALL");if(typeof b!="string"||!t(c))return k;var f=h[b];if(f&&f.state==o||b=="ALL"&&u()&&d){p(c);return k}var i=g[b];i?i.push(c):i=g[b]=[c];return k},k.ready(a,function(){u()&&s(g.ALL,function(a){p(a)}),k.feature&&k.feature("domloaded",!0)});if(window.addEventListener)a.addEventListener("DOMContentLoaded",z,!1),window.addEventListener("load",z,!1);else if(window.attachEvent){a.attachEvent("onreadystatechange",function(){a.readyState==="complete"&&z()});var A=1;try{A=window.frameElement}catch(B){}!A&&b.doScroll&&function(){try{b.doScroll("left"),z()}catch(a){setTimeout(arguments.callee,1);return}}(),window.attachEvent("onload",z)}!a.readyState&&a.addEventListener&&(a.readyState="loading",a.addEventListener("DOMContentLoaded",handler=function(){a.removeEventListener("DOMContentLoaded",handler,!1),a.readyState="complete"},!1)),setTimeout(function(){c=!0,s(f,function(a){a()})},300)})(document)
diff --git a/docs/slides/flops14/_support/reveal/lib/js/highlight.js b/docs/slides/flops14/_support/reveal/lib/js/highlight.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/lib/js/highlight.js
@@ -0,0 +1,5 @@
+/*
+Syntax highlighting with language autodetection.
+http://softwaremaniacs.org/soft/highlight/
+*/
+var hljs=new function(){function m(p){return p.replace(/&/gm,"&amp;").replace(/</gm,"&lt;")}function c(r,q,p){return RegExp(q,"m"+(r.cI?"i":"")+(p?"g":""))}function j(r){for(var p=0;p<r.childNodes.length;p++){var q=r.childNodes[p];if(q.nodeName=="CODE"){return q}if(!(q.nodeType==3&&q.nodeValue.match(/\s+/))){break}}}function g(t,s){var r="";for(var q=0;q<t.childNodes.length;q++){if(t.childNodes[q].nodeType==3){var p=t.childNodes[q].nodeValue;if(s){p=p.replace(/\n/g,"")}r+=p}else{if(t.childNodes[q].nodeName=="BR"){r+="\n"}else{r+=g(t.childNodes[q])}}}if(/MSIE [678]/.test(navigator.userAgent)){r=r.replace(/\r/g,"\n")}return r}function a(s){var q=s.className.split(/\s+/);q=q.concat(s.parentNode.className.split(/\s+/));for(var p=0;p<q.length;p++){var r=q[p].replace(/^language-/,"");if(d[r]||r=="no-highlight"){return r}}}function b(p){var q=[];(function(s,t){for(var r=0;r<s.childNodes.length;r++){if(s.childNodes[r].nodeType==3){t+=s.childNodes[r].nodeValue.length}else{if(s.childNodes[r].nodeName=="BR"){t+=1}else{q.push({event:"start",offset:t,node:s.childNodes[r]});t=arguments.callee(s.childNodes[r],t);q.push({event:"stop",offset:t,node:s.childNodes[r]})}}}return t})(p,0);return q}function l(y,z,x){var r=0;var w="";var t=[];function u(){if(y.length&&z.length){if(y[0].offset!=z[0].offset){return(y[0].offset<z[0].offset)?y:z}else{return z[0].event=="start"?y:z}}else{return y.length?y:z}}function s(C){var D="<"+C.nodeName.toLowerCase();for(var A=0;A<C.attributes.length;A++){var B=C.attributes[A];D+=" "+B.nodeName.toLowerCase();if(B.nodeValue!=undefined&&B.nodeValue!=false&&B.nodeValue!=null){D+='="'+m(B.nodeValue)+'"'}}return D+">"}while(y.length||z.length){var v=u().splice(0,1)[0];w+=m(x.substr(r,v.offset-r));r=v.offset;if(v.event=="start"){w+=s(v.node);t.push(v.node)}else{if(v.event=="stop"){var q=t.length;do{q--;var p=t[q];w+=("</"+p.nodeName.toLowerCase()+">")}while(p!=v.node);t.splice(q,1);while(q<t.length){w+=s(t[q]);q++}}}}w+=x.substr(r);return w}function i(){function p(u,t,v){if(u.compiled){return}if(!v){u.bR=c(t,u.b?u.b:"\\B|\\b");if(!u.e&&!u.eW){u.e="\\B|\\b"}if(u.e){u.eR=c(t,u.e)}}if(u.i){u.iR=c(t,u.i)}if(u.r==undefined){u.r=1}if(u.k){u.lR=c(t,u.l||hljs.IR,true)}for(var s in u.k){if(!u.k.hasOwnProperty(s)){continue}if(u.k[s] instanceof Object){u.kG=u.k}else{u.kG={keyword:u.k}}break}if(!u.c){u.c=[]}u.compiled=true;for(var r=0;r<u.c.length;r++){p(u.c[r],t,false)}if(u.starts){p(u.starts,t,false)}}for(var q in d){if(!d.hasOwnProperty(q)){continue}p(d[q].dM,d[q],true)}}function e(J,D){if(!i.called){i();i.called=true}function z(r,M){for(var L=0;L<M.c.length;L++){if(M.c[L].bR.test(r)){return M.c[L]}}}function w(L,r){if(C[L].e&&C[L].eR.test(r)){return 1}if(C[L].eW){var M=w(L-1,r);return M?M+1:0}return 0}function x(r,L){return L.iR&&L.iR.test(r)}function A(O,N){var M=[];for(var L=0;L<O.c.length;L++){M.push(O.c[L].b)}var r=C.length-1;do{if(C[r].e){M.push(C[r].e)}r--}while(C[r+1].eW);if(O.i){M.push(O.i)}return c(N,"("+M.join("|")+")",true)}function s(M,L){var N=C[C.length-1];if(!N.t){N.t=A(N,H)}N.t.lastIndex=L;var r=N.t.exec(M);if(r){return[M.substr(L,r.index-L),r[0],false]}else{return[M.substr(L),"",true]}}function p(O,r){var L=H.cI?r[0].toLowerCase():r[0];for(var N in O.kG){if(!O.kG.hasOwnProperty(N)){continue}var M=O.kG[N].hasOwnProperty(L);if(M){return[N,M]}}return false}function F(M,O){if(!O.k){return m(M)}var N="";var P=0;O.lR.lastIndex=0;var L=O.lR.exec(M);while(L){N+=m(M.substr(P,L.index-P));var r=p(O,L);if(r){t+=r[1];N+='<span class="'+r[0]+'">'+m(L[0])+"</span>"}else{N+=m(L[0])}P=O.lR.lastIndex;L=O.lR.exec(M)}N+=m(M.substr(P,M.length-P));return N}function K(r,M){if(M.sL&&d[M.sL]){var L=e(M.sL,r);t+=L.keyword_count;return L.value}else{return F(r,M)}}function I(M,r){var L=M.cN?'<span class="'+M.cN+'">':"";if(M.rB){q+=L;M.buffer=""}else{if(M.eB){q+=m(r)+L;M.buffer=""}else{q+=L;M.buffer=r}}C.push(M);B+=M.r}function E(O,L,Q){var R=C[C.length-1];if(Q){q+=K(R.buffer+O,R);return false}var M=z(L,R);if(M){q+=K(R.buffer+O,R);I(M,L);return M.rB}var r=w(C.length-1,L);if(r){var N=R.cN?"</span>":"";if(R.rE){q+=K(R.buffer+O,R)+N}else{if(R.eE){q+=K(R.buffer+O,R)+N+m(L)}else{q+=K(R.buffer+O+L,R)+N}}while(r>1){N=C[C.length-2].cN?"</span>":"";q+=N;r--;C.length--}var P=C[C.length-1];C.length--;C[C.length-1].buffer="";if(P.starts){I(P.starts,"")}return R.rE}if(x(L,R)){throw"Illegal"}}var H=d[J];var C=[H.dM];var B=0;var t=0;var q="";try{var v=0;H.dM.buffer="";do{var y=s(D,v);var u=E(y[0],y[1],y[2]);v+=y[0].length;if(!u){v+=y[1].length}}while(!y[2]);if(C.length>1){throw"Illegal"}return{r:B,keyword_count:t,value:q}}catch(G){if(G=="Illegal"){return{r:0,keyword_count:0,value:m(D)}}else{throw G}}}function f(t){var r={keyword_count:0,r:0,value:m(t)};var q=r;for(var p in d){if(!d.hasOwnProperty(p)){continue}var s=e(p,t);s.language=p;if(s.keyword_count+s.r>q.keyword_count+q.r){q=s}if(s.keyword_count+s.r>r.keyword_count+r.r){q=r;r=s}}if(q.language){r.second_best=q}return r}function h(r,q,p){if(q){r=r.replace(/^((<[^>]+>|\t)+)/gm,function(t,w,v,u){return w.replace(/\t/g,q)})}if(p){r=r.replace(/\n/g,"<br>")}return r}function o(u,x,q){var y=g(u,q);var s=a(u);if(s=="no-highlight"){return}if(s){var w=e(s,y)}else{var w=f(y);s=w.language}var p=b(u);if(p.length){var r=document.createElement("pre");r.innerHTML=w.value;w.value=l(p,b(r),y)}w.value=h(w.value,x,q);var t=u.className;if(!t.match("(\\s|^)(language-)?"+s+"(\\s|$)")){t=t?(t+" "+s):s}if(/MSIE [678]/.test(navigator.userAgent)&&u.tagName=="CODE"&&u.parentNode.tagName=="PRE"){var r=u.parentNode;var v=document.createElement("div");v.innerHTML="<pre><code>"+w.value+"</code></pre>";u=v.firstChild.firstChild;v.firstChild.cN=r.cN;r.parentNode.replaceChild(v.firstChild,r)}else{u.innerHTML=w.value}u.className=t;u.result={language:s,kw:w.keyword_count,re:w.r};if(w.second_best){u.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function k(){if(k.called){return}k.called=true;var r=document.getElementsByTagName("pre");for(var p=0;p<r.length;p++){var q=j(r[p]);if(q){o(q,hljs.tabReplace)}}}function n(){if(window.addEventListener){window.addEventListener("DOMContentLoaded",k,false);window.addEventListener("load",k,false)}else{if(window.attachEvent){window.attachEvent("onload",k)}else{window.onload=k}}}var d={};this.LANGUAGES=d;this.highlight=e;this.highlightAuto=f;this.fixMarkup=h;this.highlightBlock=o;this.initHighlighting=k;this.initHighlightingOnLoad=n;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\.",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.inherit=function(p,s){var r={};for(var q in p){r[q]=p[q]}if(s){for(var q in s){r[q]=s[q]}}return r}}();hljs.LANGUAGES.cs={dM:{k:{"abstract":1,as:1,base:1,bool:1,"break":1,"byte":1,"case":1,"catch":1,"char":1,checked:1,"class":1,"const":1,"continue":1,decimal:1,"default":1,delegate:1,"do":1,"do":1,"double":1,"else":1,"enum":1,event:1,explicit:1,extern:1,"false":1,"finally":1,fixed:1,"float":1,"for":1,foreach:1,"goto":1,"if":1,implicit:1,"in":1,"int":1,"interface":1,internal:1,is:1,lock:1,"long":1,namespace:1,"new":1,"null":1,object:1,operator:1,out:1,override:1,params:1,"private":1,"protected":1,"public":1,readonly:1,ref:1,"return":1,sbyte:1,sealed:1,"short":1,sizeof:1,stackalloc:1,"static":1,string:1,struct:1,"switch":1,"this":1,"throw":1,"true":1,"try":1,"typeof":1,uint:1,ulong:1,unchecked:1,unsafe:1,ushort:1,using:1,virtual:1,"volatile":1,"void":1,"while":1,ascending:1,descending:1,from:1,get:1,group:1,into:1,join:1,let:1,orderby:1,partial:1,select:1,set:1,value:1,"var":1,where:1,yield:1},c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"}]},hljs.CLCM,hljs.CBLCLM,{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},hljs.ASM,hljs.QSM,hljs.CNM]}};hljs.LANGUAGES.ruby=function(){var g="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var a="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var n={keyword:{and:1,"false":1,then:1,defined:1,module:1,"in":1,"return":1,redo:1,"if":1,BEGIN:1,retry:1,end:1,"for":1,"true":1,self:1,when:1,next:1,until:1,"do":1,begin:1,unless:1,END:1,rescue:1,nil:1,"else":1,"break":1,undef:1,not:1,"super":1,"class":1,"case":1,require:1,yield:1,alias:1,"while":1,ensure:1,elsif:1,or:1,def:1},keymethods:{__id__:1,__send__:1,abort:1,abs:1,"all?":1,allocate:1,ancestors:1,"any?":1,arity:1,assoc:1,at:1,at_exit:1,autoload:1,"autoload?":1,"between?":1,binding:1,binmode:1,"block_given?":1,call:1,callcc:1,caller:1,capitalize:1,"capitalize!":1,casecmp:1,"catch":1,ceil:1,center:1,chomp:1,"chomp!":1,chop:1,"chop!":1,chr:1,"class":1,class_eval:1,"class_variable_defined?":1,class_variables:1,clear:1,clone:1,close:1,close_read:1,close_write:1,"closed?":1,coerce:1,collect:1,"collect!":1,compact:1,"compact!":1,concat:1,"const_defined?":1,const_get:1,const_missing:1,const_set:1,constants:1,count:1,crypt:1,"default":1,default_proc:1,"delete":1,"delete!":1,delete_at:1,delete_if:1,detect:1,display:1,div:1,divmod:1,downcase:1,"downcase!":1,downto:1,dump:1,dup:1,each:1,each_byte:1,each_index:1,each_key:1,each_line:1,each_pair:1,each_value:1,each_with_index:1,"empty?":1,entries:1,eof:1,"eof?":1,"eql?":1,"equal?":1,"eval":1,exec:1,exit:1,"exit!":1,extend:1,fail:1,fcntl:1,fetch:1,fileno:1,fill:1,find:1,find_all:1,first:1,flatten:1,"flatten!":1,floor:1,flush:1,for_fd:1,foreach:1,fork:1,format:1,freeze:1,"frozen?":1,fsync:1,getc:1,gets:1,global_variables:1,grep:1,gsub:1,"gsub!":1,"has_key?":1,"has_value?":1,hash:1,hex:1,id:1,include:1,"include?":1,included_modules:1,index:1,indexes:1,indices:1,induced_from:1,inject:1,insert:1,inspect:1,instance_eval:1,instance_method:1,instance_methods:1,"instance_of?":1,"instance_variable_defined?":1,instance_variable_get:1,instance_variable_set:1,instance_variables:1,"integer?":1,intern:1,invert:1,ioctl:1,"is_a?":1,isatty:1,"iterator?":1,join:1,"key?":1,keys:1,"kind_of?":1,lambda:1,last:1,length:1,lineno:1,ljust:1,load:1,local_variables:1,loop:1,lstrip:1,"lstrip!":1,map:1,"map!":1,match:1,max:1,"member?":1,merge:1,"merge!":1,method:1,"method_defined?":1,method_missing:1,methods:1,min:1,module_eval:1,modulo:1,name:1,nesting:1,"new":1,next:1,"next!":1,"nil?":1,nitems:1,"nonzero?":1,object_id:1,oct:1,open:1,pack:1,partition:1,pid:1,pipe:1,pop:1,popen:1,pos:1,prec:1,prec_f:1,prec_i:1,print:1,printf:1,private_class_method:1,private_instance_methods:1,"private_method_defined?":1,private_methods:1,proc:1,protected_instance_methods:1,"protected_method_defined?":1,protected_methods:1,public_class_method:1,public_instance_methods:1,"public_method_defined?":1,public_methods:1,push:1,putc:1,puts:1,quo:1,raise:1,rand:1,rassoc:1,read:1,read_nonblock:1,readchar:1,readline:1,readlines:1,readpartial:1,rehash:1,reject:1,"reject!":1,remainder:1,reopen:1,replace:1,require:1,"respond_to?":1,reverse:1,"reverse!":1,reverse_each:1,rewind:1,rindex:1,rjust:1,round:1,rstrip:1,"rstrip!":1,scan:1,seek:1,select:1,send:1,set_trace_func:1,shift:1,singleton_method_added:1,singleton_methods:1,size:1,sleep:1,slice:1,"slice!":1,sort:1,"sort!":1,sort_by:1,split:1,sprintf:1,squeeze:1,"squeeze!":1,srand:1,stat:1,step:1,store:1,strip:1,"strip!":1,sub:1,"sub!":1,succ:1,"succ!":1,sum:1,superclass:1,swapcase:1,"swapcase!":1,sync:1,syscall:1,sysopen:1,sysread:1,sysseek:1,system:1,syswrite:1,taint:1,"tainted?":1,tell:1,test:1,"throw":1,times:1,to_a:1,to_ary:1,to_f:1,to_hash:1,to_i:1,to_int:1,to_io:1,to_proc:1,to_s:1,to_str:1,to_sym:1,tr:1,"tr!":1,tr_s:1,"tr_s!":1,trace_var:1,transpose:1,trap:1,truncate:1,"tty?":1,type:1,ungetc:1,uniq:1,"uniq!":1,unpack:1,unshift:1,untaint:1,untrace_var:1,upcase:1,"upcase!":1,update:1,upto:1,"value?":1,values:1,values_at:1,warn:1,write:1,write_nonblock:1,"zero?":1,zip:1}};var h={cN:"yardoctag",b:"@[A-Za-z]+"};var d={cN:"comment",b:"#",e:"$",c:[h]};var c={cN:"comment",b:"^\\=begin",e:"^\\=end",c:[h],r:10};var b={cN:"comment",b:"^__END__",e:"\\n$"};var u={cN:"subst",b:"#\\{",e:"}",l:g,k:n};var p=[hljs.BE,u];var s={cN:"string",b:"'",e:"'",c:p,r:0};var r={cN:"string",b:'"',e:'"',c:p,r:0};var q={cN:"string",b:"%[qw]?\\(",e:"\\)",c:p,r:10};var o={cN:"string",b:"%[qw]?\\[",e:"\\]",c:p,r:10};var m={cN:"string",b:"%[qw]?{",e:"}",c:p,r:10};var l={cN:"string",b:"%[qw]?<",e:">",c:p,r:10};var k={cN:"string",b:"%[qw]?/",e:"/",c:p,r:10};var j={cN:"string",b:"%[qw]?%",e:"%",c:p,r:10};var i={cN:"string",b:"%[qw]?-",e:"-",c:p,r:10};var t={cN:"string",b:"%[qw]?\\|",e:"\\|",c:p,r:10};var e={cN:"function",b:"\\bdef\\s+",e:" |$|;",l:g,k:n,c:[{cN:"title",b:a,l:g,k:n},{cN:"params",b:"\\(",e:"\\)",l:g,k:n},d,c,b]};var f={cN:"identifier",b:g,l:g,k:n,r:0};var v=[d,c,b,s,r,q,o,m,l,k,j,i,t,{cN:"class",b:"\\b(class|module)\\b",e:"$|;",k:{"class":1,module:1},c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+hljs.IR+"::)?"+hljs.IR}]},d,c,b]},e,{cN:"constant",b:"(::)?([A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:[s,r,q,o,m,l,k,j,i,t,f],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},f,{b:"("+hljs.RSR+")\\s*",c:[d,c,b,{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[hljs.BE]}],r:0}];u.c=v;e.c[1].c=v;return{dM:{l:g,k:n,c:v}}}();hljs.LANGUAGES.javascript={dM:{k:{keyword:{"in":1,"if":1,"for":1,"while":1,"finally":1,"var":1,"new":1,"function":1,"do":1,"return":1,"void":1,"else":1,"break":1,"catch":1,"instanceof":1,"with":1,"throw":1,"case":1,"default":1,"try":1,"this":1,"switch":1,"continue":1,"typeof":1,"delete":1},literal:{"true":1,"false":1,"null":1}},c:[hljs.ASM,hljs.QSM,hljs.CLCM,hljs.CBLCLM,hljs.CNM,{b:"("+hljs.RSR+"|case|return|throw)\\s*",k:{"return":1,"throw":1,"case":1},c:[hljs.CLCM,hljs.CBLCLM,{cN:"regexp",b:"/",e:"/[gim]*",c:[{b:"\\\\/"}]}],r:0},{cN:"function",b:"\\bfunction\\b",e:"{",k:{"function":1},c:[{cN:"title",b:"[A-Za-z$_][0-9A-Za-z$_]*"},{cN:"params",b:"\\(",e:"\\)",c:[hljs.ASM,hljs.QSM,hljs.CLCM,hljs.CBLCLM]}]}]}};hljs.LANGUAGES.css=function(){var a={cN:"function",b:hljs.IR+"\\(",e:"\\)",c:[{eW:true,eE:true,c:[hljs.NM,hljs.ASM,hljs.QSM]}]};return{cI:true,dM:{i:"[=/|']",c:[hljs.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:{"font-face":1,page:1}},{cN:"at_rule",b:"@",e:"[{;]",eE:true,k:{"import":1,page:1,media:1,charset:1},c:[a,hljs.ASM,hljs.QSM,hljs.NM]},{cN:"tag",b:hljs.IR,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[hljs.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[a,hljs.NM,hljs.QSM,hljs.ASM,hljs.CBLCLM,{cN:"hexcolor",b:"\\#[0-9A-F]+"},{cN:"important",b:"!important"}]}}]}]}]}}}();hljs.LANGUAGES.xml=function(){var b="[A-Za-z0-9\\._:-]+";var a={eW:true,c:[{cN:"attribute",b:b,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,dM:{c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style",e:">",k:{title:{style:1}},c:[a],starts:{cN:"css",e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script",e:">",k:{title:{script:1}},c:[a],starts:{cN:"javascript",e:"<\/script>",rE:true,sL:"javascript"}},{cN:"vbscript",b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:"[^ />]+"},a]}]}}}();hljs.LANGUAGES.java={dM:{k:{"false":1,"synchronized":1,"int":1,"abstract":1,"float":1,"private":1,"char":1,"interface":1,"boolean":1,"static":1,"null":1,"if":1,"const":1,"for":1,"true":1,"while":1,"long":1,"throw":1,strictfp:1,"finally":1,"protected":1,"extends":1,"import":1,"native":1,"final":1,"implements":1,"return":1,"void":1,"enum":1,"else":1,"break":1,"transient":1,"new":1,"catch":1,"instanceof":1,"byte":1,"super":1,"class":1,"volatile":1,"case":1,assert:1,"short":1,"package":1,"default":1,"double":1,"public":1,"try":1,"this":1,"switch":1,"continue":1,"throws":1},c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},hljs.CLCM,hljs.CBLCLM,hljs.ASM,hljs.QSM,{cN:"class",b:"(class |interface )",e:"{",k:{"class":1,"interface":1},i:":",c:[{b:"(implements|extends)",k:{"extends":1,"implements":1},r:10},{cN:"title",b:hljs.UIR}]},hljs.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}};hljs.LANGUAGES.php={cI:true,dM:{k:{and:1,include_once:1,list:1,"abstract":1,global:1,"private":1,echo:1,"interface":1,as:1,"static":1,endswitch:1,array:1,"null":1,"if":1,endwhile:1,or:1,"const":1,"for":1,endforeach:1,self:1,"var":1,"while":1,isset:1,"public":1,"protected":1,exit:1,foreach:1,"throw":1,elseif:1,"extends":1,include:1,__FILE__:1,empty:1,require_once:1,"function":1,"do":1,xor:1,"return":1,"implements":1,parent:1,clone:1,use:1,__CLASS__:1,__LINE__:1,"else":1,"break":1,print:1,"eval":1,"new":1,"catch":1,__METHOD__:1,"class":1,"case":1,exception:1,php_user_filter:1,"default":1,die:1,require:1,__FUNCTION__:1,enddeclare:1,"final":1,"try":1,"this":1,"switch":1,"continue":1,endfor:1,endif:1,declare:1,unset:1,"true":1,"false":1,namespace:1},c:[hljs.CLCM,hljs.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+",r:10}]},hljs.CNM,hljs.inherit(hljs.ASM,{i:null}),hljs.inherit(hljs.QSM,{i:null}),{cN:"variable",b:"\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"}]}};hljs.LANGUAGES.python=function(){var c={cN:"string",b:"(u|b)?r?'''",e:"'''",r:10};var b={cN:"string",b:'(u|b)?r?"""',e:'"""',r:10};var a={cN:"string",b:"(u|r|ur|b|br)'",e:"'",c:[hljs.BE],r:10};var f={cN:"string",b:'(u|r|ur|b|br)"',e:'"',c:[hljs.BE],r:10};var d={cN:"title",b:hljs.UIR};var e={cN:"params",b:"\\(",e:"\\)",c:[c,b,a,f,hljs.ASM,hljs.QSM]};return{dM:{k:{keyword:{and:1,elif:1,is:1,global:1,as:1,"in":1,"if":1,from:1,raise:1,"for":1,except:1,"finally":1,print:1,"import":1,pass:1,"return":1,exec:1,"else":1,"break":1,not:1,"with":1,"class":1,assert:1,yield:1,"try":1,"while":1,"continue":1,del:1,or:1,def:1,lambda:1,nonlocal:10},built_in:{None:1,True:1,False:1,Ellipsis:1,NotImplemented:1}},i:"(</|->|\\?)",c:[hljs.HCM,c,b,a,f,hljs.ASM,hljs.QSM,{cN:"function",b:"\\bdef ",e:":",i:"$",k:{def:1},c:[d,e],r:10},{cN:"class",b:"\\bclass ",e:":",i:"[${]",k:{"class":1},c:[d,e],r:10},hljs.CNM,{cN:"decorator",b:"@",e:"$"}]}}}();hljs.LANGUAGES.perl=function(){var c={getpwent:1,getservent:1,quotemeta:1,msgrcv:1,scalar:1,kill:1,dbmclose:1,undef:1,lc:1,ma:1,syswrite:1,tr:1,send:1,umask:1,sysopen:1,shmwrite:1,vec:1,qx:1,utime:1,local:1,oct:1,semctl:1,localtime:1,readpipe:1,"do":1,"return":1,format:1,read:1,sprintf:1,dbmopen:1,pop:1,getpgrp:1,not:1,getpwnam:1,rewinddir:1,qq:1,fileno:1,qw:1,endprotoent:1,wait:1,sethostent:1,bless:1,s:1,opendir:1,"continue":1,each:1,sleep:1,endgrent:1,shutdown:1,dump:1,chomp:1,connect:1,getsockname:1,die:1,socketpair:1,close:1,flock:1,exists:1,index:1,shmget:1,sub:1,"for":1,endpwent:1,redo:1,lstat:1,msgctl:1,setpgrp:1,abs:1,exit:1,select:1,print:1,ref:1,gethostbyaddr:1,unshift:1,fcntl:1,syscall:1,"goto":1,getnetbyaddr:1,join:1,gmtime:1,symlink:1,semget:1,splice:1,x:1,getpeername:1,recv:1,log:1,setsockopt:1,cos:1,last:1,reverse:1,gethostbyname:1,getgrnam:1,study:1,formline:1,endhostent:1,times:1,chop:1,length:1,gethostent:1,getnetent:1,pack:1,getprotoent:1,getservbyname:1,rand:1,mkdir:1,pos:1,chmod:1,y:1,substr:1,endnetent:1,printf:1,next:1,open:1,msgsnd:1,readdir:1,use:1,unlink:1,getsockopt:1,getpriority:1,rindex:1,wantarray:1,hex:1,system:1,getservbyport:1,endservent:1,"int":1,chr:1,untie:1,rmdir:1,prototype:1,tell:1,listen:1,fork:1,shmread:1,ucfirst:1,setprotoent:1,"else":1,sysseek:1,link:1,getgrgid:1,shmctl:1,waitpid:1,unpack:1,getnetbyname:1,reset:1,chdir:1,grep:1,split:1,require:1,caller:1,lcfirst:1,until:1,warn:1,"while":1,values:1,shift:1,telldir:1,getpwuid:1,my:1,getprotobynumber:1,"delete":1,and:1,sort:1,uc:1,defined:1,srand:1,accept:1,"package":1,seekdir:1,getprotobyname:1,semop:1,our:1,rename:1,seek:1,"if":1,q:1,chroot:1,sysread:1,setpwent:1,no:1,crypt:1,getc:1,chown:1,sqrt:1,write:1,setnetent:1,setpriority:1,foreach:1,tie:1,sin:1,msgget:1,map:1,stat:1,getlogin:1,unless:1,elsif:1,truncate:1,exec:1,keys:1,glob:1,tied:1,closedir:1,ioctl:1,socket:1,readlink:1,"eval":1,xor:1,readline:1,binmode:1,setservent:1,eof:1,ord:1,bind:1,alarm:1,pipe:1,atan2:1,getgrent:1,exp:1,time:1,push:1,setgrent:1,gt:1,lt:1,or:1,ne:1,m:1};var d={cN:"subst",b:"[$@]\\{",e:"}",k:c,r:10};var b={cN:"variable",b:"\\$\\d"};var a={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var g=[hljs.BE,d,b,a];var f={b:"->",c:[{b:hljs.IR},{b:"{",e:"}"}]};var e=[b,a,hljs.HCM,{cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5},f,{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:g,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:g,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:g,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:g,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:g,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:g,r:5},{cN:"string",b:"'",e:"'",c:[hljs.BE],r:0},{cN:"string",b:'"',e:'"',c:g,r:0},{cN:"string",b:"`",e:"`",c:[hljs.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[hljs.BE],r:0},{cN:"sub",b:"\\bsub\\b",e:"(\\s*\\(.*?\\))?[;{]",k:{sub:1},r:5},{cN:"operator",b:"-\\w\\b",r:0},{cN:"pod",b:"\\=\\w",e:"\\=cut"}];d.c=e;f.c[1].c=e;return{dM:{k:c,c:e}}}();hljs.LANGUAGES.cpp=function(){var b={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,virtual:1,operator:2,sizeof:2,dynamic_cast:2,typedef:2,const_cast:2,"const":1,struct:1,"for":1,static_cast:2,union:1,namespace:1,unsigned:1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,bool:1,template:1,mutable:1,"if":1,"public":1,friend:2,"do":1,"return":1,"goto":1,auto:1,"void":2,"enum":1,"else":1,"break":1,"new":1,extern:1,using:1,"true":1,"class":1,asm:1,"case":1,typeid:1,"short":1,reinterpret_cast:2,"default":1,"double":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,"delete":1,alignof:1,char16_t:1,char32_t:1,constexpr:1,decltype:1,noexcept:1,nullptr:1,static_assert:1,thread_local:1},built_in:{std:1,string:1,cin:1,cout:1,cerr:1,clog:1,stringstream:1,istringstream:1,ostringstream:1,auto_ptr:1,deque:1,list:1,queue:1,stack:1,vector:1,map:1,set:1,bitset:1,multiset:1,multimap:1,unordered_set:1,unordered_map:1,unordered_multiset:1,unordered_multimap:1,array:1,shared_ptr:1}};var a={cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,r:10};a.c=[a];return{dM:{k:b,i:"</",c:[hljs.CLCM,hljs.CBLCLM,hljs.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},hljs.CNM,{cN:"preprocessor",b:"#",e:"$"},a]}}}();
diff --git a/docs/slides/flops14/_support/reveal/lib/js/html5shiv.js b/docs/slides/flops14/_support/reveal/lib/js/html5shiv.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/lib/js/html5shiv.js
@@ -0,0 +1,7 @@
+document.createElement('header');
+document.createElement('nav');
+document.createElement('section');
+document.createElement('article');
+document.createElement('aside');
+document.createElement('footer');
+document.createElement('hgroup');
diff --git a/docs/slides/flops14/_support/reveal/lib/js/showdown.js b/docs/slides/flops14/_support/reveal/lib/js/showdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/lib/js/showdown.js
@@ -0,0 +1,1341 @@
+//
+// showdown.js -- A javascript port of Markdown.
+//
+// Copyright (c) 2007 John Fraser.
+//
+// Original Markdown Copyright (c) 2004-2005 John Gruber
+//   <http://daringfireball.net/projects/markdown/>
+//
+// Redistributable under a BSD-style open source license.
+// See license.txt for more information.
+//
+// The full source distribution is at:
+//
+//				A A L
+//				T C A
+//				T K B
+//
+//   <http://www.attacklab.net/>
+//
+
+//
+// Wherever possible, Showdown is a straight, line-by-line port
+// of the Perl version of Markdown.
+//
+// This is not a normal parser design; it's basically just a
+// series of string substitutions.  It's hard to read and
+// maintain this way,  but keeping Showdown close to the original
+// design makes it easier to port new features.
+//
+// More importantly, Showdown behaves like markdown.pl in most
+// edge cases.  So web applications can do client-side preview
+// in Javascript, and then build identical HTML on the server.
+//
+// This port needs the new RegExp functionality of ECMA 262,
+// 3rd Edition (i.e. Javascript 1.5).  Most modern web browsers
+// should do fine.  Even with the new regular expression features,
+// We do a lot of work to emulate Perl's regex functionality.
+// The tricky changes in this file mostly have the "attacklab:"
+// label.  Major or self-explanatory changes don't.
+//
+// Smart diff tools like Araxis Merge will be able to match up
+// this file with markdown.pl in a useful way.  A little tweaking
+// helps: in a copy of markdown.pl, replace "#" with "//" and
+// replace "$text" with "text".  Be sure to ignore whitespace
+// and line endings.
+//
+
+
+//
+// Showdown usage:
+//
+//   var text = "Markdown *rocks*.";
+//
+//   var converter = new Showdown.converter();
+//   var html = converter.makeHtml(text);
+//
+//   alert(html);
+//
+// Note: move the sample code to the bottom of this
+// file before uncommenting it.
+//
+
+
+//
+// Showdown namespace
+//
+var Showdown = {};
+
+//
+// converter
+//
+// Wraps all "globals" so that the only thing
+// exposed is makeHtml().
+//
+Showdown.converter = function() {
+
+//
+// Globals:
+//
+
+// Global hashes, used by various utility routines
+var g_urls;
+var g_titles;
+var g_html_blocks;
+
+// Used to track when we're inside an ordered or unordered list
+// (see _ProcessListItems() for details):
+var g_list_level = 0;
+
+
+this.makeHtml = function(text) {
+//
+// Main function. The order in which other subs are called here is
+// essential. Link and image substitutions need to happen before
+// _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
+// and <img> tags get encoded.
+//
+
+	// Clear the global hashes. If we don't clear these, you get conflicts
+	// from other articles when generating a page which contains more than
+	// one article (e.g. an index page that shows the N most recent
+	// articles):
+	g_urls = new Array();
+	g_titles = new Array();
+	g_html_blocks = new Array();
+
+	// attacklab: Replace ~ with ~T
+	// This lets us use tilde as an escape char to avoid md5 hashes
+	// The choice of character is arbitray; anything that isn't
+    // magic in Markdown will work.
+	text = text.replace(/~/g,"~T");
+
+	// attacklab: Replace $ with ~D
+	// RegExp interprets $ as a special character
+	// when it's in a replacement string
+	text = text.replace(/\$/g,"~D");
+
+	// Standardize line endings
+	text = text.replace(/\r\n/g,"\n"); // DOS to Unix
+	text = text.replace(/\r/g,"\n"); // Mac to Unix
+
+	// Make sure text begins and ends with a couple of newlines:
+	text = "\n\n" + text + "\n\n";
+
+	// Convert all tabs to spaces.
+	text = _Detab(text);
+
+	// Strip any lines consisting only of spaces and tabs.
+	// This makes subsequent regexen easier to write, because we can
+	// match consecutive blank lines with /\n+/ instead of something
+	// contorted like /[ \t]*\n+/ .
+	text = text.replace(/^[ \t]+$/mg,"");
+
+	// Handle github codeblocks prior to running HashHTML so that
+	// HTML contained within the codeblock gets escaped propertly
+	text = _DoGithubCodeBlocks(text);
+
+	// Turn block-level HTML blocks into hash entries
+	text = _HashHTMLBlocks(text);
+
+	// Strip link definitions, store in hashes.
+	text = _StripLinkDefinitions(text);
+
+	text = _RunBlockGamut(text);
+
+	text = _UnescapeSpecialChars(text);
+
+	// attacklab: Restore dollar signs
+	text = text.replace(/~D/g,"$$");
+
+	// attacklab: Restore tildes
+	text = text.replace(/~T/g,"~");
+
+	return text;
+};
+
+
+var _StripLinkDefinitions = function(text) {
+//
+// Strips link definitions from text, stores the URLs and titles in
+// hash references.
+//
+
+	// Link defs are in the form: ^[id]: url "optional title"
+
+	/*
+		var text = text.replace(/
+				^[ ]{0,3}\[(.+)\]:  // id = $1  attacklab: g_tab_width - 1
+				  [ \t]*
+				  \n?				// maybe *one* newline
+				  [ \t]*
+				<?(\S+?)>?			// url = $2
+				  [ \t]*
+				  \n?				// maybe one newline
+				  [ \t]*
+				(?:
+				  (\n*)				// any lines skipped = $3 attacklab: lookbehind removed
+				  ["(]
+				  (.+?)				// title = $4
+				  [")]
+				  [ \t]*
+				)?					// title is optional
+				(?:\n+|$)
+			  /gm,
+			  function(){...});
+	*/
+	var text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,
+		function (wholeMatch,m1,m2,m3,m4) {
+			m1 = m1.toLowerCase();
+			g_urls[m1] = _EncodeAmpsAndAngles(m2);  // Link IDs are case-insensitive
+			if (m3) {
+				// Oops, found blank lines, so it's not a title.
+				// Put back the parenthetical statement we stole.
+				return m3+m4;
+			} else if (m4) {
+				g_titles[m1] = m4.replace(/"/g,"&quot;");
+			}
+
+			// Completely remove the definition from the text
+			return "";
+		}
+	);
+
+	return text;
+}
+
+
+var _HashHTMLBlocks = function(text) {
+	// attacklab: Double up blank lines to reduce lookaround
+	text = text.replace(/\n/g,"\n\n");
+
+	// Hashify HTML blocks:
+	// We only want to do this for block-level HTML tags, such as headers,
+	// lists, and tables. That's because we still want to wrap <p>s around
+	// "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+	// phrase emphasis, and spans. The list of tags we're looking for is
+	// hard-coded:
+	var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del|style|section|header|footer|nav|article|aside";
+	var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside";
+
+	// First, look for nested blocks, e.g.:
+	//   <div>
+	//     <div>
+	//     tags for inner block must be indented.
+	//     </div>
+	//   </div>
+	//
+	// The outermost tags must start at the left margin for this to match, and
+	// the inner nested divs must be indented.
+	// We need to do this before the next, more liberal match, because the next
+	// match will start at the first `<div>` and stop at the first `</div>`.
+
+	// attacklab: This regex can be expensive when it fails.
+	/*
+		var text = text.replace(/
+		(						// save in $1
+			^					// start of line  (with /m)
+			<($block_tags_a)	// start tag = $2
+			\b					// word break
+								// attacklab: hack around khtml/pcre bug...
+			[^\r]*?\n			// any number of lines, minimally matching
+			</\2>				// the matching end tag
+			[ \t]*				// trailing spaces/tabs
+			(?=\n+)				// followed by a newline
+		)						// attacklab: there are sentinel newlines at end of document
+		/gm,function(){...}};
+	*/
+	text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,hashElement);
+
+	//
+	// Now match more liberally, simply from `\n<tag>` to `</tag>\n`
+	//
+
+	/*
+		var text = text.replace(/
+		(						// save in $1
+			^					// start of line  (with /m)
+			<($block_tags_b)	// start tag = $2
+			\b					// word break
+								// attacklab: hack around khtml/pcre bug...
+			[^\r]*?				// any number of lines, minimally matching
+			.*</\2>				// the matching end tag
+			[ \t]*				// trailing spaces/tabs
+			(?=\n+)				// followed by a newline
+		)						// attacklab: there are sentinel newlines at end of document
+		/gm,function(){...}};
+	*/
+	text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
+
+	// Special case just for <hr />. It was easier to make a special case than
+	// to make the other regex more complicated.
+
+	/*
+		text = text.replace(/
+		(						// save in $1
+			\n\n				// Starting after a blank line
+			[ ]{0,3}
+			(<(hr)				// start tag = $2
+			\b					// word break
+			([^<>])*?			//
+			\/?>)				// the matching end tag
+			[ \t]*
+			(?=\n{2,})			// followed by a blank line
+		)
+		/g,hashElement);
+	*/
+	text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,hashElement);
+
+	// Special case for standalone HTML comments:
+
+	/*
+		text = text.replace(/
+		(						// save in $1
+			\n\n				// Starting after a blank line
+			[ ]{0,3}			// attacklab: g_tab_width - 1
+			<!
+			(--[^\r]*?--\s*)+
+			>
+			[ \t]*
+			(?=\n{2,})			// followed by a blank line
+		)
+		/g,hashElement);
+	*/
+	text = text.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,hashElement);
+
+	// PHP and ASP-style processor instructions (<?...?> and <%...%>)
+
+	/*
+		text = text.replace(/
+		(?:
+			\n\n				// Starting after a blank line
+		)
+		(						// save in $1
+			[ ]{0,3}			// attacklab: g_tab_width - 1
+			(?:
+				<([?%])			// $2
+				[^\r]*?
+				\2>
+			)
+			[ \t]*
+			(?=\n{2,})			// followed by a blank line
+		)
+		/g,hashElement);
+	*/
+	text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,hashElement);
+
+	// attacklab: Undo double lines (see comment at top of this function)
+	text = text.replace(/\n\n/g,"\n");
+	return text;
+}
+
+var hashElement = function(wholeMatch,m1) {
+	var blockText = m1;
+
+	// Undo double lines
+	blockText = blockText.replace(/\n\n/g,"\n");
+	blockText = blockText.replace(/^\n/,"");
+
+	// strip trailing blank lines
+	blockText = blockText.replace(/\n+$/g,"");
+
+	// Replace the element text with a marker ("~KxK" where x is its key)
+	blockText = "\n\n~K" + (g_html_blocks.push(blockText)-1) + "K\n\n";
+
+	return blockText;
+};
+
+var _RunBlockGamut = function(text) {
+//
+// These are all the transformations that form block-level
+// tags like paragraphs, headers, and list items.
+//
+	text = _DoHeaders(text);
+
+	// Do Horizontal Rules:
+	var key = hashBlock("<hr />");
+	text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key);
+	text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key);
+	text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key);
+
+	text = _DoLists(text);
+	text = _DoCodeBlocks(text);
+	text = _DoBlockQuotes(text);
+
+	// We already ran _HashHTMLBlocks() before, in Markdown(), but that
+	// was to escape raw HTML in the original Markdown source. This time,
+	// we're escaping the markup we've just created, so that we don't wrap
+	// <p> tags around block-level tags.
+	text = _HashHTMLBlocks(text);
+	text = _FormParagraphs(text);
+
+	return text;
+};
+
+
+var _RunSpanGamut = function(text) {
+//
+// These are all the transformations that occur *within* block-level
+// tags like paragraphs, headers, and list items.
+//
+
+	text = _DoCodeSpans(text);
+	text = _EscapeSpecialCharsWithinTagAttributes(text);
+	text = _EncodeBackslashEscapes(text);
+
+	// Process anchor and image tags. Images must come first,
+	// because ![foo][f] looks like an anchor.
+	text = _DoImages(text);
+	text = _DoAnchors(text);
+
+	// Make links out of things like `<http://example.com/>`
+	// Must come after _DoAnchors(), because you can use < and >
+	// delimiters in inline links like [this](<url>).
+	text = _DoAutoLinks(text);
+	text = _EncodeAmpsAndAngles(text);
+	text = _DoItalicsAndBold(text);
+
+	// Do hard breaks:
+	text = text.replace(/  +\n/g," <br />\n");
+
+	return text;
+}
+
+var _EscapeSpecialCharsWithinTagAttributes = function(text) {
+//
+// Within tags -- meaning between < and > -- encode [\ ` * _] so they
+// don't conflict with their use in Markdown for code, italics and strong.
+//
+
+	// Build a regex to find HTML tags and comments.  See Friedl's
+	// "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
+	var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;
+
+	text = text.replace(regex, function(wholeMatch) {
+		var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g,"$1`");
+		tag = escapeCharacters(tag,"\\`*_");
+		return tag;
+	});
+
+	return text;
+}
+
+var _DoAnchors = function(text) {
+//
+// Turn Markdown link shortcuts into XHTML <a> tags.
+//
+	//
+	// First, handle reference-style links: [link text] [id]
+	//
+
+	/*
+		text = text.replace(/
+		(							// wrap whole match in $1
+			\[
+			(
+				(?:
+					\[[^\]]*\]		// allow brackets nested one level
+					|
+					[^\[]			// or anything else
+				)*
+			)
+			\]
+
+			[ ]?					// one optional space
+			(?:\n[ ]*)?				// one optional newline followed by spaces
+
+			\[
+			(.*?)					// id = $3
+			\]
+		)()()()()					// pad remaining backreferences
+		/g,_DoAnchors_callback);
+	*/
+	text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeAnchorTag);
+
+	//
+	// Next, inline-style links: [link text](url "optional title")
+	//
+
+	/*
+		text = text.replace(/
+			(						// wrap whole match in $1
+				\[
+				(
+					(?:
+						\[[^\]]*\]	// allow brackets nested one level
+					|
+					[^\[\]]			// or anything else
+				)
+			)
+			\]
+			\(						// literal paren
+			[ \t]*
+			()						// no id, so leave $3 empty
+			<?(.*?)>?				// href = $4
+			[ \t]*
+			(						// $5
+				(['"])				// quote char = $6
+				(.*?)				// Title = $7
+				\6					// matching quote
+				[ \t]*				// ignore any spaces/tabs between closing quote and )
+			)?						// title is optional
+			\)
+		)
+		/g,writeAnchorTag);
+	*/
+	text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
+
+	//
+	// Last, handle reference-style shortcuts: [link text]
+	// These must come last in case you've also got [link test][1]
+	// or [link test](/foo)
+	//
+
+	/*
+		text = text.replace(/
+		(		 					// wrap whole match in $1
+			\[
+			([^\[\]]+)				// link text = $2; can't contain '[' or ']'
+			\]
+		)()()()()()					// pad rest of backreferences
+		/g, writeAnchorTag);
+	*/
+	text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
+
+	return text;
+}
+
+var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
+	if (m7 == undefined) m7 = "";
+	var whole_match = m1;
+	var link_text   = m2;
+	var link_id	 = m3.toLowerCase();
+	var url		= m4;
+	var title	= m7;
+
+	if (url == "") {
+		if (link_id == "") {
+			// lower-case and turn embedded newlines into spaces
+			link_id = link_text.toLowerCase().replace(/ ?\n/g," ");
+		}
+		url = "#"+link_id;
+
+		if (g_urls[link_id] != undefined) {
+			url = g_urls[link_id];
+			if (g_titles[link_id] != undefined) {
+				title = g_titles[link_id];
+			}
+		}
+		else {
+			if (whole_match.search(/\(\s*\)$/m)>-1) {
+				// Special case for explicit empty url
+				url = "";
+			} else {
+				return whole_match;
+			}
+		}
+	}
+
+	url = escapeCharacters(url,"*_");
+	var result = "<a href=\"" + url + "\"";
+
+	if (title != "") {
+		title = title.replace(/"/g,"&quot;");
+		title = escapeCharacters(title,"*_");
+		result +=  " title=\"" + title + "\"";
+	}
+
+	result += ">" + link_text + "</a>";
+
+	return result;
+}
+
+
+var _DoImages = function(text) {
+//
+// Turn Markdown image shortcuts into <img> tags.
+//
+
+	//
+	// First, handle reference-style labeled images: ![alt text][id]
+	//
+
+	/*
+		text = text.replace(/
+		(						// wrap whole match in $1
+			!\[
+			(.*?)				// alt text = $2
+			\]
+
+			[ ]?				// one optional space
+			(?:\n[ ]*)?			// one optional newline followed by spaces
+
+			\[
+			(.*?)				// id = $3
+			\]
+		)()()()()				// pad rest of backreferences
+		/g,writeImageTag);
+	*/
+	text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeImageTag);
+
+	//
+	// Next, handle inline images:  ![alt text](url "optional title")
+	// Don't forget: encode * and _
+
+	/*
+		text = text.replace(/
+		(						// wrap whole match in $1
+			!\[
+			(.*?)				// alt text = $2
+			\]
+			\s?					// One optional whitespace character
+			\(					// literal paren
+			[ \t]*
+			()					// no id, so leave $3 empty
+			<?(\S+?)>?			// src url = $4
+			[ \t]*
+			(					// $5
+				(['"])			// quote char = $6
+				(.*?)			// title = $7
+				\6				// matching quote
+				[ \t]*
+			)?					// title is optional
+		\)
+		)
+		/g,writeImageTag);
+	*/
+	text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeImageTag);
+
+	return text;
+}
+
+var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
+	var whole_match = m1;
+	var alt_text   = m2;
+	var link_id	 = m3.toLowerCase();
+	var url		= m4;
+	var title	= m7;
+
+	if (!title) title = "";
+
+	if (url == "") {
+		if (link_id == "") {
+			// lower-case and turn embedded newlines into spaces
+			link_id = alt_text.toLowerCase().replace(/ ?\n/g," ");
+		}
+		url = "#"+link_id;
+
+		if (g_urls[link_id] != undefined) {
+			url = g_urls[link_id];
+			if (g_titles[link_id] != undefined) {
+				title = g_titles[link_id];
+			}
+		}
+		else {
+			return whole_match;
+		}
+	}
+
+	alt_text = alt_text.replace(/"/g,"&quot;");
+	url = escapeCharacters(url,"*_");
+	var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
+
+	// attacklab: Markdown.pl adds empty title attributes to images.
+	// Replicate this bug.
+
+	//if (title != "") {
+		title = title.replace(/"/g,"&quot;");
+		title = escapeCharacters(title,"*_");
+		result +=  " title=\"" + title + "\"";
+	//}
+
+	result += " />";
+
+	return result;
+}
+
+
+var _DoHeaders = function(text) {
+
+	// Setext-style headers:
+	//	Header 1
+	//	========
+	//
+	//	Header 2
+	//	--------
+	//
+	text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
+		function(wholeMatch,m1){return hashBlock('<h1 id="' + headerId(m1) + '">' + _RunSpanGamut(m1) + "</h1>");});
+
+	text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
+		function(matchFound,m1){return hashBlock('<h2 id="' + headerId(m1) + '">' + _RunSpanGamut(m1) + "</h2>");});
+
+	// atx-style headers:
+	//  # Header 1
+	//  ## Header 2
+	//  ## Header 2 with closing hashes ##
+	//  ...
+	//  ###### Header 6
+	//
+
+	/*
+		text = text.replace(/
+			^(\#{1,6})				// $1 = string of #'s
+			[ \t]*
+			(.+?)					// $2 = Header text
+			[ \t]*
+			\#*						// optional closing #'s (not counted)
+			\n+
+		/gm, function() {...});
+	*/
+
+	text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
+		function(wholeMatch,m1,m2) {
+			var h_level = m1.length;
+			return hashBlock("<h" + h_level + ' id="' + headerId(m2) + '">' + _RunSpanGamut(m2) + "</h" + h_level + ">");
+		});
+
+	function headerId(m) {
+		return m.replace(/[^\w]/g, '').toLowerCase();
+	}
+	return text;
+}
+
+// This declaration keeps Dojo compressor from outputting garbage:
+var _ProcessListItems;
+
+var _DoLists = function(text) {
+//
+// Form HTML ordered (numbered) and unordered (bulleted) lists.
+//
+
+	// attacklab: add sentinel to hack around khtml/safari bug:
+	// http://bugs.webkit.org/show_bug.cgi?id=11231
+	text += "~0";
+
+	// Re-usable pattern to match any entirel ul or ol list:
+
+	/*
+		var whole_list = /
+		(									// $1 = whole list
+			(								// $2
+				[ ]{0,3}					// attacklab: g_tab_width - 1
+				([*+-]|\d+[.])				// $3 = first list item marker
+				[ \t]+
+			)
+			[^\r]+?
+			(								// $4
+				~0							// sentinel for workaround; should be $
+			|
+				\n{2,}
+				(?=\S)
+				(?!							// Negative lookahead for another list item marker
+					[ \t]*
+					(?:[*+-]|\d+[.])[ \t]+
+				)
+			)
+		)/g
+	*/
+	var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
+
+	if (g_list_level) {
+		text = text.replace(whole_list,function(wholeMatch,m1,m2) {
+			var list = m1;
+			var list_type = (m2.search(/[*+-]/g)>-1) ? "ul" : "ol";
+
+			// Turn double returns into triple returns, so that we can make a
+			// paragraph for the last item in a list, if necessary:
+			list = list.replace(/\n{2,}/g,"\n\n\n");;
+			var result = _ProcessListItems(list);
+
+			// Trim any trailing whitespace, to put the closing `</$list_type>`
+			// up on the preceding line, to get it past the current stupid
+			// HTML block parser. This is a hack to work around the terrible
+			// hack that is the HTML block parser.
+			result = result.replace(/\s+$/,"");
+			result = "<"+list_type+">" + result + "</"+list_type+">\n";
+			return result;
+		});
+	} else {
+		whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
+		text = text.replace(whole_list,function(wholeMatch,m1,m2,m3) {
+			var runup = m1;
+			var list = m2;
+
+			var list_type = (m3.search(/[*+-]/g)>-1) ? "ul" : "ol";
+			// Turn double returns into triple returns, so that we can make a
+			// paragraph for the last item in a list, if necessary:
+			var list = list.replace(/\n{2,}/g,"\n\n\n");;
+			var result = _ProcessListItems(list);
+			result = runup + "<"+list_type+">\n" + result + "</"+list_type+">\n";
+			return result;
+		});
+	}
+
+	// attacklab: strip sentinel
+	text = text.replace(/~0/,"");
+
+	return text;
+}
+
+_ProcessListItems = function(list_str) {
+//
+//  Process the contents of a single ordered or unordered list, splitting it
+//  into individual list items.
+//
+	// The $g_list_level global keeps track of when we're inside a list.
+	// Each time we enter a list, we increment it; when we leave a list,
+	// we decrement. If it's zero, we're not in a list anymore.
+	//
+	// We do this because when we're not inside a list, we want to treat
+	// something like this:
+	//
+	//    I recommend upgrading to version
+	//    8. Oops, now this line is treated
+	//    as a sub-list.
+	//
+	// As a single paragraph, despite the fact that the second line starts
+	// with a digit-period-space sequence.
+	//
+	// Whereas when we're inside a list (or sub-list), that line will be
+	// treated as the start of a sub-list. What a kludge, huh? This is
+	// an aspect of Markdown's syntax that's hard to parse perfectly
+	// without resorting to mind-reading. Perhaps the solution is to
+	// change the syntax rules such that sub-lists must start with a
+	// starting cardinal number; e.g. "1." or "a.".
+
+	g_list_level++;
+
+	// trim trailing blank lines:
+	list_str = list_str.replace(/\n{2,}$/,"\n");
+
+	// attacklab: add sentinel to emulate \z
+	list_str += "~0";
+
+	/*
+		list_str = list_str.replace(/
+			(\n)?							// leading line = $1
+			(^[ \t]*)						// leading whitespace = $2
+			([*+-]|\d+[.]) [ \t]+			// list marker = $3
+			([^\r]+?						// list item text   = $4
+			(\n{1,2}))
+			(?= \n* (~0 | \2 ([*+-]|\d+[.]) [ \t]+))
+		/gm, function(){...});
+	*/
+	list_str = list_str.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
+		function(wholeMatch,m1,m2,m3,m4){
+			var item = m4;
+			var leading_line = m1;
+			var leading_space = m2;
+
+			if (leading_line || (item.search(/\n{2,}/)>-1)) {
+				item = _RunBlockGamut(_Outdent(item));
+			}
+			else {
+				// Recursion for sub-lists:
+				item = _DoLists(_Outdent(item));
+				item = item.replace(/\n$/,""); // chomp(item)
+				item = _RunSpanGamut(item);
+			}
+
+			return  "<li>" + item + "</li>\n";
+		}
+	);
+
+	// attacklab: strip sentinel
+	list_str = list_str.replace(/~0/g,"");
+
+	g_list_level--;
+	return list_str;
+}
+
+
+var _DoCodeBlocks = function(text) {
+//
+//  Process Markdown `<pre><code>` blocks.
+//
+
+	/*
+		text = text.replace(text,
+			/(?:\n\n|^)
+			(								// $1 = the code block -- one or more lines, starting with a space/tab
+				(?:
+					(?:[ ]{4}|\t)			// Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
+					.*\n+
+				)+
+			)
+			(\n*[ ]{0,3}[^ \t\n]|(?=~0))	// attacklab: g_tab_width
+		/g,function(){...});
+	*/
+
+	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
+	text += "~0";
+
+	text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
+		function(wholeMatch,m1,m2) {
+			var codeblock = m1;
+			var nextChar = m2;
+
+			codeblock = _EncodeCode( _Outdent(codeblock));
+			codeblock = _Detab(codeblock);
+			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
+			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
+
+			codeblock = "<pre><code>" + codeblock + "\n</code></pre>";
+
+			return hashBlock(codeblock) + nextChar;
+		}
+	);
+
+	// attacklab: strip sentinel
+	text = text.replace(/~0/,"");
+
+	return text;
+};
+
+var _DoGithubCodeBlocks = function(text) {
+//
+//  Process Github-style code blocks
+//  Example:
+//  ```ruby
+//  def hello_world(x)
+//    puts "Hello, #{x}"
+//  end
+//  ```
+//
+
+
+	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
+	text += "~0";
+
+	text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g,
+		function(wholeMatch,m1,m2) {
+			var language = m1;
+			var codeblock = m2;
+
+			codeblock = _EncodeCode(codeblock);
+			codeblock = _Detab(codeblock);
+			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
+			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
+
+			codeblock = "<pre><code" + (language ? " class=\"" + language + '"' : "") + ">" + codeblock + "\n</code></pre>";
+
+			return hashBlock(codeblock);
+		}
+	);
+
+	// attacklab: strip sentinel
+	text = text.replace(/~0/,"");
+
+	return text;
+}
+
+var hashBlock = function(text) {
+	text = text.replace(/(^\n+|\n+$)/g,"");
+	return "\n\n~K" + (g_html_blocks.push(text)-1) + "K\n\n";
+}
+
+var _DoCodeSpans = function(text) {
+//
+//   *  Backtick quotes are used for <code></code> spans.
+//
+//   *  You can use multiple backticks as the delimiters if you want to
+//	 include literal backticks in the code span. So, this input:
+//
+//		 Just type ``foo `bar` baz`` at the prompt.
+//
+//	   Will translate to:
+//
+//		 <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
+//
+//	There's no arbitrary limit to the number of backticks you
+//	can use as delimters. If you need three consecutive backticks
+//	in your code, use four for delimiters, etc.
+//
+//  *  You can use spaces to get literal backticks at the edges:
+//
+//		 ... type `` `bar` `` ...
+//
+//	   Turns to:
+//
+//		 ... type <code>`bar`</code> ...
+//
+
+	/*
+		text = text.replace(/
+			(^|[^\\])					// Character before opening ` can't be a backslash
+			(`+)						// $2 = Opening run of `
+			(							// $3 = The code block
+				[^\r]*?
+				[^`]					// attacklab: work around lack of lookbehind
+			)
+			\2							// Matching closer
+			(?!`)
+		/gm, function(){...});
+	*/
+
+	text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
+		function(wholeMatch,m1,m2,m3,m4) {
+			var c = m3;
+			c = c.replace(/^([ \t]*)/g,"");	// leading whitespace
+			c = c.replace(/[ \t]*$/g,"");	// trailing whitespace
+			c = _EncodeCode(c);
+			return m1+"<code>"+c+"</code>";
+		});
+
+	return text;
+}
+
+var _EncodeCode = function(text) {
+//
+// Encode/escape certain characters inside Markdown code runs.
+// The point is that in code, these characters are literals,
+// and lose their special Markdown meanings.
+//
+	// Encode all ampersands; HTML entities are not
+	// entities within a Markdown code span.
+	text = text.replace(/&/g,"&amp;");
+
+	// Do the angle bracket song and dance:
+	text = text.replace(/</g,"&lt;");
+	text = text.replace(/>/g,"&gt;");
+
+	// Now, escape characters that are magic in Markdown:
+	text = escapeCharacters(text,"\*_{}[]\\",false);
+
+// jj the line above breaks this:
+//---
+
+//* Item
+
+//   1. Subitem
+
+//            special char: *
+//---
+
+	return text;
+}
+
+
+var _DoItalicsAndBold = function(text) {
+
+	// <strong> must go first:
+	text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
+		"<strong>$2</strong>");
+
+	text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,
+		"<em>$2</em>");
+
+	return text;
+}
+
+
+var _DoBlockQuotes = function(text) {
+
+	/*
+		text = text.replace(/
+		(								// Wrap whole match in $1
+			(
+				^[ \t]*>[ \t]?			// '>' at the start of a line
+				.+\n					// rest of the first line
+				(.+\n)*					// subsequent consecutive lines
+				\n*						// blanks
+			)+
+		)
+		/gm, function(){...});
+	*/
+
+	text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
+		function(wholeMatch,m1) {
+			var bq = m1;
+
+			// attacklab: hack around Konqueror 3.5.4 bug:
+			// "----------bug".replace(/^-/g,"") == "bug"
+
+			bq = bq.replace(/^[ \t]*>[ \t]?/gm,"~0");	// trim one level of quoting
+
+			// attacklab: clean up hack
+			bq = bq.replace(/~0/g,"");
+
+			bq = bq.replace(/^[ \t]+$/gm,"");		// trim whitespace-only lines
+			bq = _RunBlockGamut(bq);				// recurse
+
+			bq = bq.replace(/(^|\n)/g,"$1  ");
+			// These leading spaces screw with <pre> content, so we need to fix that:
+			bq = bq.replace(
+					/(\s*<pre>[^\r]+?<\/pre>)/gm,
+				function(wholeMatch,m1) {
+					var pre = m1;
+					// attacklab: hack around Konqueror 3.5.4 bug:
+					pre = pre.replace(/^  /mg,"~0");
+					pre = pre.replace(/~0/g,"");
+					return pre;
+				});
+
+			return hashBlock("<blockquote>\n" + bq + "\n</blockquote>");
+		});
+	return text;
+}
+
+
+var _FormParagraphs = function(text) {
+//
+//  Params:
+//    $text - string to process with html <p> tags
+//
+
+	// Strip leading and trailing lines:
+	text = text.replace(/^\n+/g,"");
+	text = text.replace(/\n+$/g,"");
+
+	var grafs = text.split(/\n{2,}/g);
+	var grafsOut = new Array();
+
+	//
+	// Wrap <p> tags.
+	//
+	var end = grafs.length;
+	for (var i=0; i<end; i++) {
+		var str = grafs[i];
+
+		// if this is an HTML marker, copy it
+		if (str.search(/~K(\d+)K/g) >= 0) {
+			grafsOut.push(str);
+		}
+		else if (str.search(/\S/) >= 0) {
+			str = _RunSpanGamut(str);
+			str = str.replace(/^([ \t]*)/g,"<p>");
+			str += "</p>"
+			grafsOut.push(str);
+		}
+
+	}
+
+	//
+	// Unhashify HTML blocks
+	//
+	end = grafsOut.length;
+	for (var i=0; i<end; i++) {
+		// if this is a marker for an html block...
+		while (grafsOut[i].search(/~K(\d+)K/) >= 0) {
+			var blockText = g_html_blocks[RegExp.$1];
+			blockText = blockText.replace(/\$/g,"$$$$"); // Escape any dollar signs
+			grafsOut[i] = grafsOut[i].replace(/~K\d+K/,blockText);
+		}
+	}
+
+	return grafsOut.join("\n\n");
+}
+
+
+var _EncodeAmpsAndAngles = function(text) {
+// Smart processing for ampersands and angle brackets that need to be encoded.
+
+	// Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
+	//   http://bumppo.net/projects/amputator/
+	text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&amp;");
+
+	// Encode naked <'s
+	text = text.replace(/<(?![a-z\/?\$!])/gi,"&lt;");
+
+	return text;
+}
+
+
+var _EncodeBackslashEscapes = function(text) {
+//
+//   Parameter:  String.
+//   Returns:	The string, with after processing the following backslash
+//			   escape sequences.
+//
+
+	// attacklab: The polite way to do this is with the new
+	// escapeCharacters() function:
+	//
+	// 	text = escapeCharacters(text,"\\",true);
+	// 	text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
+	//
+	// ...but we're sidestepping its use of the (slow) RegExp constructor
+	// as an optimization for Firefox.  This function gets called a LOT.
+
+	text = text.replace(/\\(\\)/g,escapeCharacters_callback);
+	text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g,escapeCharacters_callback);
+	return text;
+}
+
+
+var _DoAutoLinks = function(text) {
+
+	text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
+
+	// Email addresses: <address@domain.foo>
+
+	/*
+		text = text.replace(/
+			<
+			(?:mailto:)?
+			(
+				[-.\w]+
+				\@
+				[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
+			)
+			>
+		/gi, _DoAutoLinks_callback());
+	*/
+	text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
+		function(wholeMatch,m1) {
+			return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
+		}
+	);
+
+	return text;
+}
+
+
+var _EncodeEmailAddress = function(addr) {
+//
+//  Input: an email address, e.g. "foo@example.com"
+//
+//  Output: the email address as a mailto link, with each character
+//	of the address encoded as either a decimal or hex entity, in
+//	the hopes of foiling most address harvesting spam bots. E.g.:
+//
+//	<a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
+//	   x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
+//	   &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
+//
+//  Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
+//  mailing list: <http://tinyurl.com/yu7ue>
+//
+
+	// attacklab: why can't javascript speak hex?
+	function char2hex(ch) {
+		var hexDigits = '0123456789ABCDEF';
+		var dec = ch.charCodeAt(0);
+		return(hexDigits.charAt(dec>>4) + hexDigits.charAt(dec&15));
+	}
+
+	var encode = [
+		function(ch){return "&#"+ch.charCodeAt(0)+";";},
+		function(ch){return "&#x"+char2hex(ch)+";";},
+		function(ch){return ch;}
+	];
+
+	addr = "mailto:" + addr;
+
+	addr = addr.replace(/./g, function(ch) {
+		if (ch == "@") {
+		   	// this *must* be encoded. I insist.
+			ch = encode[Math.floor(Math.random()*2)](ch);
+		} else if (ch !=":") {
+			// leave ':' alone (to spot mailto: later)
+			var r = Math.random();
+			// roughly 10% raw, 45% hex, 45% dec
+			ch =  (
+					r > .9  ?	encode[2](ch)   :
+					r > .45 ?	encode[1](ch)   :
+								encode[0](ch)
+				);
+		}
+		return ch;
+	});
+
+	addr = "<a href=\"" + addr + "\">" + addr + "</a>";
+	addr = addr.replace(/">.+:/g,"\">"); // strip the mailto: from the visible part
+
+	return addr;
+}
+
+
+var _UnescapeSpecialChars = function(text) {
+//
+// Swap back in all the special characters we've hidden.
+//
+	text = text.replace(/~E(\d+)E/g,
+		function(wholeMatch,m1) {
+			var charCodeToReplace = parseInt(m1);
+			return String.fromCharCode(charCodeToReplace);
+		}
+	);
+	return text;
+}
+
+
+var _Outdent = function(text) {
+//
+// Remove one level of line-leading tabs or spaces
+//
+
+	// attacklab: hack around Konqueror 3.5.4 bug:
+	// "----------bug".replace(/^-/g,"") == "bug"
+
+	text = text.replace(/^(\t|[ ]{1,4})/gm,"~0"); // attacklab: g_tab_width
+
+	// attacklab: clean up hack
+	text = text.replace(/~0/g,"")
+
+	return text;
+}
+
+var _Detab = function(text) {
+// attacklab: Detab's completely rewritten for speed.
+// In perl we could fix it by anchoring the regexp with \G.
+// In javascript we're less fortunate.
+
+	// expand first n-1 tabs
+	text = text.replace(/\t(?=\t)/g,"    "); // attacklab: g_tab_width
+
+	// replace the nth with two sentinels
+	text = text.replace(/\t/g,"~A~B");
+
+	// use the sentinel to anchor our regex so it doesn't explode
+	text = text.replace(/~B(.+?)~A/g,
+		function(wholeMatch,m1,m2) {
+			var leadingText = m1;
+			var numSpaces = 4 - leadingText.length % 4;  // attacklab: g_tab_width
+
+			// there *must* be a better way to do this:
+			for (var i=0; i<numSpaces; i++) leadingText+=" ";
+
+			return leadingText;
+		}
+	);
+
+	// clean up sentinels
+	text = text.replace(/~A/g,"    ");  // attacklab: g_tab_width
+	text = text.replace(/~B/g,"");
+
+	return text;
+}
+
+
+//
+//  attacklab: Utility functions
+//
+
+
+var escapeCharacters = function(text, charsToEscape, afterBackslash) {
+	// First we have to escape the escape characters so that
+	// we can build a character class out of them
+	var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g,"\\$1") + "])";
+
+	if (afterBackslash) {
+		regexString = "\\\\" + regexString;
+	}
+
+	var regex = new RegExp(regexString,"g");
+	text = text.replace(regex,escapeCharacters_callback);
+
+	return text;
+}
+
+
+var escapeCharacters_callback = function(wholeMatch,m1) {
+	var charCodeToEscape = m1.charCodeAt(0);
+	return "~E"+charCodeToEscape+"E";
+}
+
+} // end of Showdown.converter
+
+// export
+if (typeof module !== 'undefined') module.exports = Showdown;
diff --git a/docs/slides/flops14/_support/reveal/package.json b/docs/slides/flops14/_support/reveal/package.json
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/package.json
@@ -0,0 +1,20 @@
+{
+	"author": "Hakim El Hattab",
+	"name": "reveal.js",
+	"description": "HTML5 Slideware with Presenter Notes",
+	"version": "1.5.0",
+	"repository": {
+		"type": "git",
+		"url": "git://github.com/hakimel/reveal.js.git"
+	},
+	"engines": {
+		"node": "~0.6.8"
+	},
+	"dependencies": {
+		"underscore" : "1.3.3",
+		"express" : "2.5.9",
+		"socket.io" : "0.9.6",
+		"mustache" : "0.4.0"
+	},
+	"devDependencies": {}
+}
diff --git a/docs/slides/flops14/_support/reveal/plugin/speakernotes/client.js b/docs/slides/flops14/_support/reveal/plugin/speakernotes/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/plugin/speakernotes/client.js
@@ -0,0 +1,35 @@
+(function() {
+	// don't emit events from inside the previews themselves
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var socket = io.connect(window.location.origin);
+	var socketId = Math.random().toString().slice(2);
+	
+	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
+
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		var nextindexh;
+		var nextindexv;
+		var slideElement = event.currentSlide;
+
+		if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+			nextindexh = event.indexh;
+			nextindexv = event.indexv + 1;
+		} else {
+			nextindexh = event.indexh + 1;
+			nextindexv = 0;
+		}
+
+		var notes = slideElement.querySelector('aside.notes');
+		var slideData = {
+			notes : notes ? notes.innerHTML : '',
+			indexh : event.indexh,
+			indexv : event.indexv,
+			nextindexh : nextindexh,
+			nextindexv : nextindexv,
+			socketId : socketId
+		};
+
+		socket.emit('slidechanged', slideData);
+	} );
+}());
diff --git a/docs/slides/flops14/_support/reveal/plugin/speakernotes/index.js b/docs/slides/flops14/_support/reveal/plugin/speakernotes/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/plugin/speakernotes/index.js
@@ -0,0 +1,55 @@
+var express   = require('express');
+var fs        = require('fs');
+var io        = require('socket.io');
+var _         = require('underscore');
+var Mustache  = require('mustache');
+
+var app       = express.createServer();
+var staticDir = express.static;
+
+io            = io.listen(app);
+
+var opts = {
+	port :      1947,
+	baseDir :   __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		socket.broadcast.emit('slidedata', slideData);
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/notes/:socketId", function(req, res) {
+
+	fs.readFile(opts.baseDir + 'plugin/speakernotes/notes.html', function(err, data) {
+		res.send(Mustache.to_html(data.toString(), {
+			socketId : req.params.socketId
+		}));
+	});
+	// fs.createReadStream(opts.baseDir + 'speakernotes/notes.html').pipe(res);
+});
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m', 
+	green = '\033[32m', 
+	reset = '\033[0m';
+
+var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
+
+console.log( brown + "reveal.js - Speaker Notes" + reset );
+console.log( "1. Open the slides at " + green + slidesLocation + reset );
+console.log( "2. Click on the link your JS console to go to the notes page" );
+console.log( "3. Advance through your slides and your notes will advance automatically" );
diff --git a/docs/slides/flops14/_support/reveal/plugin/speakernotes/notes.html b/docs/slides/flops14/_support/reveal/plugin/speakernotes/notes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/reveal/plugin/speakernotes/notes.html
@@ -0,0 +1,111 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Slide Notes</title>
+
+		<style>
+			body {
+				font-family: Helvetica;
+			}
+
+			#notes {
+				float: left;
+				font-size: 18px;
+				width: 640px;
+				margin-top: 10px;
+			}
+
+			#wrap-current-slide {
+				width: 400px;
+				height: 320px;
+				float: left;
+				overflow: hidden;
+			}
+
+			#current-slide {
+				width: 800px;
+				height: 600px;
+				border: none;
+				-moz-transform: scale(0.5);
+				-moz-transform-origin: 0 0;
+				-o-transform: scale(0.5);
+				-o-transform-origin: 0 0;
+				-webkit-transform: scale(0.5);
+				-webkit-transform-origin: 0 0;
+			}
+
+			#wrap-next-slide {
+				width: 320px;
+				height: 256px;
+				float: left;
+				margin: 0 0 0 10px;
+				overflow: hidden;
+			}
+
+			#next-slide {
+				width: 800px;
+				height: 600px;
+				border: none;
+				-moz-transform: scale(0.25);
+				-moz-transform-origin: 0 0;
+				-o-transform: scale(0.25);
+				-o-transform-origin: 0 0;
+				-webkit-transform: scale(0.25);
+				-webkit-transform-origin: 0 0;
+			}
+
+			.slides {
+				position: relative;
+				margin-bottom: 10px;
+				border: 1px solid black;
+				border-radius: 2px;
+				background: rgb(28, 30, 32);
+			}
+
+			.slides span {
+				position: absolute;
+				top: 3px;
+				left: 3px;
+				font-weight: bold;
+				font-size: 14px;
+				color: rgba( 255, 255, 255, 0.9 );
+			}
+		</style>
+	</head>
+
+	<body>
+
+		<div id="wrap-current-slide" class="slides">
+			<iframe src="/?receiver" width="800" height="600" id="current-slide"></iframe>
+		</div>
+
+		<div id="notes"></div>
+
+		<div id="wrap-next-slide" class="slides">
+			<iframe src="/?receiver" width="640" height="512" id="next-slide"></iframe>
+			<span>UPCOMING:</span>
+		</div>
+
+		<script src="/socket.io/socket.io.js"></script>
+
+		<script>
+		var socketId = '{{socketId}}';
+		var socket = io.connect(window.location.origin);
+		var notes = document.getElementById('notes');
+		var currentSlide = document.getElementById('current-slide');
+		var nextSlide = document.getElementById('next-slide');
+
+		socket.on('slidedata', function(data) {
+			// ignore data from sockets that aren't ours
+			if (data.socketId !== socketId) { return; }
+
+			notes.innerHTML = data.notes;
+			currentSlide.contentWindow.Reveal.navigateTo(data.indexh, data.indexv);
+			nextSlide.contentWindow.Reveal.navigateTo(data.nextindexh, data.nextindexv);
+		});
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/flops14/_support/template.reveal b/docs/slides/flops14/_support/template.reveal
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/_support/template.reveal
@@ -0,0 +1,103 @@
+<!doctype html>  
+<html lang="en">
+	
+<head>
+<meta charset="utf-8">
+
+<title>LiquidHaskell FLOPS 2014</title>
+
+<meta name="description" content="LiquidHaskell FLOPS 2014">
+<meta name="author" content="Ranjit Jhala">
+
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+
+<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
+
+<link rel="stylesheet" href="$reveal$/css/main.css">
+<link rel="stylesheet" href="$reveal$/css/theme/seminar.css" id="theme">
+<link rel="stylesheet" href="$reveal$/css/liquidhaskell.css">
+
+<!-- For syntax highlighting -->
+<link rel="stylesheet" href="$reveal$/lib/css/zenburn.css">
+
+<script>
+	// If the query includes 'print-pdf' we'll use the PDF print sheet
+	document.write( '<link rel="stylesheet" href="../_support/reveal_01/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
+</script>
+
+<!--[if lt IE 9]>
+<script src="lib/js/html5shiv.js"></script>
+<![endif]-->
+</head>
+<body>
+	
+<div class="reveal">
+<!-- 
+Used to fade in a background when a specific slide state is reached
+-->
+<div class="state-background"></div>
+
+<!-- Slides
+Any section element inside of this "slides" container is displayed as a slide
+-->
+<div class="slides">
+<!-- Pandoc -->
+$if(title)$
+<section class="titlepage">
+<h1 class="title">$title$</h1>
+$for(author)$
+<h2 class="author">$author$</h2>
+$endfor$
+<h3 class="date">$date$</h3>
+</section>
+$endif$
+$body$
+<!-- End Pandoc -->
+
+</div>
+<!-- End Slides -->
+
+<!-- The navigational controls UI -->
+<aside class="controls">
+<a class="left" href="#">&#x25C4;</a>
+<a class="right" href="#">&#x25BA;</a>
+<a class="up" href="#">&#x25B2;</a>
+<a class="down" href="#">&#x25BC;</a>
+</aside>
+
+<!-- Presentation progress bar -->
+<div class="progress"><span></span></div>
+</div>
+
+<!-- Initialize reveal.js :: make settings changes here -->
+<script src="$reveal$/lib/js/head.min.js"></script>
+<script src="$reveal$/js/reveal.js"></script>
+<script>		
+	// Full list of configuration options available here:
+	// https://github.com/hakimel/reveal.js#configuration
+	Reveal.initialize({
+		controls: true,
+		progress: true,
+		history: true,
+		center: false,
+        rollingLinks: false,
+        theme: Reveal.getQueryHash().theme || 'seminar', // available themes are in /css/theme
+		transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/linear(2d)
+
+		// Optional libraries used to extend on reveal.js
+		dependencies: [
+			{ src: '$reveal$/lib/js/highlight.js', async: true, callback: function() { window.hljs.initHighlightingOnLoad(); } },
+			{ src: '$reveal$/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+			{ src: '$reveal$/lib/js/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/lib/js/data-markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/socket.io/socket.io.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+			{ src: '$reveal$/plugin/speakernotes/client.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+		]
+	});
+</script>
+<!-- Script for LiveReload -->
+<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')
+</script>
+</body>
+</html>
diff --git a/docs/slides/flops14/cleanup b/docs/slides/flops14/cleanup
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/cleanup
@@ -0,0 +1,1 @@
+find . | grep -E -e '\.(smt2|bak|json|css|md|hi|out|fqout|fq|o|err|annot|log|html|cgi|liquid)$' | xargs rm -rf
diff --git a/docs/slides/flops14/img/RedBlack.png b/docs/slides/flops14/img/RedBlack.png
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/img/RedBlack.png differ
diff --git a/docs/slides/flops14/lhs/00_Index.lhs b/docs/slides/flops14/lhs/00_Index.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/00_Index.lhs
@@ -0,0 +1,198 @@
+
+
+ {#ASD}
+=======
+
+Liquid Types For Haskell
+------------------------
+
+
+<br>
+<br>
+
+**Ranjit Jhala**
+
+University of California, San Diego
+
+<br>
+<br>
+
+
+Joint work with: 
+
+N. Vazou, E. Seidel, P. Rondon, D. Vytiniotis, S. Peyton-Jones
+
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+Well-Typed Programs Can Go Wrong
+================================
+
+ {#asd}
+-------
+
+Division By Zero
+----------------
+
+<div class="fragment"> 
+\begin{code} <div/> 
+λ> let average xs = sum xs `div` length xs
+
+λ> average [1,2,3]
+2
+\end{code}
+</div>
+
+<div class="fragment"> 
+
+\begin{code} <br> 
+λ> average []
+*** Exception: divide by zero
+\end{code}
+
+</div>
+
+Missing Keys
+------------
+
+<div class="fragment"> 
+\begin{code} <div/> 
+λ> :m +Data.Map 
+λ> let m = fromList [ ("haskell", "lazy")
+                    , ("ocaml"  , "eager")]
+
+λ> m ! "haskell"
+"lazy"
+\end{code}
+</div>
+
+<div class="fragment"> 
+\begin{code} <br> 
+λ> m ! "javascript"
+"*** Exception: key is not in the map
+\end{code}
+</div>
+
+Segmentation Faults
+-------------------
+
+<div class="fragment"> 
+\begin{code} <div/> 
+λ> :m +Data.Vector 
+λ> let v = fromList ["haskell", "ocaml"]
+λ> unsafeIndex v 0
+"haskell"
+\end{code}
+</div>
+
+<div class="fragment"> 
+\begin{code} <br> 
+λ> V.unsafeIndex v 3
+
+
+'ghci' terminated by signal SIGSEGV ...
+\end{code}
+</div>
+
+
+"HeartBleeds"
+-------------
+
+\begin{code} <div/>
+λ> :m + Data.Text Data.Text.Unsafe 
+λ> let t = pack "Kanazawa"
+λ> takeWord16 5 t
+"Kanaz"
+\end{code}
+
+<br>
+
+<div class="fragment"> 
+Memory overflows **leaking secrets**...
+
+<br>
+
+\begin{code} <div/>
+λ> takeWord16 20 t
+"kamakura\1912\3148\SOH\NUL\15928\2486\SOH\NUL"
+\end{code}
+</div>
+
+Goal
+----
+
+Extend Hindley-Milner To Prevent More Errors
+
+Liquid Types for Haskell
+========================
+
+LiquidHaskell
+-------------
+
+<br>
+<br>
+
+<div class="fragment">Refine **types** with **predicates**</div>
+
+<br>
+<br>
+
+<div class="fragment">**Expressive** specification & **Automatic** verification</div>
+
+
+
+Automatic
+---------
+
+[Liquid Types, PLDI 08](http://goto.ucsd.edu/~rjhala/liquid/liquid_types.pdf)
+
+<br>
+
++ Abstract Interpretation 
+
++ SMT Solvers 
+
+Expressive
+----------
+
+<br>
+<br>
+
+This talk ...
+
+Try Yourself
+------------
+
+<br>
+
+**google: ** `"liquidhaskell demo"` 
+
+ {#zog} 
+--------
+
+<br>
+<br>
+<br>
+<br>
+
+[[continue]](01_SimpleRefinements.lhs.slides.html)
+
+
+Plan 
+----
+
+1. <a href="01_SimpleRefinements.lhs.slides.html" target= "_blank">Refinements
+2. <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
+3. <div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target= "_blank">Higher-Order Functions</a></div>
+4. <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements:</a> <a href="06_Inductive.lhs.slides.html" target="_blank">Code</a>, <a href="08_Recursive.lhs.slides.html" target= "_blank">Data</a>,<a href="07_Array.lhs.slides.html" target= "_blank">...</a>,<a href="05_Composition.lhs.slides.html" target= "_blank">...</a></div>
+5. <div class="fragment"><a href="09_Laziness.lhs.slides.html" target="_blank">Lazy Evaluation</a></div>
+6. <div class="fragment"><a href="10_Termination.lhs.slides.html" target="_blank">Termination</a></div>
+7. <div class="fragment"><a href="11_Evaluation.lhs.slides.html" target="_blank">Evaluation</a></div>
+
diff --git a/docs/slides/flops14/lhs/01_SimpleRefinements.lhs b/docs/slides/flops14/lhs/01_SimpleRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/01_SimpleRefinements.lhs
@@ -0,0 +1,391 @@
+ {#simplerefinements}
+=======================
+
+Simple Refinement Types
+-----------------------
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+module SimpleRefinements where
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (abs, max)
+
+-- boring haskell type sigs
+zero    :: Int
+zero'   :: Int
+safeDiv :: Int -> Int -> Int
+abs     :: Int -> Int
+nats    :: L Int
+evens   :: L Int
+odds    :: L Int
+range   :: Int -> Int -> L Int
+\end{code}
+
+</div>
+
+
+Simple Refinement Types
+=======================
+
+
+Types + Predicates 
+------------------
+
+
+Ex: `Int`egers equal to `0`
+---------------------------
+
+<br>
+
+\begin{code}
+{-@ type EqZero = {v:Int | v = 0} @-}
+
+{-@ zero :: EqZero @-}
+zero     =  0
+\end{code}
+
+<br>
+
+<div class="fragment">
+Refinement types via special comments `{-@ ... @-}` 
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo</a> 
+</div>
+
+
+
+Refinements Are Predicates
+==========================
+
+From A Decidable Logic
+----------------------
+
+1. Expressions
+
+2. Predicates
+
+
+Expressions
+-----------
+
+<br>
+
+\begin{code} <div/> 
+e := x, y, z,...      -- variable
+   | 0, 1, 2,...      -- constant
+   | (e + e)          -- addition
+   | (e - e)          -- subtraction
+   | (c * e)          -- linear multiplication
+   | (v e1 e2 ... en) -- uninterpreted function
+\end{code}
+
+Predicates
+----------
+
+<br>
+
+\begin{code} <div/>
+p := e           -- atom 
+   | e1 == e2    -- equality
+   | e1 <  e2    -- ordering 
+   | (p && p)    -- and
+   | (p || p)    -- or
+   | (not p)     -- negation
+\end{code}
+
+
+Subtyping is Implication
+------------------------
+
+[PVS' Predicate Subtyping](http://pvs.csl.sri.com/papers/subtypes98/tse98.pdf)
+
+
+<!--
+
+Subtyping is Implication
+------------------------
+
+<br>
+<br>
+
+--------  ---  ------------------   ---------   ------------------
+  **If**   :   Refinement of `S`    *implies*   Refinement of `T` 
+
+**Then**   :   `S`                  *subtype*   `T`
+--------  ---  ------------------   ---------   ------------------
+
+<br>
+
+-->
+
+Subtyping is Implication
+------------------------
+
+
+<br>
+<br>
+
+---------   ------------   --------------------------   
+  **If:**            `P`   `=> Q` 
+            
+**Then:**    `{v:t | P}`   `<: {v:t | Q}`
+---------   ------------   --------------------------   
+
+
+Example: Natural Numbers
+------------------------
+
+\begin{code} <div/> 
+        type Nat = {v:Int | 0 <= v}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+-------------    ---------  ----------------
+  **By SMT:**      `v = 0`  `=>`  `0 <= v` 
+             
+      **So:**     `EqZero`  `<:`  `Nat`
+-------------    ---------  ----------------
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+Hence, we can type:
+
+\begin{code}
+{-@ zero' :: Nat @-}
+zero'     =  zero   -- zero :: EqZero <: Nat
+\end{code}
+</div>
+
+ {#universalinvariants}
+=======================
+
+Types = Universal Invariants
+----------------------------
+
+(Notoriously hard with *pure* SMT)
+
+Types Yield Universal Invariants
+================================
+
+Example: Lists
+--------------
+
+<div class="hidden">
+\begin{code}
+infixr `C`
+\end{code}
+</div>
+
+\begin{code}
+data L a = N | C a (L a)
+\end{code}
+
+<br>
+
+<div class="fragment">
+*Every element* in `nats` is non-negative:
+
+<br>
+
+\begin{code}
+{-@ nats :: L Nat @-}
+nats     =  0 `C` 1 `C` 3 `C` N
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if `nats` contained `-2`? 
+
+</div>
+
+Example: Even/Odd Lists
+-----------------------
+
+\begin{code}
+{-@ type Even = {v:Int | v mod 2 =  0} @-}
+{-@ type Odd  = {v:Int | v mod 2 /= 0} @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ evens :: L Even @-}
+evens     =  0 `C` 2 `C` 4 `C` N
+
+{-@ odds  :: L Odd  @-}
+odds      =  1 `C` 3 `C` 5 `C` N 
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if `evens` contained `1`? 
+</div>
+
+
+
+Contracts: Function Types
+=========================
+
+ {#as}
+------
+
+Example: `safeDiv`
+------------------
+
+<br>
+
+**Precondition** divisor is *non-zero*.
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+\end{code}
+
+</div>
+
+
+Example: `safeDiv`
+------------------
+
+<br>
+
++ **Pre-condition** divisor is *non-zero*.
++ **Input type** specifies *pre-condition*
+
+<br>
+
+\begin{code}
+{-@ safeDiv :: Int -> NonZero -> Int @-}
+safeDiv x y = x `div` y
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if precondition does not hold?
+
+</div>
+
+Example: `abs`
+--------------
+
+<br>
+
++ **Postcondition** result is non-negative
++ **Output type** specifies *post-condition*
+
+<br>
+
+\begin{code}
+{-@ abs       :: x:Int -> Nat @-}
+abs x 
+  | 0 <= x    = x 
+  | otherwise = 0 - x
+\end{code}
+
+
+ {#dependentfunctions}
+======================
+
+Dependent Function Types
+------------------------
+
+<br>
+
+Outputs **refer to** inputs
+
+<br>
+
+**Relational** invariants
+
+
+Dependent Function Types
+========================
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s **between** `i` and `j`
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s **between** `i` and `j`
+
+<br>
+
+\begin{code}
+{-@ type Btwn I J = {v:_ | (I<=v && v<J)} @-}
+\end{code}
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+<br>
+
+\begin{code}
+{-@ range :: i:Int -> j:Int -> L (Btwn i j) @-}
+range i j            = go i
+  where
+    go n | n < j     = n `C` go (n + 1)  
+         | otherwise =  N
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Note:** Type of `go` is automatically inferred
+</div>
+
+
+Example: Indexing Into List
+---------------------------
+
+\begin{code} 
+(!)          :: L a -> Int -> a
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "Oops!"
+\end{code}
+
+<br>
+
+<div class="fragment">(Mouseover to view type of `liquidError`)</div>
+
+<br>
+
+<div class="fragment">To ensure safety, *require* `i` between `0` and list **length**</div>
+
+<br>
+
+<div class="fragment">Need way to **measure** the length of a list [[continue...]](02_Measures.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/flops14/lhs/02_Measures.lhs b/docs/slides/flops14/lhs/02_Measures.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/02_Measures.lhs
@@ -0,0 +1,441 @@
+
+ {#measures}
+============
+
+Measuring Data Types
+--------------------
+
+<div class="hidden">
+
+\begin{code}
+module Measures where
+import Prelude hiding ((!!), length)
+import Language.Haskell.Liquid.Prelude
+
+length      :: L a -> Int
+(!)         :: L a -> Int -> a
+insert      :: Ord a => a -> L a -> L a
+insertSort  :: Ord a => [a] -> L a
+
+infixr `C`
+\end{code}
+
+</div>
+
+
+Measuring Data Types 
+====================
+
+Recap
+-----
+
+1. <div class="fragment">**Refinements:** Types + Predicates</div>
+2. <div class="fragment">**Subtyping:** SMT Implication</div>
+
+
+Example: Length of a List 
+-------------------------
+
+Given a type for lists:
+
+<br>
+
+\begin{code}
+data L a = N | C a (L a)
+\end{code}
+
+<div class="fragment">
+<br>
+
+We can define the **length** as:
+
+<br>
+
+\begin{code}
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+\end{code}
+
+</div>
+
+Example: Length of a List 
+-------------------------
+
+\begin{code} <div/>
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+\end{code}
+
+<br>
+
+LiquidHaskell **strengthens** data constructor types
+
+<br>
+
+\begin{code} <div/>
+data L a where 
+  N :: {v: L a | (llen v) = 0}
+  C :: a -> t:_ -> {v:_| llen v = 1 + llen t}
+\end{code}
+
+Measures Are Uninterpreted
+--------------------------
+
+\begin{code} <br>
+data L a where 
+  N :: {v: L a | (llen v) = 0}
+  C :: a -> t:_ -> {v:_| llen v = 1 + llen t}
+\end{code}
+
+<br>
+
+`llen` is an **uninterpreted function** in SMT logic
+
+Measures Are Uninterpreted
+--------------------------
+
+<br>
+
+In SMT, [uninterpreted function](http://fm.csl.sri.com/SSFT12/smt-euf-arithmetic.pdf) `f` obeys *congruence* axiom:
+
+<br>
+
+`forall x y. (x = y) => (f x) = (f y)`
+
+<br>
+
+<div class="fragment">
+All other facts about `llen` asserted at **fold** and **unfold**
+</div>
+
+Measures Are Uninterpreted
+--------------------------
+
+Facts about `llen` asserted at *syntax-directed* **fold** and **unfold**
+
+<br>
+
+<div class="fragment">
+\begin{code}**Fold**<br>
+z = C x y     -- z :: {v | llen v = 1 + llen y}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{code}**Unfold**<br>
+case z of 
+  N     -> e1 -- z :: {v | llen v = 0}
+  C x y -> e2 -- z :: {v | llen v = 1 + llen y}
+\end{code}
+</div>
+
+
+Measured Refinements
+--------------------
+
+Now, we can verify:
+
+<br>
+
+\begin{code}
+{-@ length      :: xs:L a -> (EqLen xs) @-}
+length N        = 0
+length (C _ xs) = 1 + length xs
+\end{code}
+
+<div class="fragment">
+
+<br>
+
+Where `EqLen` is a type alias:
+
+\begin{code}
+{-@ type EqLen Xs = {v:Nat | v = (llen Xs)} @-}
+\end{code}
+
+</div>
+
+List Indexing Redux
+-------------------
+
+We can type list lookup:
+
+\begin{code}
+{-@ (!)      :: xs:L a -> (LtLen xs) -> a @-}
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "never happens!"
+\end{code}
+
+<br>
+
+<div class="fragment">
+Where `LtLen` is a type alias:
+
+\begin{code}
+{-@ type LtLen Xs = {v:Nat | v < (llen Xs)} @-}
+\end{code}
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellMeasure.hs" target= "_blank">Demo:</a> 
+&nbsp; What if we *remove* the precondition?
+
+</div>
+
+Multiple Measures
+=================
+
+ {#adasd}
+---------
+
+LiquidHaskell allows *many* measures for a type
+
+
+Ex: List Emptiness 
+------------------
+
+Measure describing whether a `List` is empty 
+
+\begin{code}
+{-@ measure isNull :: (L a) -> Prop
+    isNull (N)      = true
+    isNull (C x xs) = false           @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+LiquidHaskell **strengthens** data constructors
+
+\begin{code} <div/> 
+data L a where 
+  N :: {v : L a | (isNull v)}
+  C :: a -> L a -> {v:(L a) | not (isNull v)}
+\end{code}
+
+</div>
+
+Conjoining Refinements
+----------------------
+
+Data constructor refinements are **conjoined** 
+
+\begin{code} <br>
+data L a where 
+  N :: {v:L a |  (llen v) = 0 
+              && (isNull v) }
+  C :: a 
+    -> xs:L a 
+    -> {v:L a |  (llen v) = 1 + (llen xs) 
+              && not (isNull v)          }
+\end{code}
+
+Multiple Measures: Red-Black Trees
+==================================
+
+ {#asdad}
+---------
+
+<img src="../img/RedBlack.png" height=300px>
+
++ <div class="fragment">**Color Invariant:** `Red` nodes have `Black` children</div>
++ <div class="fragment">**Height Invariant:** Number of `Black` nodes equal on *all paths*</div>
+<br>
+
+[[Skip...]](#/4)
+
+Basic Type 
+----------
+
+\begin{code} <br>
+data Tree a = Leaf 
+            | Node Color a (Tree a) (Tree a)
+
+data Color  = Red 
+            | Black
+\end{code}
+
+Color Invariant 
+---------------
+
+`Red` nodes have `Black` children
+
+<div class="fragment">
+\begin{code} <br>
+measure isRB        :: Tree a -> Prop
+isRB (Leaf)         = true
+isRB (Node c x l r) = c=Red => (isB l && isB r)
+                      && isRB l && isRB r
+\end{code}
+</div>
+
+<div class="fragment">
+\begin{code} where <br>
+measure isB         :: Tree a -> Prop 
+isB (Leaf)          = true
+isB (Node c x l r)  = c == Black 
+\end{code}
+</div>
+
+*Almost* Color Invariant 
+------------------------
+
+<br>
+
+Color Invariant **except** at root. 
+
+<br>
+
+<div class="fragment">
+\begin{code} <br>
+measure isAlmost        :: Tree a -> Prop
+isAlmost (Leaf)         = true
+isAlmost (Node c x l r) = isRB l && isRB r
+\end{code}
+</div>
+
+
+Height Invariant
+----------------
+
+Number of `Black` nodes equal on **all paths**
+
+<div class="fragment">
+\begin{code} <br>
+measure isBH        :: RBTree a -> Prop
+isBH (Leaf)         =  true
+isBH (Node c x l r) =  bh l = bh r 
+                    && isBH l && isBH r 
+\end{code}
+</div>
+
+<div class="fragment">
+\begin{code} where <br>
+measure bh        :: RBTree a -> Int
+bh (Leaf)         = 0
+bh (Node c x l r) = bh l 
+                  + if c = Red then 0 else 1
+\end{code}
+</div>
+
+Refined Type 
+------------
+
+\begin{code} <br>
+-- Red-Black Trees
+type RBT a  = {v:Tree a | isRB v && isBH v}
+
+-- Almost Red-Black Trees
+type ARBT a = {v:Tree a | isAlmost v && isBH v}
+\end{code}
+
+<br>
+
+[Details](https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/pos/RBTree.hs)
+
+
+Measures vs. Index Types
+========================
+
+Decouple Property & Type 
+------------------------
+
+Unlike [indexed types](http://dl.acm.org/citation.cfm?id=270793) ...
+
+<br>
+
+<div class="fragment">
+
++ Measures **decouple** properties from structures
+
++ Support **multiple** properties over structures 
+
++ Enable  **reuse** of structures in different contexts                 
+
+</div>
+
+<br>
+
+<div class="fragment">Invaluable in practice!</div>
+
+Refined Data Constructors
+=========================
+
+ {#asd}
+-------
+
+Can encode invariants **inside constructors**
+
+<div class="fragment">
+
+<br>
+
+\begin{code}
+{-@ data L a = N
+             | C { x  :: a 
+                 , xs :: L {v:a| x <= v} } @-}
+\end{code}
+</div>
+<br>
+
+<div class="fragment">
+Head `x` is less than **every** element of tail `xs`
+</div>
+
+<br>
+
+<div class="fragment">
+i.e. specifies **increasing** Lists 
+</div>
+
+Increasing Lists 
+----------------
+
+\begin{code} <br>
+data L a where
+  N :: L a
+  C :: x:a -> xs: L {v:a | x <= v} -> L a
+\end{code}
+
+<br>
+
+- <div class="fragment">LiquidHaskell **checks** property when **folding** `C`</div>
+- <div class="fragment">LiquidHaskell **assumes** property when **unfolding** `C`</div>
+
+Increasing Lists 
+----------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellInsertSort.hs" target= "_blank">Demo: Insertion Sort</a> (hover for inferred types) 
+
+<br>
+
+\begin{code}
+insertSort = foldr insert N
+
+insert y (x `C` xs) 
+  | y <= x    = y `C` (x `C` xs)
+  | otherwise = x `C` insert y xs
+insert y N    = y `C` N    
+\end{code}
+
+<br>
+
+<div class="fragment">**Problem 1:** What if we need *both* [increasing and decreasing lists](http://web.cecs.pdx.edu/~sheard/Code/QSort.html)?</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. **Measures:** Strengthened Constructors
+    - <div class="fragment">**Decouple** property from structure</div>
+    - <div class="fragment">**Reuse** structure across *different* properties</div>
+
+<br>
+
+<div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target="_blank">[continue]</a></div>
diff --git a/docs/slides/flops14/lhs/03_HigherOrderFunctions.lhs b/docs/slides/flops14/lhs/03_HigherOrderFunctions.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/03_HigherOrderFunctions.lhs
@@ -0,0 +1,215 @@
+  {#hofs}
+=========
+
+<div class="hidden">
+\begin{code}
+module Loop (
+    listSum
+  , sumNats
+  ) where
+
+import Prelude
+
+{-@ LIQUID "--no-termination"@-}
+sumNats  :: [Int] -> Int
+add         :: Int -> Int -> Int
+\end{code}
+</div>
+
+Higher-Order Specifications
+---------------------------
+
+Types scale to *Higher-Order* Specifications
+
+<br>
+
+<div class="fragment">
+
++ map
++ fold
++ visitors
++ callbacks
++ ...
+
+</div>
+
+<br>
+
+<div class="fragment">Very difficult with *first-order program logics*</div>
+
+
+Higher Order Specifications
+===========================
+
+Example: Higher Order Loop
+--------------------------
+
+<br>
+
+\begin{code}
+loop :: Int -> Int -> α -> (Int -> α -> α) -> α
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+LiquidHaskell infers `f` called with values `(Btwn lo hi)`
+
+
+Example: Summing Lists
+----------------------
+
+\begin{code}
+listSum     :: [Int] -> Int
+listSum xs  = loop 0 n 0 body 
+  where 
+    body    = \i acc -> acc + (xs !! i)
+    n       = length xs
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Function Subtyping** 
+
++ `body` called with `i :: Btwn 0 (llen xs)`
+
++ Hence, indexing with `!!` is safe.
+</div>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Loop.hs" target= "_blank">Demo:</a> Tweak `loop` exit condition? 
+</div>
+
+Polymorphic Instantiation
+=========================
+
+ {#poly}
+--------
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{code}
+{-@ sumNats :: [Nat] -> Nat @-}
+sumNats xs  = foldl (+) 0 xs 
+\end{code}
+
+<br>
+
+<div class="fragment">
+\begin{code} Recall 
+foldl :: (α -> β -> α) -> α -> [β] -> α
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+How to **instantiate** `α` and `β` ?
+</div>
+
+Function Subtyping
+------------------
+
+\begin{code}<div/>
+(+) ::  x:Int -> y:Int -> {v:Int|v=x+y} 
+    <:  Nat   -> Nat   -> Nat
+\end{code}
+
+<br>
+
+<div class="fragment">
+Because,
+
+\begin{code}<div/>
+               |- Nat       <: Int  -- Contra
+  x:Nat, y:Nat |- {v = x+y} <: Nat  -- Co
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+Because,
+
+\begin{code}<div/>
+  0<=x && 0<=y && v = x+y   => 0 <= v
+\end{code}
+</div>
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{code} <div/> 
+{-@ sumNats :: [Nat] -> Nat @-}
+sumNats xs  = foldl (+) 0 xs 
+\end{code}
+
+<br>
+
+\begin{code} Where:
+foldl :: (α -> β -> α) -> α -> [β] -> α
+(+)   :: Nat -> Nat -> Nat
+\end{code}
+
+<br>
+
+<div class="fragment">
+`sumNats` verified by **instantiating** `α,β := Nat`
+</div>
+
+<br>
+
+<div class="fragment">
+`α` is **loop invariant**, instantiation is invariant **synthesis**
+</div>
+
+Instantiation And Inference
+---------------------------
+
+Polymorphic instantiation happens *everywhere*...
+
+<br>
+
+... so *automatic inference* is crucial
+
+<br>
+
+Cannot use *unification* (unlike indexed approaches)
+
+<br>
+
+LiquidHaskell uses [SMT and Abstract Interpretation.](http://goto.ucsd.edu/~rjhala/papers/liquid_types.html)
+
+
+Iteration Dependence
+--------------------
+
+**Problem:** Cannot use parametric polymorphism to verify
+
+<br>
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+As property only holds after **last iteration** ...
+
+... cannot instantiate `α := {v:Int | v = n + m}`
+</div>
+
+<br>
+
+<div class="fragment">
+**Problem:** Need *iteration-dependent* invariants...&nbsp; &nbsp; [[Continue]](04_AbstractRefinements.lhs.slides.html)
+</div>
+
diff --git a/docs/slides/flops14/lhs/04_AbstractRefinements.lhs b/docs/slides/flops14/lhs/04_AbstractRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/04_AbstractRefinements.lhs
@@ -0,0 +1,330 @@
+  {#abstractrefinements}
+========================
+
+<div class="hidden">
+
+\begin{code}
+module AbstractRefinements where
+
+import Prelude 
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+o, no        :: Int
+maxInt       :: Int -> Int -> Int
+\end{code}
+</div>
+
+
+
+Abstract Refinements
+--------------------
+
+
+
+Abstract Refinements
+====================
+
+Two Problems
+------------
+
+<br>
+<br>
+
+<div class="fragment">
+
+**Problem 1:** 
+
+How do we specify *both* increasing and decreasing lists?
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Problem 2:** 
+
+How do we specify *iteration-dependence* in higher-order functions?
+
+</div>
+
+
+Problem Is Pervasive
+--------------------
+
+Lets distill it to a simple example...
+
+<div class="fragment">
+
+<br>
+
+(First, a few aliases)
+
+<br>
+
+\begin{code}
+{-@ type Odd  = {v:Int | (v mod 2) = 1} @-}
+{-@ type Even = {v:Int | (v mod 2) = 0} @-}
+\end{code}
+
+</div>
+
+
+Example: `maxInt` 
+-----------------
+
+Compute the larger of two `Int`s:
+
+\begin{code} <br> 
+maxInt     :: Int -> Int -> Int 
+maxInt x y = if y <= x then x else y
+\end{code}
+
+
+
+Example: `maxInt` 
+-----------------
+
+Has **many incomparable** refinement types
+
+\begin{code}<br>
+maxInt :: Nat  -> Nat  -> Nat
+maxInt :: Even -> Even -> Even
+maxInt :: Odd  -> Odd  -> Odd 
+\end{code}
+
+<br>
+
+<div class="fragment">Oh no! **Which** one should we use?</div>
+
+
+Refinement Polymorphism 
+-----------------------
+
+`maxInt` returns *one of* its two inputs `x` and `y` 
+
+<div class="fragment">
+
+<div align="center">
+
+<br>
+
+---------   ---   -------------------------------------------
+   **If**    :    the *inputs* satisfy a property  
+
+ **Then**    :    the *output* satisfies that property
+---------   ---   -------------------------------------------
+
+<br>
+
+</div>
+</div>
+
+<div class="fragment">Above holds *for all properties*!</div>
+
+<br>
+
+<div class="fragment"> 
+
+**Need to abstract properties over types**
+
+</div>
+
+<!--
+
+By Type Polymorphism?
+---------------------
+
+\begin{code} <br> 
+max     :: α -> α -> α 
+max x y = if y <= x then x else y
+\end{code}
+
+<div class="fragment"> 
+
+Instantiate `α` at callsites
+
+\begin{code}
+{-@ o :: Odd  @-}
+o = maxInt 3 7     -- α := Odd
+
+{-@ e :: Even @-}
+e = maxInt 2 8     -- α := Even
+\end{code}
+
+</div>
+
+By Type Polymorphism?
+---------------------
+
+\begin{code} <br> 
+max     :: α -> α -> α 
+max x y = if y <= x then x else y
+\end{code}
+
+<br>
+
+But there is a fly in the ointment ...
+
+Polymorphic `max` in Haskell
+----------------------------
+
+\begin{code} In Haskell the type of max is
+max :: (Ord α) => α -> α -> α
+\end{code}
+
+<br>
+
+\begin{code} Could *ignore* the class constraints, instantiate as before...
+{-@ o :: Odd @-}
+o     = max 3 7  -- α := Odd 
+\end{code}
+
+
+Polymorphic `(+)` in Haskell
+----------------------------
+
+\begin{code} ... but this is *unsound*!
+max :: (Ord α) => α -> α -> α
+(+) :: (Num α) => α -> α -> α
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+*Ignoring* class constraints would let us "prove":
+
+\begin{code}
+{-@ no :: Odd @-}
+no     = 3 + 7    -- α := Odd !
+\end{code}
+
+</div>
+
+Type Polymorphism? No.
+----------------------
+
+<div class="fragment">Need to try a bit harder...</div>
+
+-->
+
+Parametric Refinements 
+----------------------
+
+Enable *quantification over refinements* ...
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">Type says: **for any** `p` that is a property of `Int`, </div>
+
+- <div class="fragment">`max` **takes** two `Int`s that satisfy `p`,</div>
+
+- <div class="fragment">`max` **returns** an `Int` that satisfies `p`.</div>
+
+Parametric Refinements 
+----------------------
+
+Enable *quantification over refinements* ...
+
+<br>
+
+\begin{code}<div/>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+[Key idea: ](http://goto.ucsd.edu/~rjhala/papers/abstract_refinement_types.html) &nbsp; `Int<p>`  &nbsp; is just  &nbsp; `{v:Int | (p v)}`
+
+<br>
+
+i.e., Abstract Refinement is an **uninterpreted function** in SMT logic
+
+Parametric Refinements 
+----------------------
+
+\begin{code}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+**Check** and **Instantiate** 
+
+Using [SMT and Abstract Interpretation.](http://goto.ucsd.edu/~rjhala/papers/liquid_types.html)
+
+
+Using Abstract Refinements
+--------------------------
+
+- <div class="fragment">**When** we call `maxInt` with args with some refinement,</div>
+
+- <div class="fragment">**Then** `p` instantiated with *same* refinement,</div>
+
+- <div class="fragment">**Result** of call will also have *same* concrete refinement.</div>
+
+<div class="fragment">
+
+\begin{code}
+{-@ o' :: Odd  @-}
+o' = maxInt 3 7     -- p := \v -> Odd v 
+
+{-@ e' :: Even @-}
+e' = maxInt 2 8     -- p := \v -> Even v 
+\end{code}
+
+</div>
+
+Using Abstract Refinements
+--------------------------
+
+Or any other property ...
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type RGB = {v:_ | (0 <= v && v < 256)} @-}
+
+{-@ rgb :: RGB @-}
+rgb = maxInt 56 8   -- p := \v -> 0 <= v < 256
+\end{code}
+
+</div>
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. **Abstract Refinements** over Types
+
+<br>
+<br>
+
+<div class="fragment">
+  Abstract Refinements are *very* expressive ... <a href="06_Inductive.lhs.slides.html" target="_blank">[continue]</a>
+</div>
+
diff --git a/docs/slides/flops14/lhs/05_Composition.lhs b/docs/slides/flops14/lhs/05_Composition.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/05_Composition.lhs
@@ -0,0 +1,161 @@
+Abstract Refinements {#composition}
+===================================
+
+Very General Mechanism 
+----------------------
+
+**Next:** Lets add parameters...
+
+<div class="hidden">
+\begin{code}
+module Composition where
+
+import Prelude hiding ((.))
+
+plus     :: Int -> Int -> Int
+plus3'   :: Int -> Int
+\end{code}
+</div>
+
+
+Example: `plus`
+---------------
+
+\begin{code}
+{-@ plus :: x:_ -> y:_ -> {v:_ | v=x+y} @-}
+plus x y = x + y
+\end{code}
+
+
+Example: `plus 3` 
+-----------------
+
+<br>
+
+\begin{code}
+{-@ plus3' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3'     = plus 3
+\end{code}
+
+<br>
+
+Easily verified by LiquidHaskell
+
+A Composed Variant
+------------------
+
+Lets define `plus3` by *composition*
+
+A Composition Operator 
+----------------------
+
+\begin{code}
+(#) :: (b -> c) -> (a -> b) -> a -> c
+(#) f g x = f (g x)
+\end{code}
+
+
+`plus3` By Composition
+-----------------------
+
+\begin{code}
+{-@ plus3'' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3''     = plus 1 # plus 2
+\end{code}
+
+<br>
+
+Yikes! Verification *fails*. But why?
+
+<br>
+
+<div class="fragment">(Hover mouse over `#` for a clue)</div>
+
+How to type compose (#) ? 
+-------------------------
+
+This specification is *too weak* <br>
+
+\begin{code} <br>
+(#) :: (b -> c) -> (a -> b) -> (a -> c)
+\end{code}
+
+<br>
+
+Output type does not *relate* `c` with `a`!
+
+How to type compose (.) ?
+-------------------------
+
+Write specification with abstract refinement type:
+
+<br>
+
+\begin{code}
+{-@ (.) :: forall <p :: b->c->Prop, 
+                   q :: a->b->Prop>.
+             f:(x:b -> c<p x>) 
+          -> g:(x:a -> b<q x>) 
+          -> y:a -> exists[z:b<q y>].c<p z>
+ @-}
+(.) f g y = f (g y)
+\end{code}
+
+Using (.) Operator 
+------------------
+
+<br>
+
+\begin{code}
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br>
+
+<div class="fragment">*Verifies!*</div>
+
+
+Using (.) Operator 
+------------------
+
+\begin{code} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br>
+
+LiquidHaskell *instantiates*
+
+- `p` with `\x -> v = x + 1`
+- `q` with `\x -> v = x + 2`
+
+Using (.) Operator 
+------------------
+
+\begin{code} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br> To *infer* that output of `plus3` has type: 
+
+`exists [z:{v = y + 2}].{v = z + 1}`
+
+<div class="fragment">
+
+`<:`
+
+`{v:Int|v=3}`
+</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract:** Refinements over Type Signatures
+    + <div class="fragment">*Dependencies* using refinement parameters</div>
diff --git a/docs/slides/flops14/lhs/06_Inductive.lhs b/docs/slides/flops14/lhs/06_Inductive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/06_Inductive.lhs
@@ -0,0 +1,457 @@
+Abstract Refinements {#induction}
+=================================
+
+Induction
+---------
+
+Encoding *induction* with Abstract refinements
+
+<div class="hidden">
+
+\begin{code}
+module Loop where
+import Prelude hiding ((!!), foldr, length, (++))
+-- import Measures
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+
+size  :: L a -> Int
+add   :: Int -> Int -> Int
+loop  :: Int -> Int -> α -> (Int -> α -> α) -> α
+foldr :: (L a -> a -> b -> b) -> b -> L a -> b
+\end{code}
+</div>
+
+Induction
+=========
+
+Example: `loop` redux 
+---------------------
+
+Recall the *higher-order* `loop` 
+
+<br>
+
+\begin{code}
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+**Problem**
+
+- As property only holds after *last* loop iteration...
+
+- ... cannot instantiate `α` with `{v:Int | v = n + m}`
+
+</div>
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+**Problem** 
+
+Need invariant relating *iteration* `i` with *accumulator* `acc`
+
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+**Solution** 
+
+- Abstract Refinement `p :: Int -> a -> Prop`
+
+- `(p i acc)` relates *iteration* `i` with *accumulator* `acc`
+
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+<div class="fragment">
+<div align="center">
+
+------------  ---   ----------------------------
+  **Assume**   :    `out = loop lo hi base f` 
+
+   **Prove**   :    `(p hi out)`
+------------  ---   ----------------------------
+
+</div>
+</div>
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**Base Case:** &nbsp; Initial accumulator `base` satisfies invariant
+
+
+`(p lo base)`   
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**Inductive Step:** &nbsp; `f` *preserves* invariant at `i`
+
+
+`(p i acc) => (p (i+1) (f i acc))`
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**"By Induction"** &nbsp; `out` satisfies invariant at `hi` 
+
+`(p hi out)`
+
+
+Induction in `loop` (by type)
+-----------------------------
+
+Induction is an **abstract refinement type** for `loop` 
+
+<br>
+
+\begin{code}
+{-@ loop :: forall a <p :: Int -> a -> Prop>.
+        lo:Int
+     -> hi:{Int | lo <= hi}
+     -> base:a<p lo>                      
+     -> f:(i:Int -> a<p i> -> a<p (i+1)>) 
+     -> a<p hi>                           @-}
+\end{code}
+
+<br>
+
+Induction in `loop` (by type)
+-----------------------------
+
+`p` is the *index dependent* invariant!
+
+
+\begin{code}<br> 
+p    :: Int -> a -> Prop             -- invt 
+base :: a<p lo>                      -- base 
+f    :: i:Int -> a<p i> -> a<p(i+1)> -- step
+out  :: a<p hi>                      -- goal
+\end{code}
+
+
+
+Using Induction
+---------------
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br>
+
+**Verified** by *instantiating* the abstract refinement of `loop`
+
+`p := \i acc -> acc = i + n`
+
+
+<!--
+
+Using Induction
+---------------
+
+\begin{code} <div/>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br>
+
+Verified by instantiating `p := \i acc -> acc = i + n`
+
+- <div class="fragment">**Base:**  `n = 0 + n`</div>
+
+- <div class="fragment">**Step:**  `acc = i + n  =>  acc + 1 = (i + 1) + n`</div>
+
+- <div class="fragment">**Goal:**  `out = m + n`</div>
+
+-->
+
+Generalizes To Structures 
+-------------------------
+
+Same idea applies for induction over *structures* ...
+
+
+Structural Induction
+====================
+
+Example: Lists
+--------------
+
+<br>
+
+\begin{code}
+data L a = N 
+         | C a (L a)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets write a generic loop over such lists ...
+</div>
+
+Example: `foldr`
+----------------
+
+\begin{code} <br>
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets brace ourselves for the type...
+</div>
+
+Example: `foldr`
+----------------
+
+\begin{code}
+{-@ foldr :: 
+    forall a b <p :: L a -> b -> Prop>. 
+      (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
+    -> b<p N> 
+    -> ys:L a
+    -> b<p ys>                            @-}
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets step through the type...
+</div>
+
+
+`foldr`: Abstract Refinement
+----------------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  ::  b<p ys>                            
+\end{code}
+
+<br>
+
+`(p xs b)` relates `b` with **folded** `xs`
+
+`p :: L a -> b -> Prop`
+
+
+`foldr`: Base Case
+------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+`base` is related to **empty** list `N`
+
+`base :: b<p N>` 
+
+
+
+`foldr`: Ind. Step 
+------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+`step` **extends** relation from `xs` to `C x xs`
+
+`step :: xs:_ -> x:_ -> b<p xs> -> b<p (C x xs)>`
+
+
+`foldr`: Output
+---------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+Hence, relation holds between `out` and **entire input** list `ys`
+
+`out :: b<p ys>`
+
+Using `foldr`: Size
+-------------------
+
+We can now verify <br>
+
+\begin{code}
+{-@ size :: xs:_ -> {v:Int| v = (llen xs)} @-}
+size     = foldr (\_ _ n -> n + 1) 0
+\end{code}
+
+<br>
+
+<div class="fragment">
+by *automatically instantiating*
+
+`p := \xs acc -> acc = (llen xs)`
+</div>
+
+Using `foldr`: Append
+---------------------
+
+We can now verify <br>
+
+\begin{code}
+{-@ (++) :: xs:_ -> ys:_ -> (Cat a xs ys) @-} 
+xs ++ ys = foldr (\_ -> C) ys xs 
+\end{code}
+
+<div class="fragment">
+where 
+
+\begin{code}
+{-@ type Cat a X Y = 
+    {v:_|(llen v) = (llen X) + (llen Y)} @-}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+By automatically instantiating 
+
+`p := \xs acc -> llen acc = llen xs + llen ys`
+
+</div>
+
+Recap
+-----
+
+Abstract refinements *decouple* **invariant** from **traversal**
+
+<br>
+
+<div class="fragment">**Reusable** specifications for higher-order functions.</div>
+
+<br>
+
+<div class="fragment">**Automatic** checking and instantiation by SMT.</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over Type Signatures
+    + <div class="fragment">**Functions**</div>
+    + <div class="fragment">**Data** <a href="08_Recursive.lhs.slides.html" target="_blank">[continue]</a></div>
+
diff --git a/docs/slides/flops14/lhs/07_Array.lhs b/docs/slides/flops14/lhs/07_Array.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/07_Array.lhs
@@ -0,0 +1,405 @@
+Abstract Refinements {#data}
+============================
+
+Recap
+-----
+
+**So far**
+
+Decouple invariants from *functions*
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+Decouple invariants from *data structures*
+</div>
+
+Decouple Invariants From Data {#vector} 
+=======================================
+
+Example: Vectors 
+----------------
+
+<div class="hidden">
+\begin{code}
+module LiquidArray where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume, liquidError)
+
+{-@ LIQUID "--no-termination" @-}
+
+fibMemo   :: Vec Int -> Int -> (Vec Int, Int)
+fastFib   :: Int -> Int
+idv       :: Int -> Vec Int
+axiom_fib :: Int -> Bool
+axiom_fib = undefined
+
+{-@ predicate AxFib I = (fib I) == (if I <= 1 then 1 else fib(I-1) + fib(I-2)) @-}
+\end{code}
+</div>
+
+<div class="fragment">
+
+Implemented as maps from `Int` to `a` 
+
+<br>
+
+\begin{code}
+data Vec a = V (Int -> a)
+\end{code}
+
+</div>
+
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Parameterize type with *two* abstract refinements:
+
+<br>
+
+\begin{code}
+{-@ data Vec a < dom :: Int -> Prop,
+                 rng :: Int -> a -> Prop >
+      = V {a :: i:Int<dom> -> a <rng i>}  @-}
+\end{code}
+
+<br>
+
+- `dom`: *domain* on which `Vec` is *defined* 
+
+- `rng`: *range*  and relationship with *index*
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Diverse `Vec`tors by *instantiating* `dom` and `rng`
+
+<br>
+
+<div class="fragment">
+
+A quick alias for *segments* between `I` and `J`
+
+<br>
+
+\begin{code}
+{-@ predicate Seg V I J = (I <= V && V < J) @-}
+\end{code}
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type IdVec N = Vec <{\v -> (Seg v 0 N)}, 
+                        {\k v -> v=k}> 
+                       Int                  @-}
+\end{code}
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+\begin{code}
+{-@ idv :: n:Nat -> (IdVec n) @-}
+idv n   = V (\k -> if 0 < k && k < n 
+                     then k 
+                     else liquidError "eeks")
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>Whats the problem? How can we fix it?
+</div>
+
+Ex: Zero-Terminated Vectors
+---------------------------
+
+Defined between `[0..N)`, with *last* element equal to `0`:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type ZeroTerm N = 
+     Vec <{\v -> (Seg v 0 N)}, 
+          {\k v -> (k = N-1 => v = 0)}> 
+          Int                             @-}
+\end{code}
+
+</div>
+
+
+Ex: Fibonacci Table 
+-------------------
+
+A vector whose value at index `k` is either 
+
+- `0` (undefined), or, 
+
+- `k`th fibonacci number 
+
+\begin{code}
+{-@ type FibV =  
+     Vec <{\v -> true}, 
+          {\k v -> (v = 0 || v = (fib k))}> 
+          Int                               @-}
+\end{code}
+
+
+Accessing Vectors
+-----------------
+
+Next: lets *abstractly* type `Vec`tor operations, *e.g.* 
+
+<br>
+
+- `empty`
+
+- `set`
+
+- `get`
+
+
+Ex: Empty Vectors
+-----------------
+
+`empty` returns Vector whose domain is `false`
+
+<br>
+
+\begin{code}
+{-@ empty :: forall <p :: Int -> a -> Prop>. 
+               Vec <{v:Int|false}, p> a     @-}
+
+empty     = V $ \_ -> error "empty vector!"
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+What would happen if we changed `false` to `true`?
+</div>
+
+Ex: `get` Key's Value 
+---------------------
+
+- *Input* `key` in *domain*
+
+- *Output* value in *range* related with `k`
+
+\begin{code}
+{-@ get :: forall a <d :: Int -> Prop,  
+                     r :: Int -> a -> Prop>.
+           key:Int <d>
+        -> vec:Vec <d, r> a
+        -> a<r key>                        @-}
+
+get k (V f) = f k
+\end{code}
+
+
+Ex: `set` Key's Value 
+---------------------
+
+- <div class="fragment">Input `key` in *domain*</div>
+
+- <div class="fragment">Input `val` in *range* related with `key`</div>
+
+- <div class="fragment">Input `vec` defined at *domain except at* `key`</div>
+
+- <div class="fragment">Output domain *includes* `key`</div>
+
+Ex: `set` Key's Value 
+---------------------
+
+\begin{code}
+{-@ set :: forall a <d :: Int -> Prop,
+                     r :: Int -> a -> Prop>.
+           key: Int<d> -> val: a<r key>
+        -> vec: Vec<{v:Int<d>| v /= key},r> a
+        -> Vec <d, r> a                     @-}
+set key val (V f) = V $ \k -> if k == key 
+                                then val 
+                                else f key
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+Help! Can you spot and fix the errors? 
+</div>
+
+<!-- INSERT tests/pos/vecloop.lhs here AFTER FIXED -->
+
+Using the Vector API
+--------------------
+
+Memoized Fibonacci
+------------------
+
+Use `Vec` API to write a *memoized* fibonacci function
+
+<br>
+
+<div class="fragment">
+\begin{code} Using the fibonacci table:
+type FibV =  
+     Vec <{\v -> true}, 
+          {\k v -> (v = 0 || v = (fib k))}> 
+          Int                              
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+But wait, what is `fib` ?
+</div>
+
+
+Specifying Fibonacci
+--------------------
+
+`fib` is *uninterpreted* in the refinement logic  
+
+<br>
+
+\begin{code}
+{-@ measure fib :: Int -> Int @-}
+\end{code}
+
+<br>
+
+Specifying Fibonacci
+--------------------
+
+We *axiomatize* the definition of `fib` in SMT ...
+
+\begin{code}<br>
+predicate AxFib I = 
+  (fib I) == if I <= 1 
+               then 1 
+               else fib(I-1) + fib(I-2)
+\end{code}
+
+Specifying Fibonacci
+--------------------
+
+Finally, lift axiom into LiquidHaskell as *ghost function*
+
+<br>
+
+\begin{code}
+{-@ axiom_fib :: 
+      i:_ -> {v:_|((Prop v) <=> (AxFib i))} @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Note:** Recipe for *escaping* SMT limitations
+
+1. *Prove* fact externally
+2. *Use* as ghost function call
+</div>
+
+
+Fast Fibonacci
+--------------
+
+An efficient fibonacci function
+
+<br>
+
+\begin{code}
+{-@ fastFib :: n:Int -> {v:_ | v = (fib n)} @-}
+fastFib n   = snd $ fibMemo (V (\_ -> 0)) n
+\end{code}
+
+<br>
+
+<div class="fragment">
+- `fibMemo` *takes* a table initialized with `0`
+
+- `fibMemo` *returns* a table with `fib` values upto `n`.
+</div>
+
+
+Memoized Fibonacci 
+------------------
+
+\begin{code}
+fibMemo t i 
+  | i <= 1    
+  = (t, liquidAssume (axiom_fib i) 1)
+  | otherwise 
+  = case get i t of   
+     0 -> let (t1,n1) = fibMemo t  (i-1)
+              (t2,n2) = fibMemo t1 (i-2)
+              n       = liquidAssume 
+                        (axiom_fib i) (n1+n2)
+          in (set i n t2,  n)
+     n -> (t, n)
+\end{code}
+
+Memoized Fibonacci 
+------------------
+
+- `fibMemo` *takes* a table initialized with `0`
+- `fibMemo` *returns* a table with `fib` values upto `n`.
+
+<br>
+
+\begin{code}
+{-@ fibMemo :: FibV 
+            -> i:Int 
+            -> (FibV,{v:Int | v = (fib i)}) @-}
+\end{code}
+
+
+Recap
+-----
+
+Created a `Vec` container 
+
+Decoupled *domain* and *range* invariants from *data*
+
+<br>
+
+<div class="fragment">
+
+Previous, special purpose program analyses 
+
+- [Gopan-Reps-Sagiv, POPL 05](link)
+- [J.-McMillan, CAV 07](link)
+- [Logozzo-Cousot-Cousot, POPL 11](link)
+- [Dillig-Dillig, POPL 12](link) 
+- ...
+
+Encoded as instance of abstract refinement types!
+</div>
+
+
+
+
diff --git a/docs/slides/flops14/lhs/08_Recursive.lhs b/docs/slides/flops14/lhs/08_Recursive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/08_Recursive.lhs
@@ -0,0 +1,544 @@
+Decouple Invariants From Data {#recursive} 
+==========================================
+
+ {#asd}
+-------
+
+Recursive Structures 
+--------------------
+
+Lets see another example of decoupling...
+
+<div class="hidden">
+\begin{code}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+
+module List (insertSort) where
+
+{-@ LIQUID "--no-termination" @-}
+
+mergeSort     :: Ord a => [a] -> [a]
+insertSort :: (Ord a) => [a] -> L a 
+slist :: L Int
+slist' :: L Int
+iGoUp, iGoDn, iDiff :: [Int]
+infixr `C`
+\end{code}
+</div>
+
+Decouple Invariants From Recursive Data
+=======================================
+
+Recall: Lists
+-------------
+
+\begin{code}
+data L a = N 
+         | C { hd :: a, tl :: L a }
+\end{code}
+
+
+Recall: Refined Constructors 
+----------------------------
+
+Define **increasing** Lists with strengthened constructors:
+
+\begin{code} <br>
+data L a where
+  N :: L a
+  C :: hd:a -> tl: L {v:a | hd <= v} -> L a
+\end{code}
+
+Problem: Decreasing Lists?
+--------------------------
+
+What if we need *both* [increasing *and* decreasing lists?](http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Data-List.html#sort)
+
+<br>
+
+<div class="fragment">
+[Separate (indexed) types](http://web.cecs.pdx.edu/~sheard/Code/QSort.html) get quite complicated ...
+</div>
+
+Abstract That Refinement!
+-------------------------
+
+\begin{code}
+{-@ data L a <p :: a -> a -> Prop>
+      = N 
+      | C { hd :: a, tl :: L <p> a<p hd> } @-}
+\end{code}
+
+<br>
+
+<div class="fragment"> `p` is a **binary relation** between two `a` values</div>
+
+<br>
+
+<div class="fragment"> Definition relates `hd` with **all** the elements of `tl`</div>
+
+<br>
+
+<div class="fragment"> Recursive: `p` holds for **every pair** of elements!</div>
+
+Example
+-------
+
+Consider a list with *three* or more elements 
+
+\begin{code} <br>
+x1 `C` x2 `C` x3 `C` rest :: L <p> a 
+\end{code}
+
+Example: Unfold Once
+--------------------
+
+\begin{code} <br> 
+x1                 :: a
+x2 `C` x3 `C` rest :: L <p> a<p x1> 
+\end{code}
+
+Example: Unfold Twice
+---------------------
+
+\begin{code} <br> 
+x1          :: a
+x2          :: a<p x1>  
+x3 `C` rest :: L <p> a<p x1 && p x2> 
+\end{code}
+
+Example: Unfold Thrice
+----------------------
+
+\begin{code} <br> 
+x1   :: a
+x2   :: a<p x1>  
+x3   :: a<p x1 && p x2>  
+rest :: L <p> a<p x1 && p x2 && p x3> 
+\end{code}
+
+<br>
+
+<div class="fragment">
+Note how `p` holds between **every pair** of elements in the list. 
+</div>
+
+A Concrete Example
+------------------
+
+That was a rather *abstract*!
+
+<br>
+
+How can we *use* fact that `p` holds between *every pair*?
+
+<br>
+
+<div class="fragment">**Instantiate** `p` with a *concrete* refinement</div>
+
+
+Example: Increasing Lists
+-------------------------
+
+**Instantiate** `p` with a *concrete* refinement
+
+<br>
+
+\begin{code}
+{-@ type IncL a = L <{\hd v -> hd <= v}> a @-}
+\end{code}
+
+<br>
+
+<div class="fragment"> Refinement says: &nbsp; `hd` less than **every** `v` in tail,</div>
+
+<br>
+
+<div class="fragment"> i.e., `IncL` denotes **increasing** lists. </div>
+
+Example: Increasing Lists
+-------------------------
+
+LiquidHaskell *verifies* that `slist` is indeed increasing...
+
+\begin{code}
+{-@ slist :: IncL Int @-}
+slist     = 1 `C` 6 `C` 12 `C` N
+\end{code}
+
+<br> 
+
+<div class="fragment">
+
+... and *protests* that `slist'` is not: 
+
+\begin{code}
+{-@ slist' :: IncL Int @-}
+slist' = 6 `C` 1 `C` 12 `C` N
+\end{code}
+</div>
+
+Insertion Sort
+--------------
+
+\begin{code}
+{-@ insertSort :: (Ord a) => [a] -> IncL a @-}
+insertSort     = foldr insert N
+
+insert y N          = y `C` N
+insert y (x `C` xs) 
+  | y < x           = y `C` (x `C` xs)
+  | otherwise       = x `C` insert y xs
+\end{code}
+
+<br>
+
+(Mouseover `insert` to see inferred type.)
+
+Checking GHC Lists
+------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target= "_blank">Demo:</a> 
+Above applies to GHC's List definition:
+
+\begin{code} <br> 
+data [a] <p :: a -> a -> Prop>
+  = [] 
+  | (:) { h :: a, tl :: [a<p h>]<p> }
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Increasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Incs a = [a]<{\h v -> h <= v}> @-}
+
+{-@ iGoUp :: Incs Int @-}
+iGoUp     = [1,2,3]
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Decreasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Decs a = [a]<{\h v -> h >= v}> @-}
+
+{-@ iGoDn :: Decs Int @-}
+iGoDn     = [3,2,1]
+\end{code}
+
+
+Checking GHC Lists
+------------------
+
+Duplicate-free Lists
+
+<br>
+
+\begin{code}
+{-@ type Difs a = [a]<{\h v -> h /= v}> @-}
+
+{-@ iDiff :: Difs Int @-}
+iDiff     = [1,3,2]
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Now we can check all the usual list sorting algorithms 
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target="_blank">Demo:</a> List Sorting
+
+<!-- 
+
+Example: `mergeSort` [1/2]
+--------------------------
+
+\begin{code}
+{-@ mergeSort  :: (Ord a) => [a] -> Incs a @-}
+mergeSort []   = []
+mergeSort [x]  = [x]
+mergeSort xs   = merge xs1' xs2' 
+  where 
+   (xs1, xs2)  = split xs
+   xs1'        = mergeSort xs1
+   xs2'        = mergeSort xs2
+\end{code}
+
+Example: `mergeSort` [2/2]
+--------------------------
+
+\begin{code}
+split (x:y:zs) = (x:xs, y:ys) 
+  where 
+    (xs, ys)   = split zs
+split xs       = (xs, [])
+
+merge xs []    = xs
+merge [] ys    = ys
+merge (x:xs) (y:ys) 
+  | x <= y     = x : merge xs (y:ys)
+  | otherwise  = y : merge (x:xs) ys
+\end{code}
+
+
+
+Example: `Data.List.sort` 
+-------------------------
+
+<br>
+
+GHC's "official" list sorting routine
+
+<br>
+
+Juggling lists of increasing & decreasing lists
+
+
+
+
+Ex: `Data.List.sort` [1/5]
+--------------------------
+
+**Step 1.** Make sequences of increasing & decreasing lists
+
+<br>
+
+\begin{code}
+sequences (a:b:xs)
+  | a `compare` b == GT = descending b [a]  xs
+  | otherwise           = ascending  b (a:) xs
+sequences [x]           = [[x]]
+sequences []            = [[]]
+\end{code}
+
+Ex: `Data.List.sort` [2/5]
+--------------------------
+
+**Step 1.** Make sequences of increasing & decreasing lists
+
+<br>
+
+\begin{code}
+descending a as (b:bs)
+  | a `compare` b == GT 
+  = descending b (a:as) bs
+descending a as bs      
+  = (a:as): sequences bs
+\end{code}
+
+Ex: `Data.List.sort` [3/5]
+--------------------------
+
+**Step 1.** Make sequences of increasing & decreasing lists
+
+<br>
+
+
+\begin{code}
+ascending a as (b:bs)
+  | a `compare` b /= GT 
+  = ascending b (\ys -> as (a:ys)) bs
+ascending a as bs      
+  = as [a]: sequences bs
+\end{code}
+
+Ex: `Data.List.sort` [4/5]
+--------------------------
+
+**Step 2.** Merge sequences
+
+<br>
+
+\begin{code}
+mergeAll [x]        = x
+mergeAll xs         = mergeAll (mergePairs xs)
+
+mergePairs (a:b:xs) = merge a b: mergePairs xs
+mergePairs [x]      = [x]
+mergePairs []       = []
+\end{code}
+
+
+Ex: `Data.List.sort` [5/5]
+--------------------------
+
+Put it all together
+
+<br>
+
+\begin{code}
+{-@ sort :: (Ord a) => [a] -> Incs a  @-}
+sort = mergeAll . sequences
+\end{code}
+
+<br>
+
+<div class="fragment">No other hints or annotations required.</div>
+
+-->
+
+Phew!
+-----
+
+Lets see one last example...
+
+<br>
+<br>
+<br>
+<br>
+
+[[Skip]](#/1/32)
+
+
+Example: Binary Trees
+---------------------
+
+... `Map` from keys of type `k` to values of type `a` 
+
+<br>
+
+<div class="fragment">
+
+Implemented, in `Data.Map` as a binary tree:
+
+<br>
+
+\begin{code}
+data Map k a = Tip
+             | Bin Size k a (Map k a) (Map k a)
+
+type Size    = Int
+\end{code}
+</div>
+
+Two Abstract Refinements
+------------------------
+
+- `l` : relates root `key` with `left`-subtree keys
+- `r` : relates root `key` with `right`-subtree keys
+
+\begin{code}
+{-@ data Map k a < l :: k -> k -> Prop
+                 , r :: k -> k -> Prop >
+    = Tip
+    | Bin (sz :: Size) (key :: k) (val :: a)
+          (left  :: Map <l,r> (k<l key>) a)
+          (right :: Map <l,r> (k<r key>) a) @-}
+\end{code}
+
+
+Ex: Binary Search Trees
+-----------------------
+
+Keys are *Binary-Search* Ordered
+
+<br>
+
+\begin{code}
+{-@ type BST k a = 
+      Map <{\r v -> v < r }, 
+           {\r v -> v > r }> 
+          k a                   @-}
+\end{code}
+
+Ex: Minimum Heaps 
+-----------------
+
+Root contains *minimum* value
+
+<br>
+
+\begin{code}
+{-@ type MinHeap k a = 
+      Map <{\r v -> r <= v}, 
+           {\r v -> r <= v}> 
+           k a               @-}
+\end{code}
+
+Ex: Maximum Heaps 
+-----------------
+
+Root contains *maximum* value
+
+<br>
+
+\begin{code}
+{-@ type MaxHeap k a = 
+      Map <{\r v -> r >= v}, 
+           {\r v -> r >= v}> 
+           k a               @-}
+\end{code}
+
+
+Example: Data.Map
+-----------------
+
+Standard Key-Value container
+
+<br>
+
+- <div class="fragment">1300+ non-comment lines</div>
+
+- <div class="fragment">`insert`, `split`, `merge`,...</div>
+
+- <div class="fragment">Rotation, Rebalance,...</div>
+
+<br>
+
+<div class="fragment">
+SMT & inference crucial for [verification](https://github.com/ucsd-progsys/liquidhaskell/blob/master/benchmarks/esop2013-submission/Base.hs)
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Map.hs" target="_blank">Demo:</a> Binary Search Maps
+</div>
+
+Recap: Abstract Refinements
+---------------------------
+
+<div class="fragment">
+
+Decouple invariants from **functions**
+
++ `max`
++ `loop`
++ `foldr`
+
+</div>
+
+<div class="fragment">
+Decouple invariants from **data**
+
++ `Vector`
++ `List`
++ `Tree`
+
+</div>
+
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. **Abstract:** Refinements over functions and data
+5. <div class="fragment">Er, what about Haskell's **lazy evaluation**?</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](09_Laziness.lhs.slides.html)</div>
diff --git a/docs/slides/flops14/lhs/09_Laziness.lhs b/docs/slides/flops14/lhs/09_Laziness.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/09_Laziness.lhs
@@ -0,0 +1,272 @@
+ {#laziness}
+============
+
+<div class="hidden">
+\begin{code}
+module Laziness where
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short"          @-}
+
+
+safeDiv :: Int -> Int -> Int
+foo     :: Int -> Int
+-- zero    :: Int 
+-- diverge :: a -> b
+\end{code}
+</div>
+
+
+Lazy Evaluation?
+----------------
+
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+
+
+[[Skip]](11_Evaluation.lhs.slides.html)
+
+Lazy Evaluation
+===============
+
+SMT based Verification
+----------------------
+
+Techniques developed for **strict** languages
+
+<br>
+
+<div class="fragment">
+
+-----------------------   ---   ------------------------------------------
+        **Floyd-Hoare**    :    `ESCJava`, `SpecSharp` ...
+     **Model Checkers**    :    `Slam`, `Blast` ...
+   **Refinement Types**    :    `DML`, `Stardust`, `Sage`, `F7`, `F*`, ...
+-----------------------   ---   ------------------------------------------
+
+</div>
+
+<br>
+
+<div class="fragment">
+Surely soundness carries over to Haskell, right?
+</div>
+
+
+Back To the Beginning
+---------------------
+
+\begin{code}
+{-@ safeDiv :: Int -> {v:Int|v /= 0} -> Int @-}
+safeDiv n 0 = liquidError "div-by-zero!"
+safeDiv n d = n `div` d
+\end{code}
+
+<br>
+
+<div class="fragment">
+Should only call `safeDiv` with **non-zero** values
+</div>
+
+An Innocent Function
+--------------------
+
+`foo` returns a value **strictly less than** input.
+
+<br>
+
+\begin{code} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+\end{code}
+
+LiquidHaskell Lies! 
+-------------------
+
+\begin{code}
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0    
+              a = foo z
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+<div class="fragment">
+Why is this program **deemed safe**?! 
+</div>
+
+
+*Safe* With Eager Eval
+----------------------
+
+\begin{code} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Safe** in Java, ML: program spins away, **never hits** divide-by-zero 
+</div>
+
+*Unsafe* With Lazy Eval
+-----------------------
+
+\begin{code} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+**Unsafe** in Haskell: program skips `foo z` and **hits** divide-by-zero!
+
+Problem: Divergence
+-------------------
+
+What is denoted by:
+
+`e :: {v:Int | P}`
+
+
+<br>
+
+<div class="fragment">
+`e` evaluates to `Int` satisfying `P`  
+</div>
+
+<div class="fragment">
+or
+
+**diverges**! 
+</div>
+
+<div class="fragment">
+<br>
+
+Classical Floyd-Hoare notion of [partial correctness](http://en.wikipedia.org/wiki/Hoare_logic#Partial_and_total_correctness)
+
+</div>
+
+
+
+Problem: Divergence
+-------------------
+
+\begin{code} **Consider** <div/> 
+        {-@ e :: {v : Int | P} @-}
+
+        let x = e in body 
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Eager Evaluation** 
+
+*Can* assume `P(x)` when checking `body`
+</div>
+
+<br>
+
+<div class="fragment">
+**Lazy Evaluation** 
+
+*Cannot* assume `P(x)` when checking `body`
+</div>
+
+Eager vs. Lazy Binders 
+----------------------
+
+\begin{code} <div/>
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0     -- :: {v:Int| v = 0}
+              a = foo z -- :: {v:Nat| v < z}
+          in  
+              (\x -> 2013 `safeDiv` z) a 
+\end{code}
+
+<br>
+
+Inconsistent refinement for `a` is sound for **eager**, unsound for **lazy**
+
+
+Panic! Now what?
+---------------
+
+<div class="fragment">
+**Solution** 
+
+Assign *non-trivial* refinements to *non-diverging* terms!
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Require A Termination Analysis**
+
+Don't worry, its easy...
+
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=TellingLies.hs" target="_blank">Demo:</a> &nbsp; Disable `"--no-termination"` and see what happens!
+</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. **Lazy Evaluation:** Requires Termination
+6. <div class="fragment">**Termination:** via Refinements!</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](10_Termination.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/flops14/lhs/10_Termination.lhs b/docs/slides/flops14/lhs/10_Termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/10_Termination.lhs
@@ -0,0 +1,314 @@
+Termination {#termination}
+==========================
+
+
+<div class="hidden">
+\begin{code}
+module Termination where
+
+import Prelude hiding (gcd, mod, map)
+fib :: Int -> Int
+gcd :: Int -> Int -> Int
+infixr `C`
+
+data L a = N | C a (L a)
+
+{-@ invariant {v: (L a) | 0 <= (llen v)} @-}
+
+mod :: Int -> Int -> Int
+mod a b | a - b >  b = mod (a - b) b
+        | a - b <  b = a - b
+        | a - b == b = 0
+
+merge :: Ord a => L a -> L a -> L a
+\end{code}
+</div>
+
+<!--
+
+Dependent != Refinement
+-----------------------
+
+<div class="fragment">**Dependent Types**</div>
+
++ <div class="fragment">*Arbitrary terms* appear inside types</div> 
++ <div class="fragment">Termination ensures well-defined</div>
+
+<br>
+
+<div class="fragment">**Refinement Types**</div>
+
++ <div class="fragment">*Restricted refinements* appear in types</div>
++ <div class="fragment">Termination *not* required ...</div> 
++ <div class="fragment">... except, alas, with *lazy* evaluation!</div>
+
+-->
+
+Refinements & Termination
+-------------------------
+
+<div class="fragment">
+Fortunately, we can ensure termination **using refinements**
+</div>
+
+
+Main Idea
+---------
+
+Recursive calls must be on **smaller** inputs
+
+<br>
+
++ [Turing](http://classes.soe.ucsc.edu/cmps210/Winter11/Papers/turing-1936.pdf)
++ [Sized Types](http://dl.acm.org/citation.cfm?id=240882)
++ [DML](http://dl.acm.org/citation.cfm?id=609232)
++ [Size Change Principle](http://dl.acm.org/citation.cfm?id=360210)
+
+Recur On *Smaller* `Nat` 
+------------------------
+
+<div class="fragment">
+
+**To ensure termination of**
+
+\begin{code} <div/>
+foo   :: Nat -> T
+foo x =  body
+\end{code}
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:Nat | v < x} -> T`
+
+<br>
+
+*i.e.* require recursive calls have `Nat` inputs *smaller than* `x`
+</div>
+
+
+
+Ex: Recur On *Smaller* `Nat` 
+----------------------------
+
+\begin{code}
+{-@ fib  :: Nat -> Nat @-}
+fib 0    = 1
+fib 1    = 1
+fib n    = fib (n-1) + fib (n-2)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Terminates, as both `n-1` and `n-2` are `< n`
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=GCD.hs" target="_blank">Demo:</a> &nbsp; What if we drop the `fib 1` equation? 
+</div>
+
+Refinements Are Essential!
+--------------------------
+
+\begin{code}
+{-@ gcd :: a:Nat -> {b:Nat | b < a} -> Int @-}
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Need refinements to prove `(a mod b) < b` at *recursive* call!
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ mod :: a:Nat 
+        -> b:{v:Nat|(0 < v && v < a)} 
+        -> {v:Nat| v < b}                 @-}
+\end{code}
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{code}<div/>
+foo   :: S -> T
+foo x = body
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Reduce** to `Nat` case...
+</div>
+
+<br>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{code}<div/>
+foo   :: S -> T
+foo x = body
+\end{code}
+
+<br>
+
+Specify a **default measure** `mS :: S -> Int`
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:s | 0 <= (mS v) < (mS x)} -> T`
+</div>
+
+
+Ex: Recur on *smaller* `List`
+-----------------------------
+
+\begin{code} 
+map f N        = N
+map f (C x xs) = (f x) `C` (map f xs) 
+\end{code}
+
+<br>
+
+Terminates using **default** measure `llen` 
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ data L [llen] a = N 
+                    | C { x::a, xs :: L a} @-}
+
+{-@ measure llen :: L a -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)   @-}
+\end{code}
+</div>
+
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of smallness spread across **multiple inputs**?
+
+<br>
+
+\begin{code}
+merge xs@(x `C` xs') ys@(y `C` ys')
+  | x < y     = x `C` merge xs' ys
+  | otherwise = y `C` merge xs ys'
+\end{code}
+
+<br>
+
+<div class="fragment">
+Neither input decreases, but their **sum** does.
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+Neither input decreases, but their **sum** does.
+
+<br>
+
+\begin{code}
+{-@ merge :: Ord a => xs:_ -> ys:_ -> _ 
+          /  [(llen xs) + (llen ys)]     @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+Synthesize **ghost** parameter equal to `[...]`
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+... thereby reducing to decreasing **single parameter** case. 
+
+</div>
+
+Important Extensions 
+--------------------
+
+<br>
+
+<div class="fragment">**Mutual** recursion</div>
+
+<br>
+
+<div class="fragment">**Lexicographic** ordering</div>
+
+<br>
+
+<div class="fragment">Fit easily into our framework ...</div>
+
+Recap
+-----
+
+Main idea: Recursive calls on **smaller** inputs
+
+<br>
+
+<div class="fragment">Use refinements to **check** smaller</div>
+
+<br>
+
+<div class="fragment">Use refinements to **establish** smaller</div>
+
+
+A Curious Circularity
+---------------------
+
+<div class="fragment">Refinements require termination ...</div> 
+
+<br>
+
+<div class="fragment">... Termination requires refinements!</div>
+
+<br>
+
+<div class="fragment"> Meta-theory is tricky, but all ends well.</div>
+
+Recap
+-----
+
+1. Refinements: Types + Predicates
+2. Subtyping: SMT Implication
+3. Measures: Strengthened Constructors
+4. Abstract: Refinements over functions and data
+5. Lazy Evaluation: Requires Termination
+6. **Termination:** via Refinements!
+7. <div class="fragment">**Evaluation:** How good is this in practice?</div>
+
+<br>
+<br>
+
+<div class="fragment">[[continue...]](11_Evaluation.lhs.slides.html)</div>
+
+
diff --git a/docs/slides/flops14/lhs/11_Evaluation.lhs b/docs/slides/flops14/lhs/11_Evaluation.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/lhs/11_Evaluation.lhs
@@ -0,0 +1,118 @@
+ {#ASda}
+========
+
+Evaluation
+----------
+
+
+
+Evaluation
+==========
+
+LiquidHaskell Is For Real
+-------------------------
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg: to force Makefile"
+\end{code}
+
+</div>
+
+
+<br>
+
+Substantial code bases.
+
+<br>
+
+Complex properties.
+
+<br>
+
+<div class="fragment">Inference is crucial.</div>
+
+
+
+Numbers
+-------
+
+<div align="center">
+
+**Library**                     **LOC**
+---------------------------   ---------
+`Data.List`                         814
+`Data.Set.Splay`                    149
+`Data.Vector.Algorithms`           1219
+`Data.Map.Base`                    1396
+`Data.Text`                        3125
+`Data.Bytestring`                  3501 
+**Total**                     **10224**
+---------------------------   ---------
+
+</div>
+
+Numbers
+-------
+
+<div align="center">
+
+**Library**                     **LOC**     **Time**
+---------------------------   ---------   ----------
+`Data.List`                         814          52s
+`Data.Set.Splay`                    149          26s
+`Data.Vector.Algorithms`           1219         196s 
+`Data.Map.Base`                    1396         247s
+`Data.Text`                        3125         809s
+`Data.Bytestring`                  3501         549s
+**Total**                     **10224**    **1880s**
+---------------------------   ---------   ----------
+
+</div>
+
+
+Termination
+-----------
+
+Proving termination is **easy in practice**.
+
+<br>
+
+- <div class="fragment">`503` recursive functions</div>
+- <div class="fragment">`67%` automatically proved</div>
+- <div class="fragment">`30%` need *witnesses* `/[...]`</div>
+- <div class="fragment">`1`   witness per `100` lines of code</div>
+- <div class="fragment">`20`  *not proven* to terminate</div>
+- <div class="fragment">`12`  *do not* terminate (e.g. top-level `IO` loops)</div>
+- <div class="fragment">`8`   currently *outside scope* of LiquidHaskell</div>
+
+
+Future Work
+-----------
+
+<br>
+<br>
+
+- <div class="fragment">Speed</div>
+
+- <div class="fragment">Case Studies</div>
+
+- <div class="fragment">**Error Messages**</div>
+
+ {#asd}
+=======
+
+
+Thank You!
+----------
+
+<br>
+
+`cabal install liquidhaskell`
+
+<br>
+
+`https://github.com/ucsd-progsys/liquidhaskell`
+
+<br>
diff --git a/docs/slides/flops14/reveal.js/.gitignore b/docs/slides/flops14/reveal.js/.gitignore
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+.svn
+log/*.log
+tmp/**
+node_modules/
+.sass-cache
diff --git a/docs/slides/flops14/reveal.js/.travis.yml b/docs/slides/flops14/reveal.js/.travis.yml
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - 0.8
+before_script:
+  - npm install -g grunt-cli
diff --git a/docs/slides/flops14/reveal.js/Gruntfile.js b/docs/slides/flops14/reveal.js/Gruntfile.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/Gruntfile.js
@@ -0,0 +1,137 @@
+/* global module:false */
+module.exports = function(grunt) {
+	var port = grunt.option('port') || 8000;
+	// Project configuration
+	grunt.initConfig({
+		pkg: grunt.file.readJSON('package.json'),
+		meta: {
+			banner:
+				'/*!\n' +
+				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
+				' * http://lab.hakim.se/reveal-js\n' +
+				' * MIT licensed\n' +
+				' *\n' +
+				' * Copyright (C) 2013 Hakim El Hattab, http://hakim.se\n' +
+				' */'
+		},
+
+		qunit: {
+			files: [ 'test/*.html' ]
+		},
+
+		uglify: {
+			options: {
+				banner: '<%= meta.banner %>\n'
+			},
+			build: {
+				src: 'js/reveal.js',
+				dest: 'js/reveal.min.js'
+			}
+		},
+
+		cssmin: {
+			compress: {
+				files: {
+					'css/reveal.min.css': [ 'css/reveal.css' ]
+				}
+			}
+		},
+
+		sass: {
+			main: {
+				files: {
+					'css/theme/default.css': 'css/theme/source/default.scss',
+					'css/theme/beige.css': 'css/theme/source/beige.scss',
+					'css/theme/night.css': 'css/theme/source/night.scss',
+					'css/theme/serif.css': 'css/theme/source/serif.scss',
+					'css/theme/simple.css': 'css/theme/source/simple.scss',
+					'css/theme/sky.css': 'css/theme/source/sky.scss',
+					'css/theme/moon.css': 'css/theme/source/moon.scss',
+					'css/theme/solarized.css': 'css/theme/source/solarized.scss',
+					'css/theme/blood.css': 'css/theme/source/blood.scss'
+				}
+			}
+		},
+
+		jshint: {
+			options: {
+				curly: false,
+				eqeqeq: true,
+				immed: true,
+				latedef: true,
+				newcap: true,
+				noarg: true,
+				sub: true,
+				undef: true,
+				eqnull: true,
+				browser: true,
+				expr: true,
+				globals: {
+					head: false,
+					module: false,
+					console: false,
+					unescape: false
+				}
+			},
+			files: [ 'Gruntfile.js', 'js/reveal.js' ]
+		},
+
+		connect: {
+			server: {
+				options: {
+					port: port,
+					base: '.'
+				}
+			}
+		},
+
+		zip: {
+			'reveal-js-presentation.zip': [
+				'index.html',
+				'css/**',
+				'js/**',
+				'lib/**',
+				'images/**',
+				'plugin/**'
+			]
+		},
+
+		watch: {
+			main: {
+				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
+				tasks: 'default'
+			},
+			theme: {
+				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
+				tasks: 'themes'
+			}
+		}
+
+	});
+
+	// Dependencies
+	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
+	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
+	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
+	grunt.loadNpmTasks( 'grunt-contrib-watch' );
+	grunt.loadNpmTasks( 'grunt-contrib-sass' );
+	grunt.loadNpmTasks( 'grunt-contrib-connect' );
+	grunt.loadNpmTasks( 'grunt-zip' );
+
+	// Default task
+	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );
+
+	// Theme task
+	grunt.registerTask( 'themes', [ 'sass' ] );
+
+	// Package presentation to archive
+	grunt.registerTask( 'package', [ 'default', 'zip' ] );
+
+	// Serve presentation locally
+	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );
+
+	// Run tests
+	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );
+
+};
diff --git a/docs/slides/flops14/reveal.js/LICENSE b/docs/slides/flops14/reveal.js/LICENSE
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2013 Hakim El Hattab, http://hakim.se
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.eot b/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.eot
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.eot differ
diff --git a/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.svg b/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.svg
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.svg
@@ -0,0 +1,230 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="LeagueGothicRegular" horiz-adv-x="724" >
+<font-face units-per-em="2048" ascent="1505" descent="-543" />
+<missing-glyph horiz-adv-x="315" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="2048" />
+<glyph unicode="&#xd;" horiz-adv-x="682" />
+<glyph unicode=" "  horiz-adv-x="315" />
+<glyph unicode="&#x09;" horiz-adv-x="315" />
+<glyph unicode="&#xa0;" horiz-adv-x="315" />
+<glyph unicode="!" horiz-adv-x="387" d="M74 1505h239l-55 -1099h-129zM86 0v227h215v-227h-215z" />
+<glyph unicode="&#x22;" horiz-adv-x="329" d="M57 1505h215l-30 -551h-154z" />
+<glyph unicode="#" horiz-adv-x="1232" d="M49 438l27 195h198l37 258h-196l26 194h197l57 420h197l-57 -420h260l57 420h197l-58 -420h193l-27 -194h-192l-37 -258h190l-26 -195h-191l-59 -438h-197l60 438h-261l-59 -438h-197l60 438h-199zM471 633h260l37 258h-260z" />
+<glyph unicode="$" horiz-adv-x="692" d="M37 358l192 13q12 -186 129 -187q88 0 93 185q0 74 -61 175q-21 36 -34 53l-40 55q-28 38 -65.5 90t-70.5 101.5t-70.5 141.5t-37.5 170q4 293 215 342v131h123v-125q201 -23 235 -282l-192 -25q-14 129 -93 125q-80 -2 -84 -162q0 -102 94 -227l41 -59q30 -42 37 -52 t33 -48l37 -52q41 -57 68 -109l26 -55q43 -94 43 -186q-4 -338 -245 -369v-217h-123v221q-236 41 -250 352z" />
+<glyph unicode="%" horiz-adv-x="1001" d="M55 911v437q0 110 82 156q33 18 90.5 18t97.5 -44t44 -87l4 -43v-437q0 -107 -81 -157q-32 -19 -77 -19q-129 0 -156 135zM158 0l553 1505h131l-547 -1505h-137zM178 911q-4 -55 37 -55q16 0 25.5 14.5t9.5 26.5v451q2 55 -35 55q-18 0 -27.5 -13.5t-9.5 -27.5v-451z M631 158v436q0 108 81 156q33 20 79 20q125 0 153 -135l4 -41v-436q0 -110 -80 -156q-32 -18 -90.5 -18t-98.5 43t-44 88zM754 158q-4 -57 37 -58q37 0 34 58v436q2 55 -34 55q-18 0 -27.5 -13t-9.5 -28v-450z" />
+<glyph unicode="&#x26;" horiz-adv-x="854" d="M49 304q0 126 44 225.5t126 222.5q-106 225 -106 442v18q0 94 47 180q70 130 223 130q203 0 252 -215q14 -61 12 -113q0 -162 -205 -434q76 -174 148 -285q33 96 47 211l176 -33q-16 -213 -92 -358q55 -63 92 -76v-235q-23 0 -86 37.5t-123 101.5q-123 -139 -252 -139 t-216 97t-87 223zM263 325.5q1 -65.5 28.5 -107.5t78.5 -42t117 86q-88 139 -174 295q-18 -30 -34.5 -98t-15.5 -133.5zM305 1194q0 -111 55 -246q101 156 101 252q-2 2 0 15.5t-2 36t-11 42.5q-19 52 -61.5 52t-62 -38t-19.5 -75v-39z" />
+<glyph unicode="'" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="(" horiz-adv-x="561" d="M66 645q0 143 29.5 292.5t73.5 261.5q92 235 159 343l30 47l162 -84q-38 -53 -86.5 -148t-82.5 -189.5t-61.5 -238t-27.5 -284.5t26.5 -282.5t64.5 -240.5q80 -207 141 -296l26 -39l-162 -84q-41 61 -96 173t-94 217.5t-70.5 257t-31.5 294.5z" />
+<glyph unicode=")" horiz-adv-x="561" d="M41 -213q36 50 85.5 147t83.5 190t61.5 236.5t27.5 284.5t-26.5 282.5t-64.5 240.5q-78 205 -140 298l-27 39l162 84q41 -61 96 -173.5t94 -217t71 -257.5t32 -296t-30 -292.5t-74 -260.5q-92 -233 -159 -342l-30 -47z" />
+<glyph unicode="*" horiz-adv-x="677" d="M74 1251l43 148l164 -70l-19 176h154l-19 -176l164 70l43 -148l-172 -34l115 -138l-131 -80l-78 152l-76 -152l-131 80l115 138z" />
+<glyph unicode="+" horiz-adv-x="1060" d="M74 649v172h370v346h172v-346h371v-172h-371v-346h-172v346h-370z" />
+<glyph unicode="," horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="-" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="." horiz-adv-x="321" d="M53 0v227h215v-227h-215z" />
+<glyph unicode="/" horiz-adv-x="720" d="M8 -147l543 1652h162l-537 -1652h-168z" />
+<glyph unicode="0" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="1" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="2" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="3" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="4" horiz-adv-x="684" d="M25 328v194l323 983h221v-983h103v-194h-103v-328h-202v328h-342zM213 522h154v516h-13z" />
+<glyph unicode="5" horiz-adv-x="704" d="M74 438h221v-59q0 -115 14.5 -159t52 -44t53 45t15.5 156v336q0 111 -70 110q-33 0 -59.5 -40t-26.5 -70h-186v792h535v-219h-344v-313q74 55 127 51q78 0 133 -40t77 -100q35 -98 35 -171v-336q0 -393 -289 -393q-78 0 -133 29.5t-84.5 71.5t-46.5 109q-24 98 -24 244z " />
+<glyph unicode="6" horiz-adv-x="700" d="M66 309v856q0 356 288.5 356.5t288.5 -356.5v-94h-221q0 162 -11.5 210t-53.5 48t-56 -37t-14 -127v-268q59 37 124.5 37t119 -36t75.5 -93q37 -92 37 -189v-307q0 -90 -42 -187q-26 -61 -89 -99.5t-157.5 -38.5t-158 38.5t-88.5 99.5q-42 98 -42 187zM287 244 q0 -20 17.5 -44t49 -24t50 24.5t18.5 43.5v450q0 18 -18.5 43t-49 25t-48 -20.5t-19.5 -41.5v-456z" />
+<glyph unicode="7" horiz-adv-x="589" d="M8 1286v219h557v-221l-221 -1284h-229l225 1286h-332z" />
+<glyph unicode="8" horiz-adv-x="696" d="M53 322v176q0 188 115 297q-102 102 -102 276v127q0 213 147 293q57 31 135 31t135.5 -31t84 -71t42.5 -93q21 -66 21 -129v-127q0 -174 -103 -276q115 -109 115 -297v-176q0 -222 -153 -306q-60 -32 -142 -32t-141.5 32.5t-88 73.5t-44.5 96q-21 69 -21 136zM269 422 q1 -139 16.5 -187.5t57.5 -48.5t59.5 30t21.5 71t4 158t-13.5 174t-66.5 57t-66.5 -57.5t-12.5 -196.5zM284 1116q-1 -123 11 -173t53 -50t53.5 50t12.5 170t-12.5 167t-51.5 47t-52 -44t-14 -167z" />
+<glyph unicode="9" horiz-adv-x="700" d="M57 340v94h222q0 -162 11 -210t53 -48t56.5 37t14.5 127v283q-59 -37 -125 -37t-119 35.5t-76 92.5q-37 96 -37 189v293q0 87 43 188q25 60 88.5 99t157.5 39t157.5 -39t88.5 -99q43 -101 43 -188v-856q0 -356 -289 -356t-289 356zM279 825q0 -18 18 -42.5t49 -24.5 t48.5 20.5t19.5 40.5v443q0 20 -17.5 43.5t-49.5 23.5t-50 -24.5t-18 -42.5v-437z" />
+<glyph unicode=":" horiz-adv-x="362" d="M74 0v227h215v-227h-215zM74 893v227h215v-227h-215z" />
+<glyph unicode=";" horiz-adv-x="362" d="M74 0v227h215v-227l-113 -266h-102l71 266h-71zM74 893v227h215v-227h-215z" />
+<glyph unicode="&#x3c;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="=" horiz-adv-x="1058" d="M74 477v172h911v-172h-911zM74 864v172h911v-172h-911z" />
+<glyph unicode="&#x3e;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="?" horiz-adv-x="645" d="M25 1260q24 67 78 131q105 128 235 122q82 -2 138 -33.5t82 -81.5q46 -88 46 -170.5t-80 -219.5l-57 -96q-18 -32 -42 -106.5t-24 -143.5v-256h-190v256q0 102 24.5 195t48 140t65.5 118t50 105t-9 67.5t-60 34.5t-78 -48t-49 -98zM199 0h215v227h-215v-227z" />
+<glyph unicode="@" horiz-adv-x="872" d="M66 303v889q0 97 73 200q39 56 117 93t184.5 37t184 -37t116.5 -93q74 -105 74 -200v-793h-164l-20 56q-14 -28 -46 -48t-67 -20q-145 0 -145 172v485q0 170 145 170q71 0 113 -67v45q0 51 -45 104.5t-145.5 53.5t-145.5 -53.5t-45 -104.5v-889q0 -53 44 -103t153.5 -50 t160.5 63l152 -86q-109 -143 -320 -143q-106 0 -184 35.5t-117 90.5q-73 102 -73 193zM535 573q0 -53 48 -53t48 53v455q0 53 -48 53t-48 -53v-455z" />
+<glyph unicode="A" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="B" horiz-adv-x="745" d="M82 0v1505h194q205 0 304.5 -91t99.5 -308q0 -106 -29.5 -175t-107.5 -136q14 -5 47 -38.5t54 -71.5q52 -97 52 -259q0 -414 -342 -426h-272zM303 219q74 0 109 31q55 56 55 211t-63 195q-42 26 -93 26h-8v-463zM303 885q87 0 119 39q45 55 45 138t-14.5 124t-30.5 60.5 t-45 28.5q-35 11 -74 11v-401z" />
+<glyph unicode="C" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175z" />
+<glyph unicode="D" horiz-adv-x="761" d="M82 0v1505h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174zM303 221q117 0 140.5 78t23.5 399v111q0 322 -23.5 398.5t-140.5 76.5v-1063z" />
+<glyph unicode="E" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506z" />
+<glyph unicode="F" horiz-adv-x="616" d="M82 0v1505h526v-227h-305v-395h205v-228h-205v-655h-221z" />
+<glyph unicode="G" horiz-adv-x="737" d="M67 271.5q0 26.5 1 37.5v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-231h-221v231q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-905q0 -46 19.5 -78.5t54 -32.5t53 28t18.5 54l2 29v272h-88v187h309v-750h-131l-26 72 q-70 -88 -172 -88q-203 0 -250 213q-11 48 -11 74.5z" />
+<glyph unicode="H" horiz-adv-x="778" d="M82 0v1505h221v-622h172v622h221v-1505h-221v655h-172v-655h-221z" />
+<glyph unicode="I" horiz-adv-x="385" d="M82 0v1505h221v-1505h-221z" />
+<glyph unicode="J" horiz-adv-x="423" d="M12 -14v217q4 0 12.5 -1t29 2t35.5 12t28.5 34.5t13.5 62.5v1192h221v-1226q0 -137 -74 -216q-74 -78 -223 -78h-4q-19 0 -39 1z" />
+<glyph unicode="K" horiz-adv-x="768" d="M82 0v1505h221v-526h8l195 526h215l-203 -495l230 -1010h-216l-153 655l-6 31h-6l-64 -154v-532h-221z" />
+<glyph unicode="L" horiz-adv-x="604" d="M82 0v1505h221v-1300h293v-205h-514z" />
+<glyph unicode="M" horiz-adv-x="991" d="M82 0v1505h270l131 -688l11 -80h4l10 80l131 688h270v-1505h-204v1010h-13l-149 -1010h-94l-142 946l-8 64h-12v-1010h-205z" />
+<glyph unicode="N" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203z" />
+<glyph unicode="O" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="P" horiz-adv-x="720" d="M82 0v1505h221q166 0 277.5 -105.5t111.5 -345t-111.5 -346t-277.5 -106.5v-602h-221zM303 827q102 0 134 45.5t32 175.5t-33 181t-133 51v-453z" />
+<glyph unicode="Q" horiz-adv-x="729" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -94 -45 -182q33 -43 88 -53v-189q-160 0 -227 117q-55 -18 -125 -18t-130 33.5t-88 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887 q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="R" horiz-adv-x="739" d="M82 0v1505h221q377 0 377 -434q0 -258 -123 -342l141 -729h-221l-115 635h-59v-635h-221zM303 840q117 0 149 98q15 49 15 125t-15.5 125t-45.5 68q-44 30 -103 30v-446z" />
+<glyph unicode="S" horiz-adv-x="702" d="M37 422l217 20q0 -256 104 -256q90 0 91 166q0 59 -32 117.5t-45 79.5l-54 79q-40 58 -77 113t-73.5 117t-68 148.5t-31.5 162.5q0 139 71.5 245t216.5 108h10q88 0 152 -36t94 -100q54 -120 54 -264l-217 -20q0 217 -89 217q-75 -2 -75 -146q0 -59 23 -105 q32 -66 58 -104l197 -296q31 -49 67 -139.5t36 -166.5q0 -378 -306 -378h-2q-229 0 -290 188q-31 99 -31 250z" />
+<glyph unicode="T" horiz-adv-x="647" d="M4 1278v227h639v-227h-209v-1278h-221v1278h-209z" />
+<glyph unicode="U" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175z" />
+<glyph unicode="V" horiz-adv-x="716" d="M18 1505h215l111 -827l8 -64h13l118 891h215l-229 -1505h-221z" />
+<glyph unicode="W" horiz-adv-x="1036" d="M25 1505h204l88 -782l5 -49h16l100 831h160l100 -831h17l92 831h205l-203 -1505h-172l-115 801h-8l-115 -801h-172z" />
+<glyph unicode="X" horiz-adv-x="737" d="M16 0l244 791l-240 714h218l120 -381l7 -18h8l127 399h217l-240 -714l244 -791h-217l-127 449l-4 18h-8l-132 -467h-217z" />
+<glyph unicode="Y" horiz-adv-x="700" d="M14 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641z" />
+<glyph unicode="Z" horiz-adv-x="626" d="M20 0v238l347 1048h-297v219h536v-219l-352 -1067h352v-219h-586z" />
+<glyph unicode="[" horiz-adv-x="538" d="M82 -213v1718h399v-196h-202v-1325h202v-197h-399z" />
+<glyph unicode="\" horiz-adv-x="792" d="M8 1692h162l614 -1872h-168z" />
+<glyph unicode="]" horiz-adv-x="538" d="M57 -16h203v1325h-203v196h400v-1718h-400v197z" />
+<glyph unicode="^" horiz-adv-x="1101" d="M53 809l381 696h234l381 -696h-199l-299 543l-299 -543h-199z" />
+<glyph unicode="_" horiz-adv-x="1210" d="M74 -154h1063v-172h-1063v172z" />
+<glyph unicode="`" horiz-adv-x="1024" d="M293 1489h215l106 -184h-159z" />
+<glyph unicode="a" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="b" horiz-adv-x="686" d="M82 0v1505h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-74h-207zM289 246q0 -29 19.5 -48.5t42 -19.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -21.5t-19.5 -46.5v-628z" />
+<glyph unicode="c" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331z" />
+<glyph unicode="d" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v458h207v-1505h-207v74q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 19.5t19.5 48.5v628q0 25 -19.5 46.5t-42 21.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="e" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="f" horiz-adv-x="475" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-65 0 -65 -175v-5v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="g" horiz-adv-x="700" d="M12 -184q0 94 162 170q-125 35 -125 149q0 45 40 93t89 75q-51 35 -80.5 95.5t-34.5 105.5l-4 43v305q0 35 16.5 91t41 94t79 69t126.5 31q135 0 206 -103q102 102 170 103v-185q-72 0 -120 -24l10 -70v-317q0 -37 -17.5 -90.5t-42 -90t-79 -66.5t-104.5 -30t-62 2 q-29 -25 -29 -46t11 -33.5t42 -20.5t45.5 -10t65.5 -10.5t95 -21.5t89 -41q96 -60 96 -205t-103 -212q-100 -65 -250 -65h-9q-156 2 -240 50t-84 165zM213 -150q0 -77 132 -77h3q59 0 108.5 19t49.5 54t-20.5 52.5t-90.5 29.5l-106 21q-76 -43 -76 -99zM262 509 q0 -17 15.5 -45t44.5 -28q63 6 63 101v307q-2 0 0 10q1 3 1 7q0 8 -3 19q-4 15 -9 30q-11 36 -46 36t-50.5 -25.5t-15.5 -52.5v-359z" />
+<glyph unicode="h" horiz-adv-x="690" d="M82 0v1505h207v-479l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="i" horiz-adv-x="370" d="M82 0v1120h207v-1120h-207zM82 1298v207h207v-207h-207z" />
+<glyph unicode="j" horiz-adv-x="364" d="M-45 -182q29 -8 57 -8q64 0 64 142v1168h207v-1149q0 -186 -51 -266q-23 -35 -71 -62.5t-115 -27.5t-91 12v191zM76 1298v207h207v-207h-207z" />
+<glyph unicode="k" horiz-adv-x="641" d="M82 0v1505h207v-714h10l113 329h186l-149 -364l188 -756h-199l-102 453l-4 16h-10l-33 -82v-387h-207z" />
+<glyph unicode="l" horiz-adv-x="370" d="M82 0v1505h207v-1505h-207z" />
+<glyph unicode="m" horiz-adv-x="1021" d="M82 0v1120h207v-94q2 0 33 30q80 81 139 81q100 0 139 -125q125 125 194.5 125t109.5 -69t40 -150v-918h-194v887q-1 49 -56 49q-41 0 -78 -53v-883h-194v887q0 49 -55 49q-41 0 -78 -53v-883h-207z" />
+<glyph unicode="n" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="o" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="p" horiz-adv-x="686" d="M82 -385v1505h207v-73q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="q" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v73h207v-1505h-207v459q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 21.5t19.5 46.5v628q0 29 -19.5 48.5t-42 19.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="r" horiz-adv-x="503" d="M82 0v1120h207v-125q8 41 58.5 91.5t148.5 50.5v-230q-34 11 -77 11t-86.5 -39t-43.5 -101v-778h-207z" />
+<glyph unicode="s" horiz-adv-x="630" d="M37 326h192q0 -170 97 -170q71 0 71 131q0 78 -129 202q-68 66 -98.5 99t-64 101.5t-33.5 134t12 114.5t39 95q59 100 201 104h11q161 0 211 -105q42 -86 42 -198h-193q0 131 -67 131q-63 -2 -64 -131q0 -33 23.5 -73t45 -62.5t66.5 -65.5q190 -182 191 -342 q0 -123 -64.5 -215t-199.5 -92q-197 0 -260 170q-29 76 -29 172z" />
+<glyph unicode="t" horiz-adv-x="501" d="M20 934v186h105v277h207v-277h141v-186h-141v-557q0 -184 65 -184l76 8v-203q-45 -14 -112 -14t-114.5 28.5t-70 64.5t-34.5 96q-17 79 -17 187v574h-105z" />
+<glyph unicode="u" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5z" />
+<glyph unicode="v" horiz-adv-x="602" d="M16 1120h201l68 -649l8 -72h16l76 721h201l-183 -1120h-204z" />
+<glyph unicode="w" horiz-adv-x="905" d="M20 1120h189l65 -585l9 -64h12l96 649h123l86 -585l10 -64h13l73 649h189l-166 -1120h-172l-80 535l-10 63h-8l-91 -598h-172z" />
+<glyph unicode="x" horiz-adv-x="618" d="M16 0l193 578l-176 542h194l74 -262l6 -31h4l6 31l74 262h195l-176 -542l192 -578h-201l-84 283l-6 30h-4l-6 -30l-84 -283h-201z" />
+<glyph unicode="y" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5z" />
+<glyph unicode="z" horiz-adv-x="532" d="M12 0v168l285 764h-240v188h459v-168l-285 -764h285v-188h-504z" />
+<glyph unicode="{" horiz-adv-x="688" d="M61 453v163q72 0 102 49.5t30 90.5v397q0 223 96 298t342 71v-172q-135 2 -188.5 -38t-53.5 -159v-397q0 -143 -127 -221q127 -82 127 -222v-397q0 -119 53.5 -159t188.5 -38v-172q-246 -4 -342 71t-96 298v397q0 57 -41 97.5t-91 42.5z" />
+<glyph unicode="|" horiz-adv-x="356" d="M82 -512v2204h192v-2204h-192z" />
+<glyph unicode="}" horiz-adv-x="688" d="M57 -281q135 -2 188.5 38t53.5 159v397q0 139 127 222q-127 78 -127 221v397q0 119 -53 159t-189 38v172q246 4 342.5 -71t96.5 -298v-397q0 -63 41 -101.5t90 -38.5v-163q-72 -4 -101.5 -52.5t-29.5 -87.5v-397q0 -223 -96.5 -298t-342.5 -71v172z" />
+<glyph unicode="~" horiz-adv-x="1280" d="M113 1352q35 106 115 200q34 41 94.5 74t121 33t116.5 -18.5t82 -33t83 -51.5q106 -72 174 -71q109 0 178 153l13 29l135 -57q-63 -189 -206 -276q-56 -34 -120 -34q-121 0 -272 101q-115 74 -178.5 74t-113.5 -45.5t-69 -90.5l-18 -45z" />
+<glyph unicode="&#xa1;" horiz-adv-x="387" d="M74 -385l55 1100h129l55 -1100h-239zM86 893v227h215v-227h-215z" />
+<glyph unicode="&#xa2;" horiz-adv-x="636" d="M66 508v489q0 297 208 328v242h123v-244q98 -16 144.5 -88t46.5 -227v-88h-189v135q0 90 -72.5 90t-72.5 -90v-604q0 -90 72 -91q74 0 73 91v155h189v-108q0 -156 -46 -228.5t-145 -89.5v-303h-123v301q-209 31 -208 330z" />
+<glyph unicode="&#xa3;" horiz-adv-x="817" d="M4 63q8 20 23.5 53.5t70 91.5t117.5 68q37 111 37 189t-31 184h-188v137h147l-6 21q-78 254 -78 333t15.5 140t48.5 116q72 122 231 126q190 4 267 -126q65 -108 65 -276h-213q0 201 -115 197q-47 -2 -68.5 -51t-21.5 -139.5t70 -315.5l6 -25h211v-137h-174 q25 -100 24.5 -189t-57.5 -204q16 -8 44 -24q59 -35 89 -35q74 4 82 190l188 -22q-12 -182 -81.5 -281.5t-169.5 -99.5q-51 0 -143.5 51t-127.5 51t-63.5 -25.5t-40.5 -52.5l-12 -24z" />
+<glyph unicode="&#xa5;" horiz-adv-x="720" d="M25 1505h217l110 -481l6 -14h4l7 14l110 481h217l-196 -753h147v-138h-176v-137h176v-137h-176v-340h-221v340h-176v137h176v137h-176v138h147z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1024" d="M272 1305v200h191v-200h-191zM561 1305v200h191v-200h-191z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM627 487v531q0 122 97 174q40 22 95 22 q147 0 182 -147l7 -49v-125h-138v142q0 11 -12 28.5t-37 17.5q-47 -2 -49 -63v-531q0 -63 49 -63q53 2 49 63v125h138v-125q0 -68 -40 -127q-18 -26 -57 -47.5t-108.5 -21.5t-117.5 49t-54 98z" />
+<glyph unicode="&#xaa;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xad;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#xae;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM625 313v879h196q231 0 232 -258 q0 -76 -16.5 -125t-71.5 -96l106 -400h-151l-95 365h-55v-365h-145zM770 805h45q43 0 65.5 21.5t27.5 45t5 61.5t-5 62.5t-27.5 46t-65.5 21.5h-45v-258z" />
+<glyph unicode="&#xaf;" horiz-adv-x="1024" d="M313 1315v162h398v-162h-398z" />
+<glyph unicode="&#xb2;" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="&#xb3;" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="&#xb4;" horiz-adv-x="1024" d="M410 1305l106 184h215l-162 -184h-159z" />
+<glyph unicode="&#xb7;" horiz-adv-x="215" d="M0 649v228h215v-228h-215z" />
+<glyph unicode="&#xb8;" horiz-adv-x="1024" d="M426 -111h172v-141l-45 -133h-104l40 133h-63v141z" />
+<glyph unicode="&#xb9;" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="&#xba;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="&#xbf;" horiz-adv-x="645" d="M41 -106q0 82 80 219l57 95q18 32 42 106.5t24 144.5v256h190v-256q0 -102 -24.5 -195.5t-48 -140.5t-65.5 -118t-50 -104.5t9 -67.5t60 -35t78 48.5t49 98.5l179 -84q-24 -66 -78 -132q-104 -126 -236 -122q-163 4 -220 115q-46 90 -46 172zM231 893v227h215v-227h-215z " />
+<glyph unicode="&#xc0;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM141 1823h215l107 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc1;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM293 1638l106 185h215l-161 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc2;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM133 1638l141 185h220l141 -185h-189l-63 72l-61 -72h-189zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc3;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM184 1632v152q49 39 95.5 39t104.5 -18.5t100.5 -19.5t97.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-98 19.5t-102 -33zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc4;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM143 1638v201h191v-201h-191zM307 541h152l-64 475l-6 39h-12zM432 1638v201h191v-201h-191z" />
+<glyph unicode="&#xc5;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM231 1761.5q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM307 541h152l-64 475l-6 39h-12zM309 1761.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50 t-23.5 50t-52.5 21.5t-52.5 -21.5t-23.5 -50z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1099" d="M16 0l420 1505h623v-227h-285v-395h205v-242h-205v-414h285v-227h-506v307h-227l-90 -307h-220zM393 541h160v514h-10z" />
+<glyph unicode="&#xc7;" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM268 -111v-141h64l-41 -133h104l45 133v141h-172z" />
+<glyph unicode="&#xc8;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM111 1823h215l106 -185h-160z" />
+<glyph unicode="&#xc9;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM236 1638l106 185h215l-162 -185h-159z" />
+<glyph unicode="&#xca;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM84 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xcb;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM94 1638v201h191v-201h-191zM383 1638v201h190v-201h-190z" />
+<glyph unicode="&#xcc;" horiz-adv-x="401" d="M-6 1823h215l106 -185h-159zM98 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcd;" horiz-adv-x="401" d="M82 0v1505h221v-1505h-221zM86 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xce;" horiz-adv-x="370" d="M-66 1638l142 185h219l141 -185h-188l-64 72l-61 -72h-189zM74 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcf;" horiz-adv-x="372" d="M-53 1638v201h190v-201h-190zM76 0v1505h221v-1505h-221zM236 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd0;" horiz-adv-x="761" d="M20 655v228h62v622h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174v655h-62zM303 221q117 0 141.5 81t22.5 452q2 371 -22.5 450.5t-141.5 79.5v-401h84v-228h-84v-434z " />
+<glyph unicode="&#xd1;" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203zM207 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39t-102.5 19.5t-100 19.5t-99.5 -33z" />
+<glyph unicode="&#xd2;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM121 1823h215l106 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd3;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM285 1638l106 185h215l-162 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5 t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd4;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM113 1638l141 185h219l141 -185h-188l-64 72l-61 -72h-188zM289 309q0 -46 19.5 -78 t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd5;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM164 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39 t-102.5 19.5t-100 19.5t-99.5 -33zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd6;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM123 1638v201h190v-201h-190zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887zM412 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd8;" d="M59 -20l47 157q-36 74 -36 148l-2 24v887q0 42 17 106t45 107t88.5 78t148 35t153.5 -43l15 47h122l-45 -150q43 -84 43 -155l2 -25v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-150.5 -34.5t-153 43l-15 -47h-129zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v488zM289 727l147 479q-8 100 -74 101q-35 0 -53 -28t-18 -54l-2 -29v-469z" />
+<glyph unicode="&#xd9;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM145 1823h215l107 -185h-160z" />
+<glyph unicode="&#xda;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM307 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xdb;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM125 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xdc;" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175zM135 1638v201h191v-201h-191zM424 1638v201h190v-201h-190z" />
+<glyph unicode="&#xdd;" horiz-adv-x="704" d="M16 1505l226 -864v-641h221v641l225 864h-217l-111 -481l-6 -14h-4l-6 14l-111 481h-217zM254 1638l106 185h215l-161 -185h-160z" />
+<glyph unicode="&#xde;" d="M82 0v1505h219v-241h2q166 0 277.5 -105.5t111.5 -345.5t-111.5 -346.5t-277.5 -106.5v-360h-221zM303 586q102 0 134 45t32 175t-33 181t-133 51v-452z" />
+<glyph unicode="&#xdf;" horiz-adv-x="733" d="M66 0v1235q0 123 70.5 205t206.5 82t204.5 -81t68.5 -197t-88 -181q152 -88 152 -488q0 -362 -87 -475q-46 -59 -102.5 -79.5t-144.5 -20.5v193q45 0 70 25q57 57 57 357q0 316 -57 377q-25 27 -70 27v141q35 0 60.5 33t25.5 84q0 100 -86 100q-74 0 -74 -102v-1235h-206 z" />
+<glyph unicode="&#xe0;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1489h215 l107 -184h-160zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe1;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xe2;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM90 1305 l141 184h220l141 -184h-189l-63 71l-61 -71h-189zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe3;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM143 1305v151 q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe4;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1305v200 h191v-200h-191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM391 1305v200h191v-200h-191z" />
+<glyph unicode="&#xe5;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM188 1421.5 q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM266 1421.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50t-23.5 50t-52.5 21.5t-52.5 -21.5 t-23.5 -50z" />
+<glyph unicode="&#xe6;" horiz-adv-x="989" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t197.5 88q84 0 152 -52q66 51 162 52q199 0 251 -197q14 -51 15 -92v-326h-342v-256q0 -60 38 -88q17 -12 38 -12q70 10 73 113v122h193v-129 q0 -37 -16.5 -93t-41 -95t-80 -69.5t-130.5 -30.5q-158 0 -226 131q-102 -131 -221 -131q-59 0 -112.5 60t-53.5 191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM588 684h149v158q0 48 -19.5 81t-53 33t-53 -28.5t-21.5 -57.5l-2 -28v-158z " />
+<glyph unicode="&#xe7;" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331zM238 -111v-141h63l-41 -133h105l45 133v141h-172z " />
+<glyph unicode="&#xe8;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM102 1489h215l107 -184 h-160zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xe9;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xea;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM80 1305l141 184h219 l142 -184h-189l-63 71l-62 -71h-188zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xeb;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM90 1305v200h191v-200 h-191zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xec;" horiz-adv-x="370" d="M-33 1489h215l107 -184h-160zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xed;" horiz-adv-x="370" d="M82 0h207v1120h-207v-1120zM82 1305l106 184h215l-161 -184h-160z" />
+<glyph unicode="&#xee;" horiz-adv-x="370" d="M-66 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xef;" horiz-adv-x="372" d="M-53 1305v200h190v-200h-190zM82 0v1120h207v-1120h-207zM236 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf0;" horiz-adv-x="673" d="M76 279v579q0 279 172 279q63 0 155 -78q-12 109 -51 203l-82 -72l-55 63l100 88l-45 66l109 100q25 -27 53 -61l94 82l56 -66l-101 -88q125 -201 125 -446v-656q0 -102 -56 -188q-26 -39 -80 -69.5t-129 -30.5t-130 30.5t-80 73.5q-53 91 -53 160zM270 267.5 q-2 -11.5 2 -29t10 -34.5q16 -38 58 -38q70 10 72 113v563q-2 0 0 11t-2 28.5t-10 34.5q-16 40 -60 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf1;" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207zM147 1305v151q49 39 95.5 39t105 -18.5t97 -19.5t100.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#xf2;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM98 1489h215l107 -184h-160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf3;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5 t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM260 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xf4;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM78 1305l141 184h219l142 -184h-189l-63 71l-62 -71h-188zM258 267.5q-2 -11.5 2 -29 t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf5;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM131 1305v151q49 39 95.5 39t104.5 -18.5t98.5 -19.5t98.5 32v-152q-51 -39 -95 -39 t-102 19.5t-101 19.5t-99 -32zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf6;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM90 1305v200h191v-200h-191zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf8;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t118 32t117.5 -19l21 80h75l-30 -121q88 -84 94 -229v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-120.5 -30.5t-112 16l-20 -78h-80l31 121q-41 39 -64.5 97.5t-25.5 97.5zM258 436l125 486q-18 35 -55 34q-68 -10 -70 -114 v-406zM274 197q17 -31 54 -31q70 10 71 113v403z" />
+<glyph unicode="&#xf9;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM113 1489h215l106 -184h-160z" />
+<glyph unicode="&#xfa;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM274 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfb;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM94 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189z" />
+<glyph unicode="&#xfc;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM106 1305v200h191v-200h-191zM395 1305v200h191v-200h-191z" />
+<glyph unicode="&#xfd;" horiz-adv-x="634" d="M25 1120l190 -1153q0 -68 -36 -123t-97 -61l-49 4v-184q70 -4 92 -4q115 0 192.5 95t94.5 222l198 1204h-202l-82 -688l-4 -57h-9l-4 57l-82 688h-202zM231 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfe;" horiz-adv-x="686" d="M82 -385v1890h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="&#xff;" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5zM78 1305v200h190v-200h-190zM367 1305v200h190v-200h-190z" />
+<glyph unicode="&#x152;" horiz-adv-x="983" d="M68 309v887q0 41 17 101.5t45 100.5t88.5 73.5t143.5 33.5h580v-227h-285v-395h205v-242h-205v-414h285v-227h-580q-84 0 -144 31.5t-88 78.5q-55 91 -60 169zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v901q-6 96 -74 97q-35 0 -53 -28t-18 -54l-2 -29 v-887z" />
+<glyph unicode="&#x153;" horiz-adv-x="995" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t145.5 32t156 -60q66 59 170 60q199 0 252 -197q14 -51 14 -92v-326h-342v-250q0 -46 22.5 -76t53.5 -30q70 10 73 113v122h193v-129q0 -37 -16.5 -93t-41 -95t-80 -69.5t-146 -30.5t-154.5 57q-68 -57 -156 -57t-143.5 30.5 t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM594 684h149v158q0 48 -19 81t-58 33t-55.5 -37.5t-16.5 -70.5v-164z" />
+<glyph unicode="&#x178;" horiz-adv-x="704" d="M16 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641zM113 1638v201h190v-201h-190zM401 1638v201h191v-201h-191z" />
+<glyph unicode="&#x2c6;" horiz-adv-x="1021" d="M260 1305l141 184h220l141 -184h-189l-63 71l-61 -71h-189z" />
+<glyph unicode="&#x2dc;" horiz-adv-x="1024" d="M313 1305v151q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#x2000;" horiz-adv-x="952" />
+<glyph unicode="&#x2001;" horiz-adv-x="1905" />
+<glyph unicode="&#x2002;" horiz-adv-x="952" />
+<glyph unicode="&#x2003;" horiz-adv-x="1905" />
+<glyph unicode="&#x2004;" horiz-adv-x="635" />
+<glyph unicode="&#x2005;" horiz-adv-x="476" />
+<glyph unicode="&#x2006;" horiz-adv-x="317" />
+<glyph unicode="&#x2007;" horiz-adv-x="317" />
+<glyph unicode="&#x2008;" horiz-adv-x="238" />
+<glyph unicode="&#x2009;" horiz-adv-x="381" />
+<glyph unicode="&#x200a;" horiz-adv-x="105" />
+<glyph unicode="&#x2010;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2011;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2012;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2013;" horiz-adv-x="806" d="M74 649v195h659v-195h-659z" />
+<glyph unicode="&#x2014;" horiz-adv-x="972" d="M74 649v195h825v-195h-825z" />
+<glyph unicode="&#x2018;" horiz-adv-x="309" d="M49 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x2019;" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="&#x201a;" horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="&#x201c;" horiz-adv-x="624" d="M53 1012v227l113 266h102l-71 -266h71v-227h-215zM356 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x201d;" horiz-adv-x="624" d="M53 1012l72 266h-72v227h215v-227l-112 -266h-103zM356 1012l72 266h-72v227h215v-227l-112 -266h-103z" />
+<glyph unicode="&#x201e;" horiz-adv-x="624" d="M53 0v227h215v-227l-112 -266h-103l72 266h-72zM356 0v227h215v-227l-112 -266h-103l72 266h-72z" />
+<glyph unicode="&#x2022;" horiz-adv-x="663" d="M82 815q0 104 72.5 177t177 73t177.5 -72.5t73 -177t-73 -177.5t-177 -73t-177 73t-73 177z" />
+<glyph unicode="&#x2026;" horiz-adv-x="964" d="M53 0v227h215v-227h-215zM375 0v227h215v-227h-215zM696 0v227h215v-227h-215z" />
+<glyph unicode="&#x202f;" horiz-adv-x="381" />
+<glyph unicode="&#x2039;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="&#x203a;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="&#x205f;" horiz-adv-x="476" />
+<glyph unicode="&#x20ac;" horiz-adv-x="813" d="M53 547v137h107v137h-107v137h107v238q0 42 17.5 106t45 107t88 78t144.5 35t144 -34t88 -81q53 -90 61 -178l2 -33v-84h-207v84q-2 0 0 11.5t-3 27.5t-12 33q-18 39 -69 39q-70 -10 -78 -111v-238h233v-137h-233v-137h233v-137h-233v-238q0 -43 21.5 -76.5t59.5 -33.5 t58.5 27.5t20.5 56.5l2 26v84h207v-84q0 -38 -17.5 -104t-45.5 -109t-88 -77.5t-144 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175l-2 35v238h-107z" />
+<glyph unicode="&#x2122;" horiz-adv-x="937" d="M74 1401v104h321v-104h-104v-580h-113v580h-104zM440 821v684h138l67 -319h6l68 319h137v-684h-104v449l-78 -449h-51l-80 449v-449h-103z" />
+<glyph unicode="&#xe000;" horiz-adv-x="1120" d="M0 0v1120h1120v-1120h-1120z" />
+<glyph unicode="&#xfb01;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2v-184q-41 12 -91 12t-69.5 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h358v-1120h-207v934h-151v-934h-207v934h-105z" />
+<glyph unicode="&#xfb02;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2h164v-1505h-207v1329q-37 4 -67.5 4t-50 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="&#xfb03;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1120h207v-1120h-207zM1032 1298v207h207v-207h-207z" />
+<glyph unicode="&#xfb04;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1505h207v-1505h-207z" />
+</font>
+</defs></svg> 
diff --git a/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.ttf b/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.ttf differ
diff --git a/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.woff b/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.woff
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/reveal.js/lib/font/league_gothic-webfont.woff differ
diff --git a/docs/slides/flops14/reveal.js/lib/font/league_gothic_license b/docs/slides/flops14/reveal.js/lib/font/league_gothic_license
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/lib/font/league_gothic_license
@@ -0,0 +1,2 @@
+SIL Open Font License (OFL)
+http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
diff --git a/docs/slides/flops14/reveal.js/plugin/highlight/highlight.js b/docs/slides/flops14/reveal.js/plugin/highlight/highlight.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/highlight/highlight.js
@@ -0,0 +1,32 @@
+// START CUSTOM REVEAL.JS INTEGRATION
+(function() {
+	if( typeof window.addEventListener === 'function' ) {
+		var hljs_nodes = document.querySelectorAll( 'pre code' );
+
+		for( var i = 0, len = hljs_nodes.length; i < len; i++ ) {
+			var element = hljs_nodes[i];
+
+			// trim whitespace if data-trim attribute is present
+			if( element.hasAttribute( 'data-trim' ) && typeof element.innerHTML.trim === 'function' ) {
+				element.innerHTML = element.innerHTML.trim();
+			}
+
+			// Now escape html unless prevented by author
+			if( ! element.hasAttribute( 'data-noescape' )) {
+				element.innerHTML = element.innerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;");
+			}
+
+			// re-highlight when focus is lost (for edited code)
+			element.addEventListener( 'focusout', function( event ) {
+				hljs.highlightBlock( event.currentTarget );
+			}, false );
+		}
+	}
+})();
+// END CUSTOM REVEAL.JS INTEGRATION
+
+// highlight.js build includes support for:
+// All languages in master + fsharp
+
+
+var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName=="CODE"){return o}if(!(o.nodeType==3&&o.nodeValue.match(/\s+/))){break}}}function h(p,o){return Array.prototype.map.call(p.childNodes,function(q){if(q.nodeType==3){return o?q.nodeValue.replace(/\n/g,""):q.nodeValue}if(q.nodeName=="BR"){return"\n"}return h(q,o)}).join("")}function a(q){var p=(q.className+" "+(q.parentNode?q.parentNode.className:"")).split(/\s+/);p=p.map(function(r){return r.replace(/^language-/,"")});for(var o=0;o<p.length;o++){if(e[p[o]]||p[o]=="no-highlight"){return p[o]}}}function c(q){var o=[];(function p(r,s){for(var t=r.firstChild;t;t=t.nextSibling){if(t.nodeType==3){s+=t.nodeValue.length}else{if(t.nodeName=="BR"){s+=1}else{if(t.nodeType==1){o.push({event:"start",offset:s,node:t});s=p(t,s);o.push({event:"stop",offset:s,node:t})}}}}return s})(q,0);return o}function j(x,v,w){var p=0;var y="";var r=[];function t(){if(x.length&&v.length){if(x[0].offset!=v[0].offset){return(x[0].offset<v[0].offset)?x:v}else{return v[0].event=="start"?x:v}}else{return x.length?x:v}}function s(A){function z(B){return" "+B.nodeName+'="'+l(B.value)+'"'}return"<"+A.nodeName+Array.prototype.map.call(A.attributes,z).join("")+">"}while(x.length||v.length){var u=t().splice(0,1)[0];y+=l(w.substr(p,u.offset-p));p=u.offset;if(u.event=="start"){y+=s(u.node);r.push(u.node)}else{if(u.event=="stop"){var o,q=r.length;do{q--;o=r[q];y+=("</"+o.nodeName.toLowerCase()+">")}while(o!=u.node);r.splice(q,1);while(q<r.length){y+=s(r[q]);q++}}}}return y+l(w.substr(p))}function f(r){function o(s){return(s&&s.source)||s}function p(t,s){return RegExp(o(t),"m"+(r.cI?"i":"")+(s?"g":""))}function q(z,x){if(z.compiled){return}z.compiled=true;var u=[];if(z.k){var s={};function A(B,t){t.split(" ").forEach(function(C){var D=C.split("|");s[D[0]]=[B,D[1]?Number(D[1]):1];u.push(D[0])})}z.lR=p(z.l||hljs.IR+"(?!\\.)",true);if(typeof z.k=="string"){A("keyword",z.k)}else{for(var y in z.k){if(!z.k.hasOwnProperty(y)){continue}A(y,z.k[y])}}z.k=s}if(x){if(z.bWK){z.b="\\b("+u.join("|")+")\\b(?!\\.)\\s*"}z.bR=p(z.b?z.b:"\\B|\\b");if(!z.e&&!z.eW){z.e="\\B|\\b"}if(z.e){z.eR=p(z.e)}z.tE=o(z.e)||"";if(z.eW&&x.tE){z.tE+=(z.e?"|":"")+x.tE}}if(z.i){z.iR=p(z.i)}if(z.r===undefined){z.r=1}if(!z.c){z.c=[]}for(var w=0;w<z.c.length;w++){if(z.c[w]=="self"){z.c[w]=z}q(z.c[w],z)}if(z.starts){q(z.starts,x)}var v=[];for(var w=0;w<z.c.length;w++){v.push(o(z.c[w].b))}if(z.tE){v.push(o(z.tE))}if(z.i){v.push(o(z.i))}z.t=v.length?p(v.join("|"),true):{exec:function(t){return null}}}q(r)}function d(E,F,C){function o(r,N){for(var M=0;M<N.c.length;M++){var L=N.c[M].bR.exec(r);if(L&&L.index==0){return N.c[M]}}}function s(L,r){if(L.e&&L.eR.test(r)){return L}if(L.eW){return s(L.parent,r)}}function t(r,L){return !C&&L.i&&L.iR.test(r)}function y(M,r){var L=G.cI?r[0].toLowerCase():r[0];return M.k.hasOwnProperty(L)&&M.k[L]}function H(){var L=l(w);if(!A.k){return L}var r="";var O=0;A.lR.lastIndex=0;var M=A.lR.exec(L);while(M){r+=L.substr(O,M.index-O);var N=y(A,M);if(N){v+=N[1];r+='<span class="'+N[0]+'">'+M[0]+"</span>"}else{r+=M[0]}O=A.lR.lastIndex;M=A.lR.exec(L)}return r+L.substr(O)}function z(){if(A.sL&&!e[A.sL]){return l(w)}var r=A.sL?d(A.sL,w):g(w);if(A.r>0){v+=r.keyword_count;B+=r.r}return'<span class="'+r.language+'">'+r.value+"</span>"}function K(){return A.sL!==undefined?z():H()}function J(M,r){var L=M.cN?'<span class="'+M.cN+'">':"";if(M.rB){x+=L;w=""}else{if(M.eB){x+=l(r)+L;w=""}else{x+=L;w=r}}A=Object.create(M,{parent:{value:A}})}function D(L,r){w+=L;if(r===undefined){x+=K();return 0}var N=o(r,A);if(N){x+=K();J(N,r);return N.rB?0:r.length}var O=s(A,r);if(O){var M=A;if(!(M.rE||M.eE)){w+=r}x+=K();do{if(A.cN){x+="</span>"}B+=A.r;A=A.parent}while(A!=O.parent);if(M.eE){x+=l(r)}w="";if(O.starts){J(O.starts,"")}return M.rE?0:r.length}if(t(r,A)){throw new Error('Illegal lexem "'+r+'" for mode "'+(A.cN||"<unnamed>")+'"')}w+=r;return r.length||1}var G=e[E];f(G);var A=G;var w="";var B=0;var v=0;var x="";try{var u,q,p=0;while(true){A.t.lastIndex=p;u=A.t.exec(F);if(!u){break}q=D(F.substr(p,u.index-p),u[0]);p=u.index+q}D(F.substr(p));return{r:B,keyword_count:v,value:x,language:E}}catch(I){if(I.message.indexOf("Illegal")!=-1){return{r:0,keyword_count:0,value:l(F)}}else{throw I}}}function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p in e){if(!e.hasOwnProperty(p)){continue}var r=d(p,s,false);r.language=p;if(r.keyword_count+r.r>q.keyword_count+q.r){q=r}if(r.keyword_count+r.r>o.keyword_count+o.r){q=o;o=r}}if(q.language){o.second_best=q}return o}function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\t)+)/gm,function(r,v,u,t){return v.replace(/\t/g,p)})}if(o){q=q.replace(/\n/g,"<br>")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}var w=t?d(t,v,true):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match("(\\s|^)(language-)?"+t+"(\\s|$)")){s=s?(s+" "+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagName("pre"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener("DOMContentLoaded",n,false);window.addEventListener("load",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES["1c"]=function(b){var f="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*";var c="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт";var e="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку  стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон";var a={cN:"dquote",b:'""'};var d={cN:"string",b:'"',e:'"|$',c:[a],r:0};var g={cN:"string",b:"\\|",e:'"|$',c:[a]};return{cI:true,l:f,k:{keyword:c,built_in:e},c:[b.CLCM,b.NM,d,g,{cN:"function",b:"(процедура|функция)",e:"$",l:f,k:"процедура функция",c:[{cN:"title",b:f},{cN:"tail",eW:true,c:[{cN:"params",b:"\\(",e:"\\)",l:f,k:"знач",c:[d,g]},{cN:"export",b:"экспорт",eW:true,l:f,k:"экспорт",c:[b.CLCM]}]},b.CLCM]},{cN:"preprocessor",b:"#",e:"$"},{cN:"date",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}}(hljs);hljs.LANGUAGES.actionscript=function(a){var d="[a-zA-Z_$][a-zA-Z0-9_$]*";var c="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";var e={cN:"rest_arg",b:"[.]{3}",e:d,r:10};var b={cN:"title",b:d};return{k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{cN:"package",bWK:true,e:"{",k:"package",c:[b]},{cN:"class",bWK:true,e:"{",k:"class interface",c:[{bWK:true,k:"extends implements"},b]},{cN:"preprocessor",bWK:true,e:";",k:"import include"},{cN:"function",bWK:true,e:"[{;]",k:"function",i:"\\S",c:[b,{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,e]},{cN:"type",b:":",e:c,r:10}]}]}}(hljs);hljs.LANGUAGES.apache=function(a){var b={cN:"number",b:"[\\$%]\\d+"};return{cI:true,k:{keyword:"acceptfilter acceptmutex acceptpathinfo accessfilename action addalt addaltbyencoding addaltbytype addcharset adddefaultcharset adddescription addencoding addhandler addicon addiconbyencoding addiconbytype addinputfilter addlanguage addmoduleinfo addoutputfilter addoutputfilterbytype addtype alias aliasmatch allow allowconnect allowencodedslashes allowoverride anonymous anonymous_logemail anonymous_mustgiveemail anonymous_nouserid anonymous_verifyemail authbasicauthoritative authbasicprovider authdbduserpwquery authdbduserrealmquery authdbmgroupfile authdbmtype authdbmuserfile authdefaultauthoritative authdigestalgorithm authdigestdomain authdigestnccheck authdigestnonceformat authdigestnoncelifetime authdigestprovider authdigestqop authdigestshmemsize authgroupfile authldapbinddn authldapbindpassword authldapcharsetconfig authldapcomparednonserver authldapdereferencealiases authldapgroupattribute authldapgroupattributeisdn authldapremoteuserattribute authldapremoteuserisdn authldapurl authname authnprovideralias authtype authuserfile authzdbmauthoritative authzdbmtype authzdefaultauthoritative authzgroupfileauthoritative authzldapauthoritative authzownerauthoritative authzuserauthoritative balancermember browsermatch browsermatchnocase bufferedlogs cachedefaultexpire cachedirlength cachedirlevels cachedisable cacheenable cachefile cacheignorecachecontrol cacheignoreheaders cacheignorenolastmod cacheignorequerystring cachelastmodifiedfactor cachemaxexpire cachemaxfilesize cacheminfilesize cachenegotiateddocs cacheroot cachestorenostore cachestoreprivate cgimapextension charsetdefault charsetoptions charsetsourceenc checkcaseonly checkspelling chrootdir contentdigest cookiedomain cookieexpires cookielog cookiename cookiestyle cookietracking coredumpdirectory customlog dav davdepthinfinity davgenericlockdb davlockdb davmintimeout dbdexptime dbdkeep dbdmax dbdmin dbdparams dbdpersist dbdpreparesql dbdriver defaulticon defaultlanguage defaulttype deflatebuffersize deflatecompressionlevel deflatefilternote deflatememlevel deflatewindowsize deny directoryindex directorymatch directoryslash documentroot dumpioinput dumpiologlevel dumpiooutput enableexceptionhook enablemmap enablesendfile errordocument errorlog example expiresactive expiresbytype expiresdefault extendedstatus extfilterdefine extfilteroptions fileetag filterchain filterdeclare filterprotocol filterprovider filtertrace forcelanguagepriority forcetype forensiclog gracefulshutdowntimeout group header headername hostnamelookups identitycheck identitychecktimeout imapbase imapdefault imapmenu include indexheadinsert indexignore indexoptions indexorderdefault indexstylesheet isapiappendlogtoerrors isapiappendlogtoquery isapicachefile isapifakeasync isapilognotsupported isapireadaheadbuffer keepalive keepalivetimeout languagepriority ldapcacheentries ldapcachettl ldapconnectiontimeout ldapopcacheentries ldapopcachettl ldapsharedcachefile ldapsharedcachesize ldaptrustedclientcert ldaptrustedglobalcert ldaptrustedmode ldapverifyservercert limitinternalrecursion limitrequestbody limitrequestfields limitrequestfieldsize limitrequestline limitxmlrequestbody listen listenbacklog loadfile loadmodule lockfile logformat loglevel maxclients maxkeepaliverequests maxmemfree maxrequestsperchild maxrequestsperthread maxspareservers maxsparethreads maxthreads mcachemaxobjectcount mcachemaxobjectsize mcachemaxstreamingbuffer mcacheminobjectsize mcacheremovalalgorithm mcachesize metadir metafiles metasuffix mimemagicfile minspareservers minsparethreads mmapfile mod_gzip_on mod_gzip_add_header_count mod_gzip_keep_workfiles mod_gzip_dechunk mod_gzip_min_http mod_gzip_minimum_file_size mod_gzip_maximum_file_size mod_gzip_maximum_inmem_size mod_gzip_temp_dir mod_gzip_item_include mod_gzip_item_exclude mod_gzip_command_version mod_gzip_can_negotiate mod_gzip_handle_methods mod_gzip_static_suffix mod_gzip_send_vary mod_gzip_update_static modmimeusepathinfo multiviewsmatch namevirtualhost noproxy nwssltrustedcerts nwsslupgradeable options order passenv pidfile protocolecho proxybadheader proxyblock proxydomain proxyerroroverride proxyftpdircharset proxyiobuffersize proxymaxforwards proxypass proxypassinterpolateenv proxypassmatch proxypassreverse proxypassreversecookiedomain proxypassreversecookiepath proxypreservehost proxyreceivebuffersize proxyremote proxyremotematch proxyrequests proxyset proxystatus proxytimeout proxyvia readmename receivebuffersize redirect redirectmatch redirectpermanent redirecttemp removecharset removeencoding removehandler removeinputfilter removelanguage removeoutputfilter removetype requestheader require rewritebase rewritecond rewriteengine rewritelock rewritelog rewriteloglevel rewritemap rewriteoptions rewriterule rlimitcpu rlimitmem rlimitnproc satisfy scoreboardfile script scriptalias scriptaliasmatch scriptinterpretersource scriptlog scriptlogbuffer scriptloglength scriptsock securelisten seerequesttail sendbuffersize serveradmin serveralias serverlimit servername serverpath serverroot serversignature servertokens setenv setenvif setenvifnocase sethandler setinputfilter setoutputfilter ssienableaccess ssiendtag ssierrormsg ssistarttag ssitimeformat ssiundefinedecho sslcacertificatefile sslcacertificatepath sslcadnrequestfile sslcadnrequestpath sslcarevocationfile sslcarevocationpath sslcertificatechainfile sslcertificatefile sslcertificatekeyfile sslciphersuite sslcryptodevice sslengine sslhonorciperorder sslmutex ssloptions sslpassphrasedialog sslprotocol sslproxycacertificatefile sslproxycacertificatepath sslproxycarevocationfile sslproxycarevocationpath sslproxyciphersuite sslproxyengine sslproxymachinecertificatefile sslproxymachinecertificatepath sslproxyprotocol sslproxyverify sslproxyverifydepth sslrandomseed sslrequire sslrequiressl sslsessioncache sslsessioncachetimeout sslusername sslverifyclient sslverifydepth startservers startthreads substitute suexecusergroup threadlimit threadsperchild threadstacksize timeout traceenable transferlog typesconfig unsetenv usecanonicalname usecanonicalphysicalport user userdir virtualdocumentroot virtualdocumentrootip virtualscriptalias virtualscriptaliasip win32disableacceptex xbithack",literal:"on off"},c:[a.HCM,{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",b]},b,{cN:"tag",b:"</?",e:">"},a.QSM]}}(hljs);hljs.LANGUAGES.applescript=function(a){var b=a.inherit(a.QSM,{i:""});var e={cN:"title",b:a.UIR};var d={cN:"params",b:"\\(",e:"\\)",c:["self",a.CNM,b]};var c=[{cN:"comment",b:"--",e:"$",},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",{b:"--",e:"$"}]},a.HCM];return{k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[b,a.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bWK:true,k:"on",i:"[${=;\\n]",c:[e,d]}].concat(c),i:"//"}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);hljs.LANGUAGES.asciidoc=function(a){return{c:[{cN:"comment",b:"^/{4,}\\n",e:"\\n/{4,}$",r:10},{cN:"comment",b:"^//",e:"$",r:0},{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"header",b:"^(={1,5}) .+?( \\1)?$",r:10},{cN:"header",b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$",r:10},{cN:"attribute",b:"^:.+?:",e:"\\s",eE:true,r:10},{cN:"attribute",b:"^\\[.+?\\]$",r:0},{cN:"blockquote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"label",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{cN:"horizontal_rule",b:"^'{4,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:true,c:[{b:"(link|image:?):",r:0},{cN:"link_url",b:"\\w",e:"[^\\[]+",r:0},{cN:"link_label",b:"\\[",e:"\\]",eB:true,eE:true,r:0}],r:10}]}}(hljs);hljs.LANGUAGES.avrasm=function(a){return{cI:true,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf"},c:[a.CBLCLM,{cN:"comment",b:";",e:"$"},a.CNM,a.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"label",b:"^[A-Za-z0-9_.$]+:"},{cN:"preprocessor",b:"#",e:"$"},{cN:"preprocessor",b:"\\.[a-zA-Z]+"},{cN:"localvars",b:"@[0-9]+"}]}}(hljs);hljs.LANGUAGES.axapta=function(a){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"{",i:":",k:"class interface",c:[{cN:"inheritance",bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]}]}}(hljs);hljs.LANGUAGES.bash=function(a){var c={cN:"variable",b:/\$[\w\d#@][\w\d_]*/};var b={cN:"variable",b:/\$\{(.*?)\}/};var e={cN:"string",b:/"/,e:/"/,c:[a.BE,c,b,{cN:"variable",b:/\$\(/,e:/\)/,c:a.BE}],r:0};var d={cN:"string",b:/'/,e:/'/,r:0};return{l:/-?[a-z]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[{cN:"title",b:/\w[\w\d_]*/}],r:0},a.HCM,a.NM,e,d,c,b]}}(hljs);hljs.LANGUAGES.brainfuck=function(a){return{c:[{cN:"comment",b:"[^\\[\\]\\.,\\+\\-<> \r\n]",eE:true,e:"[\\[\\]\\.,\\+\\-<> \r\n]",r:0},{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]"},{cN:"literal",b:"[\\+\\-]"}]}}(hljs);hljs.LANGUAGES.clojure=function(l){var e={built_in:"def cond apply if-not if-let if not not= = &lt; < > &lt;= <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for doseq dosync dotimes and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import intern refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! import use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if throw printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time ns assert re-find re-groups rand-int rand mod locking assert-valid-fdecl alias namespace resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! memfn to-array future future-call into-array aset gen-class reduce merge map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"};var f="[a-zA-Z_0-9\\!\\.\\?\\-\\+\\*\\/\\<\\=\\>\\&\\#\\$';]+";var a="[\\s:\\(\\{]+\\d+(\\.\\d+)?";var d={cN:"number",b:a,r:0};var j={cN:"string",b:'"',e:'"',c:[l.BE],r:0};var o={cN:"comment",b:";",e:"$",r:0};var n={cN:"collection",b:"[\\[\\{]",e:"[\\]\\}]"};var c={cN:"comment",b:"\\^"+f};var b={cN:"comment",b:"\\^\\{",e:"\\}"};var h={cN:"attribute",b:"[:]"+f};var m={cN:"list",b:"\\(",e:"\\)"};var g={eW:true,k:{literal:"true false nil"},r:0};var i={k:e,l:f,cN:"title",b:f,starts:g};m.c=[{cN:"comment",b:"comment"},i];g.c=[m,j,c,b,o,h,n,d];n.c=[m,j,c,o,h,n,d];return{i:"\\S",c:[o,m]}}(hljs);hljs.LANGUAGES.cmake=function(a){return{cI:true,k:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file",c:[{cN:"envvar",b:"\\${",e:"}"},a.HCM,a.QSM,a.NM]}}(hljs);hljs.LANGUAGES.coffeescript=function(c){var b={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module exports global window document"};var a="[A-Za-z$_][0-9A-Za-z$_]*";var f={cN:"title",b:a};var e={cN:"subst",b:"#\\{",e:"}",k:b,};var d=[c.BNM,c.inherit(c.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",b:"'''",e:"'''",c:[c.BE]},{cN:"string",b:"'",e:"'",c:[c.BE],r:0},{cN:"string",b:'"""',e:'"""',c:[c.BE,e]},{cN:"string",b:'"',e:'"',c:[c.BE,e],r:0},{cN:"regexp",b:"///",e:"///",c:[c.HCM]},{cN:"regexp",b:"//[gim]*",r:0},{cN:"regexp",b:"/\\S(\\\\.|[^\\n])*?/[gim]*(?=\\s|\\W|$)"},{cN:"property",b:"@"+a},{b:"`",e:"`",eB:true,eE:true,sL:"javascript"}];e.c=d;return{k:b,c:d.concat([{cN:"comment",b:"###",e:"###"},c.HCM,{cN:"function",b:"("+a+"\\s*=\\s*)?(\\(.*\\))?\\s*[-=]>",e:"[-=]>",rB:true,c:[f,{cN:"params",b:"\\(",rB:true,c:[{b:/\(/,e:/\)/,k:b,c:["self"].concat(d)}]}]},{cN:"class",bWK:true,k:"class",e:"$",i:"[:\\[\\]]",c:[{bWK:true,k:"extends",eW:true,i:":",c:[f]},f]},{cN:"attribute",b:a+":",e:":",rB:true,eE:true}])}}(hljs);hljs.LANGUAGES.cpp=function(a){var b={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long throw volatile static protected bool template mutable if public friend do return goto auto void enum else break new extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'\\\\?.",e:"'",i:"."},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},a.CNM,{cN:"preprocessor",b:"#",e:"$",c:[{b:"<",e:">",i:"\\n"},a.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,r:10,c:["self"]}]}}(hljs);hljs.LANGUAGES.cs=function(a){return{k:"abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async await ascending descending from get group into join let orderby partial select set value var where yield",c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"}]},a.CLCM,a.CBLCLM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},a.ASM,a.QSM,a.CNM]}}(hljs);hljs.LANGUAGES.css=function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.NM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}}(hljs);hljs.LANGUAGES.d=function(x){var b={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"};var c="(0|[1-9][\\d_]*)",q="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",h="0[bB][01_]+",v="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",y="0[xX]"+v,p="([eE][+-]?"+q+")",o="("+q+"(\\.\\d*|"+p+")|\\d+\\."+q+q+"|\\."+c+p+"?)",k="(0[xX]("+v+"\\."+v+"|\\.?"+v+")[pP][+-]?"+q+")",l="("+c+"|"+h+"|"+y+")",n="("+k+"|"+o+")";var z="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};";var m={cN:"number",b:"\\b"+l+"(L|u|U|Lu|LU|uL|UL)?",r:0};var j={cN:"number",b:"\\b("+n+"([fF]|L|i|[fF]i|Li)?|"+l+"(i|[fF]i|Li))",r:0};var s={cN:"string",b:"'("+z+"|.)",e:"'",i:"."};var r={b:z,r:0};var w={cN:"string",b:'"',c:[r],e:'"[cwd]?',r:0};var f={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5};var u={cN:"string",b:"`",e:"`[cwd]?"};var i={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10};var t={cN:"string",b:'q"\\{',e:'\\}"'};var e={cN:"shebang",b:"^#!",e:"$",r:5};var g={cN:"preprocessor",b:"#(line)",e:"$",r:5};var d={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"};var a={cN:"comment",b:"\\/\\+",c:["self"],e:"\\+\\/",r:10};return{l:x.UIR,k:b,c:[x.CLCM,x.CBLCLM,a,i,w,f,u,t,j,m,s,e,g,d]}}(hljs);hljs.LANGUAGES.delphi=function(b){var f="and safecall cdecl then string exports library not pascal set virtual file in array label packed end. index while const raise for to implementation with except overload destructor downto finally program exit unit inherited override if type until function do begin repeat goto nil far initialization object else var uses external resourcestring interface end finalization class asm mod case on shr shl of register xorwrite threadvar try record near stored constructor stdcall inline div out or procedure";var e="safecall stdcall pascal stored const implementation finalization except to finally program inherited override then exports string read not mod shr try div shl set library message packed index for near overload label downto exit public goto interface asm on of constructor or private array unit raise destructor var type until function else external with case default record while protected property procedure published and cdecl do threadvar file in if end virtual write far out begin repeat nil initialization object uses resourcestring class register xorwrite inline static";var a={cN:"comment",b:"{",e:"}",r:0};var g={cN:"comment",b:"\\(\\*",e:"\\*\\)",r:10};var c={cN:"string",b:"'",e:"'",c:[{b:"''"}],r:0};var d={cN:"string",b:"(#\\d+)+"};var h={cN:"function",bWK:true,e:"[:;]",k:"function constructor|10 destructor|10 procedure|10",c:[{cN:"title",b:b.IR},{cN:"params",b:"\\(",e:"\\)",k:f,c:[c,d]},a,g]};return{cI:true,k:f,i:'("|\\$[G-Zg-z]|\\/\\*|</)',c:[a,g,b.CLCM,c,d,b.NM,h,{cN:"class",b:"=\\bclass\\b",e:"end;",k:e,c:[c,d,a,g,b.CLCM,h]}]}}(hljs);hljs.LANGUAGES.diff=function(a){return{c:[{cN:"chunk",b:"^\\@\\@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +\\@\\@$",r:10},{cN:"chunk",b:"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$",r:10},{cN:"chunk",b:"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$",r:10},{cN:"header",b:"Index: ",e:"$"},{cN:"header",b:"=====",e:"=====$"},{cN:"header",b:"^\\-\\-\\-",e:"$"},{cN:"header",b:"^\\*{3} ",e:"$"},{cN:"header",b:"^\\+\\+\\+",e:"$"},{cN:"header",b:"\\*{5}",e:"\\*{5}$"},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}(hljs);hljs.LANGUAGES.django=function(c){function e(h,g){return(g==undefined||(!h.cN&&g.cN=="tag")||h.cN=="value")}function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}if(e(l,k)){m=b.concat(m)}if(m.length){g.c=m}}return g}var d={cN:"filter",b:"\\|[A-Za-z]+\\:?",k:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone",c:[{cN:"argument",b:'"',e:'"'}]};var b=[{cN:"template_comment",b:"{%\\s*comment\\s*%}",e:"{%\\s*endcomment\\s*%}"},{cN:"template_comment",b:"{#",e:"#}"},{cN:"template_tag",b:"{%",e:"%}",k:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor in ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup by as ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim",c:[d]},{cN:"variable",b:"{{",e:"}}",c:[d]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.dos=function(a){return{cI:true,k:{flow:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",keyword:"shift cd dir echo setlocal endlocal set pause copy",stream:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux",winutils:"ping net ipconfig taskkill xcopy ren del"},c:[{cN:"envvar",b:"%%[^ ]"},{cN:"envvar",b:"%[^ ]+?%"},{cN:"envvar",b:"![^ ]+?!"},{cN:"number",b:"\\b\\d+",r:0},{cN:"comment",b:"@?rem",e:"$"}]}}(hljs);hljs.LANGUAGES["erlang-repl"]=function(a){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},{cN:"comment",b:"%",e:"$"},{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a.ASM,a.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}}(hljs);hljs.LANGUAGES.erlang=function(i){var c="[a-z'][a-zA-Z0-9_']*";var o="("+c+":"+c+"|"+c+")";var f={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun let not of orelse|10 query receive rem try when xor",literal:"false true"};var l={cN:"comment",b:"%",e:"$",r:0};var e={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0};var g={b:"fun\\s+"+c+"/\\d+"};var n={b:o+"\\(",e:"\\)",rB:true,r:0,c:[{cN:"function_name",b:o,r:0},{b:"\\(",e:"\\)",eW:true,rE:true,r:0}]};var h={cN:"tuple",b:"{",e:"}",r:0};var a={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0};var m={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0};var b={b:"#",e:"}",i:".",r:0,rB:true,c:[{cN:"record_name",b:"#"+i.UIR,r:0},{b:"{",eW:true,r:0}]};var k={k:f,b:"(fun|receive|if|try|case)",e:"end"};k.c=[l,g,i.inherit(i.ASM,{cN:""}),k,n,i.QSM,e,h,a,m,b];var j=[l,g,k,n,i.QSM,e,h,a,m,b];n.c[1].c=j;h.c=j;b.c[1].c=j;var d={cN:"params",b:"\\(",e:"\\)",c:j};return{k:f,i:"(</|\\*=|\\+=|-=|/=|/\\*|\\*/|\\(\\*|\\*\\))",c:[{cN:"function",b:"^"+c+"\\s*\\(",e:"->",rB:true,i:"\\(|#|//|/\\*|\\\\|:",c:[d,{cN:"title",b:c}],starts:{e:";|\\.",k:f,c:j}},l,{cN:"pp",b:"^-",e:"\\.",r:0,eE:true,rB:true,l:"-"+i.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior",c:[d]},e,i.QSM,b,a,m,h]}}(hljs);hljs.LANGUAGES.fsharp=function(a){var b="'[a-zA-Z0-9_]+";return{k:"yield! return! let! do!abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun|10 function global if in inherit inline interface internal lazy let match member module mutable|10 namespace new null of open or override private public rec|10 return sig static struct then to true try type upcast use val void when while with yield",c:[{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},{cN:"comment",b:"//",e:"$",rB:true},{cN:"comment",b:"\\(\\*",e:"\\*\\)"},{cN:"class",bWK:true,e:"\\(|=|$",k:"type",c:[{cN:"title",b:a.UIR}]},{cN:"annotation",b:"\\[<",e:">\\]",r:10},{cN:"typeparam",b:"<",e:">",c:[{cN:"title",b:b}]},a.CLCM,a.CBLCLM,a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),a.CNM]}}(hljs);hljs.LANGUAGES.glsl=function(a){return{k:{keyword:"atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly",built_in:"gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffsetgl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse",literal:"true false"},i:'"',c:[a.CLCM,a.CBLCLM,a.CNM,{cN:"preprocessor",b:"#",e:"$"}]}}(hljs);hljs.LANGUAGES.go=function(a){var b={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer",constant:"true false iota nil",typename:"bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"string",b:"`",e:"`"},{cN:"number",b:"[^a-zA-Z_0-9](\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?",r:0},a.CNM]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.haml=function(a){return{cI:true,c:[{cN:"doctype",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},{cN:"comment",b:"^\\s*(-#|/).*$",r:0},{b:"^\\s*-(?!#)",starts:{e:"\\n",sL:"ruby"},r:0},{cN:"tag",b:"^\\s*%",c:[{cN:"title",b:"\\w+",r:0},{cN:"value",b:"[#\\.]\\w+",r:0},{b:"{\\s*",e:"\\s*}",eE:true,c:[{b:":\\w+\\s*=>",e:",\\s+",rB:true,eW:true,r:0,c:[{cN:"symbol",b:":\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0},{b:"\\(\\s*",e:"\\s*\\)",eE:true,c:[{b:"\\w+\\s*=",e:"\\s+",rB:true,eW:true,r:0,c:[{cN:"attribute",b:"\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0}],r:10},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"},r:0}]}}(hljs);hljs.LANGUAGES.handlebars=function(c){function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}m=d.concat(m);if(m.length){g.c=m}}return g}var b="each in with if else unless bindattr action collection debugger log outlet template unbound view yield";var e={cN:"variable",b:"[a-zA-Z.]+",k:b};var d=[{cN:"expression",b:"{{",e:"}}",c:[{cN:"begin-block",b:"#[a-zA-Z .]+",k:b},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z .]+",k:b},{cN:"variable",b:"[a-zA-Z.]+",k:b}]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.haskell=function(a){var d={cN:"type",b:"\\b[A-Z][\\w']*",r:0};var c={cN:"container",b:"\\(",e:"\\)",i:'"',c:[{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},{cN:"title",b:"[_a-z][\\w']*"}]};var b={cN:"container",b:"{",e:"}",c:c.c};return{k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance not as foreign ccall safe unsafe",c:[{cN:"comment",b:"--",e:"$"},{cN:"preprocessor",b:"{-#",e:"#-}"},{cN:"comment",c:["self"],b:"{-",e:"-}"},{cN:"string",b:"\\s+'",e:"'",c:[a.BE],r:0},a.QSM,{cN:"import",b:"\\bimport",e:"$",k:"import qualified as hiding",c:[c],i:"\\W\\.|;"},{cN:"module",b:"\\bmodule",e:"where",k:"module where",c:[c],i:"\\W\\.|;"},{cN:"class",b:"\\b(class|instance)",e:"where",k:"class where instance",c:[d]},{cN:"typedef",b:"\\b(data|(new)?type)",e:"$",k:"data type newtype deriving",c:[d,c,b]},a.CNM,{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},d,{cN:"title",b:"^[_a-z][\\w']*"},{b:"->|<-"}]}}(hljs);hljs.LANGUAGES.http=function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}}(hljs);hljs.LANGUAGES.ini=function(a){return{cI:true,i:"[^\\s]",c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:"on off true false yes no",c:[a.QSM,a.NM],r:0}]}]}}(hljs);hljs.LANGUAGES.java=function(a){return{k:"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,{cN:"class",bWK:true,e:"{",k:"class interface",eE:true,i:":",c:[{bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]},a.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}}(hljs);hljs.LANGUAGES.javascript=function(a){return{k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const",literal:"true false null undefined NaN Infinity"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,a.REGEXP_MODE,{b:/</,e:/>;/,sL:"xml"}],r:0},{cN:"function",bWK:true,e:/{/,k:"function",c:[{cN:"title",b:/[A-Za-z$_][0-9A-Za-z$_]*/},{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBLCLM],i:/["'\(]/}],i:/\[|%/}]}}(hljs);hljs.LANGUAGES.json=function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}}(hljs);hljs.LANGUAGES.lasso=function(b){var a="[a-zA-Z_][a-zA-Z0-9_.]*|&[lg]t;";var c="<\\?(lasso(script)?|=)";return{cI:true,l:a,k:{literal:"true false none minimal full all infinity nan and or not bw ew cn lt lte gt gte eq neq ft rx nrx",built_in:"array date decimal duration integer map pair string tag xml null list queue set stack staticarray local var variable data global self inherited void",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require skip split_thread sum take thread to trait type where with yield"},c:[{cN:"preprocessor",b:"\\]|\\?>",r:0,starts:{cN:"markup",e:"\\[|"+c,rE:true}},{cN:"preprocessor",b:"\\[noprocess\\]",starts:{cN:"markup",e:"\\[/noprocess\\]",rE:true}},{cN:"preprocessor",b:"\\[no_square_brackets|\\[/noprocess|"+c},{cN:"preprocessor",b:"\\[",r:0},{cN:"shebang",b:"^#!.+lasso9\\b",r:10},b.CLCM,{cN:"javadoc",b:"/\\*\\*!",e:"\\*/"},b.CBLCLM,b.CNM,b.inherit(b.ASM,{i:null}),b.inherit(b.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{cN:"variable",b:"#\\d+|[#$]"+a},{cN:"tag",b:"::",e:a},{cN:"attribute",b:"\\.\\.\\.|-"+b.UIR},{cN:"class",bWK:true,k:"define",eE:true,e:"\\(|=>",c:[{cN:"title",b:b.UIR+"=?"}]}]}}(hljs);hljs.LANGUAGES.lisp=function(i){var l="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*";var m="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?";var k={cN:"shebang",b:"^#!",e:"$"};var a={cN:"literal",b:"\\b(t{1}|nil)\\b"};var d=[{cN:"number",b:m},{cN:"number",b:"#b[0-1]+(/[0-1]+)?"},{cN:"number",b:"#o[0-7]+(/[0-7]+)?"},{cN:"number",b:"#x[0-9a-f]+(/[0-9a-f]+)?"},{cN:"number",b:"#c\\("+m+" +"+m,e:"\\)"}];var h={cN:"string",b:'"',e:'"',c:[i.BE],r:0};var n={cN:"comment",b:";",e:"$"};var g={cN:"variable",b:"\\*",e:"\\*"};var o={cN:"keyword",b:"[:&]"+l};var b={b:"\\(",e:"\\)",c:["self",a,h].concat(d)};var e={cN:"quoted",b:"['`]\\(",e:"\\)",c:d.concat([h,g,o,b])};var c={cN:"quoted",b:"\\(quote ",e:"\\)",k:{title:"quote"},c:d.concat([h,g,o,b])};var j={cN:"list",b:"\\(",e:"\\)"};var f={eW:true,r:0};j.c=[{cN:"title",b:l},f];f.c=[e,c,j,a].concat(d).concat([h,n,g,o]);return{i:"[^\\s]",c:d.concat([k,a,h,n,e,c,j])}}(hljs);hljs.LANGUAGES.lua=function(b){var a="\\[=*\\[";var e="\\]=*\\]";var c={b:a,e:e,c:["self"]};var d=[{cN:"comment",b:"--(?!"+a+")",e:"$"},{cN:"comment",b:"--"+a,e:e,c:[c],r:10}];return{l:b.UIR,k:{keyword:"and break do else elseif end false for if in local nil not or repeat return then true until while",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},c:d.concat([{cN:"function",bWK:true,e:"\\)",k:"function",c:[{cN:"title",b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"},{cN:"params",b:"\\(",eW:true,c:d}].concat(d)},b.CNM,b.ASM,b.QSM,{cN:"string",b:a,e:e,c:[c],r:10}])}}(hljs);hljs.LANGUAGES.markdown=function(a){return{c:[{cN:"header",b:"^#{1,3}",e:"$"},{cN:"header",b:"^.+?\\n[=-]{2,}$"},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",b:"\\*.+?\\*"},{cN:"emphasis",b:"_.+?_",r:0},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",b:"`.+?`"},{cN:"code",b:"^    ",e:"$",r:0},{cN:"horizontal_rule",b:"^-{3,}",e:"$"},{b:"\\[.+?\\]\\(.+?\\)",rB:true,c:[{cN:"link_label",b:"\\[.+\\]"},{cN:"link_url",b:"\\(",e:"\\)",eB:true,eE:true}]}]}}(hljs);hljs.LANGUAGES.matlab=function(a){var b=[a.CNM,{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0}];return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bWK:true,e:"$",k:"function",c:[{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)"},{cN:"params",b:"\\[",e:"\\]"}]},{cN:"transposed_variable",b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:""},{cN:"matrix",b:"\\[",e:"\\]'*[\\.']*",c:b},{cN:"cell",b:"\\{",e:"\\}'*[\\.']*",c:b},{cN:"comment",b:"\\%",e:"$"}].concat(b)}}(hljs);hljs.LANGUAGES.mel=function(a){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:"</",c:[a.CNM,a.ASM,a.QSM,{cN:"string",b:"`",e:"`",c:[a.BE]},{cN:"variable",b:"\\$\\d",r:5},{cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+|[^\\s\\w{]|{\\w+}|\\w+)"},a.CLCM,a.CBLCLM]}}(hljs);hljs.LANGUAGES.mizar=function(a){return{k:["environ vocabularies notations constructors definitions registrations theorems schemes requirements","begin end definition registration cluster existence pred func defpred deffunc theorem proof","let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from","be being by means equals implies iff redefine define now not or attr is mode suppose per cases set","thesis contradiction scheme reserve struct","correctness compatibility coherence symmetry assymetry reflexivity irreflexivity","connectedness uniqueness commutativity idempotence involutiveness projectivity"].join(" "),c:[{cN:"comment",b:"::",e:"$"}]}}(hljs);hljs.LANGUAGES.nginx=function(b){var c=[{cN:"variable",b:"\\$\\d+"},{cN:"variable",b:"\\${",e:"}"},{cN:"variable",b:"[\\$\\@]"+b.UIR}];var a={eW:true,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[b.HCM,{cN:"string",b:'"',e:'"',c:[b.BE].concat(c),r:0},{cN:"string",b:"'",e:"'",c:[b.BE].concat(c),r:0},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:true,eE:true},{cN:"regexp",b:"\\s\\^",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"~\\*?\\s+",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"\\*(\\.[a-z\\-]+)+",c:[b.BE].concat(c)},{cN:"regexp",b:"([a-z\\-]+\\.)+\\*",c:[b.BE].concat(c)},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0}].concat(c)};return{c:[b.HCM,{b:b.UIR+"\\s",e:";|{",rB:true,c:[{cN:"title",b:b.UIR,starts:a}],r:0}],i:"[^\\s\\}]"}}(hljs);hljs.LANGUAGES.objectivec=function(a){var b={keyword:"int float while private char catch export sizeof typedef const struct for union unsigned long volatile static protected bool mutable if public do return goto void enum else break extern asm case short default double throw register explicit signed typename try this switch continue wchar_t inline readonly assign property self synchronized end synthesize id optional required nonatomic super unichar finally dynamic IBOutlet IBAction selector strong weak readonly",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection UIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.CNM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"preprocessor",b:"#import",e:"$",c:[{cN:"title",b:'"',e:'"'},{cN:"title",b:"<",e:">"}]},{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"({|$)",k:"interface class protocol implementation",c:[{cN:"id",b:a.UIR}]},{cN:"variable",b:"\\."+a.UIR,r:0}]}}(hljs);hljs.LANGUAGES.parser3=function(a){return{sL:"xml",r:0,c:[{cN:"comment",b:"^#",e:"$"},{cN:"comment",b:"\\^rem{",e:"}",r:10,c:[{b:"{",e:"}",c:["self"]}]},{cN:"preprocessor",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},a.CNM]}}(hljs);hljs.LANGUAGES.perl=function(e){var a="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when";var d={cN:"subst",b:"[$@]\\{",e:"\\}",k:a,r:10};var b={cN:"variable",b:"\\$\\d"};var i={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var f=[e.BE,d,b,i];var h={b:"->",c:[{b:e.IR},{b:"{",e:"}"}]};var g={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5};var c=[b,i,e.HCM,g,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:true},h,{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:f,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:f,r:5},{cN:"string",b:"'",e:"'",c:[e.BE],r:0},{cN:"string",b:'"',e:'"',c:f,r:0},{cN:"string",b:"`",e:"`",c:[e.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"("+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,g,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bWK:true,e:"(\\s*\\(.*?\\))?[;{]",k:"sub",r:5},{cN:"operator",b:"-\\w\\b",r:0}];d.c=c;h.c[1].c=c;return{k:a,c:c}}(hljs);hljs.LANGUAGES.php=function(a){var e={cN:"variable",b:"\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"};var b=[a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),{cN:"string",b:'b"',e:'"',c:[a.BE]},{cN:"string",b:"b'",e:"'",c:[a.BE]}];var c=[a.BNM,a.CNM];var d={cN:"title",b:a.UIR};return{cI:true,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return implements parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception php_user_filter default die require __FUNCTION__ enddeclare final try this switch continue endfor endif declare unset true false namespace trait goto instanceof insteadof __DIR__ __NAMESPACE__ __halt_compiler",c:[a.CLCM,a.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"}]},{cN:"comment",eB:true,b:"__halt_compiler.+?;",eW:true},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[a.BE]},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"},e,{cN:"function",bWK:true,e:"{",k:"function",i:"\\$|\\[|%",c:[d,{cN:"params",b:"\\(",e:"\\)",c:["self",e,a.CBLCLM].concat(b).concat(c)}]},{cN:"class",bWK:true,e:"{",k:"class",i:"[:\\(\\$]",c:[{bWK:true,eW:true,k:"extends",c:[d]},d]},{b:"=>"}].concat(b).concat(c)}}(hljs);hljs.LANGUAGES.profile=function(a){return{c:[a.CNM,{cN:"built_in",b:"{",e:"}$",eB:true,eE:true,c:[a.ASM,a.QSM],r:0},{cN:"filename",b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:true},{cN:"header",b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{cN:"summary",b:"function calls",e:"$",c:[a.CNM],r:10},a.ASM,a.QSM,{cN:"function",b:"\\(",e:"\\)$",c:[{cN:"title",b:a.UIR,r:0}],r:0}]}}(hljs);hljs.LANGUAGES.python=function(a){var f={cN:"prompt",b:/^(>>>|\.\.\.) /};var c=[{cN:"string",b:/(u|b)?r?'''/,e:/'''/,c:[f],r:10},{cN:"string",b:/(u|b)?r?"""/,e:/"""/,c:[f],r:10},{cN:"string",b:/(u|r|ur)'/,e:/'/,c:[a.BE],r:10},{cN:"string",b:/(u|r|ur)"/,e:/"/,c:[a.BE],r:10},{cN:"string",b:/(b|br)'/,e:/'/,c:[a.BE]},{cN:"string",b:/(b|br)"/,e:/"/,c:[a.BE]}].concat([a.ASM,a.QSM]);var e={cN:"title",b:a.UIR};var d={cN:"params",b:/\(/,e:/\)/,c:["self",a.CNM,f].concat(c)};var b={bWK:true,e:/:/,i:/[${=;\n]/,c:[e,d],r:10};return{k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10",built_in:"None True False Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:c.concat([f,a.HCM,a.inherit(b,{cN:"function",k:"def"}),a.inherit(b,{cN:"class",k:"class"}),a.CNM,{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}])}}(hljs);hljs.LANGUAGES.r=function(a){var b="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[a.HCM,{b:b,l:b,k:{keyword:"function if in break next repeat else for return switch while try tryCatch|10 stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...|10",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",b:'"',e:'"',c:[a.BE],r:0},{cN:"string",b:"'",e:"'",c:[a.BE],r:0}]}}(hljs);hljs.LANGUAGES.rib=function(a){return{k:"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd",i:"</",c:[a.HCM,a.CNM,a.ASM,a.QSM]}}(hljs);hljs.LANGUAGES.rsl=function(a){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,a.ASM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"shader",bWK:true,e:"\\(",k:"surface displacement light volume imager"},{cN:"shading",bWK:true,e:"\\(",k:"illuminate illuminance gather"}]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.ruleslanguage=function(a){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEMASK|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN DELETE SAVE SAVE_UPDATE CLEAR DETERMINANT LABEL REPORT REVENUE ABORT CALL DONE LEAVE EACH IN LIST NOVALUE FROM TOTAL CHARGE BLOCK AND OR CSV_FILE BILL_PERIOD RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM ABORT WARN NUMDAYS RATE_CODE READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}}(hljs);hljs.LANGUAGES.rust=function(b){var d={cN:"title",b:b.UIR};var c={cN:"number",b:"\\b(0[xb][A-Za-z0-9_]+|[0-9_]+(\\.[0-9_]+)?([uif](8|16|32|64)?)?)",r:0};var a="assert bool break char check claim comm const cont copy dir do drop else enum extern export f32 f64 fail false float fn for i16 i32 i64 i8 if impl int let log loop match mod move mut priv pub pure ref return self static str struct task true trait type u16 u32 u64 u8 uint unsafe use vec while";return{k:a,i:"</",c:[b.CLCM,b.CBLCLM,b.inherit(b.QSM,{i:null}),b.ASM,c,{cN:"function",bWK:true,e:"(\\(|<)",k:"fn",c:[d]},{cN:"preprocessor",b:"#\\[",e:"\\]"},{bWK:true,e:"(=|<)",k:"type",c:[d],i:"\\S"},{bWK:true,e:"({|<)",k:"trait enum",c:[d],i:"\\S"}]}}(hljs);hljs.LANGUAGES.scala=function(a){var c={cN:"annotation",b:"@[A-Za-z]+"};var b={cN:"string",b:'u?r?"""',e:'"""',r:10};return{k:"type yield lazy override def with val var false true sealed abstract private trait object null if for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,b,{cN:"class",b:"((case )?class |object |trait )",e:"({|$)",i:":",k:"case class trait object",c:[{bWK:true,k:"extends with",r:10},{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,b,c]}]},a.CNM,c]}}(hljs);hljs.LANGUAGES.scss=function(a){var c="[a-zA-Z-][a-zA-Z0-9_-]*";var d={cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};var b={cN:"hexcolor",b:"#[0-9A-Fa-f]+"};var e={cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[d,b,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"important",b:"!important"}]}};return{cI:true,i:"[=/|']",c:[a.CLCM,a.CBLCLM,{cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]},{cN:"id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{cN:"pseudo",b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{cN:"pseudo",b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{cN:"value",b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{cN:"value",b:":",e:";",c:[b,a.NM,a.QSM,a.ASM,{cN:"important",b:"!important"}]},{cN:"at_rule",b:"@",e:"[{;]",k:"mixin include for extend charset import media page font-face namespace",c:[d,a.QSM,a.ASM,b,a.NM,{cN:"preprocessor",b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}}(hljs);hljs.LANGUAGES.smalltalk=function(a){var b="[a-z][a-zA-Z0-9_]*";var d={cN:"char",b:"\\$.{1}"};var c={cN:"symbol",b:"#"+a.UIR};return{k:"self super nil true false thisContext",c:[{cN:"comment",b:'"',e:'"',r:0},a.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:b+":"},a.CNM,c,d,{cN:"localvars",b:"\\|\\s*"+b+"(\\s+"+b+")*\\s*\\|"},{cN:"array",b:"\\#\\(",e:"\\)",c:[a.ASM,d,a.CNM,c]}]}}(hljs);hljs.LANGUAGES.sql=function(a){return{cI:true,c:[{cN:"operator",b:"(begin|end|start|commit|rollback|savepoint|lock|alter|create|drop|rename|call|delete|do|handler|insert|load|replace|select|truncate|update|set|show|pragma|grant)\\b(?!:)",e:";",eW:true,k:{keyword:"all partial global month current_timestamp using go revoke smallint indicator end-exec disconnect zone with character assertion to add current_user usage input local alter match collate real then rollback get read timestamp session_user not integer bit unique day minute desc insert execute like ilike|2 level decimal drop continue isolation found where constraints domain right national some module transaction relative second connect escape close system_user for deferred section cast current sqlstate allocate intersect deallocate numeric public preserve full goto initially asc no key output collation group by union session both last language constraint column of space foreign deferrable prior connection unknown action commit view or first into float year primary cascaded except restrict set references names table outer open select size are rows from prepare distinct leading create only next inner authorization schema corresponding option declare precision immediate else timezone_minute external varying translation true case exception join hour default double scroll value cursor descriptor values dec fetch procedure delete and false int is describe char as at in varchar null trailing any absolute current_time end grant privileges when cross check write current_date pad begin temporary exec time update catalog user sql date on identity timezone_hour natural whenever interval work order cascade diagnostics nchar having left call do handler load replace truncate start lock show pragma exists number trigger if before after each row",aggregate:"count sum min max avg"},c:[{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0},{cN:"string",b:'"',e:'"',c:[a.BE,{b:'""'}],r:0},{cN:"string",b:"`",e:"`",c:[a.BE]},a.CNM]},a.CBLCLM,{cN:"comment",b:"--",e:"$"}]}}(hljs);hljs.LANGUAGES.tex=function(a){var d={cN:"command",b:"\\\\[a-zA-Zа-яА-я]+[\\*]?"};var c={cN:"command",b:"\\\\[^a-zA-Zа-яА-я0-9]"};var b={cN:"special",b:"[{}\\[\\]\\&#~]",r:0};return{c:[{b:"\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",rB:true,c:[d,c,{cN:"number",b:" *=",e:"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",eB:true}],r:10},d,c,b,{cN:"formula",b:"\\$\\$",e:"\\$\\$",c:[d,c,b],r:0},{cN:"formula",b:"\\$",e:"\\$",c:[d,c,b],r:0},{cN:"comment",b:"%",e:"$",r:0}]}}(hljs);hljs.LANGUAGES.vala=function(a){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object",literal:"false true null"},c:[{cN:"class",bWK:true,e:"{",k:"class interface delegate namespace",i:"[^,:\\n\\s\\.]",c:[{cN:"title",b:a.UIR}]},a.CLCM,a.CBLCLM,{cN:"string",b:'"""',e:'"""',r:5},a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"^#",e:"$",r:2},{cN:"constant",b:" [A-Z_]+ ",r:0}]}}(hljs);hljs.LANGUAGES.vbnet=function(a){return{cI:true,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"(//|endif|gosub|variant|wend)",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"'''|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"},]},a.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end region externalsource"},]}}(hljs);hljs.LANGUAGES.vbscript=function(a){return{cI:true,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$"},a.CNM]}}(hljs);hljs.LANGUAGES.vhdl=function(a){return{cI:true,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",typename:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[a.CBLCLM,{cN:"comment",b:"--",e:"$"},a.QSM,a.CNM,{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[a.BE]},{cN:"attribute",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[a.BE]}]}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);
diff --git a/docs/slides/flops14/reveal.js/plugin/leap/leap.js b/docs/slides/flops14/reveal.js/plugin/leap/leap.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/leap/leap.js
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2013, Leap Motion, Inc.
+ * 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 HOLDER 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.
+ *
+ * Version 0.2.0 - http://js.leapmotion.com/0.2.0/leap.min.js
+ * Grab latest versions from http://js.leapmotion.com/
+ */
+
+!function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i}({1:[function(require,module,exports){var chooseProtocol=require("./protocol").chooseProtocol,EventEmitter=require("events").EventEmitter,_=require("underscore");var BaseConnection=module.exports=function(opts){this.opts=_.defaults(opts||{},{host:"127.0.0.1",enableGestures:false,port:6437,enableHeartbeat:true,heartbeatInterval:100,requestProtocolVersion:3});this.host=opts.host;this.port=opts.port;this.on("ready",function(){this.enableGestures(this.opts.enableGestures);if(this.opts.enableHeartbeat)this.startHeartbeat()});this.on("disconnect",function(){if(this.opts.enableHeartbeat)this.stopHeartbeat()});this.heartbeatTimer=null};BaseConnection.prototype.getUrl=function(){return"ws://"+this.host+":"+this.port+"/v"+this.opts.requestProtocolVersion+".json"};BaseConnection.prototype.sendHeartbeat=function(){if(this.protocol){this.setHeartbeatState(true);this.protocol.sendHeartbeat(this)}};BaseConnection.prototype.handleOpen=function(){this.emit("connect")};BaseConnection.prototype.enableGestures=function(enabled){this.gesturesEnabled=enabled?true:false;this.send(this.protocol.encode({enableGestures:this.gesturesEnabled}))};BaseConnection.prototype.handleClose=function(){this.disconnect();this.startReconnection()};BaseConnection.prototype.startReconnection=function(){var connection=this;setTimeout(function(){connection.connect()},1e3)};BaseConnection.prototype.disconnect=function(){if(!this.socket)return;this.socket.close();delete this.socket;delete this.protocol;this.emit("disconnect")};BaseConnection.prototype.handleData=function(data){var message=JSON.parse(data);var messageEvent;if(this.protocol===undefined){messageEvent=this.protocol=chooseProtocol(message);this.emit("ready")}else{messageEvent=this.protocol(message)}this.emit(messageEvent.type,messageEvent)};BaseConnection.prototype.connect=function(){if(this.socket)return;this.socket=this.setupSocket();return true};BaseConnection.prototype.send=function(data){this.socket.send(data)};BaseConnection.prototype.stopHeartbeat=function(){if(!this.heartbeatTimer)return;clearInterval(this.heartbeatTimer);delete this.heartbeatTimer;this.setHeartbeatState(false)};BaseConnection.prototype.setHeartbeatState=function(state){if(this.heartbeatState===state)return;this.heartbeatState=state;this.emit(this.heartbeatState?"focus":"blur")};_.extend(BaseConnection.prototype,EventEmitter.prototype)},{"./protocol":12,events:17,underscore:20}],2:[function(require,module,exports){var CircularBuffer=module.exports=function(size){this.pos=0;this._buf=[];this.size=size};CircularBuffer.prototype.get=function(i){if(i==undefined)i=0;if(i>=this.size)return undefined;if(i>=this._buf.length)return undefined;return this._buf[(this.pos-i-1)%this.size]};CircularBuffer.prototype.push=function(o){this._buf[this.pos%this.size]=o;return this.pos++}},{}],3:[function(require,module,exports){var Connection=module.exports=require("./base_connection");Connection.prototype.setupSocket=function(){var connection=this;var socket=new WebSocket(this.getUrl());socket.onopen=function(){connection.handleOpen()};socket.onmessage=function(message){connection.handleData(message.data)};socket.onclose=function(){connection.handleClose()};return socket};Connection.prototype.startHeartbeat=function(){if(!this.protocol.sendHeartbeat||this.heartbeatTimer)return;var connection=this;var propertyName=null;if(typeof document.hidden!=="undefined"){propertyName="hidden"}else if(typeof document.mozHidden!=="undefined"){propertyName="mozHidden"}else if(typeof document.msHidden!=="undefined"){propertyName="msHidden"}else if(typeof document.webkitHidden!=="undefined"){propertyName="webkitHidden"}else{propertyName=undefined}var windowVisible=true;var focusListener=window.addEventListener("focus",function(e){windowVisible=true});var blurListener=window.addEventListener("blur",function(e){windowVisible=false});this.on("disconnect",function(){if(connection.heartbeatTimer){clearTimeout(connection.heartbeatTimer);delete connection.heartbeatTimer}window.removeEventListener(focusListener);window.removeEventListener(blurListener)});this.heartbeatTimer=setInterval(function(){var isVisible=propertyName===undefined?true:document[propertyName]===false;if(isVisible&&windowVisible){connection.sendHeartbeat()}else{connection.setHeartbeatState(false)}},this.opts.heartbeatInterval)}},{"./base_connection":1}],4:[function(require,module,exports){!function(process){var Frame=require("./frame"),CircularBuffer=require("./circular_buffer"),Pipeline=require("./pipeline"),EventEmitter=require("events").EventEmitter,gestureListener=require("./gesture").gestureListener,_=require("underscore");var Controller=module.exports=function(opts){var inNode=typeof process!=="undefined"&&process.title==="node";opts=_.defaults(opts||{},{inNode:inNode});this.inNode=opts.inNode;opts=_.defaults(opts||{},{frameEventName:this.useAnimationLoop()?"animationFrame":"deviceFrame",supressAnimationLoop:false});this.supressAnimationLoop=opts.supressAnimationLoop;this.frameEventName=opts.frameEventName;this.history=new CircularBuffer(200);this.lastFrame=Frame.Invalid;this.lastValidFrame=Frame.Invalid;this.lastConnectionFrame=Frame.Invalid;this.accumulatedGestures=[];if(opts.connectionType===undefined){this.connectionType=this.inBrowser()?require("./connection"):require("./node_connection")}else{this.connectionType=opts.connectionType}this.connection=new this.connectionType(opts);this.setupConnectionEvents()};Controller.prototype.gesture=function(type,cb){var creator=gestureListener(this,type);if(cb!==undefined){creator.stop(cb)}return creator};Controller.prototype.inBrowser=function(){return!this.inNode};Controller.prototype.useAnimationLoop=function(){return this.inBrowser()&&typeof chrome==="undefined"};Controller.prototype.connect=function(){var controller=this;if(this.connection.connect()&&this.inBrowser()&&!controller.supressAnimationLoop){var callback=function(){controller.emit("animationFrame",controller.lastConnectionFrame);window.requestAnimFrame(callback)};window.requestAnimFrame(callback)}};Controller.prototype.disconnect=function(){this.connection.disconnect()};Controller.prototype.frame=function(num){return this.history.get(num)||Frame.Invalid};Controller.prototype.loop=function(callback){switch(callback.length){case 1:this.on(this.frameEventName,callback);break;case 2:var controller=this;var scheduler=null;var immediateRunnerCallback=function(frame){callback(frame,function(){if(controller.lastFrame!=frame){immediateRunnerCallback(controller.lastFrame)}else{controller.once(controller.frameEventName,immediateRunnerCallback)}})};this.once(this.frameEventName,immediateRunnerCallback);break}this.connect()};Controller.prototype.addStep=function(step){if(!this.pipeline)this.pipeline=new Pipeline(this);this.pipeline.addStep(step)};Controller.prototype.processFrame=function(frame){if(frame.gestures){this.accumulatedGestures=this.accumulatedGestures.concat(frame.gestures)}if(this.pipeline){frame=this.pipeline.run(frame);if(!frame)frame=Frame.Invalid}this.lastConnectionFrame=frame;this.emit("deviceFrame",frame)};Controller.prototype.processFinishedFrame=function(frame){this.lastFrame=frame;if(frame.valid){this.lastValidFrame=frame}frame.controller=this;frame.historyIdx=this.history.push(frame);if(frame.gestures){frame.gestures=this.accumulatedGestures;this.accumulatedGestures=[];for(var gestureIdx=0;gestureIdx!=frame.gestures.length;gestureIdx++){this.emit("gesture",frame.gestures[gestureIdx],frame)}}this.emit("frame",frame)};Controller.prototype.setupConnectionEvents=function(){var controller=this;this.connection.on("frame",function(frame){controller.processFrame(frame)});this.on(this.frameEventName,function(frame){controller.processFinishedFrame(frame)});this.connection.on("disconnect",function(){controller.emit("disconnect")});this.connection.on("ready",function(){controller.emit("ready")});this.connection.on("connect",function(){controller.emit("connect")});this.connection.on("focus",function(){controller.emit("focus")});this.connection.on("blur",function(){controller.emit("blur")});this.connection.on("protocol",function(protocol){controller.emit("protocol",protocol)});this.connection.on("deviceConnect",function(evt){controller.emit(evt.state?"deviceConnected":"deviceDisconnected")})};_.extend(Controller.prototype,EventEmitter.prototype)}(require("__browserify_process"))},{"./circular_buffer":2,"./connection":3,"./frame":5,"./gesture":6,"./node_connection":16,"./pipeline":10,__browserify_process:18,events:17,underscore:20}],5:[function(require,module,exports){var Hand=require("./hand"),Pointable=require("./pointable"),createGesture=require("./gesture").createGesture,glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,InteractionBox=require("./interaction_box"),_=require("underscore");var Frame=module.exports=function(data){this.valid=true;this.id=data.id;this.timestamp=data.timestamp;this.hands=[];this.handsMap={};this.pointables=[];this.tools=[];this.fingers=[];if(data.interactionBox){this.interactionBox=new InteractionBox(data.interactionBox)}this.gestures=[];this.pointablesMap={};this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.data=data;this.type="frame";this.currentFrameRate=data.currentFrameRate;var handMap={};for(var handIdx=0,handCount=data.hands.length;handIdx!=handCount;handIdx++){var hand=new Hand(data.hands[handIdx]);hand.frame=this;this.hands.push(hand);this.handsMap[hand.id]=hand;handMap[hand.id]=handIdx}for(var pointableIdx=0,pointableCount=data.pointables.length;pointableIdx!=pointableCount;pointableIdx++){var pointable=new Pointable(data.pointables[pointableIdx]);pointable.frame=this;this.pointables.push(pointable);this.pointablesMap[pointable.id]=pointable;(pointable.tool?this.tools:this.fingers).push(pointable);if(pointable.handId!==undefined&&handMap.hasOwnProperty(pointable.handId)){var hand=this.hands[handMap[pointable.handId]];hand.pointables.push(pointable);(pointable.tool?hand.tools:hand.fingers).push(pointable)}}if(data.gestures){for(var gestureIdx=0,gestureCount=data.gestures.length;gestureIdx!=gestureCount;gestureIdx++){this.gestures.push(createGesture(data.gestures[gestureIdx]))}}};Frame.prototype.tool=function(id){var pointable=this.pointable(id);return pointable.tool?pointable:Pointable.Invalid};Frame.prototype.pointable=function(id){return this.pointablesMap[id]||Pointable.Invalid};Frame.prototype.finger=function(id){var pointable=this.pointable(id);return!pointable.tool?pointable:Pointable.Invalid};Frame.prototype.hand=function(id){return this.handsMap[id]||Hand.Invalid};Frame.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Frame.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceFrame._rotation[5],this._rotation[2]-sinceFrame._rotation[6],this._rotation[3]-sinceFrame._rotation[1]])};Frame.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);return mat3.multiply(mat3.create(),sinceFrame._rotation,transpose)};Frame.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;return Math.exp(this._scaleFactor-sinceFrame._scaleFactor)};Frame.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.subtract(vec3.create(),this._translation,sinceFrame._translation)};Frame.prototype.toString=function(){var str="Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")";if(this.gestures)str+=" | Gesture count:("+this.gestures.length+")";str+=" ]";return str};Frame.prototype.dump=function(){var out="";out+="Frame Info:<br/>";out+=this.toString();out+="<br/><br/>Hands:<br/>";for(var handIdx=0,handCount=this.hands.length;handIdx!=handCount;handIdx++){out+="  "+this.hands[handIdx].toString()+"<br/>"}out+="<br/><br/>Pointables:<br/>";for(var pointableIdx=0,pointableCount=this.pointables.length;pointableIdx!=pointableCount;pointableIdx++){out+="  "+this.pointables[pointableIdx].toString()+"<br/>"}if(this.gestures){out+="<br/><br/>Gestures:<br/>";for(var gestureIdx=0,gestureCount=this.gestures.length;gestureIdx!=gestureCount;gestureIdx++){out+="  "+this.gestures[gestureIdx].toString()+"<br/>"}}out+="<br/><br/>Raw JSON:<br/>";out+=JSON.stringify(this.data);return out};Frame.Invalid={valid:false,hands:[],fingers:[],tools:[],gestures:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},hand:function(){return Hand.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"gl-matrix":19,underscore:20}],6:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3,EventEmitter=require("events").EventEmitter,_=require("underscore");var createGesture=exports.createGesture=function(data){var gesture;switch(data.type){case"circle":gesture=new CircleGesture(data);break;case"swipe":gesture=new SwipeGesture(data);break;case"screenTap":gesture=new ScreenTapGesture(data);break;case"keyTap":gesture=new KeyTapGesture(data);break;default:throw"unkown gesture type"}gesture.id=data.id;gesture.handIds=data.handIds;gesture.pointableIds=data.pointableIds;gesture.duration=data.duration;gesture.state=data.state;gesture.type=data.type;return gesture};var gestureListener=exports.gestureListener=function(controller,type){var handlers={};var gestureMap={};var gestureCreator=function(){var candidateGesture=gestureMap[gesture.id];if(candidateGesture!==undefined)gesture.update(gesture,frame);if(gesture.state=="start"||gesture.state=="stop"){if(type==gesture.type&&gestureMap[gesture.id]===undefined){gestureMap[gesture.id]=new Gesture(gesture,frame);gesture.update(gesture,frame)}if(gesture.state=="stop"){delete gestureMap[gesture.id]}}};controller.on("gesture",function(gesture,frame){if(gesture.type==type){if(gesture.state=="start"||gesture.state=="stop"){if(gestureMap[gesture.id]===undefined){var gestureTracker=new Gesture(gesture,frame);gestureMap[gesture.id]=gestureTracker;_.each(handlers,function(cb,name){gestureTracker.on(name,cb)})}}gestureMap[gesture.id].update(gesture,frame);if(gesture.state=="stop"){delete gestureMap[gesture.id]}}});var builder={start:function(cb){handlers["start"]=cb;return builder},stop:function(cb){handlers["stop"]=cb;return builder},complete:function(cb){handlers["stop"]=cb;return builder},update:function(cb){handlers["update"]=cb;return builder}};return builder};var Gesture=exports.Gesture=function(gesture,frame){this.gestures=[gesture];this.frames=[frame]};Gesture.prototype.update=function(gesture,frame){this.gestures.push(gesture);this.frames.push(frame);this.emit(gesture.state,this)};_.extend(Gesture.prototype,EventEmitter.prototype);var CircleGesture=function(data){this.center=data.center;this.normal=data.normal;this.progress=data.progress;this.radius=data.radius};CircleGesture.prototype.toString=function(){return"CircleGesture ["+JSON.stringify(this)+"]"};var SwipeGesture=function(data){this.startPosition=data.startPosition;this.position=data.position;this.direction=data.direction;this.speed=data.speed};SwipeGesture.prototype.toString=function(){return"SwipeGesture ["+JSON.stringify(this)+"]"};var ScreenTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};ScreenTapGesture.prototype.toString=function(){return"ScreenTapGesture ["+JSON.stringify(this)+"]"};var KeyTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};KeyTapGesture.prototype.toString=function(){return"KeyTapGesture ["+JSON.stringify(this)+"]"}},{events:17,"gl-matrix":19,underscore:20}],7:[function(require,module,exports){var Pointable=require("./pointable"),glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,_=require("underscore");var Hand=module.exports=function(data){this.id=data.id;this.palmPosition=data.palmPosition;this.direction=data.direction;this.palmVelocity=data.palmVelocity;this.palmNormal=data.palmNormal;this.sphereCenter=data.sphereCenter;this.sphereRadius=data.sphereRadius;this.valid=true;this.pointables=[];this.fingers=[];this.tools=[];this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.timeVisible=data.timeVisible;this.stabilizedPalmPosition=data.stabilizedPalmPosition};Hand.prototype.finger=function(id){var finger=this.frame.finger(id);return finger&&finger.handId==this.id?finger:Pointable.Invalid};Hand.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Hand.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceHand._rotation[5],this._rotation[2]-sinceHand._rotation[6],this._rotation[3]-sinceHand._rotation[1]])};Hand.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);var m=mat3.multiply(mat3.create(),sinceHand._rotation,transpose);return m};Hand.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 1;return Math.exp(this._scaleFactor-sinceHand._scaleFactor)};Hand.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return[this._translation[0]-sinceHand._translation[0],this._translation[1]-sinceHand._translation[1],this._translation[2]-sinceHand._translation[2]]};Hand.prototype.toString=function(){return"Hand [ id: "+this.id+" | palm velocity:"+this.palmVelocity+" | sphere center:"+this.sphereCenter+" ] "};Hand.Invalid={valid:false,fingers:[],tools:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./pointable":11,"gl-matrix":19,underscore:20}],8:[function(require,module,exports){!function(){module.exports={Controller:require("./controller"),Frame:require("./frame"),Gesture:require("./gesture"),Hand:require("./hand"),Pointable:require("./pointable"),InteractionBox:require("./interaction_box"),Connection:require("./connection"),CircularBuffer:require("./circular_buffer"),UI:require("./ui"),glMatrix:require("gl-matrix"),mat3:require("gl-matrix").mat3,vec3:require("gl-matrix").vec3,loopController:undefined,loop:function(opts,callback){if(callback===undefined){callback=opts;opts={}}if(!this.loopController)this.loopController=new this.Controller(opts);this.loopController.loop(callback)}}}()},{"./circular_buffer":2,"./connection":3,"./controller":4,"./frame":5,"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"./ui":13,"gl-matrix":19}],9:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var InteractionBox=module.exports=function(data){this.valid=true;this.center=data.center;this.size=data.size;this.width=data.size[0];this.height=data.size[1];this.depth=data.size[2]};InteractionBox.prototype.denormalizePoint=function(normalizedPosition){return vec3.fromValues((normalizedPosition[0]-.5)*this.size[0]+this.center[0],(normalizedPosition[1]-.5)*this.size[1]+this.center[1],(normalizedPosition[2]-.5)*this.size[2]+this.center[2])};InteractionBox.prototype.normalizePoint=function(position,clamp){var vec=vec3.fromValues((position[0]-this.center[0])/this.size[0]+.5,(position[1]-this.center[1])/this.size[1]+.5,(position[2]-this.center[2])/this.size[2]+.5);if(clamp){vec[0]=Math.min(Math.max(vec[0],0),1);vec[1]=Math.min(Math.max(vec[1],0),1);vec[2]=Math.min(Math.max(vec[2],0),1)}return vec};InteractionBox.prototype.toString=function(){return"InteractionBox [ width:"+this.width+" | height:"+this.height+" | depth:"+this.depth+" ]"};InteractionBox.Invalid={valid:false}},{"gl-matrix":19}],10:[function(require,module,exports){var Pipeline=module.exports=function(){this.steps=[]};Pipeline.prototype.addStep=function(step){this.steps.push(step)};Pipeline.prototype.run=function(frame){var stepsLength=this.steps.length;for(var i=0;i!=stepsLength;i++){if(!frame)break;frame=this.steps[i](frame)}return frame}},{}],11:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var Pointable=module.exports=function(data){this.valid=true;this.id=data.id;this.handId=data.handId;this.length=data.length;this.tool=data.tool;this.width=data.width;this.direction=data.direction;this.stabilizedTipPosition=data.stabilizedTipPosition;this.tipPosition=data.tipPosition;this.tipVelocity=data.tipVelocity;this.touchZone=data.touchZone;this.touchDistance=data.touchDistance;this.timeVisible=data.timeVisible};Pointable.prototype.toString=function(){if(this.tool==true){return"Pointable [ id:"+this.id+" "+this.length+"mmx | with:"+this.width+"mm | direction:"+this.direction+" ]"}else{return"Pointable [ id:"+this.id+" "+this.length+"mmx | direction: "+this.direction+" ]"}};Pointable.Invalid={valid:false}},{"gl-matrix":19}],12:[function(require,module,exports){var Frame=require("./frame");var Event=function(data){this.type=data.type;this.state=data.state};var chooseProtocol=exports.chooseProtocol=function(header){var protocol;switch(header.version){case 1:protocol=JSONProtocol(1,function(data){return new Frame(data)});break;case 2:protocol=JSONProtocol(2,function(data){return new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;case 3:protocol=JSONProtocol(3,function(data){return data.event?new Event(data.event):new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;default:throw"unrecognized version"}return protocol};var JSONProtocol=function(version,cb){var protocol=cb;protocol.encode=function(message){return JSON.stringify(message)};protocol.version=version;protocol.versionLong="Version "+version;protocol.type="protocol";return protocol}},{"./frame":5}],13:[function(require,module,exports){exports.UI={Region:require("./ui/region"),Cursor:require("./ui/cursor")}},{"./ui/cursor":14,"./ui/region":15}],14:[function(require,module,exports){var Cursor=module.exports=function(){return function(frame){var pointable=frame.pointables.sort(function(a,b){return a.z-b.z})[0];if(pointable&&pointable.valid){frame.cursorPosition=pointable.tipPosition}return frame}}},{}],15:[function(require,module,exports){var EventEmitter=require("events").EventEmitter,_=require("underscore");var Region=module.exports=function(start,end){this.start=new Vector(start);this.end=new Vector(end);this.enteredFrame=null};Region.prototype.hasPointables=function(frame){for(var i=0;i!=frame.pointables.length;i++){var position=frame.pointables[i].tipPosition;if(position.x>=this.start.x&&position.x<=this.end.x&&position.y>=this.start.y&&position.y<=this.end.y&&position.z>=this.start.z&&position.z<=this.end.z){return true}}return false};Region.prototype.listener=function(opts){var region=this;if(opts&&opts.nearThreshold)this.setupNearRegion(opts.nearThreshold);return function(frame){return region.updatePosition(frame)}};Region.prototype.clipper=function(){var region=this;return function(frame){region.updatePosition(frame);return region.enteredFrame?frame:null}};Region.prototype.setupNearRegion=function(distance){var nearRegion=this.nearRegion=new Region([this.start.x-distance,this.start.y-distance,this.start.z-distance],[this.end.x+distance,this.end.y+distance,this.end.z+distance]);var region=this;nearRegion.on("enter",function(frame){region.emit("near",frame)});nearRegion.on("exit",function(frame){region.emit("far",frame)});region.on("exit",function(frame){region.emit("near",frame)})};Region.prototype.updatePosition=function(frame){if(this.nearRegion)this.nearRegion.updatePosition(frame);if(this.hasPointables(frame)&&this.enteredFrame==null){this.enteredFrame=frame;this.emit("enter",this.enteredFrame)}else if(!this.hasPointables(frame)&&this.enteredFrame!=null){this.enteredFrame=null;this.emit("exit",this.enteredFrame)}return frame};Region.prototype.normalize=function(position){return new Vector([(position.x-this.start.x)/(this.end.x-this.start.x),(position.y-this.start.y)/(this.end.y-this.start.y),(position.z-this.start.z)/(this.end.z-this.start.z)])};Region.prototype.mapToXY=function(position,width,height){var normalized=this.normalize(position);var x=normalized.x,y=normalized.y;if(x>1)x=1;else if(x<-1)x=-1;if(y>1)y=1;else if(y<-1)y=-1;return[(x+1)/2*width,(1-y)/2*height,normalized.z]};_.extend(Region.prototype,EventEmitter.prototype)},{events:17,underscore:20}],16:[function(require,module,exports){},{}],17:[function(require,module,exports){!function(process){if(!process.EventEmitter)process.EventEmitter=function(){};var EventEmitter=exports.EventEmitter=process.EventEmitter;var isArray=typeof Array.isArray==="function"?Array.isArray:function(xs){return Object.prototype.toString.call(xs)==="[object Array]"};function indexOf(xs,x){if(xs.indexOf)return xs.indexOf(x);for(var i=0;i<xs.length;i++){if(x===xs[i])return i}return-1}var defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!this._events)this._events={};this._events.maxListeners=n};EventEmitter.prototype.emit=function(type){if(type==="error"){if(!this._events||!this._events.error||isArray(this._events.error)&&!this._events.error.length){if(arguments[1]instanceof Error){throw arguments[1]}else{throw new Error("Uncaught, unspecified 'error' event.")}return false}}if(!this._events)return false;var handler=this._events[type];if(!handler)return false;if(typeof handler=="function"){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:var args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}return true}else if(isArray(handler)){var args=Array.prototype.slice.call(arguments,1);var listeners=handler.slice();for(var i=0,l=listeners.length;i<l;i++){listeners[i].apply(this,args)}return true}else{return false}};EventEmitter.prototype.addListener=function(type,listener){if("function"!==typeof listener){throw new Error("addListener only takes instances of Function")}if(!this._events)this._events={};this.emit("newListener",type,listener);if(!this._events[type]){this._events[type]=listener}else if(isArray(this._events[type])){if(!this._events[type].warned){var m;if(this._events.maxListeners!==undefined){m=this._events.maxListeners}else{m=defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);console.trace()}}this._events[type].push(listener)}else{this._events[type]=[this._events[type],listener]}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){var self=this;self.on(type,function g(){self.removeListener(type,g);listener.apply(this,arguments)});return this};EventEmitter.prototype.removeListener=function(type,listener){if("function"!==typeof listener){throw new Error("removeListener only takes instances of Function")}if(!this._events||!this._events[type])return this;var list=this._events[type];if(isArray(list)){var i=indexOf(list,listener);if(i<0)return this;list.splice(i,1);if(list.length==0)delete this._events[type]}else if(this._events[type]===listener){delete this._events[type]}return this};EventEmitter.prototype.removeAllListeners=function(type){if(arguments.length===0){this._events={};return this}if(type&&this._events&&this._events[type])this._events[type]=null;return this};EventEmitter.prototype.listeners=function(type){if(!this._events)this._events={};if(!this._events[type])this._events[type]=[];if(!isArray(this._events[type])){this._events[type]=[this._events[type]]}return this._events[type]}}(require("__browserify_process"))},{__browserify_process:18}],18:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){if(ev.source===window&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}],19:[function(require,module,exports){!function(){!function(){"use strict";var shim={};if(typeof exports==="undefined"){if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){shim.exports={};define(function(){return shim.exports})}else{shim.exports=window}}else{shim.exports=exports}!function(exports){var vec2={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec2.create=function(){return new Float32Array(2)};vec2.clone=function(a){var out=new Float32Array(2);out[0]=a[0];out[1]=a[1];return out};vec2.fromValues=function(x,y){var out=new Float32Array(2);out[0]=x;out[1]=y;return out};vec2.copy=function(out,a){out[0]=a[0];out[1]=a[1];return out};vec2.set=function(out,x,y){out[0]=x;out[1]=y;return out};vec2.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];return out};vec2.sub=vec2.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];return out};vec2.mul=vec2.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];return out};vec2.div=vec2.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];return out};vec2.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);
+out[1]=Math.min(a[1],b[1]);return out};vec2.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);return out};vec2.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;return out};vec2.dist=vec2.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return Math.sqrt(x*x+y*y)};vec2.sqrDist=vec2.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return x*x+y*y};vec2.len=vec2.length=function(a){var x=a[0],y=a[1];return Math.sqrt(x*x+y*y)};vec2.sqrLen=vec2.squaredLength=function(a){var x=a[0],y=a[1];return x*x+y*y};vec2.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];return out};vec2.normalize=function(out,a){var x=a[0],y=a[1];var len=x*x+y*y;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len}return out};vec2.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]};vec2.cross=function(out,a,b){var z=a[0]*b[1]-a[1]*b[0];out[0]=out[1]=0;out[2]=z;return out};vec2.lerp=function(out,a,b,t){var ax=a[0],ay=a[1];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);return out};vec2.transformMat2=function(out,a,m){var x=a[0],y=a[1];out[0]=x*m[0]+y*m[1];out[1]=x*m[2]+y*m[3];return out};vec2.forEach=function(){var vec=new Float32Array(2);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=2}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1]}return a}}();vec2.str=function(a){return"vec2("+a[0]+", "+a[1]+")"};if(typeof exports!=="undefined"){exports.vec2=vec2}var vec3={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec3.create=function(){return new Float32Array(3)};vec3.clone=function(a){var out=new Float32Array(3);out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.fromValues=function(x,y,z){var out=new Float32Array(3);out[0]=x;out[1]=y;out[2]=z;return out};vec3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.set=function(out,x,y,z){out[0]=x;out[1]=y;out[2]=z;return out};vec3.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];return out};vec3.sub=vec3.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];return out};vec3.mul=vec3.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];return out};vec3.div=vec3.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];return out};vec3.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);return out};vec3.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);return out};vec3.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;return out};vec3.dist=vec3.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrDist=vec3.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return x*x+y*y+z*z};vec3.len=vec3.length=function(a){var x=a[0],y=a[1],z=a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrLen=vec3.squaredLength=function(a){var x=a[0],y=a[1],z=a[2];return x*x+y*y+z*z};vec3.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];return out};vec3.normalize=function(out,a){var x=a[0],y=a[1],z=a[2];var len=x*x+y*y+z*z;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len}return out};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};vec3.cross=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2];out[0]=ay*bz-az*by;out[1]=az*bx-ax*bz;out[2]=ax*by-ay*bx;return out};vec3.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);return out};vec3.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12];out[1]=m[1]*x+m[5]*y+m[9]*z+m[13];out[2]=m[2]*x+m[6]*y+m[10]*z+m[14];return out};vec3.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec3.forEach=function(){var vec=new Float32Array(3);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=3}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2]}return a}}();vec3.str=function(a){return"vec3("+a[0]+", "+a[1]+", "+a[2]+")"};if(typeof exports!=="undefined"){exports.vec3=vec3}var vec4={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec4.create=function(){return new Float32Array(4)};vec4.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.fromValues=function(x,y,z,w){var out=new Float32Array(4);out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.set=function(out,x,y,z,w){out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];out[3]=a[3]+b[3];return out};vec4.sub=vec4.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];out[3]=a[3]-b[3];return out};vec4.mul=vec4.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];out[3]=a[3]*b[3];return out};vec4.div=vec4.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];out[3]=a[3]/b[3];return out};vec4.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);out[3]=Math.min(a[3],b[3]);return out};vec4.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);out[3]=Math.max(a[3],b[3]);return out};vec4.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;out[3]=a[3]*b;return out};vec4.dist=vec4.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrDist=vec4.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return x*x+y*y+z*z+w*w};vec4.len=vec4.length=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrLen=vec4.squaredLength=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return x*x+y*y+z*z+w*w};vec4.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=-a[3];return out};vec4.normalize=function(out,a){var x=a[0],y=a[1],z=a[2],w=a[3];var len=x*x+y*y+z*z+w*w;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len;out[3]=a[3]*len}return out};vec4.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]};vec4.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);out[3]=aw+t*(b[3]-aw);return out};vec4.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2],w=a[3];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12]*w;out[1]=m[1]*x+m[5]*y+m[9]*z+m[13]*w;out[2]=m[2]*x+m[6]*y+m[10]*z+m[14]*w;out[3]=m[3]*x+m[7]*y+m[11]*z+m[15]*w;return out};vec4.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec4.forEach=function(){var vec=new Float32Array(4);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=4}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];vec[3]=a[i+3];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2];a[i+3]=vec[3]}return a}}();vec4.str=function(a){return"vec4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.vec4=vec4}var mat2={};var mat2Identity=new Float32Array([1,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat2.create=function(){return new Float32Array(mat2Identity)};mat2.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=1;return out};mat2.transpose=function(out,a){if(out===a){var a1=a[1];out[1]=a[2];out[2]=a1}else{out[0]=a[0];out[1]=a[2];out[2]=a[1];out[3]=a[3]}return out};mat2.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],det=a0*a3-a2*a1;if(!det){return null}det=1/det;out[0]=a3*det;out[1]=-a1*det;out[2]=-a2*det;out[3]=a0*det;return out};mat2.adjoint=function(out,a){var a0=a[0];out[0]=a[3];out[1]=-a[1];out[2]=-a[2];out[3]=a0;return out};mat2.determinant=function(a){return a[0]*a[3]-a[2]*a[1]};mat2.mul=mat2.multiply=function(out,a,b){var a0=a[0],a1=a[1],a2=a[2],a3=a[3];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=a0*b0+a1*b2;out[1]=a0*b1+a1*b3;out[2]=a2*b0+a3*b2;out[3]=a2*b1+a3*b3;return out};mat2.rotate=function(out,a,rad){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],s=Math.sin(rad),c=Math.cos(rad);out[0]=a0*c+a1*s;out[1]=a0*-s+a1*c;out[2]=a2*c+a3*s;out[3]=a2*-s+a3*c;return out};mat2.scale=function(out,a,v){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],v0=v[0],v1=v[1];out[0]=a0*v0;out[1]=a1*v1;out[2]=a2*v0;out[3]=a3*v1;return out};mat2.str=function(a){return"mat2("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.mat2=mat2}var mat3={};var mat3Identity=new Float32Array([1,0,0,0,1,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat3.create=function(){return new Float32Array(mat3Identity)};mat3.clone=function(a){var out=new Float32Array(9);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=1;out[5]=0;out[6]=0;out[7]=0;out[8]=1;return out};mat3.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a12=a[5];out[1]=a[3];out[2]=a[6];out[3]=a01;out[5]=a[7];out[6]=a02;out[7]=a12}else{out[0]=a[0];out[1]=a[3];out[2]=a[6];out[3]=a[1];out[4]=a[4];out[5]=a[7];out[6]=a[2];out[7]=a[5];out[8]=a[8]}return out};mat3.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b01=a22*a11-a12*a21,b11=-a22*a10+a12*a20,b21=a21*a10-a11*a20,det=a00*b01+a01*b11+a02*b21;if(!det){return null}det=1/det;out[0]=b01*det;out[1]=(-a22*a01+a02*a21)*det;out[2]=(a12*a01-a02*a11)*det;out[3]=b11*det;out[4]=(a22*a00-a02*a20)*det;out[5]=(-a12*a00+a02*a10)*det;out[6]=b21*det;out[7]=(-a21*a00+a01*a20)*det;out[8]=(a11*a00-a01*a10)*det;return out};mat3.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];out[0]=a11*a22-a12*a21;out[1]=a02*a21-a01*a22;out[2]=a01*a12-a02*a11;out[3]=a12*a20-a10*a22;out[4]=a00*a22-a02*a20;out[5]=a02*a10-a00*a12;out[6]=a10*a21-a11*a20;out[7]=a01*a20-a00*a21;out[8]=a00*a11-a01*a10;return out};mat3.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];return a00*(a22*a11-a12*a21)+a01*(-a22*a10+a12*a20)+a02*(a21*a10-a11*a20)};mat3.mul=mat3.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b00=b[0],b01=b[1],b02=b[2],b10=b[3],b11=b[4],b12=b[5],b20=b[6],b21=b[7],b22=b[8];out[0]=b00*a00+b01*a10+b02*a20;out[1]=b00*a01+b01*a11+b02*a21;out[2]=b00*a02+b01*a12+b02*a22;out[3]=b10*a00+b11*a10+b12*a20;out[4]=b10*a01+b11*a11+b12*a21;out[5]=b10*a02+b11*a12+b12*a22;out[6]=b20*a00+b21*a10+b22*a20;out[7]=b20*a01+b21*a11+b22*a21;out[8]=b20*a02+b21*a12+b22*a22;return out};mat3.str=function(a){return"mat3("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+")"};if(typeof exports!=="undefined"){exports.mat3=mat3}var mat4={};var mat4Identity=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat4.create=function(){return new Float32Array(mat4Identity)};mat4.clone=function(a){var out=new Float32Array(16);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=1;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=1;out[11]=0;out[12]=0;out[13]=0;out[14]=0;out[15]=1;return out};mat4.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a03=a[3],a12=a[6],a13=a[7],a23=a[11];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a01;out[6]=a[9];out[7]=a[13];out[8]=a02;out[9]=a12;out[11]=a[14];out[12]=a03;out[13]=a13;out[14]=a23}else{out[0]=a[0];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a[1];out[5]=a[5];out[6]=a[9];out[7]=a[13];out[8]=a[2];out[9]=a[6];out[10]=a[10];out[11]=a[14];out[12]=a[3];out[13]=a[7];out[14]=a[11];out[15]=a[15]}return out};mat4.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32,det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;if(!det){return null}det=1/det;out[0]=(a11*b11-a12*b10+a13*b09)*det;out[1]=(a02*b10-a01*b11-a03*b09)*det;out[2]=(a31*b05-a32*b04+a33*b03)*det;out[3]=(a22*b04-a21*b05-a23*b03)*det;out[4]=(a12*b08-a10*b11-a13*b07)*det;out[5]=(a00*b11-a02*b08+a03*b07)*det;out[6]=(a32*b02-a30*b05-a33*b01)*det;out[7]=(a20*b05-a22*b02+a23*b01)*det;out[8]=(a10*b10-a11*b08+a13*b06)*det;out[9]=(a01*b08-a00*b10-a03*b06)*det;out[10]=(a30*b04-a31*b02+a33*b00)*det;out[11]=(a21*b02-a20*b04-a23*b00)*det;out[12]=(a11*b07-a10*b09-a12*b06)*det;out[13]=(a00*b09-a01*b07+a02*b06)*det;out[14]=(a31*b01-a30*b03-a32*b00)*det;out[15]=(a20*b03-a21*b01+a22*b00)*det;return out};mat4.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];out[0]=a11*(a22*a33-a23*a32)-a21*(a12*a33-a13*a32)+a31*(a12*a23-a13*a22);out[1]=-(a01*(a22*a33-a23*a32)-a21*(a02*a33-a03*a32)+a31*(a02*a23-a03*a22));out[2]=a01*(a12*a33-a13*a32)-a11*(a02*a33-a03*a32)+a31*(a02*a13-a03*a12);out[3]=-(a01*(a12*a23-a13*a22)-a11*(a02*a23-a03*a22)+a21*(a02*a13-a03*a12));out[4]=-(a10*(a22*a33-a23*a32)-a20*(a12*a33-a13*a32)+a30*(a12*a23-a13*a22));out[5]=a00*(a22*a33-a23*a32)-a20*(a02*a33-a03*a32)+a30*(a02*a23-a03*a22);out[6]=-(a00*(a12*a33-a13*a32)-a10*(a02*a33-a03*a32)+a30*(a02*a13-a03*a12));out[7]=a00*(a12*a23-a13*a22)-a10*(a02*a23-a03*a22)+a20*(a02*a13-a03*a12);out[8]=a10*(a21*a33-a23*a31)-a20*(a11*a33-a13*a31)+a30*(a11*a23-a13*a21);out[9]=-(a00*(a21*a33-a23*a31)-a20*(a01*a33-a03*a31)+a30*(a01*a23-a03*a21));out[10]=a00*(a11*a33-a13*a31)-a10*(a01*a33-a03*a31)+a30*(a01*a13-a03*a11);out[11]=-(a00*(a11*a23-a13*a21)-a10*(a01*a23-a03*a21)+a20*(a01*a13-a03*a11));out[12]=-(a10*(a21*a32-a22*a31)-a20*(a11*a32-a12*a31)+a30*(a11*a22-a12*a21));out[13]=a00*(a21*a32-a22*a31)-a20*(a01*a32-a02*a31)+a30*(a01*a22-a02*a21);out[14]=-(a00*(a11*a32-a12*a31)-a10*(a01*a32-a02*a31)+a30*(a01*a12-a02*a11));out[15]=a00*(a11*a22-a12*a21)-a10*(a01*a22-a02*a21)+a20*(a01*a12-a02*a11);return out};mat4.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32;return b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06};mat4.mul=mat4.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=b0*a00+b1*a10+b2*a20+b3*a30;out[1]=b0*a01+b1*a11+b2*a21+b3*a31;out[2]=b0*a02+b1*a12+b2*a22+b3*a32;out[3]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[4];b1=b[5];b2=b[6];b3=b[7];out[4]=b0*a00+b1*a10+b2*a20+b3*a30;out[5]=b0*a01+b1*a11+b2*a21+b3*a31;out[6]=b0*a02+b1*a12+b2*a22+b3*a32;out[7]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[8];b1=b[9];b2=b[10];b3=b[11];out[8]=b0*a00+b1*a10+b2*a20+b3*a30;out[9]=b0*a01+b1*a11+b2*a21+b3*a31;out[10]=b0*a02+b1*a12+b2*a22+b3*a32;out[11]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[12];b1=b[13];b2=b[14];b3=b[15];out[12]=b0*a00+b1*a10+b2*a20+b3*a30;out[13]=b0*a01+b1*a11+b2*a21+b3*a31;out[14]=b0*a02+b1*a12+b2*a22+b3*a32;out[15]=b0*a03+b1*a13+b2*a23+b3*a33;return out};mat4.translate=function(out,a,v){var x=v[0],y=v[1],z=v[2],a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23;if(a===out){out[12]=a[0]*x+a[4]*y+a[8]*z+a[12];out[13]=a[1]*x+a[5]*y+a[9]*z+a[13];out[14]=a[2]*x+a[6]*y+a[10]*z+a[14];out[15]=a[3]*x+a[7]*y+a[11]*z+a[15]}else{a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];out[0]=a00;out[1]=a01;out[2]=a02;out[3]=a03;out[4]=a10;out[5]=a11;out[6]=a12;out[7]=a13;out[8]=a20;out[9]=a21;out[10]=a22;out[11]=a23;out[12]=a00*x+a10*y+a20*z+a[12];out[13]=a01*x+a11*y+a21*z+a[13];out[14]=a02*x+a12*y+a22*z+a[14];out[15]=a03*x+a13*y+a23*z+a[15]}return out};mat4.scale=function(out,a,v){var x=v[0],y=v[1],z=v[2];out[0]=a[0]*x;out[1]=a[1]*x;out[2]=a[2]*x;out[3]=a[3]*x;out[4]=a[4]*y;out[5]=a[5]*y;out[6]=a[6]*y;out[7]=a[7]*y;out[8]=a[8]*z;out[9]=a[9]*z;out[10]=a[10]*z;out[11]=a[11]*z;out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.rotate=function(out,a,rad,axis){var x=axis[0],y=axis[1],z=axis[2],len=Math.sqrt(x*x+y*y+z*z),s,c,t,a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23,b00,b01,b02,b10,b11,b12,b20,b21,b22;if(Math.abs(len)<GLMAT_EPSILON){return null}len=1/len;x*=len;y*=len;z*=len;s=Math.sin(rad);c=Math.cos(rad);t=1-c;a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];b00=x*x*t+c;b01=y*x*t+z*s;b02=z*x*t-y*s;b10=x*y*t-z*s;b11=y*y*t+c;b12=z*y*t+x*s;b20=x*z*t+y*s;b21=y*z*t-x*s;b22=z*z*t+c;out[0]=a00*b00+a10*b01+a20*b02;out[1]=a01*b00+a11*b01+a21*b02;out[2]=a02*b00+a12*b01+a22*b02;out[3]=a03*b00+a13*b01+a23*b02;out[4]=a00*b10+a10*b11+a20*b12;out[5]=a01*b10+a11*b11+a21*b12;out[6]=a02*b10+a12*b11+a22*b12;out[7]=a03*b10+a13*b11+a23*b12;out[8]=a00*b20+a10*b21+a20*b22;out[9]=a01*b20+a11*b21+a21*b22;out[10]=a02*b20+a12*b21+a22*b22;out[11]=a03*b20+a13*b21+a23*b22;if(a!==out){out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}return out};mat4.rotateX=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[4]=a10*c+a20*s;out[5]=a11*c+a21*s;out[6]=a12*c+a22*s;out[7]=a13*c+a23*s;out[8]=a20*c-a10*s;out[9]=a21*c-a11*s;out[10]=a22*c-a12*s;out[11]=a23*c-a13*s;return out};mat4.rotateY=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c-a20*s;out[1]=a01*c-a21*s;out[2]=a02*c-a22*s;out[3]=a03*c-a23*s;out[8]=a00*s+a20*c;out[9]=a01*s+a21*c;out[10]=a02*s+a22*c;out[11]=a03*s+a23*c;return out};mat4.rotateZ=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7];if(a!==out){out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c+a10*s;out[1]=a01*c+a11*s;out[2]=a02*c+a12*s;out[3]=a03*c+a13*s;out[4]=a10*c-a00*s;out[5]=a11*c-a01*s;out[6]=a12*c-a02*s;out[7]=a13*c-a03*s;return out};mat4.fromRotationTranslation=function(out,q,v){var x=q[0],y=q[1],z=q[2],w=q[3],x2=x+x,y2=y+y,z2=z+z,xx=x*x2,xy=x*y2,xz=x*z2,yy=y*y2,yz=y*z2,zz=z*z2,wx=w*x2,wy=w*y2,wz=w*z2;out[0]=1-(yy+zz);out[1]=xy+wz;out[2]=xz-wy;out[3]=0;out[4]=xy-wz;out[5]=1-(xx+zz);out[6]=yz+wx;out[7]=0;out[8]=xz+wy;out[9]=yz-wx;out[10]=1-(xx+yy);out[11]=0;out[12]=v[0];out[13]=v[1];out[14]=v[2];out[15]=1;return out};mat4.frustum=function(out,left,right,bottom,top,near,far){var rl=1/(right-left),tb=1/(top-bottom),nf=1/(near-far);out[0]=near*2*rl;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=near*2*tb;out[6]=0;out[7]=0;out[8]=(right+left)*rl;out[9]=(top+bottom)*tb;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=far*near*2*nf;out[15]=0;return out};mat4.perspective=function(out,fovy,aspect,near,far){var f=1/Math.tan(fovy/2),nf=1/(near-far);out[0]=f/aspect;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=f;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=2*far*near*nf;out[15]=0;return out};mat4.ortho=function(out,left,right,bottom,top,near,far){var lr=1/(left-right),bt=1/(bottom-top),nf=1/(near-far);out[0]=-2*lr;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=-2*bt;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=2*nf;out[11]=0;out[12]=(left+right)*lr;out[13]=(top+bottom)*bt;out[14]=(far+near)*nf;out[15]=1;return out};mat4.lookAt=function(out,eye,center,up){var x0,x1,x2,y0,y1,y2,z0,z1,z2,len,eyex=eye[0],eyey=eye[1],eyez=eye[2],upx=up[0],upy=up[1],upz=up[2],centerx=center[0],centery=center[1],centerz=center[2];if(Math.abs(eyex-centerx)<GLMAT_EPSILON&&Math.abs(eyey-centery)<GLMAT_EPSILON&&Math.abs(eyez-centerz)<GLMAT_EPSILON){return mat4.identity(out)}z0=eyex-centerx;z1=eyey-centery;z2=eyez-centerz;len=1/Math.sqrt(z0*z0+z1*z1+z2*z2);z0*=len;z1*=len;z2*=len;x0=upy*z2-upz*z1;x1=upz*z0-upx*z2;x2=upx*z1-upy*z0;len=Math.sqrt(x0*x0+x1*x1+x2*x2);if(!len){x0=0;x1=0;x2=0}else{len=1/len;x0*=len;x1*=len;x2*=len}y0=z1*x2-z2*x1;y1=z2*x0-z0*x2;y2=z0*x1-z1*x0;len=Math.sqrt(y0*y0+y1*y1+y2*y2);if(!len){y0=0;y1=0;y2=0}else{len=1/len;y0*=len;y1*=len;y2*=len}out[0]=x0;out[1]=y0;out[2]=z0;out[3]=0;out[4]=x1;out[5]=y1;out[6]=z1;out[7]=0;out[8]=x2;out[9]=y2;out[10]=z2;out[11]=0;out[12]=-(x0*eyex+x1*eyey+x2*eyez);out[13]=-(y0*eyex+y1*eyey+y2*eyez);out[14]=-(z0*eyex+z1*eyey+z2*eyez);out[15]=1;return out};mat4.str=function(a){return"mat4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+")"};if(typeof exports!=="undefined"){exports.mat4=mat4}var quat={};var quatIdentity=new Float32Array([0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}quat.create=function(){return new Float32Array(quatIdentity)};quat.clone=vec4.clone;quat.fromValues=vec4.fromValues;quat.copy=vec4.copy;quat.set=vec4.set;quat.identity=function(out){out[0]=0;out[1]=0;out[2]=0;out[3]=1;return out};quat.setAxisAngle=function(out,axis,rad){rad=rad*.5;var s=Math.sin(rad);out[0]=s*axis[0];out[1]=s*axis[1];out[2]=s*axis[2];out[3]=Math.cos(rad);return out};quat.add=vec4.add;quat.mul=quat.multiply=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=b[3];out[0]=ax*bw+aw*bx+ay*bz-az*by;out[1]=ay*bw+aw*by+az*bx-ax*bz;out[2]=az*bw+aw*bz+ax*by-ay*bx;out[3]=aw*bw-ax*bx-ay*by-az*bz;return out};quat.scale=vec4.scale;quat.rotateX=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+aw*bx;out[1]=ay*bw+az*bx;out[2]=az*bw-ay*bx;out[3]=aw*bw-ax*bx;return out};quat.rotateY=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],by=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw-az*by;out[1]=ay*bw+aw*by;out[2]=az*bw+ax*by;out[3]=aw*bw-ay*by;return out};quat.rotateZ=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bz=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+ay*bz;out[1]=ay*bw-ax*bz;out[2]=az*bw+aw*bz;out[3]=aw*bw-az*bz;return out};quat.calculateW=function(out,a){var x=a[0],y=a[1],z=a[2];out[0]=x;out[1]=y;out[2]=z;out[3]=-Math.sqrt(Math.abs(1-x*x-y*y-z*z));return out};quat.dot=vec4.dot;quat.lerp=vec4.lerp;quat.slerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=a[3];var cosHalfTheta=ax*bx+ay*by+az*bz+aw*bw,halfTheta,sinHalfTheta,ratioA,ratioB;if(Math.abs(cosHalfTheta)>=1){if(out!==a){out[0]=ax;out[1]=ay;out[2]=az;out[3]=aw}return out}halfTheta=Math.acos(cosHalfTheta);sinHalfTheta=Math.sqrt(1-cosHalfTheta*cosHalfTheta);if(Math.abs(sinHalfTheta)<.001){out[0]=ax*.5+bx*.5;out[1]=ay*.5+by*.5;out[2]=az*.5+bz*.5;out[3]=aw*.5+bw*.5;return out}ratioA=Math.sin((1-t)*halfTheta)/sinHalfTheta;ratioB=Math.sin(t*halfTheta)/sinHalfTheta;out[0]=ax*ratioA+bx*ratioB;out[1]=ay*ratioA+by*ratioB;out[2]=az*ratioA+bz*ratioB;out[3]=aw*ratioA+bw*ratioB;return out};quat.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],dot=a0*a0+a1*a1+a2*a2+a3*a3,invDot=dot?1/dot:0;out[0]=-a0*invDot;out[1]=-a1*invDot;out[2]=-a2*invDot;out[3]=a3*invDot;return out};quat.conjugate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=a[3];return out};quat.len=quat.length=vec4.length;quat.sqrLen=quat.squaredLength=vec4.squaredLength;quat.normalize=vec4.normalize;quat.str=function(a){return"quat("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.quat=quat}}(shim.exports)}()}()},{}],20:[function(require,module,exports){!function(){!function(){var root=this;var previousUnderscore=root._;var breaker={};var ArrayProto=Array.prototype,ObjProto=Object.prototype,FuncProto=Function.prototype;var push=ArrayProto.push,slice=ArrayProto.slice,concat=ArrayProto.concat,toString=ObjProto.toString,hasOwnProperty=ObjProto.hasOwnProperty;var nativeForEach=ArrayProto.forEach,nativeMap=ArrayProto.map,nativeReduce=ArrayProto.reduce,nativeReduceRight=ArrayProto.reduceRight,nativeFilter=ArrayProto.filter,nativeEvery=ArrayProto.every,nativeSome=ArrayProto.some,nativeIndexOf=ArrayProto.indexOf,nativeLastIndexOf=ArrayProto.lastIndexOf,nativeIsArray=Array.isArray,nativeKeys=Object.keys,nativeBind=FuncProto.bind;var _=function(obj){if(obj instanceof _)return obj;if(!(this instanceof _))return new _(obj);this._wrapped=obj};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=_}exports._=_}else{root._=_}_.VERSION="1.4.4";var each=_.each=_.forEach=function(obj,iterator,context){if(obj==null)return;if(nativeForEach&&obj.forEach===nativeForEach){obj.forEach(iterator,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){if(iterator.call(context,obj[i],i,obj)===breaker)return}}else{for(var key in obj){if(_.has(obj,key)){if(iterator.call(context,obj[key],key,obj)===breaker)return}}}};_.map=_.collect=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeMap&&obj.map===nativeMap)return obj.map(iterator,context);each(obj,function(value,index,list){results[results.length]=iterator.call(context,value,index,list)});return results};var reduceError="Reduce of empty array with no initial value";_.reduce=_.foldl=_.inject=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduce&&obj.reduce===nativeReduce){if(context)iterator=_.bind(iterator,context);return initial?obj.reduce(iterator,memo):obj.reduce(iterator)}each(obj,function(value,index,list){if(!initial){memo=value;initial=true}else{memo=iterator.call(context,memo,value,index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.reduceRight=_.foldr=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduceRight&&obj.reduceRight===nativeReduceRight){if(context)iterator=_.bind(iterator,context);return initial?obj.reduceRight(iterator,memo):obj.reduceRight(iterator)}var length=obj.length;if(length!==+length){var keys=_.keys(obj);length=keys.length}each(obj,function(value,index,list){index=keys?keys[--length]:--length;if(!initial){memo=obj[index];initial=true}else{memo=iterator.call(context,memo,obj[index],index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.find=_.detect=function(obj,iterator,context){var result;any(obj,function(value,index,list){if(iterator.call(context,value,index,list)){result=value;return true}});return result};_.filter=_.select=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeFilter&&obj.filter===nativeFilter)return obj.filter(iterator,context);each(obj,function(value,index,list){if(iterator.call(context,value,index,list))results[results.length]=value});return results};_.reject=function(obj,iterator,context){return _.filter(obj,function(value,index,list){return!iterator.call(context,value,index,list)},context)};_.every=_.all=function(obj,iterator,context){iterator||(iterator=_.identity);var result=true;if(obj==null)return result;if(nativeEvery&&obj.every===nativeEvery)return obj.every(iterator,context);each(obj,function(value,index,list){if(!(result=result&&iterator.call(context,value,index,list)))return breaker});return!!result};var any=_.some=_.any=function(obj,iterator,context){iterator||(iterator=_.identity);var result=false;if(obj==null)return result;if(nativeSome&&obj.some===nativeSome)return obj.some(iterator,context);each(obj,function(value,index,list){if(result||(result=iterator.call(context,value,index,list)))return breaker});return!!result};_.contains=_.include=function(obj,target){if(obj==null)return false;if(nativeIndexOf&&obj.indexOf===nativeIndexOf)return obj.indexOf(target)!=-1;return any(obj,function(value){return value===target})};_.invoke=function(obj,method){var args=slice.call(arguments,2);var isFunc=_.isFunction(method);return _.map(obj,function(value){return(isFunc?method:value[method]).apply(value,args)})};_.pluck=function(obj,key){return _.map(obj,function(value){return value[key]})};_.where=function(obj,attrs,first){if(_.isEmpty(attrs))return first?null:[];return _[first?"find":"filter"](obj,function(value){for(var key in attrs){if(attrs[key]!==value[key])return false}return true})};_.findWhere=function(obj,attrs){return _.where(obj,attrs,true)};_.max=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.max.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return-Infinity;var result={computed:-Infinity,value:-Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed>=result.computed&&(result={value:value,computed:computed})});return result.value};_.min=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.min.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return Infinity;var result={computed:Infinity,value:Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed<result.computed&&(result={value:value,computed:computed})});return result.value};_.shuffle=function(obj){var rand;var index=0;var shuffled=[];each(obj,function(value){rand=_.random(index++);shuffled[index-1]=shuffled[rand];shuffled[rand]=value});return shuffled};var lookupIterator=function(value){return _.isFunction(value)?value:function(obj){return obj[value]}};_.sortBy=function(obj,value,context){var iterator=lookupIterator(value);return _.pluck(_.map(obj,function(value,index,list){return{value:value,index:index,criteria:iterator.call(context,value,index,list)}}).sort(function(left,right){var a=left.criteria;
+var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)return-1}return left.index<right.index?-1:1}),"value")};var group=function(obj,value,context,behavior){var result={};var iterator=lookupIterator(value||_.identity);each(obj,function(value,index){var key=iterator.call(context,value,index,obj);behavior(result,key,value)});return result};_.groupBy=function(obj,value,context){return group(obj,value,context,function(result,key,value){(_.has(result,key)?result[key]:result[key]=[]).push(value)})};_.countBy=function(obj,value,context){return group(obj,value,context,function(result,key){if(!_.has(result,key))result[key]=0;result[key]++})};_.sortedIndex=function(array,obj,iterator,context){iterator=iterator==null?_.identity:lookupIterator(iterator);var value=iterator.call(context,obj);var low=0,high=array.length;while(low<high){var mid=low+high>>>1;iterator.call(context,array[mid])<value?low=mid+1:high=mid}return low};_.toArray=function(obj){if(!obj)return[];if(_.isArray(obj))return slice.call(obj);if(obj.length===+obj.length)return _.map(obj,_.identity);return _.values(obj)};_.size=function(obj){if(obj==null)return 0;return obj.length===+obj.length?obj.length:_.keys(obj).length};_.first=_.head=_.take=function(array,n,guard){if(array==null)return void 0;return n!=null&&!guard?slice.call(array,0,n):array[0]};_.initial=function(array,n,guard){return slice.call(array,0,array.length-(n==null||guard?1:n))};_.last=function(array,n,guard){if(array==null)return void 0;if(n!=null&&!guard){return slice.call(array,Math.max(array.length-n,0))}else{return array[array.length-1]}};_.rest=_.tail=_.drop=function(array,n,guard){return slice.call(array,n==null||guard?1:n)};_.compact=function(array){return _.filter(array,_.identity)};var flatten=function(input,shallow,output){each(input,function(value){if(_.isArray(value)){shallow?push.apply(output,value):flatten(value,shallow,output)}else{output.push(value)}});return output};_.flatten=function(array,shallow){return flatten(array,shallow,[])};_.without=function(array){return _.difference(array,slice.call(arguments,1))};_.uniq=_.unique=function(array,isSorted,iterator,context){if(_.isFunction(isSorted)){context=iterator;iterator=isSorted;isSorted=false}var initial=iterator?_.map(array,iterator,context):array;var results=[];var seen=[];each(initial,function(value,index){if(isSorted?!index||seen[seen.length-1]!==value:!_.contains(seen,value)){seen.push(value);results.push(array[index])}});return results};_.union=function(){return _.uniq(concat.apply(ArrayProto,arguments))};_.intersection=function(array){var rest=slice.call(arguments,1);return _.filter(_.uniq(array),function(item){return _.every(rest,function(other){return _.indexOf(other,item)>=0})})};_.difference=function(array){var rest=concat.apply(ArrayProto,slice.call(arguments,1));return _.filter(array,function(value){return!_.contains(rest,value)})};_.zip=function(){var args=slice.call(arguments);var length=_.max(_.pluck(args,"length"));var results=new Array(length);for(var i=0;i<length;i++){results[i]=_.pluck(args,""+i)}return results};_.object=function(list,values){if(list==null)return{};var result={};for(var i=0,l=list.length;i<l;i++){if(values){result[list[i]]=values[i]}else{result[list[i][0]]=list[i][1]}}return result};_.indexOf=function(array,item,isSorted){if(array==null)return-1;var i=0,l=array.length;if(isSorted){if(typeof isSorted=="number"){i=isSorted<0?Math.max(0,l+isSorted):isSorted}else{i=_.sortedIndex(array,item);return array[i]===item?i:-1}}if(nativeIndexOf&&array.indexOf===nativeIndexOf)return array.indexOf(item,isSorted);for(;i<l;i++)if(array[i]===item)return i;return-1};_.lastIndexOf=function(array,item,from){if(array==null)return-1;var hasIndex=from!=null;if(nativeLastIndexOf&&array.lastIndexOf===nativeLastIndexOf){return hasIndex?array.lastIndexOf(item,from):array.lastIndexOf(item)}var i=hasIndex?from:array.length;while(i--)if(array[i]===item)return i;return-1};_.range=function(start,stop,step){if(arguments.length<=1){stop=start||0;start=0}step=arguments[2]||1;var len=Math.max(Math.ceil((stop-start)/step),0);var idx=0;var range=new Array(len);while(idx<len){range[idx++]=start;start+=step}return range};_.bind=function(func,context){if(func.bind===nativeBind&&nativeBind)return nativeBind.apply(func,slice.call(arguments,1));var args=slice.call(arguments,2);return function(){return func.apply(context,args.concat(slice.call(arguments)))}};_.partial=function(func){var args=slice.call(arguments,1);return function(){return func.apply(this,args.concat(slice.call(arguments)))}};_.bindAll=function(obj){var funcs=slice.call(arguments,1);if(funcs.length===0)funcs=_.functions(obj);each(funcs,function(f){obj[f]=_.bind(obj[f],obj)});return obj};_.memoize=function(func,hasher){var memo={};hasher||(hasher=_.identity);return function(){var key=hasher.apply(this,arguments);return _.has(memo,key)?memo[key]:memo[key]=func.apply(this,arguments)}};_.delay=function(func,wait){var args=slice.call(arguments,2);return setTimeout(function(){return func.apply(null,args)},wait)};_.defer=function(func){return _.delay.apply(_,[func,1].concat(slice.call(arguments,1)))};_.throttle=function(func,wait){var context,args,timeout,result;var previous=0;var later=function(){previous=new Date;timeout=null;result=func.apply(context,args)};return function(){var now=new Date;var remaining=wait-(now-previous);context=this;args=arguments;if(remaining<=0){clearTimeout(timeout);timeout=null;previous=now;result=func.apply(context,args)}else if(!timeout){timeout=setTimeout(later,remaining)}return result}};_.debounce=function(func,wait,immediate){var timeout,result;return function(){var context=this,args=arguments;var later=function(){timeout=null;if(!immediate)result=func.apply(context,args)};var callNow=immediate&&!timeout;clearTimeout(timeout);timeout=setTimeout(later,wait);if(callNow)result=func.apply(context,args);return result}};_.once=function(func){var ran=false,memo;return function(){if(ran)return memo;ran=true;memo=func.apply(this,arguments);func=null;return memo}};_.wrap=function(func,wrapper){return function(){var args=[func];push.apply(args,arguments);return wrapper.apply(this,args)}};_.compose=function(){var funcs=arguments;return function(){var args=arguments;for(var i=funcs.length-1;i>=0;i--){args=[funcs[i].apply(this,args)]}return args[0]}};_.after=function(times,func){if(times<=0)return func();return function(){if(--times<1){return func.apply(this,arguments)}}};_.keys=nativeKeys||function(obj){if(obj!==Object(obj))throw new TypeError("Invalid object");var keys=[];for(var key in obj)if(_.has(obj,key))keys[keys.length]=key;return keys};_.values=function(obj){var values=[];for(var key in obj)if(_.has(obj,key))values.push(obj[key]);return values};_.pairs=function(obj){var pairs=[];for(var key in obj)if(_.has(obj,key))pairs.push([key,obj[key]]);return pairs};_.invert=function(obj){var result={};for(var key in obj)if(_.has(obj,key))result[obj[key]]=key;return result};_.functions=_.methods=function(obj){var names=[];for(var key in obj){if(_.isFunction(obj[key]))names.push(key)}return names.sort()};_.extend=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){obj[prop]=source[prop]}}});return obj};_.pick=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));each(keys,function(key){if(key in obj)copy[key]=obj[key]});return copy};_.omit=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));for(var key in obj){if(!_.contains(keys,key))copy[key]=obj[key]}return copy};_.defaults=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){if(obj[prop]==null)obj[prop]=source[prop]}}});return obj};_.clone=function(obj){if(!_.isObject(obj))return obj;return _.isArray(obj)?obj.slice():_.extend({},obj)};_.tap=function(obj,interceptor){interceptor(obj);return obj};var eq=function(a,b,aStack,bStack){if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;if(a instanceof _)a=a._wrapped;if(b instanceof _)b=b._wrapped;var className=toString.call(a);if(className!=toString.call(b))return false;switch(className){case"[object String]":return a==String(b);case"[object Number]":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case"[object Date]":case"[object Boolean]":return+a==+b;case"[object RegExp]":return a.source==b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return false;var length=aStack.length;while(length--){if(aStack[length]==a)return bStack[length]==b}aStack.push(a);bStack.push(b);var size=0,result=true;if(className=="[object Array]"){size=a.length;result=size==b.length;if(result){while(size--){if(!(result=eq(a[size],b[size],aStack,bStack)))break}}}else{var aCtor=a.constructor,bCtor=b.constructor;if(aCtor!==bCtor&&!(_.isFunction(aCtor)&&aCtor instanceof aCtor&&_.isFunction(bCtor)&&bCtor instanceof bCtor)){return false}for(var key in a){if(_.has(a,key)){size++;if(!(result=_.has(b,key)&&eq(a[key],b[key],aStack,bStack)))break}}if(result){for(key in b){if(_.has(b,key)&&!size--)break}result=!size}}aStack.pop();bStack.pop();return result};_.isEqual=function(a,b){return eq(a,b,[],[])};_.isEmpty=function(obj){if(obj==null)return true;if(_.isArray(obj)||_.isString(obj))return obj.length===0;for(var key in obj)if(_.has(obj,key))return false;return true};_.isElement=function(obj){return!!(obj&&obj.nodeType===1)};_.isArray=nativeIsArray||function(obj){return toString.call(obj)=="[object Array]"};_.isObject=function(obj){return obj===Object(obj)};each(["Arguments","Function","String","Number","Date","RegExp"],function(name){_["is"+name]=function(obj){return toString.call(obj)=="[object "+name+"]"}});if(!_.isArguments(arguments)){_.isArguments=function(obj){return!!(obj&&_.has(obj,"callee"))}}if(typeof/./!=="function"){_.isFunction=function(obj){return typeof obj==="function"}}_.isFinite=function(obj){return isFinite(obj)&&!isNaN(parseFloat(obj))};_.isNaN=function(obj){return _.isNumber(obj)&&obj!=+obj};_.isBoolean=function(obj){return obj===true||obj===false||toString.call(obj)=="[object Boolean]"};_.isNull=function(obj){return obj===null};_.isUndefined=function(obj){return obj===void 0};_.has=function(obj,key){return hasOwnProperty.call(obj,key)};_.noConflict=function(){root._=previousUnderscore;return this};_.identity=function(value){return value};_.times=function(n,iterator,context){var accum=Array(n);for(var i=0;i<n;i++)accum[i]=iterator.call(context,i);return accum};_.random=function(min,max){if(max==null){max=min;min=0}return min+Math.floor(Math.random()*(max-min+1))};var entityMap={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};entityMap.unescape=_.invert(entityMap.escape);var entityRegexes={escape:new RegExp("["+_.keys(entityMap.escape).join("")+"]","g"),unescape:new RegExp("("+_.keys(entityMap.unescape).join("|")+")","g")};_.each(["escape","unescape"],function(method){_[method]=function(string){if(string==null)return"";return(""+string).replace(entityRegexes[method],function(match){return entityMap[method][match]})}});_.result=function(object,property){if(object==null)return null;var value=object[property];return _.isFunction(value)?value.call(object):value};_.mixin=function(obj){each(_.functions(obj),function(name){var func=_[name]=obj[name];_.prototype[name]=function(){var args=[this._wrapped];push.apply(args,arguments);return result.call(this,func.apply(_,args))}})};var idCounter=0;_.uniqueId=function(prefix){var id=++idCounter+"";return prefix?prefix+id:id};_.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var noMatch=/(.)^/;var escapes={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"};var escaper=/\\|'|\r|\n|\t|\u2028|\u2029/g;_.template=function(text,data,settings){var render;settings=_.defaults({},settings,_.templateSettings);var matcher=new RegExp([(settings.escape||noMatch).source,(settings.interpolate||noMatch).source,(settings.evaluate||noMatch).source].join("|")+"|$","g");var index=0;var source="__p+='";text.replace(matcher,function(match,escape,interpolate,evaluate,offset){source+=text.slice(index,offset).replace(escaper,function(match){return"\\"+escapes[match]});if(escape){source+="'+\n((__t=("+escape+"))==null?'':_.escape(__t))+\n'"}if(interpolate){source+="'+\n((__t=("+interpolate+"))==null?'':__t)+\n'"}if(evaluate){source+="';\n"+evaluate+"\n__p+='"}index=offset+match.length;return match});source+="';\n";if(!settings.variable)source="with(obj||{}){\n"+source+"}\n";source="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+source+"return __p;\n";try{render=new Function(settings.variable||"obj","_",source)}catch(e){e.source=source;throw e}if(data)return render(data,_);var template=function(data){return render.call(this,data,_)};template.source="function("+(settings.variable||"obj")+"){\n"+source+"}";return template};_.chain=function(obj){return _(obj).chain()};var result=function(obj){return this._chain?_(obj).chain():obj};_.mixin(_);each(["pop","push","reverse","shift","sort","splice","unshift"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){var obj=this._wrapped;method.apply(obj,arguments);if((name=="shift"||name=="splice")&&obj.length===0)delete obj[0];return result.call(this,obj)}});each(["concat","join","slice"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){return result.call(this,method.apply(this._wrapped,arguments))}});_.extend(_.prototype,{chain:function(){this._chain=true;return this},value:function(){return this._wrapped}})}.call(this)}()},{}],21:[function(require,module,exports){window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){window.setTimeout(callback,1e3/60)}}();Leap=require("../lib/index")},{"../lib/index":8}]},{},[21]);
+
+/*
+ * Leap Motion integration for Reveal.js.
+ * James Sun  [sun16]
+ * Rory Hardy [gneatgeek]
+ */
+
+(function () {
+  var body        = document.body,
+      controller  = new Leap.Controller({ enableGestures: true }),
+      lastGesture = 0,
+      leapConfig  = Reveal.getConfig().leap,
+      pointer     = document.createElement( 'div' ),
+      config      = {
+        autoCenter       : true,      // Center pointer around detected position.
+        gestureDelay     : 500,       // How long to delay between gestures.
+        naturalSwipe     : true,      // Swipe as if it were a touch screen.
+        pointerColor     : '#00aaff', // Default color of the pointer.
+        pointerOpacity   : 0.7,       // Default opacity of the pointer.
+        pointerSize      : 15,        // Default minimum height/width of the pointer.
+        pointerTolerance : 120        // Bigger = slower pointer.
+      },
+      entered, enteredPosition, now, size, tipPosition; // Other vars we need later, but don't need to redeclare.
+
+      // Merge user defined settings with defaults
+      if( leapConfig ) {
+        for( key in leapConfig ) {
+          config[key] = leapConfig[key];
+        }
+      }
+
+      pointer.id = 'leap';
+
+      pointer.style.position        = 'absolute';
+      pointer.style.visibility      = 'hidden';
+      pointer.style.zIndex          = 50;
+      pointer.style.opacity         = config.pointerOpacity;
+      pointer.style.backgroundColor = config.pointerColor;
+
+      body.appendChild( pointer );
+
+  // Leap's loop
+  controller.on( 'frame', function ( frame ) {
+    // Timing code to rate limit gesture execution
+    now = new Date().getTime();
+
+    // Pointer: 1 to 2 fingers. Strictly one finger works but may cause innaccuracies.
+    // The innaccuracies were observed on a development model and may not be an issue with consumer models.
+    if( frame.fingers.length > 0 && frame.fingers.length < 3 ) {
+      // Invert direction and multiply by 3 for greater effect.
+      size = -3 * frame.fingers[0].tipPosition[2];
+
+      if( size < config.pointerSize ) {
+        size = config.pointerSize;
+      }
+
+      pointer.style.width        = size     + 'px';
+      pointer.style.height       = size     + 'px';
+      pointer.style.borderRadius = size - 5 + 'px';
+      pointer.style.visibility   = 'visible';
+
+      if( config.autoCenter ) {
+        tipPosition = frame.fingers[0].tipPosition;
+
+        // Check whether the finger has entered the z range of the Leap Motion. Used for the autoCenter option.
+        if( !entered ) {
+          entered         = true;
+          enteredPosition = frame.fingers[0].tipPosition;
+        }
+
+        pointer.style.top =
+          (-1 * (( tipPosition[1] - enteredPosition[1] ) * body.offsetHeight / config.pointerTolerance )) +
+            ( body.offsetHeight / 2 ) + 'px';
+
+        pointer.style.left =
+          (( tipPosition[0] - enteredPosition[0] ) * body.offsetWidth / config.pointerTolerance ) +
+            ( body.offsetWidth / 2 ) + 'px';
+      }
+      else {
+        pointer.style.top  = ( 1 - (( tipPosition[1] - 50) / config.pointerTolerance )) *
+          body.offsetHeight + 'px';
+
+        pointer.style.left = ( tipPosition[0] * body.offsetWidth / config.pointerTolerance ) +
+          ( body.offsetWidth / 2 ) + 'px';
+      }
+    }
+    else {
+      // Hide pointer on exit
+      entered                  = false;
+      pointer.style.visibility = 'hidden';
+    }
+
+    // Gestures
+    if( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) {
+      var gesture = frame.gestures[0];
+
+      // One hand gestures
+      if( frame.hands.length === 1 ) {
+        // Swipe gestures. 3+ fingers.
+        if( frame.fingers.length > 2 && gesture.type === 'swipe' ) {
+          // Define here since some gestures will throw undefined for these.
+          var x = gesture.direction[0],
+              y = gesture.direction[1];
+
+          // Left/right swipe gestures
+          if( Math.abs( x ) > Math.abs( y )) {
+            if( x > 0 ) {
+              config.naturalSwipe ? Reveal.left() : Reveal.right();
+            }
+            else {
+              config.naturalSwipe ? Reveal.right() : Reveal.left();
+            }
+          }
+          // Up/down swipe gestures
+          else {
+            if( y > 0 ) {
+              config.naturalSwipe ? Reveal.down() : Reveal.up();
+            }
+            else {
+              config.naturalSwipe ? Reveal.up() : Reveal.down();
+            }
+          }
+
+          lastGesture = now;
+        }
+      }
+      // Two hand gestures
+      else if( frame.hands.length === 2 ) {
+        // Upward two hand swipe gesture
+        if( gesture.direction[1] > 0 && gesture.type === 'swipe' ) {
+          Reveal.toggleOverview();
+        }
+
+        lastGesture = now;
+      }
+    }
+  });
+
+  controller.connect();
+})();
diff --git a/docs/slides/flops14/reveal.js/plugin/markdown/markdown.js b/docs/slides/flops14/reveal.js/plugin/markdown/markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/markdown/markdown.js
@@ -0,0 +1,392 @@
+/**
+ * The reveal.js markdown plugin. Handles parsing of
+ * markdown inside of presentations as well as loading
+ * of external markdown documents.
+ */
+(function( root, factory ) {
+	if( typeof exports === 'object' ) {
+		module.exports = factory( require( './marked' ) );
+	}
+	else {
+		// Browser globals (root is window)
+		root.RevealMarkdown = factory( root.marked );
+		root.RevealMarkdown.initialize();
+	}
+}( this, function( marked ) {
+
+	if( typeof marked === 'undefined' ) {
+		throw 'The reveal.js Markdown plugin requires marked to be loaded';
+	}
+
+	if( typeof hljs !== 'undefined' ) {
+		marked.setOptions({
+			highlight: function( lang, code ) {
+				return hljs.highlightAuto( lang, code ).value;
+			}
+		});
+	}
+
+	var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$',
+		DEFAULT_NOTES_SEPARATOR = 'note:',
+		DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
+		DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
+
+
+	/**
+	 * Retrieves the markdown contents of a slide section
+	 * element. Normalizes leading tabs/whitespace.
+	 */
+	function getMarkdownFromSlide( section ) {
+
+		var template = section.querySelector( 'script' );
+
+		// strip leading whitespace so it isn't evaluated as code
+		var text = ( template || section ).textContent;
+
+		var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
+			leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
+
+		if( leadingTabs > 0 ) {
+			text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+		}
+		else if( leadingWs > 1 ) {
+			text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+		}
+
+		return text;
+
+	}
+
+	/**
+	 * Given a markdown slide section element, this will
+	 * return all arguments that aren't related to markdown
+	 * parsing. Used to forward any other user-defined arguments
+	 * to the output markdown slide.
+	 */
+	function getForwardedAttributes( section ) {
+
+		var attributes = section.attributes;
+		var result = [];
+
+		for( var i = 0, len = attributes.length; i < len; i++ ) {
+			var name = attributes[i].name,
+				value = attributes[i].value;
+
+			// disregard attributes that are used for markdown loading/parsing
+			if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
+
+			if( value ) {
+				result.push( name + '=' + value );
+			}
+			else {
+				result.push( name );
+			}
+		}
+
+		return result.join( ' ' );
+
+	}
+
+	/**
+	 * Inspects the given options and fills out default
+	 * values for what's not defined.
+	 */
+	function getSlidifyOptions( options ) {
+
+		options = options || {};
+		options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
+		options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
+		options.attributes = options.attributes || '';
+
+		return options;
+
+	}
+
+	/**
+	 * Helper function for constructing a markdown slide.
+	 */
+	function createMarkdownSlide( content, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
+
+		if( notesMatch.length === 2 ) {
+			content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
+		}
+
+		return '<script type="text/template">' + content + '</script>';
+
+	}
+
+	/**
+	 * Parses a data string into multiple slides based
+	 * on the passed in separator arguments.
+	 */
+	function slidify( markdown, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
+			horizontalSeparatorRegex = new RegExp( options.separator );
+
+		var matches,
+			lastIndex = 0,
+			isHorizontal,
+			wasHorizontal = true,
+			content,
+			sectionStack = [];
+
+		// iterate until all blocks between separators are stacked up
+		while( matches = separatorRegex.exec( markdown ) ) {
+			notes = null;
+
+			// determine direction (horizontal by default)
+			isHorizontal = horizontalSeparatorRegex.test( matches[0] );
+
+			if( !isHorizontal && wasHorizontal ) {
+				// create vertical stack
+				sectionStack.push( [] );
+			}
+
+			// pluck slide content from markdown input
+			content = markdown.substring( lastIndex, matches.index );
+
+			if( isHorizontal && wasHorizontal ) {
+				// add to horizontal stack
+				sectionStack.push( content );
+			}
+			else {
+				// add to vertical stack
+				sectionStack[sectionStack.length-1].push( content );
+			}
+
+			lastIndex = separatorRegex.lastIndex;
+			wasHorizontal = isHorizontal;
+		}
+
+		// add the remaining slide
+		( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
+
+		var markdownSections = '';
+
+		// flatten the hierarchical stack, and insert <section data-markdown> tags
+		for( var i = 0, len = sectionStack.length; i < len; i++ ) {
+			// vertical
+			if( sectionStack[i] instanceof Array ) {
+				markdownSections += '<section '+ options.attributes +'>';
+
+				sectionStack[i].forEach( function( child ) {
+					markdownSections += '<section data-markdown>' +  createMarkdownSlide( child, options ) + '</section>';
+				} );
+
+				markdownSections += '</section>';
+			}
+			else {
+				markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
+			}
+		}
+
+		return markdownSections;
+
+	}
+
+	/**
+	 * Parses any current data-markdown slides, splits
+	 * multi-slide markdown into separate sections and
+	 * handles loading of external markdown.
+	 */
+	function processSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]'),
+			section;
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			section = sections[i];
+
+			if( section.getAttribute( 'data-markdown' ).length ) {
+
+				var xhr = new XMLHttpRequest(),
+					url = section.getAttribute( 'data-markdown' );
+
+				datacharset = section.getAttribute( 'data-charset' );
+
+				// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
+				if( datacharset != null && datacharset != '' ) {
+					xhr.overrideMimeType( 'text/html; charset=' + datacharset );
+				}
+
+				xhr.onreadystatechange = function() {
+					if( xhr.readyState === 4 ) {
+						if ( xhr.status >= 200 && xhr.status < 300 ) {
+
+							section.outerHTML = slidify( xhr.responseText, {
+								separator: section.getAttribute( 'data-separator' ),
+								verticalSeparator: section.getAttribute( 'data-vertical' ),
+								notesSeparator: section.getAttribute( 'data-notes' ),
+								attributes: getForwardedAttributes( section )
+							});
+
+						}
+						else {
+
+							section.outerHTML = '<section data-state="alert">' +
+								'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
+								'Check your browser\'s JavaScript console for more details.' +
+								'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
+								'</section>';
+
+						}
+					}
+				};
+
+				xhr.open( 'GET', url, false );
+
+				try {
+					xhr.send();
+				}
+				catch ( e ) {
+					alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
+				}
+
+			}
+			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) {
+
+				section.outerHTML = slidify( getMarkdownFromSlide( section ), {
+					separator: section.getAttribute( 'data-separator' ),
+					verticalSeparator: section.getAttribute( 'data-vertical' ),
+					notesSeparator: section.getAttribute( 'data-notes' ),
+					attributes: getForwardedAttributes( section )
+				});
+
+			}
+			else {
+				section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
+			}
+		}
+
+	}
+
+	/**
+	 * Check if a node value has the attributes pattern.
+	 * If yes, extract it and add that value as one or several attributes
+	 * the the terget element.
+	 *
+	 * You need Cache Killer on Chrome to see the effect on any FOM transformation
+	 * directly on refresh (F5)
+	 * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
+	 */
+	function addAttributeInElement( node, elementTarget, separator ) {
+
+		var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
+		var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
+		var nodeValue = node.nodeValue;
+		if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
+
+			var classes = matches[1];
+			nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
+			node.nodeValue = nodeValue;
+			while( matchesClass = mardownClassRegex.exec( classes ) ) {
+				elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Add attributes to the parent element of a text node,
+	 * or the element of an attribute node.
+	 */
+	function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
+
+		if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
+			previousParentElement = element;
+			for( var i = 0; i < element.childNodes.length; i++ ) {
+				childElement = element.childNodes[i];
+				if ( i > 0 ) {
+					j = i - 1;
+					while ( j >= 0 ) {
+						aPreviousChildElement = element.childNodes[j];
+						if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
+							previousParentElement = aPreviousChildElement;
+							break;
+						}
+						j = j - 1;
+					}
+				}
+				parentSection = section;
+				if( childElement.nodeName ==  "section" ) {
+					parentSection = childElement ;
+					previousParentElement = childElement ;
+				}
+				if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
+					addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
+				}
+			}
+		}
+
+		if ( element.nodeType == Node.COMMENT_NODE ) {
+			if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
+				addAttributeInElement( element, section, separatorSectionAttributes );
+			}
+		}
+	}
+
+	/**
+	 * Converts any current data-markdown slides in the
+	 * DOM to HTML.
+	 */
+	function convertSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]');
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			var section = sections[i];
+
+			// Only parse the same slide once
+			if( !section.getAttribute( 'data-markdown-parsed' ) ) {
+
+				section.setAttribute( 'data-markdown-parsed', true )
+
+				var notes = section.querySelector( 'aside.notes' );
+				var markdown = getMarkdownFromSlide( section );
+
+				section.innerHTML = marked( markdown );
+				addAttributes( 	section, section, null, section.getAttribute( 'data-element-attributes' ) ||
+								section.parentNode.getAttribute( 'data-element-attributes' ) ||
+								DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
+								section.getAttribute( 'data-attributes' ) ||
+								section.parentNode.getAttribute( 'data-attributes' ) ||
+								DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
+
+				// If there were notes, we need to re-add them after
+				// having overwritten the section's HTML
+				if( notes ) {
+					section.appendChild( notes );
+				}
+
+			}
+
+		}
+
+	}
+
+	// API
+	return {
+
+		initialize: function() {
+			processSlides();
+			convertSlides();
+		},
+
+		// TODO: Do these belong in the API?
+		processSlides: processSlides,
+		convertSlides: convertSlides,
+		slidify: slidify
+
+	};
+
+}));
diff --git a/docs/slides/flops14/reveal.js/plugin/markdown/marked.js b/docs/slides/flops14/reveal.js/plugin/markdown/marked.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/markdown/marked.js
@@ -0,0 +1,37 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){3,} *\n*/,blockquote:/^( *>[^\n]+(\n[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr",/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";block.html=replace(block.html)("comment",/\x3c!--[\s\S]*?--\x3e/)("closed",
+/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1",
+"\\2")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm)if(this.options.tables)this.rules=block.tables;else this.rules=block.gfm}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};
+Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1)this.tokens.push({type:"space"})}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,
+"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,
+"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]="center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].split(/ *\| */);this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=
+src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);
+bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+
+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item[item.length-1]==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:cap[1]==="pre"||cap[1]==="script",text:cap[0]});continue}if(top&&
+(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]=
+"center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */);this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1][cap[1].length-1]==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",
+text:cap[0]});continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^\x3c!--[\s\S]*?--\x3e|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;
+if(!this.links)throw new Error("Tokens array requires a `links` property.");if(this.options.gfm)if(this.options.breaks)this.rules=inline.breaks;else this.rules=inline.gfm;else if(this.options.pedantic)this.rules=inline.pedantic}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);
+out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1][6]===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.url.exec(src)){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.tag.exec(src)){src=src.substring(cap[0].length);
+out+=this.options.sanitize?escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);out+=this.outputLink(cap,{href:cap[2],title:cap[3]});continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0][0];src=cap[0].substring(1)+src;continue}out+=this.outputLink(cap,link);continue}if(cap=this.rules.strong.exec(src)){src=
+src.substring(cap[0].length);out+="<strong>"+this.output(cap[2]||cap[1])+"</strong>";continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+="<em>"+this.output(cap[2]||cap[1])+"</em>";continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+="<code>"+escape(cap[2],true)+"</code>";continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+="<br>";continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+="<del>"+
+this.output(cap[1])+"</del>";continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=escape(cap[0]);continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return out};InlineLexer.prototype.outputLink=function(cap,link){if(cap[0][0]!=="!")return'<a href="'+escape(link.href)+'"'+(link.title?' title="'+escape(link.title)+'"':"")+">"+this.output(cap[1])+"</a>";else return'<img src="'+escape(link.href)+'" alt="'+escape(cap[1])+'"'+(link.title?' title="'+
+escape(link.title)+'"':"")+">"};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/--/g,"\u2014").replace(/'([^']*)'/g,"\u2018$1\u2019").replace(/"([^"]*)"/g,"\u201c$1\u201d").replace(/\.{3}/g,"\u2026")};InlineLexer.prototype.mangle=function(text){var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>0.5)ch="x"+ch.toString(16);out+="&#"+ch+";"}return out};function Parser(options){this.tokens=[];this.token=null;
+this.options=options||marked.defaults}Parser.parse=function(src,options){var parser=new Parser(options);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options);this.tokens=src.reverse();var out="";while(this.next())out+=this.tok();return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;
+while(this.peek().type==="text")body+="\n"+this.next().text;return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case "space":return"";case "hr":return"<hr>\n";case "heading":return"<h"+this.token.depth+">"+this.inline.output(this.token.text)+"</h"+this.token.depth+">\n";case "code":if(this.options.highlight){var code=this.options.highlight(this.token.text,this.token.lang);if(code!=null&&code!==this.token.text){this.token.escaped=true;this.token.text=code}}if(!this.token.escaped)this.token.text=
+escape(this.token.text,true);return"<pre><code"+(this.token.lang?' class="'+this.options.langPrefix+this.token.lang+'"':"")+">"+this.token.text+"</code></pre>\n";case "table":var body="",heading,i,row,cell,j;body+="<thead>\n<tr>\n";for(i=0;i<this.token.header.length;i++){heading=this.inline.output(this.token.header[i]);body+=this.token.align[i]?'<th align="'+this.token.align[i]+'">'+heading+"</th>\n":"<th>"+heading+"</th>\n"}body+="</tr>\n</thead>\n";body+="<tbody>\n";for(i=0;i<this.token.cells.length;i++){row=
+this.token.cells[i];body+="<tr>\n";for(j=0;j<row.length;j++){cell=this.inline.output(row[j]);body+=this.token.align[j]?'<td align="'+this.token.align[j]+'">'+cell+"</td>\n":"<td>"+cell+"</td>\n"}body+="</tr>\n"}body+="</tbody>\n";return"<table>\n"+body+"</table>\n";case "blockquote_start":var body="";while(this.next().type!=="blockquote_end")body+=this.tok();return"<blockquote>\n"+body+"</blockquote>\n";case "list_start":var type=this.token.ordered?"ol":"ul",body="";while(this.next().type!=="list_end")body+=
+this.tok();return"<"+type+">\n"+body+"</"+type+">\n";case "list_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.token.type==="text"?this.parseText():this.tok();return"<li>"+body+"</li>\n";case "loose_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.tok();return"<li>"+body+"</li>\n";case "html":return!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;case "paragraph":return"<p>"+this.inline.output(this.token.text)+
+"</p>\n";case "text":return"<p>"+this.parseText()+"</p>\n"}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=
+1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target)if(Object.prototype.hasOwnProperty.call(target,key))obj[key]=target[key]}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}if(opt)opt=merge({},marked.defaults,opt);var tokens=Lexer.lex(tokens,opt),highlight=opt.highlight,pending=0,l=tokens.length,i=0;if(!highlight||highlight.length<3)return callback(null,Parser.parse(tokens,opt));var done=function(){delete opt.highlight;
+var out=Parser.parse(tokens,opt);opt.highlight=highlight;return callback(null,out)};for(;i<l;i++)(function(token){if(token.type!=="code")return;pending++;return highlight(token.text,token.lang,function(err,code){if(code==null||code===token.text)return--pending||done();token.text=code;token.escaped=true;--pending||done()})})(tokens[i]);return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";
+if((opt||marked.defaults).silent)return"<p>An error occured:</p><pre>"+escape(e.message+"",true)+"</pre>";throw e;}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,smartLists:false,silent:false,highlight:null,langPrefix:""};marked.Parser=Parser;marked.parser=Parser.parse;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;
+marked.parse=marked;if(typeof exports==="object")module.exports=marked;else if(typeof define==="function"&&define.amd)define(function(){return marked});else this.marked=marked}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
diff --git a/docs/slides/flops14/reveal.js/plugin/math/math.js b/docs/slides/flops14/reveal.js/plugin/math/math.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/math/math.js
@@ -0,0 +1,64 @@
+/**
+ * A plugin which enables rendering of math equations inside
+ * of reveal.js slides. Essentially a thin wrapper for MathJax.
+ *
+ * @author Hakim El Hattab
+ */
+var RevealMath = window.RevealMath || (function(){
+
+	var options = Reveal.getConfig().math || {};
+	options.mathjax = options.mathjax || 'http://cdn.mathjax.org/mathjax/latest/MathJax.js';
+	options.config = options.config || 'TeX-AMS_HTML-full';
+
+	loadScript( options.mathjax + '?config=' + options.config, function() {
+
+		MathJax.Hub.Config({
+			messageStyle: 'none',
+			tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] },
+			skipStartupTypeset: true
+		});
+
+		// Typeset followed by an immediate reveal.js layout since
+		// the typesetting process could affect slide height
+		MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
+		MathJax.Hub.Queue( Reveal.layout );
+
+		// Reprocess equations in slides when they turn visible
+		Reveal.addEventListener( 'slidechanged', function( event ) {
+
+			MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
+
+		} );
+
+	} );
+
+	function loadScript( url, callback ) {
+
+		var head = document.querySelector( 'head' );
+		var script = document.createElement( 'script' );
+		script.type = 'text/javascript';
+		script.src = url;
+
+		// Wrapper for callback to make sure it only fires once
+		var finish = function() {
+			if( typeof callback === 'function' ) {
+				callback.call();
+				callback = null;
+			}
+		}
+
+		script.onload = finish;
+
+		// IE
+		script.onreadystatechange = function() {
+			if ( this.readyState === 'loaded' ) {
+				finish();
+			}
+		}
+
+		// Normal browsers
+		head.appendChild( script );
+
+	}
+
+})();
diff --git a/docs/slides/flops14/reveal.js/plugin/multiplex/client.js b/docs/slides/flops14/reveal.js/plugin/multiplex/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/multiplex/client.js
@@ -0,0 +1,13 @@
+(function() {
+	var multiplex = Reveal.getConfig().multiplex;
+	var socketId = multiplex.id;
+	var socket = io.connect(multiplex.url);
+
+	socket.on(multiplex.id, function(data) {
+		// ignore data from sockets that aren't ours
+		if (data.socketId !== socketId) { return; }
+		if( window.location.host === 'localhost:1947' ) return;
+
+		Reveal.slide(data.indexh, data.indexv, data.indexf, 'remote');
+	});
+}());
diff --git a/docs/slides/flops14/reveal.js/plugin/multiplex/index.js b/docs/slides/flops14/reveal.js/plugin/multiplex/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/multiplex/index.js
@@ -0,0 +1,56 @@
+var express		= require('express');
+var fs			= require('fs');
+var io			= require('socket.io');
+var crypto		= require('crypto');
+
+var app			= express.createServer();
+var staticDir	= express.static;
+
+io				= io.listen(app);
+
+var opts = {
+	port: 1948,
+	baseDir : __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		if (typeof slideData.secret == 'undefined' || slideData.secret == null || slideData.secret === '') return;
+		if (createHash(slideData.secret) === slideData.socketId) {
+			slideData.secret = null;
+			socket.broadcast.emit(slideData.socketId, slideData);
+		};
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/token", function(req,res) {
+	var ts = new Date().getTime();
+	var rand = Math.floor(Math.random()*9999999);
+	var secret = ts.toString() + rand.toString();
+	res.send({secret: secret, socketId: createHash(secret)});
+});
+
+var createHash = function(secret) {
+	var cipher = crypto.createCipher('blowfish', secret);
+	return(cipher.final('hex'));
+};
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset );
diff --git a/docs/slides/flops14/reveal.js/plugin/multiplex/master.js b/docs/slides/flops14/reveal.js/plugin/multiplex/master.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/multiplex/master.js
@@ -0,0 +1,51 @@
+(function() {
+	// Don't emit events from inside of notes windows
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var multiplex = Reveal.getConfig().multiplex;
+
+	var socket = io.connect(multiplex.url);
+
+	var notify = function( slideElement, indexh, indexv, origin ) {
+		if( typeof origin === 'undefined' && origin !== 'remote' ) {
+			var nextindexh;
+			var nextindexv;
+
+			var fragmentindex = Reveal.getIndices().f;
+			if (typeof fragmentindex == 'undefined') {
+				fragmentindex = 0;
+			}
+
+			if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+				nextindexh = indexh;
+				nextindexv = indexv + 1;
+			} else {
+				nextindexh = indexh + 1;
+				nextindexv = 0;
+			}
+
+			var slideData = {
+				indexh : indexh,
+				indexv : indexv,
+				indexf : fragmentindex,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				secret: multiplex.secret,
+				socketId : multiplex.id
+			};
+
+			socket.emit('slidechanged', slideData);
+		}
+	}
+
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		notify( event.currentSlide, event.indexh, event.indexv, event.origin );
+	} );
+
+	var fragmentNotify = function( event ) {
+		notify( Reveal.getCurrentSlide(), Reveal.getIndices().h, Reveal.getIndices().v, event.origin );
+	};
+
+	Reveal.addEventListener( 'fragmentshown', fragmentNotify );
+	Reveal.addEventListener( 'fragmenthidden', fragmentNotify );
+}());
diff --git a/docs/slides/flops14/reveal.js/plugin/notes-server/client.js b/docs/slides/flops14/reveal.js/plugin/notes-server/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/notes-server/client.js
@@ -0,0 +1,57 @@
+(function() {
+	// don't emit events from inside the previews themselves
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var socket = io.connect(window.location.origin);
+	var socketId = Math.random().toString().slice(2);
+	
+	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
+	window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId);
+
+	// Fires when a fragment is shown
+	Reveal.addEventListener( 'fragmentshown', function( event ) {
+		var fragmentData = {
+			fragment : 'next',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when a fragment is hidden
+	Reveal.addEventListener( 'fragmenthidden', function( event ) {
+		var fragmentData = {
+			fragment : 'previous',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when slide is changed
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		var nextindexh;
+		var nextindexv;
+		var slideElement = event.currentSlide;
+
+		if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+			nextindexh = event.indexh;
+			nextindexv = event.indexv + 1;
+		} else {
+			nextindexh = event.indexh + 1;
+			nextindexv = 0;
+		}
+
+		var notes = slideElement.querySelector('aside.notes');
+		var slideData = {
+			notes : notes ? notes.innerHTML : '',
+			indexh : event.indexh,
+			indexv : event.indexv,
+			nextindexh : nextindexh,
+			nextindexv : nextindexv,
+			socketId : socketId,
+			markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false
+
+		};
+
+		socket.emit('slidechanged', slideData);
+	} );
+}());
diff --git a/docs/slides/flops14/reveal.js/plugin/notes-server/index.js b/docs/slides/flops14/reveal.js/plugin/notes-server/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/notes-server/index.js
@@ -0,0 +1,59 @@
+var express   = require('express');
+var fs        = require('fs');
+var io        = require('socket.io');
+var _         = require('underscore');
+var Mustache  = require('mustache');
+
+var app       = express.createServer();
+var staticDir = express.static;
+
+io            = io.listen(app);
+
+var opts = {
+	port :      1947,
+	baseDir :   __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		socket.broadcast.emit('slidedata', slideData);
+	});
+	socket.on('fragmentchanged', function(fragmentData) {
+		socket.broadcast.emit('fragmentdata', fragmentData);
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/notes/:socketId", function(req, res) {
+
+	fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) {
+		res.send(Mustache.to_html(data.toString(), {
+			socketId : req.params.socketId
+		}));
+	});
+	// fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res);
+});
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
+
+console.log( brown + "reveal.js - Speaker Notes" + reset );
+console.log( "1. Open the slides at " + green + slidesLocation + reset );
+console.log( "2. Click on the link your JS console to go to the notes page" );
+console.log( "3. Advance through your slides and your notes will advance automatically" );
diff --git a/docs/slides/flops14/reveal.js/plugin/notes/notes.js b/docs/slides/flops14/reveal.js/plugin/notes/notes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/notes/notes.js
@@ -0,0 +1,78 @@
+/**
+ * Handles opening of and synchronization with the reveal.js
+ * notes window.
+ */
+var RevealNotes = (function() {
+
+	function openNotes() {
+		var jsFileLocation = document.querySelector('script[src$="notes.js"]').src;  // this js file path
+		jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, '');   // the js folder path
+		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' );
+
+		// Fires when slide is changed
+		Reveal.addEventListener( 'slidechanged', post );
+
+		// Fires when a fragment is shown
+		Reveal.addEventListener( 'fragmentshown', post );
+
+		// Fires when a fragment is hidden
+		Reveal.addEventListener( 'fragmenthidden', post );
+
+		/**
+		 * Posts the current slide data to the notes window
+		 */
+		function post() {
+			var slideElement = Reveal.getCurrentSlide(),
+				slideIndices = Reveal.getIndices(),
+				messageData;
+
+			var notes = slideElement.querySelector( 'aside.notes' ),
+				nextindexh,
+				nextindexv;
+
+			if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
+				nextindexh = slideIndices.h;
+				nextindexv = slideIndices.v + 1;
+			} else {
+				nextindexh = slideIndices.h + 1;
+				nextindexv = 0;
+			}
+
+			messageData = {
+				notes : notes ? notes.innerHTML : '',
+				indexh : slideIndices.h,
+				indexv : slideIndices.v,
+				indexf : slideIndices.f,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
+			};
+
+			notesPopup.postMessage( JSON.stringify( messageData ), '*' );
+		}
+
+		// Navigate to the current slide when the notes are loaded
+		notesPopup.addEventListener( 'load', function( event ) {
+			post();
+		}, false );
+	}
+
+	// If the there's a 'notes' query set, open directly
+	if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
+		openNotes();
+	}
+
+	// Open the notes when the 's' key is hit
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openNotes();
+		}
+	}, false );
+
+	return { open: openNotes };
+})();
diff --git a/docs/slides/flops14/reveal.js/plugin/postmessage/postmessage.js b/docs/slides/flops14/reveal.js/plugin/postmessage/postmessage.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/postmessage/postmessage.js
@@ -0,0 +1,42 @@
+/*
+
+	simple postmessage plugin
+
+	Useful when a reveal slideshow is inside an iframe.
+	It allows to call reveal methods from outside.
+
+	Example:
+		 var reveal =  window.frames[0];
+
+		 // Reveal.prev(); 
+		 reveal.postMessage(JSON.stringify({method: 'prev', args: []}), '*');
+		 // Reveal.next(); 
+		 reveal.postMessage(JSON.stringify({method: 'next', args: []}), '*');
+		 // Reveal.slide(2, 2); 
+		 reveal.postMessage(JSON.stringify({method: 'slide', args: [2,2]}), '*');
+
+	Add to the slideshow:
+
+		dependencies: [
+			...
+			{ src: 'plugin/postmessage/postmessage.js', async: true, condition: function() { return !!document.body.classList; } }
+		]
+
+*/
+
+(function (){
+
+	window.addEventListener( "message", function ( event ) {
+		var data = JSON.parse( event.data ),
+				method = data.method,
+				args = data.args;
+
+		if( typeof Reveal[method] === 'function' ) {
+			Reveal[method].apply( Reveal, data.args );
+		}
+	}, false);
+
+}());
+
+
+
diff --git a/docs/slides/flops14/reveal.js/plugin/print-pdf/print-pdf.js b/docs/slides/flops14/reveal.js/plugin/print-pdf/print-pdf.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/print-pdf/print-pdf.js
@@ -0,0 +1,44 @@
+/**
+ * phantomjs script for printing presentations to PDF.
+ *
+ * Example:
+ * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf
+ *
+ * By Manuel Bieh (https://github.com/manuelbieh)
+ */
+
+// html2pdf.js
+var page = new WebPage();
+var system = require( 'system' );
+
+page.viewportSize  = {
+	width: 1024,
+	height: 768
+};
+
+page.paperSize = {
+	format: 'letter',
+	orientation: 'landscape',
+	margin: {
+		left: '0',
+		right: '0',
+		top: '0',
+		bottom: '0'
+	}
+};
+
+var revealFile = system.args[1] || 'index.html?print-pdf';
+var slideFile = system.args[2] || 'slides.pdf';
+
+if( slideFile.match( /\.pdf$/gi ) === null ) {
+	slideFile += '.pdf';
+}
+
+console.log( 'Printing PDF...' );
+
+page.open( revealFile, function( status ) {
+	console.log( 'Printed succesfully' );
+	page.render( slideFile );
+	phantom.exit();
+} );
+
diff --git a/docs/slides/flops14/reveal.js/plugin/remotes/remotes.js b/docs/slides/flops14/reveal.js/plugin/remotes/remotes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/remotes/remotes.js
@@ -0,0 +1,39 @@
+/**
+ * Touch-based remote controller for your presentation courtesy 
+ * of the folks at http://remotes.io
+ */
+
+(function(window){
+
+    /**
+     * Detects if we are dealing with a touch enabled device (with some false positives)
+     * Borrowed from modernizr: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touch.js   
+     */
+    var hasTouch  = (function(){
+        return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
+    })();
+
+    /**
+     * Detects if notes are enable and the current page is opened inside an /iframe
+     * this prevents loading Remotes.io several times
+     */
+    var isNotesAndIframe = (function(){
+        return window.RevealNotes && !(self == top);
+    })();
+
+    if(!hasTouch && !isNotesAndIframe){
+        head.ready( 'remotes.ne.min.js', function() {
+            new Remotes("preview")
+                .on("swipe-left", function(e){ Reveal.right(); })
+                .on("swipe-right", function(e){ Reveal.left(); })
+                .on("swipe-up", function(e){ Reveal.down(); })
+                .on("swipe-down", function(e){ Reveal.up(); })
+                .on("tap", function(e){ Reveal.next(); })
+                .on("zoom-out", function(e){ Reveal.toggleOverview(true); })
+                .on("zoom-in", function(e){ Reveal.toggleOverview(false); })
+            ;
+        } );
+
+        head.js('https://hakim-static.s3.amazonaws.com/reveal-js/remotes.ne.min.js');
+    }
+})(window);
diff --git a/docs/slides/flops14/reveal.js/plugin/search/search.js b/docs/slides/flops14/reveal.js/plugin/search/search.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/search/search.js
@@ -0,0 +1,196 @@
+/*
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
+ * by navigatating to that slide and highlighting it.
+ *
+ * By Jon Snyder <snyder.jon@gmail.com>, February 2013
+ */
+
+var RevealSearch = (function() {
+
+	var matchedSlides;
+	var currentMatchedIndex;
+	var searchboxDirty;
+	var myHilitor;
+
+// Original JavaScript code by Chirp Internet: www.chirp.com.au
+// Please acknowledge use of this code by including this header.
+// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
+
+function Hilitor(id, tag)
+{
+
+  var targetNode = document.getElementById(id) || document.body;
+  var hiliteTag = tag || "EM";
+  var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
+  var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
+  var wordColor = [];
+  var colorIdx = 0;
+  var matchRegex = "";
+  var matchingSlides = [];
+
+  this.setRegex = function(input)
+  {
+    input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
+    matchRegex = new RegExp("(" + input + ")","i");
+  }
+
+  this.getRegex = function()
+  {
+    return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
+  }
+
+  // recursively apply word highlighting
+  this.hiliteWords = function(node)
+  {
+    if(node == undefined || !node) return;
+    if(!matchRegex) return;
+    if(skipTags.test(node.nodeName)) return;
+
+    if(node.hasChildNodes()) {
+      for(var i=0; i < node.childNodes.length; i++)
+        this.hiliteWords(node.childNodes[i]);
+    }
+    if(node.nodeType == 3) { // NODE_TEXT
+      if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
+      	//find the slide's section element and save it in our list of matching slides
+      	var secnode = node.parentNode;
+      	while (secnode.nodeName != 'SECTION') {
+      		secnode = secnode.parentNode;
+      	}
+      	
+      	var slideIndex = Reveal.getIndices(secnode);
+      	var slidelen = matchingSlides.length;
+      	var alreadyAdded = false;
+      	for (var i=0; i < slidelen; i++) {
+      		if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
+      			alreadyAdded = true;
+      		}
+      	}
+      	if (! alreadyAdded) {
+      		matchingSlides.push(slideIndex);
+      	}
+      	
+        if(!wordColor[regs[0].toLowerCase()]) {
+          wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
+        }
+
+        var match = document.createElement(hiliteTag);
+        match.appendChild(document.createTextNode(regs[0]));
+        match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
+        match.style.fontStyle = "inherit";
+        match.style.color = "#000";
+
+        var after = node.splitText(regs.index);
+        after.nodeValue = after.nodeValue.substring(regs[0].length);
+        node.parentNode.insertBefore(match, after);
+      }
+    }
+  };
+
+  // remove highlighting
+  this.remove = function()
+  {
+    var arr = document.getElementsByTagName(hiliteTag);
+    while(arr.length && (el = arr[0])) {
+      el.parentNode.replaceChild(el.firstChild, el);
+    }
+  };
+
+  // start highlighting at target node
+  this.apply = function(input)
+  {
+    if(input == undefined || !input) return;
+    this.remove();
+    this.setRegex(input);
+    this.hiliteWords(targetNode);
+    return matchingSlides;
+  };
+
+}
+
+	function openSearch() {
+		//ensure the search term input dialog is visible and has focus:
+		var inputbox = document.getElementById("searchinput");
+		inputbox.style.display = "inline";
+		inputbox.focus();
+		inputbox.select();
+	}
+
+	function toggleSearch() {
+		var inputbox = document.getElementById("searchinput");
+		if (inputbox.style.display !== "inline") {
+			openSearch();
+		}
+		else {
+			inputbox.style.display = "none";
+			myHilitor.remove();
+		}
+	}
+
+	function doSearch() {
+		//if there's been a change in the search term, perform a new search:
+		if (searchboxDirty) {
+			var searchstring = document.getElementById("searchinput").value;
+
+			//find the keyword amongst the slides
+			myHilitor = new Hilitor("slidecontent");
+			matchedSlides = myHilitor.apply(searchstring);
+			currentMatchedIndex = 0;
+		}
+
+		//navigate to the next slide that has the keyword, wrapping to the first if necessary
+		if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
+			currentMatchedIndex = 0;
+		}
+		if (matchedSlides.length > currentMatchedIndex) {
+			Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
+			currentMatchedIndex++;
+		}
+	}
+
+	var dom = {};
+	dom.wrapper = document.querySelector( '.reveal' );
+
+	if( !dom.wrapper.querySelector( '.searchbox' ) ) {
+			var searchElement = document.createElement( 'div' );
+			searchElement.id = "searchinputdiv";
+			searchElement.classList.add( 'searchdiv' );
+      searchElement.style.position = 'absolute';
+      searchElement.style.top = '10px';
+      searchElement.style.left = '10px';
+      //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
+			searchElement.innerHTML = '<span><input type="search" id="searchinput" class="searchinput" style="vertical-align: top;"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJiSURBVHjatFZNaxNBGH5md+Mmu92NVdKDRipSAyqCghgQD4L4cRe86UUtAQ+eFCxoa4/25EXBFi8eBE+eRPoDhB6KgiiixdAPCEkx2pjvTXadd9yNsflwuyUDD/O+u8PzzDPvzOwyx3EwyCZhwG3gAkp7MnpjgbopjsltcD4gjuXZZKeAR348MYLYTm3LzOs/y3j3JTfZxgXWXmTuwPHIc4VmoOmv5IrI53+AO2DdHLjkDWQ3GoEEVFXtXQOvkSnPWcyUceviLhwbDYv8/XIVj97kse7TodLvZXxYxrPUHkQ1ufXs3FEdybEIxucySOesoNvUgWU1cP3MkCBfTFdw9fGaAMVmRELq7LBw2Q3/FaAxxWIRpw+ZIr/7IouPqzUBiqmdHAv7EuhRAwf1er2Vy4x1jW3b2d5Jfvu5IPp7l2LYbcgCFFNb+FoJ7oBqEAqFMPNqFcmEgVMJDfMT+1tvN0pNjERlMS6QA5pFOKxiKVPFhakPeL3It+WGJUDxt2wFR+JhzI7v5ctkd8DXOZAkCYYxhO+lKm4+Xfqz/rIixBuNBl7eOYzkQQNzqX249mRl6zUgEcYkaJrGhUwBinVdh6IouPzwE6/DL5w4oLkH8y981aDf+uq6hlKpJESiUdNfDZi7/ehG9K6KfiA3pml0PLcsq+cSMTj2NL9ukc4UOmz7AZ3+crkC4mHujFvXNaMFB3bEr8xPS6p5O+jXxq4VZtaen7/PwzrntjcLUE0iHPS1Ud1cdiEJl/8WivZk0wXd7zWOMkeF8s0CcAmkNrC2nvXZDbbbN73ccYnZoH9bfgswAFzAe9/h3dbKAAAAAElFTkSuQmCC" id="searchbutton" class="searchicon" style="vertical-align: top; margin-top: -1px;"/></span>';
+			dom.wrapper.appendChild( searchElement );
+	}
+
+	document.getElementById("searchbutton").addEventListener( 'click', function(event) {
+		doSearch();
+	}, false );
+
+	document.getElementById("searchinput").addEventListener( 'keyup', function( event ) {
+		switch (event.keyCode) {
+			case 13:
+				event.preventDefault();
+				doSearch();
+				searchboxDirty = false;
+				break;
+			default:
+				searchboxDirty = true;
+		}
+	}, false );
+
+	// Open the search when the 's' key is hit (yes, this conflicts with the notes plugin, disabling for now)
+	/*
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openSearch();
+		}
+	}, false );
+*/
+	return { open: openSearch };
+})();
diff --git a/docs/slides/flops14/reveal.js/plugin/zoom-js/zoom.js b/docs/slides/flops14/reveal.js/plugin/zoom-js/zoom.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/plugin/zoom-js/zoom.js
@@ -0,0 +1,258 @@
+// Custom reveal.js integration
+(function(){
+	var isEnabled = true;
+
+	document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) {
+		var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key';
+
+		if( event[ modifier ] && isEnabled ) {
+			event.preventDefault();
+			zoom.to({ element: event.target, pan: false });
+		}
+	} );
+
+	Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
+	Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
+})();
+
+/*!
+ * zoom.js 0.2 (modified version for use with reveal.js)
+ * http://lab.hakim.se/zoom-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var zoom = (function(){
+
+	// The current zoom level (scale)
+	var level = 1;
+
+	// The current mouse position, used for panning
+	var mouseX = 0,
+		mouseY = 0;
+
+	// Timeout before pan is activated
+	var panEngageTimeout = -1,
+		panUpdateInterval = -1;
+
+	var currentOptions = null;
+
+	// Check for transform support so that we can fallback otherwise
+	var supportsTransforms = 	'WebkitTransform' in document.body.style ||
+								'MozTransform' in document.body.style ||
+								'msTransform' in document.body.style ||
+								'OTransform' in document.body.style ||
+								'transform' in document.body.style;
+
+	if( supportsTransforms ) {
+		// The easing that will be applied when we zoom in/out
+		document.body.style.transition = 'transform 0.8s ease';
+		document.body.style.OTransition = '-o-transform 0.8s ease';
+		document.body.style.msTransition = '-ms-transform 0.8s ease';
+		document.body.style.MozTransition = '-moz-transform 0.8s ease';
+		document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
+	}
+
+	// Zoom out if the user hits escape
+	document.addEventListener( 'keyup', function( event ) {
+		if( level !== 1 && event.keyCode === 27 ) {
+			zoom.out();
+		}
+	}, false );
+
+	// Monitor mouse movement for panning
+	document.addEventListener( 'mousemove', function( event ) {
+		if( level !== 1 ) {
+			mouseX = event.clientX;
+			mouseY = event.clientY;
+		}
+	}, false );
+
+	/**
+	 * Applies the CSS required to zoom in, prioritizes use of CSS3
+	 * transforms but falls back on zoom for IE.
+	 *
+	 * @param {Number} pageOffsetX
+	 * @param {Number} pageOffsetY
+	 * @param {Number} elementOffsetX
+	 * @param {Number} elementOffsetY
+	 * @param {Number} scale
+	 */
+	function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) {
+
+		if( supportsTransforms ) {
+			var origin = pageOffsetX +'px '+ pageOffsetY +'px',
+				transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')';
+
+			document.body.style.transformOrigin = origin;
+			document.body.style.OTransformOrigin = origin;
+			document.body.style.msTransformOrigin = origin;
+			document.body.style.MozTransformOrigin = origin;
+			document.body.style.WebkitTransformOrigin = origin;
+
+			document.body.style.transform = transform;
+			document.body.style.OTransform = transform;
+			document.body.style.msTransform = transform;
+			document.body.style.MozTransform = transform;
+			document.body.style.WebkitTransform = transform;
+		}
+		else {
+			// Reset all values
+			if( scale === 1 ) {
+				document.body.style.position = '';
+				document.body.style.left = '';
+				document.body.style.top = '';
+				document.body.style.width = '';
+				document.body.style.height = '';
+				document.body.style.zoom = '';
+			}
+			// Apply scale
+			else {
+				document.body.style.position = 'relative';
+				document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px';
+				document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px';
+				document.body.style.width = ( scale * 100 ) + '%';
+				document.body.style.height = ( scale * 100 ) + '%';
+				document.body.style.zoom = scale;
+			}
+		}
+
+		level = scale;
+
+		if( level !== 1 && document.documentElement.classList ) {
+			document.documentElement.classList.add( 'zoomed' );
+		}
+		else {
+			document.documentElement.classList.remove( 'zoomed' );
+		}
+	}
+
+	/**
+	 * Pan the document when the mosue cursor approaches the edges
+	 * of the window.
+	 */
+	function pan() {
+		var range = 0.12,
+			rangeX = window.innerWidth * range,
+			rangeY = window.innerHeight * range,
+			scrollOffset = getScrollOffset();
+
+		// Up
+		if( mouseY < rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
+		}
+		// Down
+		else if( mouseY > window.innerHeight - rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
+		}
+
+		// Left
+		if( mouseX < rangeX ) {
+			window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
+		}
+		// Right
+		else if( mouseX > window.innerWidth - rangeX ) {
+			window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
+		}
+	}
+
+	function getScrollOffset() {
+		return {
+			x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
+			y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset
+		}
+	}
+
+	return {
+		/**
+		 * Zooms in on either a rectangle or HTML element.
+		 *
+		 * @param {Object} options
+		 *   - element: HTML element to zoom in on
+		 *   OR
+		 *   - x/y: coordinates in non-transformed space to zoom in on
+		 *   - width/height: the portion of the screen to zoom in on
+		 *   - scale: can be used instead of width/height to explicitly set scale
+		 */
+		to: function( options ) {
+			// Due to an implementation limitation we can't zoom in
+			// to another element without zooming out first
+			if( level !== 1 ) {
+				zoom.out();
+			}
+			else {
+				options.x = options.x || 0;
+				options.y = options.y || 0;
+
+				// If an element is set, that takes precedence
+				if( !!options.element ) {
+					// Space around the zoomed in element to leave on screen
+					var padding = 20;
+
+					options.width = options.element.getBoundingClientRect().width + ( padding * 2 );
+					options.height = options.element.getBoundingClientRect().height + ( padding * 2 );
+					options.x = options.element.getBoundingClientRect().left - padding;
+					options.y = options.element.getBoundingClientRect().top - padding;
+				}
+
+				// If width/height values are set, calculate scale from those values
+				if( options.width !== undefined && options.height !== undefined ) {
+					options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
+				}
+
+				if( options.scale > 1 ) {
+					options.x *= options.scale;
+					options.y *= options.scale;
+
+					var scrollOffset = getScrollOffset();
+
+					if( options.element ) {
+						scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2;
+					}
+
+					magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale );
+
+					if( options.pan !== false ) {
+
+						// Wait with engaging panning as it may conflict with the
+						// zoom transition
+						panEngageTimeout = setTimeout( function() {
+							panUpdateInterval = setInterval( pan, 1000 / 60 );
+						}, 800 );
+
+					}
+				}
+
+				currentOptions = options;
+			}
+		},
+
+		/**
+		 * Resets the document zoom state to its default.
+		 */
+		out: function() {
+			clearTimeout( panEngageTimeout );
+			clearInterval( panUpdateInterval );
+
+			var scrollOffset = getScrollOffset();
+
+			if( currentOptions && currentOptions.element ) {
+				scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2;
+			}
+
+			magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 );
+
+			level = 1;
+		},
+
+		// Alias
+		magnify: function( options ) { this.to( options ) },
+		reset: function() { this.out() },
+
+		zoomLevel: function() {
+			return level;
+		}
+	}
+
+})();
+
diff --git a/docs/slides/flops14/reveal.js/test/examples/assets/image1.png b/docs/slides/flops14/reveal.js/test/examples/assets/image1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/reveal.js/test/examples/assets/image1.png differ
diff --git a/docs/slides/flops14/reveal.js/test/examples/assets/image2.png b/docs/slides/flops14/reveal.js/test/examples/assets/image2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/flops14/reveal.js/test/examples/assets/image2.png differ
diff --git a/docs/slides/flops14/reveal.js/test/qunit-1.12.0.css b/docs/slides/flops14/reveal.js/test/qunit-1.12.0.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/test/qunit-1.12.0.css
@@ -0,0 +1,244 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+	margin: 0;
+	padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+	padding: 0.5em 0 0.5em 1em;
+
+	color: #8699a4;
+	background-color: #0d3349;
+
+	font-size: 1.5em;
+	line-height: 1em;
+	font-weight: normal;
+
+	border-radius: 5px 5px 0 0;
+	-moz-border-radius: 5px 5px 0 0;
+	-webkit-border-top-right-radius: 5px;
+	-webkit-border-top-left-radius: 5px;
+}
+
+#qunit-header a {
+	text-decoration: none;
+	color: #c2ccd1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+	color: #fff;
+}
+
+#qunit-testrunner-toolbar label {
+	display: inline-block;
+	padding: 0 .5em 0 .1em;
+}
+
+#qunit-banner {
+	height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+	padding: 0.5em 0 0.5em 2em;
+	color: #5E740B;
+	background-color: #eee;
+	overflow: hidden;
+}
+
+#qunit-userAgent {
+	padding: 0.5em 0 0.5em 2.5em;
+	background-color: #2b81af;
+	color: #fff;
+	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+#qunit-modulefilter-container {
+	float: right;
+}
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+	list-style-position: inside;
+}
+
+#qunit-tests li {
+	padding: 0.4em 0.5em 0.4em 2.5em;
+	border-bottom: 1px solid #fff;
+	list-style-position: inside;
+}
+
+#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
+	display: none;
+}
+
+#qunit-tests li strong {
+	cursor: pointer;
+}
+
+#qunit-tests li a {
+	padding: 0.5em;
+	color: #c2ccd1;
+	text-decoration: none;
+}
+#qunit-tests li a:hover,
+#qunit-tests li a:focus {
+	color: #000;
+}
+
+#qunit-tests li .runtime {
+	float: right;
+	font-size: smaller;
+}
+
+.qunit-assert-list {
+	margin-top: 0.5em;
+	padding: 0.5em;
+
+	background-color: #fff;
+
+	border-radius: 5px;
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+}
+
+.qunit-collapsed {
+	display: none;
+}
+
+#qunit-tests table {
+	border-collapse: collapse;
+	margin-top: .2em;
+}
+
+#qunit-tests th {
+	text-align: right;
+	vertical-align: top;
+	padding: 0 .5em 0 0;
+}
+
+#qunit-tests td {
+	vertical-align: top;
+}
+
+#qunit-tests pre {
+	margin: 0;
+	white-space: pre-wrap;
+	word-wrap: break-word;
+}
+
+#qunit-tests del {
+	background-color: #e0f2be;
+	color: #374e0c;
+	text-decoration: none;
+}
+
+#qunit-tests ins {
+	background-color: #ffcaca;
+	color: #500;
+	text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts                       { color: black; }
+#qunit-tests b.passed                       { color: #5E740B; }
+#qunit-tests b.failed                       { color: #710909; }
+
+#qunit-tests li li {
+	padding: 5px;
+	background-color: #fff;
+	border-bottom: none;
+	list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+	color: #3c510c;
+	background-color: #fff;
+	border-left: 10px solid #C6E746;
+}
+
+#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name               { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected           { color: #999999; }
+
+#qunit-banner.qunit-pass                    { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+	color: #710909;
+	background-color: #fff;
+	border-left: 10px solid #EE5757;
+	white-space: pre;
+}
+
+#qunit-tests > li:last-child {
+	border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-webkit-border-bottom-right-radius: 5px;
+	-webkit-border-bottom-left-radius: 5px;
+}
+
+#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name             { color: #000000; }
+
+#qunit-tests .fail .test-actual             { color: #EE5757; }
+#qunit-tests .fail .test-expected           { color: green;   }
+
+#qunit-banner.qunit-fail                    { background-color: #EE5757; }
+
+
+/** Result */
+
+#qunit-testresult {
+	padding: 0.5em 0.5em 0.5em 2.5em;
+
+	color: #2b81af;
+	background-color: #D2E0E6;
+
+	border-bottom: 1px solid white;
+}
+#qunit-testresult .module-name {
+	font-weight: bold;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+	position: absolute;
+	top: -10000px;
+	left: -10000px;
+	width: 1000px;
+	height: 1000px;
+}
diff --git a/docs/slides/flops14/reveal.js/test/qunit-1.12.0.js b/docs/slides/flops14/reveal.js/test/qunit-1.12.0.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/test/qunit-1.12.0.js
@@ -0,0 +1,2212 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * https://jquery.org/license/
+ */
+
+(function( window ) {
+
+var QUnit,
+	assert,
+	config,
+	onErrorFnPrev,
+	testId = 0,
+	fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	// Keep a local reference to Date (GH-283)
+	Date = window.Date,
+	setTimeout = window.setTimeout,
+	defined = {
+		setTimeout: typeof window.setTimeout !== "undefined",
+		sessionStorage: (function() {
+			var x = "qunit-test-string";
+			try {
+				sessionStorage.setItem( x, x );
+				sessionStorage.removeItem( x );
+				return true;
+			} catch( e ) {
+				return false;
+			}
+		}())
+	},
+	/**
+	 * Provides a normalized error string, correcting an issue
+	 * with IE 7 (and prior) where Error.prototype.toString is
+	 * not properly implemented
+	 *
+	 * Based on http://es5.github.com/#x15.11.4.4
+	 *
+	 * @param {String|Error} error
+	 * @return {String} error message
+	 */
+	errorString = function( error ) {
+		var name, message,
+			errorString = error.toString();
+		if ( errorString.substring( 0, 7 ) === "[object" ) {
+			name = error.name ? error.name.toString() : "Error";
+			message = error.message ? error.message.toString() : "";
+			if ( name && message ) {
+				return name + ": " + message;
+			} else if ( name ) {
+				return name;
+			} else if ( message ) {
+				return message;
+			} else {
+				return "Error";
+			}
+		} else {
+			return errorString;
+		}
+	},
+	/**
+	 * Makes a clone of an object using only Array or Object as base,
+	 * and copies over the own enumerable properties.
+	 *
+	 * @param {Object} obj
+	 * @return {Object} New object with only the own properties (recursively).
+	 */
+	objectValues = function( obj ) {
+		// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
+		/*jshint newcap: false */
+		var key, val,
+			vals = QUnit.is( "array", obj ) ? [] : {};
+		for ( key in obj ) {
+			if ( hasOwn.call( obj, key ) ) {
+				val = obj[key];
+				vals[key] = val === Object(val) ? objectValues(val) : val;
+			}
+		}
+		return vals;
+	};
+
+function Test( settings ) {
+	extend( this, settings );
+	this.assertions = [];
+	this.testNumber = ++Test.count;
+}
+
+Test.count = 0;
+
+Test.prototype = {
+	init: function() {
+		var a, b, li,
+			tests = id( "qunit-tests" );
+
+		if ( tests ) {
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml;
+
+			// `a` initialized at top of scope
+			a = document.createElement( "a" );
+			a.innerHTML = "Rerun";
+			a.href = QUnit.url({ testNumber: this.testNumber });
+
+			li = document.createElement( "li" );
+			li.appendChild( b );
+			li.appendChild( a );
+			li.className = "running";
+			li.id = this.id = "qunit-test-output" + testId++;
+
+			tests.appendChild( li );
+		}
+	},
+	setup: function() {
+		if (
+			// Emit moduleStart when we're switching from one module to another
+			this.module !== config.previousModule ||
+				// They could be equal (both undefined) but if the previousModule property doesn't
+				// yet exist it means this is the first test in a suite that isn't wrapped in a
+				// module, in which case we'll just emit a moduleStart event for 'undefined'.
+				// Without this, reporters can get testStart before moduleStart  which is a problem.
+				!hasOwn.call( config, "previousModule" )
+		) {
+			if ( hasOwn.call( config, "previousModule" ) ) {
+				runLoggingCallbacks( "moduleDone", QUnit, {
+					name: config.previousModule,
+					failed: config.moduleStats.bad,
+					passed: config.moduleStats.all - config.moduleStats.bad,
+					total: config.moduleStats.all
+				});
+			}
+			config.previousModule = this.module;
+			config.moduleStats = { all: 0, bad: 0 };
+			runLoggingCallbacks( "moduleStart", QUnit, {
+				name: this.module
+			});
+		}
+
+		config.current = this;
+
+		this.testEnvironment = extend({
+			setup: function() {},
+			teardown: function() {}
+		}, this.moduleTestEnvironment );
+
+		this.started = +new Date();
+		runLoggingCallbacks( "testStart", QUnit, {
+			name: this.testName,
+			module: this.module
+		});
+
+		/*jshint camelcase:false */
+
+
+		/**
+		 * Expose the current test environment.
+		 *
+		 * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
+		 */
+		QUnit.current_testEnvironment = this.testEnvironment;
+
+		/*jshint camelcase:true */
+
+		if ( !config.pollution ) {
+			saveGlobal();
+		}
+		if ( config.notrycatch ) {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+			return;
+		}
+		try {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+		} catch( e ) {
+			QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+		}
+	},
+	run: function() {
+		config.current = this;
+
+		var running = id( "qunit-testresult" );
+
+		if ( running ) {
+			running.innerHTML = "Running: <br/>" + this.nameHtml;
+		}
+
+		if ( this.async ) {
+			QUnit.stop();
+		}
+
+		this.callbackStarted = +new Date();
+
+		if ( config.notrycatch ) {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+			return;
+		}
+
+		try {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+		} catch( e ) {
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+
+			QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
+			// else next test will carry the responsibility
+			saveGlobal();
+
+			// Restart the tests if they're blocking
+			if ( config.blocking ) {
+				QUnit.start();
+			}
+		}
+	},
+	teardown: function() {
+		config.current = this;
+		if ( config.notrycatch ) {
+			if ( typeof this.callbackRuntime === "undefined" ) {
+				this.callbackRuntime = +new Date() - this.callbackStarted;
+			}
+			this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			return;
+		} else {
+			try {
+				this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			} catch( e ) {
+				QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+			}
+		}
+		checkPollution();
+	},
+	finish: function() {
+		config.current = this;
+		if ( config.requireExpects && this.expected === null ) {
+			QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
+		} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
+			QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
+		} else if ( this.expected === null && !this.assertions.length ) {
+			QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
+		}
+
+		var i, assertion, a, b, time, li, ol,
+			test = this,
+			good = 0,
+			bad = 0,
+			tests = id( "qunit-tests" );
+
+		this.runtime = +new Date() - this.started;
+		config.stats.all += this.assertions.length;
+		config.moduleStats.all += this.assertions.length;
+
+		if ( tests ) {
+			ol = document.createElement( "ol" );
+			ol.className = "qunit-assert-list";
+
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				assertion = this.assertions[i];
+
+				li = document.createElement( "li" );
+				li.className = assertion.result ? "pass" : "fail";
+				li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
+				ol.appendChild( li );
+
+				if ( assertion.result ) {
+					good++;
+				} else {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+
+			// store result when possible
+			if ( QUnit.config.reorder && defined.sessionStorage ) {
+				if ( bad ) {
+					sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
+				} else {
+					sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
+				}
+			}
+
+			if ( bad === 0 ) {
+				addClass( ol, "qunit-collapsed" );
+			}
+
+			// `b` initialized at top of scope
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+
+			addEvent(b, "click", function() {
+				var next = b.parentNode.lastChild,
+					collapsed = hasClass( next, "qunit-collapsed" );
+				( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
+			});
+
+			addEvent(b, "dblclick", function( e ) {
+				var target = e && e.target ? e.target : window.event.srcElement;
+				if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
+					target = target.parentNode;
+				}
+				if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
+					window.location = QUnit.url({ testNumber: test.testNumber });
+				}
+			});
+
+			// `time` initialized at top of scope
+			time = document.createElement( "span" );
+			time.className = "runtime";
+			time.innerHTML = this.runtime + " ms";
+
+			// `li` initialized at top of scope
+			li = id( this.id );
+			li.className = bad ? "fail" : "pass";
+			li.removeChild( li.firstChild );
+			a = li.firstChild;
+			li.appendChild( b );
+			li.appendChild( a );
+			li.appendChild( time );
+			li.appendChild( ol );
+
+		} else {
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				if ( !this.assertions[i].result ) {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+		}
+
+		runLoggingCallbacks( "testDone", QUnit, {
+			name: this.testName,
+			module: this.module,
+			failed: bad,
+			passed: this.assertions.length - bad,
+			total: this.assertions.length,
+			duration: this.runtime
+		});
+
+		QUnit.reset();
+
+		config.current = undefined;
+	},
+
+	queue: function() {
+		var bad,
+			test = this;
+
+		synchronize(function() {
+			test.init();
+		});
+		function run() {
+			// each of these can by async
+			synchronize(function() {
+				test.setup();
+			});
+			synchronize(function() {
+				test.run();
+			});
+			synchronize(function() {
+				test.teardown();
+			});
+			synchronize(function() {
+				test.finish();
+			});
+		}
+
+		// `bad` initialized at top of scope
+		// defer when previous test run passed, if storage is available
+		bad = QUnit.config.reorder && defined.sessionStorage &&
+						+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
+
+		if ( bad ) {
+			run();
+		} else {
+			synchronize( run, true );
+		}
+	}
+};
+
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+QUnit = {
+
+	// call on start of module test to prepend name to all tests
+	module: function( name, testEnvironment ) {
+		config.currentModule = name;
+		config.currentModuleTestEnvironment = testEnvironment;
+		config.modules[name] = true;
+	},
+
+	asyncTest: function( testName, expected, callback ) {
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		QUnit.test( testName, expected, callback, true );
+	},
+
+	test: function( testName, expected, callback, async ) {
+		var test,
+			nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
+
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		if ( config.currentModule ) {
+			nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
+		}
+
+		test = new Test({
+			nameHtml: nameHtml,
+			testName: testName,
+			expected: expected,
+			async: async,
+			callback: callback,
+			module: config.currentModule,
+			moduleTestEnvironment: config.currentModuleTestEnvironment,
+			stack: sourceFromStacktrace( 2 )
+		});
+
+		if ( !validTest( test ) ) {
+			return;
+		}
+
+		test.queue();
+	},
+
+	// Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
+	expect: function( asserts ) {
+		if (arguments.length === 1) {
+			config.current.expected = asserts;
+		} else {
+			return config.current.expected;
+		}
+	},
+
+	start: function( count ) {
+		// QUnit hasn't been initialized yet.
+		// Note: RequireJS (et al) may delay onLoad
+		if ( config.semaphore === undefined ) {
+			QUnit.begin(function() {
+				// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+				setTimeout(function() {
+					QUnit.start( count );
+				});
+			});
+			return;
+		}
+
+		config.semaphore -= count || 1;
+		// don't start until equal number of stop-calls
+		if ( config.semaphore > 0 ) {
+			return;
+		}
+		// ignore if start is called more often then stop
+		if ( config.semaphore < 0 ) {
+			config.semaphore = 0;
+			QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
+			return;
+		}
+		// A slight delay, to avoid any current callbacks
+		if ( defined.setTimeout ) {
+			setTimeout(function() {
+				if ( config.semaphore > 0 ) {
+					return;
+				}
+				if ( config.timeout ) {
+					clearTimeout( config.timeout );
+				}
+
+				config.blocking = false;
+				process( true );
+			}, 13);
+		} else {
+			config.blocking = false;
+			process( true );
+		}
+	},
+
+	stop: function( count ) {
+		config.semaphore += count || 1;
+		config.blocking = true;
+
+		if ( config.testTimeout && defined.setTimeout ) {
+			clearTimeout( config.timeout );
+			config.timeout = setTimeout(function() {
+				QUnit.ok( false, "Test timed out" );
+				config.semaphore = 1;
+				QUnit.start();
+			}, config.testTimeout );
+		}
+	}
+};
+
+// `assert` initialized at top of scope
+// Assert helpers
+// All of these must either call QUnit.push() or manually do:
+// - runLoggingCallbacks( "log", .. );
+// - config.current.assertions.push({ .. });
+// We attach it to the QUnit object *after* we expose the public API,
+// otherwise `assert` will become a global variable in browsers (#341).
+assert = {
+	/**
+	 * Asserts rough true-ish result.
+	 * @name ok
+	 * @function
+	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+	 */
+	ok: function( result, msg ) {
+		if ( !config.current ) {
+			throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+		result = !!result;
+		msg = msg || (result ? "okay" : "failed" );
+
+		var source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: msg
+			};
+
+		msg = "<span class='test-message'>" + escapeText( msg ) + "</span>";
+
+		if ( !result ) {
+			source = sourceFromStacktrace( 2 );
+			if ( source ) {
+				details.source = source;
+				msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
+			}
+		}
+		runLoggingCallbacks( "log", QUnit, details );
+		config.current.assertions.push({
+			result: result,
+			message: msg
+		});
+	},
+
+	/**
+	 * Assert that the first two arguments are equal, with an optional message.
+	 * Prints out both actual and expected values.
+	 * @name equal
+	 * @function
+	 * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
+	 */
+	equal: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected == actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notEqual
+	 * @function
+	 */
+	notEqual: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected != actual, actual, expected, message );
+	},
+
+	/**
+	 * @name propEqual
+	 * @function
+	 */
+	propEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notPropEqual
+	 * @function
+	 */
+	notPropEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name deepEqual
+	 * @function
+	 */
+	deepEqual: function( actual, expected, message ) {
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notDeepEqual
+	 * @function
+	 */
+	notDeepEqual: function( actual, expected, message ) {
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name strictEqual
+	 * @function
+	 */
+	strictEqual: function( actual, expected, message ) {
+		QUnit.push( expected === actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notStrictEqual
+	 * @function
+	 */
+	notStrictEqual: function( actual, expected, message ) {
+		QUnit.push( expected !== actual, actual, expected, message );
+	},
+
+	"throws": function( block, expected, message ) {
+		var actual,
+			expectedOutput = expected,
+			ok = false;
+
+		// 'expected' is optional
+		if ( typeof expected === "string" ) {
+			message = expected;
+			expected = null;
+		}
+
+		config.current.ignoreGlobalErrors = true;
+		try {
+			block.call( config.current.testEnvironment );
+		} catch (e) {
+			actual = e;
+		}
+		config.current.ignoreGlobalErrors = false;
+
+		if ( actual ) {
+			// we don't want to validate thrown error
+			if ( !expected ) {
+				ok = true;
+				expectedOutput = null;
+			// expected is a regexp
+			} else if ( QUnit.objectType( expected ) === "regexp" ) {
+				ok = expected.test( errorString( actual ) );
+			// expected is a constructor
+			} else if ( actual instanceof expected ) {
+				ok = true;
+			// expected is a validation function which returns true is validation passed
+			} else if ( expected.call( {}, actual ) === true ) {
+				expectedOutput = null;
+				ok = true;
+			}
+
+			QUnit.push( ok, actual, expectedOutput, message );
+		} else {
+			QUnit.pushFailure( message, null, "No exception was thrown." );
+		}
+	}
+};
+
+/**
+ * @deprecated since 1.8.0
+ * Kept assertion helpers in root for backwards compatibility.
+ */
+extend( QUnit, assert );
+
+/**
+ * @deprecated since 1.9.0
+ * Kept root "raises()" for backwards compatibility.
+ * (Note that we don't introduce assert.raises).
+ */
+QUnit.raises = assert[ "throws" ];
+
+/**
+ * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
+ * Kept to avoid TypeErrors for undefined methods.
+ */
+QUnit.equals = function() {
+	QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
+};
+QUnit.same = function() {
+	QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
+};
+
+// We want access to the constructor's prototype
+(function() {
+	function F() {}
+	F.prototype = QUnit;
+	QUnit = new F();
+	// Make F QUnit's constructor so that we can add to the prototype later
+	QUnit.constructor = F;
+}());
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+	// The queue of tests to run
+	queue: [],
+
+	// block until document ready
+	blocking: true,
+
+	// when enabled, show only failing tests
+	// gets persisted through sessionStorage and can be changed in UI via checkbox
+	hidepassed: false,
+
+	// by default, run previously failed tests first
+	// very useful in combination with "Hide passed tests" checked
+	reorder: true,
+
+	// by default, modify document.title when suite is done
+	altertitle: true,
+
+	// when enabled, all tests must call expect()
+	requireExpects: false,
+
+	// add checkboxes that are persisted in the query-string
+	// when enabled, the id is set to `true` as a `QUnit.config` property
+	urlConfig: [
+		{
+			id: "noglobals",
+			label: "Check for Globals",
+			tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
+		},
+		{
+			id: "notrycatch",
+			label: "No try-catch",
+			tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
+		}
+	],
+
+	// Set of all modules.
+	modules: {},
+
+	// logging callback queues
+	begin: [],
+	done: [],
+	log: [],
+	testStart: [],
+	testDone: [],
+	moduleStart: [],
+	moduleDone: []
+};
+
+// Export global variables, unless an 'exports' object exists,
+// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
+if ( typeof exports === "undefined" ) {
+	extend( window, QUnit.constructor.prototype );
+
+	// Expose QUnit object
+	window.QUnit = QUnit;
+}
+
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+	var i,
+		location = window.location || { search: "", protocol: "file:" },
+		params = location.search.slice( 1 ).split( "&" ),
+		length = params.length,
+		urlParams = {},
+		current;
+
+	if ( params[ 0 ] ) {
+		for ( i = 0; i < length; i++ ) {
+			current = params[ i ].split( "=" );
+			current[ 0 ] = decodeURIComponent( current[ 0 ] );
+			// allow just a key to turn on a flag, e.g., test.html?noglobals
+			current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
+			urlParams[ current[ 0 ] ] = current[ 1 ];
+		}
+	}
+
+	QUnit.urlParams = urlParams;
+
+	// String search anywhere in moduleName+testName
+	config.filter = urlParams.filter;
+
+	// Exact match of the module name
+	config.module = urlParams.module;
+
+	config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
+
+	// Figure out if we're running the tests from a server or not
+	QUnit.isLocal = location.protocol === "file:";
+}());
+
+// Extend QUnit object,
+// these after set here because they should not be exposed as global functions
+extend( QUnit, {
+	assert: assert,
+
+	config: config,
+
+	// Initialize the configuration options
+	init: function() {
+		extend( config, {
+			stats: { all: 0, bad: 0 },
+			moduleStats: { all: 0, bad: 0 },
+			started: +new Date(),
+			updateRate: 1000,
+			blocking: false,
+			autostart: true,
+			autorun: false,
+			filter: "",
+			queue: [],
+			semaphore: 1
+		});
+
+		var tests, banner, result,
+			qunit = id( "qunit" );
+
+		if ( qunit ) {
+			qunit.innerHTML =
+				"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+				"<h2 id='qunit-banner'></h2>" +
+				"<div id='qunit-testrunner-toolbar'></div>" +
+				"<h2 id='qunit-userAgent'></h2>" +
+				"<ol id='qunit-tests'></ol>";
+		}
+
+		tests = id( "qunit-tests" );
+		banner = id( "qunit-banner" );
+		result = id( "qunit-testresult" );
+
+		if ( tests ) {
+			tests.innerHTML = "";
+		}
+
+		if ( banner ) {
+			banner.className = "";
+		}
+
+		if ( result ) {
+			result.parentNode.removeChild( result );
+		}
+
+		if ( tests ) {
+			result = document.createElement( "p" );
+			result.id = "qunit-testresult";
+			result.className = "result";
+			tests.parentNode.insertBefore( result, tests );
+			result.innerHTML = "Running...<br/>&nbsp;";
+		}
+	},
+
+	// Resets the test setup. Useful for tests that modify the DOM.
+	/*
+	DEPRECATED: Use multiple tests instead of resetting inside a test.
+	Use testStart or testDone for custom cleanup.
+	This method will throw an error in 2.0, and will be removed in 2.1
+	*/
+	reset: function() {
+		var fixture = id( "qunit-fixture" );
+		if ( fixture ) {
+			fixture.innerHTML = config.fixture;
+		}
+	},
+
+	// Trigger an event on an element.
+	// @example triggerEvent( document.body, "click" );
+	triggerEvent: function( elem, type, event ) {
+		if ( document.createEvent ) {
+			event = document.createEvent( "MouseEvents" );
+			event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+				0, 0, 0, 0, 0, false, false, false, false, 0, null);
+
+			elem.dispatchEvent( event );
+		} else if ( elem.fireEvent ) {
+			elem.fireEvent( "on" + type );
+		}
+	},
+
+	// Safe object type checking
+	is: function( type, obj ) {
+		return QUnit.objectType( obj ) === type;
+	},
+
+	objectType: function( obj ) {
+		if ( typeof obj === "undefined" ) {
+				return "undefined";
+		// consider: typeof null === object
+		}
+		if ( obj === null ) {
+				return "null";
+		}
+
+		var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+			type = match && match[1] || "";
+
+		switch ( type ) {
+			case "Number":
+				if ( isNaN(obj) ) {
+					return "nan";
+				}
+				return "number";
+			case "String":
+			case "Boolean":
+			case "Array":
+			case "Date":
+			case "RegExp":
+			case "Function":
+				return type.toLowerCase();
+		}
+		if ( typeof obj === "object" ) {
+			return "object";
+		}
+		return undefined;
+	},
+
+	push: function( result, actual, expected, message ) {
+		if ( !config.current ) {
+			throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
+		}
+
+		var output, source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: message,
+				actual: actual,
+				expected: expected
+			};
+
+		message = escapeText( message ) || ( result ? "okay" : "failed" );
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		if ( !result ) {
+			expected = escapeText( QUnit.jsDump.parse(expected) );
+			actual = escapeText( QUnit.jsDump.parse(actual) );
+			output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
+
+			if ( actual !== expected ) {
+				output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
+				output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
+			}
+
+			source = sourceFromStacktrace();
+
+			if ( source ) {
+				details.source = source;
+				output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+			}
+
+			output += "</table>";
+		}
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: !!result,
+			message: output
+		});
+	},
+
+	pushFailure: function( message, source, actual ) {
+		if ( !config.current ) {
+			throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+
+		var output,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: false,
+				message: message
+			};
+
+		message = escapeText( message ) || "error";
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		output += "<table>";
+
+		if ( actual ) {
+			output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
+		}
+
+		if ( source ) {
+			details.source = source;
+			output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+		}
+
+		output += "</table>";
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: false,
+			message: output
+		});
+	},
+
+	url: function( params ) {
+		params = extend( extend( {}, QUnit.urlParams ), params );
+		var key,
+			querystring = "?";
+
+		for ( key in params ) {
+			if ( hasOwn.call( params, key ) ) {
+				querystring += encodeURIComponent( key ) + "=" +
+					encodeURIComponent( params[ key ] ) + "&";
+			}
+		}
+		return window.location.protocol + "//" + window.location.host +
+			window.location.pathname + querystring.slice( 0, -1 );
+	},
+
+	extend: extend,
+	id: id,
+	addEvent: addEvent,
+	addClass: addClass,
+	hasClass: hasClass,
+	removeClass: removeClass
+	// load, equiv, jsDump, diff: Attached later
+});
+
+/**
+ * @deprecated: Created for backwards compatibility with test runner that set the hook function
+ * into QUnit.{hook}, instead of invoking it and passing the hook function.
+ * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
+ * Doing this allows us to tell if the following methods have been overwritten on the actual
+ * QUnit object.
+ */
+extend( QUnit.constructor.prototype, {
+
+	// Logging callbacks; all receive a single argument with the listed properties
+	// run test/logs.html for any related changes
+	begin: registerLoggingCallback( "begin" ),
+
+	// done: { failed, passed, total, runtime }
+	done: registerLoggingCallback( "done" ),
+
+	// log: { result, actual, expected, message }
+	log: registerLoggingCallback( "log" ),
+
+	// testStart: { name }
+	testStart: registerLoggingCallback( "testStart" ),
+
+	// testDone: { name, failed, passed, total, duration }
+	testDone: registerLoggingCallback( "testDone" ),
+
+	// moduleStart: { name }
+	moduleStart: registerLoggingCallback( "moduleStart" ),
+
+	// moduleDone: { name, failed, passed, total }
+	moduleDone: registerLoggingCallback( "moduleDone" )
+});
+
+if ( typeof document === "undefined" || document.readyState === "complete" ) {
+	config.autorun = true;
+}
+
+QUnit.load = function() {
+	runLoggingCallbacks( "begin", QUnit, {} );
+
+	// Initialize the config, saving the execution queue
+	var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
+		urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
+		numModules = 0,
+		moduleNames = [],
+		moduleFilterHtml = "",
+		urlConfigHtml = "",
+		oldconfig = extend( {}, config );
+
+	QUnit.init();
+	extend(config, oldconfig);
+
+	config.blocking = false;
+
+	len = config.urlConfig.length;
+
+	for ( i = 0; i < len; i++ ) {
+		val = config.urlConfig[i];
+		if ( typeof val === "string" ) {
+			val = {
+				id: val,
+				label: val,
+				tooltip: "[no tooltip available]"
+			};
+		}
+		config[ val.id ] = QUnit.urlParams[ val.id ];
+		urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
+			"' name='" + escapeText( val.id ) +
+			"' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
+			" title='" + escapeText( val.tooltip ) +
+			"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
+			"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
+	}
+	for ( i in config.modules ) {
+		if ( config.modules.hasOwnProperty( i ) ) {
+			moduleNames.push(i);
+		}
+	}
+	numModules = moduleNames.length;
+	moduleNames.sort( function( a, b ) {
+		return a.localeCompare( b );
+	});
+	moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+		( config.module === undefined  ? "selected='selected'" : "" ) +
+		">< All Modules ></option>";
+
+
+	for ( i = 0; i < numModules; i++) {
+			moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " +
+				( config.module === moduleNames[i] ? "selected='selected'" : "" ) +
+				">" + escapeText(moduleNames[i]) + "</option>";
+	}
+	moduleFilterHtml += "</select>";
+
+	// `userAgent` initialized at top of scope
+	userAgent = id( "qunit-userAgent" );
+	if ( userAgent ) {
+		userAgent.innerHTML = navigator.userAgent;
+	}
+
+	// `banner` initialized at top of scope
+	banner = id( "qunit-header" );
+	if ( banner ) {
+		banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
+	}
+
+	// `toolbar` initialized at top of scope
+	toolbar = id( "qunit-testrunner-toolbar" );
+	if ( toolbar ) {
+		// `filter` initialized at top of scope
+		filter = document.createElement( "input" );
+		filter.type = "checkbox";
+		filter.id = "qunit-filter-pass";
+
+		addEvent( filter, "click", function() {
+			var tmp,
+				ol = document.getElementById( "qunit-tests" );
+
+			if ( filter.checked ) {
+				ol.className = ol.className + " hidepass";
+			} else {
+				tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
+				ol.className = tmp.replace( / hidepass /, " " );
+			}
+			if ( defined.sessionStorage ) {
+				if (filter.checked) {
+					sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+				} else {
+					sessionStorage.removeItem( "qunit-filter-passed-tests" );
+				}
+			}
+		});
+
+		if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
+			filter.checked = true;
+			// `ol` initialized at top of scope
+			ol = document.getElementById( "qunit-tests" );
+			ol.className = ol.className + " hidepass";
+		}
+		toolbar.appendChild( filter );
+
+		// `label` initialized at top of scope
+		label = document.createElement( "label" );
+		label.setAttribute( "for", "qunit-filter-pass" );
+		label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
+		label.innerHTML = "Hide passed tests";
+		toolbar.appendChild( label );
+
+		urlConfigCheckboxesContainer = document.createElement("span");
+		urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
+		urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
+		// For oldIE support:
+		// * Add handlers to the individual elements instead of the container
+		// * Use "click" instead of "change"
+		// * Fallback from event.target to event.srcElement
+		addEvents( urlConfigCheckboxes, "click", function( event ) {
+			var params = {},
+				target = event.target || event.srcElement;
+			params[ target.name ] = target.checked ? true : undefined;
+			window.location = QUnit.url( params );
+		});
+		toolbar.appendChild( urlConfigCheckboxesContainer );
+
+		if (numModules > 1) {
+			moduleFilter = document.createElement( "span" );
+			moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+			moduleFilter.innerHTML = moduleFilterHtml;
+			addEvent( moduleFilter.lastChild, "change", function() {
+				var selectBox = moduleFilter.getElementsByTagName("select")[0],
+					selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+				window.location = QUnit.url({
+					module: ( selectedModule === "" ) ? undefined : selectedModule,
+					// Remove any existing filters
+					filter: undefined,
+					testNumber: undefined
+				});
+			});
+			toolbar.appendChild(moduleFilter);
+		}
+	}
+
+	// `main` initialized at top of scope
+	main = id( "qunit-fixture" );
+	if ( main ) {
+		config.fixture = main.innerHTML;
+	}
+
+	if ( config.autostart ) {
+		QUnit.start();
+	}
+};
+
+addEvent( window, "load", QUnit.load );
+
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will suppress the default browser handler,
+// returning false will let it run.
+window.onerror = function ( error, filePath, linerNr ) {
+	var ret = false;
+	if ( onErrorFnPrev ) {
+		ret = onErrorFnPrev( error, filePath, linerNr );
+	}
+
+	// Treat return value as window.onerror itself does,
+	// Only do our handling if not suppressed.
+	if ( ret !== true ) {
+		if ( QUnit.config.current ) {
+			if ( QUnit.config.current.ignoreGlobalErrors ) {
+				return true;
+			}
+			QUnit.pushFailure( error, filePath + ":" + linerNr );
+		} else {
+			QUnit.test( "global failure", extend( function() {
+				QUnit.pushFailure( error, filePath + ":" + linerNr );
+			}, { validTest: validTest } ) );
+		}
+		return false;
+	}
+
+	return ret;
+};
+
+function done() {
+	config.autorun = true;
+
+	// Log the last module results
+	if ( config.currentModule ) {
+		runLoggingCallbacks( "moduleDone", QUnit, {
+			name: config.currentModule,
+			failed: config.moduleStats.bad,
+			passed: config.moduleStats.all - config.moduleStats.bad,
+			total: config.moduleStats.all
+		});
+	}
+	delete config.previousModule;
+
+	var i, key,
+		banner = id( "qunit-banner" ),
+		tests = id( "qunit-tests" ),
+		runtime = +new Date() - config.started,
+		passed = config.stats.all - config.stats.bad,
+		html = [
+			"Tests completed in ",
+			runtime,
+			" milliseconds.<br/>",
+			"<span class='passed'>",
+			passed,
+			"</span> assertions of <span class='total'>",
+			config.stats.all,
+			"</span> passed, <span class='failed'>",
+			config.stats.bad,
+			"</span> failed."
+		].join( "" );
+
+	if ( banner ) {
+		banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
+	}
+
+	if ( tests ) {
+		id( "qunit-testresult" ).innerHTML = html;
+	}
+
+	if ( config.altertitle && typeof document !== "undefined" && document.title ) {
+		// show ✖ for good, ✔ for bad suite result in title
+		// use escape sequences in case file gets loaded with non-utf-8-charset
+		document.title = [
+			( config.stats.bad ? "\u2716" : "\u2714" ),
+			document.title.replace( /^[\u2714\u2716] /i, "" )
+		].join( " " );
+	}
+
+	// clear own sessionStorage items if all tests passed
+	if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
+		// `key` & `i` initialized at top of scope
+		for ( i = 0; i < sessionStorage.length; i++ ) {
+			key = sessionStorage.key( i++ );
+			if ( key.indexOf( "qunit-test-" ) === 0 ) {
+				sessionStorage.removeItem( key );
+			}
+		}
+	}
+
+	// scroll back to top to show results
+	if ( window.scrollTo ) {
+		window.scrollTo(0, 0);
+	}
+
+	runLoggingCallbacks( "done", QUnit, {
+		failed: config.stats.bad,
+		passed: passed,
+		total: config.stats.all,
+		runtime: runtime
+	});
+}
+
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+	var include,
+		filter = config.filter && config.filter.toLowerCase(),
+		module = config.module && config.module.toLowerCase(),
+		fullName = (test.module + ": " + test.testName).toLowerCase();
+
+	// Internally-generated tests are always valid
+	if ( test.callback && test.callback.validTest === validTest ) {
+		delete test.callback.validTest;
+		return true;
+	}
+
+	if ( config.testNumber ) {
+		return test.testNumber === config.testNumber;
+	}
+
+	if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
+		return false;
+	}
+
+	if ( !filter ) {
+		return true;
+	}
+
+	include = filter.charAt( 0 ) !== "!";
+	if ( !include ) {
+		filter = filter.slice( 1 );
+	}
+
+	// If the filter matches, we need to honour include
+	if ( fullName.indexOf( filter ) !== -1 ) {
+		return include;
+	}
+
+	// Otherwise, do the opposite
+	return !include;
+}
+
+// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
+// Later Safari and IE10 are supposed to support error.stack as well
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+	offset = offset === undefined ? 3 : offset;
+
+	var stack, include, i;
+
+	if ( e.stacktrace ) {
+		// Opera
+		return e.stacktrace.split( "\n" )[ offset + 3 ];
+	} else if ( e.stack ) {
+		// Firefox, Chrome
+		stack = e.stack.split( "\n" );
+		if (/^error$/i.test( stack[0] ) ) {
+			stack.shift();
+		}
+		if ( fileName ) {
+			include = [];
+			for ( i = offset; i < stack.length; i++ ) {
+				if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+					break;
+				}
+				include.push( stack[ i ] );
+			}
+			if ( include.length ) {
+				return include.join( "\n" );
+			}
+		}
+		return stack[ offset ];
+	} else if ( e.sourceURL ) {
+		// Safari, PhantomJS
+		// hopefully one day Safari provides actual stacktraces
+		// exclude useless self-reference for generated Error objects
+		if ( /qunit.js$/.test( e.sourceURL ) ) {
+			return;
+		}
+		// for actual exceptions, this is useful
+		return e.sourceURL + ":" + e.line;
+	}
+}
+function sourceFromStacktrace( offset ) {
+	try {
+		throw new Error();
+	} catch ( e ) {
+		return extractStacktrace( e, offset );
+	}
+}
+
+/**
+ * Escape text for attribute or text content.
+ */
+function escapeText( s ) {
+	if ( !s ) {
+		return "";
+	}
+	s = s + "";
+	// Both single quotes and double quotes (for attributes)
+	return s.replace( /['"<>&]/g, function( s ) {
+		switch( s ) {
+			case "'":
+				return "&#039;";
+			case "\"":
+				return "&quot;";
+			case "<":
+				return "&lt;";
+			case ">":
+				return "&gt;";
+			case "&":
+				return "&amp;";
+		}
+	});
+}
+
+function synchronize( callback, last ) {
+	config.queue.push( callback );
+
+	if ( config.autorun && !config.blocking ) {
+		process( last );
+	}
+}
+
+function process( last ) {
+	function next() {
+		process( last );
+	}
+	var start = new Date().getTime();
+	config.depth = config.depth ? config.depth + 1 : 1;
+
+	while ( config.queue.length && !config.blocking ) {
+		if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
+			config.queue.shift()();
+		} else {
+			setTimeout( next, 13 );
+			break;
+		}
+	}
+	config.depth--;
+	if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+		done();
+	}
+}
+
+function saveGlobal() {
+	config.pollution = [];
+
+	if ( config.noglobals ) {
+		for ( var key in window ) {
+			if ( hasOwn.call( window, key ) ) {
+				// in Opera sometimes DOM element ids show up here, ignore them
+				if ( /^qunit-test-output/.test( key ) ) {
+					continue;
+				}
+				config.pollution.push( key );
+			}
+		}
+	}
+}
+
+function checkPollution() {
+	var newGlobals,
+		deletedGlobals,
+		old = config.pollution;
+
+	saveGlobal();
+
+	newGlobals = diff( config.pollution, old );
+	if ( newGlobals.length > 0 ) {
+		QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
+	}
+
+	deletedGlobals = diff( old, config.pollution );
+	if ( deletedGlobals.length > 0 ) {
+		QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
+	}
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+	var i, j,
+		result = a.slice();
+
+	for ( i = 0; i < result.length; i++ ) {
+		for ( j = 0; j < b.length; j++ ) {
+			if ( result[i] === b[j] ) {
+				result.splice( i, 1 );
+				i--;
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+function extend( a, b ) {
+	for ( var prop in b ) {
+		if ( hasOwn.call( b, prop ) ) {
+			// Avoid "Member not found" error in IE8 caused by messing with window.constructor
+			if ( !( prop === "constructor" && a === window ) ) {
+				if ( b[ prop ] === undefined ) {
+					delete a[ prop ];
+				} else {
+					a[ prop ] = b[ prop ];
+				}
+			}
+		}
+	}
+
+	return a;
+}
+
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+	// Standards-based browsers
+	if ( elem.addEventListener ) {
+		elem.addEventListener( type, fn, false );
+	// IE
+	} else {
+		elem.attachEvent( "on" + type, fn );
+	}
+}
+
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+	var i = elems.length;
+	while ( i-- ) {
+		addEvent( elems[i], type, fn );
+	}
+}
+
+function hasClass( elem, name ) {
+	return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
+}
+
+function addClass( elem, name ) {
+	if ( !hasClass( elem, name ) ) {
+		elem.className += (elem.className ? " " : "") + name;
+	}
+}
+
+function removeClass( elem, name ) {
+	var set = " " + elem.className + " ";
+	// Class name may appear multiple times
+	while ( set.indexOf(" " + name + " ") > -1 ) {
+		set = set.replace(" " + name + " " , " ");
+	}
+	// If possible, trim it for prettiness, but not necessarily
+	elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
+}
+
+function id( name ) {
+	return !!( typeof document !== "undefined" && document && document.getElementById ) &&
+		document.getElementById( name );
+}
+
+function registerLoggingCallback( key ) {
+	return function( callback ) {
+		config[key].push( callback );
+	};
+}
+
+// Supports deprecated method of completely overwriting logging callbacks
+function runLoggingCallbacks( key, scope, args ) {
+	var i, callbacks;
+	if ( QUnit.hasOwnProperty( key ) ) {
+		QUnit[ key ].call(scope, args );
+	} else {
+		callbacks = config[ key ];
+		for ( i = 0; i < callbacks.length; i++ ) {
+			callbacks[ i ].call( scope, args );
+		}
+	}
+}
+
+// Test for equality any JavaScript type.
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = (function() {
+
+	// Call the o related callback with the given arguments.
+	function bindCallbacks( o, callbacks, args ) {
+		var prop = QUnit.objectType( o );
+		if ( prop ) {
+			if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
+				return callbacks[ prop ].apply( callbacks, args );
+			} else {
+				return callbacks[ prop ]; // or undefined
+			}
+		}
+	}
+
+	// the real equiv function
+	var innerEquiv,
+		// stack to decide between skip/abort functions
+		callers = [],
+		// stack to avoiding loops from circular referencing
+		parents = [],
+		parentsB = [],
+
+		getProto = Object.getPrototypeOf || function ( obj ) {
+			/*jshint camelcase:false */
+			return obj.__proto__;
+		},
+		callbacks = (function () {
+
+			// for string, boolean, number and null
+			function useStrictEquality( b, a ) {
+				/*jshint eqeqeq:false */
+				if ( b instanceof a.constructor || a instanceof b.constructor ) {
+					// to catch short annotation VS 'new' annotation of a
+					// declaration
+					// e.g. var i = 1;
+					// var j = new Number(1);
+					return a == b;
+				} else {
+					return a === b;
+				}
+			}
+
+			return {
+				"string": useStrictEquality,
+				"boolean": useStrictEquality,
+				"number": useStrictEquality,
+				"null": useStrictEquality,
+				"undefined": useStrictEquality,
+
+				"nan": function( b ) {
+					return isNaN( b );
+				},
+
+				"date": function( b, a ) {
+					return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
+				},
+
+				"regexp": function( b, a ) {
+					return QUnit.objectType( b ) === "regexp" &&
+						// the regex itself
+						a.source === b.source &&
+						// and its modifiers
+						a.global === b.global &&
+						// (gmi) ...
+						a.ignoreCase === b.ignoreCase &&
+						a.multiline === b.multiline &&
+						a.sticky === b.sticky;
+				},
+
+				// - skip when the property is a method of an instance (OOP)
+				// - abort otherwise,
+				// initial === would have catch identical references anyway
+				"function": function() {
+					var caller = callers[callers.length - 1];
+					return caller !== Object && typeof caller !== "undefined";
+				},
+
+				"array": function( b, a ) {
+					var i, j, len, loop, aCircular, bCircular;
+
+					// b could be an object literal here
+					if ( QUnit.objectType( b ) !== "array" ) {
+						return false;
+					}
+
+					len = a.length;
+					if ( len !== b.length ) {
+						// safe and faster
+						return false;
+					}
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+					for ( i = 0; i < len; i++ ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									parents.pop();
+									parentsB.pop();
+									return false;
+								}
+							}
+						}
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							parents.pop();
+							parentsB.pop();
+							return false;
+						}
+					}
+					parents.pop();
+					parentsB.pop();
+					return true;
+				},
+
+				"object": function( b, a ) {
+					/*jshint forin:false */
+					var i, j, loop, aCircular, bCircular,
+						// Default to true
+						eq = true,
+						aProperties = [],
+						bProperties = [];
+
+					// comparing constructors is more strict than using
+					// instanceof
+					if ( a.constructor !== b.constructor ) {
+						// Allow objects with no prototype to be equivalent to
+						// objects with Object as their constructor.
+						if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
+							( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
+								return false;
+						}
+					}
+
+					// stack constructor before traversing properties
+					callers.push( a.constructor );
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+
+					// be strict: don't ensure hasOwnProperty and go deep
+					for ( i in a ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									eq = false;
+									break;
+								}
+							}
+						}
+						aProperties.push(i);
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							eq = false;
+							break;
+						}
+					}
+
+					parents.pop();
+					parentsB.pop();
+					callers.pop(); // unstack, we are done
+
+					for ( i in b ) {
+						bProperties.push( i ); // collect b's properties
+					}
+
+					// Ensures identical properties name
+					return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
+				}
+			};
+		}());
+
+	innerEquiv = function() { // can take multiple arguments
+		var args = [].slice.apply( arguments );
+		if ( args.length < 2 ) {
+			return true; // end transition
+		}
+
+		return (function( a, b ) {
+			if ( a === b ) {
+				return true; // catch the most you can
+			} else if ( a === null || b === null || typeof a === "undefined" ||
+					typeof b === "undefined" ||
+					QUnit.objectType(a) !== QUnit.objectType(b) ) {
+				return false; // don't lose time with error prone cases
+			} else {
+				return bindCallbacks(a, callbacks, [ b, a ]);
+			}
+
+			// apply transition with (1..n) arguments
+		}( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) );
+	};
+
+	return innerEquiv;
+}());
+
+/**
+ * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
+ * http://flesler.blogspot.com Licensed under BSD
+ * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
+ *
+ * @projectDescription Advanced and extensible data dumping for Javascript.
+ * @version 1.0.0
+ * @author Ariel Flesler
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
+ */
+QUnit.jsDump = (function() {
+	function quote( str ) {
+		return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
+	}
+	function literal( o ) {
+		return o + "";
+	}
+	function join( pre, arr, post ) {
+		var s = jsDump.separator(),
+			base = jsDump.indent(),
+			inner = jsDump.indent(1);
+		if ( arr.join ) {
+			arr = arr.join( "," + s + inner );
+		}
+		if ( !arr ) {
+			return pre + post;
+		}
+		return [ pre, inner + arr, base + post ].join(s);
+	}
+	function array( arr, stack ) {
+		var i = arr.length, ret = new Array(i);
+		this.up();
+		while ( i-- ) {
+			ret[i] = this.parse( arr[i] , undefined , stack);
+		}
+		this.down();
+		return join( "[", ret, "]" );
+	}
+
+	var reName = /^function (\w+)/,
+		jsDump = {
+			// type is used mostly internally, you can fix a (custom)type in advance
+			parse: function( obj, type, stack ) {
+				stack = stack || [ ];
+				var inStack, res,
+					parser = this.parsers[ type || this.typeOf(obj) ];
+
+				type = typeof parser;
+				inStack = inArray( obj, stack );
+
+				if ( inStack !== -1 ) {
+					return "recursion(" + (inStack - stack.length) + ")";
+				}
+				if ( type === "function" )  {
+					stack.push( obj );
+					res = parser.call( this, obj, stack );
+					stack.pop();
+					return res;
+				}
+				return ( type === "string" ) ? parser : this.parsers.error;
+			},
+			typeOf: function( obj ) {
+				var type;
+				if ( obj === null ) {
+					type = "null";
+				} else if ( typeof obj === "undefined" ) {
+					type = "undefined";
+				} else if ( QUnit.is( "regexp", obj) ) {
+					type = "regexp";
+				} else if ( QUnit.is( "date", obj) ) {
+					type = "date";
+				} else if ( QUnit.is( "function", obj) ) {
+					type = "function";
+				} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
+					type = "window";
+				} else if ( obj.nodeType === 9 ) {
+					type = "document";
+				} else if ( obj.nodeType ) {
+					type = "node";
+				} else if (
+					// native arrays
+					toString.call( obj ) === "[object Array]" ||
+					// NodeList objects
+					( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
+				) {
+					type = "array";
+				} else if ( obj.constructor === Error.prototype.constructor ) {
+					type = "error";
+				} else {
+					type = typeof obj;
+				}
+				return type;
+			},
+			separator: function() {
+				return this.multiline ?	this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
+			},
+			// extra can be a number, shortcut for increasing-calling-decreasing
+			indent: function( extra ) {
+				if ( !this.multiline ) {
+					return "";
+				}
+				var chr = this.indentChar;
+				if ( this.HTML ) {
+					chr = chr.replace( /\t/g, "   " ).replace( / /g, "&nbsp;" );
+				}
+				return new Array( this.depth + ( extra || 0 ) ).join(chr);
+			},
+			up: function( a ) {
+				this.depth += a || 1;
+			},
+			down: function( a ) {
+				this.depth -= a || 1;
+			},
+			setParser: function( name, parser ) {
+				this.parsers[name] = parser;
+			},
+			// The next 3 are exposed so you can use them
+			quote: quote,
+			literal: literal,
+			join: join,
+			//
+			depth: 1,
+			// This is the list of parsers, to modify them, use jsDump.setParser
+			parsers: {
+				window: "[Window]",
+				document: "[Document]",
+				error: function(error) {
+					return "Error(\"" + error.message + "\")";
+				},
+				unknown: "[Unknown]",
+				"null": "null",
+				"undefined": "undefined",
+				"function": function( fn ) {
+					var ret = "function",
+						// functions never have name in IE
+						name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
+
+					if ( name ) {
+						ret += " " + name;
+					}
+					ret += "( ";
+
+					ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
+					return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
+				},
+				array: array,
+				nodelist: array,
+				"arguments": array,
+				object: function( map, stack ) {
+					/*jshint forin:false */
+					var ret = [ ], keys, key, val, i;
+					QUnit.jsDump.up();
+					keys = [];
+					for ( key in map ) {
+						keys.push( key );
+					}
+					keys.sort();
+					for ( i = 0; i < keys.length; i++ ) {
+						key = keys[ i ];
+						val = map[ key ];
+						ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
+					}
+					QUnit.jsDump.down();
+					return join( "{", ret, "}" );
+				},
+				node: function( node ) {
+					var len, i, val,
+						open = QUnit.jsDump.HTML ? "&lt;" : "<",
+						close = QUnit.jsDump.HTML ? "&gt;" : ">",
+						tag = node.nodeName.toLowerCase(),
+						ret = open + tag,
+						attrs = node.attributes;
+
+					if ( attrs ) {
+						for ( i = 0, len = attrs.length; i < len; i++ ) {
+							val = attrs[i].nodeValue;
+							// IE6 includes all attributes in .attributes, even ones not explicitly set.
+							// Those have values like undefined, null, 0, false, "" or "inherit".
+							if ( val && val !== "inherit" ) {
+								ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
+							}
+						}
+					}
+					ret += close;
+
+					// Show content of TextNode or CDATASection
+					if ( node.nodeType === 3 || node.nodeType === 4 ) {
+						ret += node.nodeValue;
+					}
+
+					return ret + open + "/" + tag + close;
+				},
+				// function calls it internally, it's the arguments part of the function
+				functionArgs: function( fn ) {
+					var args,
+						l = fn.length;
+
+					if ( !l ) {
+						return "";
+					}
+
+					args = new Array(l);
+					while ( l-- ) {
+						// 97 is 'a'
+						args[l] = String.fromCharCode(97+l);
+					}
+					return " " + args.join( ", " ) + " ";
+				},
+				// object calls it internally, the key part of an item in a map
+				key: quote,
+				// function calls it internally, it's the content of the function
+				functionCode: "[code]",
+				// node calls it internally, it's an html attribute value
+				attribute: quote,
+				string: quote,
+				date: quote,
+				regexp: literal,
+				number: literal,
+				"boolean": literal
+			},
+			// if true, entities are escaped ( <, >, \t, space and \n )
+			HTML: false,
+			// indentation unit
+			indentChar: "  ",
+			// if true, items in a collection, are separated by a \n, else just a space.
+			multiline: true
+		};
+
+	return jsDump;
+}());
+
+// from jquery.js
+function inArray( elem, array ) {
+	if ( array.indexOf ) {
+		return array.indexOf( elem );
+	}
+
+	for ( var i = 0, length = array.length; i < length; i++ ) {
+		if ( array[ i ] === elem ) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/*
+ * Javascript Diff Algorithm
+ *  By John Resig (http://ejohn.org/)
+ *  Modified by Chu Alan "sprite"
+ *
+ * Released under the MIT license.
+ *
+ * More Info:
+ *  http://ejohn.org/projects/javascript-diff-algorithm/
+ *
+ * Usage: QUnit.diff(expected, actual)
+ *
+ * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
+ */
+QUnit.diff = (function() {
+	/*jshint eqeqeq:false, eqnull:true */
+	function diff( o, n ) {
+		var i,
+			ns = {},
+			os = {};
+
+		for ( i = 0; i < n.length; i++ ) {
+			if ( !hasOwn.call( ns, n[i] ) ) {
+				ns[ n[i] ] = {
+					rows: [],
+					o: null
+				};
+			}
+			ns[ n[i] ].rows.push( i );
+		}
+
+		for ( i = 0; i < o.length; i++ ) {
+			if ( !hasOwn.call( os, o[i] ) ) {
+				os[ o[i] ] = {
+					rows: [],
+					n: null
+				};
+			}
+			os[ o[i] ].rows.push( i );
+		}
+
+		for ( i in ns ) {
+			if ( hasOwn.call( ns, i ) ) {
+				if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
+					n[ ns[i].rows[0] ] = {
+						text: n[ ns[i].rows[0] ],
+						row: os[i].rows[0]
+					};
+					o[ os[i].rows[0] ] = {
+						text: o[ os[i].rows[0] ],
+						row: ns[i].rows[0]
+					};
+				}
+			}
+		}
+
+		for ( i = 0; i < n.length - 1; i++ ) {
+			if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
+						n[ i + 1 ] == o[ n[i].row + 1 ] ) {
+
+				n[ i + 1 ] = {
+					text: n[ i + 1 ],
+					row: n[i].row + 1
+				};
+				o[ n[i].row + 1 ] = {
+					text: o[ n[i].row + 1 ],
+					row: i + 1
+				};
+			}
+		}
+
+		for ( i = n.length - 1; i > 0; i-- ) {
+			if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
+						n[ i - 1 ] == o[ n[i].row - 1 ]) {
+
+				n[ i - 1 ] = {
+					text: n[ i - 1 ],
+					row: n[i].row - 1
+				};
+				o[ n[i].row - 1 ] = {
+					text: o[ n[i].row - 1 ],
+					row: i - 1
+				};
+			}
+		}
+
+		return {
+			o: o,
+			n: n
+		};
+	}
+
+	return function( o, n ) {
+		o = o.replace( /\s+$/, "" );
+		n = n.replace( /\s+$/, "" );
+
+		var i, pre,
+			str = "",
+			out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
+			oSpace = o.match(/\s+/g),
+			nSpace = n.match(/\s+/g);
+
+		if ( oSpace == null ) {
+			oSpace = [ " " ];
+		}
+		else {
+			oSpace.push( " " );
+		}
+
+		if ( nSpace == null ) {
+			nSpace = [ " " ];
+		}
+		else {
+			nSpace.push( " " );
+		}
+
+		if ( out.n.length === 0 ) {
+			for ( i = 0; i < out.o.length; i++ ) {
+				str += "<del>" + out.o[i] + oSpace[i] + "</del>";
+			}
+		}
+		else {
+			if ( out.n[0].text == null ) {
+				for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
+					str += "<del>" + out.o[n] + oSpace[n] + "</del>";
+				}
+			}
+
+			for ( i = 0; i < out.n.length; i++ ) {
+				if (out.n[i].text == null) {
+					str += "<ins>" + out.n[i] + nSpace[i] + "</ins>";
+				}
+				else {
+					// `pre` initialized at top of scope
+					pre = "";
+
+					for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
+						pre += "<del>" + out.o[n] + oSpace[n] + "</del>";
+					}
+					str += " " + out.n[i].text + nSpace[i] + pre;
+				}
+			}
+		}
+
+		return str;
+	};
+}());
+
+// for CommonJS environments, export everything
+if ( typeof exports !== "undefined" ) {
+	extend( exports, QUnit.constructor.prototype );
+}
+
+// get at whatever the global object is, like window in browsers
+}( (function() {return this;}.call()) ));
diff --git a/docs/slides/flops14/reveal.js/test/test-markdown-element-attributes.js b/docs/slides/flops14/reveal.js/test/test-markdown-element-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/test/test-markdown-element-attributes.js
@@ -0,0 +1,46 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
+	});
+
+
+	test( 'Attributes on element header in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
+	});
+
+	test( 'Attributes on element paragraphs in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
+	});
+
+	test( 'Attributes on element list items in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.roll-in' ).length, 3, 'found a vertical slide with three list items with class fragment.roll-in' );
+	});
+
+	test( 'Attributes on element paragraphs in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
+	});
+
+	test( 'Attributes on elements in vertical slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
+	});
+
+	test( 'Attributes on elements in single slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/flops14/reveal.js/test/test-markdown-slide-attributes.js b/docs/slides/flops14/reveal.js/test/test-markdown-slide-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/test/test-markdown-slide-attributes.js
@@ -0,0 +1,47 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' );
+	});
+
+	test( 'Id on slide', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' );
+	});
+
+	test( 'data-background attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-background attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-transition attributes with inline content', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/flops14/reveal.js/test/test-markdown.js b/docs/slides/flops14/reveal.js/test/test-markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/test/test-markdown.js
@@ -0,0 +1,15 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/flops14/reveal.js/test/test.js b/docs/slides/flops14/reveal.js/test/test.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/flops14/reveal.js/test/test.js
@@ -0,0 +1,438 @@
+
+// These tests expect the DOM to contain a presentation
+// with the following slide structure:
+//
+// 1
+// 2 - Three sub-slides
+// 3 - Three fragment elements
+// 3 - Two fragments with same data-fragment-index
+// 4
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	// ---------------------------------------------------------------
+	// DOM TESTS
+
+	QUnit.module( 'DOM' );
+
+	test( 'Initial slides classes', function() {
+		var horizontalSlides = document.querySelectorAll( '.reveal .slides>section' )
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.past' ).length, 0, 'no .past slides' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section.present' ).length, 1, 'one .present slide' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section.future' ).length, horizontalSlides.length - 1, 'remaining horizontal slides are .future' );
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.stack' ).length, 2, 'two .stacks' );
+
+		ok( document.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length > 0, 'vertical slides are given .future' );
+	});
+
+	// ---------------------------------------------------------------
+	// API TESTS
+
+	QUnit.module( 'API' );
+
+	test( 'Reveal.isReady', function() {
+		strictEqual( Reveal.isReady(), true, 'returns true' );
+	});
+
+	test( 'Reveal.isOverview', function() {
+		strictEqual( Reveal.isOverview(), false, 'false by default' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), true, 'true after toggling on' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), false, 'false after toggling off' );
+	});
+
+	test( 'Reveal.isPaused', function() {
+		strictEqual( Reveal.isPaused(), false, 'false by default' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), true, 'true after pausing' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), false, 'false after resuming' );
+	});
+
+	test( 'Reveal.isFirstSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+
+		Reveal.slide( 1, 0 );
+		strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.isLastSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+
+		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
+
+		Reveal.slide( lastSlideIndex, 0 );
+		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( ', 0+ lastSlideIndex +' )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.getIndices', function() {
+		var indices = Reveal.getIndices();
+
+		ok( typeof indices.hasOwnProperty( 'h' ), 'h exists' );
+		ok( typeof indices.hasOwnProperty( 'v' ), 'v exists' );
+		ok( typeof indices.hasOwnProperty( 'f' ), 'f exists' );
+
+		Reveal.slide( 1, 0 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 0, 'h 1, v 0' );
+
+		Reveal.slide( 1, 2 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 2, 'h 1, v 2' );
+
+		Reveal.slide( 0, 0 );
+	});
+
+	test( 'Reveal.getSlide', function() {
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+
+		equal( Reveal.getSlide( 0 ), firstSlide, 'gets correct first slide' );
+
+		strictEqual( Reveal.getSlide( 100 ), undefined, 'returns undefined when slide can\'t be found' );
+	});
+
+	test( 'Reveal.getPreviousSlide/getCurrentSlide', function() {
+		Reveal.slide( 0, 0 );
+		Reveal.slide( 1, 0 );
+
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+		var secondSlide = document.querySelector( '.reveal .slides>section:nth-child(2)>section' );
+
+		equal( Reveal.getPreviousSlide(), firstSlide, 'previous is slide #0' );
+		equal( Reveal.getCurrentSlide(), secondSlide, 'current is slide #1' );
+	});
+
+	test( 'Reveal.getScale', function() {
+		ok( typeof Reveal.getScale() === 'number', 'has scale' );
+	});
+
+	test( 'Reveal.getConfig', function() {
+		ok( typeof Reveal.getConfig() === 'object', 'has config' );
+	});
+
+	test( 'Reveal.configure', function() {
+		strictEqual( Reveal.getConfig().loop, false, '"loop" is false to start with' );
+
+		Reveal.configure({ loop: true });
+		strictEqual( Reveal.getConfig().loop, true, '"loop" has changed to true' );
+
+		Reveal.configure({ loop: false, customTestValue: 1 });
+		strictEqual( Reveal.getConfig().customTestValue, 1, 'supports custom values' );
+	});
+
+	test( 'Reveal.availableRoutes', function() {
+		Reveal.slide( 0, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: false, up: false, down: false, right: true }, 'correct for first slide' );
+
+		Reveal.slide( 1, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: true, up: false, down: true, right: true }, 'correct for vertical slide' );
+	});
+
+	test( 'Reveal.next', function() {
+		Reveal.slide( 0, 0 );
+
+		// Step through vertical child slides
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 1, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } );
+
+		// Step through fragments
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } );
+	});
+
+	test( 'Reveal.next at end', function() {
+		Reveal.slide( 3 );
+
+		// We're at the end, this should have no effect
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+	});
+
+
+	// ---------------------------------------------------------------
+	// FRAGMENT TESTS
+
+	QUnit.module( 'Fragments' );
+
+	test( 'Sliding to fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'Reveal.slide( 2, 0, -1 )' );
+
+		Reveal.slide( 2, 0, 0 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'Reveal.slide( 2, 0, 0 )' );
+
+		Reveal.slide( 2, 0, 2 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'Reveal.slide( 2, 0, 2 )' );
+
+		Reveal.slide( 2, 0, 1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'Reveal.slide( 2, 0, 1 )' );
+	});
+
+	test( 'Hiding all fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' );
+
+		Reveal.slide( 2, 0, -1 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index is -1' );
+	});
+
+	test( 'Current fragment', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 1, 'one current fragment at index 0' );
+
+		Reveal.slide( 1, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
+	});
+
+	test( 'Stepping through fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+
+		// forwards:
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'next() goes to next fragment' );
+
+		Reveal.right();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'right() goes to next fragment' );
+
+		Reveal.down();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'down() goes to next fragment' );
+
+		Reveal.down(); // moves to f #3
+
+		// backwards:
+
+		Reveal.prev();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'prev() goes to prev fragment' );
+
+		Reveal.left();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'left() goes to prev fragment' );
+
+		Reveal.up();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'up() goes to prev fragment' );
+	});
+
+	test( 'Stepping past fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 0, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 3, 'all fragments visible when on future slide' );
+	});
+
+	test( 'Fragment indices', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(2)' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 2, 'both fragments of same index are shown' );
+	});
+
+	test( 'Index generation', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		// These have no indices defined to start with
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' );
+	});
+
+	test( 'Index normalization', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(3)' );
+
+		// These start out as 1-4-4 and should normalize to 0-1-1
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' );
+	});
+
+	asyncTest( 'fragmentshown event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmentshown', _onEvent );
+
+		Reveal.slide( 2, 0 );
+		Reveal.slide( 2, 0 ); // should do nothing
+		Reveal.slide( 2, 0, 0 ); // should do nothing
+		Reveal.next();
+		Reveal.next();
+		Reveal.prev(); // shouldn't fire fragmentshown
+
+		start();
+
+		Reveal.removeEventListener( 'fragmentshown', _onEvent );
+	});
+
+	asyncTest( 'fragmenthidden event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmenthidden', _onEvent );
+
+		Reveal.slide( 2, 0, 2 );
+		Reveal.slide( 2, 0, 2 ); // should do nothing
+		Reveal.prev();
+		Reveal.prev();
+		Reveal.next(); // shouldn't fire fragmenthidden
+
+		start();
+
+		Reveal.removeEventListener( 'fragmenthidden', _onEvent );
+	});
+
+
+	// ---------------------------------------------------------------
+	// CONFIGURATION VALUES
+
+	QUnit.module( 'Configuration' );
+
+	test( 'Controls', function() {
+		var controlsElement = document.querySelector( '.reveal>.controls' );
+
+		Reveal.configure({ controls: false });
+		equal( controlsElement.style.display, 'none', 'controls are hidden' );
+
+		Reveal.configure({ controls: true });
+		equal( controlsElement.style.display, 'block', 'controls are visible' );
+	});
+
+	test( 'Progress', function() {
+		var progressElement = document.querySelector( '.reveal>.progress' );
+
+		Reveal.configure({ progress: false });
+		equal( progressElement.style.display, 'none', 'progress are hidden' );
+
+		Reveal.configure({ progress: true });
+		equal( progressElement.style.display, 'block', 'progress are visible' );
+	});
+
+	test( 'Loop', function() {
+		Reveal.configure({ loop: true });
+
+		Reveal.slide( 0, 0 );
+
+		Reveal.left();
+		notEqual( Reveal.getIndices().h, 0, 'looped from start to end' );
+
+		Reveal.right();
+		equal( Reveal.getIndices().h, 0, 'looped from end to start' );
+
+		Reveal.configure({ loop: false });
+	});
+
+
+	// ---------------------------------------------------------------
+	// EVENT TESTS
+
+	QUnit.module( 'Events' );
+
+	asyncTest( 'slidechanged', function() {
+		expect( 3 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'slidechanged', _onEvent );
+
+		Reveal.slide( 1, 0 ); // should trigger
+		Reveal.slide( 1, 0 ); // should do nothing
+		Reveal.next(); // should trigger
+		Reveal.slide( 3, 0 ); // should trigger
+		Reveal.next(); // should do nothing
+
+		start();
+
+		Reveal.removeEventListener( 'slidechanged', _onEvent );
+
+	});
+
+	asyncTest( 'paused', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'paused', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'paused', _onEvent );
+	});
+
+	asyncTest( 'resumed', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'resumed', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'resumed', _onEvent );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/niki/Makefile b/docs/slides/niki/Makefile
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/Makefile
@@ -0,0 +1,45 @@
+####################################################################
+SERVERHOME=nvazou@goto.ucsd.edu:~/public_html/liquidtutorial/
+####################################################################
+
+
+PANDOC=pandoc --columns=80  -s  --mathjax --slide-level=2
+SLIDY=$(PANDOC) -t slidy
+DZSLIDES=$(PANDOC) --highlight-style tango --css=slides.css -w dzslides
+HANDOUT=$(PANDOC) --highlight-style tango --css=text.css -w html5
+WEBTEX=$(PANDOC) -s --webtex -i -t slidy
+BEAMER=pandoc -t beamer
+LIQUID=liquid
+objects := $(patsubst %.lhs,%.lhs.slides.html,$(wildcard lhs/*.lhs))
+
+
+####################################################################
+
+all: slides copy
+
+slides: $(objects)
+
+lhs/%.lhs.markdown: lhs/%.lhs
+	-$(LIQUID) $?
+
+lhs/%.lhs.slides.html: lhs/%.lhs.markdown
+	$(DZSLIDES) $? -o $@ 
+
+lhs/%.lhs.slides.pdf: lhs/%.lhs.markdown
+	$(BEAMER) $? -o $@ 
+
+copy:
+	cp lhs/*lhs.html html/
+	cp lhs/*lhs.slides.html html/
+	cp css/*.css html/
+	cp -r fonts html/
+	cp index.html html/
+	cp Benchmarks.html html/
+
+clean:
+#	cd lhs/ && ../cleanup && cd ../
+#	cd html/ && rm -rf * && cd ../
+#	cp index.html html/
+
+upload: 
+	scp -r html/* $(SERVERHOME)
diff --git a/docs/slides/niki/fonts/OFT.txt b/docs/slides/niki/fonts/OFT.txt
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/fonts/OFT.txt
@@ -0,0 +1,93 @@
+﻿Copyright (c) 2011, ParaType Ltd. (http://www.paratype.com/public),
+with Reserved Font Names "PT Sans", "PT Serif", "PT Mono" and "ParaType".
+
+This Font Software is licensed under the Open Font License, Version 1.1 
+This license is copied below, and is also available with a FAQ at: 
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/docs/slides/niki/fonts/PT_Mono-Regular.ttf b/docs/slides/niki/fonts/PT_Mono-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/fonts/PT_Mono-Regular.ttf differ
diff --git a/docs/slides/niki/fonts/PT_Sans-Narrow-Web-Bold.ttf b/docs/slides/niki/fonts/PT_Sans-Narrow-Web-Bold.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/fonts/PT_Sans-Narrow-Web-Bold.ttf differ
diff --git a/docs/slides/niki/fonts/PT_Sans-Narrow-Web-Regular.ttf b/docs/slides/niki/fonts/PT_Sans-Narrow-Web-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/fonts/PT_Sans-Narrow-Web-Regular.ttf differ
diff --git a/docs/slides/niki/fonts/PT_Sans-Web-Bold.ttf b/docs/slides/niki/fonts/PT_Sans-Web-Bold.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/fonts/PT_Sans-Web-Bold.ttf differ
diff --git a/docs/slides/niki/fonts/PT_Sans-Web-BoldItalic.ttf b/docs/slides/niki/fonts/PT_Sans-Web-BoldItalic.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/fonts/PT_Sans-Web-BoldItalic.ttf differ
diff --git a/docs/slides/niki/fonts/PT_Sans-Web-Italic.ttf b/docs/slides/niki/fonts/PT_Sans-Web-Italic.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/fonts/PT_Sans-Web-Italic.ttf differ
diff --git a/docs/slides/niki/fonts/PT_Sans-Web-Regular.ttf b/docs/slides/niki/fonts/PT_Sans-Web-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/fonts/PT_Sans-Web-Regular.ttf differ
diff --git a/docs/slides/niki/html/benchmarks.png b/docs/slides/niki/html/benchmarks.png
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/html/benchmarks.png differ
diff --git a/docs/slides/niki/html/fonts/OFT.txt b/docs/slides/niki/html/fonts/OFT.txt
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/html/fonts/OFT.txt
@@ -0,0 +1,93 @@
+﻿Copyright (c) 2011, ParaType Ltd. (http://www.paratype.com/public),
+with Reserved Font Names "PT Sans", "PT Serif", "PT Mono" and "ParaType".
+
+This Font Software is licensed under the Open Font License, Version 1.1 
+This license is copied below, and is also available with a FAQ at: 
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/docs/slides/niki/html/fonts/PT_Mono-Regular.ttf b/docs/slides/niki/html/fonts/PT_Mono-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/html/fonts/PT_Mono-Regular.ttf differ
diff --git a/docs/slides/niki/html/fonts/PT_Sans-Narrow-Web-Bold.ttf b/docs/slides/niki/html/fonts/PT_Sans-Narrow-Web-Bold.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/html/fonts/PT_Sans-Narrow-Web-Bold.ttf differ
diff --git a/docs/slides/niki/html/fonts/PT_Sans-Narrow-Web-Regular.ttf b/docs/slides/niki/html/fonts/PT_Sans-Narrow-Web-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/html/fonts/PT_Sans-Narrow-Web-Regular.ttf differ
diff --git a/docs/slides/niki/html/fonts/PT_Sans-Web-Bold.ttf b/docs/slides/niki/html/fonts/PT_Sans-Web-Bold.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/html/fonts/PT_Sans-Web-Bold.ttf differ
diff --git a/docs/slides/niki/html/fonts/PT_Sans-Web-BoldItalic.ttf b/docs/slides/niki/html/fonts/PT_Sans-Web-BoldItalic.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/html/fonts/PT_Sans-Web-BoldItalic.ttf differ
diff --git a/docs/slides/niki/html/fonts/PT_Sans-Web-Italic.ttf b/docs/slides/niki/html/fonts/PT_Sans-Web-Italic.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/html/fonts/PT_Sans-Web-Italic.ttf differ
diff --git a/docs/slides/niki/html/fonts/PT_Sans-Web-Regular.ttf b/docs/slides/niki/html/fonts/PT_Sans-Web-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/niki/html/fonts/PT_Sans-Web-Regular.ttf differ
diff --git a/docs/slides/niki/html/liquid.css b/docs/slides/niki/html/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/html/liquid.css
@@ -0,0 +1,105 @@
+.hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+  // font-weight: bold;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   /* color: #00FFFF; color: #0E84B5; */
+  //font-weight: bold;  
+}
+
+.hs-definition { 
+  color: #06287E 
+  /* font-weight: bold; */ 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  // font-size: 120%;
+  // font-family: Bitstream Vera Sans Mono,monospace;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/niki/html/slides.css b/docs/slides/niki/html/slides.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/html/slides.css
@@ -0,0 +1,258 @@
+@font-face {
+	font-family: 'PT Mono';
+    font-style: normal;
+	font-weight: normal;
+	src: local("☺"), url('fonts/PT_Mono-Regular.ttf') format('truetype');
+}
+@font-face {
+	font-family: 'PT Sans';
+    font-style: normal; 
+	font-weight: bold;
+	src: local("☺"), url('fonts/PT_Sans-Web-Bold.ttf') format('truetype');
+}@font-face {
+	font-family: 'PT Sans';
+    font-style: italic;
+	font-weight: normal;
+	src: local("☺"), url('fonts/PT_Sans-Web-Italic.ttf') format('truetype');
+}@font-face {
+	font-family: 'PT Sans';
+    font-style: normal;
+	font-weight: normal;
+	src: local("☺"), url('fonts/PT_Sans-Web-Regular.ttf') format('truetype');
+}
+@font-face {
+	font-family: 'PT Sans Narrow';
+    font-style: normal;
+	font-weight: bold;
+	src: local("☺"), url('fonts/PT_Sans-Narrow-Web-Bold.ttf') format('truetype');
+}
+@font-face {
+	font-family: 'PT Sans Narrow';
+    font-style: normal;
+	font-weight: normal;
+	src: local("☺"), url('fonts/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
+}
+html {
+    height: 100%;
+	background-color: #fefffe;
+}
+body {
+	width: 1024px !important;
+    height: 600px !important;
+	margin-left: -512px !important;
+	margin-top: -300px !important;
+}
+section {
+	background: transparent;
+	color: #000;
+	width: 100%  !important;
+	/* width: 800px !important; */
+	height: 600px !important;
+    padding: 50px 112px 0;	
+	font-family: 'PT Sans', sans-serif;
+	font-size: 16pt;
+}
+
+body :first-child {
+}
+address, blockquote, dl, fieldset, form, h1, h2, h3, h4, h5, h6, hr, ol, p, pre, table, ul, dl { padding: 10px 20px 10px 20px; }
+h1, h2, h3 {
+	text-align: left;
+	color: #666; 
+	font-family: 'PT Sans Narrow', sans-serif;
+	font-weight: bold;
+}
+input, select {
+border 0.5pt solid black;
+font-size: 16pt;
+line-height: 10pt;
+padding: 0 0 -2.5pt 0;
+z-index:1;
+}
+ul, ol {
+	margin: 10px 10px 10px 50px;
+}
+a { color: #205CB3; }
+section.titleslide h1 { margin-top: 200px; }
+h1.title { margin-top: 150px; font-size:200%; margin-bottom: 20px; text-align: center; text-shadow:0px 2px 1px #444; 
+-webkit-transition: color 1s ease-in-out;
+-moz-transition: color 1s ease-in-out;
+ }
+h1.title:hover {
+color: #C43628;
+}
+h2.author { font-size: 120%; margin-top: 0px; margin-bottom: 0px; text-align:center; color: #555; font-family: 'PT Sans Narrow'; font-weight: normal;}
+h3.date { font-size: 80%; margin-top: 0px; text-align: center; color: #555; font-family: 'PT Mono'; font-weight: normal;}
+h1 { font-size: 180%; margin: 0 0 10px; text-shadow:0px 2px 1px #fff;}
+h2 { font-size: 140%; } 
+h3 { font-size: 100%; }
+blockquote { font-style: italic }
+q {
+	display: inline-block;
+	width: 700px;
+	height: 600px;
+	background-color: black;
+	color: white;
+	font-size: 60px;
+	padding: 50px;
+}
+footer {
+	position: absolute;
+	bottom: 10px;
+	right: 20px;
+	text-shadow: white 0px 1px 0px, rgba(0, 0, 0, 0.2) 0 2px 5px;
+}
+/* JHALA: pre, code { background: transparent; } */
+pre, code {background-color:#E6F0FA;}
+
+pre { padding: 10px 50px; }
+td > pre { padding: 0px; }
+td { padding: 5px; }
+::-moz-selection { background-color: khaki; }
+code { font-family: 'PT Mono'; font-size: 90%; }
+code > span.co { font-style: normal; }
+code > span.kw { font-weight: normal; }
+code > span.er { font-weight: normal; }
+
+/* Transition effect */
+/* Feel free to change the transition effect for original
+animations. See here:
+https://developer.mozilla.org/en/CSS/CSS_transitions
+How to use CSS3 Transitions: */
+section {
+	-moz-transition: left 400ms ease-in-out 0s;
+	-webkit-transition: left 400ms ease-in-out 0s;
+	-ms-transition: left 400ms ease-in-out 0s;
+	transition: left 400ms ease-in-out 0s;
+}
+
+/* Before */
+section { left: -150%; }
+/* Now */
+section[aria-selected] { left: 0; }
+/* After */
+section[aria-selected] ~ section { left: +150%; }
+
+/* Incremental elements */
+
+/* By default, visible */
+.incremental > * { opacity: 1; }
+
+/* The current item */
+.incremental > *[aria-selected] { color: red; opacity: 1; }
+
+/* The items to-be-selected */
+.incremental > *[aria-selected] ~ * { opacity: 0.2; }
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+a { color: #205CB3; }
+
+.hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+  // font-weight: bold;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   /* color: #00FFFF; color: #0E84B5; */
+  //font-weight: bold;  
+}
+
+.hs-definition { 
+  color: #06287E 
+  /* font-weight: bold; */ 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 60%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 80%;
+  // font-family: Bitstream Vera Sans Mono,monospace;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/niki/lhs/AbstractRefinements.lhs b/docs/slides/niki/lhs/AbstractRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/AbstractRefinements.lhs
@@ -0,0 +1,254 @@
+Abstract Refinements
+---------------------
+
+\begin{code}
+module AbstractRefinements where
+
+import Prelude hiding (max)
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+\end{code}
+
+Polymorphic Max Function
+-----------------------
+\begin{code} Consinder a polymorphic max function:
+max     :: a -> a -> a
+max x y = if x >= y then x else y
+\end{code}
+
+<br>
+
+\begin{code} We can instantiate `a` with `Odd`
+max     :: Odd -> Odd -> Odd
+
+maxOdd :: Odd
+maxOdd = max 3 7
+\end{code}
+
+
+Polymorphic Max in Haskell
+-----------------------
+\begin{code} In Haskell the type of max is
+max     :: Ord a => a -> a -> a
+\end{code}
+
+
+<br>
+
+We could **ignore** the class constraints, and procced as before:
+
+\begin{code} Instantiate `a` with `Odd`
+max     :: Odd -> Odd -> Odd
+
+maxOdd :: Odd
+maxOdd = max 3 7
+\end{code}
+
+
+Polymorphic Add in Haskell
+-----------------------
+
+\begin{code} But this can lead to **unsoundness**:
+max     :: Ord a => a -> a -> a
+(+)     :: Num a => a -> a -> a
+\end{code}
+
+<br>
+
+So, **ignoring** class constraints allows us to: 
+\begin{code} instantiate `a` with `Odd`
+(+)     :: Odd -> Odd -> Odd
+
+addOdd :: Odd
+addOdd = 3 + 7
+\end{code}
+
+
+Polymorphism via Parametric Invariants 
+--------------------------------------
+
+`max` returns *one of* its two inputs `x` and `y`. 
+
+- **If** *both inputs* satisfy a property  
+
+- **Then** *output* must satisfy that property
+
+This holds, **regardless of what that property was!**
+ 
+- That  is, we can **abstract over refinements**
+
+- Or,  **parameterize** a type over its refinements.
+
+Parametric Invariants
+--------------------- 
+
+\begin{code}
+{-@ max :: forall <p :: a -> Prop>. Ord a => a<p> -> a<p> -> a<p> @-}
+max     :: Ord a => a -> a -> a
+max x y = if x <= y then y else x 
+\end{code}
+
+
+
+Where
+
+- `a<p>` is just an abbreviation for `{v:a | (p v)}`
+
+
+This type states explicitly:
+
+- **For any property** `p`, that is a property of `a`, 
+
+- `max` takes two **inputs** of which satisfy `p`,
+
+- `max` returns an **output** that satisfies `p`. 
+
+
+
+Using Abstract Refinements
+--------------------------
+
+- **If** we call `max` with two arguments with the same concrete refinement,
+
+- **Then** the `p` will be instantiated with that concrete refinement,
+
+- **The output** of the call will also enjoy the concrete refinement.
+
+
+
+\begin{code}
+{-@ type Odd = {v:Int | (v mod 2) = 1} @-}
+
+{-@ maxOdd :: Odd @-}
+maxOdd     :: Int
+maxOdd     = max 3 5
+\end{code}
+
+
+Abstract Refinements in Type Constructors
+-----------------------------------------
+
+Types cannot track information of monomorphic arguments:
+
+\begin{code}
+data F = F {w::Int}
+\end{code}
+
+<br>
+
+The type `F` cannot give us information about the field `x`.
+
+\begin{code}
+foo = let f = F 0 in -- :: f :: F
+      case f of 
+      F x -> liquidAssert (x >= 0)
+\end{code}
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=AbstractRefinements.hs" target= "_blank">Demo:</a> 
+Lets solve this error using Abstract Refinements
+
+Abstract Refinements in Type Constructors
+-----------------------------------------
+
+- Abstract over the refinement you care
+\begin{code}
+data G = G {y::Int{- <p> -}}
+\end{code}
+
+- Move it to the left-hand side
+\begin{code}
+{-@ data G <p :: Int -> Prop> = G (y::Int<p>) @-}
+\end{code}
+
+- The type `G <p>` now describes the field `x`.
+
+\begin{code}
+bar = let f = G 0 in -- :: f :: G <{v = 0}>
+      case f of 
+      G x -> liquidAssert (x >= 0)
+\end{code}
+
+Abstract Refinements in Lists
+-----------------------------------------
+
+\begin{code} Remember increasing Lists?
+data IL a = N | C (x :: a) (xs :: L {v:a | x <= v})
+\end{code}
+
+- Abstract over the refinement you care
+\begin{code}
+data L a = N | C {x :: a, xs :: L a {- v:a | p v x -}}
+\end{code}
+
+- Move it to the left-hand side
+\begin{code}
+{-@ data L a <p :: a -> a -> Prop> = 
+      N 
+    | C (x :: a) (xs :: L <p> a<p x>)  @-}
+\end{code}
+
+<br>
+
+We can get back increasing Lists:
+\begin{code}
+{-@ type IncrL a = L <{\x v -> x <= v}> a @-}
+\end{code}
+
+
+Multiple Instantiations
+-----------------------
+
+\begin{code} Now increasing lists 
+type IncrL a = L <{\x v -> x <= v}> a
+\end{code}
+
+<br>
+
+\begin{code} Co-exist with decreasing ones
+type DecrL a = L <{\x v -> x >= v}> a
+\end{code}
+
+Ghc Sort
+--------
+
+We can now verify algorithms that use **both** increasing and decreasing lists
+
+\begin{code}
+{-@ type OList a = [a]<{\hd v -> hd <= v}> @-}
+
+{-@ sort :: (Ord a) => [a] -> OList a  @-}
+sort :: (Ord a) => [a] -> [a]
+sort = mergeAll . sequences
+  where
+    sequences (a:b:xs)
+      | a `compare` b == GT = descending b [a]  xs
+      | otherwise           = ascending  b (a:) xs
+    sequences [x] = [[x]]
+    sequences []  = [[]]
+
+    descending a as (b:bs)
+      | a `compare` b == GT = descending b (a:as) bs
+    descending a as bs      = (a:as): sequences bs
+
+    ascending a as (b:bs)
+      | a `compare` b /= GT = ascending b (\ys -> as (a:ys)) bs
+    ascending a as bs       = as [a]: sequences bs
+\end{code}
+
+Ghc Sort : Helper Functions
+---------------------------
+
+\begin{code}
+mergeAll [x] = x
+mergeAll xs  = mergeAll (mergePairs xs)
+
+mergePairs (a:b:xs) = merge1 a b: mergePairs xs
+mergePairs [x]      = [x]
+mergePairs []       = []
+
+merge1 (a:as') (b:bs')
+  | a `compare` b == GT = b:merge1 (a:as')  bs'
+  | otherwise           = a:merge1 as' (b:bs')
+merge1 [] bs            = bs
+merge1 as []            = as
+\end{code}
diff --git a/docs/slides/niki/lhs/Array.lhs b/docs/slides/niki/lhs/Array.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/Array.lhs
@@ -0,0 +1,226 @@
+%Indexed-Dependent Refinements
+
+Indexed-Dependent Refinements
+-----------------------------
+
+\begin{code}
+module LiquidArray where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume)
+
+{-@ LIQUID "--no-termination" @-}
+\end{code}
+
+Indexed-Dependent Refinements
+-----------------------------
+
+We define a Vector of `a`s 
+implemented as a function from `Int` to `a`s <br>
+<br>
+
+\begin{code}
+data Vec a = V (Int -> a)
+\end{code}
+
+Abstract Over the Domain and Range
+----------------------------------
+
+We parameterize the definition with two abstract refinements:
+<br>
+<br>
+
+\begin{code}
+{-@ data Vec a <dom :: Int -> Prop, rng :: Int -> a -> Prop>
+      = V {a :: i:Int<dom> -> a <rng i>}
+  @-}
+\end{code}
+
+
+- `dom`: describes the *domain* 
+
+- `rng`: describes each value with respect to its index
+
+Describing Vectors
+------------------
+
+\begin{code}By instantiating these two predicates, we describe Vector's *domain* and *range*
+{-@ data Vec a <dom :: Int -> Prop, rng :: Int -> a -> Prop>
+      = V {a :: i:Int<dom> -> a <rng i>}
+  @-}
+\end{code}
+<br>
+
+A vector of `Int` *defined on* values less than `42`
+*containing values* equal to their index:
+<br>
+<br>
+
+\begin{code}
+{-@ type IdVec = 
+      Vec <{\v -> (v < 42)}, {\j v -> (v = j)}> Int
+  @-}
+\end{code}
+
+Describing Vectors
+------------------
+\begin{code}By instantiating these two predicates, we describe Vector's *domain* and *range*
+{-@ data Vec a <dom :: Int -> Prop, rng :: Int -> a -> Prop>
+      = V {a :: i:Int<dom> -> a <rng i>}
+  @-}
+\end{code}
+<br>
+
+A vector *defined on* the range `[0..n)` with its *last element* equal to `0`:
+<br>
+<br>
+
+\begin{code}
+{-@ type ZeroTerm N = 
+     Vec <{\v -> (0 <= v && v < N)}, {\j v -> (j = N - 1 => v = 0)}> Int
+  @-}
+\end{code}
+
+Describing Vectors
+------------------
+\begin{code}By instantiating these two predicates, we describe Vector's *domain* and *range*
+{-@ data Vec a <dom :: Int -> Prop, rng :: Int -> a -> Prop>
+      = V {a :: i:Int<dom> -> a <rng i>}
+  @-}
+\end{code}
+<br>
+
+
+A vector *defined on* integers whose *value at index `j`* is either 
+`0` or the `j`th fibonacci:
+<br>
+<br>
+
+\begin{code}
+{-@ type FibV =  
+     Vec <{\v -> 0=0}, {\j v -> ((v != 0) => (v = (fib j)))}> Int 
+  @-}
+\end{code}
+
+
+Operations on Vectors
+---------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target= "_blank">Demo:</a> 
+
+We give appropriate types to vector operations (empty, set, get...)
+
+- This means *abstracting* over the domain and range
+
+
+Empty
+-----
+
+`empty` returns a Vector whose domain is always false
+<br>
+<br>
+
+\begin{code}
+{-@ empty :: forall <p :: Int -> a -> Prop>. Vec < {v:Int | 0=1}, p> a @-}
+
+empty     :: Vec  a
+empty     = V $ \_ -> (error "Empty array!")
+\end{code}
+
+Typing Get
+----------
+
+If `i` satisfies the domain then
+if we `get` the `i`th element of an array, 
+the result should satisfy the range at `i`
+<br>
+<br>
+
+\begin{code}
+{-@ get :: forall a <r :: Int -> a -> Prop, d :: Int -> Prop>.
+           i: Int<d>
+        -> a: Vec<d, r> a
+        -> a<r i> @-}
+
+get :: Int -> Vec a -> a
+get i (V f) = f i
+\end{code}
+
+Typing Set
+----------
+
+If `i` satisfies the domain then
+if we `set` the `i`th element of a Vector to a value
+that satisfies range at `i`, 
+then Vector's domain will be extended with `i`
+<br>
+<br>
+
+\begin{code}
+{-@ set :: forall a <r :: Int -> a -> Prop, d :: Int -> Prop>.
+           i: Int<d>
+        -> x: a<r i>
+        -> a: Vec < {v:Int<d> | v != i}, r> a
+        -> Vec <d, r> a @-}
+
+set :: Int -> a -> Vec a -> Vec a
+set i v (V f) = V $ \k -> if k == i then v else f k
+\end{code}
+
+Using Vectors
+-------------
+
+\begin{code}Remember the fibonacci memoization Vector:
+type FibV = 
+     Vec <{\v -> 0=0}, {\j v -> ((v != 0) => (v = (fib j)))}> Int
+\end{code}
+<br>
+
+Where `fib` is an *uninterprented function* 
+\begin{code}
+{-@ measure fib :: Int -> Int @-}
+\end{code}
+<br>
+
+We used `fib` to define the `axiom_fib`
+
+\begin{code}
+{-@ predicate Fib I = 
+  (fib i) = (if (i <= 1) then 1 else ((fib (i-1)) + (fib (i-2))))
+  @-}
+
+{-@ assume axiom_fib :: i:Int -> {v: Bool | ((Prop v) <=> (Fib i))} @-}
+
+axiom_fib :: Int -> Bool
+axiom_fib i = undefined
+\end{code}
+
+
+Fast Fibonacci
+--------------
+Now we can efficiently compute the `i`th fibonacci number
+
+\begin{code}
+{-@ fastFib :: x:Int -> {v:Int | v = fib(x)} @-}
+fastFib     :: Int -> Int
+fastFib n   = snd $ fibMemo (V (\_ -> 0)) n
+\end{code}
+
+Fibonacci Memo
+--------------
+
+\begin{code}
+{-@ fibMemo :: FibV -> i:Int -> (FibV, {v: Int | v = (fib i)}) @-}
+
+fibMemo :: Vec Int -> Int -> (Vec Int, Int)
+fibMemo t i 
+  | i <= 1    
+  = (t, liquidAssume (axiom_fib i) (1 :: Int))
+  
+  | otherwise 
+  = case get i t of   
+      0 -> let (t1, n1) = fibMemo t  (i-1)
+               (t2, n2) = fibMemo t1 (i-2)
+               n        = liquidAssume (axiom_fib i) (n1 + n2)
+            in (set i n t2,  n)
+      n -> (t, n)
+\end{code}
diff --git a/docs/slides/niki/lhs/Composition.lhs b/docs/slides/niki/lhs/Composition.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/Composition.lhs
@@ -0,0 +1,103 @@
+% Function Composition
+
+Function Composition
+--------------------
+
+\begin{code}
+module Composition where
+\end{code}
+
+A Plus Function
+---------------
+
+Consider a simple `plus` function 
+
+\begin{code}
+{-@ plus :: x:Int -> y:Int -> {v:Int | v = x + y} @-}
+plus     :: Int -> Int -> Int
+plus x y = x + y
+\end{code}
+
+A Simple Addition 
+-----------------
+
+Consider a simple use of `plus` a function that adds `3` to its input:
+
+\begin{code}
+{-@ plus3' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3'     :: Int -> Int
+plus3' x   = x + 3
+\end{code}
+
+- The refinement type captures its behaviour...
+
+- ... and LiquidHaskell easily verifies this type.
+
+A Composed Variant
+------------------
+
+Instead, suppose we defined the previous function by composition 
+
+We first add `2` to the argument and then add `1` to the intermediate result...
+
+\begin{code}
+{-@ plus3'' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3''     :: Int -> Int
+plus3''     = (plus 1) . (plus 2)
+\end{code}
+
+but verification **fails** as we need a way to **compose** the refinements!
+
+**Problem** What is a suitable description of the compose operator
+
+\begin{code} _ 
+(.) :: (b -> c) -> (a -> b) -> (a -> c)
+\end{code}
+
+that lets us **relate** `a` and `c` via `b` ?
+
+
+
+Composing Refinements, Abstractly
+---------------------------------
+
+- We can analyze the *composition* operator
+
+- With a very *descriptive* abstract refinement type!
+
+\begin{code}
+
+{-@ cc :: forall < p :: b -> c -> Prop
+                , q :: a -> b -> Prop>.
+         f:(x:b -> c<p x>) 
+      -> g:(x:a -> b<q x>) 
+      -> y:a 
+      -> exists[z:b<q y>].c<p z>
+ @-}
+
+cc :: (b -> c) -> (a -> b) -> a -> c
+cc f g x = f (g x)
+\end{code}
+
+Using Composition
+-----------------
+
+We can verify the desired `plus3` function:
+
+\begin{code}
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     :: Int -> Int
+plus3     = (+ 1) `cc` (+ 2)
+\end{code}
+
+LiquidHaskell verifies the above, by **instantiating**
+
+- `p` with `v = x + 1`
+- `q` with `v = x + 2`
+
+which lets it infer that the output of `plus3` has type:
+
+- `exists [z:{v=y+2}]. {v = z + 1}`
+
+which is a subtype of `{v:Int | v = 3}`
+
diff --git a/docs/slides/niki/lhs/Inductive.lhs b/docs/slides/niki/lhs/Inductive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/Inductive.lhs
@@ -0,0 +1,178 @@
+% Inductive Refinements
+
+Inductive Refinements
+---------------------
+
+\begin{code}
+module Loop where
+import Prelude hiding ((!!), foldr, length, (++))
+import Measures
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+\end{code}
+
+
+`loop` Revisited
+----------------
+
+Recall the **higher-order** `loop` function <br>
+
+\begin{code}
+loop :: Int -> Int -> a -> (Int -> a -> a) -> a
+loop lo hi base f            = go lo base
+  where go i acc | i < hi    = go (i+1) (f i acc)
+                 | otherwise = acc
+\end{code}
+
+We used `loop` to write <br>
+
+\begin{code}
+
+{-@ add :: n:Nat -> m:{v:Int| v >= 0} -> {v:Int| v = m + n} @-}
+add :: Int -> Int -> Int
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+**Problem:** Verification requires an **index dependent loop invariant** `p` 
+
+- Which relates index `i` with accumulator `acc`: formally `(p acc i)`
+
+Loop Invariants and Induction
+-----------------------------
+\begin{code} Recall the **higher-order** `loop` function
+loop :: Int -> Int -> a -> (Int -> a -> a) -> a
+loop lo hi base f            = go lo base
+  where go i acc | i < hi    = go (i+1) (f i acc)
+                 | otherwise = acc
+\end{code}
+
+To verify output satisfies relation at `hi` we prove that **if**
+
+- **base case** initial accumulator `base` satisfies invariant at `lo`
+    - `(p base lo)`
+
+- **induction step** `f` **preserves** the invariant at `i`
+    - **if** `(p acc i)` <b>then</b> `(p (f i acc) (i+1))`
+
+- **then** "by induction" result satisfies invariant at `hi`
+    - `(p (loop lo hi base f) hi)`
+
+
+Encoding Induction With Abstract Refinements
+--------------------------------------------
+
+We capture induction with an **abstract refinement type** for `loop` <br>
+
+\begin{code}
+{-@ loop :: forall a <p :: Int -> a -> Prop>.
+             lo:Int 
+          -> hi:{v:Int|lo <= v}
+          -> base:a<p lo> 
+          -> f:(i:Int -> a<p i> -> a<p (i+1)>) 
+          -> a<p hi>
+  @-}
+\end{code}
+
+<br>
+
+\begin{code} `p` is the index dependent invariant!
+p     :: Int -> a -> Prop>                  -- ind  hyp 
+base  :: a<p lo>                            -- base case 
+f     :: (i:Int -> a<p i> -> a <p (i+1)>)   -- ind. step
+out   :: a<p hi>                            -- output holds at hi         
+\end{code}
+
+
+Encoding Induction With Abstract Refinements
+--------------------------------------------
+
+\begin{code} Lets revisit 
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br> The invariant is: `p` instantiated with `\i acc -> acc = i + n`
+
+**base case:**  `(p 0 n)` holds as `n = 0 + n`
+
+**ind. step**  `\_ z -> z + 1` preserves invariant
+
+- `acc =  i + n` *implies* `acc + 1 = (i + 1) + n`
+
+**output** hence, `loop 0 m n (\_ z -> z + 1) = m + n`
+
+Which lets us verify that
+
+\begin{code}.
+add :: n:Nat -> m:Nat -> {v:Int| v = m + n}
+\end{code}
+
+Structural Induction With Abstract Refinements
+----------------------------------------------
+
+Same idea applies for induction over *structures*
+
+We define a `foldr` function that resembles loop.
+\begin{code}
+\end{code}
+\begin{code}
+{-@ foldr :: forall a b <p :: L a -> b -> Prop>. 
+                (xs:L a -> x:a -> b <p xs> -> b <p (Measures.C x xs)>) 
+              -> b <p Measures.N> 
+              -> ys: L a
+              -> b <p ys>
+  @-}
+foldr :: (L a -> a -> b -> b) -> b -> L a -> b
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{code}
+
+<br>
+
+- **base case** `b` is related to nil `N`
+- **ind. step** `f` extends relation over cons `C`
+- **output** relation holds over entire list `ys`
+
+
+
+Structural Induction With Abstract Refinements
+----------------------------------------------
+
+We can now verify <br>
+
+\begin{code}
+{-@ size :: xs:L a -> {v: Int | v = (llen xs)} @-}
+size :: L a -> Int
+size = foldr (\_ _ n -> n + 1) 0
+\end{code}
+
+<br>
+
+Here, the relation 
+
+- `(p xs acc)` 
+
+is **automatically instantiated** with
+
+- `acc = (llen xs)`
+
+Structural Induction With Abstract Refinements
+----------------------------------------------
+
+Similarly we can now verify <br>
+
+\begin{code}_
+{-@ ++ :: xs:L a -> ys:L a -> {v:L a | (llen v) = (llen xs) + (llen ys)} @-} 
+xs ++ ys = foldr (\_ z zs -> C z zs) ys xs 
+\end{code}
+
+<br>
+
+Here, the relation 
+
+- `(p xs acc)` 
+
+is **automatically instantiated** with
+
+- `(llen acc) = (llen xs) + (llen ys)`
+
+
diff --git a/docs/slides/niki/lhs/Laziness.lhs b/docs/slides/niki/lhs/Laziness.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/Laziness.lhs
@@ -0,0 +1,99 @@
+% Laziness
+
+Laziness
+--------
+
+
+\begin{code}
+module Laziness where
+import Language.Haskell.Liquid.Prelude
+\end{code}
+
+
+Infinite Computations can lead to Unsoundness
+----------------------------------------------
+
+Infinite Computations can be refined with **false**
+\begin{code}
+{-@ foo :: n:Nat -> {v:Nat | v < n} @-}
+foo     :: Int -> Int
+foo n   | n > 0     = n - 1
+        | otherwise = foo n
+\end{code}
+
+<br>
+
+Under **false** anything can be proven
+\begin{code}
+prop = liquidAssert ((\x -> 0==1) (foo 0))
+\end{code}
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=TellingLies.hs" target=
+"_blank">Demo:</a> Check a real property here! 
+
+Our solution (Current Work)
+---------------------------
+
+- Use **termination analysis** to track infinite computations
+
+- Use **true** refinements for infinite computations
+
+
+Size-based Termination Analysis
+-------------------------------
+
+- Use refinement types to force the recursive argument to **decrease**
+\begin{code}
+{-@ unsafeFoo :: n:Nat -> {v:Nat | v < n} @-}
+unsafeFoo     :: Int -> Int
+  -- unsafeFoo :: n'{v:Nat | v < n} -> {v:Nat | v < n'}
+unsafeFoo n   | n > 0     = n - 1
+              | otherwise = unsafeFoo n
+\end{code}
+
+<br>
+
+- `prop` is safe, but the program is decided unsafe
+\begin{code}
+prop1 = liquidAssert ((\x -> 0==1) inf)
+  where inf = unsafeFoo 0
+\end{code}
+
+Refinements of infinite Computations
+------------------------------------
+If you need a non-terminating function, use `Lazy` to declare
+
+ - We know that `foo` may not terminate
+
+ - Its return type is refined with **true**
+
+\begin{code}
+{-@ Lazy safeFoo @-}
+{-@ safeFoo :: n:Nat -> {v:Int | true} @-}
+safeFoo    :: Int   -> Int
+safeFoo n   | n > 0     = n - 1
+            | otherwise = safeFoo n
+\end{code}
+
+<br>
+
+Now, `prop` is unsafe
+
+\begin{code}
+prop2 = liquidAssert ((\x -> 0==1) inf)
+  where inf = safeFoo 0
+\end{code}
+
+Restore Soundness
+-----------------
+
+- Use **termination analysis** to track infinite objects
+
+- Use **true** refinements for infinite objects
+
+`Foo` was declared `Lazy`
+-------------------------
+\begin{code}
+{-@ Lazy foo @-}
+\end{code}
+
diff --git a/docs/slides/niki/lhs/List.lhs b/docs/slides/niki/lhs/List.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/List.lhs
@@ -0,0 +1,484 @@
+% Recursive Invariants
+
+Recursive Invariants
+--------------------
+
+\begin{code}
+module List where
+
+{-@ LIQUID "--no-termination" @-}
+\end{code}
+
+
+Recursive Invariants
+--------------------
+
+Recall the definition of lists <br>
+
+\begin{code}
+infixr `C`
+data L a = N | C a (L a)
+\end{code}
+
+Lets parameterize the definition with an abstract refinement `p` <br>
+
+\begin{code}
+{-@ data L a <p :: a -> a -> Prop>
+      = N 
+      | C (h :: a) (tl :: (L <p> a<p h>))
+  @-}
+\end{code}
+
+- `p` is a binary relation between two `a` values
+
+- definition relates *head* with all the *tail* elements 
+
+**Recursive** : So `p` holds between **every pair** of list elements!
+
+Recursive Invariants: Example
+-----------------------------
+
+Consider a list with three elements <br>
+
+\begin{code} _ 
+h1 `C` h2 `C` h3 `C` N :: L <p> a 
+\end{code}
+
+Recursive Invariants: Example
+-----------------------------
+
+If we unfold the list **once** we get <br>
+
+\begin{code} _
+h1              :: a
+h2 `C` h3 `C` N :: L <p> a<p h1> 
+\end{code}
+
+Recursive Invariants: Example
+-----------------------------
+
+If we unfold the list a **second** time we get <br>
+
+\begin{code} _ 
+h1       :: a
+h2       :: a<p h1>  
+h3 `C` N :: L <p> a<p h1 && p h2> 
+\end{code}
+
+Recursive Invariants: Example
+-----------------------------
+
+Finally, with a **third** unfold we get <br>
+
+\begin{code} _ 
+h1 :: a
+h2 :: a<p h1>  
+h3 :: a<p h1 && p h2>  
+N  :: L <p> a<p h1 && p h2 && p h3> 
+\end{code}
+
+<br>
+
+Note how `p` holds between **every pair** of elements in the list. 
+
+Using Recursive Invariants
+--------------------------
+
+That was a rather *abstract*.
+
+How would we **use** the fact that `p` holds between **every pair** ?
+
+
+Using Recursive Invariants
+--------------------------
+
+That was a rather *abstract*.
+
+How would we **use** the fact that `p` holds between **every pair** ?
+
+<br>
+
+Lets *instantiate* `p` with a concrete refinement 
+
+<br>
+
+\begin{code}
+{-@ type SL a = L <{\hd v -> hd <= v}> a @-}
+\end{code}
+
+- The refinement says `hd` is less than the arbitrary tail element `v`.
+
+- Thus `SL` denotes lists sorted in **increasing order**!
+
+Using Recursive Invariants
+--------------------------
+
+LiquidHaskell verifies that the following list is indeed increasing...
+
+<br>
+
+\begin{code}
+{-@ slist :: SL Int @-}
+slist :: L Int
+slist = 1 `C` 6 `C` 12 `C` N
+\end{code}
+
+<br> ... and complains that the following is not: <br>
+
+
+\begin{code}
+{-@ slist' :: SL Int @-}
+slist' :: L Int
+slist' = 6 `C` 1 `C` 12 `C` N
+\end{code}
+
+
+InsertSort
+----------
+
+More interestingly, we can verify that various sorting algorithms return sorted lists.
+
+<br>
+
+\begin{code}
+{-@ insertSort' :: (Ord a) => [a] -> SL a @-}
+insertSort'     :: (Ord a) => [a] -> L a 
+insertSort'     = foldr insert' N
+\end{code}
+
+<br> The hard work is done by `insert` defined as <br>
+
+\begin{code}
+insert' y N                      = y `C` N                           
+insert' y (x `C` xs) | y <= x    = y `C` x `C` xs
+                     | otherwise = x `C` insert' y xs
+\end{code}
+
+<br>
+
+**Hover** the mouse over `insert'` to see what type was inferred for it.
+
+Analyzing Plain Lists
+---------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target= "_blank">Demo:</a> 
+
+
+We can easily modify GHC's List definition to abstract over a refinement:
+
+<br>
+
+\begin{code} _
+data [a] <p :: a -> a -> Prop>
+  = [] 
+  | (:) (h :: a) (tl :: ([a<p h>]<p>))
+\end{code}
+
+<br>
+
+So, we can define and use **ordered** versions of GHC Lists
+
+<br>
+
+\begin{code}
+{-@ type OList a = [a]<{\hd v -> (hd <= v)}> @-}
+\end{code}
+
+Insertion Sort
+--------------
+
+Now we can verify the usual sorting algorithms: 
+
+<br>
+
+\begin{code}
+{-@ insertSort :: (Ord a) => xs:[a] -> OList a @-}
+insertSort xs  = foldr insert [] xs
+\end{code}
+
+<br> 
+
+where the helper does the work
+
+<br>
+
+\begin{code}
+insert y []                   = [y]
+insert y (x : xs) | y <= x    = y : x : xs 
+                  | otherwise = x : insert y xs
+\end{code}
+
+Merge Sort
+----------
+
+Now we can verify the usual sorting algorithms: 
+
+
+\begin{code}
+{-@ mergeSort :: (Ord a) => [a] -> OList a @-}
+mergeSort     :: Ord a => [a] -> [a]
+mergeSort []  = []
+mergeSort [x] = [x]
+mergeSort xs  = merge (mergeSort xs1) (mergeSort xs2) 
+  where 
+   (xs1, xs2) = split xs
+
+split :: [a]    -> ([a], [a])
+split (x:(y:zs)) = (x:xs, y:ys) where (xs, ys) = split zs
+split xs         = (xs, [])
+
+merge :: Ord a => [a] -> [a] -> [a]
+merge xs [] = xs
+merge [] ys = ys
+merge (x:xs) (y:ys) | x <= y    = x:(merge xs (y:ys))
+                    | otherwise = y:(merge (x:xs) ys)
+\end{code}
+
+<br> A significant amount of inference happens above. See the types.
+
+QuickSort
+---------
+
+Now we can verify the usual sorting algorithms: <br>
+
+\begin{code}
+{-@ quickSort    :: (Ord a) => [a] -> OList a @-}
+quickSort []     = []
+quickSort (x:xs) = append x lts gts 
+  where 
+    lts          = quickSort [y | y <- xs, y < x]
+    gts          = quickSort [z | z <- xs, z >= x]
+\end{code}
+
+<br> We require a special `append` parameterized by the **pivot** <br>
+
+\begin{code}
+append k []     ys  = k : ys
+append k (x:xs) ys  = x : append k xs ys
+\end{code}
+
+Look at the inferred type to understand why!
+
+
+Other Instantiations: Decreasing Lists
+--------------------------------------
+
+We may *instantiate* `p` with many different concrete relations
+
+<br> **Decreasing Lists** <br>
+
+\begin{code}
+{-@ type DecrList a = [a]<{\hd v -> (hd >= v)}> @-}
+\end{code}
+
+<br> After which we can check that <br>
+
+\begin{code}
+{-@ decList :: DecrList Int @-}
+decList :: [Int]
+decList = [3, 2, 1, 0]
+\end{code}
+
+Multiple Instantiations: Distinct Lists 
+---------------------------------------
+
+We may *instantiate* `p` with many different concrete relations
+
+<br> **Distinct Lists**: Lists not containing any duplicate values <br>
+
+\begin{code}
+{-@ type DiffList a = [a]<{\hd v -> (hd /= v)}> @-}
+\end{code}
+
+<br> After which we can check that <br>
+
+\begin{code}
+{-@ diffList :: DiffList Int @-}
+diffList :: [Int]
+diffList = [2, 3, 1, 0]
+\end{code}
+
+Binary Trees 
+------------
+
+
+- Consider a `Map` from keys of type `k` to values of type `a` 
+
+- Implemented as a binary tree:
+
+\begin{code}
+data Map k a = Tip
+             | Bin Size k a (Map k a) (Map k a)
+
+type Size    = Int
+\end{code}
+
+Binary Trees 
+------------
+
+We abstract from the structure two refinements `l` and `r` 
+
+- `l` relates root `key` with **left**-subtree keys
+
+- `r` relates root `key` with **right**-subtree keys
+
+\begin{code}
+{-@
+  data Map k a <l :: k -> k -> Prop, r :: k -> k -> Prop>
+      = Tip
+      | Bin (sz    :: Size)
+            (key   :: k)
+            (value :: a)
+            (left  :: Map <l, r> (k <l key>) a)
+            (right :: Map <l, r> (k <r key>) a)
+  @-}
+\end{code}
+
+
+Ordered Trees
+-------------
+
+Thus, if we instantiate the refinements thus: 
+
+<br>
+
+\begin{code}
+{-@ type BST k a     = Map <{\r v -> v < r }, {\r v -> v > r }> k a @-}
+{-@ type MinHeap k a = Map <{\r v -> r <= v}, {\r v -> r <= v}> k a @-}
+{-@ type MaxHeap k a = Map <{\r v -> r >= v}, {\r v -> r >= v}> k a @-}
+\end{code}
+
+- `BST k v` denotes **binary-search** ordered trees
+
+- `MinHeap k v` denotes **min-heap** ordered trees
+
+- `MaxHeap k v` denotes **max-heap** ordered trees.
+
+Binary Search Ordering
+----------------------
+
+We can use the `BST` type to automatically verify that tricky functions
+ensure and preserve binary-search ordering.
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Map.hs" target= "_blank">Demo:</a> 
+
+\begin{code}So, we can have
+empty :: BST k a
+
+insert :: Ord k => k:k -> a:a -> t:BST k a -> BST k a
+
+delete :: (Ord k) => k:k -> t:BST k a -> BST k a
+\end{code}
+
+Binary Search Ordering: Empty
+-----------------------------
+
+\begin{code}
+{-@ empty :: BST k a @-}
+empty     :: Map k a
+empty     = Tip
+\end{code}
+
+Binary Search Ordering: Insert
+------------------------------
+
+\begin{code}
+{-@ insertBST :: Ord k => k:k -> a:a -> t:BST k a -> BST k a @-}
+insertBST     :: Ord k => k -> a -> Map k a -> Map k a
+insertBST kx x t
+  = case t of
+     Tip -> singleton kx x
+     Bin sz ky y l r
+         -> case compare kx ky of
+              LT -> balance ky y (insertBST kx x l) r
+              GT -> balance ky y l (insertBST kx x r)
+              EQ -> Bin sz kx x l r
+\end{code}
+
+Binary Search Ordering: Delete 
+------------------------------
+
+\begin{code}
+{-@ delete :: (Ord k) => k:k -> t:BST k a -> BST k a @-}
+delete :: Ord k => k -> Map k a -> Map k a
+delete k t
+  = case t of
+      Tip -> Tip
+      Bin _ kx x l r
+          -> case compare k kx of
+               LT -> balance kx x (delete k l) r
+               GT -> balance kx x l (delete k r)
+               EQ -> glue kx l r
+\end{code}
+
+
+Helper Functions: Constructors
+------------------------------
+
+Below are the helper functions used by `insert` and `delete`:
+
+\begin{code}
+singleton :: k -> a -> Map k a
+singleton k x
+  = Bin 1 k x Tip Tip
+
+bin :: k -> a -> Map k a -> Map k a -> Map k a
+bin k x l r
+  = Bin (size l + size r + 1) k x l r
+
+size :: Map k a -> Int
+size t
+  = case t of
+      Tip            -> 0
+      Bin sz _ _ _ _ -> sz
+\end{code}
+
+Helper Functions: Extractors 
+----------------------------
+
+\begin{code}
+deleteFindMax t
+  = case t of
+      Bin _ k x l Tip -> (k, x, l)
+      Bin _ k x l r -> let (km3, vm, rm) = deleteFindMax r in
+                       (km3, vm, (balance k x l rm))
+      Tip           -> (error ms, error ms, Tip)
+  where 
+    ms = "Map.deleteFindMax : empty Map"
+
+deleteFindMin t
+  = case t of
+      Bin _ k x Tip r -> (k, x, r)
+      Bin _ k x l r -> let (km4, vm, lm) = deleteFindMin l in
+                       (km4, vm, (balance k x lm r))
+      Tip             -> (error ms, error ms, Tip)
+  where 
+    ms = "Map.deleteFindMin : empty Map"
+\end{code}
+
+Helper Functions: Connectors 
+----------------------------
+
+Below are the helper functions used by `insert` and `delete`:
+
+\begin{code}
+glue :: k -> Map k a -> Map k a -> Map k a
+glue k Tip r = r
+glue k l Tip = l
+glue k l r
+  | size l > size r = let (km1, vm, lm) = deleteFindMax l 
+                      in balance km1 vm lm r
+
+  | otherwise       = let (km2, vm, rm) = deleteFindMin r 
+                      in balance km2 vm l rm
+
+{-@ balance :: key:k 
+            -> a 
+            -> (BST {v:k | v < key} a) 
+            -> (BST {v:k| key < v} a) -> (BST k a) @-}
+balance :: k -> a -> Map k a -> Map k a -> Map k a
+balance k x l r = undefined
+\end{code}
+
+
+
diff --git a/docs/slides/niki/lhs/Loop.lhs b/docs/slides/niki/lhs/Loop.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/Loop.lhs
@@ -0,0 +1,121 @@
+% Higher Order Specifications
+
+
+Higher Order Specifications
+---------------------------
+
+\begin{code}
+module Loop where
+
+{-@ LIQUID "--no-termination"@-}
+\end{code}
+
+
+Higher Order Specifications
+---------------------------
+
+Consider a `loop` function: <br>
+
+\begin{code}
+loop :: Int -> Int -> a -> (Int -> a -> a) -> a
+loop lo hi base f        = go lo base
+  where 
+    go i acc | i < hi    = go (i+1) (f i acc)
+             | otherwise = acc
+\end{code}
+
+<br>
+
+LiquidHaskell **infers**
+
+- if `lo <= hi` then `f` called with `lo <= i < hi`
+
+
+Higher Order Specifications
+---------------------------
+
+Lets use `(!!)` to write a function that sums an `Int` list
+
+\begin{code}
+{-@ listSum :: [Int] -> Int @-}
+listSum     :: [Int] -> Int
+listSum xs  = loop 0 n 0 body 
+  where 
+    body    = \i acc -> acc + (xs !! i)
+    n       = length xs
+\end{code}
+
+By **function subtyping** LiquidHaskell **infers**
+
+- `body` called with `0 <= i < llen xs` 
+- hence, indexing safe.
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Loop.hs" target= "_blank">Demo:</a> 
+Let's change the `0` to `-1` and see what happens!
+
+Higher Order Specifications
+---------------------------
+
+We can give this function a better type:
+
+\begin{code}
+{-@ listNatSum :: [Nat] -> Nat @-}
+listNatSum     :: [Int] -> Int
+listNatSum xs  = loop 0 n 0 body 
+  where 
+    body       = \i acc -> acc + (xs !! i)
+    n          = length xs
+\end{code}
+
+To verify this type, note: `(+) :: Nat -> Nat -> Nat` 
+
+LiquidHaskell **instantiates** `a` in `loop` with `Nat` 
+
+- `loop :: Int -> Int -> Nat -> (Int -> Nat -> Nat) -> Nat`
+
+Yielding the output.
+
+Higher Order Specifications
+---------------------------
+
+By the same analysis, LiquidHaskell verifies that <br>
+
+\begin{code}
+{-@ listEvenSum :: [Even] -> Even @-}
+listEvenSum     :: [Int] -> Int
+listEvenSum xs  = loop 0 n 0 body 
+  where body   = \i acc -> acc + (xs !! i)
+        n      = length xs
+\end{code}
+
+Here, the system deduces that `(+)` has type
+
+- `x:Int-> y:Int -> {v:Int| v=x+y} <: Even -> Even -> Even`
+
+Hence, verification proceeds by *instantiating* `a` with `Even`
+
+- `loop :: Int -> Int -> Even -> (Int -> Even -> Even) -> Even`
+
+
+
+Another Example
+---------------
+
+Consider a simpler example:<br>
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Int| v = m + n} @-}
+add     :: Int -> Int -> Int
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+Cannot use parametric polymorphism as before! 
+
+- Cannot instantiate `a` with `{v:Int|v = n + m}` ... 
+- ... as this only holds after **last iteration** of loop!
+
+Require Higher Order Invariants
+
+- On values computed in **intermediate** iterations...
+- ... i.e. invariants that **depend on the iteration index**.
+
diff --git a/docs/slides/niki/lhs/Measures.lhs b/docs/slides/niki/lhs/Measures.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/Measures.lhs
@@ -0,0 +1,176 @@
+% Measures
+
+Measures
+-----------------------
+
+\begin{code}
+module Measures where
+import Prelude hiding ((!!), length)
+import Language.Haskell.Liquid.Prelude
+\end{code}
+
+
+Measuring A List's length in logic
+----------------------------------
+
+On `List` data type
+\begin{code}
+infixr `C`
+data L a = N | C a (L a)
+\end{code}
+
+We define a **measure** for the length of a `List` <br>
+
+\begin{code}
+{-@ measure llen :: (L a) -> Int
+    llen(N)      = 0
+    llen(C x xs) = 1 + (llen xs)
+  @-}
+\end{code}
+
+<br>
+
+\begin{code} LiquidHaskell then **automatically strengthens** the types of data constructors
+data L a where 
+  N :: {v : L a | (llen v) = 0}
+  C :: x:a -> xs:(L a) -> {v:(L a) |(llen v) = 1 + (llen xs)}
+\end{code}
+
+Measuring A List's length in logic
+----------------------------------
+
+Now we can verify
+
+<br>
+
+\begin{code}
+{-@ length :: xs:(L a) -> {v:Int | v = (llen xs)} @-}
+length     :: L a -> Int
+length N        = 0
+length (C _ xs) = 1 + (length xs)
+\end{code}
+
+Measuring A List's length in logic
+----------------------------------
+
+And we can type `(!!)` as
+
+
+<br>
+
+\begin{code}
+{-@ (!!)     :: ls:(L a) -> i:{v:Nat | v < (llen ls)} -> a @-}
+(!!)         :: L a -> Int -> a
+(C x _) !! 0 = x
+(C _ xs)!! n = xs!!(n-1)
+_       !! _ = liquidError "This should not happen!"
+\end{code}
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellMeasure.hs" target= "_blank">Demo:</a> 
+Lets see what happens if we **change** the precondition
+
+
+Another measure for List
+--------------------------
+
+We define a new **measure** to check nullity of a `List` <br>
+
+\begin{code}
+{-@ measure isNull :: (L a) -> Prop
+    isNull(N)      = true
+    isNull(C x xs) = false
+  @-}
+\end{code}
+
+<br>
+
+\begin{code} LiquidHaskell then **automatically strengthens** the types of data constructors
+data L a where 
+  N :: {v : L a | isNull v}
+  C :: x:a -> xs:(L a) -> {v:(L a) | not (isNull v)}
+\end{code}
+
+
+
+Multiple measures for List
+--------------------------
+
+The types of data constructors will be the **conjuction** of all the inferred types:
+
+
+\begin{code} The types from `llen` definition
+data L a where 
+  N :: {v : L a | (llen v) = 0}
+  C :: a -> xs: L a -> {v:L a |(llen v) = 1 + (llen xs)}
+\end{code}
+
+<br>
+\begin{code} and the types from `isNull`
+data L a where 
+  N :: {v : L a | isNull v}
+  C :: a -> xs: L a -> {v:L a | not (isNull v)}
+\end{code}
+
+
+<br>
+\begin{code} So, the final types will be
+data L a where 
+  N :: {v : L a | (llen v) = 0 && (isNull v)}
+  C :: a -> xs: L a -> {v:L a |(llen v) = 1 + (llen xs) && not (isNull v)}
+\end{code}
+
+
+Invariants in Data Constructors
+------------------------------
+
+We can refine the definition of data types setting **invariants**
+\begin{code}
+{-@ data L a = N
+             | C (x :: a) (xs :: L {v:a | x <= v})  @-}
+\end{code}
+
+<br>
+
+\begin{code} As before,the types of data constuctors are strengthened to
+data L a where
+  N :: L a
+  C :: x:a -> xs: L {v:a | x <= v} -> L a
+\end{code}
+
+LiquidHaskell
+
+- **Proves** the property when `C` is called
+
+- **Assumes** the property when `C` is opened
+
+
+
+Increasing Lists
+-----------------
+
+This invariant constrains all Lists to **increasing**
+\begin{code}
+{-@ data L a = N
+             | C (x :: a) (xs :: L {v:a | x <= v})  @-}
+\end{code}
+
+<br>
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellInsertSort.hs"
+target= "_blank">Insert sort</a> 
+\begin{code}
+{-@ insert :: Ord a => a -> L a -> L a @-}
+insert :: Ord a => a -> L a -> L a
+insert y (x `C` xs) | x <= y    = x `C` insert y xs
+                    | otherwise = y `C` insert x xs
+
+{-@ insertSort  :: Ord a => [a] -> L a @-}
+insertSort  :: Ord a => [a] -> L a
+insertSort = foldr insert N
+\end{code}
+
+<br>
+What if increasing and decreasing lists should co-exist?
+
+We use **abstract refinements** to allow it!
diff --git a/docs/slides/niki/lhs/SimpleRefinements.lhs b/docs/slides/niki/lhs/SimpleRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/SimpleRefinements.lhs
@@ -0,0 +1,138 @@
+% Simple Refinement Types
+
+Simple Refinement Types
+-----------------------
+
+\begin{code}
+module SimpleRefinements where
+import Language.Haskell.Liquid.Prelude
+\end{code}
+
+
+Simple Refinement Types
+-----------------------
+
+We use special comments to give specifications, 
+as *refinement types*.
+
+This type describes `Int` values that equal `0`.
+
+
+\begin{code}
+{-@ zero :: {v:Int | v = 0} @-}
+zero     :: Int
+zero     =  0
+\end{code}
+
+Refinements are *logical formulas*
+----------------------------------
+
+If 
+
+- refinement of `T1` **implies** refinement of `T2` 
+
+- `p1 => p2`
+
+Then
+
+- `T1` is a **subtype** of `T2`
+
+- `{v:t | p1} <: {v:t | p2}`
+
+Refinements are *logical formulas*
+----------------------------------
+
+For example, since
+
+- `v = 0` *implies* `v >= 0`
+
+Therefore
+ 
+- `{v:Int | v = 0} <: {v:Int | v >= 0}`
+
+
+Refinements are *logical formulas*
+----------------------------------
+
+\begin{code} So we can have a type for natural numbers: <br>
+type Nat = {v:Int | v >= 0}
+\end{code}
+
+<br>
+
+And, via SMT based subtyping LiquidHaskell verifies:
+
+<br>
+
+\begin{code}
+{-@ zero' :: Nat @-}
+zero'     :: Int
+zero'     =  0
+\end{code}
+
+
+Lists: Universal Invariants 
+---------------------------
+
+Constructors enable *universally quantified* invariants.
+
+For example, we define a list:
+
+\begin{code}
+infixr `C`
+data L a = N | C a (L a)
+\end{code}
+
+<br>
+
+And specify that, *every element* in a list is non-negative:
+
+\begin{code}
+{-@ natList :: L Nat @-}
+natList     :: L Int
+natList     =  0 `C` 1 `C` 3 `C` N
+\end{code}
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+Lets see what happens if `natList` contained a negative number. 
+
+Refinement Function Types
+-------------------------
+
+Consider a `safeDiv` operator: <br>
+
+\begin{code}
+safeDiv    :: Int -> Int -> Int
+safeDiv x y = x `div` y
+\end{code}
+
+<br>
+We can use refinements to specify a **precondition**: divisor is **non-zero** <br>
+
+\begin{code}
+{-@ safeDiv :: Int -> {v:Int | v != 0} -> Int @-}
+\end{code}
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+Lets see what happens if the preconditions cannot be
+proven. 
+
+Dependent Function Types
+------------------------
+
+\begin{code} Consider a list indexing function:
+(!!)         :: L a -> Int -> a
+(C x _) !! 0 = x
+(C _ xs)!! n = xs!!(n-1)
+_       !! _ = liquidError "This should not happen!"
+\end{code}
+
+<br>
+
+We desire a **precondition** that index `i` be between `0` and **list length**.
+
+We use **measures** to talk about the length of a list in **logic**.
+
+
diff --git a/docs/slides/niki/lhs/liquid.css b/docs/slides/niki/lhs/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/liquid.css
@@ -0,0 +1,105 @@
+.hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+  // font-weight: bold;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   /* color: #00FFFF; color: #0E84B5; */
+  //font-weight: bold;  
+}
+
+.hs-definition { 
+  color: #06287E 
+  /* font-weight: bold; */ 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  // font-size: 120%;
+  // font-family: Bitstream Vera Sans Mono,monospace;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/niki/lhs/slides.css b/docs/slides/niki/lhs/slides.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/niki/lhs/slides.css
@@ -0,0 +1,258 @@
+@font-face {
+	font-family: 'PT Mono';
+    font-style: normal;
+	font-weight: normal;
+	src: local("☺"), url('fonts/PT_Mono-Regular.ttf') format('truetype');
+}
+@font-face {
+	font-family: 'PT Sans';
+    font-style: normal; 
+	font-weight: bold;
+	src: local("☺"), url('fonts/PT_Sans-Web-Bold.ttf') format('truetype');
+}@font-face {
+	font-family: 'PT Sans';
+    font-style: italic;
+	font-weight: normal;
+	src: local("☺"), url('fonts/PT_Sans-Web-Italic.ttf') format('truetype');
+}@font-face {
+	font-family: 'PT Sans';
+    font-style: normal;
+	font-weight: normal;
+	src: local("☺"), url('fonts/PT_Sans-Web-Regular.ttf') format('truetype');
+}
+@font-face {
+	font-family: 'PT Sans Narrow';
+    font-style: normal;
+	font-weight: bold;
+	src: local("☺"), url('fonts/PT_Sans-Narrow-Web-Bold.ttf') format('truetype');
+}
+@font-face {
+	font-family: 'PT Sans Narrow';
+    font-style: normal;
+	font-weight: normal;
+	src: local("☺"), url('fonts/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
+}
+html {
+    height: 100%;
+	background-color: #fefffe;
+}
+body {
+	width: 1024px !important;
+    height: 600px !important;
+	margin-left: -512px !important;
+	margin-top: -300px !important;
+}
+section {
+	background: transparent;
+	color: #000;
+	width: 100%  !important;
+	/* width: 800px !important; */
+	height: 600px !important;
+    padding: 50px 112px 0;	
+	font-family: 'PT Sans', sans-serif;
+	font-size: 16pt;
+}
+
+body :first-child {
+}
+address, blockquote, dl, fieldset, form, h1, h2, h3, h4, h5, h6, hr, ol, p, pre, table, ul, dl { padding: 10px 20px 10px 20px; }
+h1, h2, h3 {
+	text-align: left;
+	color: #666; 
+	font-family: 'PT Sans Narrow', sans-serif;
+	font-weight: bold;
+}
+input, select {
+border 0.5pt solid black;
+font-size: 16pt;
+line-height: 10pt;
+padding: 0 0 -2.5pt 0;
+z-index:1;
+}
+ul, ol {
+	margin: 10px 10px 10px 50px;
+}
+a { color: #205CB3; }
+section.titleslide h1 { margin-top: 200px; }
+h1.title { margin-top: 150px; font-size:200%; margin-bottom: 20px; text-align: center; text-shadow:0px 2px 1px #444; 
+-webkit-transition: color 1s ease-in-out;
+-moz-transition: color 1s ease-in-out;
+ }
+h1.title:hover {
+color: #C43628;
+}
+h2.author { font-size: 120%; margin-top: 0px; margin-bottom: 0px; text-align:center; color: #555; font-family: 'PT Sans Narrow'; font-weight: normal;}
+h3.date { font-size: 80%; margin-top: 0px; text-align: center; color: #555; font-family: 'PT Mono'; font-weight: normal;}
+h1 { font-size: 180%; margin: 0 0 10px; text-shadow:0px 2px 1px #fff;}
+h2 { font-size: 140%; } 
+h3 { font-size: 100%; }
+blockquote { font-style: italic }
+q {
+	display: inline-block;
+	width: 700px;
+	height: 600px;
+	background-color: black;
+	color: white;
+	font-size: 60px;
+	padding: 50px;
+}
+footer {
+	position: absolute;
+	bottom: 10px;
+	right: 20px;
+	text-shadow: white 0px 1px 0px, rgba(0, 0, 0, 0.2) 0 2px 5px;
+}
+/* JHALA: pre, code { background: transparent; } */
+pre, code {background-color:#E6F0FA;}
+
+pre { padding: 10px 50px; }
+td > pre { padding: 0px; }
+td { padding: 5px; }
+::-moz-selection { background-color: khaki; }
+code { font-family: 'PT Mono'; font-size: 90%; }
+code > span.co { font-style: normal; }
+code > span.kw { font-weight: normal; }
+code > span.er { font-weight: normal; }
+
+/* Transition effect */
+/* Feel free to change the transition effect for original
+animations. See here:
+https://developer.mozilla.org/en/CSS/CSS_transitions
+How to use CSS3 Transitions: */
+section {
+	-moz-transition: left 400ms ease-in-out 0s;
+	-webkit-transition: left 400ms ease-in-out 0s;
+	-ms-transition: left 400ms ease-in-out 0s;
+	transition: left 400ms ease-in-out 0s;
+}
+
+/* Before */
+section { left: -150%; }
+/* Now */
+section[aria-selected] { left: 0; }
+/* After */
+section[aria-selected] ~ section { left: +150%; }
+
+/* Incremental elements */
+
+/* By default, visible */
+.incremental > * { opacity: 1; }
+
+/* The current item */
+.incremental > *[aria-selected] { color: red; opacity: 1; }
+
+/* The items to-be-selected */
+.incremental > *[aria-selected] ~ * { opacity: 0.2; }
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+a { color: #205CB3; }
+
+.hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+  // font-weight: bold;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   /* color: #00FFFF; color: #0E84B5; */
+  //font-weight: bold;  
+}
+
+.hs-definition { 
+  color: #06287E 
+  /* font-weight: bold; */ 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 60%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 80%;
+  // font-family: Bitstream Vera Sans Mono,monospace;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/plpv14/Makefile b/docs/slides/plpv14/Makefile
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/Makefile
@@ -0,0 +1,70 @@
+####################################################################
+SERVERHOME=nvazou@goto.ucsd.edu:~/public_html/liquidtutorial/
+RJSERVER=rjhala@goto.ucsd.edu:~/public_html/liquid/haskell/plpv/lhs/
+####################################################################
+
+# REVEAL=$(PANDOC) -t revealjs -V revealjs-url=../_support/reveal -V theme=serif
+
+REVEAL=pandoc \
+	   --from=markdown+simple_tables 		\
+	   --to=html5                           \
+	   --standalone                         \
+	   --mathjax \
+	   --section-divs                       \
+	   --template=_support/template.reveal  \
+	   --variable reveal=../_support/reveal
+
+PANDOC=pandoc --columns=80  -s --mathjax --slide-level=2
+SLIDY=$(PANDOC) -t slidy
+DZSLIDES=$(PANDOC) --highlight-style tango --css=slides.css -w dzslides
+HANDOUT=$(PANDOC) --highlight-style tango --css=text.css -w html5
+WEBTEX=$(PANDOC) -s --webtex -i -t slidy
+BEAMER=pandoc -t beamer
+LIQUID=liquid --short-names 
+
+mdObjects   := $(patsubst %.lhs,%.lhs.markdown,$(wildcard lhs/*.lhs))
+htmlObjects := $(patsubst %.lhs,%.lhs.slides.html,$(wildcard lhs/*.lhs))
+
+####################################################################
+
+one: $(mdObjects)
+	$(REVEAL) lhs/00_Index.lhs.markdown > lhs/index.html
+
+tut: $(mdObjects)
+	$(REVEAL) lhs/*.markdown > lhs/tutorial.html 
+
+all: slides copy
+
+slides: $(htmlObjects)
+
+plpv: slides
+	scp lhs/*.html $(RJSERVER)
+
+lhs/%.lhs.markdown: lhs/%.lhs
+	-$(LIQUID) $?
+
+lhs/%.lhs.slides.html: lhs/%.lhs.markdown
+	$(REVEAL) $? -o $@ 
+
+lhs/%.lhs.slides.pdf: lhs/%.lhs.markdown
+	$(BEAMER) $? -o $@ 
+
+foo:
+	$(LIQUID) lhs/Foo.lhs
+	$(REVEAL) lhs/Foo.lhs.markdown -o lhs/Foo.lhs.html
+
+copy:
+	cp lhs/*lhs.html html/
+	cp lhs/*lhs.slides.html html/
+	cp css/*.css html/
+	cp -r fonts html/
+	cp index.html html/
+	cp Benchmarks.html html/
+
+clean:
+#	cd lhs/ && ../cleanup && cd ../
+#	cd html/ && rm -rf * && cd ../
+#	cp index.html html/
+
+upload: 
+	scp -r html/* $(SERVERHOME)
diff --git a/docs/slides/plpv14/_support/liquid.css b/docs/slides/plpv14/_support/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/liquid.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/plpv14/_support/reveal/LICENSE b/docs/slides/plpv14/_support/reveal/LICENSE
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/docs/slides/plpv14/_support/reveal/README.md b/docs/slides/plpv14/_support/reveal/README.md
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/README.md
@@ -0,0 +1,226 @@
+# reveal.js
+
+A framework for easily creating beautiful presentations using HTML. [Check out the live demo](http://lab.hakim.se/reveal-js/).
+
+reveal.js comes with a broad range of features including [nested slides](https://github.com/hakimel/reveal.js#markup), [markdown contents](https://github.com/hakimel/reveal.js#markdown), [PDF export](https://github.com/hakimel/reveal.js#pdf-export), [speaker notes](https://github.com/hakimel/reveal.js#speaker-notes) and a [JavaScript API](https://github.com/hakimel/reveal.js#api). It's best viewed in a browser with support for CSS 3D transforms but [fallbacks](https://github.com/hakimel/reveal.js/wiki/Browser-Support) are available to make sure your presentation can still be viewed elsewhere.
+
+
+#### More reading in the Wiki:
+- [Changelog](https://github.com/hakimel/reveal.js/wiki/Changelog): Up-to-date version history.
+- [Examples](https://github.com/hakimel/reveal.js/wiki/Example-Presentations): Presentations created with reveal.js, add your own!
+- [Browser Support](https://github.com/hakimel/reveal.js/wiki/Changelog): Explanation of browser support and fallbacks.
+
+
+The framework is and will remain free. Donations are available as an optional way of supporting the project. Proceeds go towards futher development, hosting and domain costs for the GUI editor which will be out shortly.
+
+[![Click here to lend your support to: reveal.js and make a donation at www.pledgie.com !](http://www.pledgie.com/campaigns/18182.png?skin_name=chrome)](http://www.pledgie.com/campaigns/18182)
+
+
+## Instructions
+
+### Markup
+
+Markup heirarchy needs to be ``<div class="reveal"> <div class="slides"> <section>`` where the ``<section>`` represents one slide and can be repeated indefinitely. If you place multiple ``<section>``'s inside of another ``<section>`` they will be shown as vertical slides. The first of the vertical slides is the "root" of the others (at the top), and it will be included in the horizontal sequence. For example:
+
+```html
+<div class="reveal">
+	<div class="slides"> 
+		<section>Single Horizontal Slide</section>
+		<section>
+			<section>Vertical Slide 1</section>
+			<section>Vertical Slide 2</section>
+		</section>
+	</div>
+</div>
+```
+
+### Markdown
+
+It's possible to write your slides using Markdown. To enable Markdown simply add the ```data-markdown``` attribute to your ```<section>``` elements and reveal.js will automatically load the JavaScript parser. 
+
+This is based on [data-markdown](https://gist.github.com/1343518) from [Paul Irish](https://github.com/paulirish) which in turn uses [showdown](https://github.com/coreyti/showdown/). This is sensitive to indentation (avoid mixing tabs and spaces) and line breaks (avoid consecutive breaks). Updates to come.
+
+```html
+<section data-markdown>
+	## Page title
+	
+	A paragraph with some text and a [link](http://hakim.se).
+</section>
+```
+
+
+### Configuration
+
+At the end of your page you need to initialize reveal by running the following code. Note that all config values are optional and will default as specified below.
+
+```javascript
+Reveal.initialize({
+	// Display controls in the bottom right corner
+	controls: true,
+
+	// Display a presentation progress bar
+	progress: true,
+
+	// Push each slide change to the browser history
+	history: false,
+
+	// Enable keyboard shortcuts for navigation
+	keyboard: true,
+
+	// Loop the presentation
+	loop: false,
+
+	// Number of milliseconds between automatically proceeding to the 
+	// next slide, disabled when set to 0
+	autoSlide: 0,
+
+	// Enable slide navigation via mouse wheel
+	mouseWheel: true,
+
+	// Apply a 3D roll to links on hover
+	rollingLinks: true,
+
+	// Transition style
+	transition: 'default' // default/cube/page/concave/linear(2d)
+});
+```
+
+### Dependencies
+
+Reveal.js doesn't _rely_ on any third party scripts to work but a few optional libraries are included by default. These libraries are loaded as dependencies in the order they appear, for example:
+
+```javascript
+Reveal.initialize({
+	dependencies: [
+		// Syntax highlight for <code> elements
+		{ src: 'lib/js/highlight.js', async: true, callback: function() { window.hljs.initHighlightingOnLoad(); } },
+		// Cross-browser shim that fully implements classList - https://github.com/eligrey/classList.js/
+		{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } }
+		// Interpret Markdown in <section> elements
+		{ src: 'lib/js/data-markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+		{ src: 'lib/js/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+		// Speaker notes support
+		{ src: 'plugin/speakernotes/client.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+		{ src: '/socket.io/socket.io.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+	]
+});
+```
+
+You can add your own extensions using the same syntax. The following properties are available for each dependency object:
+- **src**: Path to the script to load
+- **async**: [optional] Flags if the script should load after reveal.js has started, defaults to false
+- **callback**: [optional] Function to execute when the script has loaded
+- **condition**: [optional] Function which must return true for the script to be loaded
+
+
+### API
+
+The Reveal class provides a minimal JavaScript API for controlling navigation and reading state:
+
+```javascript
+// Navigation
+Reveal.navigateTo( indexh, indexv );
+Reveal.navigateLeft();
+Reveal.navigateRight();
+Reveal.navigateUp();
+Reveal.navigateDown();
+Reveal.navigatePrev();
+Reveal.navigateNext();
+Reveal.toggleOverview();
+
+// Retrieves the previous and current slide elements
+Reveal.getPreviousSlide();
+Reveal.getCurrentSlide();
+
+Reveal.getIndices(); // { h: 0, v: 0 } }
+```
+
+### States
+
+If you set ``data-state="somestate"`` on a slide ``<section>``, "somestate" will be applied as a class on the document element when that slide is opened. This allows you to apply broad style changes to the page based on the active slide.
+
+Furthermore you can also listen to these changes in state via JavaScript:
+
+```javascript
+Reveal.addEventListener( 'somestate', function() {
+	// TODO: Sprinkle magic
+}, false );
+```
+
+### Slide change event
+
+An 'slidechanged' event is fired each time the slide is changed (regardless of state). The event object holds the index values of the current slide as well as a reference to the previous and current slide HTML nodes.
+
+```javascript
+Reveal.addEventListener( 'slidechanged', function( event ) {
+	// event.previousSlide, event.currentSlide, event.indexh, event.indexv
+} );
+```
+
+### Fragment events
+
+When a slide fragment is either shown or hidden reveal.js will dispatch an event.
+
+```javascript
+Reveal.addEventListener( 'fragmentshown', function( event ) {
+	// event.fragment = the fragment DOM element
+} );
+Reveal.addEventListener( 'fragmenthidden', function( event ) {
+	// event.fragment = the fragment DOM element
+} );
+```
+
+### Internal links
+
+It's easy to link between slides. The first example below targets the index of another slide whereas the second targets a slide with an ID attribute (```<section id="some-slide">```):
+
+```html
+<a href="#/2/2">Link</a>
+<a href="#/some-slide">Link</a>
+```
+
+## PDF Export
+
+Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome). 
+Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-13872948.
+
+1. Open the desired presentation with *print-pdf* anywhere in the query, for example: [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf)
+2. Open the in-browser print dialog (CMD+P).
+3. Change the **Destination** setting to **Save as PDF**.
+4. Change the **Layout** to **Landscape**.
+5. Change the **Margins** to **None**.
+6. Click **Save**.
+
+![Chrome Print Settings](https://s3.amazonaws.com/hakim-static/reveal-js/pdf-print-settings.png)
+
+## Speaker Notes
+
+If you're interested in using speaker notes, reveal.js comes with a Node server that allows you to deliver your presentation in one browser while viewing speaker notes in another. 
+
+To include speaker notes in your presentation, simply add an `<aside class="notes">` element to any slide. These notes will be hidden in the main presentation view.
+
+You'll also need to [install Node.js](http://nodejs.org/); then, install the server dependencies by running `npm install`.
+
+Once Node.js and the dependencies are installed, run the following command from the root directory:
+
+		node plugin/speakernotes
+
+By default, the slides will be served at [localhost:1947](http://localhost:1947).
+
+You can change the appearance of the speaker notes by editing the file at `plugin/speakernotes/notes.html`.	
+
+### Known Issues
+
+- The notes page is supposed to show the current slide and the next slide, but when it first starts, it always shows the first slide in both positions. 
+
+## Folder Structure
+- **css/** Core styles without which the project does not function
+- **js/** Like above but for JavaScript
+- **plugin/** Components that have been developed as extensions to reveal.js
+- **lib/** All other third party assets (JavaScript, CSS, fonts)
+
+## License
+
+MIT licensed
+
+Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
diff --git a/docs/slides/plpv14/_support/reveal/css/liquidhaskell.css b/docs/slides/plpv14/_support/reveal/css/liquidhaskell.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/liquidhaskell.css
@@ -0,0 +1,105 @@
+
+/******************************************************************/
+/* LIQUID: Hacking the Background *********************************/
+/******************************************************************/
+
+.hidden {
+  display: none;
+}
+
+.reveal .hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+  font-size:70%
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   
+}
+
+.hs-definition { 
+  color: #06287E 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext {display: none}
+
+a.annot:hover span.annottext { 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  font-size: 75%;
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+  color:black;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 100%;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/plpv14/_support/reveal/css/main.css b/docs/slides/plpv14/_support/reveal/css/main.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/main.css
@@ -0,0 +1,925 @@
+@charset "UTF-8";
+
+/**
+ * reveal.js
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+.reveal a {
+  color: #8b7c69;
+  text-decoration: none;
+}
+
+/*********************************************
+ * RESET STYLES
+ *********************************************/
+
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed, 
+figure, figcaption, footer, header, hgroup, 
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font-size: 100%;
+	font: inherit;
+	vertical-align: baseline;
+}
+
+article, aside, details, figcaption, figure, 
+footer, header, hgroup, menu, nav, section {
+	display: block;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+html, 
+body {
+	padding: 0;
+	margin: 0;
+	width: 100%;
+	height: 100%;
+	min-height: 600px;
+	overflow: hidden;
+}
+
+body {
+	position: relative;
+	line-height: 1;
+}
+
+@media screen and (max-width: 1024px) {
+	body {
+		font-size: 30px;
+	}
+}
+
+::selection { 
+	background:#FF5E99; 
+	color:#fff; 
+	text-shadow: none; 
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1 { font-size: 0.77em; }
+.reveal h2 { font-size: 2.11em;	}
+.reveal h3 { font-size: 1.55em;	}
+.reveal h4 { font-size: 1em;	}
+
+
+/*********************************************
+ * VIEW FRAGMENTS
+ *********************************************/
+
+.reveal .slides section .fragment {
+	opacity: 0;
+
+	-webkit-transition: all .2s ease;
+	   -moz-transition: all .2s ease;
+	    -ms-transition: all .2s ease;
+	     -o-transition: all .2s ease;
+	        transition: all .2s ease;
+}
+	.reveal .slides section .fragment.visible {
+		opacity: 1;
+	}
+
+
+/*********************************************
+ * DEFAULT ELEMENT STYLES
+ *********************************************/
+
+.reveal .slides section {
+	line-height: 1.2em;
+	font-weight: normal;
+}
+
+.reveal img {
+	/* preserve aspect ratio and scale image so it's bound within the section */
+	max-width: 100%;
+	max-height: 100%;
+} 
+
+.reveal strong, 
+.reveal b {
+	font-weight: bold;
+}
+
+.reveal em, 
+.reveal i {
+	font-style: italic;
+}
+
+.reveal ol, 
+.reveal ul {
+	display: inline-block;
+
+	text-align: left;
+	margin: 0 0 0 .7em;
+}
+
+.reveal ol {
+	list-style-type: decimal;
+}
+
+.reveal ul {
+	list-style-type: disc;
+	padding-bottom: 0.8em;
+}
+
+.reveal ul ul {
+	list-style-type: circle;
+}
+
+.reveal ul ul ul {
+	list-style-type: square;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+	display: block;
+	margin-left: 0;
+}
+
+.reveal p {
+	margin-bottom: 10px;
+	line-height: 1.2em;
+}
+
+.reveal q,
+.reveal blockquote {
+	quotes: none;
+}
+
+
+.reveal blockquote {
+	display: block;
+	position: relative;
+	width: 70%;
+	margin: 5px auto;
+	padding: 5px;
+	
+	font-size: 80%;
+	font-style: italic;
+	background: rgba(255, 255, 255, 0.05);
+	box-shadow: 0px 0px 2px rgba(0,0,0,0.2);
+}
+
+
+
+/*--DW-- disable funky quote marks for blockquotes*/
+/*
+.reveal blockquote:before {
+	content: '“';
+}
+.reveal blockquote:after {
+	content: '”';
+}
+*/
+
+.reveal q {	
+	font-style: italic;
+}
+	.reveal q:before {
+		content: '“';
+	}
+	.reveal q:after {
+		content: '”';
+	}
+
+.reveal pre {
+	display: block;
+	position: relative;
+	width: 90%;
+	margin: 10px auto;
+
+	text-align: left;
+	font-size: 0.85em;
+	font-family: monospace;
+	line-height: 1.2em;
+
+	word-wrap: break-word;
+
+	box-shadow: 0px 0px 6px rgba(0,0,0,0.3);
+}
+
+.reveal code {
+	font-family: monospace;
+	overflow-x: auto;
+}
+
+.reveal table th, 
+.reveal table td {
+	text-align: left;
+	padding-right: .3em;
+}
+
+.reveal table th {
+	text-shadow: rgb(255,255,255) 1px 1px 2px;
+}
+
+.reveal sup { 
+	vertical-align: super;
+}
+.reveal sub { 
+	vertical-align: sub;
+}
+
+.reveal small {
+	display: inline-block;
+	font-size: 0.6em;
+	line-height: 1.2em;
+	vertical-align: top;
+}
+
+.reveal small * {
+	vertical-align: top;
+}
+
+
+/*********************************************
+ * CONTROLS
+ *********************************************/
+
+.reveal .controls {
+	display: none;
+	position: fixed;
+	width: 100px;
+	height: 100px;
+	z-index: 30;
+
+	right: 0;
+	bottom: 0;
+}
+	
+	.reveal .controls a {
+		font-family: Arial;
+		font-size: 0.83em;
+		position: absolute;
+		opacity: 0.1;
+	}
+		.reveal .controls a.enabled {
+			opacity: 0.6;
+		}
+		.reveal .controls a.enabled:active {
+			margin-top: 1px;
+		}
+
+	.reveal .controls .left {
+		top: 30px;
+	}
+
+	.reveal .controls .right {
+		left: 60px;
+		top: 30px;
+	}
+
+	.reveal .controls .up {
+		left: 30px;
+	}
+
+	.reveal .controls .down {
+		left: 30px;
+		top: 60px;
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	position: fixed;
+	display: none;
+	height: 3px;
+	width: 100%;
+	bottom: 0;
+	left: 0;
+}
+	
+	.reveal .progress span {
+		display: block;
+		height: 100%;
+		width: 0px;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+/*********************************************
+ * ROLLING LINKS
+ *********************************************/
+
+.reveal .roll {
+	display: inline-block;
+	line-height: 1.2;
+	overflow: hidden;
+
+	vertical-align: top;
+
+	-webkit-perspective: 400px;
+	   -moz-perspective: 400px;
+	    -ms-perspective: 400px;
+	        perspective: 400px;
+
+	-webkit-perspective-origin: 50% 50%;
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+	.reveal .roll:hover {
+		background: none;
+		text-shadow: none;
+	}
+.reveal .roll span {
+	display: block;
+	position: relative;
+	padding: 0 2px;
+
+	pointer-events: none;
+
+	-webkit-transition: all 400ms ease;
+	   -moz-transition: all 400ms ease;
+	    -ms-transition: all 400ms ease;
+	        transition: all 400ms ease;
+
+	-webkit-transform-origin: 50% 0%;
+	   -moz-transform-origin: 50% 0%;
+	    -ms-transform-origin: 50% 0%;
+	        transform-origin: 50% 0%;
+
+	-webkit-transform-style: preserve-3d;
+	   -moz-transform-style: preserve-3d;
+	    -ms-transform-style: preserve-3d;
+	        transform-style: preserve-3d;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	        backface-visibility: hidden;
+}
+	.reveal .roll:hover span {
+	    background: rgba(0,0,0,0.5);
+
+	    -webkit-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	       -moz-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	        -ms-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	            transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg );
+	}
+.reveal .roll span:after {
+	content: attr(data-title);
+
+	display: block;
+	position: absolute;
+	left: 0;
+	top: 0;
+	padding: 0 2px;
+
+	-webkit-transform-origin: 50% 0%;
+	   -moz-transform-origin: 50% 0%;
+	    -ms-transform-origin: 50% 0%;
+	        transform-origin: 50% 0%;
+
+	-webkit-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	   -moz-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	    -ms-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+	        transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg );
+}
+
+
+/*********************************************
+ * SLIDES
+ *********************************************/
+
+.reveal .slides {
+	position: absolute;
+	max-width: 1024px;
+	width: 100%;
+	height: 80%;
+	left: 50%;
+	top: 50%;
+	margin-top: -320px;
+	padding: 20px 0px;
+	overflow: visible;
+	
+	text-align: center;
+
+	-webkit-transition: -webkit-perspective .4s ease;
+	   -moz-transition: -moz-perspective .4s ease;
+	    -ms-transition: -ms-perspective .4s ease;
+	     -o-transition: -o-perspective .4s ease;
+	        transition: perspective .4s ease;
+	
+	-webkit-perspective: 600px;
+	   -moz-perspective: 600px;
+	    -ms-perspective: 600px;
+	        perspective: 600px;
+
+	-webkit-perspective-origin: 0% 25%;
+	   -moz-perspective-origin: 0% 25%;
+	    -ms-perspective-origin: 0% 25%;
+	        perspective-origin: 0% 25%;
+}
+
+.reveal .slides>section,
+.reveal .slides>section>section {
+	display: none;
+	position: absolute;
+	width: 100%;
+	min-height: 600px;
+
+	z-index: 10;
+	
+	-webkit-transform-style: preserve-3d;
+	   -moz-transform-style: preserve-3d;
+	    -ms-transform-style: preserve-3d;
+	        transform-style: preserve-3d;
+	
+	-webkit-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	   -moz-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	    -ms-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	     -o-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	        transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+}
+
+.reveal .slides>section.present {
+	display: block;
+	z-index: 11;
+	opacity: 1;
+}
+
+.reveal .slides>section {
+	margin-left: -50%;
+}
+
+
+/*********************************************
+ * DEFAULT TRANSITION
+ *********************************************/
+
+.reveal .slides>section.past {
+	display: block;
+	opacity: 0;
+	
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
+}
+.reveal .slides>section.future {
+	display: block;
+	opacity: 0;
+	
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
+}
+
+.reveal .slides>section>section.past {
+	display: block;
+	opacity: 0;
+	
+	-webkit-transform: translate3d(0, -50%, 0) rotateX(70deg) translate3d(0, -50%, 0);
+	   -moz-transform: translate3d(0, -50%, 0) rotateX(70deg) translate3d(0, -50%, 0);
+	    -ms-transform: translate3d(0, -50%, 0) rotateX(70deg) translate3d(0, -50%, 0);
+	        transform: translate3d(0, -50%, 0) rotateX(70deg) translate3d(0, -50%, 0);
+}
+.reveal .slides>section>section.future {
+	display: block;
+	opacity: 0;
+	
+	-webkit-transform: translate3d(0, 50%, 0) rotateX(-70deg) translate3d(0, 50%, 0);
+	   -moz-transform: translate3d(0, 50%, 0) rotateX(-70deg) translate3d(0, 50%, 0);
+	    -ms-transform: translate3d(0, 50%, 0) rotateX(-70deg) translate3d(0, 50%, 0);
+	        transform: translate3d(0, 50%, 0) rotateX(-70deg) translate3d(0, 50%, 0);
+}
+
+
+/*********************************************
+ * CONCAVE TRANSITION
+ *********************************************/
+
+.reveal.concave  .slides>section.past {
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+	        transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
+}
+.reveal.concave  .slides>section.future {
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+	        transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
+}
+
+.reveal.concave  .slides>section>section.past {
+	-webkit-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	   -moz-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	    -ms-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+	        transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0);
+}
+.reveal.concave  .slides>section>section.future {
+	-webkit-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	   -moz-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	    -ms-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+	        transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0);
+}
+
+
+/*********************************************
+ * LINEAR TRANSITION
+ *********************************************/
+
+.reveal.linear .slides>section.past {
+	-webkit-transform: translate(-150%, 0);
+	   -moz-transform: translate(-150%, 0);
+	    -ms-transform: translate(-150%, 0);
+	     -o-transform: translate(-150%, 0);
+	        transform: translate(-150%, 0);
+}
+.reveal.linear .slides>section.future {
+	-webkit-transform: translate(150%, 0);
+	   -moz-transform: translate(150%, 0);
+	    -ms-transform: translate(150%, 0);
+	     -o-transform: translate(150%, 0);
+	        transform: translate(150%, 0);
+}
+
+.reveal.linear .slides>section>section.past {
+	-webkit-transform: translate(0, -150%);
+	   -moz-transform: translate(0, -150%);
+	    -ms-transform: translate(0, -150%);
+	     -o-transform: translate(0, -150%);
+	        transform: translate(0, -150%);
+}
+.reveal.linear .slides>section>section.future {
+	-webkit-transform: translate(0, 150%);
+	   -moz-transform: translate(0, 150%);
+	    -ms-transform: translate(0, 150%);
+	     -o-transform: translate(0, 150%);
+	        transform: translate(0, 150%);
+}
+
+/*********************************************
+ * BOX TRANSITION
+ *********************************************/
+
+.reveal.cube .slides {
+	margin-top: -350px;
+
+	-webkit-perspective-origin: 50% 25%;
+	   -moz-perspective-origin: 50% 25%;
+	    -ms-perspective-origin: 50% 25%;
+	        perspective-origin: 50% 25%;
+
+	-webkit-perspective: 1300px;
+	   -moz-perspective: 1300px;
+	    -ms-perspective: 1300px;
+	        perspective: 1300px;
+}
+
+.reveal.cube .slides section {
+	padding: 30px;
+
+	-webkit-backface-visibility: hidden;
+	   -moz-backface-visibility: hidden;
+	    -ms-backface-visibility: hidden;
+	        backface-visibility: hidden;
+	
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+	.reveal.cube .slides section:not(.stack):before {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+		background: #232628;
+		border-radius: 4px;
+
+		-webkit-transform: translateZ( -20px );
+		   -moz-transform: translateZ( -20px );
+		    -ms-transform: translateZ( -20px );
+		     -o-transform: translateZ( -20px );
+		        transform: translateZ( -20px );
+	}
+	.reveal.cube .slides section:not(.stack):after {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 90%;
+		height: 30px;
+		left: 5%;
+		bottom: 0;
+		background: none;
+		z-index: 1;
+
+		border-radius: 4px;
+		box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ(-90px) rotateX( 65deg );
+		   -moz-transform: translateZ(-90px) rotateX( 65deg );
+		    -ms-transform: translateZ(-90px) rotateX( 65deg );
+		     -o-transform: translateZ(-90px) rotateX( 65deg );
+		        transform: translateZ(-90px) rotateX( 65deg );
+	}
+
+.reveal.cube .slides>section.stack {
+	padding: 0;
+	background: none;
+}
+
+.reveal.cube .slides>section.past {
+	-webkit-transform-origin: 100% 0%;
+	   -moz-transform-origin: 100% 0%;
+	    -ms-transform-origin: 100% 0%;
+	        transform-origin: 100% 0%;
+
+	-webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	   -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	    -ms-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+	        transform: translate3d(-100%, 0, 0) rotateY(-90deg);
+}
+
+.reveal.cube .slides>section.future {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	   -moz-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	    -ms-transform: translate3d(100%, 0, 0) rotateY(90deg);
+	        transform: translate3d(100%, 0, 0) rotateY(90deg);
+}
+
+.reveal.cube .slides>section>section.past {
+	-webkit-transform-origin: 0% 100%;
+	   -moz-transform-origin: 0% 100%;
+	    -ms-transform-origin: 0% 100%;
+	        transform-origin: 0% 100%;
+
+	-webkit-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	   -moz-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	    -ms-transform: translate3d(0, -100%, 0) rotateX(90deg);
+	        transform: translate3d(0, -100%, 0) rotateX(90deg);
+}
+
+.reveal.cube .slides>section>section.future {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	   -moz-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	    -ms-transform: translate3d(0, 100%, 0) rotateX(-90deg);
+	        transform: translate3d(0, 100%, 0) rotateX(-90deg);
+}
+
+
+/*********************************************
+ * PAGE TRANSITION
+ *********************************************/
+
+.reveal.page .slides {
+	margin-top: -350px;
+
+	-webkit-perspective-origin: 50% 50%;
+ 	   -moz-perspective-origin: 50% 50%;
+ 	    -ms-perspective-origin: 50% 50%;
+ 	        perspective-origin: 50% 50%;
+
+	-webkit-perspective: 3000px;
+	   -moz-perspective: 3000px;
+	    -ms-perspective: 3000px;
+	        perspective: 3000px;
+}
+
+.reveal.page .slides section {
+	padding: 30px;
+
+	-webkit-box-sizing: border-box;
+	   -moz-box-sizing: border-box;
+	        box-sizing: border-box;
+}
+	.reveal.page .slides section.past {
+		z-index: 12;
+	}
+	.reveal.page .slides section:not(.stack):before {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+		background: rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ( -20px );
+		   -moz-transform: translateZ( -20px );
+		    -ms-transform: translateZ( -20px );
+		     -o-transform: translateZ( -20px );
+		        transform: translateZ( -20px );
+	}
+	.reveal.page .slides section:not(.stack):after {
+		content: '';
+		position: absolute;
+		display: block;
+		width: 90%;
+		height: 30px;
+		left: 5%;
+		bottom: 0;
+		background: none;
+		z-index: 1;
+
+		border-radius: 4px;
+		box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
+
+		-webkit-transform: translateZ(-90px) rotateX( 65deg );
+	}
+
+.reveal.page .slides>section.stack {
+	padding: 0;
+	background: none;
+}
+
+.reveal.page .slides>section.past {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	   -moz-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	    -ms-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+	        transform: translate3d(-40%, 0, 0) rotateY(-80deg);
+}
+
+.reveal.page .slides>section.future {
+	-webkit-transform-origin: 100% 0%;
+	   -moz-transform-origin: 100% 0%;
+	    -ms-transform-origin: 100% 0%;
+	        transform-origin: 100% 0%;
+
+	-webkit-transform: translate3d(0, 0, 0);
+	   -moz-transform: translate3d(0, 0, 0);
+	    -ms-transform: translate3d(0, 0, 0);
+	        transform: translate3d(0, 0, 0);
+}
+
+.reveal.page .slides>section>section.past {
+	-webkit-transform-origin: 0% 0%;
+	   -moz-transform-origin: 0% 0%;
+	    -ms-transform-origin: 0% 0%;
+	        transform-origin: 0% 0%;
+
+	-webkit-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	   -moz-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	    -ms-transform: translate3d(0, -40%, 0) rotateX(80deg);
+	        transform: translate3d(0, -40%, 0) rotateX(80deg);
+}
+
+.reveal.page .slides>section>section.future {
+	-webkit-transform-origin: 0% 100%;
+	   -moz-transform-origin: 0% 100%;
+	    -ms-transform-origin: 0% 100%;
+	        transform-origin: 0% 100%;
+
+	-webkit-transform: translate3d(0, 0, 0);
+	   -moz-transform: translate3d(0, 0, 0);
+	    -ms-transform: translate3d(0, 0, 0);
+	        transform: translate3d(0, 0, 0);
+}
+
+
+/*********************************************
+ * OVERVIEW
+ *********************************************/
+
+.reveal.overview .slides {
+	-webkit-perspective: 700px;
+	   -moz-perspective: 700px;
+	    -ms-perspective: 700px;
+	        perspective: 700px;
+}
+
+.reveal.overview .slides section {
+	padding: 20px 0;
+	max-height: 600px;
+	overflow: hidden;	
+	opacity: 1;
+	cursor: pointer;
+	background: rgba(0,0,0,0.1);
+}
+.reveal.overview .slides section .fragment {
+	opacity: 1;
+}
+.reveal.overview .slides section:after,
+.reveal.overview .slides section:before {
+	display: none !important;
+}
+.reveal.overview .slides section>section {
+	opacity: 1;
+	cursor: pointer;
+}
+	.reveal.overview .slides section:hover {
+		background: rgba(0,0,0,0.3);
+	}
+
+	.reveal.overview .slides section.present {
+		background: rgba(0,0,0,0.3);
+	}
+.reveal.overview .slides>section.stack {
+	background: none;
+	padding: 0;
+	overflow: visible;
+}
+
+
+/*********************************************
+ * FALLBACK
+ *********************************************/
+
+.no-transforms {
+	overflow-y: auto;
+}
+
+.no-transforms .slides section {
+	display: block!important;
+	opacity: 1!important;
+	position: relative!important;
+	height: auto;
+	min-height: auto;
+	margin-bottom: 100px;
+
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	        transform: none;
+}
+
+
+/*********************************************
+ * DEFAULT STATES
+ *********************************************/
+
+.state-background {
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	background: rgba( 0, 0, 0, 0 );
+
+	-webkit-transition: background 800ms ease;
+	   -moz-transition: background 800ms ease;
+	    -ms-transition: background 800ms ease;
+	     -o-transition: background 800ms ease;
+	        transition: background 800ms ease;
+}
+.alert .state-background {
+	background: rgba( 200, 50, 30, 0.6 );
+}
+.soothe .state-background {
+	background: rgba( 50, 200, 90, 0.4 );
+}
+.blackout .state-background {
+	background: rgba( 0, 0, 0, 0.6 );
+}
+
+
+/*********************************************
+ * SPEAKER NOTES
+ *********************************************/
+
+.reveal aside.notes {
+	display: none;
+}
+
diff --git a/docs/slides/plpv14/_support/reveal/css/print/paper.css b/docs/slides/plpv14/_support/reveal/css/print/paper.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/print/paper.css
@@ -0,0 +1,170 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and 
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending 
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+body {
+	background: #fff;
+	font-size: 13pt;
+	width: auto;
+	height: auto;
+	border: 0;
+	margin: 0 5%;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+}
+html {
+	background: #fff;
+	width: auto;
+	height: auto;
+	overflow: visible;
+}
+
+/* SECTION 2: Remove any elements not needed in print. 
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow, 
+.controls a, 
+.reveal .progress, 
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display:none;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div, a {
+	font-size: 13pt;
+	font-family: Georgia, "Times New Roman", Times, serif !important;
+	color: #000; 
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Diffrentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	color: #000!important;
+	height: auto;
+	line-height: normal;
+	font-family: Georgia, "Times New Roman", Times, serif !important;
+	text-shadow: 0 0 0 #000 !important;
+	text-align: left;
+	letter-spacing: normal;
+}
+/* Need to reduce the size of the fonts for printing */
+h1 { font-size: 26pt !important;  }
+h2 { font-size: 22pt !important; }
+h3 { font-size: 20pt !important; }
+h4 { font-size: 20pt !important; font-variant: small-caps; }
+h5 { font-size: 19pt !important; }
+h6 { font-size: 18pt !important; font-style: italic; }
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link, 
+a:visited {
+	color: #000 !important;
+	font-weight: bold;
+	text-decoration: underline;
+}
+.reveal a:link:after, 
+.reveal a:visited:after {
+	content: " (" attr(href) ") ";
+	color: #222 !important;
+	font-size: 90%;
+}
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+	text-align: left !important;
+}
+.reveal .slides {
+	position: static;
+	width: auto;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin-left: auto;
+	margin-top: auto;
+	padding: auto;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides>section, .reveal .slides>section>section, 
+.reveal .slides>section.past, .reveal .slides>section.future,
+.reveal.linear .slides>section, .reveal.linear .slides>section>section,
+.reveal.linear .slides>section.past, .reveal.linear .slides>section.future {
+	
+	visibility: visible;
+	position: static;
+	width: 90%;
+	height: auto;
+	display: block;
+	overflow: visible;
+
+	left: 0%;
+	top: 0%;
+	margin-left: 0px;
+	margin-top: 0px;
+	padding: 20px 0px;
+
+	opacity: 1;
+
+	-webkit-transform-style: flat;
+	   -moz-transform-style: flat;
+	    -ms-transform-style: flat;
+	        transform-style: flat;
+
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	        transform: none;
+}
+.reveal section {
+	page-break-after: always !important; 
+	display: block !important;
+}
+.reveal section.stack {
+	page-break-after: avoid !important; 
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+}
+.reveal section img {
+	display: block;
+	margin: 15px 0px;
+	background: rgba(255,255,255,1);
+	border: 1px solid #666;
+	box-shadow: none;
+}
diff --git a/docs/slides/plpv14/_support/reveal/css/print/pdf.css b/docs/slides/plpv14/_support/reveal/css/print/pdf.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/print/pdf.css
@@ -0,0 +1,158 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and 
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending 
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+* {
+	-webkit-print-color-adjust: exact; 
+}
+
+body {
+	font-size: 22pt;
+	width: auto;
+	height: auto;
+	border: 0;
+	margin: 0 5%;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+	background: #333;
+}
+
+html {
+	width: auto;
+	height: auto;
+	overflow: visible;
+}
+
+/* SECTION 2: Remove any elements not needed in print. 
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow, 
+.controls a, 
+.reveal .progress, 
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display:none;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div, a {
+	font-size: 22pt;
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Diffrentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	text-shadow: 0 0 0 #000 !important;
+}
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link, 
+a:visited {
+	font-weight: bold;
+	text-decoration: underline;
+}
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+}
+.reveal .slides {
+	position: static;
+	width: 100%;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin-left: auto;
+	margin-top: auto;
+	padding: auto;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides>section, .reveal .slides>section>section, 
+.reveal .slides>section.past, .reveal .slides>section.future,
+.reveal.linear .slides>section, .reveal.linear .slides>section>section,
+.reveal.linear .slides>section.past, .reveal.linear .slides>section.future {
+	
+	visibility: visible;
+	position: static;
+	width: 100%;
+	height: auto;
+	min-height: initial;
+	display: block;
+	overflow: visible;
+
+	left: 0%;
+	top: 0%;
+	margin-left: 0px;
+	margin-top: 50px;
+	padding: 20px 0px;
+
+	opacity: 1;
+
+	-webkit-transform-style: flat;
+	   -moz-transform-style: flat;
+	    -ms-transform-style: flat;
+	        transform-style: flat;
+
+	-webkit-transform: none;
+	   -moz-transform: none;
+	    -ms-transform: none;
+	        transform: none;
+}
+.reveal section {
+	page-break-after: always !important; 
+	display: block !important;
+}
+.reveal section.stack {
+	margin: 0px !important;
+	padding: 0px !important;
+	page-break-after: avoid !important; 
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+}
+.reveal img {
+	box-shadow: none;
+}
+.reveal .roll {
+	overflow: visible;
+	line-height: 1em;
+}
+
+.reveal small a {
+	font-size: 16pt !important;
+}
diff --git a/docs/slides/plpv14/_support/reveal/css/theme/beige.css b/docs/slides/plpv14/_support/reveal/css/theme/beige.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/theme/beige.css
@@ -0,0 +1,179 @@
+/**
+ * A beige theme for reveal.js presentations, similar 
+ * to the default theme.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'Lato', Times, 'Times New Roman', serif;
+	font-size: 36px;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #333;
+
+	background: #f7f3de;
+	background: -moz-radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%, rgba(247,242,211,1) 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(247,242,211,1)));
+	background: -webkit-radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%,rgba(247,242,211,1) 100%);
+	background: -o-radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%,rgba(247,242,211,1) 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%,rgba(247,242,211,1) 100%);
+	background: radial-gradient(center, ellipse cover,  rgba(255,255,255,1) 0%,rgba(247,242,211,1) 100%);
+}
+
+::-moz-selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+::-webkit-selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+::selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2, 
+.reveal h3, 
+.reveal h4, 
+.reveal h5, 
+.reveal h6 {
+	margin: 0 0 20px 0;
+	color: #333;
+	font-family: 'League Gothic', Impact, sans-serif;
+	line-height: 0.9em;
+	letter-spacing: 0.02em;
+	
+	text-transform: uppercase;
+}
+
+.reveal h1 {
+	text-shadow: 	0 1px 0 #ccc,
+					0 2px 0 #c9c9c9,
+					0 3px 0 #bbb,
+					0 4px 0 #b9b9b9,
+					0 5px 0 #aaa,
+					0 6px 1px rgba(0,0,0,.1),
+					0 0 5px rgba(0,0,0,.1),
+					0 1px 3px rgba(0,0,0,.3),
+					0 3px 5px rgba(0,0,0,.2),
+					0 5px 10px rgba(0,0,0,.25),
+					0 20px 20px rgba(0,0,0,.15);
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: #8b743d;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		text-shadow: none;
+		border: none;
+		border-radius: 2px;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: #8b743d;
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 30px 0 0 0;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid #eee;
+	
+	-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: #8b743d;
+		
+		-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		color: #8b743d;
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: #8b743d;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/plpv14/_support/reveal/css/theme/default.css b/docs/slides/plpv14/_support/reveal/css/theme/default.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/theme/default.css
@@ -0,0 +1,223 @@
+/**
+ * The default theme for reveal.js presentations.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@font-face {
+		font-family: 'PTSansNarrow';
+        src: url('../../lib/font/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+@font-face {
+		font-family: 'OpenSans';
+        src: url('../../lib/font/OpenSans-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'Lato', Times, 'Times New Roman', serif;
+	font-size: 36;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #eee;
+
+	background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM1NTVhNWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMWMxZTIwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+	background-color: #2b2b2b;
+	background: -moz-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%, rgba(28,30,32,1) 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(85,90,95,1)), color-stop(100%,rgba(28,30,32,1)));
+	background: -webkit-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -o-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+}
+
+
+/*********************************************
+ * main.css OVERIDES
+ *********************************************/
+
+
+/* Undo globally centered text from main.css*/
+.reveal .slides {
+	text-align: left;
+}
+
+.reveal li {
+	padding-bottom: 0.7em;
+	line-height: 1em;
+}
+
+.reveal p + ul {
+	padding-left: 4%
+}
+
+
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2 {
+	margin: 0 0 20px 0;
+	color: #eee;
+	font-family: 'League Gothic', Impact, sans-serif;
+	line-height: 0.9em;
+	letter-spacing: 0.02em;
+	
+	text-align: center;
+	text-transform: uppercase;
+	text-shadow: 0px 1px 0px rgba(0,0,0,1);
+}
+
+.reveal h1 {
+	padding-top: 3%%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	color: rgba(255,255,255,0.5);
+}
+
+.reveal h2 {
+	font-family: 'PTSansNarrow';
+	font-size: 130%;
+}
+
+.reveal .titlepage h1,
+.reveal h1.topic {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: hsl(185, 85%, 50%);
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		color: hsl(185, 85%, 70%);
+		
+		text-shadow: none;
+		border: none;
+		border-radius: 2px;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: hsl(185, 60%, 35%);
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 30px 0 0 0;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid #eee;
+	
+	-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: #13DAEC;
+		
+		-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		color: hsl(185, 85%, 70%);
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: hsl(185, 85%, 50%);
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/plpv14/_support/reveal/css/theme/seminar.css b/docs/slides/plpv14/_support/reveal/css/theme/seminar.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/theme/seminar.css
@@ -0,0 +1,196 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb; }
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 40px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	// :color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.05em 0.05em 0.25em blue;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+/*
+.reveal a:not(.image) {
+  line-height: 1.3em; }
+
+
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c; }
+
+*/
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #51483d; }
diff --git a/docs/slides/plpv14/_support/reveal/css/theme/seminar.orig.css b/docs/slides/plpv14/_support/reveal/css/theme/seminar.orig.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/theme/seminar.orig.css
@@ -0,0 +1,301 @@
+/**
+ * The default theme for reveal.js presentations.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.ttf') format('truetype');
+	font-weight: normal;
+	font-style: normal;
+}
+
+@font-face {
+		font-family: 'PTSansNarrow';
+        src: url('../../lib/font/PT_Sans-Narrow-Web-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+@font-face {
+		font-family: 'OpenSans';
+        src: url('../../lib/font/OpenSans-Regular.ttf') format('truetype');
+        font-weight: normal;
+        font-style: normal;
+}
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'OpenSans', Times, 'Times New Roman', serif;
+	font-size: 36;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #eee;
+
+	background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM1NTVhNWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMWMxZTIwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+	background-color: #2b2b2b;
+	background: -moz-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%, rgba(28,30,32,1) 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(85,90,95,1)), color-stop(100%,rgba(28,30,32,1)));
+	background: -webkit-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -o-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+	background: radial-gradient(center, ellipse cover,  rgba(85,90,95,1) 0%,rgba(28,30,32,1) 100%);
+}
+
+
+/*********************************************
+ * main.css OVERIDES
+ *********************************************/
+
+
+/*--DW-- uncomment below to undo globally centered text from main.css*/
+
+/*.reveal .slides {
+	text-align: left;
+}
+
+.reveal li {
+	padding-bottom: 0.7em;
+	line-height: 1em;
+}
+.reveal ul ul {
+	padding-left: 8%;
+	padding-top: 0.7em;
+	font-size: 85%;
+}*/
+
+/*--DW--
+* override list width to make multiline list items
+* a bit more manageable
+*/
+.reveal ul {
+	max-width: 80%;
+}
+
+.reveal li {
+	padding-bottom: 0.3em;
+}
+
+/*--DW-- uncenter pararagraph blocks*/
+.reveal .slides p {
+	text-align: left
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2 {
+	margin: 0 0 20px 0;
+	color: #eee;
+	font-family: 'League Gothic', Impact, sans-serif;
+	line-height: 0.9em;
+	letter-spacing: 0.02em;
+	
+	text-align: center;
+	text-transform: uppercase;
+	text-shadow: 0px 1px 0px rgba(0,0,0,1);
+}
+
+.reveal h2 {
+	font-family: 'PTSansNarrow';
+	font-size: 130%;
+}
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+
+
+/*********************************************
+ * BLOCKQUOTES
+ *********************************************/
+
+/*--DW--*/
+.reveal blockquote
+{   background: rgba(255,255,255, .2);
+    font-size: 75%;
+    text-align: justify;
+    width: 70%;
+    padding: 0.5em 5% 0.2em;
+    margin: 0 10%;
+    border: 2px solid rgba(255, 255, 255, .1);
+    -webkit-box-shadow: .1em .1em .5em black inset;
+    -moz-box-shadow: .1em .1em .5em black inset;
+    box-shadow: .1em .1em .5em black inset;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: hsl(185, 85%, 50%);
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+.reveal a:not(.image):hover {
+	color: hsl(185, 85%, 70%);
+	
+	text-shadow: none;
+	border: none;
+	border-radius: 2px;
+}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: hsl(185, 60%, 35%);
+}
+
+
+/*********************************************
+ * IMAGES AND FIGURES
+ *********************************************/
+
+/*--DW-- added figures; changed img styling*/
+/*pandoc*/
+.reveal figure {
+	margin-left: auto;
+	margin-right: auto;
+}
+
+/*pandoc*/
+.reveal figcaption {
+	text-align: center;
+	font-size: 75%;
+	font-style: italic;
+}
+.reveal section img,
+.reveal section embed {
+/*	width: 80%;
+	height: 80%;
+*/	display: block;
+	margin-left: auto;
+	margin-right: auto;
+	padding: 15px;
+	background: rgba(255,255,255, .75);
+    border: 2px solid rgba(255, 255, 255, .1);
+    -webkit-box-shadow: .1em .1em .5em black inset;
+       -moz-box-shadow: .1em .1em .5em black inset;
+            box-shadow: .1em .1em .5em black inset;
+
+/*--DW-- original image box styling*/
+/*
+-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+
+-webkit-transition: all .2s linear;
+   -moz-transition: all .2s linear;
+    -ms-transition: all .2s linear;
+     -o-transition: all .2s linear;
+        transition: all .2s linear;
+*/
+}
+
+.reveal a:hover img {
+	background: rgba(255,255,255,0.2);
+	border-color: #13DAEC;
+	
+	-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		/*color: hsl(185, 85%, 70%);*/
+		color: rgba(138, 201, 85, 0.60);
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		/*background: hsl(185, 85%, 50%);*/
+		background: rgba(138, 201, 85, 0.60);
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/plpv14/_support/reveal/css/theme/serif.css b/docs/slides/plpv14/_support/reveal/css/theme/serif.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/theme/serif.css
@@ -0,0 +1,190 @@
+/**
+ * A simple theme for reveal.js presentations, similar
+ * to the default theme. The accent color is brown.
+ *
+ * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
+ */
+.reveal a:not(.image) {
+  line-height: 1.3em; 
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb; }
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: normal;
+  letter-spacing: -0.02em;
+  color: black; }
+
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 40px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none; }
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+
+
+
+/*pandoc*/
+.reveal .level1 h1 {
+	padding-top: 3%;
+	padding-bottom: 0.3em;
+	border-bottom: 1px solid #8e8e8e;
+	font-size: 100%;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h1 {
+	font-size: 3em;
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.05em 0.05em 0.25em blue;
+}
+
+/*pandoc*/
+.reveal .titlepage h2 {
+	font-size: 1em;
+	color: rgba(255,255,255,0.5);
+}
+
+/*pandoc*/
+.reveal .titlepage h3 {
+	font-size: 0.75em;
+	color: rgba(255,255,255,0.5);
+	text-align: center;
+}
+
+/*pandoc*/
+.reveal .topic h1 {
+	font-size: 2.11em;
+	color: rgba(255,255,255,0.9);
+	padding-top: 30%;
+	padding-bottom: 1em;
+	border: none;
+	text-shadow: 0.1em 0.1em 0.1em black;
+}
+
+/*pandoc*/
+.reveal .placeholder h1,
+.reveal .placeholder h2 {
+	border: none;
+}
+
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease; }
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none; }
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear; }
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d; }
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d; }
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d; }
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+  color: #51483d; }
diff --git a/docs/slides/plpv14/_support/reveal/css/theme/simple.css b/docs/slides/plpv14/_support/reveal/css/theme/simple.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/theme/simple.css
@@ -0,0 +1,150 @@
+/**
+ * A simple theme for reveal.js presentations, similar 
+ * to the default theme. The accent color is darkblue; 
+ * do a find-replace to change it.
+ * 
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se; so is the theme - beige.css - that this is based off of.
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@import url(http://fonts.googleapis.com/css?family=News+Cycle:400,700);
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'Lato', Times, 'Times New Roman', serif;
+	font-size: 36px;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: black !important;
+
+	background: white;
+}
+
+::-moz-selection {
+    background:rgba(0, 0, 0, 0.99);
+	color: white; 
+}
+::-webkit-selection {
+    background:rgba(0, 0, 0, 0.99);
+	color: white; 
+}
+::selection {
+    background:rgba(0, 0, 0, 0.99);
+	color: white; 
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2, 
+.reveal h3, 
+.reveal h4, 
+.reveal h5, 
+.reveal h6 {
+	margin: 0 0 20px 0;
+	color: black;
+	font-family: 'News Cycle', Impact, sans-serif;
+	line-height: 0.9em;
+	
+	text-transform: uppercase;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: darkblue;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		text-shadow: none;
+		border: none;
+		border-radius: 2px;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: darkblue;
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 30px 0 0 0;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid #eee;
+	
+	-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: darkblue;
+		
+		-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: black;
+}
+	.reveal .controls a.enabled {
+		color: darkblue;
+		opacity: 1;
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: darkblue;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/plpv14/_support/reveal/css/theme/sky.css b/docs/slides/plpv14/_support/reveal/css/theme/sky.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/css/theme/sky.css
@@ -0,0 +1,165 @@
+/**
+ * Sky theme for reveal.js presentations.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+/*********************************************
+ * FONT-FACE DEFINITIONS
+ *********************************************/
+
+@import url(http://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+
+
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	font-family: 'Open Sans', sans-serif;
+	font-size: 36px;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: #333;
+
+	background: #f7fbfc;
+	background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmN2ZiZmMiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjYWRkOWU0IiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+	background: -moz-radial-gradient(center, ellipse cover,  #f7fbfc 0%, #add9e4 100%);
+	background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#f7fbfc), color-stop(100%,#add9e4));
+	background: -webkit-radial-gradient(center, ellipse cover,  #f7fbfc 0%,#add9e4 100%);
+	background: -o-radial-gradient(center, ellipse cover,  #f7fbfc 0%,#add9e4 100%);
+	background: -ms-radial-gradient(center, ellipse cover,  #f7fbfc 0%,#add9e4 100%);
+	background: radial-gradient(ellipse at center,  #f7fbfc 0%,#add9e4 100%);
+}
+
+::-moz-selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+::-webkit-selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+::selection {
+	background:rgba(79, 64, 28, 0.99);
+	color: white; 
+}
+
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1, 
+.reveal h2, 
+.reveal h3, 
+.reveal h4, 
+.reveal h5, 
+.reveal h6 {
+	margin: 0 0 20px 0;
+	color: #333;
+	font-family: 'Quicksand', sans-serif;
+	line-height: 0.9em;
+	letter-spacing: -0.08em;
+	
+	text-transform: uppercase;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: #3b759e;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		text-shadow: none;
+		border: none;
+		border-radius: 2px;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: #3b759e;
+}
+
+
+/*********************************************
+ * MISC
+ *********************************************/
+
+.reveal section img {
+	margin: 30px 0 0 0;
+	background: rgba(255,255,255,0.12);
+	border: 1px solid #ddd;
+	
+	-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	   -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+	
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: #3b759e;
+		
+		-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		   -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+		        box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+.reveal blockquote {
+	background: rgba(255, 255, 255, 0.4);
+}
+
+.reveal p {
+	margin-bottom: 20px;
+}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls a {
+	color: #fff;
+}
+	.reveal .controls a.enabled {
+		color: #3b759e;
+		text-shadow: 0px 0px 2px hsla(185, 45%, 70%, 0.3);
+	}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: #3b759e;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+
diff --git a/docs/slides/plpv14/_support/reveal/js/.reveal.js.swo b/docs/slides/plpv14/_support/reveal/js/.reveal.js.swo
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/_support/reveal/js/.reveal.js.swo differ
diff --git a/docs/slides/plpv14/_support/reveal/js/.reveal.js.swp b/docs/slides/plpv14/_support/reveal/js/.reveal.js.swp
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/_support/reveal/js/.reveal.js.swp differ
diff --git a/docs/slides/plpv14/_support/reveal/js/.reveal.min.js.swo b/docs/slides/plpv14/_support/reveal/js/.reveal.min.js.swo
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/_support/reveal/js/.reveal.min.js.swo differ
diff --git a/docs/slides/plpv14/_support/reveal/js/.reveal.min.js.swp b/docs/slides/plpv14/_support/reveal/js/.reveal.min.js.swp
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/_support/reveal/js/.reveal.min.js.swp differ
diff --git a/docs/slides/plpv14/_support/reveal/js/reveal.js b/docs/slides/plpv14/_support/reveal/js/reveal.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/js/reveal.js
@@ -0,0 +1,1149 @@
+/*!
+ * reveal.js 2.0 r22
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var Reveal = (function(){
+	
+	var HORIZONTAL_SLIDES_SELECTOR = '.reveal .slides>section',
+		VERTICAL_SLIDES_SELECTOR = '.reveal .slides>section.present>section',
+
+		IS_TOUCH_DEVICE = !!( 'ontouchstart' in window ),
+
+		// Configurations defaults, can be overridden at initialization time 
+		config = {
+			// Display controls in the bottom right corner
+			controls: true,
+
+			// Display a presentation progress bar
+			progress: true,
+
+			// Push each slide change to the browser history
+			history: false,
+
+			// Enable keyboard shortcuts for navigation
+			keyboard: true,
+
+			// Loop the presentation
+			loop: false,
+
+			// Number of milliseconds between automatically proceeding to the 
+			// next slide, disabled when set to 0
+			autoSlide: 0,
+
+			// Enable slide navigation via mouse wheel
+			mouseWheel: true,
+
+			// Apply a 3D roll to links on hover
+			rollingLinks: true,
+
+			// Transition style (see /css/theme)
+			theme: 'default', 
+
+			// Transition style
+			transition: 'default', // default/cube/page/concave/linear(2d),
+
+			// Script dependencies to load
+			dependencies: []
+		},
+
+		// The horizontal and verical index of the currently active slide
+		indexh = 0,
+		indexv = 0,
+
+		// The previous and current slide HTML elements
+		previousSlide,
+		currentSlide,
+
+		// Slides may hold a data-state attribute which we pick up and apply 
+		// as a class to the body. This list contains the combined state of 
+		// all current slides.
+		state = [],
+
+		// Cached references to DOM elements
+		dom = {},
+
+		// Detect support for CSS 3D transforms
+		supports3DTransforms =  'WebkitPerspective' in document.body.style ||
+                        		'MozPerspective' in document.body.style ||
+                        		'msPerspective' in document.body.style ||
+                        		'OPerspective' in document.body.style ||
+                        		'perspective' in document.body.style,
+        
+        supports2DTransforms =  'WebkitTransform' in document.body.style ||
+                        		'MozTransform' in document.body.style ||
+                        		'msTransform' in document.body.style ||
+                        		'OTransform' in document.body.style ||
+                        		'transform' in document.body.style,
+		
+		// Throttles mouse wheel navigation
+		mouseWheelTimeout = 0,
+
+		// An interval used to automatically move on to the next slide
+		autoSlideTimeout = 0,
+
+		// Delays updates to the URL due to a Chrome thumbnailer bug
+		writeURLTimeout = 0,
+
+		// Holds information about the currently ongoing touch input
+		touch = {
+			startX: 0,
+			startY: 0,
+			startSpan: 0,
+			startCount: 0,
+			handled: false,
+			threshold: 40
+		};
+	
+	
+	/**
+	 * Starts up the presentation if the client is capable.
+	 */
+	function initialize( options ) {
+		if( ( !supports2DTransforms && !supports3DTransforms ) ) {
+			document.body.setAttribute( 'class', 'no-transforms' );
+
+			// If the browser doesn't support core features we won't be 
+			// using JavaScript to control the presentation
+			return;
+		}
+
+		// Copy options over to our config object
+		extend( config, options );
+
+		// Cache references to DOM elements
+		dom.theme = document.querySelector( '#theme' );
+		dom.wrapper = document.querySelector( '.reveal' );
+		dom.progress = document.querySelector( '.reveal .progress' );
+		dom.progressbar = document.querySelector( '.reveal .progress span' );
+
+		if ( config.controls ) {
+			dom.controls = document.querySelector( '.reveal .controls' );
+			dom.controlsLeft = document.querySelector( '.reveal .controls .left' );
+			dom.controlsRight = document.querySelector( '.reveal .controls .right' );
+			dom.controlsUp = document.querySelector( '.reveal .controls .up' );
+			dom.controlsDown = document.querySelector( '.reveal .controls .down' );
+		}
+
+		// Loads the dependencies and continues to #start() once done
+		load();
+
+		// Set up hiding of the browser address bar
+		if( navigator.userAgent.match( /(iphone|ipod|android)/i ) ) {
+			// Give the page some scrollable overflow
+			document.documentElement.style.overflow = 'scroll';
+			document.body.style.height = '120%';
+
+			// Events that should trigger the address bar to hide
+			window.addEventListener( 'load', removeAddressBar, false );
+			window.addEventListener( 'orientationchange', removeAddressBar, false );
+		}
+		
+	}
+
+	/**
+	 * Loads the dependencies of reveal.js. Dependencies are 
+	 * defined via the configuration option 'dependencies' 
+	 * and will be loaded prior to starting/binding reveal.js. 
+	 * Some dependencies may have an 'async' flag, if so they 
+	 * will load after reveal.js has been started up.
+	 */
+	function load() {
+		var scripts = [],
+			scriptsAsync = [];
+
+		for( var i = 0, len = config.dependencies.length; i < len; i++ ) {
+			var s = config.dependencies[i];
+
+			// Load if there's no condition or the condition is truthy
+			if( !s.condition || s.condition() ) {
+				if( s.async ) {
+					scriptsAsync.push( s.src );
+				}
+				else {
+					scripts.push( s.src );
+				}
+
+				// Extension may contain callback functions
+				if( typeof s.callback === 'function' ) {
+					head.ready( s.src.match( /([\w\d_-]*)\.?[^\\\/]*$/i )[0], s.callback );
+				}
+			}
+		}
+
+		// Called once synchronous scritps finish loading
+		function proceed() {
+			// Load asynchronous scripts
+			head.js.apply( null, scriptsAsync );
+			
+			start();
+		}
+
+		if( scripts.length ) {
+			head.ready( proceed );
+
+			// Load synchronous scripts
+			head.js.apply( null, scripts );
+		}
+		else {
+			proceed();
+		}
+	}
+
+	/**
+	 * Starts up reveal.js by binding input events and navigating 
+	 * to the current URL deeplink if there is one.
+	 */
+	function start() {
+		// Subscribe to input
+		addEventListeners();
+
+		// Updates the presentation to match the current configuration values
+		configure();
+
+		// Read the initial hash
+		readURL();
+
+		// Start auto-sliding if it's enabled
+		cueAutoSlide();
+	}
+
+	/**
+	 * Applies the configuration settings from the config object.
+	 */
+	function configure() {
+		if( supports3DTransforms === false ) {
+			config.transition = 'linear';
+		}
+
+		if( config.controls && dom.controls ) {
+			dom.controls.style.display = 'block';
+		}
+
+		if( config.progress && dom.progress ) {
+			dom.progress.style.display = 'block';
+		}
+
+		// Load the theme in the config, if it's not already loaded
+		if( config.theme && dom.theme ) {
+			var themeURL = dom.theme.getAttribute( 'href' );
+			var themeFinder = /[^/]*?(?=\.css)/;
+			var themeName = themeURL.match(themeFinder)[0];
+			if(  config.theme !== themeName ) {
+				themeURL = themeURL.replace(themeFinder, config.theme);
+				dom.theme.setAttribute( 'href', themeURL );
+			}
+		}
+
+
+		if( config.transition !== 'default' ) {
+			dom.wrapper.classList.add( config.transition );
+		}
+
+		if( config.mouseWheel ) {
+			document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
+			document.addEventListener( 'mousewheel', onDocumentMouseScroll, false );
+		}
+
+		if( config.rollingLinks ) {
+			// Add some 3D magic to our anchors
+			linkify();
+		}
+	}
+
+	function addEventListeners() {
+		document.addEventListener( 'touchstart', onDocumentTouchStart, false );
+		document.addEventListener( 'touchmove', onDocumentTouchMove, false );
+		document.addEventListener( 'touchend', onDocumentTouchEnd, false );
+		window.addEventListener( 'hashchange', onWindowHashChange, false );
+
+		if( config.keyboard ) {
+			document.addEventListener( 'keydown', onDocumentKeyDown, false );
+		}
+
+		if ( config.controls && dom.controls ) {
+			dom.controlsLeft.addEventListener( 'click', preventAndForward( navigateLeft ), false );
+			dom.controlsRight.addEventListener( 'click', preventAndForward( navigateRight ), false );
+			dom.controlsUp.addEventListener( 'click', preventAndForward( navigateUp ), false );
+			dom.controlsDown.addEventListener( 'click', preventAndForward( navigateDown ), false );	
+		}
+	}
+
+	function removeEventListeners() {
+		document.removeEventListener( 'keydown', onDocumentKeyDown, false );
+		document.removeEventListener( 'touchstart', onDocumentTouchStart, false );
+		document.removeEventListener( 'touchmove', onDocumentTouchMove, false );
+		document.removeEventListener( 'touchend', onDocumentTouchEnd, false );
+		window.removeEventListener( 'hashchange', onWindowHashChange, false );
+		
+		if ( config.controls && dom.controls ) {
+			dom.controlsLeft.removeEventListener( 'click', preventAndForward( navigateLeft ), false );
+			dom.controlsRight.removeEventListener( 'click', preventAndForward( navigateRight ), false );
+			dom.controlsUp.removeEventListener( 'click', preventAndForward( navigateUp ), false );
+			dom.controlsDown.removeEventListener( 'click', preventAndForward( navigateDown ), false );
+		}
+	}
+
+	/**
+	 * Extend object a with the properties of object b. 
+	 * If there's a conflict, object b takes precedence.
+	 */
+	function extend( a, b ) {
+		for( var i in b ) {
+			a[ i ] = b[ i ];
+		}
+	}
+
+	/**
+	 * Measures the distance in pixels between point a
+	 * and point b. 
+	 * 
+	 * @param {Object} a point with x/y properties
+	 * @param {Object} b point with x/y properties
+	 */
+	function distanceBetween( a, b ) {
+		var dx = a.x - b.x,
+			dy = a.y - b.y;
+
+		return Math.sqrt( dx*dx + dy*dy );
+	}
+
+	/**
+	 * Prevents an events defaults behavior calls the 
+	 * specified delegate.
+	 * 
+	 * @param {Function} delegate The method to call 
+	 * after the wrapper has been executed
+	 */
+	function preventAndForward( delegate ) {
+		return function( event ) {
+			event.preventDefault();
+			delegate.call();
+		}
+	}
+
+	/**
+	 * Causes the address bar to hide on mobile devices, 
+	 * more vertical space ftw.
+	 */
+	function removeAddressBar() {
+		setTimeout( function() {
+			window.scrollTo( 0, 1 );
+		}, 0 );
+	}
+	
+	/**
+	 * Handler for the document level 'keydown' event.
+	 * 
+	 * @param {Object} event
+	 */
+	function onDocumentKeyDown( event ) {
+		// FFT: Use document.querySelector( ':focus' ) === null 
+		// instead of checking contentEditable?
+
+		// Disregard the event if the target is editable or a 
+		// modifier is present
+		if ( event.target.contentEditable != 'inherit' || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+				
+		var triggered = false;
+
+		switch( event.keyCode ) {
+			// p, page up
+			case 80: case 33: navigatePrev(); triggered = true; break; 
+			// n, page down
+			case 78: case 34: navigateNext(); triggered = true; break;
+			// h, left
+			case 72: case 37: navigateLeft(); triggered = true; break;
+			// l, right
+			case 76: case 39: navigateRight(); triggered = true; break;
+			// k, up
+			case 75: case 38: navigateUp(); triggered = true; break;
+			// j, down
+			case 74: case 40: navigateDown(); triggered = true; break;
+			// home
+			case 36: navigateTo( 0 ); triggered = true; break;
+			// end
+			case 35: navigateTo( Number.MAX_VALUE ); triggered = true; break;
+			// space
+			case 32: overviewIsActive() ? deactivateOverview() : navigateNext(); triggered = true; break;
+			// return
+			case 13: if( overviewIsActive() ) { deactivateOverview(); triggered = true; } break;
+		}
+
+		// If the input resulted in a triggered action we should prevent 
+		// the browsers default behavior
+		if( triggered ) {
+			event.preventDefault();
+		}
+		else if ( event.keyCode === 27 && supports3DTransforms ) {
+			toggleOverview();
+	
+			event.preventDefault();
+		}
+
+		// If auto-sliding is enabled we need to cue up 
+		// another timeout
+		cueAutoSlide();
+
+	}
+
+	/**
+	 * Handler for the document level 'touchstart' event,
+	 * enables support for swipe and pinch gestures.
+	 */
+	function onDocumentTouchStart( event ) {
+		touch.startX = event.touches[0].clientX;
+		touch.startY = event.touches[0].clientY;
+		touch.startCount = event.touches.length;
+
+		// If there's two touches we need to memorize the distance 
+		// between those two points to detect pinching
+		if( event.touches.length === 2 ) {
+			touch.startSpan = distanceBetween( {
+				x: event.touches[1].clientX,
+				y: event.touches[1].clientY
+			}, {
+				x: touch.startX,
+				y: touch.startY
+			} );
+		}
+	}
+	
+	/**
+	 * Handler for the document level 'touchmove' event.
+	 */
+	function onDocumentTouchMove( event ) {
+		// Each touch should only trigger one action
+		if( !touch.handled ) {
+			var currentX = event.touches[0].clientX;
+			var currentY = event.touches[0].clientY;
+
+			// If the touch started off with two points and still has 
+			// two active touches; test for the pinch gesture
+			if( event.touches.length === 2 && touch.startCount === 2 ) {
+
+				// The current distance in pixels between the two touch points
+				var currentSpan = distanceBetween( {
+					x: event.touches[1].clientX,
+					y: event.touches[1].clientY
+				}, {
+					x: touch.startX,
+					y: touch.startY
+				} );
+
+				// If the span is larger than the desire amount we've got 
+				// ourselves a pinch
+				if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
+					touch.handled = true;
+
+					if( currentSpan < touch.startSpan ) {
+						activateOverview();
+					}
+					else {
+						deactivateOverview();
+					}
+				}
+
+			}
+			// There was only one touch point, look for a swipe
+			else if( event.touches.length === 1 ) {
+				var deltaX = currentX - touch.startX,
+					deltaY = currentY - touch.startY;
+
+				if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					touch.handled = true;
+					navigateLeft();
+				} 
+				else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					touch.handled = true;
+					navigateRight();
+				} 
+				else if( deltaY > touch.threshold ) {
+					touch.handled = true;
+					navigateUp();
+				} 
+				else if( deltaY < -touch.threshold ) {
+					touch.handled = true;
+					navigateDown();
+				}
+			}
+
+			event.preventDefault();
+		}
+	}
+
+	/**
+	 * Handler for the document level 'touchend' event.
+	 */
+	function onDocumentTouchEnd( event ) {
+		touch.handled = false;
+	}
+
+	/**
+	 * Handles mouse wheel scrolling, throttled to avoid 
+	 * skipping multiple slides.
+	 */
+	function onDocumentMouseScroll( event ){
+		clearTimeout( mouseWheelTimeout );
+
+		mouseWheelTimeout = setTimeout( function() {
+			var delta = event.detail || -event.wheelDelta;
+			if( delta > 0 ) {
+				navigateNext();
+			}
+			else {
+				navigatePrev();
+			}
+		}, 100 );
+	}
+	
+	/**
+	 * Handler for the window level 'hashchange' event.
+	 * 
+	 * @param {Object} event
+	 */
+	function onWindowHashChange( event ) {
+		readURL();
+	}
+
+	/**
+	 * Wrap all links in 3D goodness.
+	 */
+	function linkify() {
+		if( supports3DTransforms && !( 'msPerspective' in document.body.style ) ) {
+        	var nodes = document.querySelectorAll( '.reveal .slides section a:not(.image)' );
+
+	        for( var i = 0, len = nodes.length; i < len; i++ ) {
+	            var node = nodes[i];
+	            
+	            if( node.textContent && !node.querySelector( 'img' ) && ( !node.className || !node.classList.contains( node, 'roll' ) ) ) {
+	                node.classList.add( 'roll' );
+	                node.innerHTML = '<span data-title="'+ node.text +'">' + node.innerHTML + '</span>';
+	            }
+	        };
+        }
+	}
+
+	/**
+	 * Displays the overview of slides (quick nav) by 
+	 * scaling down and arranging all slide elements.
+	 * 
+	 * Experimental feature, might be dropped if perf 
+	 * can't be improved.
+	 */
+	function activateOverview() {
+		
+		dom.wrapper.classList.add( 'overview' );
+
+		var horizontalSlides = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+
+		for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
+			var hslide = horizontalSlides[i],
+				htransform = 'translateZ(-2500px) translate(' + ( ( i - indexh ) * 105 ) + '%, 0%)';
+			
+			hslide.setAttribute( 'data-index-h', i );
+			hslide.style.display = 'block';
+			hslide.style.WebkitTransform = htransform;
+			hslide.style.MozTransform = htransform;
+			hslide.style.msTransform = htransform;
+			hslide.style.OTransform = htransform;
+			hslide.style.transform = htransform;
+		
+			if( !hslide.classList.contains( 'stack' ) ) {
+				// Navigate to this slide on click
+				hslide.addEventListener( 'click', onOverviewSlideClicked, true );
+			}
+	
+			var verticalSlides = Array.prototype.slice.call( hslide.querySelectorAll( 'section' ) );
+
+			for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
+				var vslide = verticalSlides[j],
+					vtransform = 'translate(0%, ' + ( ( j - ( i === indexh ? indexv : 0 ) ) * 105 ) + '%)';
+
+				vslide.setAttribute( 'data-index-h', i );
+				vslide.setAttribute( 'data-index-v', j );
+				vslide.style.display = 'block';
+				vslide.style.WebkitTransform = vtransform;
+				vslide.style.MozTransform = vtransform;
+				vslide.style.msTransform = vtransform;
+				vslide.style.OTransform = vtransform;
+				vslide.style.transform = vtransform;
+
+				// Navigate to this slide on click
+				vslide.addEventListener( 'click', onOverviewSlideClicked, true );
+			}
+			
+		}
+	}
+	
+	/**
+	 * Exits the slide overview and enters the currently
+	 * active slide.
+	 */
+	function deactivateOverview() {
+		dom.wrapper.classList.remove( 'overview' );
+
+		var slides = Array.prototype.slice.call( document.querySelectorAll( '.reveal .slides section' ) );
+
+		for( var i = 0, len = slides.length; i < len; i++ ) {
+			var element = slides[i];
+
+			// Resets all transforms to use the external styles
+			element.style.WebkitTransform = '';
+			element.style.MozTransform = '';
+			element.style.msTransform = '';
+			element.style.OTransform = '';
+			element.style.transform = '';
+
+			element.removeEventListener( 'click', onOverviewSlideClicked );
+		}
+
+		slide();
+	}
+
+	/**
+	 * Checks if the overview is currently active.
+	 * 
+	 * @return {Boolean} true if the overview is active,
+	 * false otherwise
+	 */
+	function overviewIsActive() {
+		return dom.wrapper.classList.contains( 'overview' );
+	}
+
+	/**
+	 * Invoked when a slide is and we're in the overview.
+	 */
+	function onOverviewSlideClicked( event ) {
+		// TODO There's a bug here where the event listeners are not 
+		// removed after deactivating the overview.
+		if( overviewIsActive() ) {
+			event.preventDefault();
+
+			deactivateOverview();
+
+			indexh = this.getAttribute( 'data-index-h' );
+			indexv = this.getAttribute( 'data-index-v' );
+
+			slide();
+		}
+	}
+
+	/**
+	 * Updates one dimension of slides by showing the slide
+	 * with the specified index.
+	 * 
+	 * @param {String} selector A CSS selector that will fetch
+	 * the group of slides we are working with
+	 * @param {Number} index The index of the slide that should be
+	 * shown
+	 * 
+	 * @return {Number} The index of the slide that is now shown,
+	 * might differ from the passed in index if it was out of 
+	 * bounds.
+	 */
+	function updateSlides( selector, index ) {
+		
+		// Select all slides and convert the NodeList result to
+		// an array
+		var slides = Array.prototype.slice.call( document.querySelectorAll( selector ) ),
+			slidesLength = slides.length;
+		
+		if( slidesLength ) {
+
+			// Should the index loop?
+			if( config.loop ) {
+				index %= slidesLength;
+
+				if( index < 0 ) {
+					index = slidesLength + index;
+				}
+			}
+			
+			// Enforce max and minimum index bounds
+			index = Math.max( Math.min( index, slidesLength - 1 ), 0 );
+			
+			for( var i = 0; i < slidesLength; i++ ) {
+				var slide = slides[i];
+
+				// Optimization; hide all slides that are three or more steps 
+				// away from the present slide
+				if( overviewIsActive() === false ) {
+					// The distance loops so that it measures 1 between the first
+					// and last slides
+					var distance = Math.abs( ( index - i ) % ( slidesLength - 3 ) ) || 0;
+
+					slide.style.display = distance > 3 ? 'none' : 'block';
+				}
+
+				slides[i].classList.remove( 'past' );
+				slides[i].classList.remove( 'present' );
+				slides[i].classList.remove( 'future' );
+
+				if( i < index ) {
+					// Any element previous to index is given the 'past' class
+					slides[i].classList.add( 'past' );
+				}
+				else if( i > index ) {
+					// Any element subsequent to index is given the 'future' class
+					slides[i].classList.add( 'future' );
+				}
+
+				// If this element contains vertical slides
+				if( slide.querySelector( 'section' ) ) {
+					slides[i].classList.add( 'stack' );
+				}
+			}
+
+			// Mark the current slide as present
+			slides[index].classList.add( 'present' );
+
+			// If this slide has a state associated with it, add it
+			// onto the current state of the deck
+			var slideState = slides[index].getAttribute( 'data-state' );
+			if( slideState ) {
+				state = state.concat( slideState.split( ' ' ) );
+			}
+		}
+		else {
+			// Since there are no slides we can't be anywhere beyond the 
+			// zeroth index
+			index = 0;
+		}
+		
+		return index;
+		
+	}
+	
+	/**
+	 * Updates the visual slides to represent the currently
+	 * set indices. 
+	 */
+	function slide( h, v ) {
+		// Remember where we were at before
+		previousSlide = currentSlide;
+
+		// Remember the state before this slide
+		var stateBefore = state.concat();
+
+		// Reset the state array
+		state.length = 0;
+
+		var indexhBefore = indexh,
+			indexvBefore = indexv;
+
+		// Activate and transition to the new slide
+		indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
+		indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
+
+		// Apply the new state
+		stateLoop: for( var i = 0, len = state.length; i < len; i++ ) {
+			// Check if this state existed on the previous slide. If it 
+			// did, we will avoid adding it repeatedly.
+			for( var j = 0; j < stateBefore.length; j++ ) {
+				if( stateBefore[j] === state[i] ) {
+					stateBefore.splice( j, 1 );
+					continue stateLoop;
+				}
+			}
+
+			document.documentElement.classList.add( state[i] );
+
+			// Dispatch custom event matching the state's name
+			dispatchEvent( state[i] );
+		}
+
+		// Clean up the remaints of the previous state
+		while( stateBefore.length ) {
+			document.documentElement.classList.remove( stateBefore.pop() );
+		}
+
+		// Update progress if enabled
+		if( config.progress && dom.progress ) {
+			dom.progressbar.style.width = ( indexh / ( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length - 1 ) ) * window.innerWidth + 'px';
+		}
+
+		// Close the overview if it's active
+		if( overviewIsActive() ) {
+			activateOverview();
+		}
+
+		updateControls();
+		
+		clearTimeout( writeURLTimeout );
+		writeURLTimeout = setTimeout( writeURL, 1500 );
+
+		// Query all horizontal slides in the deck
+		var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+
+		// Find the current horizontal slide and any possible vertical slides
+		// within it
+		var currentHorizontalSlide = horizontalSlides[ indexh ],
+			currentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' );
+
+		// Store references to the previous and current slides
+		currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;
+
+		// Dispatch an event if the slide changed
+		if( indexh !== indexhBefore || indexv !== indexvBefore ) {
+			dispatchEvent( 'slidechanged', {
+				'indexh': indexh, 
+				'indexv': indexv,
+				'previousSlide': previousSlide,
+				'currentSlide': currentSlide
+			} );
+		}
+		else {
+			// Ensure that the previous slide is never the same as the current
+			previousSlide = null;
+		}
+
+		// Solves an edge case where the previous slide maintains the 
+		// 'present' class when navigating between adjacent vertical 
+		// stacks
+		if( previousSlide ) {
+			previousSlide.classList.remove( 'present' );
+		}
+	}
+
+	/**
+	 * Updates the state and link pointers of the controls.
+	 */
+	function updateControls() {
+		if ( !config.controls || !dom.controls ) {
+			return;
+		}
+		
+		var routes = availableRoutes();
+
+		// Remove the 'enabled' class from all directions
+		[ dom.controlsLeft, dom.controlsRight, dom.controlsUp, dom.controlsDown ].forEach( function( node ) {
+			node.classList.remove( 'enabled' );
+		} )
+
+		if( routes.left ) dom.controlsLeft.classList.add( 'enabled' );
+		if( routes.right ) dom.controlsRight.classList.add( 'enabled' );
+		if( routes.up ) dom.controlsUp.classList.add( 'enabled' );
+		if( routes.down ) dom.controlsDown.classList.add( 'enabled' );
+	}
+
+	/**
+	 * Determine what available routes there are for navigation.
+	 * 
+	 * @return {Object} containing four booleans: left/right/up/down
+	 */
+	function availableRoutes() {
+		var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
+		var verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
+
+		return {
+			left: indexh > 0,
+			right: indexh < horizontalSlides.length - 1,
+			up: indexv > 0,
+			down: indexv < verticalSlides.length - 1
+		};
+	}
+	
+	/**
+	 * Reads the current URL (hash) and navigates accordingly.
+	 */
+	function readURL() {
+		var hash = window.location.hash;
+
+		// Attempt to parse the hash as either an index or name
+		var bits = hash.slice( 2 ).split( '/' ),
+			name = hash.replace( /#|\//gi, '' );
+
+		// If the first bit is invalid and there is a name we can 
+		// assume that this is a named link
+		if( isNaN( parseInt( bits[0] ) ) && name.length ) {
+			// Find the slide with the specified name
+			var slide = document.querySelector( '#' + name );
+
+			if( slide ) {
+				// Find the position of the named slide and navigate to it
+				var indices = Reveal.getIndices( slide );
+				navigateTo( indices.h, indices.v );
+			}
+			// If the slide doesn't exist, navigate to the current slide
+			else {
+				navigateTo( indexh, indexv );
+			}
+		}
+		else {
+			// Read the index components of the hash
+			var h = parseInt( bits[0] ) || 0,
+				v = parseInt( bits[1] ) || 0;
+
+			navigateTo( h, v );
+		}
+	}
+	
+	/**
+	 * Updates the page URL (hash) to reflect the current
+	 * state. 
+	 */
+	function writeURL() {
+		if( config.history ) {
+			var url = '/';
+			
+			// Only include the minimum possible number of components in
+			// the URL
+			if( indexh > 0 || indexv > 0 ) url += indexh;
+			if( indexv > 0 ) url += '/' + indexv;
+			
+			window.location.hash = url;
+		}
+	}
+
+	/**
+	 * Dispatches an event of the specified type from the 
+	 * reveal DOM element.
+	 */
+	function dispatchEvent( type, properties ) {
+		var event = document.createEvent( "HTMLEvents", 1, 2 );
+		event.initEvent( type, true, true );
+		extend( event, properties );
+		dom.wrapper.dispatchEvent( event );
+	}
+
+	/**
+	 * Navigate to the next slide fragment.
+	 * 
+	 * @return {Boolean} true if there was a next fragment,
+	 * false otherwise
+	 */
+	function nextFragment() {
+		// Vertical slides:
+		if( document.querySelector( VERTICAL_SLIDES_SELECTOR + '.present' ) ) {
+			var verticalFragments = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR + '.present .fragment:not(.visible)' );
+			if( verticalFragments.length ) {
+				verticalFragments[0].classList.add( 'visible' );
+
+				// Notify subscribers of the change
+				dispatchEvent( 'fragmentshown', { fragment: verticalFragments[0] } );
+				return true;
+			}
+		}
+		// Horizontal slides:
+		else {
+			var horizontalFragments = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.present .fragment:not(.visible)' );
+			if( horizontalFragments.length ) {
+				horizontalFragments[0].classList.add( 'visible' );
+
+				// Notify subscribers of the change
+				dispatchEvent( 'fragmentshown', { fragment: horizontalFragments[0] } );
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Navigate to the previous slide fragment.
+	 * 
+	 * @return {Boolean} true if there was a previous fragment,
+	 * false otherwise
+	 */
+	function previousFragment() {
+		// Vertical slides:
+		if( document.querySelector( VERTICAL_SLIDES_SELECTOR + '.present' ) ) {
+			var verticalFragments = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR + '.present .fragment.visible' );
+			if( verticalFragments.length ) {
+				verticalFragments[ verticalFragments.length - 1 ].classList.remove( 'visible' );
+
+				// Notify subscribers of the change
+				dispatchEvent( 'fragmenthidden', { fragment: verticalFragments[ verticalFragments.length - 1 ] } );
+				return true;
+			}
+		}
+		// Horizontal slides:
+		else {
+			var horizontalFragments = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.present .fragment.visible' );
+			if( horizontalFragments.length ) {
+				horizontalFragments[ horizontalFragments.length - 1 ].classList.remove( 'visible' );
+
+				// Notify subscribers of the change
+				dispatchEvent( 'fragmenthidden', { fragment: horizontalFragments[ horizontalFragments.length - 1 ] } );
+				return true;
+			}
+		}
+		
+		return false;
+	}
+
+	function cueAutoSlide() {
+		clearTimeout( autoSlideTimeout );
+
+		// Cue the next auto-slide if enabled
+		if( config.autoSlide ) {
+			autoSlideTimeout = setTimeout( navigateNext, config.autoSlide );
+		}
+	}
+	
+	/**
+	 * Triggers a navigation to the specified indices.
+	 * 
+	 * @param {Number} h The horizontal index of the slide to show
+	 * @param {Number} v The vertical index of the slide to show
+	 */
+	function navigateTo( h, v ) {
+		slide( h, v );
+	}
+	
+	function navigateLeft() {
+		// Prioritize hiding fragments
+		if( overviewIsActive() || previousFragment() === false ) {
+			slide( indexh - 1, 0 );
+		}
+	}
+	function navigateRight() {
+		// Prioritize revealing fragments
+		if( overviewIsActive() || nextFragment() === false ) {
+			slide( indexh + 1, 0 );
+		}
+	}
+	function navigateUp() {
+		// Prioritize hiding fragments
+		if( overviewIsActive() || previousFragment() === false ) {
+			slide( indexh, indexv - 1 );
+		}
+	}
+	function navigateDown() {
+		// Prioritize revealing fragments
+		if( overviewIsActive() || nextFragment() === false ) {
+			slide( indexh, indexv + 1 );
+		}
+	}
+
+	/**
+	 * Navigates backwards, prioritized in the following order:
+	 * 1) Previous fragment
+	 * 2) Previous vertical slide
+	 * 3) Previous horizontal slide
+	 */
+	function navigatePrev() {
+		// Prioritize revealing fragments
+		if( previousFragment() === false ) {
+			if( availableRoutes().up ) {
+				navigateUp();
+			}
+			else {
+				// Fetch the previous horizontal slide, if there is one
+				var previousSlide = document.querySelector( '.reveal .slides>section.past:nth-child(' + indexh + ')' );
+
+				if( previousSlide ) {
+					indexv = ( previousSlide.querySelectorAll('section').length + 1 ) || 0;
+					indexh --;
+					slide();
+				}
+			}
+		}
+	}
+
+	/**
+	 * Same as #navigatePrev() but navigates forwards.
+	 */
+	function navigateNext() {
+		// Prioritize revealing fragments
+		if( nextFragment() === false ) {
+			availableRoutes().down ? navigateDown() : navigateRight();
+		}
+
+		// If auto-sliding is enabled we need to cue up 
+		// another timeout
+		cueAutoSlide();
+	}
+
+	/**
+	 * Toggles the slide overview mode on and off.
+	 */
+	function toggleOverview() {
+		if( overviewIsActive() ) {
+			deactivateOverview();
+		}
+		else {
+			activateOverview();
+		}
+	}
+	
+	// Expose some methods publicly
+	return {
+		initialize: initialize,
+		navigateTo: navigateTo,
+		navigateLeft: navigateLeft,
+		navigateRight: navigateRight,
+		navigateUp: navigateUp,
+		navigateDown: navigateDown,
+		navigatePrev: navigatePrev,
+		navigateNext: navigateNext,
+		toggleOverview: toggleOverview,
+
+		// Adds or removes all internal event listeners (such as keyboard)
+		addEventListeners: addEventListeners,
+		removeEventListeners: removeEventListeners,
+
+		// Returns the indices of the current, or specified, slide
+		getIndices: function( slide ) {
+			// By default, return the current indices
+			var h = indexh,
+				v = indexv;
+
+			// If a slide is specified, return the indices of that slide
+			if( slide ) {
+				var isVertical = !!slide.parentNode.nodeName.match( /section/gi );
+				var slideh = isVertical ? slide.parentNode : slide;
+
+				// Select all horizontal slides
+				var horizontalSlides = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+
+				// Now that we know which the horizontal slide is, get its index
+				h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
+
+				// If this is a vertical slide, grab the vertical index
+				if( isVertical ) {
+					v = Math.max( Array.prototype.slice.call( slide.parentNode.children ).indexOf( slide ), 0 );
+				}
+			}
+
+			return { h: h, v: v };
+		},
+
+		// Returns the previous slide element, may be null
+		getPreviousSlide: function() {
+			return previousSlide
+		},
+
+		// Returns the current slide element
+		getCurrentSlide: function() {
+			return currentSlide
+		},
+
+		// Helper method, retrieves query string as a key/value hash
+		getQueryHash: function() {
+			var query = {};
+
+			location.search.replace( /[A-Z0-9]+?=(\w*)/gi, function(a) {
+				query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
+			} );
+
+			return query;
+		},
+
+		// Forward event binding to the reveal DOM element
+		addEventListener: function( type, listener, useCapture ) {
+			if( 'addEventListener' in window ) {
+				( dom.wrapper || document.querySelector( '.reveal' ) ).addEventListener( type, listener, useCapture );
+			}
+		},
+		removeEventListener: function( type, listener, useCapture ) {
+			if( 'addEventListener' in window ) {
+				( dom.wrapper || document.querySelector( '.reveal' ) ).removeEventListener( type, listener, useCapture );
+			}
+		}
+	};
+	
+})();
diff --git a/docs/slides/plpv14/_support/reveal/js/reveal.min.js b/docs/slides/plpv14/_support/reveal/js/reveal.min.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/js/reveal.min.js
@@ -0,0 +1,8 @@
+/*!
+ * reveal.js 2.0 r22
+ * http://lab.hakim.se/reveal-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var Reveal=(function(){var k=".reveal .slides>section",b=".reveal .slides>section.present>section",e=!!("ontouchstart" in window),N={controls:true,progress:true,history:false,keyboard:true,loop:false,autoSlide:0,mouseWheel:true,rollingLinks:true,theme:"default",transition:"default",dependencies:[]},l=0,c=0,w,E,ac=[],d={},P="WebkitPerspective" in document.body.style||"MozPerspective" in document.body.style||"msPerspective" in document.body.style||"OPerspective" in document.body.style||"perspective" in document.body.style,m="WebkitTransform" in document.body.style||"MozTransform" in document.body.style||"msTransform" in document.body.style||"OTransform" in document.body.style||"transform" in document.body.style,x=0,j=0,B=0,W={startX:0,startY:0,startSpan:0,startCount:0,handled:false,threshold:40};function h(ad){if((!m&&!P)){document.body.setAttribute("class","no-transforms");return}r(N,ad);d.theme=document.querySelector("#theme");d.wrapper=document.querySelector(".reveal");d.progress=document.querySelector(".reveal .progress");d.progressbar=document.querySelector(".reveal .progress span");if(N.controls){d.controls=document.querySelector(".reveal .controls");d.controlsLeft=document.querySelector(".reveal .controls .left");d.controlsRight=document.querySelector(".reveal .controls .right");d.controlsUp=document.querySelector(".reveal .controls .up");d.controlsDown=document.querySelector(".reveal .controls .down")}R();if(navigator.userAgent.match(/(iphone|ipod|android)/i)){document.documentElement.style.overflow="scroll";document.body.style.height="120%";window.addEventListener("load",X,false);window.addEventListener("orientationchange",X,false)}}function R(){var ae=[],ai=[];for(var af=0,ad=N.dependencies.length;af<ad;af++){var ag=N.dependencies[af];if(!ag.condition||ag.condition()){if(ag.async){ai.push(ag.src)}else{ae.push(ag.src)}if(typeof ag.callback==="function"){head.ready(ag.src.match(/([\w\d_-]*)\.?[^\\\/]*$/i)[0],ag.callback)}}}function ah(){head.js.apply(null,ai);F()}if(ae.length){head.ready(ah);head.js.apply(null,ae)}else{ah()}}function F(){C();I();H();K()}function I(){if(P===false){N.transition="linear"}if(N.controls&&d.controls){d.controls.style.display="block"}if(N.progress&&d.progress){d.progress.style.display="block"}if(N.theme&&d.theme){var af=d.theme.getAttribute("href");var ad=/[^/]*?(?=\.css)/;var ae=af.match(ad)[0];if(N.theme!==ae){af=af.replace(ad,N.theme);d.theme.setAttribute("href",af)}}if(N.transition!=="default"){d.wrapper.classList.add(N.transition)}if(N.mouseWheel){document.addEventListener("DOMMouseScroll",n,false);document.addEventListener("mousewheel",n,false)}if(N.rollingLinks){J()}}function C(){document.addEventListener("touchstart",y,false);document.addEventListener("touchmove",Z,false);document.addEventListener("touchend",S,false);window.addEventListener("hashchange",u,false);if(N.keyboard){document.addEventListener("keydown",aa,false)}if(N.controls&&d.controls){d.controlsLeft.addEventListener("click",o(z),false);d.controlsRight.addEventListener("click",o(i),false);d.controlsUp.addEventListener("click",o(s),false);d.controlsDown.addEventListener("click",o(D),false)}}function Q(){document.removeEventListener("keydown",aa,false);document.removeEventListener("touchstart",y,false);document.removeEventListener("touchmove",Z,false);document.removeEventListener("touchend",S,false);window.removeEventListener("hashchange",u,false);if(N.controls&&d.controls){d.controlsLeft.removeEventListener("click",o(z),false);d.controlsRight.removeEventListener("click",o(i),false);d.controlsUp.removeEventListener("click",o(s),false);d.controlsDown.removeEventListener("click",o(D),false)}}function r(ae,ad){for(var af in ad){ae[af]=ad[af]}}function O(af,ad){var ag=af.x-ad.x,ae=af.y-ad.y;return Math.sqrt(ag*ag+ae*ae)}function o(ad){return function(ae){ae.preventDefault();ad.call()}}function X(){setTimeout(function(){window.scrollTo(0,1)},0)}function aa(ae){if(ae.target.contentEditable!="inherit"||ae.shiftKey||ae.altKey||ae.ctrlKey||ae.metaKey){return}var ad=false;switch(ae.keyCode){case 80:case 33:U();ad=true;break;case 78:case 34:v();ad=true;break;case 72:case 37:z();ad=true;break;case 76:case 39:i();ad=true;break;case 75:case 38:s();ad=true;break;case 74:case 40:D();ad=true;break;case 36:L(0);ad=true;break;case 35:L(Number.MAX_VALUE);ad=true;break;case 32:V()?Y():v();ad=true;break;case 13:if(V()){Y();ad=true}break}if(ad){ae.preventDefault()}else{if(ae.keyCode===27&&P){T();ae.preventDefault()}}K()}function y(ad){W.startX=ad.touches[0].clientX;W.startY=ad.touches[0].clientY;W.startCount=ad.touches.length;if(ad.touches.length===2){W.startSpan=O({x:ad.touches[1].clientX,y:ad.touches[1].clientY},{x:W.startX,y:W.startY})}}function Z(ai){if(!W.handled){var ag=ai.touches[0].clientX;var af=ai.touches[0].clientY;if(ai.touches.length===2&&W.startCount===2){var ah=O({x:ai.touches[1].clientX,y:ai.touches[1].clientY},{x:W.startX,y:W.startY});if(Math.abs(W.startSpan-ah)>W.threshold){W.handled=true;if(ah<W.startSpan){G()}else{Y()}}}else{if(ai.touches.length===1){var ae=ag-W.startX,ad=af-W.startY;if(ae>W.threshold&&Math.abs(ae)>Math.abs(ad)){W.handled=true;z()}else{if(ae<-W.threshold&&Math.abs(ae)>Math.abs(ad)){W.handled=true;i()}else{if(ad>W.threshold){W.handled=true;s()}else{if(ad<-W.threshold){W.handled=true;D()}}}}}}ai.preventDefault()}}function S(ad){W.handled=false}function n(ad){clearTimeout(x);x=setTimeout(function(){var ae=ad.detail||-ad.wheelDelta;if(ae>0){v()}else{U()}},100)}function u(ad){H()}function J(){if(P&&!("msPerspective" in document.body.style)){var ae=document.querySelectorAll(".reveal .slides section a:not(.image)");for(var af=0,ad=ae.length;af<ad;af++){var ag=ae[af];if(ag.textContent&&!ag.querySelector("img")&&(!ag.className||!ag.classList.contains(ag,"roll"))){ag.classList.add("roll");ag.innerHTML='<span data-title="'+ag.text+'">'+ag.innerHTML+"</span>"}}}}function G(){d.wrapper.classList.add("overview");var ad=Array.prototype.slice.call(document.querySelectorAll(k));for(var ai=0,ag=ad.length;ai<ag;ai++){var af=ad[ai],am="translateZ(-2500px) translate("+((ai-l)*105)+"%, 0%)";af.setAttribute("data-index-h",ai);af.style.display="block";af.style.WebkitTransform=am;af.style.MozTransform=am;af.style.msTransform=am;af.style.OTransform=am;af.style.transform=am;if(!af.classList.contains("stack")){af.addEventListener("click",A,true)}var al=Array.prototype.slice.call(af.querySelectorAll("section"));for(var ah=0,ae=al.length;ah<ae;ah++){var ak=al[ah],aj="translate(0%, "+((ah-(ai===l?c:0))*105)+"%)";ak.setAttribute("data-index-h",ai);ak.setAttribute("data-index-v",ah);ak.style.display="block";ak.style.WebkitTransform=aj;ak.style.MozTransform=aj;ak.style.msTransform=aj;ak.style.OTransform=aj;ak.style.transform=aj;ak.addEventListener("click",A,true)}}}function Y(){d.wrapper.classList.remove("overview");var ag=Array.prototype.slice.call(document.querySelectorAll(".reveal .slides section"));for(var af=0,ad=ag.length;af<ad;af++){var ae=ag[af];ae.style.WebkitTransform="";ae.style.MozTransform="";ae.style.msTransform="";ae.style.OTransform="";ae.style.transform="";ae.removeEventListener("click",A)}a()}function V(){return d.wrapper.classList.contains("overview")}function A(ad){if(V()){ad.preventDefault();Y();l=this.getAttribute("data-index-h");c=this.getAttribute("data-index-v");a()}}function ab(ae,ag){var ai=Array.prototype.slice.call(document.querySelectorAll(ae)),aj=ai.length;if(aj){if(N.loop){ag%=aj;if(ag<0){ag=aj+ag}}ag=Math.max(Math.min(ag,aj-1),0);for(var ah=0;ah<aj;ah++){var ad=ai[ah];if(V()===false){var ak=Math.abs((ag-ah)%(aj-3))||0;ad.style.display=ak>3?"none":"block"}ai[ah].classList.remove("past");ai[ah].classList.remove("present");ai[ah].classList.remove("future");if(ah<ag){ai[ah].classList.add("past")}else{if(ah>ag){ai[ah].classList.add("future")}}if(ad.querySelector("section")){ai[ah].classList.add("stack")}}ai[ag].classList.add("present");var af=ai[ag].getAttribute("data-state");if(af){ac=ac.concat(af.split(" "))}}else{ag=0}return ag}function a(aj,an){w=E;var ag=ac.concat();ac.length=0;var am=l,ae=c;l=ab(k,aj===undefined?l:aj);c=ab(b,an===undefined?c:an);stateLoop:for(var ah=0,ak=ac.length;ah<ak;ah++){for(var af=0;af<ag.length;af++){if(ag[af]===ac[ah]){ag.splice(af,1);continue stateLoop}}document.documentElement.classList.add(ac[ah]);p(ac[ah])}while(ag.length){document.documentElement.classList.remove(ag.pop())}if(N.progress&&d.progress){d.progressbar.style.width=(l/(document.querySelectorAll(k).length-1))*window.innerWidth+"px"}if(V()){G()}q();clearTimeout(B);B=setTimeout(g,1500);var ad=document.querySelectorAll(k);var al=ad[l],ai=al.querySelectorAll("section");E=ai[c]||al;if(l!==am||c!==ae){p("slidechanged",{indexh:l,indexv:c,previousSlide:w,currentSlide:E})}else{w=null}if(w){w.classList.remove("present")}}function q(){if(!N.controls||!d.controls){return}var ad=f();[d.controlsLeft,d.controlsRight,d.controlsUp,d.controlsDown].forEach(function(ae){ae.classList.remove("enabled")});if(ad.left){d.controlsLeft.classList.add("enabled")}if(ad.right){d.controlsRight.classList.add("enabled")}if(ad.up){d.controlsUp.classList.add("enabled")}if(ad.down){d.controlsDown.classList.add("enabled")}}function f(){var ad=document.querySelectorAll(k);var ae=document.querySelectorAll(b);return{left:l>0,right:l<ad.length-1,up:c>0,down:c<ae.length-1}}function H(){var ai=window.location.hash;var ah=ai.slice(2).split("/"),af=ai.replace(/#|\//gi,"");if(isNaN(parseInt(ah[0]))&&af.length){var ad=document.querySelector("#"+af);if(ad){var aj=Reveal.getIndices(ad);L(aj.h,aj.v)}else{L(l,c)}}else{var ag=parseInt(ah[0])||0,ae=parseInt(ah[1])||0;L(ag,ae)}}function g(){if(N.history){var ad="/";if(l>0||c>0){ad+=l}if(c>0){ad+="/"+c}window.location.hash=ad}}function p(ae,ad){var af=document.createEvent("HTMLEvents",1,2);af.initEvent(ae,true,true);r(af,ad);d.wrapper.dispatchEvent(af)}function t(){if(document.querySelector(b+".present")){var ae=document.querySelectorAll(b+".present .fragment:not(.visible)");if(ae.length){ae[0].classList.add("visible");p("fragmentshown",{fragment:ae[0]});return true}}else{var ad=document.querySelectorAll(k+".present .fragment:not(.visible)");if(ad.length){ad[0].classList.add("visible");p("fragmentshown",{fragment:ad[0]});return true}}return false}function M(){if(document.querySelector(b+".present")){var ae=document.querySelectorAll(b+".present .fragment.visible");if(ae.length){ae[ae.length-1].classList.remove("visible");p("fragmenthidden",{fragment:ae[ae.length-1]});return true}}else{var ad=document.querySelectorAll(k+".present .fragment.visible");if(ad.length){ad[ad.length-1].classList.remove("visible");p("fragmenthidden",{fragment:ad[ad.length-1]});return true}}return false}function K(){clearTimeout(j);if(N.autoSlide){j=setTimeout(v,N.autoSlide)}}function L(ae,ad){a(ae,ad)}function z(){if(V()||M()===false){a(l-1,0)}}function i(){if(V()||t()===false){a(l+1,0)}}function s(){if(V()||M()===false){a(l,c-1)}}function D(){if(V()||t()===false){a(l,c+1)}}function U(){if(M()===false){if(f().up){s()}else{var ad=document.querySelector(".reveal .slides>section.past:nth-child("+l+")");if(ad){c=(ad.querySelectorAll("section").length+1)||0;l--;a()}}}}function v(){if(t()===false){f().down?D():i()}K()}function T(){if(V()){Y()}else{G()}}return{initialize:h,navigateTo:L,navigateLeft:z,navigateRight:i,navigateUp:s,navigateDown:D,navigatePrev:U,navigateNext:v,toggleOverview:T,addEventListeners:C,removeEventListeners:Q,getIndices:function(ad){var ah=l,af=c;if(ad){var ai=!!ad.parentNode.nodeName.match(/section/gi);var ag=ai?ad.parentNode:ad;var ae=Array.prototype.slice.call(document.querySelectorAll(k));ah=Math.max(ae.indexOf(ag),0);if(ai){af=Math.max(Array.prototype.slice.call(ad.parentNode.children).indexOf(ad),0)}}return{h:ah,v:af}},getPreviousSlide:function(){return w},getCurrentSlide:function(){return E},getQueryHash:function(){var ad={};location.search.replace(/[A-Z0-9]+?=(\w*)/gi,function(ae){ad[ae.split("=").shift()]=ae.split("=").pop()});return ad},addEventListener:function(ae,af,ad){if("addEventListener" in window){(d.wrapper||document.querySelector(".reveal")).addEventListener(ae,af,ad)}},removeEventListener:function(ae,af,ad){if("addEventListener" in window){(d.wrapper||document.querySelector(".reveal")).removeEventListener(ae,af,ad)}}}})();
diff --git a/docs/slides/plpv14/_support/reveal/lib/css/zenburn.css b/docs/slides/plpv14/_support/reveal/lib/css/zenburn.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/lib/css/zenburn.css
@@ -0,0 +1,115 @@
+/*
+
+Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
+based on dark.css by Ivan Sagalaev
+
+*/
+
+pre code {
+  display: block; padding: 0.5em;
+  background: #3F3F3F;
+  color: #DCDCDC;
+}
+
+pre .keyword,
+pre .tag,
+pre .django .tag,
+pre .django .keyword,
+pre .css .class,
+pre .css .id,
+pre .lisp .title {
+  color: #E3CEAB;
+}
+
+pre .django .template_tag,
+pre .django .variable,
+pre .django .filter .argument {
+  color: #DCDCDC;
+}
+
+pre .number,
+pre .date {
+  color: #8CD0D3;
+}
+
+pre .dos .envvar,
+pre .dos .stream,
+pre .variable,
+pre .apache .sqbracket {
+  color: #EFDCBC;
+}
+
+pre .dos .flow,
+pre .diff .change,
+pre .python .exception,
+pre .python .built_in,
+pre .literal,
+pre .tex .special {
+  color: #EFEFAF;
+}
+
+pre .diff .chunk,
+pre .ruby .subst {
+  color: #8F8F8F;
+}
+
+pre .dos .keyword,
+pre .python .decorator,
+pre .class .title,
+pre .haskell .label,
+pre .function .title,
+pre .ini .title,
+pre .diff .header,
+pre .ruby .class .parent,
+pre .apache .tag,
+pre .nginx .built_in,
+pre .tex .command,
+pre .input_number {
+    color: #efef8f;
+}
+
+pre .dos .winutils,
+pre .ruby .symbol,
+pre .ruby .symbol .string,
+pre .ruby .symbol .keyword,
+pre .ruby .symbol .keymethods,
+pre .ruby .string,
+pre .ruby .instancevar {
+  color: #DCA3A3;
+}
+
+pre .diff .deletion,
+pre .string,
+pre .tag .value,
+pre .preprocessor,
+pre .built_in,
+pre .sql .aggregate,
+pre .javadoc,
+pre .smalltalk .class,
+pre .smalltalk .localvars,
+pre .smalltalk .array,
+pre .css .rules .value,
+pre .attr_selector,
+pre .pseudo,
+pre .apache .cbracket,
+pre .tex .formula {
+  color: #CC9393;
+}
+
+pre .shebang,
+pre .diff .addition,
+pre .comment,
+pre .java .annotation,
+pre .template_comment,
+pre .pi,
+pre .doctype {
+  color: #7F9F7F;
+}
+
+pre .xml .css,
+pre .xml .javascript,
+pre .xml .vbscript,
+pre .tex .formula {
+  opacity: 0.5;
+}
+
diff --git a/docs/slides/plpv14/_support/reveal/lib/font/OpenSans-Regular.ttf b/docs/slides/plpv14/_support/reveal/lib/font/OpenSans-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/_support/reveal/lib/font/OpenSans-Regular.ttf differ
diff --git a/docs/slides/plpv14/_support/reveal/lib/font/PT_Sans-Narrow-Web-Regular.ttf b/docs/slides/plpv14/_support/reveal/lib/font/PT_Sans-Narrow-Web-Regular.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/_support/reveal/lib/font/PT_Sans-Narrow-Web-Regular.ttf differ
diff --git a/docs/slides/plpv14/_support/reveal/lib/font/league_gothic-webfont.ttf b/docs/slides/plpv14/_support/reveal/lib/font/league_gothic-webfont.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/_support/reveal/lib/font/league_gothic-webfont.ttf differ
diff --git a/docs/slides/plpv14/_support/reveal/lib/js/classList.js b/docs/slides/plpv14/_support/reveal/lib/js/classList.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/lib/js/classList.js
@@ -0,0 +1,2 @@
+/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
+if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.className),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.className=this.toString()}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(o){o+="";if(g(this,o)===-1){this.push(o);this._updateClassName()}};e.remove=function(p){p+="";var o=g(this,p);if(o!==-1){this.splice(o,1);this._updateClassName()}};e.toggle=function(o){o+="";if(g(this,o)===-1){this.add(o)}else{this.remove(o)}};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
diff --git a/docs/slides/plpv14/_support/reveal/lib/js/data-markdown.js b/docs/slides/plpv14/_support/reveal/lib/js/data-markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/lib/js/data-markdown.js
@@ -0,0 +1,27 @@
+// From https://gist.github.com/1343518
+// Modified by Hakim to handle markdown indented with tabs
+(function(){
+
+    var slides = document.querySelectorAll('[data-markdown]');
+
+    for( var i = 0, len = slides.length; i < len; i++ ) {
+        var elem = slides[i];
+
+        // strip leading whitespace so it isn't evaluated as code
+        var text = elem.innerHTML;
+
+        var leadingWs = text.match(/^\n?(\s*)/)[1].length,
+            leadingTabs = text.match(/^\n?(\t*)/)[1].length;
+
+        if( leadingTabs > 0 ) {
+            text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+        }
+        else if( leadingWs > 1 ) {
+            text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+        }
+
+        // here, have sum HTML
+        elem.innerHTML = (new Showdown.converter()).makeHtml(text);
+    }
+
+})();
diff --git a/docs/slides/plpv14/_support/reveal/lib/js/head.min.js b/docs/slides/plpv14/_support/reveal/lib/js/head.min.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/lib/js/head.min.js
@@ -0,0 +1,8 @@
+/**
+    Head JS     The only script in your <HEAD>
+    Copyright   Tero Piirainen (tipiirai)
+    License     MIT / http://bit.ly/mit-license
+    Version     0.96
+
+    http://headjs.com
+*/(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c<a.length;c++)b.call(a,a[c],c)}}function r(a){var b;if(typeof a=="object")for(var c in a)a[c]&&(b={name:c,url:a[c]});else b={name:q(a),url:a};var d=h[b.name];if(d&&d.url===b.url)return d;h[b.name]=b;return b}function q(a){var b=a.split("/"),c=b[b.length-1],d=c.indexOf("?");return d!=-1?c.substring(0,d):c}function p(a){a._done||(a(),a._done=1)}var b=a.documentElement,c,d,e=[],f=[],g={},h={},i=a.createElement("script").async===!0||"MozAppearance"in a.documentElement.style||window.opera,j=window.head_conf&&head_conf.head||"head",k=window[j]=window[j]||function(){k.ready.apply(null,arguments)},l=1,m=2,n=3,o=4;i?k.js=function(){var a=arguments,b=a[a.length-1],c={};t(b)||(b=null),s(a,function(d,e){d!=b&&(d=r(d),c[d.name]=d,x(d,b&&e==a.length-2?function(){u(c)&&p(b)}:null))});return k}:k.js=function(){var a=arguments,b=[].slice.call(a,1),d=b[0];if(!c){f.push(function(){k.js.apply(null,a)});return k}d?(s(b,function(a){t(a)||w(r(a))}),x(r(a[0]),t(d)?d:function(){k.js.apply(null,b)})):x(r(a[0]));return k},k.ready=function(b,c){if(b==a){d?p(c):e.push(c);return k}t(b)&&(c=b,b="ALL");if(typeof b!="string"||!t(c))return k;var f=h[b];if(f&&f.state==o||b=="ALL"&&u()&&d){p(c);return k}var i=g[b];i?i.push(c):i=g[b]=[c];return k},k.ready(a,function(){u()&&s(g.ALL,function(a){p(a)}),k.feature&&k.feature("domloaded",!0)});if(window.addEventListener)a.addEventListener("DOMContentLoaded",z,!1),window.addEventListener("load",z,!1);else if(window.attachEvent){a.attachEvent("onreadystatechange",function(){a.readyState==="complete"&&z()});var A=1;try{A=window.frameElement}catch(B){}!A&&b.doScroll&&function(){try{b.doScroll("left"),z()}catch(a){setTimeout(arguments.callee,1);return}}(),window.attachEvent("onload",z)}!a.readyState&&a.addEventListener&&(a.readyState="loading",a.addEventListener("DOMContentLoaded",handler=function(){a.removeEventListener("DOMContentLoaded",handler,!1),a.readyState="complete"},!1)),setTimeout(function(){c=!0,s(f,function(a){a()})},300)})(document)
diff --git a/docs/slides/plpv14/_support/reveal/lib/js/highlight.js b/docs/slides/plpv14/_support/reveal/lib/js/highlight.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/lib/js/highlight.js
@@ -0,0 +1,5 @@
+/*
+Syntax highlighting with language autodetection.
+http://softwaremaniacs.org/soft/highlight/
+*/
+var hljs=new function(){function m(p){return p.replace(/&/gm,"&amp;").replace(/</gm,"&lt;")}function c(r,q,p){return RegExp(q,"m"+(r.cI?"i":"")+(p?"g":""))}function j(r){for(var p=0;p<r.childNodes.length;p++){var q=r.childNodes[p];if(q.nodeName=="CODE"){return q}if(!(q.nodeType==3&&q.nodeValue.match(/\s+/))){break}}}function g(t,s){var r="";for(var q=0;q<t.childNodes.length;q++){if(t.childNodes[q].nodeType==3){var p=t.childNodes[q].nodeValue;if(s){p=p.replace(/\n/g,"")}r+=p}else{if(t.childNodes[q].nodeName=="BR"){r+="\n"}else{r+=g(t.childNodes[q])}}}if(/MSIE [678]/.test(navigator.userAgent)){r=r.replace(/\r/g,"\n")}return r}function a(s){var q=s.className.split(/\s+/);q=q.concat(s.parentNode.className.split(/\s+/));for(var p=0;p<q.length;p++){var r=q[p].replace(/^language-/,"");if(d[r]||r=="no-highlight"){return r}}}function b(p){var q=[];(function(s,t){for(var r=0;r<s.childNodes.length;r++){if(s.childNodes[r].nodeType==3){t+=s.childNodes[r].nodeValue.length}else{if(s.childNodes[r].nodeName=="BR"){t+=1}else{q.push({event:"start",offset:t,node:s.childNodes[r]});t=arguments.callee(s.childNodes[r],t);q.push({event:"stop",offset:t,node:s.childNodes[r]})}}}return t})(p,0);return q}function l(y,z,x){var r=0;var w="";var t=[];function u(){if(y.length&&z.length){if(y[0].offset!=z[0].offset){return(y[0].offset<z[0].offset)?y:z}else{return z[0].event=="start"?y:z}}else{return y.length?y:z}}function s(C){var D="<"+C.nodeName.toLowerCase();for(var A=0;A<C.attributes.length;A++){var B=C.attributes[A];D+=" "+B.nodeName.toLowerCase();if(B.nodeValue!=undefined&&B.nodeValue!=false&&B.nodeValue!=null){D+='="'+m(B.nodeValue)+'"'}}return D+">"}while(y.length||z.length){var v=u().splice(0,1)[0];w+=m(x.substr(r,v.offset-r));r=v.offset;if(v.event=="start"){w+=s(v.node);t.push(v.node)}else{if(v.event=="stop"){var q=t.length;do{q--;var p=t[q];w+=("</"+p.nodeName.toLowerCase()+">")}while(p!=v.node);t.splice(q,1);while(q<t.length){w+=s(t[q]);q++}}}}w+=x.substr(r);return w}function i(){function p(u,t,v){if(u.compiled){return}if(!v){u.bR=c(t,u.b?u.b:"\\B|\\b");if(!u.e&&!u.eW){u.e="\\B|\\b"}if(u.e){u.eR=c(t,u.e)}}if(u.i){u.iR=c(t,u.i)}if(u.r==undefined){u.r=1}if(u.k){u.lR=c(t,u.l||hljs.IR,true)}for(var s in u.k){if(!u.k.hasOwnProperty(s)){continue}if(u.k[s] instanceof Object){u.kG=u.k}else{u.kG={keyword:u.k}}break}if(!u.c){u.c=[]}u.compiled=true;for(var r=0;r<u.c.length;r++){p(u.c[r],t,false)}if(u.starts){p(u.starts,t,false)}}for(var q in d){if(!d.hasOwnProperty(q)){continue}p(d[q].dM,d[q],true)}}function e(J,D){if(!i.called){i();i.called=true}function z(r,M){for(var L=0;L<M.c.length;L++){if(M.c[L].bR.test(r)){return M.c[L]}}}function w(L,r){if(C[L].e&&C[L].eR.test(r)){return 1}if(C[L].eW){var M=w(L-1,r);return M?M+1:0}return 0}function x(r,L){return L.iR&&L.iR.test(r)}function A(O,N){var M=[];for(var L=0;L<O.c.length;L++){M.push(O.c[L].b)}var r=C.length-1;do{if(C[r].e){M.push(C[r].e)}r--}while(C[r+1].eW);if(O.i){M.push(O.i)}return c(N,"("+M.join("|")+")",true)}function s(M,L){var N=C[C.length-1];if(!N.t){N.t=A(N,H)}N.t.lastIndex=L;var r=N.t.exec(M);if(r){return[M.substr(L,r.index-L),r[0],false]}else{return[M.substr(L),"",true]}}function p(O,r){var L=H.cI?r[0].toLowerCase():r[0];for(var N in O.kG){if(!O.kG.hasOwnProperty(N)){continue}var M=O.kG[N].hasOwnProperty(L);if(M){return[N,M]}}return false}function F(M,O){if(!O.k){return m(M)}var N="";var P=0;O.lR.lastIndex=0;var L=O.lR.exec(M);while(L){N+=m(M.substr(P,L.index-P));var r=p(O,L);if(r){t+=r[1];N+='<span class="'+r[0]+'">'+m(L[0])+"</span>"}else{N+=m(L[0])}P=O.lR.lastIndex;L=O.lR.exec(M)}N+=m(M.substr(P,M.length-P));return N}function K(r,M){if(M.sL&&d[M.sL]){var L=e(M.sL,r);t+=L.keyword_count;return L.value}else{return F(r,M)}}function I(M,r){var L=M.cN?'<span class="'+M.cN+'">':"";if(M.rB){q+=L;M.buffer=""}else{if(M.eB){q+=m(r)+L;M.buffer=""}else{q+=L;M.buffer=r}}C.push(M);B+=M.r}function E(O,L,Q){var R=C[C.length-1];if(Q){q+=K(R.buffer+O,R);return false}var M=z(L,R);if(M){q+=K(R.buffer+O,R);I(M,L);return M.rB}var r=w(C.length-1,L);if(r){var N=R.cN?"</span>":"";if(R.rE){q+=K(R.buffer+O,R)+N}else{if(R.eE){q+=K(R.buffer+O,R)+N+m(L)}else{q+=K(R.buffer+O+L,R)+N}}while(r>1){N=C[C.length-2].cN?"</span>":"";q+=N;r--;C.length--}var P=C[C.length-1];C.length--;C[C.length-1].buffer="";if(P.starts){I(P.starts,"")}return R.rE}if(x(L,R)){throw"Illegal"}}var H=d[J];var C=[H.dM];var B=0;var t=0;var q="";try{var v=0;H.dM.buffer="";do{var y=s(D,v);var u=E(y[0],y[1],y[2]);v+=y[0].length;if(!u){v+=y[1].length}}while(!y[2]);if(C.length>1){throw"Illegal"}return{r:B,keyword_count:t,value:q}}catch(G){if(G=="Illegal"){return{r:0,keyword_count:0,value:m(D)}}else{throw G}}}function f(t){var r={keyword_count:0,r:0,value:m(t)};var q=r;for(var p in d){if(!d.hasOwnProperty(p)){continue}var s=e(p,t);s.language=p;if(s.keyword_count+s.r>q.keyword_count+q.r){q=s}if(s.keyword_count+s.r>r.keyword_count+r.r){q=r;r=s}}if(q.language){r.second_best=q}return r}function h(r,q,p){if(q){r=r.replace(/^((<[^>]+>|\t)+)/gm,function(t,w,v,u){return w.replace(/\t/g,q)})}if(p){r=r.replace(/\n/g,"<br>")}return r}function o(u,x,q){var y=g(u,q);var s=a(u);if(s=="no-highlight"){return}if(s){var w=e(s,y)}else{var w=f(y);s=w.language}var p=b(u);if(p.length){var r=document.createElement("pre");r.innerHTML=w.value;w.value=l(p,b(r),y)}w.value=h(w.value,x,q);var t=u.className;if(!t.match("(\\s|^)(language-)?"+s+"(\\s|$)")){t=t?(t+" "+s):s}if(/MSIE [678]/.test(navigator.userAgent)&&u.tagName=="CODE"&&u.parentNode.tagName=="PRE"){var r=u.parentNode;var v=document.createElement("div");v.innerHTML="<pre><code>"+w.value+"</code></pre>";u=v.firstChild.firstChild;v.firstChild.cN=r.cN;r.parentNode.replaceChild(v.firstChild,r)}else{u.innerHTML=w.value}u.className=t;u.result={language:s,kw:w.keyword_count,re:w.r};if(w.second_best){u.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function k(){if(k.called){return}k.called=true;var r=document.getElementsByTagName("pre");for(var p=0;p<r.length;p++){var q=j(r[p]);if(q){o(q,hljs.tabReplace)}}}function n(){if(window.addEventListener){window.addEventListener("DOMContentLoaded",k,false);window.addEventListener("load",k,false)}else{if(window.attachEvent){window.attachEvent("onload",k)}else{window.onload=k}}}var d={};this.LANGUAGES=d;this.highlight=e;this.highlightAuto=f;this.fixMarkup=h;this.highlightBlock=o;this.initHighlighting=k;this.initHighlightingOnLoad=n;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\.",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.inherit=function(p,s){var r={};for(var q in p){r[q]=p[q]}if(s){for(var q in s){r[q]=s[q]}}return r}}();hljs.LANGUAGES.cs={dM:{k:{"abstract":1,as:1,base:1,bool:1,"break":1,"byte":1,"case":1,"catch":1,"char":1,checked:1,"class":1,"const":1,"continue":1,decimal:1,"default":1,delegate:1,"do":1,"do":1,"double":1,"else":1,"enum":1,event:1,explicit:1,extern:1,"false":1,"finally":1,fixed:1,"float":1,"for":1,foreach:1,"goto":1,"if":1,implicit:1,"in":1,"int":1,"interface":1,internal:1,is:1,lock:1,"long":1,namespace:1,"new":1,"null":1,object:1,operator:1,out:1,override:1,params:1,"private":1,"protected":1,"public":1,readonly:1,ref:1,"return":1,sbyte:1,sealed:1,"short":1,sizeof:1,stackalloc:1,"static":1,string:1,struct:1,"switch":1,"this":1,"throw":1,"true":1,"try":1,"typeof":1,uint:1,ulong:1,unchecked:1,unsafe:1,ushort:1,using:1,virtual:1,"volatile":1,"void":1,"while":1,ascending:1,descending:1,from:1,get:1,group:1,into:1,join:1,let:1,orderby:1,partial:1,select:1,set:1,value:1,"var":1,where:1,yield:1},c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"}]},hljs.CLCM,hljs.CBLCLM,{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},hljs.ASM,hljs.QSM,hljs.CNM]}};hljs.LANGUAGES.ruby=function(){var g="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var a="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var n={keyword:{and:1,"false":1,then:1,defined:1,module:1,"in":1,"return":1,redo:1,"if":1,BEGIN:1,retry:1,end:1,"for":1,"true":1,self:1,when:1,next:1,until:1,"do":1,begin:1,unless:1,END:1,rescue:1,nil:1,"else":1,"break":1,undef:1,not:1,"super":1,"class":1,"case":1,require:1,yield:1,alias:1,"while":1,ensure:1,elsif:1,or:1,def:1},keymethods:{__id__:1,__send__:1,abort:1,abs:1,"all?":1,allocate:1,ancestors:1,"any?":1,arity:1,assoc:1,at:1,at_exit:1,autoload:1,"autoload?":1,"between?":1,binding:1,binmode:1,"block_given?":1,call:1,callcc:1,caller:1,capitalize:1,"capitalize!":1,casecmp:1,"catch":1,ceil:1,center:1,chomp:1,"chomp!":1,chop:1,"chop!":1,chr:1,"class":1,class_eval:1,"class_variable_defined?":1,class_variables:1,clear:1,clone:1,close:1,close_read:1,close_write:1,"closed?":1,coerce:1,collect:1,"collect!":1,compact:1,"compact!":1,concat:1,"const_defined?":1,const_get:1,const_missing:1,const_set:1,constants:1,count:1,crypt:1,"default":1,default_proc:1,"delete":1,"delete!":1,delete_at:1,delete_if:1,detect:1,display:1,div:1,divmod:1,downcase:1,"downcase!":1,downto:1,dump:1,dup:1,each:1,each_byte:1,each_index:1,each_key:1,each_line:1,each_pair:1,each_value:1,each_with_index:1,"empty?":1,entries:1,eof:1,"eof?":1,"eql?":1,"equal?":1,"eval":1,exec:1,exit:1,"exit!":1,extend:1,fail:1,fcntl:1,fetch:1,fileno:1,fill:1,find:1,find_all:1,first:1,flatten:1,"flatten!":1,floor:1,flush:1,for_fd:1,foreach:1,fork:1,format:1,freeze:1,"frozen?":1,fsync:1,getc:1,gets:1,global_variables:1,grep:1,gsub:1,"gsub!":1,"has_key?":1,"has_value?":1,hash:1,hex:1,id:1,include:1,"include?":1,included_modules:1,index:1,indexes:1,indices:1,induced_from:1,inject:1,insert:1,inspect:1,instance_eval:1,instance_method:1,instance_methods:1,"instance_of?":1,"instance_variable_defined?":1,instance_variable_get:1,instance_variable_set:1,instance_variables:1,"integer?":1,intern:1,invert:1,ioctl:1,"is_a?":1,isatty:1,"iterator?":1,join:1,"key?":1,keys:1,"kind_of?":1,lambda:1,last:1,length:1,lineno:1,ljust:1,load:1,local_variables:1,loop:1,lstrip:1,"lstrip!":1,map:1,"map!":1,match:1,max:1,"member?":1,merge:1,"merge!":1,method:1,"method_defined?":1,method_missing:1,methods:1,min:1,module_eval:1,modulo:1,name:1,nesting:1,"new":1,next:1,"next!":1,"nil?":1,nitems:1,"nonzero?":1,object_id:1,oct:1,open:1,pack:1,partition:1,pid:1,pipe:1,pop:1,popen:1,pos:1,prec:1,prec_f:1,prec_i:1,print:1,printf:1,private_class_method:1,private_instance_methods:1,"private_method_defined?":1,private_methods:1,proc:1,protected_instance_methods:1,"protected_method_defined?":1,protected_methods:1,public_class_method:1,public_instance_methods:1,"public_method_defined?":1,public_methods:1,push:1,putc:1,puts:1,quo:1,raise:1,rand:1,rassoc:1,read:1,read_nonblock:1,readchar:1,readline:1,readlines:1,readpartial:1,rehash:1,reject:1,"reject!":1,remainder:1,reopen:1,replace:1,require:1,"respond_to?":1,reverse:1,"reverse!":1,reverse_each:1,rewind:1,rindex:1,rjust:1,round:1,rstrip:1,"rstrip!":1,scan:1,seek:1,select:1,send:1,set_trace_func:1,shift:1,singleton_method_added:1,singleton_methods:1,size:1,sleep:1,slice:1,"slice!":1,sort:1,"sort!":1,sort_by:1,split:1,sprintf:1,squeeze:1,"squeeze!":1,srand:1,stat:1,step:1,store:1,strip:1,"strip!":1,sub:1,"sub!":1,succ:1,"succ!":1,sum:1,superclass:1,swapcase:1,"swapcase!":1,sync:1,syscall:1,sysopen:1,sysread:1,sysseek:1,system:1,syswrite:1,taint:1,"tainted?":1,tell:1,test:1,"throw":1,times:1,to_a:1,to_ary:1,to_f:1,to_hash:1,to_i:1,to_int:1,to_io:1,to_proc:1,to_s:1,to_str:1,to_sym:1,tr:1,"tr!":1,tr_s:1,"tr_s!":1,trace_var:1,transpose:1,trap:1,truncate:1,"tty?":1,type:1,ungetc:1,uniq:1,"uniq!":1,unpack:1,unshift:1,untaint:1,untrace_var:1,upcase:1,"upcase!":1,update:1,upto:1,"value?":1,values:1,values_at:1,warn:1,write:1,write_nonblock:1,"zero?":1,zip:1}};var h={cN:"yardoctag",b:"@[A-Za-z]+"};var d={cN:"comment",b:"#",e:"$",c:[h]};var c={cN:"comment",b:"^\\=begin",e:"^\\=end",c:[h],r:10};var b={cN:"comment",b:"^__END__",e:"\\n$"};var u={cN:"subst",b:"#\\{",e:"}",l:g,k:n};var p=[hljs.BE,u];var s={cN:"string",b:"'",e:"'",c:p,r:0};var r={cN:"string",b:'"',e:'"',c:p,r:0};var q={cN:"string",b:"%[qw]?\\(",e:"\\)",c:p,r:10};var o={cN:"string",b:"%[qw]?\\[",e:"\\]",c:p,r:10};var m={cN:"string",b:"%[qw]?{",e:"}",c:p,r:10};var l={cN:"string",b:"%[qw]?<",e:">",c:p,r:10};var k={cN:"string",b:"%[qw]?/",e:"/",c:p,r:10};var j={cN:"string",b:"%[qw]?%",e:"%",c:p,r:10};var i={cN:"string",b:"%[qw]?-",e:"-",c:p,r:10};var t={cN:"string",b:"%[qw]?\\|",e:"\\|",c:p,r:10};var e={cN:"function",b:"\\bdef\\s+",e:" |$|;",l:g,k:n,c:[{cN:"title",b:a,l:g,k:n},{cN:"params",b:"\\(",e:"\\)",l:g,k:n},d,c,b]};var f={cN:"identifier",b:g,l:g,k:n,r:0};var v=[d,c,b,s,r,q,o,m,l,k,j,i,t,{cN:"class",b:"\\b(class|module)\\b",e:"$|;",k:{"class":1,module:1},c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+hljs.IR+"::)?"+hljs.IR}]},d,c,b]},e,{cN:"constant",b:"(::)?([A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:[s,r,q,o,m,l,k,j,i,t,f],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},f,{b:"("+hljs.RSR+")\\s*",c:[d,c,b,{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[hljs.BE]}],r:0}];u.c=v;e.c[1].c=v;return{dM:{l:g,k:n,c:v}}}();hljs.LANGUAGES.javascript={dM:{k:{keyword:{"in":1,"if":1,"for":1,"while":1,"finally":1,"var":1,"new":1,"function":1,"do":1,"return":1,"void":1,"else":1,"break":1,"catch":1,"instanceof":1,"with":1,"throw":1,"case":1,"default":1,"try":1,"this":1,"switch":1,"continue":1,"typeof":1,"delete":1},literal:{"true":1,"false":1,"null":1}},c:[hljs.ASM,hljs.QSM,hljs.CLCM,hljs.CBLCLM,hljs.CNM,{b:"("+hljs.RSR+"|case|return|throw)\\s*",k:{"return":1,"throw":1,"case":1},c:[hljs.CLCM,hljs.CBLCLM,{cN:"regexp",b:"/",e:"/[gim]*",c:[{b:"\\\\/"}]}],r:0},{cN:"function",b:"\\bfunction\\b",e:"{",k:{"function":1},c:[{cN:"title",b:"[A-Za-z$_][0-9A-Za-z$_]*"},{cN:"params",b:"\\(",e:"\\)",c:[hljs.ASM,hljs.QSM,hljs.CLCM,hljs.CBLCLM]}]}]}};hljs.LANGUAGES.css=function(){var a={cN:"function",b:hljs.IR+"\\(",e:"\\)",c:[{eW:true,eE:true,c:[hljs.NM,hljs.ASM,hljs.QSM]}]};return{cI:true,dM:{i:"[=/|']",c:[hljs.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:{"font-face":1,page:1}},{cN:"at_rule",b:"@",e:"[{;]",eE:true,k:{"import":1,page:1,media:1,charset:1},c:[a,hljs.ASM,hljs.QSM,hljs.NM]},{cN:"tag",b:hljs.IR,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[hljs.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[a,hljs.NM,hljs.QSM,hljs.ASM,hljs.CBLCLM,{cN:"hexcolor",b:"\\#[0-9A-F]+"},{cN:"important",b:"!important"}]}}]}]}]}}}();hljs.LANGUAGES.xml=function(){var b="[A-Za-z0-9\\._:-]+";var a={eW:true,c:[{cN:"attribute",b:b,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,dM:{c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style",e:">",k:{title:{style:1}},c:[a],starts:{cN:"css",e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script",e:">",k:{title:{script:1}},c:[a],starts:{cN:"javascript",e:"<\/script>",rE:true,sL:"javascript"}},{cN:"vbscript",b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:"[^ />]+"},a]}]}}}();hljs.LANGUAGES.java={dM:{k:{"false":1,"synchronized":1,"int":1,"abstract":1,"float":1,"private":1,"char":1,"interface":1,"boolean":1,"static":1,"null":1,"if":1,"const":1,"for":1,"true":1,"while":1,"long":1,"throw":1,strictfp:1,"finally":1,"protected":1,"extends":1,"import":1,"native":1,"final":1,"implements":1,"return":1,"void":1,"enum":1,"else":1,"break":1,"transient":1,"new":1,"catch":1,"instanceof":1,"byte":1,"super":1,"class":1,"volatile":1,"case":1,assert:1,"short":1,"package":1,"default":1,"double":1,"public":1,"try":1,"this":1,"switch":1,"continue":1,"throws":1},c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},hljs.CLCM,hljs.CBLCLM,hljs.ASM,hljs.QSM,{cN:"class",b:"(class |interface )",e:"{",k:{"class":1,"interface":1},i:":",c:[{b:"(implements|extends)",k:{"extends":1,"implements":1},r:10},{cN:"title",b:hljs.UIR}]},hljs.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}};hljs.LANGUAGES.php={cI:true,dM:{k:{and:1,include_once:1,list:1,"abstract":1,global:1,"private":1,echo:1,"interface":1,as:1,"static":1,endswitch:1,array:1,"null":1,"if":1,endwhile:1,or:1,"const":1,"for":1,endforeach:1,self:1,"var":1,"while":1,isset:1,"public":1,"protected":1,exit:1,foreach:1,"throw":1,elseif:1,"extends":1,include:1,__FILE__:1,empty:1,require_once:1,"function":1,"do":1,xor:1,"return":1,"implements":1,parent:1,clone:1,use:1,__CLASS__:1,__LINE__:1,"else":1,"break":1,print:1,"eval":1,"new":1,"catch":1,__METHOD__:1,"class":1,"case":1,exception:1,php_user_filter:1,"default":1,die:1,require:1,__FUNCTION__:1,enddeclare:1,"final":1,"try":1,"this":1,"switch":1,"continue":1,endfor:1,endif:1,declare:1,unset:1,"true":1,"false":1,namespace:1},c:[hljs.CLCM,hljs.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+",r:10}]},hljs.CNM,hljs.inherit(hljs.ASM,{i:null}),hljs.inherit(hljs.QSM,{i:null}),{cN:"variable",b:"\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"}]}};hljs.LANGUAGES.python=function(){var c={cN:"string",b:"(u|b)?r?'''",e:"'''",r:10};var b={cN:"string",b:'(u|b)?r?"""',e:'"""',r:10};var a={cN:"string",b:"(u|r|ur|b|br)'",e:"'",c:[hljs.BE],r:10};var f={cN:"string",b:'(u|r|ur|b|br)"',e:'"',c:[hljs.BE],r:10};var d={cN:"title",b:hljs.UIR};var e={cN:"params",b:"\\(",e:"\\)",c:[c,b,a,f,hljs.ASM,hljs.QSM]};return{dM:{k:{keyword:{and:1,elif:1,is:1,global:1,as:1,"in":1,"if":1,from:1,raise:1,"for":1,except:1,"finally":1,print:1,"import":1,pass:1,"return":1,exec:1,"else":1,"break":1,not:1,"with":1,"class":1,assert:1,yield:1,"try":1,"while":1,"continue":1,del:1,or:1,def:1,lambda:1,nonlocal:10},built_in:{None:1,True:1,False:1,Ellipsis:1,NotImplemented:1}},i:"(</|->|\\?)",c:[hljs.HCM,c,b,a,f,hljs.ASM,hljs.QSM,{cN:"function",b:"\\bdef ",e:":",i:"$",k:{def:1},c:[d,e],r:10},{cN:"class",b:"\\bclass ",e:":",i:"[${]",k:{"class":1},c:[d,e],r:10},hljs.CNM,{cN:"decorator",b:"@",e:"$"}]}}}();hljs.LANGUAGES.perl=function(){var c={getpwent:1,getservent:1,quotemeta:1,msgrcv:1,scalar:1,kill:1,dbmclose:1,undef:1,lc:1,ma:1,syswrite:1,tr:1,send:1,umask:1,sysopen:1,shmwrite:1,vec:1,qx:1,utime:1,local:1,oct:1,semctl:1,localtime:1,readpipe:1,"do":1,"return":1,format:1,read:1,sprintf:1,dbmopen:1,pop:1,getpgrp:1,not:1,getpwnam:1,rewinddir:1,qq:1,fileno:1,qw:1,endprotoent:1,wait:1,sethostent:1,bless:1,s:1,opendir:1,"continue":1,each:1,sleep:1,endgrent:1,shutdown:1,dump:1,chomp:1,connect:1,getsockname:1,die:1,socketpair:1,close:1,flock:1,exists:1,index:1,shmget:1,sub:1,"for":1,endpwent:1,redo:1,lstat:1,msgctl:1,setpgrp:1,abs:1,exit:1,select:1,print:1,ref:1,gethostbyaddr:1,unshift:1,fcntl:1,syscall:1,"goto":1,getnetbyaddr:1,join:1,gmtime:1,symlink:1,semget:1,splice:1,x:1,getpeername:1,recv:1,log:1,setsockopt:1,cos:1,last:1,reverse:1,gethostbyname:1,getgrnam:1,study:1,formline:1,endhostent:1,times:1,chop:1,length:1,gethostent:1,getnetent:1,pack:1,getprotoent:1,getservbyname:1,rand:1,mkdir:1,pos:1,chmod:1,y:1,substr:1,endnetent:1,printf:1,next:1,open:1,msgsnd:1,readdir:1,use:1,unlink:1,getsockopt:1,getpriority:1,rindex:1,wantarray:1,hex:1,system:1,getservbyport:1,endservent:1,"int":1,chr:1,untie:1,rmdir:1,prototype:1,tell:1,listen:1,fork:1,shmread:1,ucfirst:1,setprotoent:1,"else":1,sysseek:1,link:1,getgrgid:1,shmctl:1,waitpid:1,unpack:1,getnetbyname:1,reset:1,chdir:1,grep:1,split:1,require:1,caller:1,lcfirst:1,until:1,warn:1,"while":1,values:1,shift:1,telldir:1,getpwuid:1,my:1,getprotobynumber:1,"delete":1,and:1,sort:1,uc:1,defined:1,srand:1,accept:1,"package":1,seekdir:1,getprotobyname:1,semop:1,our:1,rename:1,seek:1,"if":1,q:1,chroot:1,sysread:1,setpwent:1,no:1,crypt:1,getc:1,chown:1,sqrt:1,write:1,setnetent:1,setpriority:1,foreach:1,tie:1,sin:1,msgget:1,map:1,stat:1,getlogin:1,unless:1,elsif:1,truncate:1,exec:1,keys:1,glob:1,tied:1,closedir:1,ioctl:1,socket:1,readlink:1,"eval":1,xor:1,readline:1,binmode:1,setservent:1,eof:1,ord:1,bind:1,alarm:1,pipe:1,atan2:1,getgrent:1,exp:1,time:1,push:1,setgrent:1,gt:1,lt:1,or:1,ne:1,m:1};var d={cN:"subst",b:"[$@]\\{",e:"}",k:c,r:10};var b={cN:"variable",b:"\\$\\d"};var a={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var g=[hljs.BE,d,b,a];var f={b:"->",c:[{b:hljs.IR},{b:"{",e:"}"}]};var e=[b,a,hljs.HCM,{cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5},f,{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:g,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:g,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:g,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:g,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:g,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:g,r:5},{cN:"string",b:"'",e:"'",c:[hljs.BE],r:0},{cN:"string",b:'"',e:'"',c:g,r:0},{cN:"string",b:"`",e:"`",c:[hljs.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[hljs.BE],r:0},{cN:"sub",b:"\\bsub\\b",e:"(\\s*\\(.*?\\))?[;{]",k:{sub:1},r:5},{cN:"operator",b:"-\\w\\b",r:0},{cN:"pod",b:"\\=\\w",e:"\\=cut"}];d.c=e;f.c[1].c=e;return{dM:{k:c,c:e}}}();hljs.LANGUAGES.cpp=function(){var b={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,virtual:1,operator:2,sizeof:2,dynamic_cast:2,typedef:2,const_cast:2,"const":1,struct:1,"for":1,static_cast:2,union:1,namespace:1,unsigned:1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,bool:1,template:1,mutable:1,"if":1,"public":1,friend:2,"do":1,"return":1,"goto":1,auto:1,"void":2,"enum":1,"else":1,"break":1,"new":1,extern:1,using:1,"true":1,"class":1,asm:1,"case":1,typeid:1,"short":1,reinterpret_cast:2,"default":1,"double":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,"delete":1,alignof:1,char16_t:1,char32_t:1,constexpr:1,decltype:1,noexcept:1,nullptr:1,static_assert:1,thread_local:1},built_in:{std:1,string:1,cin:1,cout:1,cerr:1,clog:1,stringstream:1,istringstream:1,ostringstream:1,auto_ptr:1,deque:1,list:1,queue:1,stack:1,vector:1,map:1,set:1,bitset:1,multiset:1,multimap:1,unordered_set:1,unordered_map:1,unordered_multiset:1,unordered_multimap:1,array:1,shared_ptr:1}};var a={cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,r:10};a.c=[a];return{dM:{k:b,i:"</",c:[hljs.CLCM,hljs.CBLCLM,hljs.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},hljs.CNM,{cN:"preprocessor",b:"#",e:"$"},a]}}}();
diff --git a/docs/slides/plpv14/_support/reveal/lib/js/html5shiv.js b/docs/slides/plpv14/_support/reveal/lib/js/html5shiv.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/lib/js/html5shiv.js
@@ -0,0 +1,7 @@
+document.createElement('header');
+document.createElement('nav');
+document.createElement('section');
+document.createElement('article');
+document.createElement('aside');
+document.createElement('footer');
+document.createElement('hgroup');
diff --git a/docs/slides/plpv14/_support/reveal/lib/js/showdown.js b/docs/slides/plpv14/_support/reveal/lib/js/showdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/lib/js/showdown.js
@@ -0,0 +1,1341 @@
+//
+// showdown.js -- A javascript port of Markdown.
+//
+// Copyright (c) 2007 John Fraser.
+//
+// Original Markdown Copyright (c) 2004-2005 John Gruber
+//   <http://daringfireball.net/projects/markdown/>
+//
+// Redistributable under a BSD-style open source license.
+// See license.txt for more information.
+//
+// The full source distribution is at:
+//
+//				A A L
+//				T C A
+//				T K B
+//
+//   <http://www.attacklab.net/>
+//
+
+//
+// Wherever possible, Showdown is a straight, line-by-line port
+// of the Perl version of Markdown.
+//
+// This is not a normal parser design; it's basically just a
+// series of string substitutions.  It's hard to read and
+// maintain this way,  but keeping Showdown close to the original
+// design makes it easier to port new features.
+//
+// More importantly, Showdown behaves like markdown.pl in most
+// edge cases.  So web applications can do client-side preview
+// in Javascript, and then build identical HTML on the server.
+//
+// This port needs the new RegExp functionality of ECMA 262,
+// 3rd Edition (i.e. Javascript 1.5).  Most modern web browsers
+// should do fine.  Even with the new regular expression features,
+// We do a lot of work to emulate Perl's regex functionality.
+// The tricky changes in this file mostly have the "attacklab:"
+// label.  Major or self-explanatory changes don't.
+//
+// Smart diff tools like Araxis Merge will be able to match up
+// this file with markdown.pl in a useful way.  A little tweaking
+// helps: in a copy of markdown.pl, replace "#" with "//" and
+// replace "$text" with "text".  Be sure to ignore whitespace
+// and line endings.
+//
+
+
+//
+// Showdown usage:
+//
+//   var text = "Markdown *rocks*.";
+//
+//   var converter = new Showdown.converter();
+//   var html = converter.makeHtml(text);
+//
+//   alert(html);
+//
+// Note: move the sample code to the bottom of this
+// file before uncommenting it.
+//
+
+
+//
+// Showdown namespace
+//
+var Showdown = {};
+
+//
+// converter
+//
+// Wraps all "globals" so that the only thing
+// exposed is makeHtml().
+//
+Showdown.converter = function() {
+
+//
+// Globals:
+//
+
+// Global hashes, used by various utility routines
+var g_urls;
+var g_titles;
+var g_html_blocks;
+
+// Used to track when we're inside an ordered or unordered list
+// (see _ProcessListItems() for details):
+var g_list_level = 0;
+
+
+this.makeHtml = function(text) {
+//
+// Main function. The order in which other subs are called here is
+// essential. Link and image substitutions need to happen before
+// _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
+// and <img> tags get encoded.
+//
+
+	// Clear the global hashes. If we don't clear these, you get conflicts
+	// from other articles when generating a page which contains more than
+	// one article (e.g. an index page that shows the N most recent
+	// articles):
+	g_urls = new Array();
+	g_titles = new Array();
+	g_html_blocks = new Array();
+
+	// attacklab: Replace ~ with ~T
+	// This lets us use tilde as an escape char to avoid md5 hashes
+	// The choice of character is arbitray; anything that isn't
+    // magic in Markdown will work.
+	text = text.replace(/~/g,"~T");
+
+	// attacklab: Replace $ with ~D
+	// RegExp interprets $ as a special character
+	// when it's in a replacement string
+	text = text.replace(/\$/g,"~D");
+
+	// Standardize line endings
+	text = text.replace(/\r\n/g,"\n"); // DOS to Unix
+	text = text.replace(/\r/g,"\n"); // Mac to Unix
+
+	// Make sure text begins and ends with a couple of newlines:
+	text = "\n\n" + text + "\n\n";
+
+	// Convert all tabs to spaces.
+	text = _Detab(text);
+
+	// Strip any lines consisting only of spaces and tabs.
+	// This makes subsequent regexen easier to write, because we can
+	// match consecutive blank lines with /\n+/ instead of something
+	// contorted like /[ \t]*\n+/ .
+	text = text.replace(/^[ \t]+$/mg,"");
+
+	// Handle github codeblocks prior to running HashHTML so that
+	// HTML contained within the codeblock gets escaped propertly
+	text = _DoGithubCodeBlocks(text);
+
+	// Turn block-level HTML blocks into hash entries
+	text = _HashHTMLBlocks(text);
+
+	// Strip link definitions, store in hashes.
+	text = _StripLinkDefinitions(text);
+
+	text = _RunBlockGamut(text);
+
+	text = _UnescapeSpecialChars(text);
+
+	// attacklab: Restore dollar signs
+	text = text.replace(/~D/g,"$$");
+
+	// attacklab: Restore tildes
+	text = text.replace(/~T/g,"~");
+
+	return text;
+};
+
+
+var _StripLinkDefinitions = function(text) {
+//
+// Strips link definitions from text, stores the URLs and titles in
+// hash references.
+//
+
+	// Link defs are in the form: ^[id]: url "optional title"
+
+	/*
+		var text = text.replace(/
+				^[ ]{0,3}\[(.+)\]:  // id = $1  attacklab: g_tab_width - 1
+				  [ \t]*
+				  \n?				// maybe *one* newline
+				  [ \t]*
+				<?(\S+?)>?			// url = $2
+				  [ \t]*
+				  \n?				// maybe one newline
+				  [ \t]*
+				(?:
+				  (\n*)				// any lines skipped = $3 attacklab: lookbehind removed
+				  ["(]
+				  (.+?)				// title = $4
+				  [")]
+				  [ \t]*
+				)?					// title is optional
+				(?:\n+|$)
+			  /gm,
+			  function(){...});
+	*/
+	var text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,
+		function (wholeMatch,m1,m2,m3,m4) {
+			m1 = m1.toLowerCase();
+			g_urls[m1] = _EncodeAmpsAndAngles(m2);  // Link IDs are case-insensitive
+			if (m3) {
+				// Oops, found blank lines, so it's not a title.
+				// Put back the parenthetical statement we stole.
+				return m3+m4;
+			} else if (m4) {
+				g_titles[m1] = m4.replace(/"/g,"&quot;");
+			}
+
+			// Completely remove the definition from the text
+			return "";
+		}
+	);
+
+	return text;
+}
+
+
+var _HashHTMLBlocks = function(text) {
+	// attacklab: Double up blank lines to reduce lookaround
+	text = text.replace(/\n/g,"\n\n");
+
+	// Hashify HTML blocks:
+	// We only want to do this for block-level HTML tags, such as headers,
+	// lists, and tables. That's because we still want to wrap <p>s around
+	// "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+	// phrase emphasis, and spans. The list of tags we're looking for is
+	// hard-coded:
+	var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del|style|section|header|footer|nav|article|aside";
+	var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside";
+
+	// First, look for nested blocks, e.g.:
+	//   <div>
+	//     <div>
+	//     tags for inner block must be indented.
+	//     </div>
+	//   </div>
+	//
+	// The outermost tags must start at the left margin for this to match, and
+	// the inner nested divs must be indented.
+	// We need to do this before the next, more liberal match, because the next
+	// match will start at the first `<div>` and stop at the first `</div>`.
+
+	// attacklab: This regex can be expensive when it fails.
+	/*
+		var text = text.replace(/
+		(						// save in $1
+			^					// start of line  (with /m)
+			<($block_tags_a)	// start tag = $2
+			\b					// word break
+								// attacklab: hack around khtml/pcre bug...
+			[^\r]*?\n			// any number of lines, minimally matching
+			</\2>				// the matching end tag
+			[ \t]*				// trailing spaces/tabs
+			(?=\n+)				// followed by a newline
+		)						// attacklab: there are sentinel newlines at end of document
+		/gm,function(){...}};
+	*/
+	text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,hashElement);
+
+	//
+	// Now match more liberally, simply from `\n<tag>` to `</tag>\n`
+	//
+
+	/*
+		var text = text.replace(/
+		(						// save in $1
+			^					// start of line  (with /m)
+			<($block_tags_b)	// start tag = $2
+			\b					// word break
+								// attacklab: hack around khtml/pcre bug...
+			[^\r]*?				// any number of lines, minimally matching
+			.*</\2>				// the matching end tag
+			[ \t]*				// trailing spaces/tabs
+			(?=\n+)				// followed by a newline
+		)						// attacklab: there are sentinel newlines at end of document
+		/gm,function(){...}};
+	*/
+	text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
+
+	// Special case just for <hr />. It was easier to make a special case than
+	// to make the other regex more complicated.
+
+	/*
+		text = text.replace(/
+		(						// save in $1
+			\n\n				// Starting after a blank line
+			[ ]{0,3}
+			(<(hr)				// start tag = $2
+			\b					// word break
+			([^<>])*?			//
+			\/?>)				// the matching end tag
+			[ \t]*
+			(?=\n{2,})			// followed by a blank line
+		)
+		/g,hashElement);
+	*/
+	text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,hashElement);
+
+	// Special case for standalone HTML comments:
+
+	/*
+		text = text.replace(/
+		(						// save in $1
+			\n\n				// Starting after a blank line
+			[ ]{0,3}			// attacklab: g_tab_width - 1
+			<!
+			(--[^\r]*?--\s*)+
+			>
+			[ \t]*
+			(?=\n{2,})			// followed by a blank line
+		)
+		/g,hashElement);
+	*/
+	text = text.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,hashElement);
+
+	// PHP and ASP-style processor instructions (<?...?> and <%...%>)
+
+	/*
+		text = text.replace(/
+		(?:
+			\n\n				// Starting after a blank line
+		)
+		(						// save in $1
+			[ ]{0,3}			// attacklab: g_tab_width - 1
+			(?:
+				<([?%])			// $2
+				[^\r]*?
+				\2>
+			)
+			[ \t]*
+			(?=\n{2,})			// followed by a blank line
+		)
+		/g,hashElement);
+	*/
+	text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,hashElement);
+
+	// attacklab: Undo double lines (see comment at top of this function)
+	text = text.replace(/\n\n/g,"\n");
+	return text;
+}
+
+var hashElement = function(wholeMatch,m1) {
+	var blockText = m1;
+
+	// Undo double lines
+	blockText = blockText.replace(/\n\n/g,"\n");
+	blockText = blockText.replace(/^\n/,"");
+
+	// strip trailing blank lines
+	blockText = blockText.replace(/\n+$/g,"");
+
+	// Replace the element text with a marker ("~KxK" where x is its key)
+	blockText = "\n\n~K" + (g_html_blocks.push(blockText)-1) + "K\n\n";
+
+	return blockText;
+};
+
+var _RunBlockGamut = function(text) {
+//
+// These are all the transformations that form block-level
+// tags like paragraphs, headers, and list items.
+//
+	text = _DoHeaders(text);
+
+	// Do Horizontal Rules:
+	var key = hashBlock("<hr />");
+	text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key);
+	text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key);
+	text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key);
+
+	text = _DoLists(text);
+	text = _DoCodeBlocks(text);
+	text = _DoBlockQuotes(text);
+
+	// We already ran _HashHTMLBlocks() before, in Markdown(), but that
+	// was to escape raw HTML in the original Markdown source. This time,
+	// we're escaping the markup we've just created, so that we don't wrap
+	// <p> tags around block-level tags.
+	text = _HashHTMLBlocks(text);
+	text = _FormParagraphs(text);
+
+	return text;
+};
+
+
+var _RunSpanGamut = function(text) {
+//
+// These are all the transformations that occur *within* block-level
+// tags like paragraphs, headers, and list items.
+//
+
+	text = _DoCodeSpans(text);
+	text = _EscapeSpecialCharsWithinTagAttributes(text);
+	text = _EncodeBackslashEscapes(text);
+
+	// Process anchor and image tags. Images must come first,
+	// because ![foo][f] looks like an anchor.
+	text = _DoImages(text);
+	text = _DoAnchors(text);
+
+	// Make links out of things like `<http://example.com/>`
+	// Must come after _DoAnchors(), because you can use < and >
+	// delimiters in inline links like [this](<url>).
+	text = _DoAutoLinks(text);
+	text = _EncodeAmpsAndAngles(text);
+	text = _DoItalicsAndBold(text);
+
+	// Do hard breaks:
+	text = text.replace(/  +\n/g," <br />\n");
+
+	return text;
+}
+
+var _EscapeSpecialCharsWithinTagAttributes = function(text) {
+//
+// Within tags -- meaning between < and > -- encode [\ ` * _] so they
+// don't conflict with their use in Markdown for code, italics and strong.
+//
+
+	// Build a regex to find HTML tags and comments.  See Friedl's
+	// "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
+	var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;
+
+	text = text.replace(regex, function(wholeMatch) {
+		var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g,"$1`");
+		tag = escapeCharacters(tag,"\\`*_");
+		return tag;
+	});
+
+	return text;
+}
+
+var _DoAnchors = function(text) {
+//
+// Turn Markdown link shortcuts into XHTML <a> tags.
+//
+	//
+	// First, handle reference-style links: [link text] [id]
+	//
+
+	/*
+		text = text.replace(/
+		(							// wrap whole match in $1
+			\[
+			(
+				(?:
+					\[[^\]]*\]		// allow brackets nested one level
+					|
+					[^\[]			// or anything else
+				)*
+			)
+			\]
+
+			[ ]?					// one optional space
+			(?:\n[ ]*)?				// one optional newline followed by spaces
+
+			\[
+			(.*?)					// id = $3
+			\]
+		)()()()()					// pad remaining backreferences
+		/g,_DoAnchors_callback);
+	*/
+	text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeAnchorTag);
+
+	//
+	// Next, inline-style links: [link text](url "optional title")
+	//
+
+	/*
+		text = text.replace(/
+			(						// wrap whole match in $1
+				\[
+				(
+					(?:
+						\[[^\]]*\]	// allow brackets nested one level
+					|
+					[^\[\]]			// or anything else
+				)
+			)
+			\]
+			\(						// literal paren
+			[ \t]*
+			()						// no id, so leave $3 empty
+			<?(.*?)>?				// href = $4
+			[ \t]*
+			(						// $5
+				(['"])				// quote char = $6
+				(.*?)				// Title = $7
+				\6					// matching quote
+				[ \t]*				// ignore any spaces/tabs between closing quote and )
+			)?						// title is optional
+			\)
+		)
+		/g,writeAnchorTag);
+	*/
+	text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
+
+	//
+	// Last, handle reference-style shortcuts: [link text]
+	// These must come last in case you've also got [link test][1]
+	// or [link test](/foo)
+	//
+
+	/*
+		text = text.replace(/
+		(		 					// wrap whole match in $1
+			\[
+			([^\[\]]+)				// link text = $2; can't contain '[' or ']'
+			\]
+		)()()()()()					// pad rest of backreferences
+		/g, writeAnchorTag);
+	*/
+	text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
+
+	return text;
+}
+
+var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
+	if (m7 == undefined) m7 = "";
+	var whole_match = m1;
+	var link_text   = m2;
+	var link_id	 = m3.toLowerCase();
+	var url		= m4;
+	var title	= m7;
+
+	if (url == "") {
+		if (link_id == "") {
+			// lower-case and turn embedded newlines into spaces
+			link_id = link_text.toLowerCase().replace(/ ?\n/g," ");
+		}
+		url = "#"+link_id;
+
+		if (g_urls[link_id] != undefined) {
+			url = g_urls[link_id];
+			if (g_titles[link_id] != undefined) {
+				title = g_titles[link_id];
+			}
+		}
+		else {
+			if (whole_match.search(/\(\s*\)$/m)>-1) {
+				// Special case for explicit empty url
+				url = "";
+			} else {
+				return whole_match;
+			}
+		}
+	}
+
+	url = escapeCharacters(url,"*_");
+	var result = "<a href=\"" + url + "\"";
+
+	if (title != "") {
+		title = title.replace(/"/g,"&quot;");
+		title = escapeCharacters(title,"*_");
+		result +=  " title=\"" + title + "\"";
+	}
+
+	result += ">" + link_text + "</a>";
+
+	return result;
+}
+
+
+var _DoImages = function(text) {
+//
+// Turn Markdown image shortcuts into <img> tags.
+//
+
+	//
+	// First, handle reference-style labeled images: ![alt text][id]
+	//
+
+	/*
+		text = text.replace(/
+		(						// wrap whole match in $1
+			!\[
+			(.*?)				// alt text = $2
+			\]
+
+			[ ]?				// one optional space
+			(?:\n[ ]*)?			// one optional newline followed by spaces
+
+			\[
+			(.*?)				// id = $3
+			\]
+		)()()()()				// pad rest of backreferences
+		/g,writeImageTag);
+	*/
+	text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeImageTag);
+
+	//
+	// Next, handle inline images:  ![alt text](url "optional title")
+	// Don't forget: encode * and _
+
+	/*
+		text = text.replace(/
+		(						// wrap whole match in $1
+			!\[
+			(.*?)				// alt text = $2
+			\]
+			\s?					// One optional whitespace character
+			\(					// literal paren
+			[ \t]*
+			()					// no id, so leave $3 empty
+			<?(\S+?)>?			// src url = $4
+			[ \t]*
+			(					// $5
+				(['"])			// quote char = $6
+				(.*?)			// title = $7
+				\6				// matching quote
+				[ \t]*
+			)?					// title is optional
+		\)
+		)
+		/g,writeImageTag);
+	*/
+	text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeImageTag);
+
+	return text;
+}
+
+var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
+	var whole_match = m1;
+	var alt_text   = m2;
+	var link_id	 = m3.toLowerCase();
+	var url		= m4;
+	var title	= m7;
+
+	if (!title) title = "";
+
+	if (url == "") {
+		if (link_id == "") {
+			// lower-case and turn embedded newlines into spaces
+			link_id = alt_text.toLowerCase().replace(/ ?\n/g," ");
+		}
+		url = "#"+link_id;
+
+		if (g_urls[link_id] != undefined) {
+			url = g_urls[link_id];
+			if (g_titles[link_id] != undefined) {
+				title = g_titles[link_id];
+			}
+		}
+		else {
+			return whole_match;
+		}
+	}
+
+	alt_text = alt_text.replace(/"/g,"&quot;");
+	url = escapeCharacters(url,"*_");
+	var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
+
+	// attacklab: Markdown.pl adds empty title attributes to images.
+	// Replicate this bug.
+
+	//if (title != "") {
+		title = title.replace(/"/g,"&quot;");
+		title = escapeCharacters(title,"*_");
+		result +=  " title=\"" + title + "\"";
+	//}
+
+	result += " />";
+
+	return result;
+}
+
+
+var _DoHeaders = function(text) {
+
+	// Setext-style headers:
+	//	Header 1
+	//	========
+	//
+	//	Header 2
+	//	--------
+	//
+	text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
+		function(wholeMatch,m1){return hashBlock('<h1 id="' + headerId(m1) + '">' + _RunSpanGamut(m1) + "</h1>");});
+
+	text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
+		function(matchFound,m1){return hashBlock('<h2 id="' + headerId(m1) + '">' + _RunSpanGamut(m1) + "</h2>");});
+
+	// atx-style headers:
+	//  # Header 1
+	//  ## Header 2
+	//  ## Header 2 with closing hashes ##
+	//  ...
+	//  ###### Header 6
+	//
+
+	/*
+		text = text.replace(/
+			^(\#{1,6})				// $1 = string of #'s
+			[ \t]*
+			(.+?)					// $2 = Header text
+			[ \t]*
+			\#*						// optional closing #'s (not counted)
+			\n+
+		/gm, function() {...});
+	*/
+
+	text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
+		function(wholeMatch,m1,m2) {
+			var h_level = m1.length;
+			return hashBlock("<h" + h_level + ' id="' + headerId(m2) + '">' + _RunSpanGamut(m2) + "</h" + h_level + ">");
+		});
+
+	function headerId(m) {
+		return m.replace(/[^\w]/g, '').toLowerCase();
+	}
+	return text;
+}
+
+// This declaration keeps Dojo compressor from outputting garbage:
+var _ProcessListItems;
+
+var _DoLists = function(text) {
+//
+// Form HTML ordered (numbered) and unordered (bulleted) lists.
+//
+
+	// attacklab: add sentinel to hack around khtml/safari bug:
+	// http://bugs.webkit.org/show_bug.cgi?id=11231
+	text += "~0";
+
+	// Re-usable pattern to match any entirel ul or ol list:
+
+	/*
+		var whole_list = /
+		(									// $1 = whole list
+			(								// $2
+				[ ]{0,3}					// attacklab: g_tab_width - 1
+				([*+-]|\d+[.])				// $3 = first list item marker
+				[ \t]+
+			)
+			[^\r]+?
+			(								// $4
+				~0							// sentinel for workaround; should be $
+			|
+				\n{2,}
+				(?=\S)
+				(?!							// Negative lookahead for another list item marker
+					[ \t]*
+					(?:[*+-]|\d+[.])[ \t]+
+				)
+			)
+		)/g
+	*/
+	var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
+
+	if (g_list_level) {
+		text = text.replace(whole_list,function(wholeMatch,m1,m2) {
+			var list = m1;
+			var list_type = (m2.search(/[*+-]/g)>-1) ? "ul" : "ol";
+
+			// Turn double returns into triple returns, so that we can make a
+			// paragraph for the last item in a list, if necessary:
+			list = list.replace(/\n{2,}/g,"\n\n\n");;
+			var result = _ProcessListItems(list);
+
+			// Trim any trailing whitespace, to put the closing `</$list_type>`
+			// up on the preceding line, to get it past the current stupid
+			// HTML block parser. This is a hack to work around the terrible
+			// hack that is the HTML block parser.
+			result = result.replace(/\s+$/,"");
+			result = "<"+list_type+">" + result + "</"+list_type+">\n";
+			return result;
+		});
+	} else {
+		whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
+		text = text.replace(whole_list,function(wholeMatch,m1,m2,m3) {
+			var runup = m1;
+			var list = m2;
+
+			var list_type = (m3.search(/[*+-]/g)>-1) ? "ul" : "ol";
+			// Turn double returns into triple returns, so that we can make a
+			// paragraph for the last item in a list, if necessary:
+			var list = list.replace(/\n{2,}/g,"\n\n\n");;
+			var result = _ProcessListItems(list);
+			result = runup + "<"+list_type+">\n" + result + "</"+list_type+">\n";
+			return result;
+		});
+	}
+
+	// attacklab: strip sentinel
+	text = text.replace(/~0/,"");
+
+	return text;
+}
+
+_ProcessListItems = function(list_str) {
+//
+//  Process the contents of a single ordered or unordered list, splitting it
+//  into individual list items.
+//
+	// The $g_list_level global keeps track of when we're inside a list.
+	// Each time we enter a list, we increment it; when we leave a list,
+	// we decrement. If it's zero, we're not in a list anymore.
+	//
+	// We do this because when we're not inside a list, we want to treat
+	// something like this:
+	//
+	//    I recommend upgrading to version
+	//    8. Oops, now this line is treated
+	//    as a sub-list.
+	//
+	// As a single paragraph, despite the fact that the second line starts
+	// with a digit-period-space sequence.
+	//
+	// Whereas when we're inside a list (or sub-list), that line will be
+	// treated as the start of a sub-list. What a kludge, huh? This is
+	// an aspect of Markdown's syntax that's hard to parse perfectly
+	// without resorting to mind-reading. Perhaps the solution is to
+	// change the syntax rules such that sub-lists must start with a
+	// starting cardinal number; e.g. "1." or "a.".
+
+	g_list_level++;
+
+	// trim trailing blank lines:
+	list_str = list_str.replace(/\n{2,}$/,"\n");
+
+	// attacklab: add sentinel to emulate \z
+	list_str += "~0";
+
+	/*
+		list_str = list_str.replace(/
+			(\n)?							// leading line = $1
+			(^[ \t]*)						// leading whitespace = $2
+			([*+-]|\d+[.]) [ \t]+			// list marker = $3
+			([^\r]+?						// list item text   = $4
+			(\n{1,2}))
+			(?= \n* (~0 | \2 ([*+-]|\d+[.]) [ \t]+))
+		/gm, function(){...});
+	*/
+	list_str = list_str.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
+		function(wholeMatch,m1,m2,m3,m4){
+			var item = m4;
+			var leading_line = m1;
+			var leading_space = m2;
+
+			if (leading_line || (item.search(/\n{2,}/)>-1)) {
+				item = _RunBlockGamut(_Outdent(item));
+			}
+			else {
+				// Recursion for sub-lists:
+				item = _DoLists(_Outdent(item));
+				item = item.replace(/\n$/,""); // chomp(item)
+				item = _RunSpanGamut(item);
+			}
+
+			return  "<li>" + item + "</li>\n";
+		}
+	);
+
+	// attacklab: strip sentinel
+	list_str = list_str.replace(/~0/g,"");
+
+	g_list_level--;
+	return list_str;
+}
+
+
+var _DoCodeBlocks = function(text) {
+//
+//  Process Markdown `<pre><code>` blocks.
+//
+
+	/*
+		text = text.replace(text,
+			/(?:\n\n|^)
+			(								// $1 = the code block -- one or more lines, starting with a space/tab
+				(?:
+					(?:[ ]{4}|\t)			// Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
+					.*\n+
+				)+
+			)
+			(\n*[ ]{0,3}[^ \t\n]|(?=~0))	// attacklab: g_tab_width
+		/g,function(){...});
+	*/
+
+	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
+	text += "~0";
+
+	text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
+		function(wholeMatch,m1,m2) {
+			var codeblock = m1;
+			var nextChar = m2;
+
+			codeblock = _EncodeCode( _Outdent(codeblock));
+			codeblock = _Detab(codeblock);
+			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
+			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
+
+			codeblock = "<pre><code>" + codeblock + "\n</code></pre>";
+
+			return hashBlock(codeblock) + nextChar;
+		}
+	);
+
+	// attacklab: strip sentinel
+	text = text.replace(/~0/,"");
+
+	return text;
+};
+
+var _DoGithubCodeBlocks = function(text) {
+//
+//  Process Github-style code blocks
+//  Example:
+//  ```ruby
+//  def hello_world(x)
+//    puts "Hello, #{x}"
+//  end
+//  ```
+//
+
+
+	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
+	text += "~0";
+
+	text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g,
+		function(wholeMatch,m1,m2) {
+			var language = m1;
+			var codeblock = m2;
+
+			codeblock = _EncodeCode(codeblock);
+			codeblock = _Detab(codeblock);
+			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
+			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
+
+			codeblock = "<pre><code" + (language ? " class=\"" + language + '"' : "") + ">" + codeblock + "\n</code></pre>";
+
+			return hashBlock(codeblock);
+		}
+	);
+
+	// attacklab: strip sentinel
+	text = text.replace(/~0/,"");
+
+	return text;
+}
+
+var hashBlock = function(text) {
+	text = text.replace(/(^\n+|\n+$)/g,"");
+	return "\n\n~K" + (g_html_blocks.push(text)-1) + "K\n\n";
+}
+
+var _DoCodeSpans = function(text) {
+//
+//   *  Backtick quotes are used for <code></code> spans.
+//
+//   *  You can use multiple backticks as the delimiters if you want to
+//	 include literal backticks in the code span. So, this input:
+//
+//		 Just type ``foo `bar` baz`` at the prompt.
+//
+//	   Will translate to:
+//
+//		 <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
+//
+//	There's no arbitrary limit to the number of backticks you
+//	can use as delimters. If you need three consecutive backticks
+//	in your code, use four for delimiters, etc.
+//
+//  *  You can use spaces to get literal backticks at the edges:
+//
+//		 ... type `` `bar` `` ...
+//
+//	   Turns to:
+//
+//		 ... type <code>`bar`</code> ...
+//
+
+	/*
+		text = text.replace(/
+			(^|[^\\])					// Character before opening ` can't be a backslash
+			(`+)						// $2 = Opening run of `
+			(							// $3 = The code block
+				[^\r]*?
+				[^`]					// attacklab: work around lack of lookbehind
+			)
+			\2							// Matching closer
+			(?!`)
+		/gm, function(){...});
+	*/
+
+	text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
+		function(wholeMatch,m1,m2,m3,m4) {
+			var c = m3;
+			c = c.replace(/^([ \t]*)/g,"");	// leading whitespace
+			c = c.replace(/[ \t]*$/g,"");	// trailing whitespace
+			c = _EncodeCode(c);
+			return m1+"<code>"+c+"</code>";
+		});
+
+	return text;
+}
+
+var _EncodeCode = function(text) {
+//
+// Encode/escape certain characters inside Markdown code runs.
+// The point is that in code, these characters are literals,
+// and lose their special Markdown meanings.
+//
+	// Encode all ampersands; HTML entities are not
+	// entities within a Markdown code span.
+	text = text.replace(/&/g,"&amp;");
+
+	// Do the angle bracket song and dance:
+	text = text.replace(/</g,"&lt;");
+	text = text.replace(/>/g,"&gt;");
+
+	// Now, escape characters that are magic in Markdown:
+	text = escapeCharacters(text,"\*_{}[]\\",false);
+
+// jj the line above breaks this:
+//---
+
+//* Item
+
+//   1. Subitem
+
+//            special char: *
+//---
+
+	return text;
+}
+
+
+var _DoItalicsAndBold = function(text) {
+
+	// <strong> must go first:
+	text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
+		"<strong>$2</strong>");
+
+	text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,
+		"<em>$2</em>");
+
+	return text;
+}
+
+
+var _DoBlockQuotes = function(text) {
+
+	/*
+		text = text.replace(/
+		(								// Wrap whole match in $1
+			(
+				^[ \t]*>[ \t]?			// '>' at the start of a line
+				.+\n					// rest of the first line
+				(.+\n)*					// subsequent consecutive lines
+				\n*						// blanks
+			)+
+		)
+		/gm, function(){...});
+	*/
+
+	text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
+		function(wholeMatch,m1) {
+			var bq = m1;
+
+			// attacklab: hack around Konqueror 3.5.4 bug:
+			// "----------bug".replace(/^-/g,"") == "bug"
+
+			bq = bq.replace(/^[ \t]*>[ \t]?/gm,"~0");	// trim one level of quoting
+
+			// attacklab: clean up hack
+			bq = bq.replace(/~0/g,"");
+
+			bq = bq.replace(/^[ \t]+$/gm,"");		// trim whitespace-only lines
+			bq = _RunBlockGamut(bq);				// recurse
+
+			bq = bq.replace(/(^|\n)/g,"$1  ");
+			// These leading spaces screw with <pre> content, so we need to fix that:
+			bq = bq.replace(
+					/(\s*<pre>[^\r]+?<\/pre>)/gm,
+				function(wholeMatch,m1) {
+					var pre = m1;
+					// attacklab: hack around Konqueror 3.5.4 bug:
+					pre = pre.replace(/^  /mg,"~0");
+					pre = pre.replace(/~0/g,"");
+					return pre;
+				});
+
+			return hashBlock("<blockquote>\n" + bq + "\n</blockquote>");
+		});
+	return text;
+}
+
+
+var _FormParagraphs = function(text) {
+//
+//  Params:
+//    $text - string to process with html <p> tags
+//
+
+	// Strip leading and trailing lines:
+	text = text.replace(/^\n+/g,"");
+	text = text.replace(/\n+$/g,"");
+
+	var grafs = text.split(/\n{2,}/g);
+	var grafsOut = new Array();
+
+	//
+	// Wrap <p> tags.
+	//
+	var end = grafs.length;
+	for (var i=0; i<end; i++) {
+		var str = grafs[i];
+
+		// if this is an HTML marker, copy it
+		if (str.search(/~K(\d+)K/g) >= 0) {
+			grafsOut.push(str);
+		}
+		else if (str.search(/\S/) >= 0) {
+			str = _RunSpanGamut(str);
+			str = str.replace(/^([ \t]*)/g,"<p>");
+			str += "</p>"
+			grafsOut.push(str);
+		}
+
+	}
+
+	//
+	// Unhashify HTML blocks
+	//
+	end = grafsOut.length;
+	for (var i=0; i<end; i++) {
+		// if this is a marker for an html block...
+		while (grafsOut[i].search(/~K(\d+)K/) >= 0) {
+			var blockText = g_html_blocks[RegExp.$1];
+			blockText = blockText.replace(/\$/g,"$$$$"); // Escape any dollar signs
+			grafsOut[i] = grafsOut[i].replace(/~K\d+K/,blockText);
+		}
+	}
+
+	return grafsOut.join("\n\n");
+}
+
+
+var _EncodeAmpsAndAngles = function(text) {
+// Smart processing for ampersands and angle brackets that need to be encoded.
+
+	// Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
+	//   http://bumppo.net/projects/amputator/
+	text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&amp;");
+
+	// Encode naked <'s
+	text = text.replace(/<(?![a-z\/?\$!])/gi,"&lt;");
+
+	return text;
+}
+
+
+var _EncodeBackslashEscapes = function(text) {
+//
+//   Parameter:  String.
+//   Returns:	The string, with after processing the following backslash
+//			   escape sequences.
+//
+
+	// attacklab: The polite way to do this is with the new
+	// escapeCharacters() function:
+	//
+	// 	text = escapeCharacters(text,"\\",true);
+	// 	text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
+	//
+	// ...but we're sidestepping its use of the (slow) RegExp constructor
+	// as an optimization for Firefox.  This function gets called a LOT.
+
+	text = text.replace(/\\(\\)/g,escapeCharacters_callback);
+	text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g,escapeCharacters_callback);
+	return text;
+}
+
+
+var _DoAutoLinks = function(text) {
+
+	text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
+
+	// Email addresses: <address@domain.foo>
+
+	/*
+		text = text.replace(/
+			<
+			(?:mailto:)?
+			(
+				[-.\w]+
+				\@
+				[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
+			)
+			>
+		/gi, _DoAutoLinks_callback());
+	*/
+	text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
+		function(wholeMatch,m1) {
+			return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
+		}
+	);
+
+	return text;
+}
+
+
+var _EncodeEmailAddress = function(addr) {
+//
+//  Input: an email address, e.g. "foo@example.com"
+//
+//  Output: the email address as a mailto link, with each character
+//	of the address encoded as either a decimal or hex entity, in
+//	the hopes of foiling most address harvesting spam bots. E.g.:
+//
+//	<a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
+//	   x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
+//	   &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
+//
+//  Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
+//  mailing list: <http://tinyurl.com/yu7ue>
+//
+
+	// attacklab: why can't javascript speak hex?
+	function char2hex(ch) {
+		var hexDigits = '0123456789ABCDEF';
+		var dec = ch.charCodeAt(0);
+		return(hexDigits.charAt(dec>>4) + hexDigits.charAt(dec&15));
+	}
+
+	var encode = [
+		function(ch){return "&#"+ch.charCodeAt(0)+";";},
+		function(ch){return "&#x"+char2hex(ch)+";";},
+		function(ch){return ch;}
+	];
+
+	addr = "mailto:" + addr;
+
+	addr = addr.replace(/./g, function(ch) {
+		if (ch == "@") {
+		   	// this *must* be encoded. I insist.
+			ch = encode[Math.floor(Math.random()*2)](ch);
+		} else if (ch !=":") {
+			// leave ':' alone (to spot mailto: later)
+			var r = Math.random();
+			// roughly 10% raw, 45% hex, 45% dec
+			ch =  (
+					r > .9  ?	encode[2](ch)   :
+					r > .45 ?	encode[1](ch)   :
+								encode[0](ch)
+				);
+		}
+		return ch;
+	});
+
+	addr = "<a href=\"" + addr + "\">" + addr + "</a>";
+	addr = addr.replace(/">.+:/g,"\">"); // strip the mailto: from the visible part
+
+	return addr;
+}
+
+
+var _UnescapeSpecialChars = function(text) {
+//
+// Swap back in all the special characters we've hidden.
+//
+	text = text.replace(/~E(\d+)E/g,
+		function(wholeMatch,m1) {
+			var charCodeToReplace = parseInt(m1);
+			return String.fromCharCode(charCodeToReplace);
+		}
+	);
+	return text;
+}
+
+
+var _Outdent = function(text) {
+//
+// Remove one level of line-leading tabs or spaces
+//
+
+	// attacklab: hack around Konqueror 3.5.4 bug:
+	// "----------bug".replace(/^-/g,"") == "bug"
+
+	text = text.replace(/^(\t|[ ]{1,4})/gm,"~0"); // attacklab: g_tab_width
+
+	// attacklab: clean up hack
+	text = text.replace(/~0/g,"")
+
+	return text;
+}
+
+var _Detab = function(text) {
+// attacklab: Detab's completely rewritten for speed.
+// In perl we could fix it by anchoring the regexp with \G.
+// In javascript we're less fortunate.
+
+	// expand first n-1 tabs
+	text = text.replace(/\t(?=\t)/g,"    "); // attacklab: g_tab_width
+
+	// replace the nth with two sentinels
+	text = text.replace(/\t/g,"~A~B");
+
+	// use the sentinel to anchor our regex so it doesn't explode
+	text = text.replace(/~B(.+?)~A/g,
+		function(wholeMatch,m1,m2) {
+			var leadingText = m1;
+			var numSpaces = 4 - leadingText.length % 4;  // attacklab: g_tab_width
+
+			// there *must* be a better way to do this:
+			for (var i=0; i<numSpaces; i++) leadingText+=" ";
+
+			return leadingText;
+		}
+	);
+
+	// clean up sentinels
+	text = text.replace(/~A/g,"    ");  // attacklab: g_tab_width
+	text = text.replace(/~B/g,"");
+
+	return text;
+}
+
+
+//
+//  attacklab: Utility functions
+//
+
+
+var escapeCharacters = function(text, charsToEscape, afterBackslash) {
+	// First we have to escape the escape characters so that
+	// we can build a character class out of them
+	var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g,"\\$1") + "])";
+
+	if (afterBackslash) {
+		regexString = "\\\\" + regexString;
+	}
+
+	var regex = new RegExp(regexString,"g");
+	text = text.replace(regex,escapeCharacters_callback);
+
+	return text;
+}
+
+
+var escapeCharacters_callback = function(wholeMatch,m1) {
+	var charCodeToEscape = m1.charCodeAt(0);
+	return "~E"+charCodeToEscape+"E";
+}
+
+} // end of Showdown.converter
+
+// export
+if (typeof module !== 'undefined') module.exports = Showdown;
diff --git a/docs/slides/plpv14/_support/reveal/package.json b/docs/slides/plpv14/_support/reveal/package.json
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/package.json
@@ -0,0 +1,20 @@
+{
+	"author": "Hakim El Hattab",
+	"name": "reveal.js",
+	"description": "HTML5 Slideware with Presenter Notes",
+	"version": "1.5.0",
+	"repository": {
+		"type": "git",
+		"url": "git://github.com/hakimel/reveal.js.git"
+	},
+	"engines": {
+		"node": "~0.6.8"
+	},
+	"dependencies": {
+		"underscore" : "1.3.3",
+		"express" : "2.5.9",
+		"socket.io" : "0.9.6",
+		"mustache" : "0.4.0"
+	},
+	"devDependencies": {}
+}
diff --git a/docs/slides/plpv14/_support/reveal/plugin/speakernotes/client.js b/docs/slides/plpv14/_support/reveal/plugin/speakernotes/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/plugin/speakernotes/client.js
@@ -0,0 +1,35 @@
+(function() {
+	// don't emit events from inside the previews themselves
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var socket = io.connect(window.location.origin);
+	var socketId = Math.random().toString().slice(2);
+	
+	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
+
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		var nextindexh;
+		var nextindexv;
+		var slideElement = event.currentSlide;
+
+		if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+			nextindexh = event.indexh;
+			nextindexv = event.indexv + 1;
+		} else {
+			nextindexh = event.indexh + 1;
+			nextindexv = 0;
+		}
+
+		var notes = slideElement.querySelector('aside.notes');
+		var slideData = {
+			notes : notes ? notes.innerHTML : '',
+			indexh : event.indexh,
+			indexv : event.indexv,
+			nextindexh : nextindexh,
+			nextindexv : nextindexv,
+			socketId : socketId
+		};
+
+		socket.emit('slidechanged', slideData);
+	} );
+}());
diff --git a/docs/slides/plpv14/_support/reveal/plugin/speakernotes/index.js b/docs/slides/plpv14/_support/reveal/plugin/speakernotes/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/plugin/speakernotes/index.js
@@ -0,0 +1,55 @@
+var express   = require('express');
+var fs        = require('fs');
+var io        = require('socket.io');
+var _         = require('underscore');
+var Mustache  = require('mustache');
+
+var app       = express.createServer();
+var staticDir = express.static;
+
+io            = io.listen(app);
+
+var opts = {
+	port :      1947,
+	baseDir :   __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		socket.broadcast.emit('slidedata', slideData);
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/notes/:socketId", function(req, res) {
+
+	fs.readFile(opts.baseDir + 'plugin/speakernotes/notes.html', function(err, data) {
+		res.send(Mustache.to_html(data.toString(), {
+			socketId : req.params.socketId
+		}));
+	});
+	// fs.createReadStream(opts.baseDir + 'speakernotes/notes.html').pipe(res);
+});
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m', 
+	green = '\033[32m', 
+	reset = '\033[0m';
+
+var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
+
+console.log( brown + "reveal.js - Speaker Notes" + reset );
+console.log( "1. Open the slides at " + green + slidesLocation + reset );
+console.log( "2. Click on the link your JS console to go to the notes page" );
+console.log( "3. Advance through your slides and your notes will advance automatically" );
diff --git a/docs/slides/plpv14/_support/reveal/plugin/speakernotes/notes.html b/docs/slides/plpv14/_support/reveal/plugin/speakernotes/notes.html
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/reveal/plugin/speakernotes/notes.html
@@ -0,0 +1,111 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Slide Notes</title>
+
+		<style>
+			body {
+				font-family: Helvetica;
+			}
+
+			#notes {
+				float: left;
+				font-size: 18px;
+				width: 640px;
+				margin-top: 10px;
+			}
+
+			#wrap-current-slide {
+				width: 400px;
+				height: 320px;
+				float: left;
+				overflow: hidden;
+			}
+
+			#current-slide {
+				width: 800px;
+				height: 600px;
+				border: none;
+				-moz-transform: scale(0.5);
+				-moz-transform-origin: 0 0;
+				-o-transform: scale(0.5);
+				-o-transform-origin: 0 0;
+				-webkit-transform: scale(0.5);
+				-webkit-transform-origin: 0 0;
+			}
+
+			#wrap-next-slide {
+				width: 320px;
+				height: 256px;
+				float: left;
+				margin: 0 0 0 10px;
+				overflow: hidden;
+			}
+
+			#next-slide {
+				width: 800px;
+				height: 600px;
+				border: none;
+				-moz-transform: scale(0.25);
+				-moz-transform-origin: 0 0;
+				-o-transform: scale(0.25);
+				-o-transform-origin: 0 0;
+				-webkit-transform: scale(0.25);
+				-webkit-transform-origin: 0 0;
+			}
+
+			.slides {
+				position: relative;
+				margin-bottom: 10px;
+				border: 1px solid black;
+				border-radius: 2px;
+				background: rgb(28, 30, 32);
+			}
+
+			.slides span {
+				position: absolute;
+				top: 3px;
+				left: 3px;
+				font-weight: bold;
+				font-size: 14px;
+				color: rgba( 255, 255, 255, 0.9 );
+			}
+		</style>
+	</head>
+
+	<body>
+
+		<div id="wrap-current-slide" class="slides">
+			<iframe src="/?receiver" width="800" height="600" id="current-slide"></iframe>
+		</div>
+
+		<div id="notes"></div>
+
+		<div id="wrap-next-slide" class="slides">
+			<iframe src="/?receiver" width="640" height="512" id="next-slide"></iframe>
+			<span>UPCOMING:</span>
+		</div>
+
+		<script src="/socket.io/socket.io.js"></script>
+
+		<script>
+		var socketId = '{{socketId}}';
+		var socket = io.connect(window.location.origin);
+		var notes = document.getElementById('notes');
+		var currentSlide = document.getElementById('current-slide');
+		var nextSlide = document.getElementById('next-slide');
+
+		socket.on('slidedata', function(data) {
+			// ignore data from sockets that aren't ours
+			if (data.socketId !== socketId) { return; }
+
+			notes.innerHTML = data.notes;
+			currentSlide.contentWindow.Reveal.navigateTo(data.indexh, data.indexv);
+			nextSlide.contentWindow.Reveal.navigateTo(data.nextindexh, data.nextindexv);
+		});
+		</script>
+
+	</body>
+</html>
diff --git a/docs/slides/plpv14/_support/template.reveal b/docs/slides/plpv14/_support/template.reveal
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/_support/template.reveal
@@ -0,0 +1,103 @@
+<!doctype html>  
+<html lang="en">
+	
+<head>
+<meta charset="utf-8">
+
+<title>LiquidHaskell Tutorial</title>
+
+<meta name="description" content="Tutorial Slides">
+<meta name="author" content="Ranjit Jhala">
+
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+
+<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
+
+<link rel="stylesheet" href="$reveal$/css/main.css">
+<link rel="stylesheet" href="$reveal$/css/theme/seminar.css" id="theme">
+<link rel="stylesheet" href="$reveal$/css/liquidhaskell.css">
+
+<!-- For syntax highlighting -->
+<link rel="stylesheet" href="$reveal$/lib/css/zenburn.css">
+
+<script>
+	// If the query includes 'print-pdf' we'll use the PDF print sheet
+	document.write( '<link rel="stylesheet" href="../_support/reveal_01/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
+</script>
+
+<!--[if lt IE 9]>
+<script src="lib/js/html5shiv.js"></script>
+<![endif]-->
+</head>
+<body>
+	
+<div class="reveal">
+<!-- 
+Used to fade in a background when a specific slide state is reached
+-->
+<div class="state-background"></div>
+
+<!-- Slides
+Any section element inside of this "slides" container is displayed as a slide
+-->
+<div class="slides">
+<!-- Pandoc -->
+$if(title)$
+<section class="titlepage">
+<h1 class="title">$title$</h1>
+$for(author)$
+<h2 class="author">$author$</h2>
+$endfor$
+<h3 class="date">$date$</h3>
+</section>
+$endif$
+$body$
+<!-- End Pandoc -->
+
+</div>
+<!-- End Slides -->
+
+<!-- The navigational controls UI -->
+<aside class="controls">
+<a class="left" href="#">&#x25C4;</a>
+<a class="right" href="#">&#x25BA;</a>
+<a class="up" href="#">&#x25B2;</a>
+<a class="down" href="#">&#x25BC;</a>
+</aside>
+
+<!-- Presentation progress bar -->
+<div class="progress"><span></span></div>
+</div>
+
+<!-- Initialize reveal.js :: make settings changes here -->
+<script src="$reveal$/lib/js/head.min.js"></script>
+<script src="$reveal$/js/reveal.js"></script>
+<script>		
+	// Full list of configuration options available here:
+	// https://github.com/hakimel/reveal.js#configuration
+	Reveal.initialize({
+		controls: true,
+		progress: true,
+		history: true,
+		center: false,
+        rollingLinks: false,
+        theme: Reveal.getQueryHash().theme || 'seminar', // available themes are in /css/theme
+		transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/linear(2d)
+
+		// Optional libraries used to extend on reveal.js
+		dependencies: [
+			{ src: '$reveal$/lib/js/highlight.js', async: true, callback: function() { window.hljs.initHighlightingOnLoad(); } },
+			{ src: '$reveal$/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+			{ src: '$reveal$/lib/js/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/lib/js/data-markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+			{ src: '$reveal$/socket.io/socket.io.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+			{ src: '$reveal$/plugin/speakernotes/client.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
+		]
+	});
+</script>
+<!-- Script for LiveReload -->
+<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')
+</script>
+</body>
+</html>
diff --git a/docs/slides/plpv14/hopa/AbstractRefinements.lhs b/docs/slides/plpv14/hopa/AbstractRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/hopa/AbstractRefinements.lhs
@@ -0,0 +1,130 @@
+% Abstract Refinements
+
+Abstract Refinements
+--------------------
+
+\begin{code}
+module AbstractRefinements where
+\end{code}
+
+
+Abstract Refinements
+--------------------
+
+<br>
+
+\begin{code} Consider the following function 
+maxInt     :: Int -> Int -> Int 
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+\begin{code} We can give `maxInt` many (incomparable) refinement types:
+maxInt :: Nat -> Nat -> Nat
+
+maxInt :: Even -> Even -> Even
+
+maxInt :: Prime -> Prime -> Prime
+\end{code}
+
+But **which** is the **right** type?
+
+
+Parametric Invariants 
+---------------------
+
+`maxInt` returns *one of* its two inputs `x` and `y`. 
+
+- **If** *both inputs* satisfy a property  
+
+- **Then** *output* must satisfy that property
+
+This holds, **regardless of what that property was!**
+ 
+- That  is, we can **abstract over refinements**
+
+- Or,  **parameterize** a type over its refinements.
+
+Parametric Invariants
+--------------------- 
+
+\begin{code}
+{-@ maxInt :: forall <p :: Int -> Prop>. Int<p> -> Int<p> -> Int<p> @-}
+maxInt     :: Int -> Int -> Int 
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+
+
+Where
+
+- `Int<p>` is just an abbreviation for `{v:Int | (p v)}`
+
+
+This type states explicitly:
+
+- **For any property** `p`, that is a property of `Int`, 
+
+- `maxInt` takes two **inputs** of which satisfy `p`,
+
+- `maxInt` returns an **output** that satisfies `p`. 
+
+
+Parametric Invariants via Abstract Refinements
+---------------------------------------------- 
+
+\begin{code} We type `maxInt` as
+maxInt :: forall <p :: Int -> Prop>. Int<p> -> Int<p> -> Int<p> 
+\end{code}
+
+We call `p` an an **abstract refinement** <br>
+
+
+In the refinement logic,
+
+- abstract refinements are **uninterpreted function symbols**
+
+- which (only) satisfy the *congruence axiom*: forall x, y. x = y => (p x) = (p y)
+
+
+
+Using Abstract Refinements
+--------------------------
+
+- **If** we call `maxInt` with two `Int`s with the same concrete refinement,
+
+- **Then** the `p` will be instantiated with that concrete refinement,
+
+- **The output** of the call will also enjoy the concrete refinement.
+
+For example, the refinement is instantiated with `\v -> v >= 0` <br>
+
+\begin{code}
+{-@ maxNat :: Nat @-}
+maxNat     :: Int
+maxNat     = maxInt 2 5
+\end{code}
+
+Using Abstract Refinements
+--------------------------
+
+- **If** we call `maxInt` with two `Int`s with the same concrete refinement,
+
+- **Then** the `p` will be instantiated with that concrete refinement,
+
+- **The output** of the call will also enjoy the concrete refinement.
+
+Or any other property <br>
+
+\begin{code}
+{-@ type RGB = {v: Int | ((0 <= v) && (v < 256)) } @-}
+\end{code}
+
+<br> to verify <br>
+
+\begin{code}
+{-@ maxRGB :: RGB @-}
+maxRGB     :: Int
+maxRGB     = maxInt 56 8
+\end{code}
diff --git a/docs/slides/plpv14/lhs/.01_SimpleRefinements.lhs.swn b/docs/slides/plpv14/lhs/.01_SimpleRefinements.lhs.swn
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/lhs/.01_SimpleRefinements.lhs.swn differ
diff --git a/docs/slides/plpv14/lhs/00_Index.lhs b/docs/slides/plpv14/lhs/00_Index.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/00_Index.lhs
@@ -0,0 +1,151 @@
+Refinement Types For Haskell
+============================
+
+ {#berg} 
+--------
+
+<br>
+
++ Niki Vazou
++ Eric Seidel
++ *Ranjit Jhala*
+
+<br>
+
+**UC San Diego**
+
+<div class="hidden">
+
+\begin{code}
+main = putStrLn "Easter Egg"
+\end{code}
+
+</div>
+
+Install
+-------
+
+<br>
+
+`cabal install liquidhaskell`
+
+<br>
+
+<div class="fragment"> 
+
+  Requires an SMTLIB2 binary 
+  
+  <br>
+
+  + `http://z3.codeplex.com`
+  + `http://cvc4.cs.nyu.edu`
+  + `http://mathsat.fbk.eu`
+
+</div>
+
+Try Online
+----------
+
+<br>
+
+`http://goto.ucsd.edu/liquid/haskell/demo`
+
+Follow Slides
+-------------
+
+<br>
+
+`goto.ucsd.edu/~rjhala/liquid/haskell/plpv/lhs/`
+
+
+ {#plan} 
+--------
+
+1. <div class="fragment"><a href="01_SimpleRefinements.lhs.slides.html" target= "_blank">Refinements</a></div>
+2. <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
+3. <div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target= "_blank">Higher-Order Functions</a></div>
+4. <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements</a></div>
+    - <div class="fragment"><a href="05_Composition.lhs.slides.html" target="_blank">Dependency</a><a href="06_Inductive.lhs.slides.html" target= "_blank">, Induction</a> <a href="07_Array.lhs.slides.html" target= "_blank">, Indexing</a> <a href="08_Recursive.lhs.slides.html" target= "_blank">, Recursion</a></div>
+5. <div class="fragment"><a href="09_Laziness.lhs.slides.html" target="_blank">Lazy Evaluation</a></div>
+6. <div class="fragment"><a href="10_Termination.lhs.slides.html" target="_blank">Termination</a></div>
+
+<!--
+
+[Higher Order Functions](03_HigherOrderFunctions.lhs.slides.html)
+   </div>
+4. <div class="fragment">
+      [Abstract Refinements](04_AbstractRefinements.lhs.slides.html)
+   </div>
+    - <div class="fragment">[Dependency](05_Composition.lhs.slides.html), 
+                            [Induction](06_Inductive.lhs.slides.html), 
+                            [Indexing](07_Array.lhs.slides.html), 
+                            [Recursion](08_Recursive.lhs.slides.html)
+      </div>
+5. <div class="fragment">
+    [Lazy Evaluation](09_Laziness.lhs.slides.html)
+   </div>
+6. <div class="fragment">
+     [Termination](10_Termination.lhs.slides.html)
+   </div>
+
+-->
+
+Evaluation
+==========
+
+LiquidHaskell Is For Real
+-------------------------
+
+<br>
+
+Substantial code bases, tricky properties.
+
+<br>
+
+<div class="fragment">Inference, FTW.</div>
+
+Numbers
+-------
+
+<div align="center">
+
+**Library**                      LOC
+---------------------------   ------
+`GHC.List`                       310
+`Data.List`                      504
+`Data.Set.Splay`                 149
+`Data.Vector.Algorithms`        1219
+`Data.Map.Base`                 1396
+`Data.Text`                     3125
+`Data.Bytestring`               3501 
+---------------------------   ------
+
+</div>
+
+Evaluation: Termination
+-----------------------
+
+How bad is *termination* requirement anyway?
+
+- <div class="fragment">`520` recursive functions</div>
+- <div class="fragment">`67%` automatically proved</div>
+- <div class="fragment">`30%` need *witnesses* `/[...]`</div>
+- <div class="fragment">`18`  *not proven terminating*</div>
+- <div class="fragment">`12`  don't actually terminate (top-level `IO`)</div>
+- <div class="fragment">`6`   *probably* terminate, but *we* can't tell why.</div>
+
+
+Future Work
+-----------
+
+- Error Messages
+
+- Speed
+
+- Case Studies
+
+Thank You!
+----------
+
+`cabal install liquidhaskell`
+
diff --git a/docs/slides/plpv14/lhs/00_Index.lhs.markdown b/docs/slides/plpv14/lhs/00_Index.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/00_Index.lhs.markdown
@@ -0,0 +1,151 @@
+Refinement Types For Haskell
+============================
+
+ {#berg} 
+--------
+
+<br>
+
++ Niki Vazou
++ Eric Seidel
++ *Ranjit Jhala*
+
+<br>
+
+**UC San Diego**
+
+<div class="hidden">
+
+
+<pre><span class=hs-linenum>20: </span><a class=annot href="#"><span class=annottext>{x2 : (IO ()) | (x2 == Main.main)}</span><span class='hs-definition'>main</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>[(Char)] -&gt; (IO ())</span><span class='hs-varid'>putStrLn</span></a> <a class=annot href="#"><span class=annottext>{x3 : [(Char)] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-str'>"Easter Egg"</span></a>
+</pre>
+
+</div>
+
+Install
+-------
+
+<br>
+
+`cabal install liquidhaskell`
+
+<br>
+
+<div class="fragment"> 
+
+  Requires an SMTLIB2 binary 
+  
+  <br>
+
+  + `http://z3.codeplex.com`
+  + `http://cvc4.cs.nyu.edu`
+  + `http://mathsat.fbk.eu`
+
+</div>
+
+Try Online
+----------
+
+<br>
+
+`http://goto.ucsd.edu/liquid/haskell/demo`
+
+Follow Slides
+-------------
+
+<br>
+
+`goto.ucsd.edu/~rjhala/liquid/haskell/plpv/lhs/`
+
+
+ {#plan} 
+--------
+
+1. <div class="fragment"><a href="01_SimpleRefinements.lhs.slides.html" target= "_blank">Refinements</a></div>
+2. <div class="fragment"><a href="02_Measures.lhs.slides.html" target= "_blank">Measures</a></div>
+3. <div class="fragment"><a href="03_HigherOrderFunctions.lhs.slides.html" target= "_blank">Higher-Order Functions</a></div>
+4. <div class="fragment"><a href="04_AbstractRefinements.lhs.slides.html" target= "_blank">Abstract Refinements</a></div>
+    - <div class="fragment"><a href="05_Composition.lhs.slides.html" target="_blank">Dependency</a><a href="06_Inductive.lhs.slides.html" target= "_blank">, Induction</a> <a href="07_Array.lhs.slides.html" target= "_blank">, Indexing</a> <a href="08_Recursive.lhs.slides.html" target= "_blank">, Recursion</a></div>
+5. <div class="fragment"><a href="09_Laziness.lhs.slides.html" target="_blank">Lazy Evaluation</a></div>
+6. <div class="fragment"><a href="10_Termination.lhs.slides.html" target="_blank">Termination</a></div>
+
+<!--
+
+[Higher Order Functions](03_HigherOrderFunctions.lhs.slides.html)
+   </div>
+4. <div class="fragment">
+      [Abstract Refinements](04_AbstractRefinements.lhs.slides.html)
+   </div>
+    - <div class="fragment">[Dependency](05_Composition.lhs.slides.html), 
+                            [Induction](06_Inductive.lhs.slides.html), 
+                            [Indexing](07_Array.lhs.slides.html), 
+                            [Recursion](08_Recursive.lhs.slides.html)
+      </div>
+5. <div class="fragment">
+    [Lazy Evaluation](09_Laziness.lhs.slides.html)
+   </div>
+6. <div class="fragment">
+     [Termination](10_Termination.lhs.slides.html)
+   </div>
+
+-->
+
+Evaluation
+==========
+
+LiquidHaskell Is For Real
+-------------------------
+
+<br>
+
+Substantial code bases, tricky properties.
+
+<br>
+
+<div class="fragment">Inference, FTW.</div>
+
+Numbers
+-------
+
+<div align="center">
+
+**Library**                      LOC
+---------------------------   ------
+`GHC.List`                       310
+`Data.List`                      504
+`Data.Set.Splay`                 149
+`Data.Vector.Algorithms`        1219
+`Data.Map.Base`                 1396
+`Data.Text`                     3125
+`Data.Bytestring`               3501 
+---------------------------   ------
+
+</div>
+
+Evaluation: Termination
+-----------------------
+
+How bad is *termination* requirement anyway?
+
+- <div class="fragment">`520` recursive functions</div>
+- <div class="fragment">`67%` automatically proved</div>
+- <div class="fragment">`30%` need *witnesses* `/[...]`</div>
+- <div class="fragment">`18`  *not proven terminating*</div>
+- <div class="fragment">`12`  don't actually terminate (top-level `IO`)</div>
+- <div class="fragment">`6`   *probably* terminate, but *we* can't tell why.</div>
+
+
+Future Work
+-----------
+
+- Error Messages
+
+- Speed
+
+- Case Studies
+
+Thank You!
+----------
+
+`cabal install liquidhaskell`
+
diff --git a/docs/slides/plpv14/lhs/01_SimpleRefinements.lhs b/docs/slides/plpv14/lhs/01_SimpleRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/01_SimpleRefinements.lhs
@@ -0,0 +1,360 @@
+ {#simplerefinements}
+=======================
+
+Simple Refinement Types
+-----------------------
+
+<div class="hidden">
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+module SimpleRefinements where
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (abs, max)
+
+-- boring haskell type sigs
+zero    :: Int
+zero'   :: Int
+safeDiv :: Int -> Int -> Int
+abs     :: Int -> Int
+nats    :: L Int
+evens   :: L Int
+odds    :: L Int
+range   :: Int -> Int -> L Int
+\end{code}
+
+</div>
+
+
+Simple Refinement Types
+=======================
+
+
+Types + Predicates 
+------------------
+
+
+Example
+-------
+
+Integers equal to `0`
+
+<br>
+
+\begin{code}
+{-@ type EqZero = {v:Int | v = 0} @-}
+\end{code}
+
+
+Example
+-------
+
+Integers equal to `0`
+
+<br>
+
+\begin{code}
+{-@ zero :: EqZero @-}
+zero     =  0
+\end{code}
+
+<br>
+
+<div class="fragment">
+Refinement types via special comments `{-@ ... @-}`
+</div>
+
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo</a> 
+Lets take a look.
+</div>
+
+ {#refinementsArePredicates}
+============================
+
+Refinements Are Predicates
+--------------------------
+
+
+Refinements Are Predicates
+==========================
+
+Subtyping is Implication
+------------------------
+
+[Predicate Subtyping](http://pvs.csl.sri.com/papers/subtypes98/tse98.pdf)
+
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+--------  ---  ---------------------------------------------
+  **If**   :   Refinement of `S` *implies* refinement of `T` 
+
+**Then**   :   `S` is a *subtype* of `T`
+--------  ---  ---------------------------------------------
+
+<br>
+
+
+Subtyping is Implication
+------------------------
+
+
+<br>
+
+--------   ---     ----------------------------
+  **If**    :      `p => q`
+                
+**Then**    :      `{v : t | p} <: {v : t | q}`
+--------   ---     ----------------------------
+
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+--------    ---  ---------------------------------------------------
+  **As**     :   `v=0` *implies* `0<=v` ... via SMT
+                 
+  **So**     :   `{v:Int | v=0} <: {v:Int | 0<=v}`
+--------    ---  ---------------------------------------------------
+
+
+Example: Natural Numbers
+------------------------
+
+\begin{code} . 
+type Nat = {v : Int | 0 <= v}
+\end{code}
+
+<br>
+
+Via SMT, LiquidHaskell infers `EqZero <: Nat`, hence:
+
+<br>
+
+\begin{code}
+{-@ zero' :: Nat @-}
+zero'     =  zero
+\end{code}
+
+ {#universalinvariants}
+=======================
+
+Types = Universal Invariants
+----------------------------
+
+(Notoriously hard with *pure* SMT)
+
+Types Yield Universal Invariants
+================================
+
+Example: Lists
+--------------
+
+<div class="hidden">
+\begin{code}
+infixr `C`
+\end{code}
+</div>
+
+\begin{code}
+data L a = N | C a (L a)
+\end{code}
+
+<br>
+
+<div class="fragment">
+*Every element* in `nats` is non-negative:
+\begin{code}
+{-@ nats :: L Nat @-}
+nats     =  0 `C` 1 `C` 3 `C` N
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if `nats` contained `-2`? 
+
+</div>
+
+Example: Even/Odd Lists
+-----------------------
+
+\begin{code}
+{-@ type Even = {v:Int | v mod 2 =  0} @-}
+{-@ type Odd  = {v:Int | v mod 2 /= 0} @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ evens :: L Even @-}
+evens     =  0 `C` 2 `C` 4 `C` N
+
+{-@ odds  :: L Odd  @-}
+odds      =  1 `C` 3 `C` 5 `C` N 
+\end{code}
+</div>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if `evens` contained `1`? 
+</div>
+
+ {#functiontypes}
+=================
+
+Contracts = Function Types
+--------------------------
+
+Contracts: Function Types
+=========================
+
+
+Example: `safeDiv`
+------------------
+
+<br>
+
+**Precondition** divisor is *non-zero*.
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ type NonZero = {v:Int | v /= 0} @-}
+\end{code}
+</div>
+
+<br>
+
+Example: `safeDiv`
+------------------
+
+<br>
+
++ **Pre-condition** divisor is *non-zero*.
++ **Input type** specifies *pre-condition*
+
+<br>
+
+\begin{code}
+{-@ safeDiv :: Int -> NonZero -> Int @-}
+safeDiv x y = x `div` y
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if precondition does not hold?
+
+</div>
+
+Example: `abs`
+--------------
+
+<br>
+
++ **Postcondition** result is non-negative
++ **Output type** specifies *post-condition*
+
+<br>
+
+\begin{code}
+{-@ abs       :: x:Int -> Nat @-}
+abs x 
+  | 0 <= x    = x 
+  | otherwise = 0 - x
+\end{code}
+
+
+
+ {#dependentfunctions}
+======================
+
+Dependent Function Types
+------------------------
+
++ Outputs *refer to* inputs
++ *Relational* invariants
+
+
+Dependent Function Types
+========================
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+<br>
+
+\begin{code}
+{-@ type Btwn I J = {v:_|(I <= v && v < J)} @-}
+\end{code}
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+<br>
+
+\begin{code}
+{-@ range :: i:Int -> j:Int -> L (Btwn i j) @-}
+range i j         = go i
+  where
+    go n
+      | n < j     = n `C` go (n + 1)  
+      | otherwise = N
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Question:** What is the type of `go` ?
+</div>
+
+
+Example: Indexing Into List
+---------------------------
+
+\begin{code} 
+(!)          :: L a -> Int -> a
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "Oops!"
+\end{code}
+
+<br>
+
+<div class="fragment">(Mouseover to view type of `liquidError`)</div>
+
+<br>
+
+- <div class="fragment">**Q:** How to ensure safety? </div>
+- <div class="fragment">**A:** Precondition: `i` between `0` and list **length**.
+
+<div class="fragment">Need way to [measure](#measures) *length of a list* ...</div>
+
+
diff --git a/docs/slides/plpv14/lhs/01_SimpleRefinements.lhs.markdown b/docs/slides/plpv14/lhs/01_SimpleRefinements.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/01_SimpleRefinements.lhs.markdown
@@ -0,0 +1,386 @@
+ {#simplerefinements}
+=======================
+
+Simple Refinement Types
+-----------------------
+
+<div class="hidden">
+
+
+<pre><span class=hs-linenum>10: </span><span class='hs-keyword'>{-@</span> <span class='hs-conid'>LIQUID</span> <span class='hs-str'>"--no-termination"</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>11: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>SimpleRefinements</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>12: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>Liquid</span><span class='hs-varop'>.</span><span class='hs-conid'>Prelude</span>
+<span class=hs-linenum>13: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>abs</span><span class='hs-layout'>,</span> <span class='hs-varid'>max</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>14: </span>
+<span class=hs-linenum>15: </span><span class='hs-comment'>-- boring haskell type sigs</span>
+<span class=hs-linenum>16: </span><span class='hs-definition'>zero</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>17: </span><span class='hs-definition'>zero'</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>18: </span><span class='hs-definition'>safeDiv</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>19: </span><span class='hs-definition'>abs</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>20: </span><span class='hs-definition'>nats</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>21: </span><span class='hs-definition'>evens</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>22: </span><span class='hs-definition'>odds</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>23: </span><span class='hs-definition'>range</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Int</span>
+</pre>
+
+</div>
+
+
+Simple Refinement Types
+=======================
+
+
+Types + Predicates 
+------------------
+
+
+Example
+-------
+
+Integers equal to `0`
+
+<br>
+
+
+<pre><span class=hs-linenum>45: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>EqZero</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+
+Example
+-------
+
+Integers equal to `0`
+
+<br>
+
+
+<pre><span class=hs-linenum>57: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>zero</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>EqZero</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>58: </span><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV == 0)}</span><span class='hs-definition'>zero</span></a>     <span class='hs-keyglyph'>=</span>  <a class=annot href="#"><span class=annottext>x1:(Int#) -&gt; {x2 : (Int) | (x2 == (x1  :  int))}</span><span class='hs-num'>0</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">
+Refinement types via special comments `{-@ ... @-}`
+</div>
+
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo</a> 
+Lets take a look.
+</div>
+
+ {#refinementsArePredicates}
+============================
+
+Refinements Are Predicates
+--------------------------
+
+
+Refinements Are Predicates
+==========================
+
+Subtyping is Implication
+------------------------
+
+[Predicate Subtyping](http://pvs.csl.sri.com/papers/subtypes98/tse98.pdf)
+
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+--------  ---  ---------------------------------------------
+  **If**   :   Refinement of `S` *implies* refinement of `T` 
+
+**Then**   :   `S` is a *subtype* of `T`
+--------  ---  ---------------------------------------------
+
+<br>
+
+
+Subtyping is Implication
+------------------------
+
+
+<br>
+
+--------   ---     ----------------------------
+  **If**    :      `p => q`
+                
+**Then**    :      `{v : t | p} <: {v : t | q}`
+--------   ---     ----------------------------
+
+
+Subtyping is Implication
+------------------------
+
+<br>
+
+--------    ---  ---------------------------------------------------
+  **As**     :   `v=0` *implies* `0<=v` ... via SMT
+                 
+  **So**     :   `{v:Int | v=0} <: {v:Int | 0<=v}`
+--------    ---  ---------------------------------------------------
+
+
+Example: Natural Numbers
+------------------------
+
+ . 
+<pre><span class=hs-linenum>134: </span><span class='hs-keyword'>type</span> <span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span> <span class='hs-conop'>:</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>|</span> <span class='hs-num'>0</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span>
+</pre>
+
+<br>
+
+Via SMT, LiquidHaskell infers `EqZero <: Nat`, hence:
+
+<br>
+
+
+<pre><span class=hs-linenum>144: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>zero'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Nat</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>145: </span><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-definition'>zero'</span></a>     <span class='hs-keyglyph'>=</span>  <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == 0) &amp;&amp; (x3 == SimpleRefinements.zero)}</span><span class='hs-varid'>zero</span></a>
+</pre>
+
+ {#universalinvariants}
+=======================
+
+Types = Universal Invariants
+----------------------------
+
+(Notoriously hard with *pure* SMT)
+
+Types Yield Universal Invariants
+================================
+
+Example: Lists
+--------------
+
+<div class="hidden">
+
+<pre><span class=hs-linenum>164: </span><span class='hs-keyword'>infixr</span> <span class='hs-varop'>`C`</span>
+</pre>
+</div>
+
+
+<pre><span class=hs-linenum>169: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+*Every element* in `nats` is non-negative:
+
+<pre><span class=hs-linenum>177: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>nats</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Nat</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>178: </span><a class=annot href="#"><span class=annottext>(L {VV : (Int) | (VV &gt;= 0)})</span><span class='hs-definition'>nats</span></a>     <span class='hs-keyglyph'>=</span>  <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>{x14 : (Int) | (x14 &gt;= 0) &amp;&amp; (x14 &gt;= SimpleRefinements.zero) &amp;&amp; (SimpleRefinements.zero &lt;= x14)}
+-&gt; (L {x14 : (Int) | (x14 &gt;= 0) &amp;&amp; (x14 &gt;= SimpleRefinements.zero) &amp;&amp; (SimpleRefinements.zero &lt;= x14)})
+-&gt; (L {x14 : (Int) | (x14 &gt;= 0) &amp;&amp; (x14 &gt;= SimpleRefinements.zero) &amp;&amp; (SimpleRefinements.zero &lt;= x14)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a> <a class=annot href="#"><span class=annottext>{x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)}
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a> <a class=annot href="#"><span class=annottext>{x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)}
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>(L {x2 : (Int) | false})</span><span class='hs-conid'>N</span></a>
+</pre>
+</div>
+
+<br>
+
+<div class="fragment">
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if `nats` contained `-2`? 
+
+</div>
+
+Example: Even/Odd Lists
+-----------------------
+
+
+<pre><span class=hs-linenum>195: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Even</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-varid'>mod</span> <span class='hs-num'>2</span> <span class='hs-keyglyph'>=</span>  <span class='hs-num'>0</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>196: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Odd</span>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-varid'>mod</span> <span class='hs-num'>2</span> <span class='hs-varop'>/=</span> <span class='hs-num'>0</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+
+<pre><span class=hs-linenum>203: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>evens</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Even</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>204: </span><a class=annot href="#"><span class=annottext>(L {VV : (Int) | ((VV mod 2) == 0)})</span><span class='hs-definition'>evens</span></a>     <span class='hs-keyglyph'>=</span>  <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>{x17 : (Int) | ((x17 mod 2) == 0) &amp;&amp; (x17 &gt;= 0) &amp;&amp; (x17 &gt;= SimpleRefinements.zero) &amp;&amp; (SimpleRefinements.zero &lt;= x17)}
+-&gt; (L {x17 : (Int) | ((x17 mod 2) == 0) &amp;&amp; (x17 &gt;= 0) &amp;&amp; (x17 &gt;= SimpleRefinements.zero) &amp;&amp; (SimpleRefinements.zero &lt;= x17)})
+-&gt; (L {x17 : (Int) | ((x17 mod 2) == 0) &amp;&amp; (x17 &gt;= 0) &amp;&amp; (x17 &gt;= SimpleRefinements.zero) &amp;&amp; (SimpleRefinements.zero &lt;= x17)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a> <a class=annot href="#"><span class=annottext>{x23 : (Int) | ((x23 mod 2) == 0) &amp;&amp; (x23 /= 0) &amp;&amp; (x23 &gt; 0) &amp;&amp; (x23 &gt; SimpleRefinements.zero) &amp;&amp; (x23 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x23)}
+-&gt; (L {x23 : (Int) | ((x23 mod 2) == 0) &amp;&amp; (x23 /= 0) &amp;&amp; (x23 &gt; 0) &amp;&amp; (x23 &gt; SimpleRefinements.zero) &amp;&amp; (x23 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x23)})
+-&gt; (L {x23 : (Int) | ((x23 mod 2) == 0) &amp;&amp; (x23 /= 0) &amp;&amp; (x23 &gt; 0) &amp;&amp; (x23 &gt; SimpleRefinements.zero) &amp;&amp; (x23 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x23)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (4  :  int))}</span><span class='hs-num'>4</span></a> <a class=annot href="#"><span class=annottext>{x23 : (Int) | ((x23 mod 2) == 0) &amp;&amp; (x23 /= 0) &amp;&amp; (x23 &gt; 0) &amp;&amp; (x23 &gt; SimpleRefinements.zero) &amp;&amp; (x23 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x23)}
+-&gt; (L {x23 : (Int) | ((x23 mod 2) == 0) &amp;&amp; (x23 /= 0) &amp;&amp; (x23 &gt; 0) &amp;&amp; (x23 &gt; SimpleRefinements.zero) &amp;&amp; (x23 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x23)})
+-&gt; (L {x23 : (Int) | ((x23 mod 2) == 0) &amp;&amp; (x23 /= 0) &amp;&amp; (x23 &gt; 0) &amp;&amp; (x23 &gt; SimpleRefinements.zero) &amp;&amp; (x23 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x23)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>(L {x2 : (Int) | false})</span><span class='hs-conid'>N</span></a>
+<span class=hs-linenum>205: </span>
+<span class=hs-linenum>206: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>odds</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Odd</span>  <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>207: </span><a class=annot href="#"><span class=annottext>(L {VV : (Int) | ((VV mod 2) == 1)})</span><span class='hs-definition'>odds</span></a>      <span class='hs-keyglyph'>=</span>  <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a> <a class=annot href="#"><span class=annottext>{x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)}
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a> <a class=annot href="#"><span class=annottext>{x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)}
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (5  :  int))}</span><span class='hs-num'>5</span></a> <a class=annot href="#"><span class=annottext>{x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)}
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})
+-&gt; (L {x20 : (Int) | ((x20 mod 2) == 1) &amp;&amp; (x20 &gt; 0) &amp;&amp; (x20 &gt; SimpleRefinements.zero) &amp;&amp; (x20 &gt;= 0) &amp;&amp; (SimpleRefinements.zero &lt;= x20)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>(L {x2 : (Int) | false})</span><span class='hs-conid'>N</span></a> 
+</pre>
+</div>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if `evens` contained `1`? 
+</div>
+
+ {#functiontypes}
+=================
+
+Contracts = Function Types
+--------------------------
+
+Contracts: Function Types
+=========================
+
+
+Example: `safeDiv`
+------------------
+
+<br>
+
+**Precondition** divisor is *non-zero*.
+
+<br>
+
+<div class="fragment">
+
+<pre><span class=hs-linenum>237: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>NonZero</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-varop'>/=</span> <span class='hs-num'>0</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+</div>
+
+<br>
+
+Example: `safeDiv`
+------------------
+
+<br>
+
++ **Pre-condition** divisor is *non-zero*.
++ **Input type** specifies *pre-condition*
+
+<br>
+
+
+<pre><span class=hs-linenum>254: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>safeDiv</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>NonZero</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>255: </span><a class=annot href="#"><span class=annottext>(Int) -&gt; {VV : (Int) | (VV /= 0)} -&gt; (Int)</span><span class='hs-definition'>safeDiv</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV /= 0)}</span><span class='hs-varid'>y</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x1:(Int)
+-&gt; x2:(Int)
+-&gt; {x6 : (Int) | (((x1 &gt;= 0) &amp;&amp; (x2 &gt;= 0)) =&gt; (x6 &gt;= 0)) &amp;&amp; (((x1 &gt;= 0) &amp;&amp; (x2 &gt;= 1)) =&gt; (x6 &lt;= x1)) &amp;&amp; (x6 == (x1 / x2))}</span><span class='hs-varop'>`div`</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == y) &amp;&amp; (x3 /= 0)}</span><span class='hs-varid'>y</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellSimpleRefinements.hs" target= "_blank">Demo:</a> 
+What if precondition does not hold?
+
+</div>
+
+Example: `abs`
+--------------
+
+<br>
+
++ **Postcondition** result is non-negative
++ **Output type** specifies *post-condition*
+
+<br>
+
+
+<pre><span class=hs-linenum>278: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>abs</span>       <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nat</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>279: </span><a class=annot href="#"><span class=annottext>(Int) -&gt; {VV : (Int) | (VV &gt;= 0)}</span><span class='hs-definition'>abs</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>x</span></a> 
+<span class=hs-linenum>280: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>x1:(Int)
+-&gt; x2:(Int) -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt;= x2))}</span><span class='hs-varop'>&lt;=</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == x)}</span><span class='hs-varid'>x</span></a>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == x)}</span><span class='hs-varid'>x</span></a> 
+<span class=hs-linenum>281: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == x)}</span><span class='hs-varid'>x</span></a>
+</pre>
+
+
+
+ {#dependentfunctions}
+======================
+
+Dependent Function Types
+------------------------
+
++ Outputs *refer to* inputs
++ *Relational* invariants
+
+
+Dependent Function Types
+========================
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+<br>
+
+
+<pre><span class=hs-linenum>313: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Btwn</span> <span class='hs-conid'>I</span> <span class='hs-conid'>J</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span><span class='hs-keyglyph'>|</span><span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>v</span> <span class='hs-varop'>&lt;</span> <span class='hs-conid'>J</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+Example: `range`
+----------------
+
+`(range i j)` returns `Int`s between `i` and `j`
+
+<br>
+
+
+<pre><span class=hs-linenum>324: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>range</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>j</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-layout'>(</span><span class='hs-conid'>Btwn</span> <span class='hs-varid'>i</span> <span class='hs-varid'>j</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>325: </span><a class=annot href="#"><span class=annottext>i:(Int) -&gt; j:(Int) -&gt; (L {v : (Int) | (v &lt; j) &amp;&amp; (i &lt;= v)})</span><span class='hs-definition'>range</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>j</span></a>         <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x10 : (Int) | (x10 &gt;= i) &amp;&amp; (i &lt;= x10)}
+-&gt; (L {x7 : (Int) | (x7 &gt;= i) &amp;&amp; (x7 &gt;= x1) &amp;&amp; (x7 &lt; j) &amp;&amp; (i &lt;= x7) &amp;&amp; (x1 &lt;= x7)})</span><span class='hs-varid'>go</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == i)}</span><span class='hs-varid'>i</span></a>
+<span class=hs-linenum>326: </span>  <span class='hs-keyword'>where</span>
+<span class=hs-linenum>327: </span>    <a class=annot href="#"><span class=annottext>n:{VV : (Int) | (VV &gt;= i) &amp;&amp; (i &lt;= VV)}
+-&gt; (L {VV : (Int) | (VV &gt;= i) &amp;&amp; (VV &gt;= n) &amp;&amp; (VV &lt; j) &amp;&amp; (i &lt;= VV) &amp;&amp; (n &lt;= VV)})</span><span class='hs-varid'>go</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= i) &amp;&amp; (i &lt;= VV)}</span><span class='hs-varid'>n</span></a>
+<span class=hs-linenum>328: </span>      <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == n) &amp;&amp; (x4 &gt;= i) &amp;&amp; (i &lt;= x4)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>&lt;</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == j)}</span><span class='hs-varid'>j</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == n) &amp;&amp; (x4 &gt;= i) &amp;&amp; (i &lt;= x4)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>{x20 : (Int) | (x20 &gt;= i) &amp;&amp; (x20 &gt;= n) &amp;&amp; (x20 &lt; j) &amp;&amp; (i &lt;= x20) &amp;&amp; (n &lt;= x20)}
+-&gt; (L {x20 : (Int) | (x20 &gt;= i) &amp;&amp; (x20 &gt;= n) &amp;&amp; (x20 &lt; j) &amp;&amp; (i &lt;= x20) &amp;&amp; (n &lt;= x20)})
+-&gt; (L {x20 : (Int) | (x20 &gt;= i) &amp;&amp; (x20 &gt;= n) &amp;&amp; (x20 &lt; j) &amp;&amp; (i &lt;= x20) &amp;&amp; (n &lt;= x20)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>n:{VV : (Int) | (VV &gt;= i) &amp;&amp; (i &lt;= VV)}
+-&gt; (L {VV : (Int) | (VV &gt;= i) &amp;&amp; (VV &gt;= n) &amp;&amp; (VV &lt; j) &amp;&amp; (i &lt;= VV) &amp;&amp; (n &lt;= VV)})</span><span class='hs-varid'>go</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == n) &amp;&amp; (x4 &gt;= i) &amp;&amp; (i &lt;= x4)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span>  
+<span class=hs-linenum>329: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>(L {x2 : (Int) | false})</span><span class='hs-conid'>N</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">
+**Question:** What is the type of `go` ?
+</div>
+
+
+Example: Indexing Into List
+---------------------------
+
+ 
+<pre><span class=hs-linenum>343: </span><span class='hs-layout'>(</span><span class='hs-varop'>!</span><span class='hs-layout'>)</span>          <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>344: </span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>  <a class=annot href="#"><span class=annottext>forall a. (L a) -&gt; (Int) -&gt; a</span><span class='hs-varop'>!</span></a> <span class='hs-num'>0</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a>
+<span class=hs-linenum>345: </span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-varop'>!</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>(L a)</span><span class='hs-varid'>xs</span></a> <a class=annot href="#"><span class=annottext>(L a) -&gt; (Int) -&gt; a</span><span class='hs-varop'>!</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>346: </span><span class='hs-keyword'>_</span>        <span class='hs-varop'>!</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x1 : [(Char)] | false} -&gt; {VV : a | false}</span><span class='hs-varid'>liquidError</span></a> <span class=hs-error><a class=annot href="#"><span class=annottext>{x3 : [(Char)] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-str'>"Oops!"</span></a></span>
+</pre>
+
+<br>
+
+<div class="fragment">(Mouseover to view type of `liquidError`)</div>
+
+<br>
+
+- <div class="fragment">**Q:** How to ensure safety? </div>
+- <div class="fragment">**A:** Precondition: `i` between `0` and list **length**.
+
+<div class="fragment">Need way to [measure](#measures) *length of a list* ...</div>
+
+
diff --git a/docs/slides/plpv14/lhs/02_Measures.lhs b/docs/slides/plpv14/lhs/02_Measures.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/02_Measures.lhs
@@ -0,0 +1,321 @@
+
+ {#measures}
+============
+
+Measuring Data Types
+--------------------
+
+<div class="hidden">
+
+\begin{code}
+module Measures where
+import Prelude hiding ((!!), length)
+import Language.Haskell.Liquid.Prelude
+
+length      :: L a -> Int
+(!)         :: L a -> Int -> a
+insert      :: Ord a => a -> L a -> L a
+insertSort  :: Ord a => [a] -> L a
+\end{code}
+
+</div>
+
+Measuring Data Types 
+====================
+
+Recap
+-----
+
+1. <div class="fragment">**Refinements:** Types + Predicates</div>
+2. <div class="fragment">**Subtyping:** SMT Implication</div>
+
+<!--
+
+---   -----------------------   ---  -------------------------
+ 1.      **Refinement Types**    :   Types + Predicates
+ 2.             **Subtyping**    :   SMT / Logical Implication 
+---   -----------------------   ---  -------------------------
+
+-->
+
+
+Example: Lists 
+--------------
+
+<div class="hidden">
+
+\begin{code}
+infixr `C`
+\end{code}
+
+</div>
+
+<br>
+
+\begin{code}
+data L a = N 
+         | C a (L a)
+\end{code}
+
+Example: Length of a List 
+-------------------------
+
+\begin{code}
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+LiquidHaskell *strengthens* data constructor types
+\begin{code} <div/>
+data L a where 
+  N :: {v: L a | (llen v) = 0}
+  C :: a -> xs:L a 
+         -> {v:L a | (llen v) = 1 + (llen xs)}
+\end{code}
+</div>
+
+Measures Are Uninterpreted
+--------------------------
+
+\begin{code} <br>
+data L a where 
+  N :: {v: L a | (llen v) = 0}
+  C :: a -> xs:L a 
+         -> {v:L a | (llen v) = 1 + (llen xs)}
+\end{code}
+
+<br>
+
+`llen` is an *uninterpreted function* in SMT logic
+
+Measures Are Uninterpreted
+--------------------------
+
+In SMT, [uninterpreted function](http://fm.csl.sri.com/SSFT12/smt-euf-arithmetic.pdf) `f` obeys *congruence* axiom:
+
+`forall x y. (x = y) => (f x) = (f y)`
+
+<br>
+
+<div class="fragment">
+All other facts about `llen` asserted at *fold* and *unfold*
+</div>
+
+Measures Are Uninterpreted
+--------------------------
+
+All other facts about `llen` asserted at *fold* and *unfold*
+
+<br>
+
+<div class="fragment">
+\begin{code}**Fold**<br>
+z = C x y -- z :: {v | llen v = 1 + llen y}
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{code}**Unfold**<br>
+case z of 
+  N     -> e1 -- z :: {v | llen v = 0}
+  C x y -> e2 -- z :: {v | llen v = 1 + llen y}
+\end{code}
+</div>
+
+
+Measured Refinements
+--------------------
+
+Now, we can verify:
+
+<br>
+
+\begin{code}
+{-@ length      :: xs:L a -> (EqLen xs) @-}
+length N        = 0
+length (C _ xs) = 1 + (length xs)
+\end{code}
+
+<div class="fragment">
+
+<br>
+
+Where `EqLen` is a type alias:
+
+\begin{code}
+{-@ type EqLen Xs = {v:Nat | v = (llen Xs)} @-}
+\end{code}
+
+</div>
+
+List Indexing Redux
+-------------------
+
+We can type list indexed lookup:
+
+<br>
+
+\begin{code}
+{-@ (!)      :: xs:L a -> (LtLen xs) -> a @-}
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "never happens!"
+\end{code}
+
+<br>
+
+Where `LtLen` is a type alias:
+
+\begin{code}
+{-@ type LtLen Xs = {v:Nat | v < (llen Xs)} @-}
+\end{code}
+
+
+List Indexing Redux
+-------------------
+
+Now we can type list indexed lookup:
+
+\begin{code} <br>
+{-@ (!)      :: xs:L a -> (LtLen xs) -> a @-}
+(C x _)  ! 0 = x
+(C _ xs) ! i = xs ! (i - 1)
+_        ! _ = liquidError "never happens!"
+\end{code}
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellMeasure.hs" target= "_blank">Demo:</a> 
+What if we *remove* the precondition?
+
+Multiple Measures
+-----------------
+
+LiquidHaskell allows *many* measures for a type
+
+
+Multiple Measures 
+-----------------
+
+**Example:** Nullity of a `List` 
+
+\begin{code}
+{-@ measure isNull :: (L a) -> Prop
+    isNull (N)      = true
+    isNull (C x xs) = false           @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+\begin{code} LiquidHaskell **strengthens** data constructors
+data L a where 
+  N :: {v : L a | (isNull v)}
+  C :: a -> L a -> {v:(L a) | not (isNull v)}
+\end{code}
+
+</div>
+
+Multiple Measures
+-----------------
+
+LiquidHaskell *conjoins* data constructor types:
+
+\begin{code} <br>
+data L a where 
+  N :: {v:L a |  (llen v) = 0 
+              && (isNull v) }
+  C :: a 
+    -> xs:L a 
+    -> {v:L a |  (llen v) = 1 + (llen xs) 
+              && not (isNull v)          }
+\end{code}
+
+Multiple Measures
+-----------------
+
+Unlike [indexed types](http://dl.acm.org/citation.cfm?id=270793) ...
+
+<br>
+
++ <div class="fragment">Measures *decouple* properties from structures</div>
++ <div class="fragment">Support *multiple* properties over structures </div>
++ <div class="fragment">Enable  *reuse* of structures                 </div>
+
+<br>
+
+<div class="fragment">Invaluable in practice!</div>
+
+Refined Data Constructors
+-------------------------
+
+Can *directly pack* properties inside data constructors
+
+<div class="fragment">
+
+<br>
+
+\begin{code}
+{-@ data L a = N
+             | C (x :: a) 
+                 (xs :: L {v:a | x <= v})  @-}
+\end{code}
+
+</div>
+
+<div class="fragment">
+
+<br>
+
+Specifies *increasing* Lists 
+</div>
+
+Refined Data Constructors
+-------------------------
+
+**Example:** Increasing Lists, with strengthened constructors:
+
+\begin{code} <br>
+data L a where
+  N :: L a
+  C :: x:a -> xs: L {v:a | x <= v} -> L a
+\end{code}
+
+<br>
+
+- <div class="fragment">LiquidHaskell *checks* property when *folding* `C`</div>
+- <div class="fragment">LiquidHaskell *assumes* property when *unfolding* `C`</div>
+
+Refined Data Constructors
+-------------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellInsertSort.hs" target= "_blank">Demo: Insertion Sort</a> (hover for inferred types) 
+
+\begin{code}
+insertSort = foldr insert N
+
+insert y (x `C` xs) 
+  | y <= x    = y `C` (x `C` xs)
+  | otherwise = x `C` insert y xs
+insert y N    = y `C` N    
+\end{code}
+
+<br>
+
+<div class="fragment">**Problem 1:** What if we need *both* [increasing and decreasing lists](http://web.cecs.pdx.edu/~sheard/Code/QSort.html)?</div>
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. <div class="fragment">**Measures:** Strengthened Constructors</div>
+    - <div class="fragment">*Decouple* structure & property, enable *reuse*</div>
+
diff --git a/docs/slides/plpv14/lhs/02_Measures.lhs.markdown b/docs/slides/plpv14/lhs/02_Measures.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/02_Measures.lhs.markdown
@@ -0,0 +1,331 @@
+
+ {#measures}
+============
+
+Measuring Data Types
+--------------------
+
+<div class="hidden">
+
+
+<pre><span class=hs-linenum>11: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>Measures</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>12: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'>!!</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>length</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>13: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>Liquid</span><span class='hs-varop'>.</span><span class='hs-conid'>Prelude</span>
+<span class=hs-linenum>14: </span>
+<span class=hs-linenum>15: </span><span class='hs-definition'>length</span>      <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>16: </span><span class='hs-layout'>(</span><span class='hs-varop'>!</span><span class='hs-layout'>)</span>         <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>17: </span><span class='hs-definition'>insert</span>      <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>18: </span><span class='hs-definition'>insertSort</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+</pre>
+
+</div>
+
+Measuring Data Types 
+====================
+
+Recap
+-----
+
+1. <div class="fragment">**Refinements:** Types + Predicates</div>
+2. <div class="fragment">**Subtyping:** SMT Implication</div>
+
+<!--
+
+---   -----------------------   ---  -------------------------
+ 1.      **Refinement Types**    :   Types + Predicates
+ 2.             **Subtyping**    :   SMT / Logical Implication 
+---   -----------------------   ---  -------------------------
+
+-->
+
+
+Example: Lists 
+--------------
+
+<div class="hidden">
+
+
+<pre><span class=hs-linenum>48: </span><span class='hs-keyword'>infixr</span> <span class='hs-varop'>`C`</span>
+</pre>
+
+</div>
+
+<br>
+
+
+<pre><span class=hs-linenum>56: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span> 
+<span class=hs-linenum>57: </span>         <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+</pre>
+
+Example: Length of a List 
+-------------------------
+
+
+<pre><span class=hs-linenum>64: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>measure</span> <span class='hs-varid'>llen</span>  <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>65: </span>    <span class='hs-varid'>llen</span> <span class='hs-layout'>(</span><span class='hs-conid'>N</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span>
+<span class=hs-linenum>66: </span>    <span class='hs-varid'>llen</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span>  <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+LiquidHaskell *strengthens* data constructor types
+ <div/>
+<pre><span class=hs-linenum>74: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>75: </span>  <span class='hs-conid'>N</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>76: </span>  <span class='hs-conid'>C</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> 
+<span class=hs-linenum>77: </span>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+</pre>
+</div>
+
+Measures Are Uninterpreted
+--------------------------
+
+ <br>
+<pre><span class=hs-linenum>85: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>86: </span>  <span class='hs-conid'>N</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>87: </span>  <span class='hs-conid'>C</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> 
+<span class=hs-linenum>88: </span>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+</pre>
+
+<br>
+
+`llen` is an *uninterpreted function* in SMT logic
+
+Measures Are Uninterpreted
+--------------------------
+
+In SMT, [uninterpreted function](http://fm.csl.sri.com/SSFT12/smt-euf-arithmetic.pdf) `f` obeys *congruence* axiom:
+
+`forall x y. (x = y) => (f x) = (f y)`
+
+<br>
+
+<div class="fragment">
+All other facts about `llen` asserted at *fold* and *unfold*
+</div>
+
+Measures Are Uninterpreted
+--------------------------
+
+All other facts about `llen` asserted at *fold* and *unfold*
+
+<br>
+
+<div class="fragment">
+**Fold**<br>
+<pre><span class=hs-linenum>117: </span><span class='hs-definition'>z</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-comment'>-- z :: {v | llen v = 1 + llen y}</span>
+</pre>
+</div>
+
+<br>
+
+<div class="fragment">
+**Unfold**<br>
+<pre><span class=hs-linenum>125: </span><span class='hs-keyword'>case</span> <span class='hs-varid'>z</span> <span class='hs-keyword'>of</span> 
+<span class=hs-linenum>126: </span>  <span class='hs-conid'>N</span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>e1</span> <span class='hs-comment'>-- z :: {v | llen v = 0}</span>
+<span class=hs-linenum>127: </span>  <span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>e2</span> <span class='hs-comment'>-- z :: {v | llen v = 1 + llen y}</span>
+</pre>
+</div>
+
+
+Measured Refinements
+--------------------
+
+Now, we can verify:
+
+<br>
+
+
+<pre><span class=hs-linenum>140: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>length</span>      <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>EqLen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>141: </span><a class=annot href="#"><span class=annottext>forall a. x1:(L a) -&gt; {VV : (Int) | (VV == (llen x1)) &amp;&amp; (VV &gt;= 0)}</span><span class='hs-definition'>length</span></a> <span class='hs-conid'>N</span>        <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:(Int#) -&gt; {x2 : (Int) | (x2 == (x1  :  int))}</span><span class='hs-num'>0</span></a>
+<span class=hs-linenum>142: </span><span class='hs-definition'>length</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>forall a. x1:(L a) -&gt; {VV : (Int) | (VV == (llen x1)) &amp;&amp; (VV &gt;= 0)}</span><span class='hs-varid'>length</span></a> <a class=annot href="#"><span class=annottext>{x2 : (L a) | (x2 == xs)}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>)</span>
+</pre>
+
+<div class="fragment">
+
+<br>
+
+Where `EqLen` is a type alias:
+
+
+<pre><span class=hs-linenum>152: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>EqLen</span> <span class='hs-conid'>Xs</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-conid'>Xs</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+</div>
+
+List Indexing Redux
+-------------------
+
+We can type list indexed lookup:
+
+<br>
+
+
+<pre><span class=hs-linenum>165: </span><span class='hs-keyword'>{-@</span> <span class='hs-layout'>(</span><span class='hs-varop'>!</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>LtLen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>166: </span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>  <a class=annot href="#"><span class=annottext>forall a.
+x1:(L a) -&gt; {VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; (llen x1))} -&gt; a</span><span class='hs-varop'>!</span></a> <span class='hs-num'>0</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a>
+<span class=hs-linenum>167: </span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-varop'>!</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>(L {VV : a | (x &lt;= VV)})</span><span class='hs-varid'>xs</span></a> <a class=annot href="#"><span class=annottext>forall a.
+x1:(L a) -&gt; {VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; (llen x1))} -&gt; a</span><span class='hs-varop'>!</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 &gt;= 0)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>168: </span><span class='hs-keyword'>_</span>        <span class='hs-varop'>!</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x1 : [(Char)] | false} -&gt; {VV : a | false}</span><span class='hs-varid'>liquidError</span></a> <a class=annot href="#"><span class=annottext>{x3 : [(Char)] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-str'>"never happens!"</span></a>
+</pre>
+
+<br>
+
+Where `LtLen` is a type alias:
+
+
+<pre><span class=hs-linenum>176: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>LtLen</span> <span class='hs-conid'>Xs</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-varop'>&lt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-conid'>Xs</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+
+List Indexing Redux
+-------------------
+
+Now we can type list indexed lookup:
+
+ <br>
+<pre><span class=hs-linenum>186: </span><span class='hs-keyword'>{-@</span> <span class='hs-layout'>(</span><span class='hs-varop'>!</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>LtLen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>187: </span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>  <span class='hs-varop'>!</span> <span class='hs-num'>0</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span>
+<span class=hs-linenum>188: </span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-varop'>!</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>xs</span> <span class='hs-varop'>!</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>189: </span><span class='hs-keyword'>_</span>        <span class='hs-varop'>!</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>liquidError</span> <span class='hs-str'>"never happens!"</span>
+</pre>
+
+<br>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellMeasure.hs" target= "_blank">Demo:</a> 
+What if we *remove* the precondition?
+
+Multiple Measures
+-----------------
+
+LiquidHaskell allows *many* measures for a type
+
+
+Multiple Measures 
+-----------------
+
+**Example:** Nullity of a `List` 
+
+
+<pre><span class=hs-linenum>209: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>measure</span> <span class='hs-varid'>isNull</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>
+<span class=hs-linenum>210: </span>    <span class='hs-varid'>isNull</span> <span class='hs-layout'>(</span><span class='hs-conid'>N</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>true</span>
+<span class=hs-linenum>211: </span>    <span class='hs-varid'>isNull</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>false</span>           <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+
+ LiquidHaskell **strengthens** data constructors
+<pre><span class=hs-linenum>219: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>220: </span>  <span class='hs-conid'>N</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span> <span class='hs-conop'>:</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>isNull</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+<span class=hs-linenum>221: </span>  <span class='hs-conid'>C</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isNull</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
+</pre>
+
+</div>
+
+Multiple Measures
+-----------------
+
+LiquidHaskell *conjoins* data constructor types:
+
+ <br>
+<pre><span class=hs-linenum>232: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>233: </span>  <span class='hs-conid'>N</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span>  <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span> 
+<span class=hs-linenum>234: </span>              <span class='hs-varop'>&amp;&amp;</span> <span class='hs-layout'>(</span><span class='hs-varid'>isNull</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
+<span class=hs-linenum>235: </span>  <span class='hs-conid'>C</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> 
+<span class=hs-linenum>236: </span>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> 
+<span class=hs-linenum>237: </span>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span>  <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>238: </span>              <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isNull</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span>          <span class='hs-layout'>}</span>
+</pre>
+
+Multiple Measures
+-----------------
+
+Unlike [indexed types](http://dl.acm.org/citation.cfm?id=270793) ...
+
+<br>
+
++ <div class="fragment">Measures *decouple* properties from structures</div>
++ <div class="fragment">Support *multiple* properties over structures </div>
++ <div class="fragment">Enable  *reuse* of structures                 </div>
+
+<br>
+
+<div class="fragment">Invaluable in practice!</div>
+
+Refined Data Constructors
+-------------------------
+
+Can *directly pack* properties inside data constructors
+
+<div class="fragment">
+
+<br>
+
+
+<pre><span class=hs-linenum>266: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span>
+<span class=hs-linenum>267: </span>             <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>268: </span>                 <span class='hs-layout'>(</span><span class='hs-varid'>xs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>x</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span>  <span class='hs-keyword'>@-}</span>
+</pre>
+
+</div>
+
+<div class="fragment">
+
+<br>
+
+Specifies *increasing* Lists 
+</div>
+
+Refined Data Constructors
+-------------------------
+
+**Example:** Increasing Lists, with strengthened constructors:
+
+ <br>
+<pre><span class=hs-linenum>286: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>287: </span>  <span class='hs-conid'>N</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>288: </span>  <span class='hs-conid'>C</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span> <span class='hs-conid'>L</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>x</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+</pre>
+
+<br>
+
+- <div class="fragment">LiquidHaskell *checks* property when *folding* `C`</div>
+- <div class="fragment">LiquidHaskell *assumes* property when *unfolding* `C`</div>
+
+Refined Data Constructors
+-------------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=HaskellInsertSort.hs" target= "_blank">Demo: Insertion Sort</a> (hover for inferred types) 
+
+
+<pre><span class=hs-linenum>302: </span><a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; [a] -&gt; (L a)</span><span class='hs-definition'>insertSort</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>(a -&gt; (L a) -&gt; (L a)) -&gt; (L a) -&gt; [a] -&gt; (L a)</span><span class='hs-varid'>foldr</span></a> <a class=annot href="#"><span class=annottext>a -&gt; (L a) -&gt; (L a)</span><span class='hs-varid'>insert</span></a> <a class=annot href="#"><span class=annottext>{x3 : (L {VV : a | false}) | (((isNull x3)) &lt;=&gt; true) &amp;&amp; ((llen x3) == 0)}</span><span class='hs-conid'>N</span></a>
+<span class=hs-linenum>303: </span>
+<span class=hs-linenum>304: </span><a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; a -&gt; (L a) -&gt; (L a)</span><span class='hs-definition'>insert</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>y</span></a> <span class='hs-layout'>(</span><span class='hs-varid'>x</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>305: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>x1:a -&gt; x2:a -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt;= x2))}</span><span class='hs-varop'>&lt;=</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>x1:{VV : a | (VV &gt;= y)}
+-&gt; x2:(L {VV : a | (VV &gt;= y) &amp;&amp; (x1 &lt;= VV)})
+-&gt; {x3 : (L {VV : a | (VV &gt;= y)}) | (((isNull x3)) &lt;=&gt; false) &amp;&amp; ((llen x3) == (1 + (llen x2)))}</span><span class='hs-varop'>`C`</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x1:{VV : a | (VV &gt;= x) &amp;&amp; (VV &gt;= y)}
+-&gt; x2:(L {VV : a | (VV &gt;= x) &amp;&amp; (VV &gt;= y) &amp;&amp; (x1 &lt;= VV)})
+-&gt; {x3 : (L {VV : a | (VV &gt;= x) &amp;&amp; (VV &gt;= y)}) | (((isNull x3)) &lt;=&gt; false) &amp;&amp; ((llen x3) == (1 + (llen x2)))}</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (L {VV : a | (x &lt;= VV)}) | (x2 == xs)}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>306: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x1:{VV : a | (VV &gt;= x)}
+-&gt; x2:(L {VV : a | (VV &gt;= x) &amp;&amp; (x1 &lt;= VV)})
+-&gt; {x3 : (L {VV : a | (VV &gt;= x)}) | (((isNull x3)) &lt;=&gt; false) &amp;&amp; ((llen x3) == (1 + (llen x2)))}</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; a -&gt; (L a) -&gt; (L a)</span><span class='hs-varid'>insert</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>{x2 : (L {VV : a | (x &lt;= VV)}) | (x2 == xs)}</span><span class='hs-varid'>xs</span></a>
+<span class=hs-linenum>307: </span><span class='hs-definition'>insert</span> <span class='hs-varid'>y</span> <span class='hs-conid'>N</span>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>x1:{VV : a | (VV == y)}
+-&gt; x2:(L {VV : a | (VV == y) &amp;&amp; (x1 &lt;= VV)})
+-&gt; {x3 : (L {VV : a | (VV == y)}) | (((isNull x3)) &lt;=&gt; false) &amp;&amp; ((llen x3) == (1 + (llen x2)))}</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x3 : (L {VV : a | false}) | (((isNull x3)) &lt;=&gt; true) &amp;&amp; ((llen x3) == 0)}</span><span class='hs-conid'>N</span></a>    
+</pre>
+
+<br>
+
+<div class="fragment">**Problem 1:** What if we need *both* [increasing and decreasing lists](http://web.cecs.pdx.edu/~sheard/Code/QSort.html)?</div>
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. <div class="fragment">**Measures:** Strengthened Constructors</div>
+    - <div class="fragment">*Decouple* structure & property, enable *reuse*</div>
+
diff --git a/docs/slides/plpv14/lhs/03_HigherOrderFunctions.lhs b/docs/slides/plpv14/lhs/03_HigherOrderFunctions.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/03_HigherOrderFunctions.lhs
@@ -0,0 +1,173 @@
+  {#hofs}
+=========
+
+<div class="hidden">
+\begin{code}
+module Loop (
+    listSum
+  , listNatSum
+  ) where
+
+import Prelude
+
+{-@ LIQUID "--no-termination"@-}
+listNatSum  :: [Int] -> Int
+add         :: Int -> Int -> Int
+\end{code}
+</div>
+
+Higher-Order Specifications
+---------------------------
+
+Types scale to *Higher-Order* Specifications
+
+<br>
+
+<div class="fragment">
+
++ map
++ fold
++ visitors
++ callbacks
++ ...
+
+</div>
+
+<br>
+
+<div class="fragment">Very difficult with *first-order program logics*</div>
+
+
+Higher Order Specifications
+===========================
+
+Example: Higher Order Loop
+--------------------------
+
+\begin{code}
+loop :: Int -> Int -> α -> (Int -> α -> α) -> α
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+LiquidHaskell infers `f` called with values `(Btwn lo hi)`
+
+
+Example: Summing Lists
+----------------------
+
+\begin{code}
+listSum xs  = loop 0 n 0 body 
+  where 
+    body    = \i acc -> acc + (xs !! i)
+    n       = length xs
+\end{code}
+
+<br>
+
+- <div class="fragment">*Function subtyping:* `body` called on `i :: Btwn 0 (llen xs)`</div>
+- <div class="fragment">Hence, indexing with `!!` is safe.</div>
+
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Loop.hs" target= "_blank">Demo:</a> Tweak `loop` exit condition? 
+</div>
+
+Example: Summing `Nat`s
+-----------------------
+
+<br>
+
+\begin{code}
+{-@ listNatSum :: [Nat] -> Nat @-}
+listNatSum xs  = loop 0 n 0 body 
+  where 
+    body       = \i acc -> acc + (xs !! i)
+    n          = length xs
+\end{code}
+
+<br>
+
+<div class="fragment" align="center">
+
+----  ----  ---------------------------------------
+ (+)  `::`  `x:Int -> y:Int -> {v:Int| v=x+y}`
+      `<:`  `Nat   -> Nat   -> Nat`
+----  ----  ---------------------------------------
+
+</div>
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{code} <br> 
+{-@ listNatSum :: [Nat] -> Nat @-}
+listNatSum xs  = loop 0 n 0 body 
+  where 
+    body       = \i acc -> acc + (xs !! i)
+    n          = length xs
+\end{code}
+
+<br>
+
+Hence, verified by *instantiating* `α` of `loop` with `Nat`
+
+<div class="fragment">`Int -> Int -> Nat -> (Int -> Nat -> Nat) -> Nat`</div>
+
+Example: Summing `Nat`s
+-----------------------
+
+\begin{code} <br> 
+{-@ listNatSum :: [Nat] -> Nat @-}
+listNatSum xs  = loop 0 n 0 body 
+  where 
+    body       = \i acc -> acc + (xs !! i)
+    n          = length xs
+\end{code}
+
+<br>
+
++ Parameter `α` corresponds to *loop invariant*
+
++ Instantiation corresponds to invariant *synthesis*
+
+
+Instantiation And Inference
+---------------------------
+
++ <div class="fragment">Polymorphic instantiation happens *everywhere*</div> 
+
++ <div class="fragment">Automatic inference is crucial</div>
+
++ <div class="fragment">*Cannot use* unification (unlike indexed approaches)</div>
+
++ <div class="fragment">*Can reuse* [SMT/predicate abstraction.](http://goto.ucsd.edu/~rjhala/papers/liquid_types.html)</div>
+
+
+
+Iteration Dependence
+--------------------
+
+**Cannot** use parametric polymorphism to verify:
+
+<br>
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+
+- <div class="fragment">As property only holds after **last** loop iteration...</div>
+
+- <div class="fragment">... cannot instantiate `α` with `{v:Int | v = n + m}`</div>
+
+<div class="fragment">**Problem:** Need *iteration-dependent* invariants...</div>
+
diff --git a/docs/slides/plpv14/lhs/03_HigherOrderFunctions.lhs.markdown b/docs/slides/plpv14/lhs/03_HigherOrderFunctions.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/03_HigherOrderFunctions.lhs.markdown
@@ -0,0 +1,205 @@
+  {#hofs}
+=========
+
+<div class="hidden">
+
+<pre><span class=hs-linenum> 6: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>Loop</span> <span class='hs-layout'>(</span>
+<span class=hs-linenum> 7: </span>    <span class='hs-varid'>listSum</span>
+<span class=hs-linenum> 8: </span>  <span class='hs-layout'>,</span> <span class='hs-varid'>listNatSum</span>
+<span class=hs-linenum> 9: </span>  <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>10: </span>
+<span class=hs-linenum>11: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span>
+<span class=hs-linenum>12: </span>
+<span class=hs-linenum>13: </span><span class='hs-keyword'>{-@</span> <span class='hs-conid'>LIQUID</span> <span class='hs-str'>"--no-termination"</span><span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>14: </span><span class='hs-definition'>listNatSum</span>  <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Int</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>15: </span><span class='hs-definition'>add</span>         <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+</pre>
+</div>
+
+Higher-Order Specifications
+---------------------------
+
+Types scale to *Higher-Order* Specifications
+
+<br>
+
+<div class="fragment">
+
++ map
++ fold
++ visitors
++ callbacks
++ ...
+
+</div>
+
+<br>
+
+<div class="fragment">Very difficult with *first-order program logics*</div>
+
+
+Higher Order Specifications
+===========================
+
+Example: Higher Order Loop
+--------------------------
+
+
+<pre><span class=hs-linenum>48: </span><span class='hs-definition'>loop</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span>
+<span class=hs-linenum>49: </span><a class=annot href="#"><span class=annottext>forall a.
+lo:{VV : (Int) | (VV == 0) &amp;&amp; (VV &gt;= 0)}
+-&gt; hi:{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= lo)}
+-&gt; a
+-&gt; ({VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= lo) &amp;&amp; (VV &lt; hi)} -&gt; a -&gt; a)
+-&gt; a</span><span class='hs-definition'>loop</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV == 0) &amp;&amp; (VV &gt;= 0)}</span><span class='hs-varid'>lo</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= lo)}</span><span class='hs-varid'>hi</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>base</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= lo) &amp;&amp; (VV &lt; hi)} -&gt; a -&gt; a</span><span class='hs-varid'>f</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 &gt;= 0) &amp;&amp; (x4 &gt;= lo) &amp;&amp; (x4 &lt;= hi)} -&gt; a -&gt; a</span><span class='hs-varid'>go</span></a> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == 0) &amp;&amp; (x4 == lo) &amp;&amp; (x4 &gt;= 0)}</span><span class='hs-varid'>lo</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == base)}</span><span class='hs-varid'>base</span></a>
+<span class=hs-linenum>50: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>51: </span>    <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= lo) &amp;&amp; (VV &lt;= hi)} -&gt; a -&gt; a</span><span class='hs-varid'>go</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= lo) &amp;&amp; (VV &lt;= hi)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>acc</span></a> 
+<span class=hs-linenum>52: </span>      <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == i) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (x5 &gt;= lo) &amp;&amp; (x5 &lt;= hi)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>x1:{x12 : (Int) | (x12 &gt;= 0) &amp;&amp; (x12 &gt;= i) &amp;&amp; (x12 &gt;= lo) &amp;&amp; (x12 &lt;= hi)}
+-&gt; x2:{x12 : (Int) | (x12 &gt;= 0) &amp;&amp; (x12 &gt;= i) &amp;&amp; (x12 &gt;= lo) &amp;&amp; (x12 &lt;= hi)}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>&lt;</span></a> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == hi) &amp;&amp; (x4 &gt;= 0) &amp;&amp; (x4 &gt;= lo)}</span><span class='hs-varid'>hi</span></a>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= lo) &amp;&amp; (VV &lt;= hi)} -&gt; a -&gt; a</span><span class='hs-varid'>go</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == i) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (x5 &gt;= lo) &amp;&amp; (x5 &lt;= hi)}</span><span class='hs-varid'>i</span></a><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 &gt;= 0) &amp;&amp; (x4 &gt;= lo) &amp;&amp; (x4 &lt; hi)} -&gt; a -&gt; a</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == i) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (x5 &gt;= lo) &amp;&amp; (x5 &lt;= hi)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == acc)}</span><span class='hs-varid'>acc</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>53: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == acc)}</span><span class='hs-varid'>acc</span></a>
+</pre>
+
+<br>
+
+LiquidHaskell infers `f` called with values `(Btwn lo hi)`
+
+
+Example: Summing Lists
+----------------------
+
+
+<pre><span class=hs-linenum>65: </span><a class=annot href="#"><span class=annottext>forall a. (Num a) =&gt; [a] -&gt; a</span><span class='hs-definition'>listSum</span></a> <a class=annot href="#"><span class=annottext>[a]</span><span class='hs-varid'>xs</span></a>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x12 : (Int) | (x12 == 0) &amp;&amp; (x12 &gt;= 0)}
+-&gt; x2:{x9 : (Int) | (x9 &gt;= 0) &amp;&amp; (x9 &gt;= x1)}
+-&gt; a
+-&gt; ({x6 : (Int) | (x6 &gt;= 0) &amp;&amp; (x6 &gt;= x1) &amp;&amp; (x6 &lt; x2)} -&gt; a -&gt; a)
+-&gt; a</span><span class='hs-varid'>loop</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 == (len xs))}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 &gt;= 0) &amp;&amp; (x3 &lt; n)} -&gt; a -&gt; a</span><span class='hs-varid'>body</span></a> 
+<span class=hs-linenum>66: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>67: </span>    <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; n)} -&gt; a -&gt; a</span><span class='hs-varid'>body</span></a>    <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>\</span><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; n)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>acc</span></a> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == acc)}</span><span class='hs-varid'>acc</span></a> <a class=annot href="#"><span class=annottext>x1:a -&gt; x2:a -&gt; {VV : a | (VV == (x1 + x2))}</span><span class='hs-varop'>+</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x4 : [a] | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a> <a class=annot href="#"><span class=annottext>x1:[a] -&gt; {x3 : (Int) | (x3 &lt; (len x1)) &amp;&amp; (0 &lt;= x3)} -&gt; a</span><span class='hs-varop'>!!</span></a> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == i) &amp;&amp; (x4 &gt;= 0) &amp;&amp; (x4 &lt; n)}</span><span class='hs-varid'>i</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>68: </span>    <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (len xs))}</span><span class='hs-varid'>n</span></a>       <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:[a] -&gt; {x2 : (Int) | (x2 == (len x1))}</span><span class='hs-varid'>length</span></a> <a class=annot href="#"><span class=annottext>{x4 : [a] | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+</pre>
+
+<br>
+
+- <div class="fragment">*Function subtyping:* `body` called on `i :: Btwn 0 (llen xs)`</div>
+- <div class="fragment">Hence, indexing with `!!` is safe.</div>
+
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Loop.hs" target= "_blank">Demo:</a> Tweak `loop` exit condition? 
+</div>
+
+Example: Summing `Nat`s
+-----------------------
+
+<br>
+
+
+<pre><span class=hs-linenum>87: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>listNatSum</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Nat</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nat</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>88: </span><a class=annot href="#"><span class=annottext>[{VV : (Int) | (VV &gt;= 0)}] -&gt; {VV : (Int) | (VV &gt;= 0)}</span><span class='hs-definition'>listNatSum</span></a> <a class=annot href="#"><span class=annottext>[{VV : (Int) | (VV &gt;= 0)}]</span><span class='hs-varid'>xs</span></a>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x20 : (Int) | (x20 == 0) &amp;&amp; (x20 &gt;= 0)}
+-&gt; x2:{x17 : (Int) | (x17 &gt;= 0) &amp;&amp; (x17 &gt;= x1)}
+-&gt; {x14 : (Int) | (x14 &gt;= 0)}
+-&gt; ({x12 : (Int) | (x12 &gt;= 0) &amp;&amp; (x12 &gt;= x1) &amp;&amp; (x12 &lt; x2)}
+    -&gt; {x14 : (Int) | (x14 &gt;= 0)} -&gt; {x14 : (Int) | (x14 &gt;= 0)})
+-&gt; {x14 : (Int) | (x14 &gt;= 0)}</span><span class='hs-varid'>loop</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 == (len xs))}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>{x8 : (Int) | (x8 &gt;= 0) &amp;&amp; (x8 &lt; n)}
+-&gt; x2:{x5 : (Int) | (x5 &gt;= 0)}
+-&gt; {x3 : (Int) | (x3 &gt;= 0) &amp;&amp; (x3 &gt;= x2)}</span><span class='hs-varid'>body</span></a> 
+<span class=hs-linenum>89: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>90: </span>    <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; n)}
+-&gt; acc:{VV : (Int) | (VV &gt;= 0)}
+-&gt; {VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= acc)}</span><span class='hs-varid'>body</span></a>       <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>\</span><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; n)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>acc</span></a> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == acc) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>acc</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x4 : [{x7 : (Int) | (x7 &gt;= 0)}] | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a> <a class=annot href="#"><span class=annottext>x1:[{x9 : (Int) | (x9 &gt;= 0)}]
+-&gt; {x5 : (Int) | (x5 &lt; (len x1)) &amp;&amp; (0 &lt;= x5)}
+-&gt; {x9 : (Int) | (x9 &gt;= 0)}</span><span class='hs-varop'>!!</span></a> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == i) &amp;&amp; (x4 &gt;= 0) &amp;&amp; (x4 &lt; n)}</span><span class='hs-varid'>i</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>91: </span>    <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (len xs))}</span><span class='hs-varid'>n</span></a>          <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:[{x6 : (Int) | (x6 &gt;= 0)}] -&gt; {x2 : (Int) | (x2 == (len x1))}</span><span class='hs-varid'>length</span></a> <a class=annot href="#"><span class=annottext>{x4 : [{x7 : (Int) | (x7 &gt;= 0)}] | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+</pre>
+
+<br>
+
+<div class="fragment" align="center">
+
+----  ----  ---------------------------------------
+ (+)  `::`  `x:Int -> y:Int -> {v:Int| v=x+y}`
+      `<:`  `Nat   -> Nat   -> Nat`
+----  ----  ---------------------------------------
+
+</div>
+
+Example: Summing `Nat`s
+-----------------------
+
+ <br> 
+<pre><span class=hs-linenum>109: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>listNatSum</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Nat</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nat</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>110: </span><span class='hs-definition'>listNatSum</span> <span class='hs-varid'>xs</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>loop</span> <span class='hs-num'>0</span> <span class='hs-varid'>n</span> <span class='hs-num'>0</span> <span class='hs-varid'>body</span> 
+<span class=hs-linenum>111: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>112: </span>    <span class='hs-varid'>body</span>       <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>i</span> <span class='hs-varid'>acc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>acc</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>xs</span> <span class='hs-varop'>!!</span> <span class='hs-varid'>i</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>113: </span>    <span class='hs-varid'>n</span>          <span class='hs-keyglyph'>=</span> <span class='hs-varid'>length</span> <span class='hs-varid'>xs</span>
+</pre>
+
+<br>
+
+Hence, verified by *instantiating* `α` of `loop` with `Nat`
+
+<div class="fragment">`Int -> Int -> Nat -> (Int -> Nat -> Nat) -> Nat`</div>
+
+Example: Summing `Nat`s
+-----------------------
+
+ <br> 
+<pre><span class=hs-linenum>126: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>listNatSum</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Nat</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nat</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>127: </span><span class='hs-definition'>listNatSum</span> <span class='hs-varid'>xs</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>loop</span> <span class='hs-num'>0</span> <span class='hs-varid'>n</span> <span class='hs-num'>0</span> <span class='hs-varid'>body</span> 
+<span class=hs-linenum>128: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>129: </span>    <span class='hs-varid'>body</span>       <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>i</span> <span class='hs-varid'>acc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>acc</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>xs</span> <span class='hs-varop'>!!</span> <span class='hs-varid'>i</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>130: </span>    <span class='hs-varid'>n</span>          <span class='hs-keyglyph'>=</span> <span class='hs-varid'>length</span> <span class='hs-varid'>xs</span>
+</pre>
+
+<br>
+
++ Parameter `α` corresponds to *loop invariant*
+
++ Instantiation corresponds to invariant *synthesis*
+
+
+Instantiation And Inference
+---------------------------
+
++ <div class="fragment">Polymorphic instantiation happens *everywhere*</div> 
+
++ <div class="fragment">Automatic inference is crucial</div>
+
++ <div class="fragment">*Cannot use* unification (unlike indexed approaches)</div>
+
++ <div class="fragment">*Can reuse* [SMT/predicate abstraction.](http://goto.ucsd.edu/~rjhala/papers/liquid_types.html)</div>
+
+
+
+Iteration Dependence
+--------------------
+
+**Cannot** use parametric polymorphism to verify:
+
+<br>
+
+
+<pre><span class=hs-linenum>161: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>add</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>m</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span><span class='hs-keyword'>|v=m+n}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>162: </span><a class=annot href="#"><span class=annottext>n:{VV : (Int) | (VV &gt;= 0)}
+-&gt; m:{VV : (Int) | (VV &gt;= 0)}
+-&gt; {VV : (Int) | (VV == (m + n)) &amp;&amp; (VV &gt;= 0)}</span><span class='hs-definition'>add</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>m</span></a> <span class='hs-keyglyph'>=</span> <span class=hs-error><a class=annot href="#"><span class=annottext>x1:{x24 : (Int) | (x24 == 0) &amp;&amp; (x24 &gt;= 0)}
+-&gt; x2:{x21 : (Int) | (x21 &gt;= 0) &amp;&amp; (x21 &gt;= x1)}
+-&gt; {x18 : (Int) | (x18 &gt;= 0) &amp;&amp; (x18 &gt;= n)}
+-&gt; ({x15 : (Int) | (x15 &gt;= 0) &amp;&amp; (x15 &gt;= x1) &amp;&amp; (x15 &lt; x2)}
+    -&gt; {x18 : (Int) | (x18 &gt;= 0) &amp;&amp; (x18 &gt;= n)}
+    -&gt; {x18 : (Int) | (x18 &gt;= 0) &amp;&amp; (x18 &gt;= n)})
+-&gt; {x18 : (Int) | (x18 &gt;= 0) &amp;&amp; (x18 &gt;= n)}</span><span class='hs-varid'>loop</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == m) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>m</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>n</span></a></span><span class=hs-error> </span><span class=hs-error><span class='hs-layout'>(</span></span><span class=hs-error><a class=annot href="#"><span class=annottext>{x11 : (Int) | (x11 &gt;= 0) &amp;&amp; (x11 &lt; m)}
+-&gt; x2:{x8 : (Int) | (x8 &gt;= 0) &amp;&amp; (x8 &gt;= n)}
+-&gt; {x5 : (Int) | (x5 &gt; 0) &amp;&amp; (x5 &gt; x2) &amp;&amp; (x5 &gt; n) &amp;&amp; (x5 &gt;= 0)}</span><span class='hs-keyglyph'>\</span></a></span><span class=hs-error><span class='hs-keyword'>_</span></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= n)}</span><span class='hs-varid'>i</span></a></span><span class=hs-error> </span><span class=hs-error><span class='hs-keyglyph'>-&gt;</span></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == i) &amp;&amp; (x4 &gt;= 0) &amp;&amp; (x4 &gt;= n)}</span><span class='hs-varid'>i</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a></span><span class=hs-error><span class='hs-layout'>)</span></span>
+</pre>
+
+<br>
+
+
+- <div class="fragment">As property only holds after **last** loop iteration...</div>
+
+- <div class="fragment">... cannot instantiate `α` with `{v:Int | v = n + m}`</div>
+
+<div class="fragment">**Problem:** Need *iteration-dependent* invariants...</div>
+
diff --git a/docs/slides/plpv14/lhs/04_AbstractRefinements.lhs b/docs/slides/plpv14/lhs/04_AbstractRefinements.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/04_AbstractRefinements.lhs
@@ -0,0 +1,303 @@
+  {#abstractrefinements}
+========================
+
+<div class="hidden">
+
+\begin{code}
+module AbstractRefinements where
+
+import Prelude 
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+o, no        :: Int
+maxInt       :: Int -> Int -> Int
+\end{code}
+</div>
+
+
+
+Abstract Refinements
+--------------------
+
+
+
+Abstract Refinements
+====================
+
+Two Problems
+------------
+
+<div class="fragment">
+
+**Problem 1:** 
+
+How do we specify *both* [increasing and decreasing lists](http://web.cecs.pdx.edu/~sheard/Code/QSort.html)?
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Problem 2:** 
+
+How do we specify *iteration-dependence* in higher-order functions?
+
+</div>
+
+
+Problem Is Pervasive
+--------------------
+
+Lets distill it to a simple example...
+
+<div class="fragment">
+
+<br>
+
+(First, a few aliases)
+
+<br>
+
+\begin{code}
+{-@ type Odd  = {v:Int | (v mod 2) = 1} @-}
+{-@ type Even = {v:Int | (v mod 2) = 0} @-}
+\end{code}
+
+</div>
+
+
+Example: `maxInt` 
+-----------------
+
+Compute the larger of two `Int`s:
+
+\begin{code} <br> 
+maxInt     :: Int -> Int -> Int 
+maxInt x y = if y <= x then x else y
+\end{code}
+
+
+
+Example: `maxInt` 
+-----------------
+
+Has *many incomparable* refinement types
+
+\begin{code}<br>
+maxInt :: Nat  -> Nat  -> Nat
+maxInt :: Even -> Even -> Even
+maxInt :: Odd  -> Odd  -> Odd 
+\end{code}
+
+<br>
+
+<div class="fragment">Yikes. **Which** one should we use?</div>
+
+
+Refinement Polymorphism 
+-----------------------
+
+`maxInt` returns *one of* its two inputs `x` and `y` 
+
+<div align="center">
+
+<br>
+
+---------   ---   -------------------------------------------
+   **If**    :    the *inputs* satisfy a property  
+
+ **Then**    :    the *output* satisfies that property
+---------   ---   -------------------------------------------
+
+<br>
+
+</div>
+
+<div class="fragment">Above holds *for all* properties!</div>
+
+<br>
+
+<div class="fragment"> 
+
+**Need to abstract refinements over types**
+
+</div>
+
+
+By Type Polymorphism?
+---------------------
+
+\begin{code} <br> 
+max     :: α -> α -> α 
+max x y = if y <= x then x else y
+\end{code}
+
+<div class="fragment"> 
+
+Instantiate `α` at callsites
+
+\begin{code}
+{-@ o :: Odd  @-}
+o = maxInt 3 7     -- α := Odd
+
+{-@ e :: Even @-}
+e = maxInt 2 8     -- α := Even
+\end{code}
+
+</div>
+
+By Type Polymorphism?
+---------------------
+
+\begin{code} <br> 
+max     :: α -> α -> α 
+max x y = if y <= x then x else y
+\end{code}
+
+<br>
+
+But there is a fly in the ointment ...
+
+Polymorphic `max` in Haskell
+----------------------------
+
+\begin{code} In Haskell the type of max is
+max :: (Ord α) => α -> α -> α
+\end{code}
+
+<br>
+
+\begin{code} Could *ignore* the class constraints, instantiate as before...
+{-@ o :: Odd @-}
+o     = max 3 7  -- α := Odd 
+\end{code}
+
+
+Polymorphic `(+)` in Haskell
+----------------------------
+
+\begin{code} ... but this is *unsound*!
+max :: (Ord α) => α -> α -> α
+(+) :: (Num α) => α -> α -> α
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+*Ignoring* class constraints would let us "prove":
+
+\begin{code}
+{-@ no :: Odd @-}
+no     = 3 + 7    -- α := Odd !
+\end{code}
+
+</div>
+
+Type Polymorphism? No.
+----------------------
+
+<div class="fragment">Need to try a bit harder...</div>
+
+By Parametric Refinements!
+--------------------------
+
+That is, enable *quantification over refinements*...
+
+Parametric Refinements 
+----------------------
+
+\begin{code}
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+
+<div class="fragment">Type says: **for any** `p` that is a property of `Int`, </div>
+
+- <div class="fragment">`max` **takes** two `Int`s that satisfy `p`,</div>
+
+- <div class="fragment">`max` **returns** an `Int` that satisfies `p`.</div>
+
+Parametric Refinements 
+----------------------
+
+\begin{code}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+[Key idea: ](http://goto.ucsd.edu/~rjhala/papers/abstract_refinement_types.html) `Int<p>` is `{v:Int | (p v)}`
+
+<br>
+
+<div class="fragment">So, Abstract Refinement is an *uninterpreted function* in SMT logic</div>
+
+Parametric Refinements 
+----------------------
+
+\begin{code}<br>
+{-@ maxInt :: forall <p :: Int -> Prop>. 
+                Int<p> -> Int<p> -> Int<p>  @-}
+
+maxInt x y = if x <= y then y else x 
+\end{code}
+
+<br>
+
+**Check** and **Instantiate** type using *SMT & predicate abstraction*
+
+Using Abstract Refinements
+--------------------------
+
+- <div class="fragment">**When** we call `maxInt` with args with some refinement,</div>
+
+- <div class="fragment">**Then** `p` instantiated with *same* refinement,</div>
+
+- <div class="fragment">**Result** of call will also have concrete refinement.</div>
+
+<div class="fragment">
+
+\begin{code}
+{-@ o' :: Odd  @-}
+o' = maxInt 3 7     -- p := \v -> Odd v 
+
+{-@ e' :: Even @-}
+e' = maxInt 2 8     -- p := \v -> Even v 
+\end{code}
+
+</div>
+
+Using Abstract Refinements
+--------------------------
+
+Or any other property 
+
+<br>
+
+\begin{code}
+{-@ type RGB = {v:_ | (0 <= v && v < 256)} @-}
+
+{-@ rgb :: RGB @-}
+rgb = maxInt 56 8
+\end{code}
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. <div class="fragment">**Abstract:** Refinements over Type Signatures</div>
+
diff --git a/docs/slides/plpv14/lhs/04_AbstractRefinements.lhs.markdown b/docs/slides/plpv14/lhs/04_AbstractRefinements.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/04_AbstractRefinements.lhs.markdown
@@ -0,0 +1,317 @@
+  {#abstractrefinements}
+========================
+
+<div class="hidden">
+
+
+<pre><span class=hs-linenum>7: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>AbstractRefinements</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>8: </span>
+<span class=hs-linenum>9: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> 
+<span class=hs-linenum>10: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>Liquid</span><span class='hs-varop'>.</span><span class='hs-conid'>Prelude</span>
+<span class=hs-linenum>11: </span><span class='hs-keyword'>{-@</span> <span class='hs-conid'>LIQUID</span> <span class='hs-str'>"--no-termination"</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>12: </span>
+<span class=hs-linenum>13: </span><span class='hs-definition'>o</span><span class='hs-layout'>,</span> <span class='hs-varid'>no</span>        <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>14: </span><span class='hs-definition'>maxInt</span>       <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+</pre>
+</div>
+
+
+
+Abstract Refinements
+--------------------
+
+
+
+Abstract Refinements
+====================
+
+Two Problems
+------------
+
+<div class="fragment">
+
+**Problem 1:** 
+
+How do we specify *both* [increasing and decreasing lists](http://web.cecs.pdx.edu/~sheard/Code/QSort.html)?
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+**Problem 2:** 
+
+How do we specify *iteration-dependence* in higher-order functions?
+
+</div>
+
+
+Problem Is Pervasive
+--------------------
+
+Lets distill it to a simple example...
+
+<div class="fragment">
+
+<br>
+
+(First, a few aliases)
+
+<br>
+
+
+<pre><span class=hs-linenum>64: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Odd</span>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>v</span> <span class='hs-varid'>mod</span> <span class='hs-num'>2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>65: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Even</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>v</span> <span class='hs-varid'>mod</span> <span class='hs-num'>2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+</div>
+
+
+Example: `maxInt` 
+-----------------
+
+Compute the larger of two `Int`s:
+
+ <br> 
+<pre><span class=hs-linenum>77: </span><span class='hs-definition'>maxInt</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> 
+<span class=hs-linenum>78: </span><span class='hs-definition'>maxInt</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>y</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>y</span>
+</pre>
+
+
+
+Example: `maxInt` 
+-----------------
+
+Has *many incomparable* refinement types
+
+<br>
+<pre><span class=hs-linenum>89: </span><span class='hs-definition'>maxInt</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Nat</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nat</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nat</span>
+<span class=hs-linenum>90: </span><span class='hs-definition'>maxInt</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Even</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Even</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Even</span>
+<span class=hs-linenum>91: </span><span class='hs-definition'>maxInt</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Odd</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Odd</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Odd</span> 
+</pre>
+
+<br>
+
+<div class="fragment">Yikes. **Which** one should we use?</div>
+
+
+Refinement Polymorphism 
+-----------------------
+
+`maxInt` returns *one of* its two inputs `x` and `y` 
+
+<div align="center">
+
+<br>
+
+---------   ---   -------------------------------------------
+   **If**    :    the *inputs* satisfy a property  
+
+ **Then**    :    the *output* satisfies that property
+---------   ---   -------------------------------------------
+
+<br>
+
+</div>
+
+<div class="fragment">Above holds *for all* properties!</div>
+
+<br>
+
+<div class="fragment"> 
+
+**Need to abstract refinements over types**
+
+</div>
+
+
+By Type Polymorphism?
+---------------------
+
+ <br> 
+<pre><span class=hs-linenum>133: </span><span class='hs-definition'>max</span>     <span class='hs-keyglyph'>::</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> 
+<span class=hs-linenum>134: </span><span class='hs-definition'>max</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>y</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>y</span>
+</pre>
+
+<div class="fragment"> 
+
+Instantiate `α` at callsites
+
+
+<pre><span class=hs-linenum>142: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>o</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Odd</span>  <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>143: </span><a class=annot href="#"><span class=annottext>{VV : (Int) | ((VV mod 2) == 1)}</span><span class='hs-definition'>o</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; Bool&gt;.
+{x3 : (Int)&lt;p&gt; | true}
+-&gt; {x2 : (Int)&lt;p&gt; | true} -&gt; {x1 : (Int)&lt;p&gt; | true}</span><span class='hs-varid'>maxInt</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (7  :  int))}</span><span class='hs-num'>7</span></a>     <span class='hs-comment'>-- α := Odd</span>
+<span class=hs-linenum>144: </span>
+<span class=hs-linenum>145: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Even</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>146: </span><a class=annot href="#"><span class=annottext>{VV : (Int) | ((VV mod 2) == 0)}</span><span class='hs-definition'>e</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; Bool&gt;.
+{x3 : (Int)&lt;p&gt; | true}
+-&gt; {x2 : (Int)&lt;p&gt; | true} -&gt; {x1 : (Int)&lt;p&gt; | true}</span><span class='hs-varid'>maxInt</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (8  :  int))}</span><span class='hs-num'>8</span></a>     <span class='hs-comment'>-- α := Even</span>
+</pre>
+
+</div>
+
+By Type Polymorphism?
+---------------------
+
+ <br> 
+<pre><span class=hs-linenum>155: </span><span class='hs-definition'>max</span>     <span class='hs-keyglyph'>::</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> 
+<span class=hs-linenum>156: </span><span class='hs-definition'>max</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>y</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>y</span>
+</pre>
+
+<br>
+
+But there is a fly in the ointment ...
+
+Polymorphic `max` in Haskell
+----------------------------
+
+ In Haskell the type of max is
+<pre><span class=hs-linenum>167: </span><span class='hs-definition'>max</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>α</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span>
+</pre>
+
+<br>
+
+ Could *ignore* the class constraints, instantiate as before...
+<pre><span class=hs-linenum>173: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>o</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Odd</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>174: </span><span class='hs-definition'>o</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>max</span> <span class='hs-num'>3</span> <span class='hs-num'>7</span>  <span class='hs-comment'>-- α := Odd </span>
+</pre>
+
+
+Polymorphic `(+)` in Haskell
+----------------------------
+
+ ... but this is *unsound*!
+<pre><span class=hs-linenum>182: </span><span class='hs-definition'>max</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>α</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span>
+<span class=hs-linenum>183: </span><span class='hs-layout'>(</span><span class='hs-varop'>+</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Num</span> <span class='hs-varid'>α</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+
+*Ignoring* class constraints would let us "prove":
+
+
+<pre><span class=hs-linenum>193: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>no</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Odd</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>194: </span><a class=annot href="#"><span class=annottext>{VV : (Int) | ((VV mod 2) == 1)}</span><span class='hs-definition'>no</span></a>     <span class='hs-keyglyph'>=</span> <span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (7  :  int))}</span><span class='hs-num'>7</span></a></span>    <span class='hs-comment'>-- α := Odd !</span>
+</pre>
+
+</div>
+
+Type Polymorphism? No.
+----------------------
+
+<div class="fragment">Need to try a bit harder...</div>
+
+By Parametric Refinements!
+--------------------------
+
+That is, enable *quantification over refinements*...
+
+Parametric Refinements 
+----------------------
+
+
+<pre><span class=hs-linenum>213: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>maxInt</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span> 
+<span class=hs-linenum>214: </span>                <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span>  <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>215: </span>
+<span class=hs-linenum>216: </span><a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; Bool&gt;.
+{VV : (Int)&lt;p&gt; | true}
+-&gt; {VV : (Int)&lt;p&gt; | true} -&gt; {VV : (Int)&lt;p&gt; | true}</span><span class='hs-definition'>maxInt</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | ((papp1 p VV))}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | ((papp1 p VV))}</span><span class='hs-varid'>y</span></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | ((papp1 p x3)) &amp;&amp; (x3 == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x1:{x6 : (Int) | ((papp1 p x6))}
+-&gt; x2:{x6 : (Int) | ((papp1 p x6))}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt;= x2))}</span><span class='hs-varop'>&lt;=</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | ((papp1 p x3)) &amp;&amp; (x3 == y)}</span><span class='hs-varid'>y</span></a> <span class='hs-keyword'>then</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | ((papp1 p x3)) &amp;&amp; (x3 == y)}</span><span class='hs-varid'>y</span></a> <span class='hs-keyword'>else</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | ((papp1 p x3)) &amp;&amp; (x3 == x)}</span><span class='hs-varid'>x</span></a> 
+</pre>
+
+<br>
+
+
+<div class="fragment">Type says: **for any** `p` that is a property of `Int`, </div>
+
+- <div class="fragment">`max` **takes** two `Int`s that satisfy `p`,</div>
+
+- <div class="fragment">`max` **returns** an `Int` that satisfies `p`.</div>
+
+Parametric Refinements 
+----------------------
+
+<br>
+<pre><span class=hs-linenum>232: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>maxInt</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span> 
+<span class=hs-linenum>233: </span>                <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span>  <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>234: </span>
+<span class=hs-linenum>235: </span><span class='hs-definition'>maxInt</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>x</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>y</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>y</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>x</span> 
+</pre>
+
+<br>
+
+[Key idea: ](http://goto.ucsd.edu/~rjhala/papers/abstract_refinement_types.html) `Int<p>` is `{v:Int | (p v)}`
+
+<br>
+
+<div class="fragment">So, Abstract Refinement is an *uninterpreted function* in SMT logic</div>
+
+Parametric Refinements 
+----------------------
+
+<br>
+<pre><span class=hs-linenum>250: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>maxInt</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span> 
+<span class=hs-linenum>251: </span>                <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span>  <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>252: </span>
+<span class=hs-linenum>253: </span><span class='hs-definition'>maxInt</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>x</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>y</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>y</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>x</span> 
+</pre>
+
+<br>
+
+**Check** and **Instantiate** type using *SMT & predicate abstraction*
+
+Using Abstract Refinements
+--------------------------
+
+- <div class="fragment">**When** we call `maxInt` with args with some refinement,</div>
+
+- <div class="fragment">**Then** `p` instantiated with *same* refinement,</div>
+
+- <div class="fragment">**Result** of call will also have concrete refinement.</div>
+
+<div class="fragment">
+
+
+<pre><span class=hs-linenum>272: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>o'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Odd</span>  <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>273: </span><a class=annot href="#"><span class=annottext>{VV : (Int) | ((VV mod 2) == 1)}</span><span class='hs-definition'>o'</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; Bool&gt;.
+{x3 : (Int)&lt;p&gt; | true}
+-&gt; {x2 : (Int)&lt;p&gt; | true} -&gt; {x1 : (Int)&lt;p&gt; | true}</span><span class='hs-varid'>maxInt</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (7  :  int))}</span><span class='hs-num'>7</span></a>     <span class='hs-comment'>-- p := \v -&gt; Odd v </span>
+<span class=hs-linenum>274: </span>
+<span class=hs-linenum>275: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>e'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Even</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>276: </span><a class=annot href="#"><span class=annottext>{VV : (Int) | ((VV mod 2) == 0)}</span><span class='hs-definition'>e'</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; Bool&gt;.
+{x3 : (Int)&lt;p&gt; | true}
+-&gt; {x2 : (Int)&lt;p&gt; | true} -&gt; {x1 : (Int)&lt;p&gt; | true}</span><span class='hs-varid'>maxInt</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (8  :  int))}</span><span class='hs-num'>8</span></a>     <span class='hs-comment'>-- p := \v -&gt; Even v </span>
+</pre>
+
+</div>
+
+Using Abstract Refinements
+--------------------------
+
+Or any other property 
+
+<br>
+
+
+<pre><span class=hs-linenum>289: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>RGB</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>v</span> <span class='hs-varop'>&lt;</span> <span class='hs-num'>256</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>290: </span>
+<span class=hs-linenum>291: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>rgb</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RGB</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>292: </span><a class=annot href="#"><span class=annottext>{v : (Int) | (v &lt; 256) &amp;&amp; (0 &lt;= v)}</span><span class='hs-definition'>rgb</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; Bool&gt;.
+{x3 : (Int)&lt;p&gt; | true}
+-&gt; {x2 : (Int)&lt;p&gt; | true} -&gt; {x1 : (Int)&lt;p&gt; | true}</span><span class='hs-varid'>maxInt</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (56  :  int))}</span><span class='hs-num'>56</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (8  :  int))}</span><span class='hs-num'>8</span></a>
+</pre>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. <div class="fragment">**Abstract:** Refinements over Type Signatures</div>
+
diff --git a/docs/slides/plpv14/lhs/05_Composition.lhs b/docs/slides/plpv14/lhs/05_Composition.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/05_Composition.lhs
@@ -0,0 +1,161 @@
+Abstract Refinements {#composition}
+===================================
+
+Very General Mechanism 
+----------------------
+
+**Next:** Lets add parameters...
+
+<div class="hidden">
+\begin{code}
+module Composition where
+
+import Prelude hiding ((.))
+
+plus     :: Int -> Int -> Int
+plus3'   :: Int -> Int
+\end{code}
+</div>
+
+
+Example: `plus`
+---------------
+
+\begin{code}
+{-@ plus :: x:_ -> y:_ -> {v:_ | v=x+y} @-}
+plus x y = x + y
+\end{code}
+
+
+Example: `plus 3` 
+-----------------
+
+<br>
+
+\begin{code}
+{-@ plus3' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3'     = plus 3
+\end{code}
+
+<br>
+
+Easily verified by LiquidHaskell
+
+A Composed Variant
+------------------
+
+Lets define `plus3` by *composition*
+
+A Composition Operator 
+----------------------
+
+\begin{code}
+(#) :: (b -> c) -> (a -> b) -> a -> c
+(#) f g x = f (g x)
+\end{code}
+
+
+`plus3` By Composition
+-----------------------
+
+\begin{code}
+{-@ plus3'' :: x:Int -> {v:Int | v = x + 3} @-}
+plus3''     = plus 1 # plus 2
+\end{code}
+
+<br>
+
+Yikes! Verification *fails*. But why?
+
+<br>
+
+<div class="fragment">(Hover mouse over `#` for a clue)</div>
+
+How to type compose (#) ? 
+-------------------------
+
+This specification is *too weak* <br>
+
+\begin{code} <br>
+(#) :: (b -> c) -> (a -> b) -> (a -> c)
+\end{code}
+
+<br>
+
+Output type does not *relate* `c` with `a`!
+
+How to type compose (.) ?
+-------------------------
+
+Write specification with abstract refinement type:
+
+<br>
+
+\begin{code}
+{-@ (.) :: forall <p :: b->c->Prop, 
+                   q :: a->b->Prop>.
+             f:(x:b -> c<p x>) 
+          -> g:(x:a -> b<q x>) 
+          -> y:a -> exists[z:b<q y>].c<p z>
+ @-}
+(.) f g y = f (g y)
+\end{code}
+
+Using (.) Operator 
+------------------
+
+<br>
+
+\begin{code}
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br>
+
+<div class="fragment">*Verifies!*</div>
+
+
+Using (.) Operator 
+------------------
+
+\begin{code} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br>
+
+LiquidHaskell *instantiates*
+
+- `p` with `\x -> v = x + 1`
+- `q` with `\x -> v = x + 2`
+
+Using (.) Operator 
+------------------
+
+\begin{code} <br>
+{-@ plus3 :: x:Int -> {v:Int | v = x + 3} @-}
+plus3     = plus 1 . plus 2
+\end{code}
+
+<br> To *infer* that output of `plus3` has type: 
+
+`exists [z:{v = y + 2}].{v = z + 1}`
+
+<div class="fragment">
+
+`<:`
+
+`{v:Int|v=3}`
+</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract:** Refinements over Type Signatures
+    + <div class="fragment">*Dependencies* using refinement parameters</div>
diff --git a/docs/slides/plpv14/lhs/05_Composition.lhs.markdown b/docs/slides/plpv14/lhs/05_Composition.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/05_Composition.lhs.markdown
@@ -0,0 +1,169 @@
+Abstract Refinements {#composition}
+===================================
+
+Very General Mechanism 
+----------------------
+
+**Next:** Lets add parameters...
+
+<div class="hidden">
+
+<pre><span class=hs-linenum>11: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>Composition</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>12: </span>
+<span class=hs-linenum>13: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'>.</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>14: </span>
+<span class=hs-linenum>15: </span><span class='hs-definition'>plus</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>16: </span><span class='hs-definition'>plus3'</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+</pre>
+</div>
+
+
+Example: `plus`
+---------------
+
+
+<pre><span class=hs-linenum>25: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>plus</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>y</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyword'>_</span> <span class='hs-keyword'>| v=x+y}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>26: </span><a class=annot href="#"><span class=annottext>x:(Int) -&gt; y:(Int) -&gt; {v : (Int) | (v == (x + y))}</span><span class='hs-definition'>plus</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>y</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == y)}</span><span class='hs-varid'>y</span></a>
+</pre>
+
+
+Example: `plus 3` 
+-----------------
+
+<br>
+
+
+<pre><span class=hs-linenum>36: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>plus3'</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span> <span class='hs-keyword'>| v = x + 3}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>37: </span><a class=annot href="#"><span class=annottext>x:(Int) -&gt; {VV : (Int) | (VV == (x + 3))}</span><span class='hs-definition'>plus3'</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x2 : (Int) | (x2 == (x1 + x2))}</span><span class='hs-varid'>plus</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a>
+</pre>
+
+<br>
+
+Easily verified by LiquidHaskell
+
+A Composed Variant
+------------------
+
+Lets define `plus3` by *composition*
+
+A Composition Operator 
+----------------------
+
+
+<pre><span class=hs-linenum>53: </span><span class='hs-layout'>(</span><span class='hs-cpp'>#</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span>
+<span class=hs-linenum>54: </span><a class=annot href="#"><span class=annottext>forall a b c. (a -&gt; b) -&gt; (c -&gt; a) -&gt; c -&gt; b</span><span class='hs-layout'>(</span></a><span class='hs-cpp'>#</span><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>a -&gt; b</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>a -&gt; b</span><span class='hs-varid'>g</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>x</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>a -&gt; b</span><span class='hs-varid'>f</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>a -&gt; b</span><span class='hs-varid'>g</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a><span class='hs-layout'>)</span>
+</pre>
+
+
+`plus3` By Composition
+-----------------------
+
+
+<pre><span class=hs-linenum>62: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>plus3''</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span> <span class='hs-keyword'>| v = x + 3}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>63: </span><a class=annot href="#"><span class=annottext>x:(Int) -&gt; {VV : (Int) | (VV == (x + 3))}</span><span class='hs-definition'>plus3''</span></a>     <span class='hs-keyglyph'>=</span> <span class=hs-error><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x2 : (Int) | (x2 == (x1 + x2))}</span><span class='hs-varid'>plus</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>((Int) -&gt; (Int)) -&gt; ((Int) -&gt; (Int)) -&gt; (Int) -&gt; (Int)</span><span class='hs-cpp'>#</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x2 : (Int) | (x2 == (x1 + x2))}</span><span class='hs-varid'>plus</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a></span>
+</pre>
+
+<br>
+
+Yikes! Verification *fails*. But why?
+
+<br>
+
+<div class="fragment">(Hover mouse over `#` for a clue)</div>
+
+How to type compose (#) ? 
+-------------------------
+
+This specification is *too weak* <br>
+
+ <br>
+<pre><span class=hs-linenum>80: </span><span class='hs-layout'>(</span><span class='hs-cpp'>#</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+Output type does not *relate* `c` with `a`!
+
+How to type compose (.) ?
+-------------------------
+
+Write specification with abstract refinement type:
+
+<br>
+
+
+<pre><span class=hs-linenum>95: </span><span class='hs-keyword'>{-@</span> <span class='hs-layout'>(</span><span class='hs-varop'>.</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>-&gt;</span><span class='hs-varid'>c</span><span class='hs-keyglyph'>-&gt;</span><span class='hs-conid'>Prop</span><span class='hs-layout'>,</span> 
+<span class=hs-linenum>96: </span>                   <span class='hs-varid'>q</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-keyglyph'>-&gt;</span><span class='hs-varid'>b</span><span class='hs-keyglyph'>-&gt;</span><span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span>
+<span class=hs-linenum>97: </span>             <span class='hs-varid'>f</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>x</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>98: </span>          <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>g</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>q</span> <span class='hs-varid'>x</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>99: </span>          <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>y</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>exists</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>z</span><span class='hs-conop'>:</span><span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>q</span> <span class='hs-varid'>y</span><span class='hs-varop'>&gt;</span><span class='hs-keyglyph'>]</span><span class='hs-varop'>.</span><span class='hs-varid'>c</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>z</span><span class='hs-varop'>&gt;</span>
+<span class=hs-linenum>100: </span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>101: </span><a class=annot href="#"><span class=annottext>forall a b c &lt;p :: b-&gt; a-&gt; Bool, q :: c-&gt; b-&gt; Bool&gt;.
+(x:b -&gt; {VV : a&lt;p x&gt; | true})
+-&gt; (x:c -&gt; {VV : b&lt;q x&gt; | true})
+-&gt; y:c
+-&gt; exists [z:{VV : b&lt;q y&gt; | true}].{VV : a&lt;p z&gt; | true}</span><span class='hs-layout'>(</span></a><span class='hs-varop'>.</span><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>x:a -&gt; {VV : b | ((papp2 p VV x))}</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>x:a -&gt; {VV : b | ((papp2 q VV x))}</span><span class='hs-varid'>g</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>y</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:a -&gt; {VV : b | ((papp2 p VV x1))}</span><span class='hs-varid'>f</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:a -&gt; {VV : b | ((papp2 q VV x1))}</span><span class='hs-varid'>g</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a><span class='hs-layout'>)</span>
+</pre>
+
+Using (.) Operator 
+------------------
+
+<br>
+
+
+<pre><span class=hs-linenum>110: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>plus3</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span> <span class='hs-keyword'>| v = x + 3}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>111: </span><a class=annot href="#"><span class=annottext>x:(Int) -&gt; {VV : (Int) | (VV == (x + 3))}</span><span class='hs-definition'>plus3</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x2 : (Int) | (x2 == (x1 + x2))}</span><span class='hs-varid'>plus</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a> <a class=annot href="#"><span class=annottext>forall &lt;q :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool, p :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+(x:(Int) -&gt; {x8 : (Int)&lt;p x&gt; | true})
+-&gt; (x:(Int) -&gt; {x9 : (Int)&lt;q x&gt; | true})
+-&gt; x3:(Int)
+-&gt; exists [z:{x9 : (Int)&lt;q x3&gt; | true}].{x8 : (Int)&lt;p z&gt; | true}</span><span class='hs-varop'>.</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x2 : (Int) | (x2 == (x1 + x2))}</span><span class='hs-varid'>plus</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">*Verifies!*</div>
+
+
+Using (.) Operator 
+------------------
+
+ <br>
+<pre><span class=hs-linenum>123: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>plus3</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span> <span class='hs-keyword'>| v = x + 3}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>124: </span><span class='hs-definition'>plus3</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>plus</span> <span class='hs-num'>1</span> <span class='hs-varop'>.</span> <span class='hs-varid'>plus</span> <span class='hs-num'>2</span>
+</pre>
+
+<br>
+
+LiquidHaskell *instantiates*
+
+- `p` with `\x -> v = x + 1`
+- `q` with `\x -> v = x + 2`
+
+Using (.) Operator 
+------------------
+
+ <br>
+<pre><span class=hs-linenum>138: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>plus3</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span> <span class='hs-keyword'>| v = x + 3}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>139: </span><span class='hs-definition'>plus3</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>plus</span> <span class='hs-num'>1</span> <span class='hs-varop'>.</span> <span class='hs-varid'>plus</span> <span class='hs-num'>2</span>
+</pre>
+
+<br> To *infer* that output of `plus3` has type: 
+
+`exists [z:{v = y + 2}].{v = z + 1}`
+
+<div class="fragment">
+
+`<:`
+
+`{v:Int|v=3}`
+</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract:** Refinements over Type Signatures
+    + <div class="fragment">*Dependencies* using refinement parameters</div>
diff --git a/docs/slides/plpv14/lhs/06_Inductive.lhs b/docs/slides/plpv14/lhs/06_Inductive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/06_Inductive.lhs
@@ -0,0 +1,464 @@
+Abstract Refinements {#induction}
+=================================
+
+Induction
+---------
+
+Encoding *induction* with Abstract refinements
+
+<div class="hidden">
+
+\begin{code}
+module Loop where
+import Prelude hiding ((!!), foldr, length, (++))
+-- import Measures
+import Language.Haskell.Liquid.Prelude
+{-@ LIQUID "--no-termination" @-}
+
+{-@ measure llen  :: (L a) -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)  @-}
+
+size  :: L a -> Int
+add   :: Int -> Int -> Int
+loop  :: Int -> Int -> α -> (Int -> α -> α) -> α
+foldr :: (L a -> a -> b -> b) -> b -> L a -> b
+\end{code}
+</div>
+
+Induction
+=========
+
+Example: `loop` redux 
+---------------------
+
+Recall the *higher-order* `loop` 
+
+<br>
+
+\begin{code}
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+**Problem**
+
+- As property only holds after *last* loop iteration...
+
+- ... cannot instantiate `α` with `{v:Int | v = n + m}`
+
+</div>
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+**Problem** 
+
+Need invariant relating *iteration* `i` with *accumulator* `acc`
+
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+\begin{code} <br>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat|v=m+n} @-}
+add n m = loop 0 m n (\_ i -> i + 1)
+\end{code}
+
+<br>
+
+**Solution** 
+
+- Abstract Refinement `p :: Int -> a -> Prop`
+
+- `(p i acc)` relates *iteration* `i` with *accumulator* `acc`
+
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+<div class="fragment">
+<div align="center">
+
+------------  ---   ----------------------------
+  **Assume**   :    `out = loop lo hi base f` 
+
+   **Prove**   :    `(p hi out)`
+------------  ---   ----------------------------
+
+</div>
+</div>
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**Base Case** Initial accumulator `base` satisfies invariant
+
+
+`(p base lo)`   
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**Inductive Step** `f` *preserves* invariant at `i`
+
+
+`(p acc i) => (p (f i acc) (i + 1))`
+
+Induction in `loop` (by hand)
+-----------------------------
+
+\begin{code} <br> 
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+\end{code}
+
+<br>
+
+**"By Induction"** `out` satisfies invariant at `hi` 
+
+`(p out hi)`
+
+
+Induction in `loop` (by type)
+-----------------------------
+
+Induction is an **abstract refinement type** for `loop` 
+
+<br>
+
+\begin{code}
+{-@ loop :: forall a <p :: Int -> a -> Prop>.
+        lo:Int 
+     -> hi:{v:Int|lo <= v}
+     -> base:a<p lo>                      
+     -> f:(i:Int -> a<p i> -> a<p (i+1)>) 
+     -> a<p hi>                           @-}
+\end{code}
+
+<br>
+
+Induction in `loop` (by type)
+-----------------------------
+
+`p` is the *index dependent* invariant!
+
+
+\begin{code}<br> 
+p    :: Int -> a -> Prop             -- invt 
+base :: a<p lo>                      -- base 
+f    :: i:Int -> a<p i> -> a<p(i+1)> -- step
+out  :: a<p hi>                      -- goal
+\end{code}
+
+
+
+Using Induction
+---------------
+
+\begin{code}
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br>
+
+**Verified** by instantiating the abstract refinement of `loop`
+
+`p := \i acc -> acc = i + n`
+
+
+Using Induction
+---------------
+
+\begin{code} <div/>
+{-@ add :: n:Nat -> m:Nat -> {v:Nat| v=m+n} @-}
+add n m = loop 0 m n (\_ z -> z + 1)
+\end{code}
+
+<br>
+
+Verified by instantiating `p := \i acc -> acc = i + n`
+
+- <div class="fragment">**Base:**  `n = 0 + n`</div>
+
+- <div class="fragment">**Step:**  `acc = i + n  =>  acc + 1 = (i + 1) + n`</div>
+
+- <div class="fragment">**Goal:**  `out = m + n`</div>
+
+
+Generalizes To Structures 
+-------------------------
+
+Same idea applies for induction over *structures* ...
+
+
+Structural Induction
+====================
+
+Example: Lists
+--------------
+
+<br>
+
+\begin{code}
+data L a = N 
+         | C a (L a)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets write a generic loop over such lists ...
+</div>
+
+Example: `foldr`
+----------------
+
+\begin{code} <br>
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets brace ourselves for the type...
+</div>
+
+Example: `foldr`
+----------------
+
+\begin{code}
+{-@ foldr :: 
+    forall a b <p :: L a -> b -> Prop>. 
+      (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
+    -> b<p N> 
+    -> ys:L a
+    -> b<p ys>                            @-}
+foldr f b N        = b
+foldr f b (C x xs) = f xs x (foldr f b xs)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Lets step through the type...
+</div>
+
+
+`foldr`: Abstract Refinement
+----------------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  ::  b<p ys>                            
+\end{code}
+
+<br>
+
+`(p xs b)` relates `b` with folded `xs`
+
+`p :: L a -> b -> Prop`
+
+
+`foldr`: Base Case
+------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+`base` is related to empty list `N`
+
+`base :: b<p N>` states 
+
+
+
+`foldr`: Ind. Step 
+------------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+`step` extends relation from `xs` to `C x xs`
+
+`step :: xs:L a -> x:a -> b<p xs> -> b<p(C x xs)>`
+
+
+`foldr`: Output
+---------------
+
+\begin{code} <div/>
+p    :: L a -> b -> Prop   
+step :: xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)> 
+base :: b<p N> 
+ys   :: L a
+out  :: b<p ys>                            
+\end{code}
+
+<br>
+
+Relation holds between `out` and input list `ys`
+
+`out :: b<p ys>`
+
+Using `foldr`: Size
+-------------------
+
+We can now verify <br>
+
+\begin{code}
+{-@ size :: xs:_ -> {v:Int| v = (llen xs)} @-}
+size     = foldr (\_ _ n -> n + 1) 0
+\end{code}
+
+<br>
+
+<div class="fragment">
+Verified by automatically instantiating 
+
+`p := \xs acc -> acc = (llen xs)`
+</div>
+
+Using `foldr`: Append
+---------------------
+
+\begin{code}
+{-@ (++) :: xs:_ -> ys:_ -> (Cat a xs ys) @-} 
+xs ++ ys = foldr (\_ -> C) ys xs 
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+where the alias `Cat` is:
+
+<br>
+
+\begin{code}
+{-@ type Cat a X Y = 
+    {v:L a|(llen v) = (llen X) + (llen Y)} @-}
+\end{code}
+
+</div>
+
+Using `foldr`: Append
+---------------------
+
+\begin{code} <div/>
+{-@ (++) :: xs:_ -> ys:_ -> (Cat a xs ys) @-} 
+xs ++ ys = foldr (\_ -> C) ys xs 
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+Verified by automatically instantiating 
+
+`p := \xs acc -> llen acc = llen xs + llen ys`
+
+</div>
+
+Recap
+-----
+
+Abstract refinements decouple *invariant* from *traversal*
+
+<br>
+
++ <div class="fragment">*reusable* specifications for higher-order functions.</div>
+
++ <div class="fragment">*automatic* checking and instantiation by SMT.</div>
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract:** Refinements over Type Signatures
+    + *Dependencies*
+    + <div class="fragment">*Induction*</div>
diff --git a/docs/slides/plpv14/lhs/06_Inductive.lhs.markdown b/docs/slides/plpv14/lhs/06_Inductive.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/06_Inductive.lhs.markdown
@@ -0,0 +1,535 @@
+Abstract Refinements {#induction}
+=================================
+
+Induction
+---------
+
+Encoding *induction* with Abstract refinements
+
+<div class="hidden">
+
+
+<pre><span class=hs-linenum>12: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>Loop</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>13: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'>!!</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>foldr</span><span class='hs-layout'>,</span> <span class='hs-varid'>length</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'>++</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>14: </span><span class='hs-comment'>-- import Measures</span>
+<span class=hs-linenum>15: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>Liquid</span><span class='hs-varop'>.</span><span class='hs-conid'>Prelude</span>
+<span class=hs-linenum>16: </span><span class='hs-keyword'>{-@</span> <span class='hs-conid'>LIQUID</span> <span class='hs-str'>"--no-termination"</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>17: </span>
+<span class=hs-linenum>18: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>measure</span> <span class='hs-varid'>llen</span>  <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>19: </span>    <span class='hs-varid'>llen</span> <span class='hs-layout'>(</span><span class='hs-conid'>N</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span>
+<span class=hs-linenum>20: </span>    <span class='hs-varid'>llen</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span>  <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>21: </span>
+<span class=hs-linenum>22: </span><span class='hs-definition'>size</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>23: </span><span class='hs-definition'>add</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>24: </span><span class='hs-definition'>loop</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>α</span>
+<span class=hs-linenum>25: </span><span class='hs-definition'>foldr</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span>
+</pre>
+</div>
+
+Induction
+=========
+
+Example: `loop` redux 
+---------------------
+
+Recall the *higher-order* `loop` 
+
+<br>
+
+
+<pre><span class=hs-linenum>40: </span><a class=annot href="#"><span class=annottext>forall a &lt;p :: (GHC.Types.Int)-&gt; a-&gt; Bool&gt;.
+lo:(Int)
+-&gt; hi:{VV : (Int) | (lo &lt;= VV)}
+-&gt; {VV : a&lt;p lo&gt; | true}
+-&gt; (i:(Int)
+    -&gt; {VV : a&lt;p i&gt; | true}
+    -&gt; forall [ex:{VV : (Int) | (VV == (i + 1))}].{VV : a&lt;p ex&gt; | true})
+-&gt; {VV : a&lt;p hi&gt; | true}</span><span class='hs-definition'>loop</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>lo</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (lo &lt;= VV)}</span><span class='hs-varid'>hi</span></a> <a class=annot href="#"><span class=annottext>{VV : a | ((papp2 p VV lo))}</span><span class='hs-varid'>base</span></a> <a class=annot href="#"><span class=annottext>i:(Int)
+-&gt; {VV : a | ((papp2 p VV i))}
+-&gt; forall [ex:{VV : (Int) | (VV == (i + 1))}].{VV : a | ((papp2 p VV ex))}</span><span class='hs-varid'>f</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x4 : (Int) | (x4 &gt;= lo) &amp;&amp; (lo &lt;= x4) &amp;&amp; (x4 &lt;= hi)}
+-&gt; {VV : a | ((papp2 p VV x1))} -&gt; {VV : a | ((papp2 p VV hi))}</span><span class='hs-varid'>go</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == lo)}</span><span class='hs-varid'>lo</span></a> <a class=annot href="#"><span class=annottext>{VV : a | ((papp2 p VV lo)) &amp;&amp; (VV == base)}</span><span class='hs-varid'>base</span></a>
+<span class=hs-linenum>41: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>42: </span>    <a class=annot href="#"><span class=annottext>i:{VV : (Int) | (VV &gt;= lo) &amp;&amp; (VV &lt;= hi) &amp;&amp; (lo &lt;= VV)}
+-&gt; {VV : a | ((papp2 p VV i))} -&gt; {VV : a | ((papp2 p VV hi))}</span><span class='hs-varid'>go</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= lo) &amp;&amp; (VV &lt;= hi) &amp;&amp; (lo &lt;= VV)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>{VV : a | ((papp2 p VV i))}</span><span class='hs-varid'>acc</span></a> 
+<span class=hs-linenum>43: </span>      <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == i) &amp;&amp; (x5 &gt;= lo) &amp;&amp; (lo &lt;= x5) &amp;&amp; (x5 &lt;= hi)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>x1:{x14 : (Int) | (x14 &gt;= i) &amp;&amp; (x14 &gt;= lo) &amp;&amp; (i &lt;= x14) &amp;&amp; (lo &lt;= x14) &amp;&amp; (x14 &lt;= hi)}
+-&gt; x2:{x14 : (Int) | (x14 &gt;= i) &amp;&amp; (x14 &gt;= lo) &amp;&amp; (i &lt;= x14) &amp;&amp; (lo &lt;= x14) &amp;&amp; (x14 &lt;= hi)}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>&lt;</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == hi) &amp;&amp; (lo &lt;= x3)}</span><span class='hs-varid'>hi</span></a>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>i:{VV : (Int) | (VV &gt;= lo) &amp;&amp; (VV &lt;= hi) &amp;&amp; (lo &lt;= VV)}
+-&gt; {VV : a | ((papp2 p VV i))} -&gt; {VV : a | ((papp2 p VV hi))}</span><span class='hs-varid'>go</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == i) &amp;&amp; (x5 &gt;= lo) &amp;&amp; (lo &lt;= x5) &amp;&amp; (x5 &lt;= hi)}</span><span class='hs-varid'>i</span></a><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:(Int)
+-&gt; {VV : a | ((papp2 p VV x1))}
+-&gt; forall [ex:{VV : (Int) | (VV == (x1 + 1))}].{VV : a | ((papp2 p VV ex))}</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == i) &amp;&amp; (x5 &gt;= lo) &amp;&amp; (lo &lt;= x5) &amp;&amp; (x5 &lt;= hi)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>{VV : a | ((papp2 p VV i)) &amp;&amp; (VV == acc)}</span><span class='hs-varid'>acc</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>44: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | ((papp2 p VV i)) &amp;&amp; (VV == acc)}</span><span class='hs-varid'>acc</span></a>
+</pre>
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+ <br>
+<pre><span class=hs-linenum>53: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>add</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>m</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span><span class='hs-keyword'>|v=m+n}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>54: </span><span class='hs-definition'>add</span> <span class='hs-varid'>n</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>loop</span> <span class='hs-num'>0</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-keyword'>_</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>i</span> <span class='hs-varop'>+</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+
+**Problem**
+
+- As property only holds after *last* loop iteration...
+
+- ... cannot instantiate `α` with `{v:Int | v = n + m}`
+
+</div>
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+ <br>
+<pre><span class=hs-linenum>75: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>add</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>m</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span><span class='hs-keyword'>|v=m+n}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>76: </span><span class='hs-definition'>add</span> <span class='hs-varid'>n</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>loop</span> <span class='hs-num'>0</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-keyword'>_</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>i</span> <span class='hs-varop'>+</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+**Problem** 
+
+Need invariant relating *iteration* `i` with *accumulator* `acc`
+
+
+Iteration Dependence
+--------------------
+
+We used `loop` to write 
+
+ <br>
+<pre><span class=hs-linenum>92: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>add</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>m</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span><span class='hs-keyword'>|v=m+n}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>93: </span><span class='hs-definition'>add</span> <span class='hs-varid'>n</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>loop</span> <span class='hs-num'>0</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-keyword'>_</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>i</span> <span class='hs-varop'>+</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+**Solution** 
+
+- Abstract Refinement `p :: Int -> a -> Prop`
+
+- `(p i acc)` relates *iteration* `i` with *accumulator* `acc`
+
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+ <br> 
+<pre><span class=hs-linenum>110: </span><span class='hs-definition'>loop</span> <span class='hs-varid'>lo</span> <span class='hs-varid'>hi</span> <span class='hs-varid'>base</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>lo</span> <span class='hs-varid'>base</span>
+<span class=hs-linenum>111: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>112: </span>    <span class='hs-varid'>go</span> <span class='hs-varid'>i</span> <span class='hs-varid'>acc</span> 
+<span class=hs-linenum>113: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>i</span> <span class='hs-varop'>&lt;</span> <span class='hs-varid'>hi</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-varid'>i</span> <span class='hs-varid'>acc</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>114: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>acc</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+<div align="center">
+
+------------  ---   ----------------------------
+  **Assume**   :    `out = loop lo hi base f` 
+
+   **Prove**   :    `(p hi out)`
+------------  ---   ----------------------------
+
+</div>
+</div>
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+ <br> 
+<pre><span class=hs-linenum>136: </span><span class='hs-definition'>loop</span> <span class='hs-varid'>lo</span> <span class='hs-varid'>hi</span> <span class='hs-varid'>base</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>lo</span> <span class='hs-varid'>base</span>
+<span class=hs-linenum>137: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>138: </span>    <span class='hs-varid'>go</span> <span class='hs-varid'>i</span> <span class='hs-varid'>acc</span> 
+<span class=hs-linenum>139: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>i</span> <span class='hs-varop'>&lt;</span> <span class='hs-varid'>hi</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-varid'>i</span> <span class='hs-varid'>acc</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>140: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>acc</span>
+</pre>
+
+<br>
+
+**Base Case** Initial accumulator `base` satisfies invariant
+
+
+`(p base lo)`   
+
+
+Induction in `loop` (by hand)
+-----------------------------
+
+ <br> 
+<pre><span class=hs-linenum>155: </span><span class='hs-definition'>loop</span> <span class='hs-varid'>lo</span> <span class='hs-varid'>hi</span> <span class='hs-varid'>base</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>lo</span> <span class='hs-varid'>base</span>
+<span class=hs-linenum>156: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>157: </span>    <span class='hs-varid'>go</span> <span class='hs-varid'>i</span> <span class='hs-varid'>acc</span> 
+<span class=hs-linenum>158: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>i</span> <span class='hs-varop'>&lt;</span> <span class='hs-varid'>hi</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-varid'>i</span> <span class='hs-varid'>acc</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>159: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>acc</span>
+</pre>
+
+<br>
+
+**Inductive Step** `f` *preserves* invariant at `i`
+
+
+`(p acc i) => (p (f i acc) (i + 1))`
+
+Induction in `loop` (by hand)
+-----------------------------
+
+ <br> 
+<pre><span class=hs-linenum>173: </span><span class='hs-definition'>loop</span> <span class='hs-varid'>lo</span> <span class='hs-varid'>hi</span> <span class='hs-varid'>base</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>lo</span> <span class='hs-varid'>base</span>
+<span class=hs-linenum>174: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>175: </span>    <span class='hs-varid'>go</span> <span class='hs-varid'>i</span> <span class='hs-varid'>acc</span> 
+<span class=hs-linenum>176: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>i</span> <span class='hs-varop'>&lt;</span> <span class='hs-varid'>hi</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-varid'>i</span> <span class='hs-varid'>acc</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>177: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>acc</span>
+</pre>
+
+<br>
+
+**"By Induction"** `out` satisfies invariant at `hi` 
+
+`(p out hi)`
+
+
+Induction in `loop` (by type)
+-----------------------------
+
+Induction is an **abstract refinement type** for `loop` 
+
+<br>
+
+
+<pre><span class=hs-linenum>195: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>loop</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varid'>a</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span>
+<span class=hs-linenum>196: </span>        <span class='hs-varid'>lo</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> 
+<span class=hs-linenum>197: </span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>hi</span><span class='hs-conop'>:</span><span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span><span class='hs-keyword'>|lo &lt;= v}</span>
+<span class=hs-linenum>198: </span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>base</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>lo</span><span class='hs-varop'>&gt;</span>                      
+<span class=hs-linenum>199: </span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>f</span><span class='hs-conop'>:</span><span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>i</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>200: </span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>hi</span><span class='hs-varop'>&gt;</span>                           <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+Induction in `loop` (by type)
+-----------------------------
+
+`p` is the *index dependent* invariant!
+
+
+<br> 
+<pre><span class=hs-linenum>212: </span><span class='hs-definition'>p</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>             <span class='hs-comment'>-- invt </span>
+<span class=hs-linenum>213: </span><span class='hs-definition'>base</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>lo</span><span class='hs-varop'>&gt;</span>                      <span class='hs-comment'>-- base </span>
+<span class=hs-linenum>214: </span><span class='hs-definition'>f</span>    <span class='hs-keyglyph'>::</span> <span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>i</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-varop'>&gt;</span> <span class='hs-comment'>-- step</span>
+<span class=hs-linenum>215: </span><span class='hs-definition'>out</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>hi</span><span class='hs-varop'>&gt;</span>                      <span class='hs-comment'>-- goal</span>
+</pre>
+
+
+
+Using Induction
+---------------
+
+
+<pre><span class=hs-linenum>224: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>add</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>m</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span><span class='hs-keyword'>| v=m+n}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>225: </span><a class=annot href="#"><span class=annottext>n:{VV : (Int) | (VV &gt;= 0)}
+-&gt; m:{VV : (Int) | (VV &gt;= 0)}
+-&gt; {VV : (Int) | (VV == (m + n)) &amp;&amp; (VV &gt;= 0)}</span><span class='hs-definition'>add</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>m</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+x1:(Int)
+-&gt; x2:{x21 : (Int) | (x1 &lt;= x21)}
+-&gt; {x19 : (Int)&lt;p x1&gt; | (x19 &gt;= 0) &amp;&amp; (x19 &gt;= n) &amp;&amp; (n &lt;= x19)}
+-&gt; (i:(Int)
+    -&gt; {x19 : (Int)&lt;p i&gt; | (x19 &gt;= 0) &amp;&amp; (x19 &gt;= n) &amp;&amp; (n &lt;= x19)}
+    -&gt; forall [ex:{VV : (Int) | (VV == (i + 1))}].{x19 : (Int)&lt;p ex&gt; | (x19 &gt;= 0) &amp;&amp; (x19 &gt;= n) &amp;&amp; (n &lt;= x19)})
+-&gt; {x19 : (Int)&lt;p x2&gt; | (x19 &gt;= 0) &amp;&amp; (x19 &gt;= n) &amp;&amp; (n &lt;= x19)}</span><span class='hs-varid'>loop</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == m) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>m</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>n</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:(Int)
+-&gt; x2:{x17 : (Int) | (x17 == (x1 + n)) &amp;&amp; (x17 == (n + x1)) &amp;&amp; (x17 &gt;= 0) &amp;&amp; (x17 &gt;= x1) &amp;&amp; (x17 &gt;= n) &amp;&amp; (x1 &lt;= x17) &amp;&amp; (n &lt;= x17)}
+-&gt; {x9 : (Int) | (x9 == (x2 + 1)) &amp;&amp; (x9 &gt; 0) &amp;&amp; (x9 &gt; x1) &amp;&amp; (x9 &gt; x2) &amp;&amp; (x9 &gt; n) &amp;&amp; (x9 &gt;= 0) &amp;&amp; (x1 &lt;= x9) &amp;&amp; (n &lt;= x9)}</span><span class='hs-keyglyph'>\</span></a><span class='hs-keyword'>_</span> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &gt;= n) &amp;&amp; (n &lt;= VV)}</span><span class='hs-varid'>z</span></a> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == z) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (x5 &gt;= n) &amp;&amp; (n &lt;= x5)}</span><span class='hs-varid'>z</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+**Verified** by instantiating the abstract refinement of `loop`
+
+`p := \i acc -> acc = i + n`
+
+
+Using Induction
+---------------
+
+ <div/>
+<pre><span class=hs-linenum>239: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>add</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>m</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span><span class='hs-keyword'>| v=m+n}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>240: </span><span class='hs-definition'>add</span> <span class='hs-varid'>n</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>loop</span> <span class='hs-num'>0</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-keyword'>_</span> <span class='hs-varid'>z</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>z</span> <span class='hs-varop'>+</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+Verified by instantiating `p := \i acc -> acc = i + n`
+
+- <div class="fragment">**Base:**  `n = 0 + n`</div>
+
+- <div class="fragment">**Step:**  `acc = i + n  =>  acc + 1 = (i + 1) + n`</div>
+
+- <div class="fragment">**Goal:**  `out = m + n`</div>
+
+
+Generalizes To Structures 
+-------------------------
+
+Same idea applies for induction over *structures* ...
+
+
+Structural Induction
+====================
+
+Example: Lists
+--------------
+
+<br>
+
+
+<pre><span class=hs-linenum>269: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span> 
+<span class=hs-linenum>270: </span>         <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+Lets write a generic loop over such lists ...
+</div>
+
+Example: `foldr`
+----------------
+
+ <br>
+<pre><span class=hs-linenum>283: </span><span class='hs-definition'>foldr</span> <span class='hs-varid'>f</span> <span class='hs-varid'>b</span> <span class='hs-conid'>N</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>b</span>
+<span class=hs-linenum>284: </span><span class='hs-definition'>foldr</span> <span class='hs-varid'>f</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>f</span> <span class='hs-varid'>xs</span> <span class='hs-varid'>x</span> <span class='hs-layout'>(</span><span class='hs-varid'>foldr</span> <span class='hs-varid'>f</span> <span class='hs-varid'>b</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+Lets brace ourselves for the type...
+</div>
+
+Example: `foldr`
+----------------
+
+
+<pre><span class=hs-linenum>297: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>foldr</span> <span class='hs-keyglyph'>::</span> 
+<span class=hs-linenum>298: </span>    <span class='hs-keyword'>forall</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span> 
+<span class=hs-linenum>299: </span>      <span class='hs-layout'>(</span><span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>xs</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>300: </span>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-conid'>N</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>301: </span>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>302: </span>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>ys</span><span class='hs-varop'>&gt;</span>                            <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>303: </span><a class=annot href="#"><span class=annottext>forall a b &lt;p :: (Loop.L a)-&gt; b-&gt; Bool&gt;.
+(xs:(L a)
+ -&gt; x:a
+ -&gt; {VV : b&lt;p xs&gt; | true}
+ -&gt; forall [ex:{VV : (L a) | (VV == (Loop.C x xs))}].{VV : b&lt;p ex&gt; | true})
+-&gt; forall [ex:{VV : (L a) | (VV == (Loop.N))}].{VV : b&lt;p ex&gt; | true}
+-&gt; ys:(L a)
+-&gt; {VV : b&lt;p ys&gt; | true}</span><span class='hs-definition'>foldr</span></a> <a class=annot href="#"><span class=annottext>xs:(L a)
+-&gt; x:a
+-&gt; {VV : b | ((papp2 p VV xs))}
+-&gt; forall [ex:{VV : (L a) | (VV == (Loop.C x xs))}].{VV : b | ((papp2 p VV ex))}</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>forall [ex:{VV : (L a) | (VV == (Loop.N))}].{VV : a | ((papp2 p VV ex))}</span><span class='hs-varid'>b</span></a> <span class='hs-conid'>N</span>        <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall [ex:{VV : (L a) | (VV == (Loop.N))}].{VV : a | ((papp2 p VV ex))}</span><span class='hs-varid'>b</span></a>
+<span class=hs-linenum>304: </span><span class='hs-definition'>foldr</span> <span class='hs-varid'>f</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:(L a)
+-&gt; x2:a
+-&gt; {VV : b | ((papp2 p VV x1))}
+-&gt; forall [ex:{VV : (L a) | (VV == (Loop.C x2 x1))}].{VV : b | ((papp2 p VV ex))}</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{x2 : (L a) | (x2 == xs)}</span><span class='hs-varid'>xs</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>forall &lt;p :: (Loop.L a)-&gt; b-&gt; Bool&gt;.
+(xs:(L a)
+ -&gt; x:a
+ -&gt; {VV : b&lt;p xs&gt; | true}
+ -&gt; forall [ex:{VV : (L a) | (VV == (Loop.C x xs))}].{VV : b&lt;p ex&gt; | true})
+-&gt; forall [ex:{VV : (L a) | (VV == (Loop.N))}].{VV : b&lt;p ex&gt; | true}
+-&gt; x4:(L a)
+-&gt; {VV : b&lt;p x4&gt; | true}</span><span class='hs-varid'>foldr</span></a> <a class=annot href="#"><span class=annottext>x1:(L a)
+-&gt; x2:a
+-&gt; {VV : b | ((papp2 p VV x1))}
+-&gt; forall [ex:{VV : (L a) | (VV == (Loop.C x2 x1))}].{VV : b | ((papp2 p VV ex))}</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>forall [ex:{VV : (L a) | (VV == (Loop.N))}].{VV : a | ((papp2 p VV ex))}</span><span class='hs-varid'>b</span></a> <a class=annot href="#"><span class=annottext>{x2 : (L a) | (x2 == xs)}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+Lets step through the type...
+</div>
+
+
+`foldr`: Abstract Refinement
+----------------------------
+
+ <div/>
+<pre><span class=hs-linenum>318: </span><span class='hs-definition'>p</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>   
+<span class=hs-linenum>319: </span><span class='hs-definition'>step</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>xs</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>320: </span><span class='hs-definition'>base</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-conid'>N</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>321: </span><span class='hs-definition'>ys</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>322: </span><span class='hs-definition'>out</span>  <span class='hs-keyglyph'>::</span>  <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>ys</span><span class='hs-varop'>&gt;</span>                            
+</pre>
+
+<br>
+
+`(p xs b)` relates `b` with folded `xs`
+
+`p :: L a -> b -> Prop`
+
+
+`foldr`: Base Case
+------------------
+
+ <div/>
+<pre><span class=hs-linenum>336: </span><span class='hs-definition'>p</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>   
+<span class=hs-linenum>337: </span><span class='hs-definition'>step</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>xs</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>338: </span><span class='hs-definition'>base</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-conid'>N</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>339: </span><span class='hs-definition'>ys</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>340: </span><span class='hs-definition'>out</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>ys</span><span class='hs-varop'>&gt;</span>                            
+</pre>
+
+<br>
+
+`base` is related to empty list `N`
+
+`base :: b<p N>` states 
+
+
+
+`foldr`: Ind. Step 
+------------------
+
+ <div/>
+<pre><span class=hs-linenum>355: </span><span class='hs-definition'>p</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>   
+<span class=hs-linenum>356: </span><span class='hs-definition'>step</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>xs</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>357: </span><span class='hs-definition'>base</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-conid'>N</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>358: </span><span class='hs-definition'>ys</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>359: </span><span class='hs-definition'>out</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>ys</span><span class='hs-varop'>&gt;</span>                            
+</pre>
+
+<br>
+
+`step` extends relation from `xs` to `C x xs`
+
+`step :: xs:L a -> x:a -> b<p xs> -> b<p(C x xs)>`
+
+
+`foldr`: Output
+---------------
+
+ <div/>
+<pre><span class=hs-linenum>373: </span><span class='hs-definition'>p</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>   
+<span class=hs-linenum>374: </span><span class='hs-definition'>step</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>xs</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>375: </span><span class='hs-definition'>base</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-conid'>N</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>376: </span><span class='hs-definition'>ys</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>377: </span><span class='hs-definition'>out</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>ys</span><span class='hs-varop'>&gt;</span>                            
+</pre>
+
+<br>
+
+Relation holds between `out` and input list `ys`
+
+`out :: b<p ys>`
+
+Using `foldr`: Size
+-------------------
+
+We can now verify <br>
+
+
+<pre><span class=hs-linenum>392: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>size</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span><span class='hs-keyword'>| v = (llen xs)}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>393: </span><a class=annot href="#"><span class=annottext>forall a. xs:(L a) -&gt; {VV : (Int) | (VV == (llen xs))}</span><span class='hs-definition'>size</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: (Loop.L a)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+(xs:(L a)
+ -&gt; x:a
+ -&gt; {x12 : (Int)&lt;p xs&gt; | (x12 &gt;= 0)}
+ -&gt; forall [ex:{VV : (L a) | (VV == (Loop.C x xs))}].{x12 : (Int)&lt;p ex&gt; | (x12 &gt;= 0)})
+-&gt; forall [ex:{VV : (L a) | (VV == (Loop.N))}].{x12 : (Int)&lt;p ex&gt; | (x12 &gt;= 0)}
+-&gt; x4:(L a)
+-&gt; {x12 : (Int)&lt;p x4&gt; | (x12 &gt;= 0)}</span><span class='hs-varid'>foldr</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:(L a)
+-&gt; a
+-&gt; x3:{x8 : (Int) | (x8 == (llen x1)) &amp;&amp; (x8 &gt;= 0)}
+-&gt; {x5 : (Int) | (x5 == (x3 + 1)) &amp;&amp; (x5 &gt; 0) &amp;&amp; (x5 &gt; x3) &amp;&amp; (x5 &gt;= 0)}</span><span class='hs-keyglyph'>\</span></a><span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>n</span></a> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">
+Verified by automatically instantiating 
+
+`p := \xs acc -> acc = (llen xs)`
+</div>
+
+Using `foldr`: Append
+---------------------
+
+
+<pre><span class=hs-linenum>408: </span><span class='hs-keyword'>{-@</span> <span class='hs-layout'>(</span><span class='hs-varop'>++</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Cat</span> <span class='hs-varid'>a</span> <span class='hs-varid'>xs</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span> 
+<span class=hs-linenum>409: </span><a class=annot href="#"><span class=annottext>(L a)</span><span class='hs-definition'>xs</span></a> <a class=annot href="#"><span class=annottext>forall a.
+xs:(L a)
+-&gt; ys:(L a)
+-&gt; {VV : (L a) | ((llen VV) == ((llen xs) + (llen ys)))}</span><span class='hs-varop'>++</span></a> <a class=annot href="#"><span class=annottext>(L a)</span><span class='hs-varid'>ys</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: (Loop.L a)-&gt; (Loop.L a)-&gt; Bool&gt;.
+(xs:(L a)
+ -&gt; x:a
+ -&gt; {x8 : (L a)&lt;p xs&gt; | true}
+ -&gt; forall [ex:{VV : (L a) | (VV == (Loop.C x xs))}].{x8 : (L a)&lt;p ex&gt; | true})
+-&gt; forall [ex:{VV : (L a) | (VV == (Loop.N))}].{x8 : (L a)&lt;p ex&gt; | true}
+-&gt; x4:(L a)
+-&gt; {x8 : (L a)&lt;p x4&gt; | true}</span><span class='hs-varid'>foldr</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>(L a)
+-&gt; a -&gt; x3:(L a) -&gt; {x2 : (L a) | ((llen x2) == (1 + (llen x3)))}</span><span class='hs-keyglyph'>\</span></a><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>a -&gt; x2:(L a) -&gt; {x2 : (L a) | ((llen x2) == (1 + (llen x2)))}</span><span class='hs-conid'>C</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x2 : (L a) | (x2 == ys)}</span><span class='hs-varid'>ys</span></a> <a class=annot href="#"><span class=annottext>{x2 : (L a) | (x2 == xs)}</span><span class='hs-varid'>xs</span></a> 
+</pre>
+
+<br>
+
+<div class="fragment">
+
+where the alias `Cat` is:
+
+<br>
+
+
+<pre><span class=hs-linenum>421: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Cat</span> <span class='hs-varid'>a</span> <span class='hs-conid'>X</span> <span class='hs-conid'>Y</span> <span class='hs-keyglyph'>=</span> 
+<span class=hs-linenum>422: </span>    <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-keyglyph'>|</span><span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-conid'>X</span><span class='hs-layout'>)</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-conid'>Y</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+</div>
+
+Using `foldr`: Append
+---------------------
+
+ <div/>
+<pre><span class=hs-linenum>431: </span><span class='hs-keyword'>{-@</span> <span class='hs-layout'>(</span><span class='hs-varop'>++</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Cat</span> <span class='hs-varid'>a</span> <span class='hs-varid'>xs</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span> 
+<span class=hs-linenum>432: </span><span class='hs-definition'>xs</span> <span class='hs-varop'>++</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>C</span><span class='hs-layout'>)</span> <span class='hs-varid'>ys</span> <span class='hs-varid'>xs</span> 
+</pre>
+
+<br>
+
+<div class="fragment">
+
+Verified by automatically instantiating 
+
+`p := \xs acc -> llen acc = llen xs + llen ys`
+
+</div>
+
+Recap
+-----
+
+Abstract refinements decouple *invariant* from *traversal*
+
+<br>
+
++ <div class="fragment">*reusable* specifications for higher-order functions.</div>
+
++ <div class="fragment">*automatic* checking and instantiation by SMT.</div>
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract:** Refinements over Type Signatures
+    + *Dependencies*
+    + <div class="fragment">*Induction*</div>
diff --git a/docs/slides/plpv14/lhs/07_Array.lhs b/docs/slides/plpv14/lhs/07_Array.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/07_Array.lhs
@@ -0,0 +1,405 @@
+Abstract Refinements {#data}
+============================
+
+Recap
+-----
+
+**So far**
+
+Decouple invariants from *functions*
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+Decouple invariants from *data structures*
+</div>
+
+Decouple Invariants From Data {#vector} 
+=======================================
+
+Example: Vectors 
+----------------
+
+<div class="hidden">
+\begin{code}
+module LiquidArray where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume, liquidError)
+
+{-@ LIQUID "--no-termination" @-}
+
+fibMemo   :: Vec Int -> Int -> (Vec Int, Int)
+fastFib   :: Int -> Int
+idv       :: Int -> Vec Int
+axiom_fib :: Int -> Bool
+axiom_fib = undefined
+
+{-@ predicate AxFib I = (fib I) == (if I <= 1 then 1 else fib(I-1) + fib(I-2)) @-}
+\end{code}
+</div>
+
+<div class="fragment">
+
+Implemented as maps from `Int` to `a` 
+
+<br>
+
+\begin{code}
+data Vec a = V (Int -> a)
+\end{code}
+
+</div>
+
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Parameterize type with *two* abstract refinements:
+
+<br>
+
+\begin{code}
+{-@ data Vec a < dom :: Int -> Prop,
+                 rng :: Int -> a -> Prop >
+      = V {a :: i:Int<dom> -> a <rng i>}  @-}
+\end{code}
+
+<br>
+
+- `dom`: *domain* on which `Vec` is *defined* 
+
+- `rng`: *range*  and relationship with *index*
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Diverse `Vec`tors by *instantiating* `dom` and `rng`
+
+<br>
+
+<div class="fragment">
+
+A quick alias for *segments* between `I` and `J`
+
+<br>
+
+\begin{code}
+{-@ predicate Seg V I J = (I <= V && V < J) @-}
+\end{code}
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type IdVec N = Vec <{\v -> (Seg v 0 N)}, 
+                        {\k v -> v=k}> 
+                       Int                  @-}
+\end{code}
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+\begin{code}
+{-@ idv :: n:Nat -> (IdVec n) @-}
+idv n   = V (\k -> if 0 < k && k < n 
+                     then k 
+                     else liquidError "eeks")
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>Whats the problem? How can we fix it?
+</div>
+
+Ex: Zero-Terminated Vectors
+---------------------------
+
+Defined between `[0..N)`, with *last* element equal to `0`:
+
+<br>
+
+<div class="fragment">
+
+\begin{code}
+{-@ type ZeroTerm N = 
+     Vec <{\v -> (Seg v 0 N)}, 
+          {\k v -> (k = N-1 => v = 0)}> 
+          Int                             @-}
+\end{code}
+
+</div>
+
+
+Ex: Fibonacci Table 
+-------------------
+
+A vector whose value at index `k` is either 
+
+- `0` (undefined), or, 
+
+- `k`th fibonacci number 
+
+\begin{code}
+{-@ type FibV =  
+     Vec <{\v -> true}, 
+          {\k v -> (v = 0 || v = (fib k))}> 
+          Int                               @-}
+\end{code}
+
+
+Accessing Vectors
+-----------------
+
+Next: lets *abstractly* type `Vec`tor operations, *e.g.* 
+
+<br>
+
+- `empty`
+
+- `set`
+
+- `get`
+
+
+Ex: Empty Vectors
+-----------------
+
+`empty` returns Vector whose domain is `false`
+
+<br>
+
+\begin{code}
+{-@ empty :: forall <p :: Int -> a -> Prop>. 
+               Vec <{v:Int|false}, p> a     @-}
+
+empty     = V $ \_ -> error "empty vector!"
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+What would happen if we changed `false` to `true`?
+</div>
+
+Ex: `get` Key's Value 
+---------------------
+
+- *Input* `key` in *domain*
+
+- *Output* value in *range* related with `k`
+
+\begin{code}
+{-@ get :: forall a <d :: Int -> Prop,  
+                     r :: Int -> a -> Prop>.
+           key:Int <d>
+        -> vec:Vec <d, r> a
+        -> a<r key>                        @-}
+
+get k (V f) = f k
+\end{code}
+
+
+Ex: `set` Key's Value 
+---------------------
+
+- <div class="fragment">Input `key` in *domain*</div>
+
+- <div class="fragment">Input `val` in *range* related with `key`</div>
+
+- <div class="fragment">Input `vec` defined at *domain except at* `key`</div>
+
+- <div class="fragment">Output domain *includes* `key`</div>
+
+Ex: `set` Key's Value 
+---------------------
+
+\begin{code}
+{-@ set :: forall a <d :: Int -> Prop,
+                     r :: Int -> a -> Prop>.
+           key: Int<d> -> val: a<r key>
+        -> vec: Vec<{v:Int<d>| v /= key},r> a
+        -> Vec <d, r> a                     @-}
+set key val (V f) = V $ \k -> if k == key 
+                                then val 
+                                else f key
+\end{code}
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+Help! Can you spot and fix the errors? 
+</div>
+
+<!-- INSERT tests/pos/vecloop.lhs here AFTER FIXED -->
+
+Using the Vector API
+--------------------
+
+Memoized Fibonacci
+------------------
+
+Use `Vec` API to write a *memoized* fibonacci function
+
+<br>
+
+<div class="fragment">
+\begin{code} Using the fibonacci table:
+type FibV =  
+     Vec <{\v -> true}, 
+          {\k v -> (v = 0 || v = (fib k))}> 
+          Int                              
+\end{code}
+</div>
+
+<br>
+
+<div class="fragment">
+But wait, what is `fib` ?
+</div>
+
+
+Specifying Fibonacci
+--------------------
+
+`fib` is *uninterpreted* in the refinement logic  
+
+<br>
+
+\begin{code}
+{-@ measure fib :: Int -> Int @-}
+\end{code}
+
+<br>
+
+Specifying Fibonacci
+--------------------
+
+We *axiomatize* the definition of `fib` in SMT ...
+
+\begin{code}<br>
+predicate AxFib I = 
+  (fib I) == if I <= 1 
+               then 1 
+               else fib(I-1) + fib(I-2)
+\end{code}
+
+Specifying Fibonacci
+--------------------
+
+Finally, lift axiom into LiquidHaskell as *ghost function*
+
+<br>
+
+\begin{code}
+{-@ axiom_fib :: 
+      i:_ -> {v:_|((Prop v) <=> (AxFib i))} @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Note:** Recipe for *escaping* SMT limitations
+
+1. *Prove* fact externally
+2. *Use* as ghost function call
+</div>
+
+
+Fast Fibonacci
+--------------
+
+An efficient fibonacci function
+
+<br>
+
+\begin{code}
+{-@ fastFib :: n:Int -> {v:_ | v = (fib n)} @-}
+fastFib n   = snd $ fibMemo (V (\_ -> 0)) n
+\end{code}
+
+<br>
+
+<div class="fragment">
+- `fibMemo` *takes* a table initialized with `0`
+
+- `fibMemo` *returns* a table with `fib` values upto `n`.
+</div>
+
+
+Memoized Fibonacci 
+------------------
+
+\begin{code}
+fibMemo t i 
+  | i <= 1    
+  = (t, liquidAssume (axiom_fib i) 1)
+  | otherwise 
+  = case get i t of   
+     0 -> let (t1,n1) = fibMemo t  (i-1)
+              (t2,n2) = fibMemo t1 (i-2)
+              n       = liquidAssume 
+                        (axiom_fib i) (n1+n2)
+          in (set i n t2,  n)
+     n -> (t, n)
+\end{code}
+
+Memoized Fibonacci 
+------------------
+
+- `fibMemo` *takes* a table initialized with `0`
+- `fibMemo` *returns* a table with `fib` values upto `n`.
+
+<br>
+
+\begin{code}
+{-@ fibMemo :: FibV 
+            -> i:Int 
+            -> (FibV,{v:Int | v = (fib i)}) @-}
+\end{code}
+
+
+Recap
+-----
+
+Created a `Vec` container 
+
+Decoupled *domain* and *range* invariants from *data*
+
+<br>
+
+<div class="fragment">
+
+Previous, special purpose program analyses 
+
+- [Gopan-Reps-Sagiv, POPL 05](link)
+- [J.-McMillan, CAV 07](link)
+- [Logozzo-Cousot-Cousot, POPL 11](link)
+- [Dillig-Dillig, POPL 12](link) 
+- ...
+
+Encoded as instance of abstract refinement types!
+</div>
+
+
+
+
diff --git a/docs/slides/plpv14/lhs/07_Array.lhs.markdown b/docs/slides/plpv14/lhs/07_Array.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/07_Array.lhs.markdown
@@ -0,0 +1,467 @@
+Abstract Refinements {#data}
+============================
+
+Recap
+-----
+
+**So far**
+
+Decouple invariants from *functions*
+
+<br>
+
+<div class="fragment">
+
+**Next**
+
+Decouple invariants from *data structures*
+</div>
+
+Decouple Invariants From Data {#vector} 
+=======================================
+
+Example: Vectors 
+----------------
+
+<div class="hidden">
+
+<pre><span class=hs-linenum>28: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>LiquidArray</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>29: </span>
+<span class=hs-linenum>30: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>Liquid</span><span class='hs-varop'>.</span><span class='hs-conid'>Prelude</span> <span class='hs-layout'>(</span><span class='hs-varid'>liquidAssume</span><span class='hs-layout'>,</span> <span class='hs-varid'>liquidError</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>31: </span>
+<span class=hs-linenum>32: </span><span class='hs-keyword'>{-@</span> <span class='hs-conid'>LIQUID</span> <span class='hs-str'>"--no-termination"</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>33: </span>
+<span class=hs-linenum>34: </span><span class='hs-definition'>fibMemo</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Vec</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Vec</span> <span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>Int</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>35: </span><span class='hs-definition'>fastFib</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>36: </span><span class='hs-definition'>idv</span>       <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Vec</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>37: </span><span class='hs-definition'>axiom_fib</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
+<span class=hs-linenum>38: </span><a class=annot href="#"><span class=annottext>i:(Int)
+-&gt; {v : (Bool) | (((Prop v)) &lt;=&gt; ((fib i) == (if (i &lt;= 1) then 1 else ((fib (i - 1)) + (fib (i - 2))))))}</span><span class='hs-definition'>axiom_fib</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a. a</span><span class='hs-varid'>undefined</span></a>
+<span class=hs-linenum>39: </span>
+<span class=hs-linenum>40: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>predicate</span> <span class='hs-conid'>AxFib</span> <span class='hs-conid'>I</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>fib</span> <span class='hs-conid'>I</span><span class='hs-layout'>)</span> <span class='hs-varop'>==</span> <span class='hs-layout'>(</span><span class='hs-keyword'>if</span> <span class='hs-conid'>I</span> <span class='hs-varop'>&lt;=</span> <span class='hs-num'>1</span> <span class='hs-keyword'>then</span> <span class='hs-num'>1</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>fib</span><span class='hs-layout'>(</span><span class='hs-conid'>I</span><span class='hs-comment'>-</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-varop'>+</span> <span class='hs-varid'>fib</span><span class='hs-layout'>(</span><span class='hs-conid'>I</span><span class='hs-comment'>-</span><span class='hs-num'>2</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+</pre>
+</div>
+
+<div class="fragment">
+
+Implemented as maps from `Int` to `a` 
+
+<br>
+
+
+<pre><span class=hs-linenum>51: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>Vec</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>V</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+</pre>
+
+</div>
+
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Parameterize type with *two* abstract refinements:
+
+<br>
+
+
+<pre><span class=hs-linenum>65: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>data</span> <span class='hs-conid'>Vec</span> <span class='hs-varid'>a</span> <span class='hs-varop'>&lt;</span> <span class='hs-varid'>dom</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-layout'>,</span>
+<span class=hs-linenum>66: </span>                 <span class='hs-varid'>rng</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span> <span class='hs-varop'>&gt;</span>
+<span class=hs-linenum>67: </span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>V</span> <span class='hs-layout'>{</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>dom</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>rng</span> <span class='hs-varid'>i</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>}</span>  <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+- `dom`: *domain* on which `Vec` is *defined* 
+
+- `rng`: *range*  and relationship with *index*
+
+Abstract *Domain* and *Range*
+-----------------------------
+
+Diverse `Vec`tors by *instantiating* `dom` and `rng`
+
+<br>
+
+<div class="fragment">
+
+A quick alias for *segments* between `I` and `J`
+
+<br>
+
+
+<pre><span class=hs-linenum>90: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>predicate</span> <span class='hs-conid'>Seg</span> <span class='hs-conid'>V</span> <span class='hs-conid'>I</span> <span class='hs-conid'>J</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-varop'>&lt;=</span> <span class='hs-conid'>V</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-conid'>V</span> <span class='hs-varop'>&lt;</span> <span class='hs-conid'>J</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+<div class="fragment">
+
+
+<pre><span class=hs-linenum>105: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>IdVec</span> <span class='hs-conid'>N</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Vec</span> <span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Seg</span> <span class='hs-varid'>v</span> <span class='hs-num'>0</span> <span class='hs-conid'>N</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span><span class='hs-layout'>,</span> 
+<span class=hs-linenum>106: </span>                        <span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>k</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>v</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>k</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>107: </span>                       <span class='hs-conid'>Int</span>                  <span class='hs-keyword'>@-}</span>
+</pre>
+
+</div>
+
+Ex: Identity Vectors
+--------------------
+
+Defined between `[0..N)` mapping each key to itself:
+
+<br>
+
+
+<pre><span class=hs-linenum>120: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>idv</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>IdVec</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>121: </span><a class=annot href="#"><span class=annottext>n:{VV : (Int) | (VV &gt;= 0)}
+-&gt; (Vec &lt;(VV &lt; n) &amp;&amp; (0 &lt;= VV), \k4 VV -&gt; (VV == k4)&gt; (Int))</span><span class='hs-definition'>idv</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>n</span></a>   <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;rng :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool, dom :: (GHC.Types.Int)-&gt; Bool&gt;.
+(i:{x13 : (Int)&lt;dom&gt; | true}
+ -&gt; {x12 : (Int)&lt;rng i&gt; | (x12 &gt; 0) &amp;&amp; (x12 &gt;= 0) &amp;&amp; (x12 &lt; n)})
+-&gt; (Vec &lt;dom, rng&gt; {x12 : (Int) | (x12 &gt; 0) &amp;&amp; (x12 &gt;= 0) &amp;&amp; (x12 &lt; n)})</span><span class='hs-conid'>V</span></a> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; n)}</span><span class='hs-varid'>k</span></a> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>if</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a> <a class=annot href="#"><span class=annottext>x1:{x12 : (Int) | (x12 &gt;= 0) &amp;&amp; (x12 &lt; n) &amp;&amp; (0 &lt;= x12) &amp;&amp; (x12 &lt;= k)}
+-&gt; x2:{x12 : (Int) | (x12 &gt;= 0) &amp;&amp; (x12 &lt; n) &amp;&amp; (0 &lt;= x12) &amp;&amp; (x12 &lt;= k)}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>&lt;</span></a> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == k) &amp;&amp; (x4 &gt;= 0) &amp;&amp; (x4 &lt; n)}</span><span class='hs-varid'>k</span></a> <a class=annot href="#"><span class=annottext>x1:(Bool)
+-&gt; x2:(Bool)
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (((Prop x1)) &amp;&amp; ((Prop x2))))}</span><span class='hs-varop'>&amp;&amp;</span></a> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == k) &amp;&amp; (x4 &gt;= 0) &amp;&amp; (x4 &lt; n)}</span><span class='hs-varid'>k</span></a> <a class=annot href="#"><span class=annottext>x1:{x12 : (Int) | (x12 &gt;= 0) &amp;&amp; (x12 &gt;= k) &amp;&amp; (0 &lt;= x12) &amp;&amp; (x12 &lt;= n)}
+-&gt; x2:{x12 : (Int) | (x12 &gt;= 0) &amp;&amp; (x12 &gt;= k) &amp;&amp; (0 &lt;= x12) &amp;&amp; (x12 &lt;= n)}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>&lt;</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>n</span></a> 
+<span class=hs-linenum>122: </span>                     <span class='hs-keyword'>then</span> <a class=annot href="#"><span class=annottext>{x4 : (Int) | (x4 == k) &amp;&amp; (x4 &gt;= 0) &amp;&amp; (x4 &lt; n)}</span><span class='hs-varid'>k</span></a> 
+<span class=hs-linenum>123: </span>                     <span class='hs-keyword'>else</span> <a class=annot href="#"><span class=annottext>{x2 : [(Char)] | false} -&gt; {x1 : (Int) | false}</span><span class='hs-varid'>liquidError</span></a> <span class=hs-error><a class=annot href="#"><span class=annottext>{x3 : [(Char)] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-str'>"eeks"</span></a></span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>Whats the problem? How can we fix it?
+</div>
+
+Ex: Zero-Terminated Vectors
+---------------------------
+
+Defined between `[0..N)`, with *last* element equal to `0`:
+
+<br>
+
+<div class="fragment">
+
+
+<pre><span class=hs-linenum>142: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>ZeroTerm</span> <span class='hs-conid'>N</span> <span class='hs-keyglyph'>=</span> 
+<span class=hs-linenum>143: </span>     <span class='hs-conid'>Vec</span> <span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Seg</span> <span class='hs-varid'>v</span> <span class='hs-num'>0</span> <span class='hs-conid'>N</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span><span class='hs-layout'>,</span> 
+<span class=hs-linenum>144: </span>          <span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>k</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span><span class='hs-comment'>-</span><span class='hs-num'>1</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>145: </span>          <span class='hs-conid'>Int</span>                             <span class='hs-keyword'>@-}</span>
+</pre>
+
+</div>
+
+
+Ex: Fibonacci Table 
+-------------------
+
+A vector whose value at index `k` is either 
+
+- `0` (undefined), or, 
+
+- `k`th fibonacci number 
+
+
+<pre><span class=hs-linenum>161: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>FibV</span> <span class='hs-keyglyph'>=</span>  
+<span class=hs-linenum>162: </span>     <span class='hs-conid'>Vec</span> <span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>true</span><span class='hs-layout'>}</span><span class='hs-layout'>,</span> 
+<span class=hs-linenum>163: </span>          <span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>k</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span> <span class='hs-varop'>||</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>fib</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>164: </span>          <span class='hs-conid'>Int</span>                               <span class='hs-keyword'>@-}</span>
+</pre>
+
+
+Accessing Vectors
+-----------------
+
+Next: lets *abstractly* type `Vec`tor operations, *e.g.* 
+
+<br>
+
+- `empty`
+
+- `set`
+
+- `get`
+
+
+Ex: Empty Vectors
+-----------------
+
+`empty` returns Vector whose domain is `false`
+
+<br>
+
+
+<pre><span class=hs-linenum>190: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>empty</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span> 
+<span class=hs-linenum>191: </span>               <span class='hs-conid'>Vec</span> <span class='hs-varop'>&lt;</span><span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span><span class='hs-keyword'>|false}</span><span class='hs-layout'>,</span> <span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span>     <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>192: </span>
+<span class=hs-linenum>193: </span><a class=annot href="#"><span class=annottext>forall a &lt;p :: (GHC.Types.Int)-&gt; a-&gt; Bool&gt;.
+(Vec &lt;false, \_ VV -&gt; p&gt; a)</span><span class='hs-definition'>empty</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>({x4 : (Int) | false} -&gt; {VV : a | false})
+-&gt; (Vec &lt;false, \_ VV -&gt; false&gt; {VV : a | false})</span><span class='hs-conid'>V</span></a> <a class=annot href="#"><span class=annottext>(({x9 : (Int) | false} -&gt; {VV : a | false})
+ -&gt; (Vec &lt;false, \_ VV -&gt; false&gt; {VV : a | false}))
+-&gt; ({x9 : (Int) | false} -&gt; {VV : a | false})
+-&gt; (Vec &lt;false, \_ VV -&gt; false&gt; {VV : a | false})</span><span class='hs-varop'>$</span></a> <a class=annot href="#"><span class=annottext>{x1 : (Int) | false} -&gt; {VV : a | false}</span><span class='hs-keyglyph'>\</span></a><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>[(Char)] -&gt; {VV : a | false}</span><span class='hs-varid'>error</span></a> <a class=annot href="#"><span class=annottext>{x3 : [(Char)] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-str'>"empty vector!"</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+What would happen if we changed `false` to `true`?
+</div>
+
+Ex: `get` Key's Value 
+---------------------
+
+- *Input* `key` in *domain*
+
+- *Output* value in *range* related with `k`
+
+
+<pre><span class=hs-linenum>211: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>get</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varid'>a</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>d</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-layout'>,</span>  
+<span class=hs-linenum>212: </span>                     <span class='hs-varid'>r</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span>
+<span class=hs-linenum>213: </span>           <span class='hs-varid'>key</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>d</span><span class='hs-varop'>&gt;</span>
+<span class=hs-linenum>214: </span>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>vec</span><span class='hs-conop'>:</span><span class='hs-conid'>Vec</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>d</span><span class='hs-layout'>,</span> <span class='hs-varid'>r</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>215: </span>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>r</span> <span class='hs-varid'>key</span><span class='hs-varop'>&gt;</span>                        <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>216: </span>
+<span class=hs-linenum>217: </span><a class=annot href="#"><span class=annottext>forall a &lt;d :: (GHC.Types.Int)-&gt; Bool, r :: (GHC.Types.Int)-&gt; a-&gt; Bool&gt;.
+key:{VV : (Int)&lt;d&gt; | true}
+-&gt; (Vec &lt;d, \_ VV -&gt; r&gt; a) -&gt; {VV : a&lt;r key&gt; | true}</span><span class='hs-definition'>get</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | ((papp1 d VV))}</span><span class='hs-varid'>k</span></a> <span class='hs-layout'>(</span><span class='hs-conid'>V</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x2 : (Int) | ((papp1 d x2))} -&gt; {VV : a | ((papp2 r VV x1))}</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | ((papp1 d x3)) &amp;&amp; (x3 == k)}</span><span class='hs-varid'>k</span></a>
+</pre>
+
+
+Ex: `set` Key's Value 
+---------------------
+
+- <div class="fragment">Input `key` in *domain*</div>
+
+- <div class="fragment">Input `val` in *range* related with `key`</div>
+
+- <div class="fragment">Input `vec` defined at *domain except at* `key`</div>
+
+- <div class="fragment">Output domain *includes* `key`</div>
+
+Ex: `set` Key's Value 
+---------------------
+
+
+<pre><span class=hs-linenum>236: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>set</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varid'>a</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>d</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-layout'>,</span>
+<span class=hs-linenum>237: </span>                     <span class='hs-varid'>r</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;.</span>
+<span class=hs-linenum>238: </span>           <span class='hs-varid'>key</span><span class='hs-conop'>:</span> <span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>d</span><span class='hs-varop'>&gt;</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>val</span><span class='hs-conop'>:</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>r</span> <span class='hs-varid'>key</span><span class='hs-varop'>&gt;</span>
+<span class=hs-linenum>239: </span>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>vec</span><span class='hs-conop'>:</span> <span class='hs-conid'>Vec</span><span class='hs-varop'>&lt;</span><span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>d</span><span class='hs-varop'>&gt;</span><span class='hs-keyword'>| v /= key}</span><span class='hs-layout'>,</span><span class='hs-varid'>r</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>240: </span>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Vec</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>d</span><span class='hs-layout'>,</span> <span class='hs-varid'>r</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span>                     <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>241: </span><a class=annot href="#"><span class=annottext>forall a &lt;d :: (GHC.Types.Int)-&gt; Bool, r :: (GHC.Types.Int)-&gt; a-&gt; Bool&gt;.
+key:{VV : (Int)&lt;d&gt; | true}
+-&gt; {VV : a&lt;r key&gt; | true}
+-&gt; (Vec &lt;d &amp; (VV /= key), \_ VV -&gt; r&gt; a)
+-&gt; (Vec &lt;d, \_ VV -&gt; r&gt; a)</span><span class='hs-definition'>set</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | ((papp1 d VV))}</span><span class='hs-varid'>key</span></a> <a class=annot href="#"><span class=annottext>{VV : a | ((papp2 r VV key))}</span><span class='hs-varid'>val</span></a> <span class='hs-layout'>(</span><span class='hs-conid'>V</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class=hs-error><a class=annot href="#"><span class=annottext>({x6 : (Int) | ((papp1 d x6))} -&gt; {VV : a | ((papp2 r VV key))})
+-&gt; (Vec &lt;((papp1 d x3)), \_ VV -&gt; ((papp2 r VV key))&gt; {VV : a | ((papp2 r VV key))})</span><span class='hs-conid'>V</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>(({x13 : (Int) | ((papp1 d x13))} -&gt; {VV : a | ((papp2 r VV key))})
+ -&gt; (Vec &lt;((papp1 d x10)), \_ VV -&gt; ((papp2 r VV key))&gt; {VV : a | ((papp2 r VV key))}))
+-&gt; ({x13 : (Int) | ((papp1 d x13))}
+    -&gt; {VV : a | ((papp2 r VV key))})
+-&gt; (Vec &lt;((papp1 d x10)), \_ VV -&gt; ((papp2 r VV key))&gt; {VV : a | ((papp2 r VV key))})</span><span class='hs-varop'>$</span></a></span><span class=hs-error> </span><span class=hs-error><span class='hs-keyglyph'>\</span></span><span class=hs-error><a class=annot href="#"><span class=annottext>{VV : (Int) | ((papp1 d VV))}</span><span class='hs-varid'>k</span></a></span><span class=hs-error> </span><span class=hs-error><span class='hs-keyglyph'>-&gt;</span></span><span class=hs-error> </span><span class=hs-error><span class='hs-keyword'>if</span></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x3 : (Int) | ((papp1 d x3)) &amp;&amp; (x3 == k)}</span><span class='hs-varid'>k</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>x1:{x6 : (Int) | ((papp1 d x6))}
+-&gt; x2:{x6 : (Int) | ((papp1 d x6))}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 == x2))}</span><span class='hs-varop'>==</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x3 : (Int) | ((papp1 d x3)) &amp;&amp; (x3 == key)}</span><span class='hs-varid'>key</span></a></span><span class=hs-error> </span>
+<span class=hs-linenum>242: </span>                                <span class=hs-error><span class='hs-keyword'>then</span></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{VV : a | ((papp2 r VV key)) &amp;&amp; (VV == val)}</span><span class='hs-varid'>val</span></a></span><span class=hs-error> </span><span class=hs-error>
+</span><span class=hs-linenum>243: </span>                                <span class=hs-error><span class='hs-keyword'>else</span></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>x1:{x3 : (Int) | ((papp1 d x3)) &amp;&amp; (x3 /= key)}
+-&gt; {VV : a | ((papp2 r VV x1))}</span><span class='hs-varid'>f</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x3 : (Int) | ((papp1 d x3)) &amp;&amp; (x3 == key)}</span><span class='hs-varid'>key</span></a></span>
+</pre>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Array.hs" target="_blank">Demo:</a>
+Help! Can you spot and fix the errors? 
+</div>
+
+<!-- INSERT tests/pos/vecloop.lhs here AFTER FIXED -->
+
+Using the Vector API
+--------------------
+
+Memoized Fibonacci
+------------------
+
+Use `Vec` API to write a *memoized* fibonacci function
+
+<br>
+
+<div class="fragment">
+ Using the fibonacci table:
+<pre><span class=hs-linenum>267: </span><span class='hs-keyword'>type</span> <span class='hs-conid'>FibV</span> <span class='hs-keyglyph'>=</span>  
+<span class=hs-linenum>268: </span>     <span class='hs-conid'>Vec</span> <span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>true</span><span class='hs-layout'>}</span><span class='hs-layout'>,</span> 
+<span class=hs-linenum>269: </span>          <span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>k</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span> <span class='hs-varop'>||</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>fib</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>270: </span>          <span class='hs-conid'>Int</span>                              
+</pre>
+</div>
+
+<br>
+
+<div class="fragment">
+But wait, what is `fib` ?
+</div>
+
+
+Specifying Fibonacci
+--------------------
+
+`fib` is *uninterpreted* in the refinement logic  
+
+<br>
+
+
+<pre><span class=hs-linenum>289: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>measure</span> <span class='hs-varid'>fib</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+Specifying Fibonacci
+--------------------
+
+We *axiomatize* the definition of `fib` in SMT ...
+
+<br>
+<pre><span class=hs-linenum>300: </span><span class='hs-definition'>predicate</span> <span class='hs-conid'>AxFib</span> <span class='hs-conid'>I</span> <span class='hs-keyglyph'>=</span> 
+<span class=hs-linenum>301: </span>  <span class='hs-layout'>(</span><span class='hs-varid'>fib</span> <span class='hs-conid'>I</span><span class='hs-layout'>)</span> <span class='hs-varop'>==</span> <span class='hs-keyword'>if</span> <span class='hs-conid'>I</span> <span class='hs-varop'>&lt;=</span> <span class='hs-num'>1</span> 
+<span class=hs-linenum>302: </span>               <span class='hs-keyword'>then</span> <span class='hs-num'>1</span> 
+<span class=hs-linenum>303: </span>               <span class='hs-keyword'>else</span> <span class='hs-varid'>fib</span><span class='hs-layout'>(</span><span class='hs-conid'>I</span><span class='hs-comment'>-</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-varop'>+</span> <span class='hs-varid'>fib</span><span class='hs-layout'>(</span><span class='hs-conid'>I</span><span class='hs-comment'>-</span><span class='hs-num'>2</span><span class='hs-layout'>)</span>
+</pre>
+
+Specifying Fibonacci
+--------------------
+
+Finally, lift axiom into LiquidHaskell as *ghost function*
+
+<br>
+
+
+<pre><span class=hs-linenum>314: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>axiom_fib</span> <span class='hs-keyglyph'>::</span> 
+<span class=hs-linenum>315: </span>      <span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyword'>_</span><span class='hs-keyword'>|((Prop v) &lt;=&gt; (AxFib i))}</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+**Note:** Recipe for *escaping* SMT limitations
+
+1. *Prove* fact externally
+2. *Use* as ghost function call
+</div>
+
+
+Fast Fibonacci
+--------------
+
+An efficient fibonacci function
+
+<br>
+
+
+<pre><span class=hs-linenum>336: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>fastFib</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-keyword'>_</span> <span class='hs-keyword'>| v = (fib n)}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>337: </span><a class=annot href="#"><span class=annottext>n:(Int) -&gt; {v : (Int) | (v == (fib n))}</span><span class='hs-definition'>fastFib</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>n</span></a>   <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>((Vec &lt;false, \x10 VV -&gt; ((x9 == 0) || (x9 == (fib x10)))&gt; (Int)), {x13 : (Int) | (x13 == (fib n))})
+-&gt; {x2 : (Int) | (x2 == (fib n))}</span><span class='hs-varid'>snd</span></a> <a class=annot href="#"><span class=annottext>(((Vec &lt;false, \x24 VV -&gt; ((x23 == 0) || (x23 == (fib x24)))&gt; (Int)), {x27 : (Int) | (x27 == (fib n))})
+ -&gt; {x16 : (Int) | (x16 == (fib n))})
+-&gt; ((Vec &lt;false, \x24 VV -&gt; ((x23 == 0) || (x23 == (fib x24)))&gt; (Int)), {x27 : (Int) | (x27 == (fib n))})
+-&gt; {x16 : (Int) | (x16 == (fib n))}</span><span class='hs-varop'>$</span></a> <a class=annot href="#"><span class=annottext>(Vec &lt;True, \x18 VV -&gt; ((x17 == 0) || (x17 == (fib x18)))&gt; (Int))
+-&gt; x2:(Int)
+-&gt; ((Vec &lt;True, \x8 VV -&gt; ((x7 == 0) || (x7 == (fib x8)))&gt; (Int)), {x11 : (Int) | (x11 == (fib x2))})</span><span class='hs-varid'>fibMemo</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>forall &lt;rng :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool, dom :: (GHC.Types.Int)-&gt; Bool&gt;.
+(i:{x15 : (Int)&lt;dom&gt; | true}
+ -&gt; {x14 : (Int)&lt;rng i&gt; | ((x14 == 0) || (x14 == (fib n))) &amp;&amp; (x14 == 0) &amp;&amp; (x14 &gt;= 0)})
+-&gt; (Vec &lt;dom, rng&gt; {x14 : (Int) | ((x14 == 0) || (x14 == (fib n))) &amp;&amp; (x14 == 0) &amp;&amp; (x14 &gt;= 0)})</span><span class='hs-conid'>V</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>(Int) -&gt; {x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-keyglyph'>\</span></a><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == n)}</span><span class='hs-varid'>n</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">
+- `fibMemo` *takes* a table initialized with `0`
+
+- `fibMemo` *returns* a table with `fib` values upto `n`.
+</div>
+
+
+Memoized Fibonacci 
+------------------
+
+
+<pre><span class=hs-linenum>353: </span><a class=annot href="#"><span class=annottext>(Vec &lt;True, \k10 VV -&gt; ((VV == 0) || (VV == (fib k10)))&gt; (Int))
+-&gt; i:(Int)
+-&gt; ((Vec &lt;True, \k10 VV -&gt; ((VV == 0) || (VV == (fib k10)))&gt; (Int)), {VV : (Int) | (VV == (fib i))})</span><span class='hs-definition'>fibMemo</span></a> <a class=annot href="#"><span class=annottext>(Vec &lt;True, \k10 VV -&gt; ((VV == 0) || (VV == (fib k10)))&gt; (Int))</span><span class='hs-varid'>t</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>i</span></a> 
+<span class=hs-linenum>354: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == i)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>x1:(Int)
+-&gt; x2:(Int) -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt;= x2))}</span><span class='hs-varop'>&lt;=</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a>    
+<span class=hs-linenum>355: </span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a b &lt;p2 :: a-&gt; b-&gt; Bool&gt;.
+x1:a
+-&gt; x2:{VV : b&lt;p2 x1&gt; | true}
+-&gt; {x3 : (a, b)&lt;p2&gt; | ((fst x3) == x1) &amp;&amp; ((snd x3) == x2)}</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{x2 : (Vec &lt;True, \x7 VV -&gt; ((x6 == 0) || (x6 == (fib x7)))&gt; (Int)) | (x2 == t)}</span><span class='hs-varid'>t</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>x1:(Bool)
+-&gt; {x8 : (Int) | (x8 == 1) &amp;&amp; (x8 &gt; 0) &amp;&amp; (x8 &gt;= i)}
+-&gt; {x8 : (Int) | ((Prop x1)) &amp;&amp; (x8 == 1) &amp;&amp; (x8 &gt; 0) &amp;&amp; (x8 &gt;= i)}</span><span class='hs-varid'>liquidAssume</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:(Int)
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; ((fib x1) == (if (x1 &lt;= 1) then 1 else ((fib (x1 - 1)) + (fib (x1 - 2))))))}</span><span class='hs-varid'>axiom_fib</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == i)}</span><span class='hs-varid'>i</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>356: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> 
+<span class=hs-linenum>357: </span>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <a class=annot href="#"><span class=annottext>forall &lt;r :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool, d :: (GHC.Types.Int)-&gt; Bool&gt;.
+x1:{x7 : (Int)&lt;d&gt; | true}
+-&gt; (Vec &lt;d, \x5 VV -&gt; r x5&gt; (Int)) -&gt; {x6 : (Int)&lt;r x1&gt; | true}</span><span class='hs-varid'>get</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == i)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Vec &lt;True, \x7 VV -&gt; ((x6 == 0) || (x6 == (fib x7)))&gt; (Int)) | (x2 == t)}</span><span class='hs-varid'>t</span></a> <span class='hs-keyword'>of</span>   
+<span class=hs-linenum>358: </span>     <span class='hs-num'>0</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : (Vec &lt;True, \x1 VV -&gt; ((VV == 0) || (VV == (fib x1)))&gt; (Int)) | (VV == t1)}</span><span class='hs-varid'>t1</span></a><span class='hs-layout'>,</span><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV == n1)}</span><span class='hs-varid'>n1</span></a><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>(Vec &lt;True, \x18 VV -&gt; ((x17 == 0) || (x17 == (fib x18)))&gt; (Int))
+-&gt; x2:(Int)
+-&gt; ((Vec &lt;True, \x8 VV -&gt; ((x7 == 0) || (x7 == (fib x8)))&gt; (Int)), {x11 : (Int) | (x11 == (fib x2))})</span><span class='hs-varid'>fibMemo</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Vec &lt;True, \x7 VV -&gt; ((x6 == 0) || (x6 == (fib x7)))&gt; (Int)) | (x2 == t)}</span><span class='hs-varid'>t</span></a>  <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == i)}</span><span class='hs-varid'>i</span></a><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>359: </span>              <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : (Vec &lt;(VV /= i), \x1 VV -&gt; ((VV == 0) || (VV == (fib x1)))&gt; (Int)) | (VV == t2)}</span><span class='hs-varid'>t2</span></a><span class='hs-layout'>,</span><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV == n2)}</span><span class='hs-varid'>n2</span></a><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>(Vec &lt;True, \x18 VV -&gt; ((x17 == 0) || (x17 == (fib x18)))&gt; (Int))
+-&gt; x2:(Int)
+-&gt; ((Vec &lt;True, \x8 VV -&gt; ((x7 == 0) || (x7 == (fib x8)))&gt; (Int)), {x11 : (Int) | (x11 == (fib x2))})</span><span class='hs-varid'>fibMemo</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Vec &lt;True, \x8 VV -&gt; ((x7 == 0) || (x7 == (fib x8)))&gt; (Int)) | (x3 == t1) &amp;&amp; (x3 == t1)}</span><span class='hs-varid'>t1</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == i)}</span><span class='hs-varid'>i</span></a><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>360: </span>              <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>n</span></a>       <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:(Bool) -&gt; (Int) -&gt; {x2 : (Int) | ((Prop x1))}</span><span class='hs-varid'>liquidAssume</span></a> 
+<span class=hs-linenum>361: </span>                        <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:(Int)
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; ((fib x1) == (if (x1 &lt;= 1) then 1 else ((fib (x1 - 1)) + (fib (x1 - 2))))))}</span><span class='hs-varid'>axiom_fib</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == i)}</span><span class='hs-varid'>i</span></a><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n1) &amp;&amp; (x3 == n1)}</span><span class='hs-varid'>n1</span></a><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a><a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n2) &amp;&amp; (x3 == n2)}</span><span class='hs-varid'>n2</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>362: </span>          <span class='hs-keyword'>in</span> <a class=annot href="#"><span class=annottext>forall a b &lt;p2 :: a-&gt; b-&gt; Bool&gt;.
+x1:a
+-&gt; x2:{VV : b&lt;p2 x1&gt; | true}
+-&gt; {x3 : (a, b)&lt;p2&gt; | ((fst x3) == x1) &amp;&amp; ((snd x3) == x2)}</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>forall &lt;r :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool, d :: (GHC.Types.Int)-&gt; Bool&gt;.
+x1:{x13 : (Int)&lt;d&gt; | true}
+-&gt; {x12 : (Int)&lt;r x1&gt; | true}
+-&gt; (Vec &lt;d &amp; (x8 /= x1), \x10 VV -&gt; r x10&gt; (Int))
+-&gt; (Vec &lt;d, \x4 VV -&gt; r x4&gt; (Int))</span><span class='hs-varid'>set</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == i)}</span><span class='hs-varid'>i</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == n)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Vec &lt;(x5 /= i), \x9 VV -&gt; ((x8 == 0) || (x8 == (fib x9)))&gt; (Int)) | (x3 == t2) &amp;&amp; (x3 == t2)}</span><span class='hs-varid'>t2</span></a><span class='hs-layout'>,</span>  <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == n)}</span><span class='hs-varid'>n</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>363: </span>     <span class='hs-varid'>n</span> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>{x2 : ({x7 : (Vec &lt;True, \x12 VV -&gt; ((x11 == 0) || (x11 == (fib x12)))&gt; (Int)) | (x7 == t)}, {x16 : (Int) | (x16 == (fib i)) &amp;&amp; (x16 /= 0)})&lt;\_ VV -&gt; (x16 == (fib i)) &amp;&amp; (x16 /= 0)&gt; | ((fst x2) == t)}</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{x2 : (Vec &lt;True, \x7 VV -&gt; ((x6 == 0) || (x6 == (fib x7)))&gt; (Int)) | (x2 == t)}</span><span class='hs-varid'>t</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | ((x3 == 0) || (x3 == (fib i)))}</span><span class='hs-varid'>n</span></a><span class='hs-layout'>)</span>
+</pre>
+
+Memoized Fibonacci 
+------------------
+
+- `fibMemo` *takes* a table initialized with `0`
+- `fibMemo` *returns* a table with `fib` values upto `n`.
+
+<br>
+
+
+<pre><span class=hs-linenum>375: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>fibMemo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FibV</span> 
+<span class=hs-linenum>376: </span>            <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-conid'>Int</span> 
+<span class=hs-linenum>377: </span>            <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>FibV</span><span class='hs-layout'>,</span><span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span> <span class='hs-keyword'>| v = (fib i)}</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+
+Recap
+-----
+
+Created a `Vec` container 
+
+Decoupled *domain* and *range* invariants from *data*
+
+<br>
+
+<div class="fragment">
+
+Previous, special purpose program analyses 
+
+- [Gopan-Reps-Sagiv, POPL 05](link)
+- [J.-McMillan, CAV 07](link)
+- [Logozzo-Cousot-Cousot, POPL 11](link)
+- [Dillig-Dillig, POPL 12](link) 
+- ...
+
+Encoded as instance of abstract refinement types!
+</div>
+
+
+
+
diff --git a/docs/slides/plpv14/lhs/08_Recursive.lhs b/docs/slides/plpv14/lhs/08_Recursive.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/08_Recursive.lhs
@@ -0,0 +1,488 @@
+Decouple Invariants From Data {#recursive} 
+==========================================
+
+Recursive Structures 
+--------------------
+
+<div class="fragment">
+Lets see another example of decoupling...
+</div>
+
+<div class="hidden">
+\begin{code}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+
+module List (insertSort) where
+
+{-@ LIQUID "--no-termination" @-}
+
+mergeSort     :: Ord a => [a] -> [a]
+insertSort :: (Ord a) => [a] -> L a 
+slist :: L Int
+slist' :: L Int
+iGoUp, iGoDn, iDiff :: [Int]
+infixr `C`
+\end{code}
+</div>
+
+Decouple Invariants From Recursive Data
+=======================================
+
+Recall: Lists
+-------------
+
+\begin{code}
+data L a = N 
+         | C a (L a)
+\end{code}
+
+
+Recall: Refined Constructors 
+----------------------------
+
+Define *increasing* Lists with strengthened constructors:
+
+\begin{code} <br>
+data L a where
+  N :: L a
+  C :: hd:a -> tl: L {v:a | hd <= v} -> L a
+\end{code}
+
+Problem: Decreasing Lists?
+--------------------------
+
+What if we need *both* [increasing and decreasing lists](http://web.cecs.pdx.edu/~sheard/Code/QSort.html)?
+
+<br>
+
+<div class="fragment">
+*Separate* types are tedious...
+</div>
+
+
+Abstract That Refinement!
+-------------------------
+
+\begin{code}
+{-@ data L a <p :: a -> a -> Prop>
+      = N 
+      | C (hd :: a) (tl :: (L <p> a<p hd>)) @-}
+\end{code}
+
+<br>
+
+- <div class="fragment"> `p` is a *binary* relation between two `a` values</div>
+
+- <div class="fragment"> Definition relates `hd` with *all* the elements of `tl`</div>
+
+- <div class="fragment"> Recursive: `p` holds for *every pair* of elements!</div>
+
+Example
+-------
+
+Consider a list with *three* or more elements 
+
+\begin{code} <br>
+x1 `C` x2 `C` x3 `C` rest :: L <p> a 
+\end{code}
+
+Example: Unfold Once
+--------------------
+
+\begin{code} <br> 
+x1                 :: a
+x2 `C` x3 `C` rest :: L <p> a<p x1> 
+\end{code}
+
+Example: Unfold Twice
+---------------------
+
+\begin{code} <br> 
+x1          :: a
+x2          :: a<p x1>  
+x3 `C` rest :: L <p> a<p x1 && p x2> 
+\end{code}
+
+Example: Unfold Thrice
+----------------------
+
+\begin{code} <br> 
+x1   :: a
+x2   :: a<p x1>  
+x3   :: a<p x1 && p x2>  
+rest :: L <p> a<p x1 && p x2 && p x3> 
+\end{code}
+
+<br>
+
+<div class="fragment">
+Note how `p` holds between **every pair** of elements in the list. 
+</div>
+
+A Concrete Example
+------------------
+
+That was a rather *abstract*!
+
+<br>
+
+How can we *use* fact that `p` holds between *every pair* ?
+
+
+Example: Increasing Lists
+-------------------------
+
+*Instantiate* `p` with a *concrete* refinement
+
+<br>
+
+\begin{code}
+{-@ type IncL a = L <{\hd v -> hd <= v}> a @-}
+\end{code}
+
+<br>
+
+- <div class="fragment"> Refinement says `hd` less than each tail element `v`,</div>
+
+- <div class="fragment"> Thus, `IncL` denotes *increaing* lists. </div>
+
+Example: Increasing Lists
+-------------------------
+
+LiquidHaskell verifies that `slist` is indeed increasing...
+
+\begin{code}
+{-@ slist :: IncL Int @-}
+slist     = 1 `C` 6 `C` 12 `C` N
+\end{code}
+
+<br> 
+
+<div class="fragment">
+
+... and protests that `slist'` is not: 
+
+\begin{code}
+{-@ slist' :: IncL Int @-}
+slist' = 6 `C` 1 `C` 12 `C` N
+\end{code}
+</div>
+
+Insertion Sort
+--------------
+
+\begin{code}
+{-@ insertSort :: (Ord a) => [a] -> IncL a @-}
+insertSort     = foldr insert N
+
+insert y N          = y `C` N
+insert y (x `C` xs) 
+  | y < x           = y `C` (x `C` xs)
+  | otherwise       = x `C` insert y xs
+\end{code}
+
+<br>
+
+(*Hover* over `insert'` to see inferred type.)
+
+Checking GHC Lists
+------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target= "_blank">Demo:</a> 
+Above applies to GHC's List definition:
+
+\begin{code} <br> 
+data [a] <p :: a -> a -> Prop>
+  = [] 
+  | (:) (h :: a) (tl :: ([a<p h>]<p>))
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Increasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Incs a = [a]<{\h v -> h <= v}> @-}
+
+{-@ iGoUp :: Incs Int @-}
+iGoUp     = [1,2,3]
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Decreasing Lists
+
+<br>
+
+\begin{code}
+{-@ type Decs a = [a]<{\h v -> h >= v}> @-}
+
+{-@ iGoDn :: Decs Int @-}
+iGoDn     = [3,2,1]
+\end{code}
+
+
+Checking GHC Lists
+------------------
+
+Duplicate-free Lists
+
+<br>
+
+\begin{code}
+{-@ type Difs a = [a]<{\h v -> h /= v}> @-}
+
+{-@ iDiff :: Difs Int @-}
+iDiff     = [1,3,2]
+\end{code}
+
+Checking GHC Lists
+------------------
+
+Now we can check all the usual list sorting algorithms 
+
+Example: `mergeSort` [1/2]
+--------------------------
+
+\begin{code}
+{-@ mergeSort  :: (Ord a) => [a] -> Incs a @-}
+mergeSort []   = []
+mergeSort [x]  = [x]
+mergeSort xs   = merge xs1' xs2' 
+  where 
+   (xs1, xs2)  = split xs
+   xs1'        = mergeSort xs1
+   xs2'        = mergeSort xs2
+\end{code}
+
+Example: `mergeSort` [1/2]
+--------------------------
+
+\begin{code}
+split (x:y:zs) = (x:xs, y:ys) 
+  where 
+    (xs, ys)   = split zs
+split xs       = (xs, [])
+
+merge xs []    = xs
+merge [] ys    = ys
+merge (x:xs) (y:ys) 
+  | x <= y     = x : merge xs (y:ys)
+  | otherwise  = y : merge (x:xs) ys
+\end{code}
+
+Example: `Data.List.sort` 
+-------------------------
+
+GHC's "official" list sorting routine
+
+Juggling lists of increasing & decreasing lists
+
+
+Ex: `Data.List.sort` [1/4]
+--------------------------
+
+Juggling lists of increasing & decreasing lists
+
+<br>
+
+\begin{code}
+{-@ sort :: (Ord a) => [a] -> Incs a  @-}
+sort = mergeAll . sequences
+
+sequences (a:b:xs)
+  | a `compare` b == GT = descending b [a]  xs
+  | otherwise           = ascending  b (a:) xs
+sequences [x]           = [[x]]
+sequences []            = [[]]
+\end{code}
+
+Ex: `Data.List.sort` [2/4]
+--------------------------
+
+Juggling lists of increasing & decreasing lists
+
+<br>
+
+\begin{code}
+descending a as (b:bs)
+  | a `compare` b == GT 
+  = descending b (a:as) bs
+descending a as bs      
+  = (a:as): sequences bs
+\end{code}
+
+Ex: `Data.List.sort` [3/4]
+--------------------------
+
+Juggling lists of increasing & decreasing lists
+
+<br>
+
+
+\begin{code}
+ascending a as (b:bs)
+  | a `compare` b /= GT 
+  = ascending b (\ys -> as (a:ys)) bs
+ascending a as bs      
+  = as [a]: sequences bs
+\end{code}
+
+Ex: `Data.List.sort` [4/4]
+--------------------------
+
+Juggling lists of increasing & decreasing lists
+
+<br>
+
+\begin{code}
+mergeAll [x]        = x
+mergeAll xs         = mergeAll (mergePairs xs)
+
+mergePairs (a:b:xs) = merge a b: mergePairs xs
+mergePairs [x]      = [x]
+mergePairs []       = []
+\end{code}
+
+Phew!
+-----
+
+Lets see one last example...
+
+
+Example: Binary Trees
+---------------------
+
+... `Map` from keys of type `k` to values of type `a` 
+
+<br>
+
+<div class="fragment">
+
+Implemented, in `Data.Map` as a binary tree:
+
+<br>
+
+\begin{code}
+data Map k a = Tip
+             | Bin Size k a (Map k a) (Map k a)
+
+type Size    = Int
+\end{code}
+</div>
+
+Two Abstract Refinements
+------------------------
+
+- `l` : relates root `key` with `left`-subtree keys
+- `r` : relates root `key` with `right`-subtree keys
+
+\begin{code}
+{-@ data Map k a < l :: k -> k -> Prop
+                 , r :: k -> k -> Prop >
+    = Tip
+    | Bin (sz :: Size) (key :: k) (val :: a)
+          (left  :: Map <l,r> (k<l key>) a)
+          (right :: Map <l,r> (k<r key>) a) @-}
+\end{code}
+
+
+Ex: Binary Search Trees
+-----------------------
+
+Keys are *Binary-Search* Ordered
+
+<br>
+
+\begin{code}
+{-@ type BST k a = 
+      Map <{\r v -> v < r }, 
+           {\r v -> v > r }> 
+          k a                   @-}
+\end{code}
+
+Ex: Minimum Heaps 
+-----------------
+
+Root contains *minimum* value
+
+<br>
+
+\begin{code}
+{-@ type MinHeap k a = 
+      Map <{\r v -> r <= v}, 
+           {\r v -> r <= v}> 
+           k a               @-}
+\end{code}
+
+Ex: Maximum Heaps 
+-----------------
+
+Root contains *maximum* value
+
+<br>
+
+\begin{code}
+{-@ type MaxHeap k a = 
+      Map <{\r v -> r >= v}, 
+           {\r v -> r >= v}> 
+           k a               @-}
+\end{code}
+
+
+Example: Data.Map
+-----------------
+
+Standard Key-Value container
+
+- <div class="fragment">1300+ non-comment lines</div>
+
+- <div class="fragment">`insert`, `split`, `merge`,...</div>
+
+- <div class="fragment">Rotation, Rebalance,...</div>
+
+<div class="fragment">
+SMT & inference crucial for [verification](https://github.com/ucsd-progsys/liquidhaskell/blob/master/benchmarks/esop2013-submission/Base.hs)
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Map.hs" target="_blank">Demo:</a>Try online!
+</div>
+
+Recap: Abstract Refinements
+---------------------------
+
+<div class="fragment">
+
+Decouple invariants from *functions*
+
++ `max`
++ `loop`
++ `foldr`
+
+</div>
+
+<div class="fragment">
+Decouple invariants from *data*
+
++ `Vector`
++ `List`
++ `Tree`
+
+</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract Refinements:* Decouple Invariants 
+5. <div class="fragment">Er, what of *lazy evaluation*?</div>
diff --git a/docs/slides/plpv14/lhs/08_Recursive.lhs.markdown b/docs/slides/plpv14/lhs/08_Recursive.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/08_Recursive.lhs.markdown
@@ -0,0 +1,671 @@
+Decouple Invariants From Data {#recursive} 
+==========================================
+
+Recursive Structures 
+--------------------
+
+<div class="fragment">
+Lets see another example of decoupling...
+</div>
+
+<div class="hidden">
+
+<pre><span class=hs-linenum>13: </span><span class='hs-comment'>{-# LANGUAGE NoMonomorphismRestriction #-}</span>
+<span class=hs-linenum>14: </span>
+<span class=hs-linenum>15: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>List</span> <span class='hs-layout'>(</span><span class='hs-varid'>insertSort</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>16: </span>
+<span class=hs-linenum>17: </span><span class='hs-keyword'>{-@</span> <span class='hs-conid'>LIQUID</span> <span class='hs-str'>"--no-termination"</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>18: </span>
+<span class=hs-linenum>19: </span><span class='hs-definition'>mergeSort</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
+<span class=hs-linenum>20: </span><span class='hs-definition'>insertSort</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> 
+<span class=hs-linenum>21: </span><span class='hs-definition'>slist</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>22: </span><span class='hs-definition'>slist'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>23: </span><span class='hs-definition'>iGoUp</span><span class='hs-layout'>,</span> <span class='hs-varid'>iGoDn</span><span class='hs-layout'>,</span> <span class='hs-varid'>iDiff</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Int</span><span class='hs-keyglyph'>]</span>
+<span class=hs-linenum>24: </span><span class='hs-keyword'>infixr</span> <span class='hs-varop'>`C`</span>
+</pre>
+</div>
+
+Decouple Invariants From Recursive Data
+=======================================
+
+Recall: Lists
+-------------
+
+
+<pre><span class=hs-linenum>35: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span> 
+<span class=hs-linenum>36: </span>         <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+</pre>
+
+
+Recall: Refined Constructors 
+----------------------------
+
+Define *increasing* Lists with strengthened constructors:
+
+ <br>
+<pre><span class=hs-linenum>46: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>47: </span>  <span class='hs-conid'>N</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>48: </span>  <span class='hs-conid'>C</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>hd</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>tl</span><span class='hs-conop'>:</span> <span class='hs-conid'>L</span> <span class='hs-layout'>{</span><span class='hs-varid'>v</span><span class='hs-conop'>:</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>hd</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+</pre>
+
+Problem: Decreasing Lists?
+--------------------------
+
+What if we need *both* [increasing and decreasing lists](http://web.cecs.pdx.edu/~sheard/Code/QSort.html)?
+
+<br>
+
+<div class="fragment">
+*Separate* types are tedious...
+</div>
+
+
+Abstract That Refinement!
+-------------------------
+
+
+<pre><span class=hs-linenum>67: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;</span>
+<span class=hs-linenum>68: </span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span> 
+<span class=hs-linenum>69: </span>      <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C</span> <span class='hs-layout'>(</span><span class='hs-varid'>hd</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>tl</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>hd</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+- <div class="fragment"> `p` is a *binary* relation between two `a` values</div>
+
+- <div class="fragment"> Definition relates `hd` with *all* the elements of `tl`</div>
+
+- <div class="fragment"> Recursive: `p` holds for *every pair* of elements!</div>
+
+Example
+-------
+
+Consider a list with *three* or more elements 
+
+ <br>
+<pre><span class=hs-linenum>86: </span><span class='hs-definition'>x1</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>x2</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>x3</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>rest</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span> 
+</pre>
+
+Example: Unfold Once
+--------------------
+
+ <br> 
+<pre><span class=hs-linenum>93: </span><span class='hs-definition'>x1</span>                 <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>94: </span><span class='hs-definition'>x2</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>x3</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>rest</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>x1</span><span class='hs-varop'>&gt;</span> 
+</pre>
+
+Example: Unfold Twice
+---------------------
+
+ <br> 
+<pre><span class=hs-linenum>101: </span><span class='hs-definition'>x1</span>          <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>102: </span><span class='hs-definition'>x2</span>          <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>x1</span><span class='hs-varop'>&gt;</span>  
+<span class=hs-linenum>103: </span><span class='hs-definition'>x3</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>rest</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>x1</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>p</span> <span class='hs-varid'>x2</span><span class='hs-varop'>&gt;</span> 
+</pre>
+
+Example: Unfold Thrice
+----------------------
+
+ <br> 
+<pre><span class=hs-linenum>110: </span><span class='hs-definition'>x1</span>   <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span>
+<span class=hs-linenum>111: </span><span class='hs-definition'>x2</span>   <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>x1</span><span class='hs-varop'>&gt;</span>  
+<span class=hs-linenum>112: </span><span class='hs-definition'>x3</span>   <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>x1</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>p</span> <span class='hs-varid'>x2</span><span class='hs-varop'>&gt;</span>  
+<span class=hs-linenum>113: </span><span class='hs-definition'>rest</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>x1</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>p</span> <span class='hs-varid'>x2</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>p</span> <span class='hs-varid'>x3</span><span class='hs-varop'>&gt;</span> 
+</pre>
+
+<br>
+
+<div class="fragment">
+Note how `p` holds between **every pair** of elements in the list. 
+</div>
+
+A Concrete Example
+------------------
+
+That was a rather *abstract*!
+
+<br>
+
+How can we *use* fact that `p` holds between *every pair* ?
+
+
+Example: Increasing Lists
+-------------------------
+
+*Instantiate* `p` with a *concrete* refinement
+
+<br>
+
+
+<pre><span class=hs-linenum>140: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>IncL</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>L</span> <span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>hd</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>hd</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+- <div class="fragment"> Refinement says `hd` less than each tail element `v`,</div>
+
+- <div class="fragment"> Thus, `IncL` denotes *increaing* lists. </div>
+
+Example: Increasing Lists
+-------------------------
+
+LiquidHaskell verifies that `slist` is indeed increasing...
+
+
+<pre><span class=hs-linenum>155: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>slist</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IncL</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>156: </span><a class=annot href="#"><span class=annottext>(L &lt;\hd2 VV -&gt; (hd2 &lt;= VV)&gt; (Int))</span><span class='hs-definition'>slist</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+x1:{x10 : (Int) | (x10 &gt; 0)}
+-&gt; (L &lt;p&gt; {x10 : (Int)&lt;p x1&gt; | (x10 &gt; 0)})
+-&gt; (L &lt;p&gt; {x10 : (Int) | (x10 &gt; 0)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (6  :  int))}</span><span class='hs-num'>6</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+x1:{x10 : (Int) | (x10 &gt; 0)}
+-&gt; (L &lt;p&gt; {x10 : (Int)&lt;p x1&gt; | (x10 &gt; 0)})
+-&gt; (L &lt;p&gt; {x10 : (Int) | (x10 &gt; 0)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (12  :  int))}</span><span class='hs-num'>12</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+x1:{x10 : (Int) | (x10 &gt; 0)}
+-&gt; (L &lt;p&gt; {x10 : (Int)&lt;p x1&gt; | (x10 &gt; 0)})
+-&gt; (L &lt;p&gt; {x10 : (Int) | (x10 &gt; 0)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>(L &lt;\_ VV -&gt; false&gt; {x3 : (Int) | false})</span><span class='hs-conid'>N</span></a>
+</pre>
+
+<br> 
+
+<div class="fragment">
+
+... and protests that `slist'` is not: 
+
+
+<pre><span class=hs-linenum>166: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>slist'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IncL</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>167: </span><a class=annot href="#"><span class=annottext>(L &lt;\hd2 VV -&gt; (hd2 &lt;= VV)&gt; (Int))</span><span class='hs-definition'>slist'</span></a> <span class='hs-keyglyph'>=</span> <span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (6  :  int))}</span><span class='hs-num'>6</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+x1:{x10 : (Int) | (x10 &gt; 0)}
+-&gt; (L &lt;p&gt; {x10 : (Int)&lt;p x1&gt; | (x10 &gt; 0)})
+-&gt; (L &lt;p&gt; {x10 : (Int) | (x10 &gt; 0)})</span><span class='hs-varop'>`C`</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+x1:{x10 : (Int) | (x10 &gt; 0)}
+-&gt; (L &lt;p&gt; {x10 : (Int)&lt;p x1&gt; | (x10 &gt; 0)})
+-&gt; (L &lt;p&gt; {x10 : (Int) | (x10 &gt; 0)})</span><span class='hs-varop'>`C`</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (12  :  int))}</span><span class='hs-num'>12</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>forall &lt;p :: (GHC.Types.Int)-&gt; (GHC.Types.Int)-&gt; Bool&gt;.
+x1:{x10 : (Int) | (x10 &gt; 0)}
+-&gt; (L &lt;p&gt; {x10 : (Int)&lt;p x1&gt; | (x10 &gt; 0)})
+-&gt; (L &lt;p&gt; {x10 : (Int) | (x10 &gt; 0)})</span><span class='hs-varop'>`C`</span></a></span><span class=hs-error> </span><span class=hs-error><a class=annot href="#"><span class=annottext>(L &lt;\_ VV -&gt; false&gt; {x3 : (Int) | false})</span><span class='hs-conid'>N</span></a></span>
+</pre>
+</div>
+
+Insertion Sort
+--------------
+
+
+<pre><span class=hs-linenum>175: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>insertSort</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IncL</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>176: </span><a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; [a] -&gt; (L &lt;\hd2 VV -&gt; (hd2 &lt;= VV)&gt; a)</span><span class='hs-definition'>insertSort</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>(a
+ -&gt; (L &lt;\x11 VV -&gt; (VV &gt;= x11)&gt; a)
+ -&gt; (L &lt;\x11 VV -&gt; (VV &gt;= x11)&gt; a))
+-&gt; (L &lt;\x11 VV -&gt; (VV &gt;= x11)&gt; a)
+-&gt; [a]
+-&gt; (L &lt;\x11 VV -&gt; (VV &gt;= x11)&gt; a)</span><span class='hs-varid'>foldr</span></a> <a class=annot href="#"><span class=annottext>a -&gt; (L &lt;\x4 VV -&gt; (VV &gt;= x4)&gt; a) -&gt; (L &lt;\x2 VV -&gt; (VV &gt;= x2)&gt; a)</span><span class='hs-varid'>insert</span></a> <a class=annot href="#"><span class=annottext>(L &lt;\_ VV -&gt; false&gt; {VV : a | false})</span><span class='hs-conid'>N</span></a>
+<span class=hs-linenum>177: </span>
+<span class=hs-linenum>178: </span><a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+a -&gt; (L &lt;\x2 VV -&gt; (VV &gt;= x2)&gt; a) -&gt; (L &lt;\x1 VV -&gt; (VV &gt;= x1)&gt; a)</span><span class='hs-definition'>insert</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>y</span></a> <span class='hs-conid'>N</span>          <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (VV == y)}
+-&gt; (L &lt;p&gt; {VV : a&lt;p x1&gt; | (VV == y)})
+-&gt; (L &lt;p&gt; {VV : a | (VV == y)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>(L &lt;\_ VV -&gt; false&gt; {VV : a | false})</span><span class='hs-conid'>N</span></a>
+<span class=hs-linenum>179: </span><span class='hs-definition'>insert</span> <span class='hs-varid'>y</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>180: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>x1:a -&gt; x2:a -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>&lt;</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a>           <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (VV &gt;= y)}
+-&gt; (L &lt;p&gt; {VV : a&lt;p x1&gt; | (VV &gt;= y)})
+-&gt; (L &lt;p&gt; {VV : a | (VV &gt;= y)})</span><span class='hs-varop'>`C`</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (VV &gt; y) &amp;&amp; (VV &gt;= x)}
+-&gt; (L &lt;p&gt; {VV : a&lt;p x1&gt; | (VV &gt; y) &amp;&amp; (VV &gt;= x)})
+-&gt; (L &lt;p&gt; {VV : a | (VV &gt; y) &amp;&amp; (VV &gt;= x)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (L &lt;\x3 VV -&gt; (VV &gt;= x3)&gt; {VV : a | (VV &gt;= x)}) | (x2 == xs)}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>181: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>       <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (VV &gt;= x)}
+-&gt; (L &lt;p&gt; {VV : a&lt;p x1&gt; | (VV &gt;= x)})
+-&gt; (L &lt;p&gt; {VV : a | (VV &gt;= x)})</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+a -&gt; (L &lt;\x2 VV -&gt; (VV &gt;= x2)&gt; a) -&gt; (L &lt;\x1 VV -&gt; (VV &gt;= x1)&gt; a)</span><span class='hs-varid'>insert</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>{x2 : (L &lt;\x3 VV -&gt; (VV &gt;= x3)&gt; {VV : a | (VV &gt;= x)}) | (x2 == xs)}</span><span class='hs-varid'>xs</span></a>
+</pre>
+
+<br>
+
+(*Hover* over `insert'` to see inferred type.)
+
+Checking GHC Lists
+------------------
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Order.hs" target= "_blank">Demo:</a> 
+Above applies to GHC's List definition:
+
+ <br> 
+<pre><span class=hs-linenum>195: </span><span class='hs-keyword'>data</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span><span class='hs-varop'>&gt;</span>
+<span class=hs-linenum>196: </span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>[]</span> 
+<span class=hs-linenum>197: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-conop'>:</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>h</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>tl</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span> <span class='hs-varid'>h</span><span class='hs-varop'>&gt;</span><span class='hs-keyglyph'>]</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>p</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
+</pre>
+
+Checking GHC Lists
+------------------
+
+Increasing Lists
+
+<br>
+
+
+<pre><span class=hs-linenum>208: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Incs</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span><span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>h</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>h</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>209: </span>
+<span class=hs-linenum>210: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>iGoUp</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Incs</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>211: </span><a class=annot href="#"><span class=annottext>[(Int)]&lt;\h6 VV -&gt; (h6 &lt;= VV)&gt;</span><span class='hs-definition'>iGoUp</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x4 : [{x14 : (Int) | (x14 &gt; 0)}]&lt;\x11 VV -&gt; (x11 /= x12) &amp;&amp; (x12 &gt; 0) &amp;&amp; (x12 &gt; x11) &amp;&amp; (x11 &lt;= x12)&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>,</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a><span class='hs-layout'>,</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a><span class='hs-keyglyph'>]</span>
+</pre>
+
+Checking GHC Lists
+------------------
+
+Decreasing Lists
+
+<br>
+
+
+<pre><span class=hs-linenum>222: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Decs</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span><span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>h</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>h</span> <span class='hs-varop'>&gt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>223: </span>
+<span class=hs-linenum>224: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>iGoDn</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Decs</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>225: </span><a class=annot href="#"><span class=annottext>[(Int)]&lt;\h8 VV -&gt; (h8 &gt;= VV)&gt;</span><span class='hs-definition'>iGoDn</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x4 : [{x15 : (Int) | (x15 &gt; 0)}]&lt;\x13 VV -&gt; (x12 == 1) &amp;&amp; (x13 /= x12) &amp;&amp; (x12 &gt; 0) &amp;&amp; (x13 &gt;= x12) &amp;&amp; (x12 &lt; x13)&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a><span class='hs-layout'>,</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a><span class='hs-layout'>,</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-keyglyph'>]</span>
+</pre>
+
+
+Checking GHC Lists
+------------------
+
+Duplicate-free Lists
+
+<br>
+
+
+<pre><span class=hs-linenum>237: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>Difs</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span><span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>h</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>h</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>238: </span>
+<span class=hs-linenum>239: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>iDiff</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Difs</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>240: </span><a class=annot href="#"><span class=annottext>[(Int)]&lt;\h10 VV -&gt; (h10 /= VV)&gt;</span><span class='hs-definition'>iDiff</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x4 : [{x14 : (Int) | (x14 &gt; 0)}]&lt;\x12 VV -&gt; (x12 /= x11) &amp;&amp; (x11 &gt; 0) &amp;&amp; (x12 &gt;= x11) &amp;&amp; (x11 &lt; x12)&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>,</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (3  :  int))}</span><span class='hs-num'>3</span></a><span class='hs-layout'>,</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a><span class='hs-keyglyph'>]</span>
+</pre>
+
+Checking GHC Lists
+------------------
+
+Now we can check all the usual list sorting algorithms 
+
+Example: `mergeSort` [1/2]
+--------------------------
+
+
+<pre><span class=hs-linenum>252: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>mergeSort</span>  <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Incs</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>253: </span><a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; [a] -&gt; [a]&lt;\h6 VV -&gt; (h6 &lt;= VV)&gt;</span><span class='hs-definition'>mergeSort</span></a> <span class='hs-conid'>[]</span>   <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+{x4 : [{VV : a | false}]&lt;p&gt; | (((null x4)) &lt;=&gt; true) &amp;&amp; ((len x4) == 0) &amp;&amp; ((sumLens x4) == 0)}</span><span class='hs-conid'>[]</span></a>
+<span class=hs-linenum>254: </span><span class='hs-definition'>mergeSort</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>x</span><span class='hs-keyglyph'>]</span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x6 : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | (((null x6)) &lt;=&gt; true) &amp;&amp; ((len x6) == 0) &amp;&amp; ((sumLens x6) == 0) &amp;&amp; ((len x6) &gt;= 0) &amp;&amp; ((sumLens x6) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a><span class='hs-keyglyph'>]</span>
+<span class=hs-linenum>255: </span><span class='hs-definition'>mergeSort</span> <span class='hs-varid'>xs</span>   <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x10 : [a]&lt;\x11 VV -&gt; (VV &gt;= x11)&gt; | ((len x10) &gt;= 0)}
+-&gt; x2:{x7 : [a]&lt;\x8 VV -&gt; (VV &gt;= x8)&gt; | ((len x7) &gt;= 0)}
+-&gt; {x4 : [a]&lt;\x5 VV -&gt; (x5 &lt;= VV)&gt; | ((len x4) &gt;= 0) &amp;&amp; ((len x4) &gt;= (len x1)) &amp;&amp; ((len x4) &gt;= (len x2))}</span><span class='hs-varid'>merge</span></a> <a class=annot href="#"><span class=annottext>{x4 : [a]&lt;\x5 VV -&gt; (x5 &lt;= VV)&gt; | (x4 == xs1') &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs1'</span></a> <a class=annot href="#"><span class=annottext>{x4 : [a]&lt;\x5 VV -&gt; (x5 &lt;= VV)&gt; | (x4 == xs2') &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs2'</span></a> 
+<span class=hs-linenum>256: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>257: </span>   <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : [a] | (VV == xs1) &amp;&amp; ((len VV) == (len xs1)) &amp;&amp; ((len VV) &gt;= 0) &amp;&amp; ((len VV) &gt;= (len xs2))}</span><span class='hs-varid'>xs1</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV == xs2) &amp;&amp; ((len VV) == (len xs2)) &amp;&amp; ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len xs1)) &amp;&amp; ((len VV) &lt;= (len xs1))}</span><span class='hs-varid'>xs2</span></a><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x14 : [a] | ((len x14) &gt; 0)}
+-&gt; ({x9 : [a] | ((len x9) &gt;= 0) &amp;&amp; ((len x9) &lt;= (len x1))}, {x12 : [a] | ((len x12) &gt;= 0) &amp;&amp; ((len x12) &lt;= (len x1))})&lt;\x5 VV -&gt; ((len x6) &gt;= 0) &amp;&amp; ((len x6) &lt;= (len x5)) &amp;&amp; ((len x6) &lt;= (len x1))&gt;</span><span class='hs-varid'>split</span></a> <a class=annot href="#"><span class=annottext>{x3 : [a] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+<span class=hs-linenum>258: </span>   <a class=annot href="#"><span class=annottext>[a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt;</span><span class='hs-varid'>xs1'</span></a>        <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>[a] -&gt; [a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt;</span><span class='hs-varid'>mergeSort</span></a> <a class=annot href="#"><span class=annottext>{x7 : [a] | (x7 == xs1) &amp;&amp; (x7 == xs1) &amp;&amp; ((len x7) == (len xs1)) &amp;&amp; ((len x7) &gt;= 0) &amp;&amp; ((len x7) &gt;= (len xs2)) &amp;&amp; ((sumLens x7) &gt;= 0)}</span><span class='hs-varid'>xs1</span></a>
+<span class=hs-linenum>259: </span>   <a class=annot href="#"><span class=annottext>[a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt;</span><span class='hs-varid'>xs2'</span></a>        <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>[a] -&gt; [a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt;</span><span class='hs-varid'>mergeSort</span></a> <a class=annot href="#"><span class=annottext>{x8 : [a] | (x8 == xs2) &amp;&amp; (x8 == xs2) &amp;&amp; ((len x8) == (len xs2)) &amp;&amp; ((len x8) &gt;= 0) &amp;&amp; ((sumLens x8) &gt;= 0) &amp;&amp; ((len x8) &lt;= (len xs1)) &amp;&amp; ((len x8) &lt;= (len xs1))}</span><span class='hs-varid'>xs2</span></a>
+</pre>
+
+Example: `mergeSort` [1/2]
+--------------------------
+
+
+<pre><span class=hs-linenum>266: </span><a class=annot href="#"><span class=annottext>forall a.
+x1:{VV : [a] | ((len VV) &gt;= 0)}
+-&gt; ({VV : [a] | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len x1))}, {VV : [a] | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len x1))})&lt;\x1 VV -&gt; ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len x1)) &amp;&amp; ((len VV) &lt;= (len x1))&gt;</span><span class='hs-definition'>split</span></a> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>y</span><span class='hs-conop'>:</span><span class='hs-varid'>zs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a b &lt;p2 :: a-&gt; b-&gt; Bool&gt;.
+x1:a
+-&gt; x2:{VV : b&lt;p2 x1&gt; | true}
+-&gt; {x3 : (a, b)&lt;p2&gt; | ((fst x3) == x1) &amp;&amp; ((snd x3) == x2)}</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:a
+-&gt; x2:[{VV : a&lt;p x1&gt; | true}]&lt;p&gt;
+-&gt; {x4 : [a]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{x8 : [a] | (x8 == xs) &amp;&amp; (x8 == xs) &amp;&amp; ((len x8) == (len xs)) &amp;&amp; ((len x8) &gt;= 0) &amp;&amp; ((len x8) &gt;= (len ys)) &amp;&amp; ((sumLens x8) &gt;= 0) &amp;&amp; ((len x8) &lt;= (len zs))}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:a
+-&gt; x2:[{VV : a&lt;p x1&gt; | true}]&lt;p&gt;
+-&gt; {x4 : [a]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{x9 : [a] | (x9 == ys) &amp;&amp; (x9 == ys) &amp;&amp; ((len x9) == (len ys)) &amp;&amp; ((len x9) &gt;= 0) &amp;&amp; ((sumLens x9) &gt;= 0) &amp;&amp; ((len x9) &lt;= (len xs)) &amp;&amp; ((len x9) &lt;= (len xs)) &amp;&amp; ((len x9) &lt;= (len zs))}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>)</span> 
+<span class=hs-linenum>267: </span>  <span class='hs-keyword'>where</span> 
+<span class=hs-linenum>268: </span>    <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : [a] | (VV == xs) &amp;&amp; ((len VV) == (len xs)) &amp;&amp; ((len VV) &gt;= 0) &amp;&amp; ((len VV) &gt;= (len ys)) &amp;&amp; ((len VV) &lt;= (len zs))}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{VV : [a] | (VV == ys) &amp;&amp; ((len VV) == (len ys)) &amp;&amp; ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len xs)) &amp;&amp; ((len VV) &lt;= (len xs)) &amp;&amp; ((len VV) &lt;= (len zs))}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a.
+x1:{VV : [a] | ((len VV) &gt;= 0)}
+-&gt; ({VV : [a] | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len x1))}, {VV : [a] | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len x1))})&lt;\x1 VV -&gt; ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len x1)) &amp;&amp; ((len VV) &lt;= (len x1))&gt;</span><span class='hs-varid'>split</span></a> <a class=annot href="#"><span class=annottext>{x4 : [a] | (x4 == zs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>zs</span></a>
+<span class=hs-linenum>269: </span><span class='hs-definition'>split</span> <span class='hs-varid'>xs</span>       <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a b &lt;p2 :: a-&gt; b-&gt; Bool&gt;.
+x1:a
+-&gt; x2:{VV : b&lt;p2 x1&gt; | true}
+-&gt; {x3 : (a, b)&lt;p2&gt; | ((fst x3) == x1) &amp;&amp; ((snd x3) == x2)}</span><span class='hs-layout'>(</span></a><a class=annot href="#"><span class=annottext>{x3 : [a] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>,</span> <a class=annot href="#"><span class=annottext>{x6 : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | (((null x6)) &lt;=&gt; true) &amp;&amp; ((len x6) == 0) &amp;&amp; ((sumLens x6) == 0) &amp;&amp; ((len x6) &gt;= 0) &amp;&amp; ((sumLens x6) &gt;= 0)}</span><span class='hs-conid'>[]</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>270: </span>
+<span class=hs-linenum>271: </span><a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+xs:{VV : [a]&lt;\x3 VV -&gt; (VV &gt;= x3)&gt; | ((len VV) &gt;= 0)}
+-&gt; x1:{VV : [a]&lt;\x2 VV -&gt; (VV &gt;= x2)&gt; | ((len VV) &gt;= 0)}
+-&gt; {VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &gt;= (len x1)) &amp;&amp; ((len VV) &gt;= (len xs))}</span><span class='hs-definition'>merge</span></a> <a class=annot href="#"><span class=annottext>{VV : [a]&lt;\x1 VV -&gt; (VV &gt;= x1)&gt; | ((len VV) &gt;= 0)}</span><span class='hs-varid'>xs</span></a> <span class='hs-conid'>[]</span>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x4 : [a]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+<span class=hs-linenum>272: </span><span class='hs-definition'>merge</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>ys</span>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x3 : [a]&lt;\x4 VV -&gt; (VV &gt;= x4)&gt; | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-varid'>ys</span></a>
+<span class=hs-linenum>273: </span><span class='hs-definition'>merge</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>y</span><span class='hs-conop'>:</span><span class='hs-varid'>ys</span><span class='hs-layout'>)</span> 
+<span class=hs-linenum>274: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x1:a -&gt; x2:a -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt;= x2))}</span><span class='hs-varop'>&lt;=</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (x &lt;= VV)}
+-&gt; x2:[{VV : a&lt;p x1&gt; | (x &lt;= VV)}]&lt;p&gt;
+-&gt; {x4 : [{VV : a | (x &lt;= VV)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+xs:{VV : [a]&lt;\x3 VV -&gt; (VV &gt;= x3)&gt; | ((len VV) &gt;= 0)}
+-&gt; x1:{VV : [a]&lt;\x2 VV -&gt; (VV &gt;= x2)&gt; | ((len VV) &gt;= 0)}
+-&gt; {VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &gt;= (len x1)) &amp;&amp; ((len VV) &gt;= (len xs))}</span><span class='hs-varid'>merge</span></a> <a class=annot href="#"><span class=annottext>{x4 : [{VV : a | (VV &gt;= x)}]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (x &lt;= VV) &amp;&amp; (y &lt;= VV)}
+-&gt; x2:[{VV : a&lt;p x1&gt; | (x &lt;= VV) &amp;&amp; (y &lt;= VV)}]&lt;p&gt;
+-&gt; {x4 : [{VV : a | (x &lt;= VV) &amp;&amp; (y &lt;= VV)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{x4 : [{VV : a | (VV &gt;= y)}]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 == ys) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>275: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (VV &gt;= y)}
+-&gt; x2:[{VV : a&lt;p x1&gt; | (VV &gt;= y)}]&lt;p&gt;
+-&gt; {x4 : [{VV : a | (VV &gt;= y)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+xs:{VV : [a]&lt;\x3 VV -&gt; (VV &gt;= x3)&gt; | ((len VV) &gt;= 0)}
+-&gt; x1:{VV : [a]&lt;\x2 VV -&gt; (VV &gt;= x2)&gt; | ((len VV) &gt;= 0)}
+-&gt; {VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &gt;= (len x1)) &amp;&amp; ((len VV) &gt;= (len xs))}</span><span class='hs-varid'>merge</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (VV &gt; y)}
+-&gt; x2:[{VV : a&lt;p x1&gt; | (VV &gt; y)}]&lt;p&gt;
+-&gt; {x4 : [{VV : a | (VV &gt; y)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{x4 : [{VV : a | (VV &gt;= x)}]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x4 : [{VV : a | (VV &gt;= y)}]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 == ys) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>ys</span></a>
+</pre>
+
+Example: `Data.List.sort` 
+-------------------------
+
+GHC's "official" list sorting routine
+
+Juggling lists of increasing & decreasing lists
+
+
+Ex: `Data.List.sort` [1/4]
+--------------------------
+
+Juggling lists of increasing & decreasing lists
+
+<br>
+
+
+<pre><span class=hs-linenum>294: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>sort</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Incs</span> <span class='hs-varid'>a</span>  <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>295: </span><a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; [a] -&gt; [a]&lt;\h6 VV -&gt; (h6 &lt;= VV)&gt;</span><span class='hs-definition'>sort</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x5 : [{x9 : [a]&lt;\x10 VV -&gt; (x10 &lt;= VV)&gt; | ((len x9) &gt;= 0)}]&lt;\_ VV -&gt; ((len x7) &gt;= 0)&gt; | ((len x5) &gt; 0)}
+-&gt; {x2 : [a]&lt;\x3 VV -&gt; (x3 &lt;= VV)&gt; | ((len x2) &gt;= 0)}</span><span class='hs-varid'>mergeAll</span></a> <a class=annot href="#"><span class=annottext>forall &lt;q :: [a]-&gt; [[a]]-&gt; Bool, p :: [[a]]-&gt; [a]-&gt; Bool&gt;.
+(x:{x26 : [{x30 : [a]&lt;\x31 VV -&gt; (x31 &lt;= VV)&gt; | ((len x30) &gt;= 0)}]&lt;\_ VV -&gt; ((len x28) &gt;= 0)&gt; | ((len x26) &gt; 0)}
+ -&gt; {x23 : [a]&lt;\x24 VV -&gt; (x24 &lt;= VV)&gt;&lt;p x&gt; | ((len x23) &gt;= 0)})
+-&gt; (y:[a]
+    -&gt; {x26 : [{x30 : [a]&lt;\x31 VV -&gt; (x31 &lt;= VV)&gt; | ((len x30) &gt;= 0)}]&lt;\_ VV -&gt; ((len x28) &gt;= 0)&gt;&lt;q y&gt; | ((len x26) &gt; 0)})
+-&gt; x3:[a]
+-&gt; exists [z:{x26 : [{x30 : [a]&lt;\x31 VV -&gt; (x31 &lt;= VV)&gt; | ((len x30) &gt;= 0)}]&lt;\_ VV -&gt; ((len x28) &gt;= 0)&gt;&lt;q x3&gt; | ((len x26) &gt; 0)}].{x23 : [a]&lt;\x24 VV -&gt; (x24 &lt;= VV)&gt;&lt;p z&gt; | ((len x23) &gt;= 0)}</span><span class='hs-varop'>.</span></a> <a class=annot href="#"><span class=annottext>[a]
+-&gt; {x2 : [{x6 : [a]&lt;\x7 VV -&gt; (x7 &lt;= VV)&gt; | ((len x6) &gt;= 0)}]&lt;\_ VV -&gt; ((len x4) &gt;= 0)&gt; | ((len x2) &gt; 0)}</span><span class='hs-varid'>sequences</span></a>
+<span class=hs-linenum>296: </span>
+<span class=hs-linenum>297: </span><a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+[a]
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-definition'>sequences</span></a> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-conop'>:</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>298: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:a
+-&gt; x2:a
+-&gt; {x4 : (Ordering) | ((x4 == GHC.Types.EQ) &lt;=&gt; (x1 == x2)) &amp;&amp; ((x4 == GHC.Types.GT) &lt;=&gt; (x1 &gt; x2)) &amp;&amp; ((x4 == GHC.Types.LT) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>`compare`</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == b)}</span><span class='hs-varid'>b</span></a> <a class=annot href="#"><span class=annottext>x1:(Ordering)
+-&gt; x2:(Ordering) -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 == x2))}</span><span class='hs-varop'>==</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Ordering) | (x3 == GHC.Types.GT) &amp;&amp; ((cmp x3) == GHC.Types.GT)}</span><span class='hs-conid'>GT</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+a:a
+-&gt; {VV : [{VV : a | (VV &gt; a)}]&lt;\x2 VV -&gt; (VV &gt; a) &amp;&amp; (VV &gt; x2)&gt; | ((len VV) &gt; 0)}
+-&gt; {VV : [a] | ((len VV) &gt;= 0)}
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-varid'>descending</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == b)}</span><span class='hs-varid'>b</span></a> <a class=annot href="#"><span class=annottext>{x4 : [{VV : a | (VV == a) &amp;&amp; (VV &gt; b)}]&lt;\_ VV -&gt; false&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a><span class='hs-keyglyph'>]</span>  <a class=annot href="#"><span class=annottext>{x4 : [a] | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+<span class=hs-linenum>299: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>           <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+a:a
+-&gt; (x1:{VV : [{VV : a | (VV &gt;= a)}]&lt;\x3 VV -&gt; (a &lt;= VV) &amp;&amp; (x3 &lt;= VV)&gt; | ((len VV) &gt; 0)}
+    -&gt; {VV : [a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt; | (VV /= x1) &amp;&amp; ((len VV) &gt; 0) &amp;&amp; ((len VV) &gt; (len x1))})
+-&gt; {VV : [a] | ((len VV) &gt;= 0)}
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-varid'>ascending</span></a>  <a class=annot href="#"><span class=annottext>{VV : a | (VV == b)}</span><span class='hs-varid'>b</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (a &lt;= VV)}
+-&gt; x2:[{VV : a&lt;p x1&gt; | (a &lt;= VV)}]&lt;p&gt;
+-&gt; {x4 : [{VV : a | (a &lt;= VV)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x4 : [a] | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+<span class=hs-linenum>300: </span><span class='hs-definition'>sequences</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>x</span><span class='hs-keyglyph'>]</span>           <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x6 : [{x8 : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | false}]&lt;\_ VV -&gt; false&gt; | (((null x6)) &lt;=&gt; true) &amp;&amp; ((len x6) == 0) &amp;&amp; ((sumLens x6) == 0) &amp;&amp; ((len x6) &gt;= 0) &amp;&amp; ((sumLens x6) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{x4 : [{VV : a | (VV == a)}]&lt;\_ VV -&gt; false&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>x</span></a><span class='hs-keyglyph'>]</span><span class='hs-keyglyph'>]</span>
+<span class=hs-linenum>301: </span><span class='hs-definition'>sequences</span> <span class='hs-conid'>[]</span>            <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x6 : [{x8 : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | false}]&lt;\_ VV -&gt; false&gt; | (((null x6)) &lt;=&gt; true) &amp;&amp; ((len x6) == 0) &amp;&amp; ((sumLens x6) == 0) &amp;&amp; ((len x6) &gt;= 0) &amp;&amp; ((sumLens x6) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{x6 : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | (((null x6)) &lt;=&gt; true) &amp;&amp; ((len x6) == 0) &amp;&amp; ((sumLens x6) == 0) &amp;&amp; ((len x6) &gt;= 0) &amp;&amp; ((sumLens x6) &gt;= 0)}</span><span class='hs-conid'>[]</span></a><span class='hs-keyglyph'>]</span>
+</pre>
+
+Ex: `Data.List.sort` [2/4]
+--------------------------
+
+Juggling lists of increasing & decreasing lists
+
+<br>
+
+
+<pre><span class=hs-linenum>312: </span><a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+a:a
+-&gt; {VV : [{VV : a | (VV &gt; a)}]&lt;\x2 VV -&gt; (VV &gt; a) &amp;&amp; (VV &gt; x2)&gt; | ((len VV) &gt; 0)}
+-&gt; {VV : [a] | ((len VV) &gt;= 0)}
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-definition'>descending</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>{VV : [{VV : a | (VV &gt; a)}]&lt;\x1 VV -&gt; (VV &gt; a) &amp;&amp; (VV &gt; x1)&gt; | ((len VV) &gt; 0)}</span><span class='hs-keyword'>as</span></a> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>bs</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>313: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:a
+-&gt; x2:a
+-&gt; {x4 : (Ordering) | ((x4 == GHC.Types.EQ) &lt;=&gt; (x1 == x2)) &amp;&amp; ((x4 == GHC.Types.GT) &lt;=&gt; (x1 &gt; x2)) &amp;&amp; ((x4 == GHC.Types.LT) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>`compare`</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == b)}</span><span class='hs-varid'>b</span></a> <a class=annot href="#"><span class=annottext>x1:(Ordering)
+-&gt; x2:(Ordering) -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 == x2))}</span><span class='hs-varop'>==</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Ordering) | (x3 == GHC.Types.GT) &amp;&amp; ((cmp x3) == GHC.Types.GT)}</span><span class='hs-conid'>GT</span></a> 
+<span class=hs-linenum>314: </span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+a:a
+-&gt; {VV : [{VV : a | (VV &gt; a)}]&lt;\x2 VV -&gt; (VV &gt; a) &amp;&amp; (VV &gt; x2)&gt; | ((len VV) &gt; 0)}
+-&gt; {VV : [a] | ((len VV) &gt;= 0)}
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-varid'>descending</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == b)}</span><span class='hs-varid'>b</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (VV &gt; b)}
+-&gt; x2:[{VV : a&lt;p x1&gt; | (VV &gt; b)}]&lt;p&gt;
+-&gt; {x4 : [{VV : a | (VV &gt; b)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{x5 : [{VV : a | (VV &gt; a)}]&lt;\x6 VV -&gt; (VV &gt; a) &amp;&amp; (VV &gt; x6)&gt; | (x5 == as) &amp;&amp; ((len x5) &gt; 0) &amp;&amp; ((len x5) &gt;= 0) &amp;&amp; ((sumLens x5) &gt;= 0)}</span><span class='hs-keyword'>as</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x4 : [a] | (x4 == bs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>bs</span></a>
+<span class=hs-linenum>315: </span><span class='hs-definition'>descending</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>as</span> <span class='hs-varid'>bs</span>      
+<span class=hs-linenum>316: </span>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (a &lt;= VV)}
+-&gt; x2:[{VV : a&lt;p x1&gt; | (a &lt;= VV)}]&lt;p&gt;
+-&gt; {x4 : [{VV : a | (a &lt;= VV)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{x5 : [{VV : a | (VV &gt; a)}]&lt;\x6 VV -&gt; (VV &gt; a) &amp;&amp; (VV &gt; x6)&gt; | (x5 == as) &amp;&amp; ((len x5) &gt; 0) &amp;&amp; ((len x5) &gt;= 0) &amp;&amp; ((sumLens x5) &gt;= 0)}</span><span class='hs-keyword'>as</span></a><span class='hs-layout'>)</span><a class=annot href="#"><span class=annottext>forall &lt;p :: [a]-&gt; [a]-&gt; Bool&gt;.
+x1:{x15 : [a]&lt;\x16 VV -&gt; (x16 &lt;= VV)&gt; | ((len x15) &gt;= 0)}
+-&gt; x2:[{x15 : [a]&lt;\x16 VV -&gt; (x16 &lt;= VV)&gt;&lt;p x1&gt; | ((len x15) &gt;= 0)}]&lt;p&gt;
+-&gt; {x4 : [{x15 : [a]&lt;\x16 VV -&gt; (x16 &lt;= VV)&gt; | ((len x15) &gt;= 0)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+[a]
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-varid'>sequences</span></a> <a class=annot href="#"><span class=annottext>{x3 : [a] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-varid'>bs</span></a>
+</pre>
+
+Ex: `Data.List.sort` [3/4]
+--------------------------
+
+Juggling lists of increasing & decreasing lists
+
+<br>
+
+
+
+<pre><span class=hs-linenum>328: </span><a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+a:a
+-&gt; (x1:{VV : [{VV : a | (VV &gt;= a)}]&lt;\x3 VV -&gt; (a &lt;= VV) &amp;&amp; (x3 &lt;= VV)&gt; | ((len VV) &gt; 0)}
+    -&gt; {VV : [a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt; | (VV /= x1) &amp;&amp; ((len VV) &gt; 0) &amp;&amp; ((len VV) &gt; (len x1))})
+-&gt; {VV : [a] | ((len VV) &gt;= 0)}
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-definition'>ascending</span></a> <a class=annot href="#"><span class=annottext>a</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:{VV : [{VV : a | (VV &gt;= a)}]&lt;\x2 VV -&gt; (a &lt;= VV) &amp;&amp; (x2 &lt;= VV)&gt; | ((len VV) &gt; 0)}
+-&gt; {VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | (VV /= x1) &amp;&amp; ((len VV) &gt; 0) &amp;&amp; ((len VV) &gt; (len x1))}</span><span class='hs-keyword'>as</span></a> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>bs</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>329: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:a
+-&gt; x2:a
+-&gt; {x4 : (Ordering) | ((x4 == GHC.Types.EQ) &lt;=&gt; (x1 == x2)) &amp;&amp; ((x4 == GHC.Types.GT) &lt;=&gt; (x1 &gt; x2)) &amp;&amp; ((x4 == GHC.Types.LT) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>`compare`</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == b)}</span><span class='hs-varid'>b</span></a> <a class=annot href="#"><span class=annottext>x1:(Ordering)
+-&gt; x2:(Ordering) -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 /= x2))}</span><span class='hs-varop'>/=</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Ordering) | (x3 == GHC.Types.GT) &amp;&amp; ((cmp x3) == GHC.Types.GT)}</span><span class='hs-conid'>GT</span></a> 
+<span class=hs-linenum>330: </span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+a:a
+-&gt; (x1:{VV : [{VV : a | (VV &gt;= a)}]&lt;\x3 VV -&gt; (a &lt;= VV) &amp;&amp; (x3 &lt;= VV)&gt; | ((len VV) &gt; 0)}
+    -&gt; {VV : [a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt; | (VV /= x1) &amp;&amp; ((len VV) &gt; 0) &amp;&amp; ((len VV) &gt; (len x1))})
+-&gt; {VV : [a] | ((len VV) &gt;= 0)}
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-varid'>ascending</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == b)}</span><span class='hs-varid'>b</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:{x7 : [{VV : a | (VV &gt;= a) &amp;&amp; (VV &gt;= b)}]&lt;\x8 VV -&gt; (a &lt;= VV) &amp;&amp; (b &lt;= VV) &amp;&amp; (x8 &lt;= VV)&gt; | ((len x7) &gt; 0)}
+-&gt; {x4 : [a]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 /= x1) &amp;&amp; ((len x4) &gt; 0) &amp;&amp; ((len x4) &gt; (len x1))}</span><span class='hs-keyglyph'>\</span></a><a class=annot href="#"><span class=annottext>{VV : [{VV : a | (VV &gt;= a) &amp;&amp; (VV &gt;= b)}]&lt;\x1 VV -&gt; (a &lt;= VV) &amp;&amp; (b &lt;= VV) &amp;&amp; (x1 &lt;= VV)&gt; | ((len VV) &gt; 0)}</span><span class='hs-varid'>ys</span></a> <span class='hs-keyglyph'>-&gt;</span> <a class=annot href="#"><span class=annottext>x1:{x7 : [{VV : a | (VV &gt;= a)}]&lt;\x8 VV -&gt; (a &lt;= VV) &amp;&amp; (x8 &lt;= VV)&gt; | ((len x7) &gt; 0)}
+-&gt; {x4 : [a]&lt;\x5 VV -&gt; (x5 &lt;= VV)&gt; | (x4 /= x1) &amp;&amp; ((len x4) &gt; 0) &amp;&amp; ((len x4) &gt; (len x1))}</span><span class='hs-keyword'>as</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: a-&gt; a-&gt; Bool&gt;.
+x1:{VV : a | (VV &gt;= a)}
+-&gt; x2:[{VV : a&lt;p x1&gt; | (VV &gt;= a)}]&lt;p&gt;
+-&gt; {x4 : [{VV : a | (VV &gt;= a)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a><a class=annot href="#"><span class=annottext>{x5 : [{VV : a | (VV &gt;= a) &amp;&amp; (VV &gt;= b)}]&lt;\x6 VV -&gt; (a &lt;= VV) &amp;&amp; (b &lt;= VV) &amp;&amp; (x6 &lt;= VV)&gt; | (x5 == ys) &amp;&amp; ((len x5) &gt; 0) &amp;&amp; ((len x5) &gt;= 0) &amp;&amp; ((sumLens x5) &gt;= 0)}</span><span class='hs-varid'>ys</span></a><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x4 : [a] | (x4 == bs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>bs</span></a>
+<span class=hs-linenum>331: </span><span class='hs-definition'>ascending</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>as</span> <span class='hs-varid'>bs</span>      
+<span class=hs-linenum>332: </span>  <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x7 : [{VV : a | (VV &gt;= a)}]&lt;\x8 VV -&gt; (a &lt;= VV) &amp;&amp; (x8 &lt;= VV)&gt; | ((len x7) &gt; 0)}
+-&gt; {x4 : [a]&lt;\x5 VV -&gt; (x5 &lt;= VV)&gt; | (x4 /= x1) &amp;&amp; ((len x4) &gt; 0) &amp;&amp; ((len x4) &gt; (len x1))}</span><span class='hs-keyword'>as</span></a> <a class=annot href="#"><span class=annottext>{x4 : [{VV : a | (VV == a) &amp;&amp; (VV &gt; b)}]&lt;\_ VV -&gt; false&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{VV : a | (VV == a)}</span><span class='hs-varid'>a</span></a><span class='hs-keyglyph'>]</span><a class=annot href="#"><span class=annottext>forall &lt;p :: [a]-&gt; [a]-&gt; Bool&gt;.
+x1:{x15 : [a]&lt;\x16 VV -&gt; (x16 &lt;= VV)&gt; | ((len x15) &gt;= 0)}
+-&gt; x2:[{x15 : [a]&lt;\x16 VV -&gt; (x16 &lt;= VV)&gt;&lt;p x1&gt; | ((len x15) &gt;= 0)}]&lt;p&gt;
+-&gt; {x4 : [{x15 : [a]&lt;\x16 VV -&gt; (x16 &lt;= VV)&gt; | ((len x15) &gt;= 0)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+[a]
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt; 0)}</span><span class='hs-varid'>sequences</span></a> <a class=annot href="#"><span class=annottext>{x3 : [a] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-varid'>bs</span></a>
+</pre>
+
+Ex: `Data.List.sort` [4/4]
+--------------------------
+
+Juggling lists of increasing & decreasing lists
+
+<br>
+
+
+<pre><span class=hs-linenum>343: </span><a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+{VV : [{VV : [a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt;= 0)}
+-&gt; {VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}</span><span class='hs-definition'>mergeAll</span></a> <span class='hs-keyglyph'>[</span><span class='hs-varid'>x</span><span class='hs-keyglyph'>]</span>        <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x4 : [a]&lt;\x5 VV -&gt; (x5 &lt;= VV)&gt; | (x4 == x) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>x</span></a>
+<span class=hs-linenum>344: </span><span class='hs-definition'>mergeAll</span> <span class='hs-varid'>xs</span>         <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+{VV : [{VV : [a]&lt;\x2 VV -&gt; (x2 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt;= 0)}
+-&gt; {VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}</span><span class='hs-varid'>mergeAll</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:{x10 : [{x14 : [a]&lt;\x15 VV -&gt; (VV &gt;= x15)&gt; | ((len x14) &gt;= 0)}]&lt;\_ VV -&gt; ((len x12) &gt;= 0)&gt; | ((len x10) &gt;= 0)}
+-&gt; {x3 : [{x7 : [a]&lt;\x8 VV -&gt; (VV &gt;= x8)&gt; | ((len x7) &gt;= 0)}]&lt;\_ VV -&gt; ((len x5) &gt;= 0)&gt; | ((len x3) &gt;= 0) &amp;&amp; ((len x3) &lt;= (len x1))}</span><span class='hs-varid'>mergePairs</span></a> <a class=annot href="#"><span class=annottext>{x3 : [{x7 : [a]&lt;\x8 VV -&gt; (x8 &lt;= VV)&gt; | ((len x7) &gt;= 0)}]&lt;\_ VV -&gt; ((len x5) &gt;= 0)&gt; | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>)</span>
+<span class=hs-linenum>345: </span>
+<span class=hs-linenum>346: </span><a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+x1:{VV : [{VV : [a]&lt;\x2 VV -&gt; (VV &gt;= x2)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt;= 0)}
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len x1))}</span><span class='hs-definition'>mergePairs</span></a> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-conop'>:</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x10 : [a]&lt;\x11 VV -&gt; (VV &gt;= x11)&gt; | ((len x10) &gt;= 0)}
+-&gt; x2:{x7 : [a]&lt;\x8 VV -&gt; (VV &gt;= x8)&gt; | ((len x7) &gt;= 0)}
+-&gt; {x4 : [a]&lt;\x5 VV -&gt; (x5 &lt;= VV)&gt; | ((len x4) &gt;= 0) &amp;&amp; ((len x4) &gt;= (len x1)) &amp;&amp; ((len x4) &gt;= (len x2))}</span><span class='hs-varid'>merge</span></a> <a class=annot href="#"><span class=annottext>{x4 : [a]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 == a) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>{x4 : [a]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 == b) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>b</span></a><a class=annot href="#"><span class=annottext>forall &lt;p :: [a]-&gt; [a]-&gt; Bool&gt;.
+x1:{x15 : [a]&lt;\x16 VV -&gt; (VV &gt;= x16)&gt; | ((len x15) &gt;= 0)}
+-&gt; x2:[{x15 : [a]&lt;\x16 VV -&gt; (VV &gt;= x16)&gt;&lt;p x1&gt; | ((len x15) &gt;= 0)}]&lt;p&gt;
+-&gt; {x4 : [{x15 : [a]&lt;\x16 VV -&gt; (VV &gt;= x16)&gt; | ((len x15) &gt;= 0)}]&lt;p&gt; | (((null x4)) &lt;=&gt; false) &amp;&amp; ((len x4) == (1 + (len x2))) &amp;&amp; ((sumLens x4) == ((len x1) + (sumLens x2)))}</span><span class='hs-conop'>:</span></a> <a class=annot href="#"><span class=annottext>forall a.
+(Ord a) =&gt;
+x1:{VV : [{VV : [a]&lt;\x2 VV -&gt; (VV &gt;= x2)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt;= 0)}
+-&gt; {VV : [{VV : [a]&lt;\x1 VV -&gt; (x1 &lt;= VV)&gt; | ((len VV) &gt;= 0)}]&lt;\_ VV -&gt; ((len VV) &gt;= 0)&gt; | ((len VV) &gt;= 0) &amp;&amp; ((len VV) &lt;= (len x1))}</span><span class='hs-varid'>mergePairs</span></a> <a class=annot href="#"><span class=annottext>{x4 : [{x8 : [a]&lt;\x9 VV -&gt; (VV &gt;= x9)&gt; | ((len x8) &gt;= 0)}]&lt;\_ VV -&gt; ((len x6) &gt;= 0)&gt; | (x4 == xs) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>xs</span></a>
+<span class=hs-linenum>347: </span><span class='hs-definition'>mergePairs</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>x</span><span class='hs-keyglyph'>]</span>      <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x6 : [{x8 : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | false}]&lt;\_ VV -&gt; false&gt; | (((null x6)) &lt;=&gt; true) &amp;&amp; ((len x6) == 0) &amp;&amp; ((sumLens x6) == 0) &amp;&amp; ((len x6) &gt;= 0) &amp;&amp; ((sumLens x6) &gt;= 0)}</span><span class='hs-keyglyph'>[</span></a><a class=annot href="#"><span class=annottext>{x4 : [a]&lt;\x5 VV -&gt; (VV &gt;= x5)&gt; | (x4 == a) &amp;&amp; ((len x4) &gt;= 0) &amp;&amp; ((sumLens x4) &gt;= 0)}</span><span class='hs-varid'>x</span></a><span class='hs-keyglyph'>]</span>
+<span class=hs-linenum>348: </span><span class='hs-definition'>mergePairs</span> <span class='hs-conid'>[]</span>       <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall &lt;p :: [a]-&gt; [a]-&gt; Bool&gt;.
+{x4 : [{x6 : [{VV : a | false}]&lt;\_ VV -&gt; false&gt; | false}]&lt;p&gt; | (((null x4)) &lt;=&gt; true) &amp;&amp; ((len x4) == 0) &amp;&amp; ((sumLens x4) == 0)}</span><span class='hs-conid'>[]</span></a>
+</pre>
+
+Phew!
+-----
+
+Lets see one last example...
+
+
+Example: Binary Trees
+---------------------
+
+... `Map` from keys of type `k` to values of type `a` 
+
+<br>
+
+<div class="fragment">
+
+Implemented, in `Data.Map` as a binary tree:
+
+<br>
+
+
+<pre><span class=hs-linenum>371: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>Map</span> <span class='hs-varid'>k</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Tip</span>
+<span class=hs-linenum>372: </span>             <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Bin</span> <span class='hs-conid'>Size</span> <span class='hs-varid'>k</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-conid'>Map</span> <span class='hs-varid'>k</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Map</span> <span class='hs-varid'>k</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>373: </span>
+<span class=hs-linenum>374: </span><span class='hs-keyword'>type</span> <span class='hs-conid'>Size</span>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Int</span>
+</pre>
+</div>
+
+Two Abstract Refinements
+------------------------
+
+- `l` : relates root `key` with `left`-subtree keys
+- `r` : relates root `key` with `right`-subtree keys
+
+
+<pre><span class=hs-linenum>385: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>data</span> <span class='hs-conid'>Map</span> <span class='hs-varid'>k</span> <span class='hs-varid'>a</span> <span class='hs-varop'>&lt;</span> <span class='hs-varid'>l</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span>
+<span class=hs-linenum>386: </span>                 <span class='hs-layout'>,</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Prop</span> <span class='hs-varop'>&gt;</span>
+<span class=hs-linenum>387: </span>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Tip</span>
+<span class=hs-linenum>388: </span>    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Bin</span> <span class='hs-layout'>(</span><span class='hs-varid'>sz</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Size</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>key</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>val</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>389: </span>          <span class='hs-layout'>(</span><span class='hs-varid'>left</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Map</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span><span class='hs-varid'>r</span><span class='hs-varop'>&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>l</span> <span class='hs-varid'>key</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>)</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>390: </span>          <span class='hs-layout'>(</span><span class='hs-varid'>right</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Map</span> <span class='hs-varop'>&lt;</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span><span class='hs-varid'>r</span><span class='hs-varop'>&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span><span class='hs-varop'>&lt;</span><span class='hs-varid'>r</span> <span class='hs-varid'>key</span><span class='hs-varop'>&gt;</span><span class='hs-layout'>)</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+</pre>
+
+
+Ex: Binary Search Trees
+-----------------------
+
+Keys are *Binary-Search* Ordered
+
+<br>
+
+
+<pre><span class=hs-linenum>402: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>BST</span> <span class='hs-varid'>k</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> 
+<span class=hs-linenum>403: </span>      <span class='hs-conid'>Map</span> <span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>r</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>v</span> <span class='hs-varop'>&lt;</span> <span class='hs-varid'>r</span> <span class='hs-layout'>}</span><span class='hs-layout'>,</span> 
+<span class=hs-linenum>404: </span>           <span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>r</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>v</span> <span class='hs-varop'>&gt;</span> <span class='hs-varid'>r</span> <span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>405: </span>          <span class='hs-varid'>k</span> <span class='hs-varid'>a</span>                   <span class='hs-keyword'>@-}</span>
+</pre>
+
+Ex: Minimum Heaps 
+-----------------
+
+Root contains *minimum* value
+
+<br>
+
+
+<pre><span class=hs-linenum>416: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>MinHeap</span> <span class='hs-varid'>k</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> 
+<span class=hs-linenum>417: </span>      <span class='hs-conid'>Map</span> <span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>r</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>r</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-layout'>,</span> 
+<span class=hs-linenum>418: </span>           <span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>r</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>r</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>419: </span>           <span class='hs-varid'>k</span> <span class='hs-varid'>a</span>               <span class='hs-keyword'>@-}</span>
+</pre>
+
+Ex: Maximum Heaps 
+-----------------
+
+Root contains *maximum* value
+
+<br>
+
+
+<pre><span class=hs-linenum>430: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>type</span> <span class='hs-conid'>MaxHeap</span> <span class='hs-varid'>k</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> 
+<span class=hs-linenum>431: </span>      <span class='hs-conid'>Map</span> <span class='hs-varop'>&lt;</span><span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>r</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>r</span> <span class='hs-varop'>&gt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-layout'>,</span> 
+<span class=hs-linenum>432: </span>           <span class='hs-layout'>{</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>r</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>r</span> <span class='hs-varop'>&gt;=</span> <span class='hs-varid'>v</span><span class='hs-layout'>}</span><span class='hs-varop'>&gt;</span> 
+<span class=hs-linenum>433: </span>           <span class='hs-varid'>k</span> <span class='hs-varid'>a</span>               <span class='hs-keyword'>@-}</span>
+</pre>
+
+
+Example: Data.Map
+-----------------
+
+Standard Key-Value container
+
+- <div class="fragment">1300+ non-comment lines</div>
+
+- <div class="fragment">`insert`, `split`, `merge`,...</div>
+
+- <div class="fragment">Rotation, Rebalance,...</div>
+
+<div class="fragment">
+SMT & inference crucial for [verification](https://github.com/ucsd-progsys/liquidhaskell/blob/master/benchmarks/esop2013-submission/Base.hs)
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=Map.hs" target="_blank">Demo:</a>Try online!
+</div>
+
+Recap: Abstract Refinements
+---------------------------
+
+<div class="fragment">
+
+Decouple invariants from *functions*
+
++ `max`
++ `loop`
++ `foldr`
+
+</div>
+
+<div class="fragment">
+Decouple invariants from *data*
+
++ `Vector`
++ `List`
++ `Tree`
+
+</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract Refinements:* Decouple Invariants 
+5. <div class="fragment">Er, what of *lazy evaluation*?</div>
diff --git a/docs/slides/plpv14/lhs/09_Laziness.lhs b/docs/slides/plpv14/lhs/09_Laziness.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/09_Laziness.lhs
@@ -0,0 +1,237 @@
+ {#laziness}
+============
+
+<div class="hidden">
+\begin{code}
+module Laziness where
+import Language.Haskell.Liquid.Prelude
+
+{-@ LIQUID "--no-termination" @-}
+
+divide :: Int -> Int -> Int
+foo     :: Int -> Int
+-- zero    :: Int 
+-- diverge :: a -> b
+\end{code}
+</div>
+
+
+Lazy Evaluation?
+----------------
+
+Lazy Evaluation
+===============
+
+SMT based Verification
+----------------------
+
+Techniques developed for *strict* languages
+
+<br>
+
+<div class="fragment">
+
+-----------------------   ---   ------------------------------------------
+        **Floyd-Hoare**    :    `ESCJava`, `SpecSharp` ...
+     **Model Checkers**    :    `Slam`, `Blast` ...
+   **Refinement Types**    :    `DML`, `Stardust`, `F7`, `F*`, `Sage` ...
+-----------------------   ---   ------------------------------------------
+
+</div>
+
+<br>
+
+<div class="fragment">
+Surely soundness carries over to Haskell, right?
+</div>
+
+
+Back To the Beginning
+---------------------
+
+\begin{code}
+{-@ divide :: Int -> {v:Int| v /= 0} -> Int @-}
+divide n 0 = liquidError "div-by-zero!"
+divide n d = n `div` d
+\end{code}
+
+<br>
+
+<div class="fragment">
+Should only try to `divide` by non-zero values
+</div>
+
+An Innocent Function
+--------------------
+
+`foo` returns a value *strictly less than* input.
+
+<br>
+
+\begin{code}
+{-@ foo       :: n:Nat -> {v:Nat | v < n} @-}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+\end{code}
+
+LiquidHaskell Lies! 
+-------------------
+
+\begin{code}
+explode = let z = 0
+          in  (\x -> (2013 `divide` z)) (foo z)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Why is this deemed *safe*? 
+</div>
+
+<br>
+
+<div class="fragment">
+(Where's the *red* highlight when you want it?)
+</div>
+
+
+Safe With Eager Eval
+--------------------
+
+\begin{code} <div/>
+{- foo       :: n:Nat -> {v:Nat | v < n} -}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0
+          in  (\x -> (2013 `divide` z)) (foo z)
+\end{code}
+
+<br>
+
+<div class="fragment">
+In Java, ML, etc: program spins away, *never hits* divide-by-zero 
+</div>
+
+Unsafe With Lazy Eval
+---------------------
+
+\begin{code}<div/>
+{- foo       :: n:Nat -> {v:Nat | v < n} -}
+foo n   
+  | n > 0     = n - 1
+  | otherwise = foo n
+
+explode = let z = 0
+          in  (\x -> (2013 `divide` z)) (foo z)
+\end{code}
+
+<br>
+
+In Haskell, program *skips* `(foo z)` & hits divide-by-zero!
+
+Problem: Divergence
+-------------------
+
+<div class="fragment">
+What is denoted by `e :: {v:Int | 0 <= v}` ?
+</div>
+
+<br>
+
+<div class="fragment">
+`e` evaluates to a `Nat`  
+</div>
+
+<div class="fragment">
+or
+
+**diverges**! 
+</div>
+
+<div class="fragment">
+<br>
+
+Classical Floyd-Hoare notion of [partial correctness](http://en.wikipedia.org/wiki/Hoare_logic#Partial_and_total_correctness)
+
+</div>
+
+
+
+Problem: Divergence
+-------------------
+
+Suppose `e :: {v:Int | 0 <= v}`
+
+<br>
+
+**Consider**
+
+`let x = e in body`
+
+With Eager Evaluation 
+---------------------
+
+Suppose `e :: {v:Int | 0 <= v}`
+
+<br>
+
+**Consider**
+
+`let x = e in body`
+
+<br>
+
+<div class="fragment">
+**Can** assume `x` is a `Nat` when checking `body`
+</div>
+
+But With Lazy Evaluation 
+------------------------
+
+Suppose `e :: {v:Int | 0 <= v}`
+
+<br>
+
+**Consider**
+
+`let x = e in body`
+
+<br>
+
+<div class="fragment">
+**Cannot** assume `x` is a `Nat` when checking e!
+</div>
+
+Oops. Now what?
+---------------
+
+**Solution** 
+
+Only assign *non-trivial* refinements to *non-diverging* terms!
+
+<br>
+
+<div class="fragment">
+
+**Require A Termination Analysis**
+
+(Oh dear.)
+
+</div>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=TellingLies.hs" target="_blank">Demo:</a>Disable `"--no-termination" and see what happens!
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract Refinements:* Decouple Invariants 
+5. **Lazy Evaluation:** Requires Termination
+6. <div class="fragment">**Termination:** Via Refinements!</div>
+
diff --git a/docs/slides/plpv14/lhs/09_Laziness.lhs.markdown b/docs/slides/plpv14/lhs/09_Laziness.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/09_Laziness.lhs.markdown
@@ -0,0 +1,244 @@
+ {#laziness}
+============
+
+<div class="hidden">
+
+<pre><span class=hs-linenum>6: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>Laziness</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum>7: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>Liquid</span><span class='hs-varop'>.</span><span class='hs-conid'>Prelude</span>
+<span class=hs-linenum>8: </span>
+<span class=hs-linenum>9: </span><span class='hs-keyword'>{-@</span> <span class='hs-conid'>LIQUID</span> <span class='hs-str'>"--no-termination"</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>10: </span>
+<span class=hs-linenum>11: </span><span class='hs-definition'>divide</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>12: </span><span class='hs-definition'>foo</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>13: </span><span class='hs-comment'>-- zero    :: Int </span>
+<span class=hs-linenum>14: </span><span class='hs-comment'>-- diverge :: a -&gt; b</span>
+</pre>
+</div>
+
+
+Lazy Evaluation?
+----------------
+
+Lazy Evaluation
+===============
+
+SMT based Verification
+----------------------
+
+Techniques developed for *strict* languages
+
+<br>
+
+<div class="fragment">
+
+-----------------------   ---   ------------------------------------------
+        **Floyd-Hoare**    :    `ESCJava`, `SpecSharp` ...
+     **Model Checkers**    :    `Slam`, `Blast` ...
+   **Refinement Types**    :    `DML`, `Stardust`, `F7`, `F*`, `Sage` ...
+-----------------------   ---   ------------------------------------------
+
+</div>
+
+<br>
+
+<div class="fragment">
+Surely soundness carries over to Haskell, right?
+</div>
+
+
+Back To the Beginning
+---------------------
+
+
+<pre><span class=hs-linenum>53: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>divide</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Int</span><span class='hs-keyword'>| v /= 0}</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>54: </span><a class=annot href="#"><span class=annottext>(Int) -&gt; {VV : (Int) | (VV /= 0)} -&gt; (Int)</span><span class='hs-definition'>divide</span></a> <a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-varid'>n</span></a> <span class='hs-num'>0</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : [(Char)] | false} -&gt; {x1 : (Int) | false}</span><span class='hs-varid'>liquidError</span></a> <a class=annot href="#"><span class=annottext>{x3 : [(Char)] | ((len x3) &gt;= 0) &amp;&amp; ((sumLens x3) &gt;= 0)}</span><span class='hs-str'>"div-by-zero!"</span></a>
+<span class=hs-linenum>55: </span><span class='hs-definition'>divide</span> <span class='hs-varid'>n</span> <span class='hs-varid'>d</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == n)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>x1:(Int)
+-&gt; x2:(Int)
+-&gt; {x6 : (Int) | (((x1 &gt;= 0) &amp;&amp; (x2 &gt;= 0)) =&gt; (x6 &gt;= 0)) &amp;&amp; (((x1 &gt;= 0) &amp;&amp; (x2 &gt;= 1)) =&gt; (x6 &lt;= x1)) &amp;&amp; (x6 == (x1 / x2))}</span><span class='hs-varop'>`div`</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 /= 0)}</span><span class='hs-varid'>d</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">
+Should only try to `divide` by non-zero values
+</div>
+
+An Innocent Function
+--------------------
+
+`foo` returns a value *strictly less than* input.
+
+<br>
+
+
+<pre><span class=hs-linenum>72: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>foo</span>       <span class='hs-keyglyph'>::</span> <span class='hs-varid'>n</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span> <span class='hs-keyword'>| v &lt; n}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>73: </span><a class=annot href="#"><span class=annottext>n:{VV : (Int) | (VV &gt;= 0)} -&gt; {VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; n)}</span><span class='hs-definition'>foo</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>n</span></a>   
+<span class=hs-linenum>74: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>x1:{x8 : (Int) | (x8 &gt;= 0) &amp;&amp; (x8 &lt;= n)}
+-&gt; x2:{x8 : (Int) | (x8 &gt;= 0) &amp;&amp; (x8 &lt;= n)}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &gt; x2))}</span><span class='hs-varop'>&gt;</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>n</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a>
+<span class=hs-linenum>75: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{x5 : (Int) | (x5 &gt;= 0)}
+-&gt; {x3 : (Int) | (x3 &gt;= 0) &amp;&amp; (x3 &lt; x1)}</span><span class='hs-varid'>foo</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == n) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>n</span></a>
+</pre>
+
+LiquidHaskell Lies! 
+-------------------
+
+
+<pre><span class=hs-linenum>82: </span><a class=annot href="#"><span class=annottext>(Int)</span><span class='hs-definition'>explode</span></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-varid'>z</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (0  :  int))}</span><span class='hs-num'>0</span></a>
+<span class=hs-linenum>83: </span>          <span class='hs-keyword'>in</span>  <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x:{VV : (Int) | (VV == 0) &amp;&amp; (VV == 1) &amp;&amp; (VV == Laziness.explode) &amp;&amp; (VV == z) &amp;&amp; (VV &gt; 0) &amp;&amp; (VV &gt; Laziness.explode) &amp;&amp; (VV &gt; z) &amp;&amp; (VV &lt; 0) &amp;&amp; (VV &lt; Laziness.explode) &amp;&amp; (VV &lt; z)}
+-&gt; {VV : (Int) | (VV == 0) &amp;&amp; (VV == 1) &amp;&amp; (VV == Laziness.explode) &amp;&amp; (VV == x) &amp;&amp; (VV == z) &amp;&amp; (VV &gt; 0) &amp;&amp; (VV &gt; Laziness.explode) &amp;&amp; (VV &gt; x) &amp;&amp; (VV &gt; z) &amp;&amp; (VV &lt; 0) &amp;&amp; (VV &lt; Laziness.explode) &amp;&amp; (VV &lt; x) &amp;&amp; (VV &lt; z)}</span><span class='hs-keyglyph'>\</span></a><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV == 0) &amp;&amp; (VV == 1) &amp;&amp; (VV == Laziness.explode) &amp;&amp; (VV == z) &amp;&amp; (VV &gt; 0) &amp;&amp; (VV &gt; Laziness.explode) &amp;&amp; (VV &gt; z) &amp;&amp; (VV &lt; 0) &amp;&amp; (VV &lt; Laziness.explode) &amp;&amp; (VV &lt; z)}</span><span class='hs-varid'>x</span></a> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2013  :  int))}</span><span class='hs-num'>2013</span></a> <a class=annot href="#"><span class=annottext>(Int) -&gt; {x3 : (Int) | (x3 /= 0)} -&gt; (Int)</span><span class='hs-varop'>`divide`</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == z) &amp;&amp; (x3 == (0  :  int))}</span><span class='hs-varid'>z</span></a><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>x1:{x5 : (Int) | (x5 &gt;= 0)}
+-&gt; {x3 : (Int) | (x3 &gt;= 0) &amp;&amp; (x3 &lt; x1)}</span><span class='hs-varid'>foo</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == z) &amp;&amp; (x3 == (0  :  int))}</span><span class='hs-varid'>z</span></a><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+Why is this deemed *safe*? 
+</div>
+
+<br>
+
+<div class="fragment">
+(Where's the *red* highlight when you want it?)
+</div>
+
+
+Safe With Eager Eval
+--------------------
+
+ <div/>
+<pre><span class=hs-linenum>103: </span><span class='hs-comment'>{- foo       :: n:Nat -&gt; {v:Nat | v &lt; n} -}</span>
+<span class=hs-linenum>104: </span><span class='hs-definition'>foo</span> <span class='hs-varid'>n</span>   
+<span class=hs-linenum>105: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&gt;</span> <span class='hs-num'>0</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>n</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span>
+<span class=hs-linenum>106: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foo</span> <span class='hs-varid'>n</span>
+<span class=hs-linenum>107: </span>
+<span class=hs-linenum>108: </span><span class='hs-definition'>explode</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>z</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span>
+<span class=hs-linenum>109: </span>          <span class='hs-keyword'>in</span>  <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-num'>2013</span> <span class='hs-varop'>`divide`</span> <span class='hs-varid'>z</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>foo</span> <span class='hs-varid'>z</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+In Java, ML, etc: program spins away, *never hits* divide-by-zero 
+</div>
+
+Unsafe With Lazy Eval
+---------------------
+
+<div/>
+<pre><span class=hs-linenum>122: </span><span class='hs-comment'>{- foo       :: n:Nat -&gt; {v:Nat | v &lt; n} -}</span>
+<span class=hs-linenum>123: </span><span class='hs-definition'>foo</span> <span class='hs-varid'>n</span>   
+<span class=hs-linenum>124: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&gt;</span> <span class='hs-num'>0</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>n</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span>
+<span class=hs-linenum>125: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foo</span> <span class='hs-varid'>n</span>
+<span class=hs-linenum>126: </span>
+<span class=hs-linenum>127: </span><span class='hs-definition'>explode</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>z</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span>
+<span class=hs-linenum>128: </span>          <span class='hs-keyword'>in</span>  <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-num'>2013</span> <span class='hs-varop'>`divide`</span> <span class='hs-varid'>z</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>foo</span> <span class='hs-varid'>z</span><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+In Haskell, program *skips* `(foo z)` & hits divide-by-zero!
+
+Problem: Divergence
+-------------------
+
+<div class="fragment">
+What is denoted by `e :: {v:Int | 0 <= v}` ?
+</div>
+
+<br>
+
+<div class="fragment">
+`e` evaluates to a `Nat`  
+</div>
+
+<div class="fragment">
+or
+
+**diverges**! 
+</div>
+
+<div class="fragment">
+<br>
+
+Classical Floyd-Hoare notion of [partial correctness](http://en.wikipedia.org/wiki/Hoare_logic#Partial_and_total_correctness)
+
+</div>
+
+
+
+Problem: Divergence
+-------------------
+
+Suppose `e :: {v:Int | 0 <= v}`
+
+<br>
+
+**Consider**
+
+`let x = e in body`
+
+With Eager Evaluation 
+---------------------
+
+Suppose `e :: {v:Int | 0 <= v}`
+
+<br>
+
+**Consider**
+
+`let x = e in body`
+
+<br>
+
+<div class="fragment">
+**Can** assume `x` is a `Nat` when checking `body`
+</div>
+
+But With Lazy Evaluation 
+------------------------
+
+Suppose `e :: {v:Int | 0 <= v}`
+
+<br>
+
+**Consider**
+
+`let x = e in body`
+
+<br>
+
+<div class="fragment">
+**Cannot** assume `x` is a `Nat` when checking e!
+</div>
+
+Oops. Now what?
+---------------
+
+**Solution** 
+
+Only assign *non-trivial* refinements to *non-diverging* terms!
+
+<br>
+
+<div class="fragment">
+
+**Require A Termination Analysis**
+
+(Oh dear.)
+
+</div>
+
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=TellingLies.hs" target="_blank">Demo:</a>Disable `"--no-termination" and see what happens!
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract Refinements:* Decouple Invariants 
+5. **Lazy Evaluation:** Requires Termination
+6. <div class="fragment">**Termination:** Via Refinements!</div>
+
diff --git a/docs/slides/plpv14/lhs/10_Termination.lhs b/docs/slides/plpv14/lhs/10_Termination.lhs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/10_Termination.lhs
@@ -0,0 +1,291 @@
+Termination {#termination}
+==========================
+
+
+<div class="hidden">
+\begin{code}
+module Termination where
+
+import Prelude hiding (gcd, mod, map)
+fib :: Int -> Int
+gcd :: Int -> Int -> Int
+infixr `C`
+
+data L a = N | C a (L a)
+
+{-@ invariant {v: (L a) | 0 <= (llen v)} @-}
+
+mod :: Int -> Int -> Int
+mod a b | a - b >  b = mod (a - b) b
+        | a - b <  b = a - b
+        | a - b == b = 0
+
+merge :: Ord a => L a -> L a -> L a
+\end{code}
+</div>
+
+Dependent != Refinement
+-----------------------
+
+<div class="fragment">**Dependent Types**</div>
+
++ <div class="fragment">*Arbitrary terms* appear inside types</div> 
++ <div class="fragment">Termination ensures well-defined</div>
+
+<br>
+
+<div class="fragment">**Refinement Types**</div>
+
++ <div class="fragment">*Restricted refinements* appear in types</div>
++ <div class="fragment">Termination *not* required ...</div> 
++ <div class="fragment">... except, alas, with *lazy* evaluation!</div>
+
+Refinements & Termination
+----------------------------
+
+<div class="fragment">
+Fortunately, we can ensure termination *using refinements*
+</div>
+
+
+Main Idea
+---------
+
+Recursive calls must be on *smaller* inputs
+
+<br>
+
++ [Turing](http://classes.soe.ucsc.edu/cmps210/Winter11/Papers/turing-1936.pdf)
++ [Sized Types](http://dl.acm.org/citation.cfm?id=240882)
+
+Recur On *Smaller* `Nat` 
+------------------------
+
+<div class="fragment">
+
+**To ensure termination of**
+
+\begin{code} <div/>
+foo   :: Nat -> T
+foo x =  body
+\end{code}
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:Nat | v < x} -> T`
+
+<br>
+
+*i.e.* require recursive calls have inputs *smaller* than `x`
+</div>
+
+
+
+Ex: Recur On *Smaller* `Nat` 
+----------------------------
+
+\begin{code}
+{-@ fib  :: Nat -> Nat @-}
+fib 0    = 1
+fib 1    = 1
+fib n    = fib (n-1) + fib (n-2)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Terminates, as both `n-1` and `n-2` are `< n`
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=GCD.hs" target="_blank">Demo:</a>What if we drop the `fib 1` case?
+</div>
+
+Refinements Are Essential!
+--------------------------
+
+\begin{code}
+{-@ gcd :: a:Nat -> {b:Nat | b < a} -> Int @-}
+gcd a 0 = a
+gcd a b = gcd b (a `mod` b)
+\end{code}
+
+<br>
+
+<div class="fragment">
+Need refinements to prove `(a mod b) < b` at *recursive* call!
+</div>
+
+<br>
+
+<div class="fragment">
+\begin{code}
+{-@ mod :: a:Nat 
+        -> b:{v:Nat|(0 < v && v < a)} 
+        -> {v:Nat| v < b}                 @-}
+\end{code}
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{code}<div/>
+foo   :: S -> T
+foo x = body
+\end{code}
+
+<br>
+
+<div class="fragment">
+**Reduce** to `Nat` case...
+</div>
+
+<br>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+\begin{code}<div/>
+foo   :: S -> T
+foo x = body
+\end{code}
+
+<br>
+
+Specify a **default measure** `mS :: S -> Int`
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:s | 0 <= (mS v) < (mS x)} -> T`
+</div>
+
+
+Ex: Recur on *smaller* `List`
+-----------------------------
+
+\begin{code} 
+map f N        = N
+map f (C x xs) = (f x) `C` (map f xs) 
+\end{code}
+
+<br>
+
+Terminates using **default** measure `llen`
+
+<div class="fragment">
+\begin{code}
+{-@ data L [llen] a = N 
+                    | C (x::a) (xs :: L a) @-}
+{-@ measure llen :: L a -> Int
+    llen (N)      = 0
+    llen (C x xs) = 1 + (llen xs)   @-}
+\end{code}
+</div>
+
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of *smallness* spread across inputs?
+
+<br>
+
+\begin{code}
+merge xs@(x `C` xs') ys@(y `C` ys')
+  | x < y     = x `C` merge xs' ys
+  | otherwise = y `C` merge xs ys'
+\end{code}
+
+<br>
+
+<div class="fragment">
+Neither input decreases, but their *sum* does.
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+Neither input decreases, but their *sum* does.
+
+<br>
+
+\begin{code}
+{-@ merge :: Ord a => xs:_ -> ys:_ -> _ 
+          /  [(llen xs) + (llen ys)]     @-}
+\end{code}
+
+<br>
+
+<div class="fragment">
+
+Synthesize *ghost* parameter equal to `[...]`
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+Reduces to single-parameter-decrease case. 
+
+</div>
+
+Important Extensions 
+--------------------
+
+- <div class="fragment">Mutual recursion</div>
+
+- <div class="fragment">Lexicographic ordering...</div>
+
+Recap
+-----
+
+Main idea: Recursive calls on *smaller inputs*
+
+<br>
+
+- <div class="fragment">Use refinements to *check* smaller</div>
+
+- <div class="fragment">Use refinements to *establish* smaller</div>
+
+
+A Curious Circularity
+---------------------
+
+<div class="fragment">Refinements require termination ...</div> 
+
+<br>
+
+<div class="fragment">... Termination requires refinements!</div>
+
+<br>
+
+<div class="fragment"> (Meta-theory is tricky, but all ends well.)</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract Refinements:* Decouple Invariants 
+5. **Lazy Evaluation:** Requires Termination
+6. **Termination:** Via Refinements!
+7. <div class="fragment">**Evaluation** </div>
+
+
diff --git a/docs/slides/plpv14/lhs/10_Termination.lhs.markdown b/docs/slides/plpv14/lhs/10_Termination.lhs.markdown
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/10_Termination.lhs.markdown
@@ -0,0 +1,305 @@
+Termination {#termination}
+==========================
+
+
+<div class="hidden">
+
+<pre><span class=hs-linenum> 7: </span><span class='hs-keyword'>module</span> <span class='hs-conid'>Termination</span> <span class='hs-keyword'>where</span>
+<span class=hs-linenum> 8: </span>
+<span class=hs-linenum> 9: </span><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>gcd</span><span class='hs-layout'>,</span> <span class='hs-varid'>mod</span><span class='hs-layout'>,</span> <span class='hs-varid'>map</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>10: </span><span class='hs-definition'>fib</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>11: </span><span class='hs-definition'>gcd</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>12: </span><span class='hs-keyword'>infixr</span> <span class='hs-varop'>`C`</span>
+<span class=hs-linenum>13: </span>
+<span class=hs-linenum>14: </span><span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>15: </span>
+<span class=hs-linenum>16: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>invariant</span> <span class='hs-keyword'>{v:</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>| 0 &lt;= (llen v)}</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>17: </span>
+<span class=hs-linenum>18: </span><span class='hs-definition'>mod</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>19: </span><a class=annot href="#"><span class=annottext>x1:{VV : (Int) | (VV &gt;= 0)}
+-&gt; x2:{VV : (Int) | (VV &gt;= 0) &amp;&amp; (0 &lt; VV) &amp;&amp; (VV &lt; x1)}
+-&gt; {VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; x2)}</span><span class='hs-definition'>mod</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0) &amp;&amp; (0 &lt; VV) &amp;&amp; (VV &lt; a)}</span><span class='hs-varid'>b</span></a> <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == a) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a> <a class=annot href="#"><span class=annottext>x1:{x10 : (Int) | (x10 &gt; 0) &amp;&amp; (0 &lt; x10) &amp;&amp; (x10 &lt; a)}
+-&gt; x2:{x10 : (Int) | (x10 &gt; 0) &amp;&amp; (0 &lt; x10) &amp;&amp; (x10 &lt; a)}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &gt; x2))}</span><span class='hs-varop'>&gt;</span></a>  <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{VV : (Int) | (VV &gt;= 0)}
+-&gt; x2:{VV : (Int) | (VV &gt;= 0) &amp;&amp; (0 &lt; VV) &amp;&amp; (VV &lt; x1)}
+-&gt; {VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; x2)}</span><span class='hs-varid'>mod</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == a) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a>
+<span class=hs-linenum>20: </span>        <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == a) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a> <a class=annot href="#"><span class=annottext>x1:{x12 : (Int) | (x12 &gt; 0) &amp;&amp; (0 &lt; x12) &amp;&amp; (x12 &lt; a) &amp;&amp; (x12 &lt;= b)}
+-&gt; x2:{x12 : (Int) | (x12 &gt; 0) &amp;&amp; (0 &lt; x12) &amp;&amp; (x12 &lt; a) &amp;&amp; (x12 &lt;= b)}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>&lt;</span></a>  <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == a) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a>
+<span class=hs-linenum>21: </span>        <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == a) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a> <a class=annot href="#"><span class=annottext>x1:{x12 : (Int) | (x12 == b) &amp;&amp; (x12 &gt; 0) &amp;&amp; (0 &lt; x12) &amp;&amp; (x12 &lt; a)}
+-&gt; x2:{x12 : (Int) | (x12 == b) &amp;&amp; (x12 &gt; 0) &amp;&amp; (0 &lt; x12) &amp;&amp; (x12 &lt; a)}
+-&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 == x2))}</span><span class='hs-varop'>==</span></a> <a class=annot href="#"><span class=annottext>{x5 : (Int) | (x5 == b) &amp;&amp; (x5 &gt;= 0) &amp;&amp; (0 &lt; x5) &amp;&amp; (x5 &lt; a)}</span><span class='hs-varid'>b</span></a> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:(Int#) -&gt; {x2 : (Int) | (x2 == (x1  :  int))}</span><span class='hs-num'>0</span></a>
+<span class=hs-linenum>22: </span>
+<span class=hs-linenum>23: </span><span class='hs-definition'>merge</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span>
+</pre>
+</div>
+
+Dependent != Refinement
+-----------------------
+
+<div class="fragment">**Dependent Types**</div>
+
++ <div class="fragment">*Arbitrary terms* appear inside types</div> 
++ <div class="fragment">Termination ensures well-defined</div>
+
+<br>
+
+<div class="fragment">**Refinement Types**</div>
+
++ <div class="fragment">*Restricted refinements* appear in types</div>
++ <div class="fragment">Termination *not* required ...</div> 
++ <div class="fragment">... except, alas, with *lazy* evaluation!</div>
+
+Refinements & Termination
+----------------------------
+
+<div class="fragment">
+Fortunately, we can ensure termination *using refinements*
+</div>
+
+
+Main Idea
+---------
+
+Recursive calls must be on *smaller* inputs
+
+<br>
+
++ [Turing](http://classes.soe.ucsc.edu/cmps210/Winter11/Papers/turing-1936.pdf)
++ [Sized Types](http://dl.acm.org/citation.cfm?id=240882)
+
+Recur On *Smaller* `Nat` 
+------------------------
+
+<div class="fragment">
+
+**To ensure termination of**
+
+ <div/>
+<pre><span class=hs-linenum>69: </span><span class='hs-definition'>foo</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>T</span>
+<span class=hs-linenum>70: </span><span class='hs-definition'>foo</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span>  <span class='hs-varid'>body</span>
+</pre>
+
+</div>
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:Nat | v < x} -> T`
+
+<br>
+
+*i.e.* require recursive calls have inputs *smaller* than `x`
+</div>
+
+
+
+Ex: Recur On *Smaller* `Nat` 
+----------------------------
+
+
+<pre><span class=hs-linenum>93: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>fib</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nat</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>94: </span><a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)} -&gt; {VV : (Int) | (VV &gt;= 0)}</span><span class='hs-definition'>fib</span></a> <span class='hs-num'>0</span>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:(Int#) -&gt; {x2 : (Int) | (x2 == (x1  :  int))}</span><span class='hs-num'>1</span></a>
+<span class=hs-linenum>95: </span><span class='hs-definition'>fib</span> <span class='hs-num'>1</span>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:(Int#) -&gt; {x2 : (Int) | (x2 == (x1  :  int))}</span><span class='hs-num'>1</span></a>
+<span class=hs-linenum>96: </span><span class='hs-definition'>fib</span> <span class='hs-varid'>n</span>    <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)} -&gt; {VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>fib</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 &gt;= 0)}</span><span class='hs-varid'>n</span></a><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (1  :  int))}</span><span class='hs-num'>1</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 + x2))}</span><span class='hs-varop'>+</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)} -&gt; {VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>fib</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 &gt;= 0)}</span><span class='hs-varid'>n</span></a><a class=annot href="#"><span class=annottext>x1:(Int) -&gt; x2:(Int) -&gt; {x4 : (Int) | (x4 == (x1 - x2))}</span><span class='hs-comment'>-</span></a><a class=annot href="#"><span class=annottext>{x2 : (Int) | (x2 == (2  :  int))}</span><span class='hs-num'>2</span></a><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+Terminates, as both `n-1` and `n-2` are `< n`
+</div>
+
+<br>
+
+<div class="fragment">
+<a href="http://goto.ucsd.edu:8090/index.html#?demo=GCD.hs" target="_blank">Demo:</a>What if we drop the `fib 1` case?
+</div>
+
+Refinements Are Essential!
+--------------------------
+
+
+<pre><span class=hs-linenum>115: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>gcd</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{b:</span><span class='hs-conid'>Nat</span> <span class='hs-keyword'>| b &lt; a}</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>116: </span><a class=annot href="#"><span class=annottext>x1:{VV : (Int) | (VV &gt;= 0)}
+-&gt; {VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; x1)} -&gt; (Int)</span><span class='hs-definition'>gcd</span></a> <a class=annot href="#"><span class=annottext>{VV : (Int) | (VV &gt;= 0)}</span><span class='hs-varid'>a</span></a> <span class='hs-num'>0</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == a) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>a</span></a>
+<span class=hs-linenum>117: </span><span class='hs-definition'>gcd</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>x1:{VV : (Int) | (VV &gt;= 0)}
+-&gt; {VV : (Int) | (VV &gt;= 0) &amp;&amp; (VV &lt; x1)} -&gt; (Int)</span><span class='hs-varid'>gcd</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 &gt;= 0) &amp;&amp; (x3 &lt; a)}</span><span class='hs-varid'>b</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 == a) &amp;&amp; (x3 &gt;= 0)}</span><span class='hs-varid'>a</span></a> <a class=annot href="#"><span class=annottext>x1:{x9 : (Int) | (x9 &gt;= 0)}
+-&gt; x2:{x7 : (Int) | (x7 &gt;= 0) &amp;&amp; (0 &lt; x7) &amp;&amp; (x7 &lt; x1)}
+-&gt; {x3 : (Int) | (x3 &gt;= 0) &amp;&amp; (x3 &lt; x2)}</span><span class='hs-varop'>`mod`</span></a> <a class=annot href="#"><span class=annottext>{x3 : (Int) | (x3 &gt;= 0) &amp;&amp; (x3 &lt; a)}</span><span class='hs-varid'>b</span></a><span class='hs-layout'>)</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+Need refinements to prove `(a mod b) < b` at *recursive* call!
+</div>
+
+<br>
+
+<div class="fragment">
+
+<pre><span class=hs-linenum>130: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>mod</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span><span class='hs-conop'>:</span><span class='hs-conid'>Nat</span> 
+<span class=hs-linenum>131: </span>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span><span class='hs-keyword'>|(0 &lt; v &amp;&amp; v &lt; a)}</span> 
+<span class=hs-linenum>132: </span>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>{v:</span><span class='hs-conid'>Nat</span><span class='hs-keyword'>| v &lt; b}</span>                 <span class='hs-keyword'>@-}</span>
+</pre>
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+<div/>
+<pre><span class=hs-linenum>142: </span><span class='hs-definition'>foo</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>S</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>T</span>
+<span class=hs-linenum>143: </span><span class='hs-definition'>foo</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>body</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+**Reduce** to `Nat` case...
+</div>
+
+<br>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of input types other than `Nat` ?
+
+<div/>
+<pre><span class=hs-linenum>160: </span><span class='hs-definition'>foo</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>S</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>T</span>
+<span class=hs-linenum>161: </span><span class='hs-definition'>foo</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>body</span>
+</pre>
+
+<br>
+
+Specify a **default measure** `mS :: S -> Int`
+
+<br>
+
+<div class="fragment">
+**Check `body` Under Assumption**
+
+`foo :: {v:s | 0 <= (mS v) < (mS x)} -> T`
+</div>
+
+
+Ex: Recur on *smaller* `List`
+-----------------------------
+
+ 
+<pre><span class=hs-linenum>181: </span><a class=annot href="#"><span class=annottext>forall a b. (a -&gt; b) -&gt; (L a) -&gt; (L b)</span><span class='hs-definition'>map</span></a> <a class=annot href="#"><span class=annottext>a -&gt; b</span><span class='hs-varid'>f</span></a> <span class='hs-conid'>N</span>        <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>forall a. {x2 : (L a) | ((llen x2) == 0)}</span><span class='hs-conid'>N</span></a>
+<span class=hs-linenum>182: </span><span class='hs-definition'>map</span> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>a -&gt; b</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>a -&gt; x2:(L a) -&gt; {x2 : (L a) | ((llen x2) == (1 + (llen x2)))}</span><span class='hs-varop'>`C`</span></a> <span class='hs-layout'>(</span><a class=annot href="#"><span class=annottext>forall a b. (a -&gt; b) -&gt; (L a) -&gt; (L b)</span><span class='hs-varid'>map</span></a> <a class=annot href="#"><span class=annottext>a -&gt; b</span><span class='hs-varid'>f</span></a> <a class=annot href="#"><span class=annottext>{x3 : (L a) | (x3 == xs) &amp;&amp; (0 &lt;= (llen x3))}</span><span class='hs-varid'>xs</span></a><span class='hs-layout'>)</span> 
+</pre>
+
+<br>
+
+Terminates using **default** measure `llen`
+
+<div class="fragment">
+
+<pre><span class=hs-linenum>191: </span><span class='hs-keyword'>{-@</span> <span class='hs-keyword'>data</span> <span class='hs-conid'>L</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>llen</span><span class='hs-keyglyph'>]</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>N</span> 
+<span class=hs-linenum>192: </span>                    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-keyglyph'>::</span><span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>xs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>@-}</span>
+<span class=hs-linenum>193: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>measure</span> <span class='hs-varid'>llen</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
+<span class=hs-linenum>194: </span>    <span class='hs-varid'>llen</span> <span class='hs-layout'>(</span><span class='hs-conid'>N</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span>
+<span class=hs-linenum>195: </span>    <span class='hs-varid'>llen</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span>   <span class='hs-keyword'>@-}</span>
+</pre>
+</div>
+
+
+Recur On *Smaller* Inputs
+-------------------------
+
+What of *smallness* spread across inputs?
+
+<br>
+
+
+<pre><span class=hs-linenum>208: </span><a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; (L a) -&gt; (L a) -&gt; (L a)</span><span class='hs-definition'>merge</span></a> <a class=annot href="#"><span class=annottext>(L a)</span><span class='hs-varid'>xs</span></a><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-varid'>x</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>xs'</span><span class='hs-layout'>)</span> <a class=annot href="#"><span class=annottext>(L a)</span><span class='hs-varid'>ys</span></a><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-varid'>y</span> <span class='hs-varop'>`C`</span> <span class='hs-varid'>ys'</span><span class='hs-layout'>)</span>
+<span class=hs-linenum>209: </span>  <span class='hs-keyglyph'>|</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>x1:a -&gt; x2:a -&gt; {x2 : (Bool) | (((Prop x2)) &lt;=&gt; (x1 &lt; x2))}</span><span class='hs-varop'>&lt;</span></a> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a>     <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == x)}</span><span class='hs-varid'>x</span></a> <a class=annot href="#"><span class=annottext>a -&gt; x2:(L a) -&gt; {x2 : (L a) | ((llen x2) == (1 + (llen x2)))}</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; (L a) -&gt; (L a) -&gt; (L a)</span><span class='hs-varid'>merge</span></a> <a class=annot href="#"><span class=annottext>{x3 : (L a) | (x3 == xs') &amp;&amp; (0 &lt;= (llen x3))}</span><span class='hs-varid'>xs'</span></a> <a class=annot href="#"><span class=annottext>{x5 : (L a) | (x5 == ys) &amp;&amp; (x5 == (Termination.C y ys')) &amp;&amp; ((llen x5) == (1 + (llen ys'))) &amp;&amp; (0 &lt;= (llen x5))}</span><span class='hs-varid'>ys</span></a>
+<span class=hs-linenum>210: </span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <a class=annot href="#"><span class=annottext>{VV : a | (VV == y)}</span><span class='hs-varid'>y</span></a> <a class=annot href="#"><span class=annottext>a -&gt; x2:(L a) -&gt; {x2 : (L a) | ((llen x2) == (1 + (llen x2)))}</span><span class='hs-varop'>`C`</span></a> <a class=annot href="#"><span class=annottext>forall a. (Ord a) =&gt; (L a) -&gt; (L a) -&gt; (L a)</span><span class='hs-varid'>merge</span></a> <a class=annot href="#"><span class=annottext>{x5 : (L a) | (x5 == xs) &amp;&amp; (x5 == (Termination.C x xs')) &amp;&amp; ((llen x5) == (1 + (llen xs'))) &amp;&amp; (0 &lt;= (llen x5))}</span><span class='hs-varid'>xs</span></a> <a class=annot href="#"><span class=annottext>{x3 : (L a) | (x3 == ys') &amp;&amp; (0 &lt;= (llen x3))}</span><span class='hs-varid'>ys'</span></a>
+</pre>
+
+<br>
+
+<div class="fragment">
+Neither input decreases, but their *sum* does.
+</div>
+
+Recur On *Smaller* Inputs
+-------------------------
+
+Neither input decreases, but their *sum* does.
+
+<br>
+
+
+<pre><span class=hs-linenum>227: </span><span class='hs-keyword'>{-@</span> <span class='hs-varid'>merge</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>xs</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>ys</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>_</span> 
+<span class=hs-linenum>228: </span>          <span class='hs-varop'>/</span>  <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-varop'>+</span> <span class='hs-layout'>(</span><span class='hs-varid'>llen</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>     <span class='hs-keyword'>@-}</span>
+</pre>
+
+<br>
+
+<div class="fragment">
+
+Synthesize *ghost* parameter equal to `[...]`
+
+</div>
+
+<br>
+
+<div class="fragment">
+
+Reduces to single-parameter-decrease case. 
+
+</div>
+
+Important Extensions 
+--------------------
+
+- <div class="fragment">Mutual recursion</div>
+
+- <div class="fragment">Lexicographic ordering...</div>
+
+Recap
+-----
+
+Main idea: Recursive calls on *smaller inputs*
+
+<br>
+
+- <div class="fragment">Use refinements to *check* smaller</div>
+
+- <div class="fragment">Use refinements to *establish* smaller</div>
+
+
+A Curious Circularity
+---------------------
+
+<div class="fragment">Refinements require termination ...</div> 
+
+<br>
+
+<div class="fragment">... Termination requires refinements!</div>
+
+<br>
+
+<div class="fragment"> (Meta-theory is tricky, but all ends well.)</div>
+
+
+Recap
+-----
+
+1. **Refinements:** Types + Predicates
+2. **Subtyping:** SMT Implication
+3. **Measures:** Strengthened Constructors
+4. **Abstract Refinements:* Decouple Invariants 
+5. **Lazy Evaluation:** Requires Termination
+6. **Termination:** Via Refinements!
+7. <div class="fragment">**Evaluation** </div>
+
+
diff --git a/docs/slides/plpv14/lhs/liquid.css b/docs/slides/plpv14/lhs/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/lhs/liquid.css
@@ -0,0 +1,105 @@
+.hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+  // font-weight: bold;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   /* color: #00FFFF; color: #0E84B5; */
+  //font-weight: bold;  
+}
+
+.hs-definition { 
+  color: #06287E 
+  /* font-weight: bold; */ 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  // font-size: 120%;
+  // font-family: Bitstream Vera Sans Mono,monospace;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/docs/slides/plpv14/pdcreveal.tgz b/docs/slides/plpv14/pdcreveal.tgz
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/pdcreveal.tgz differ
diff --git a/docs/slides/plpv14/reveal.js/.gitignore b/docs/slides/plpv14/reveal.js/.gitignore
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+.svn
+log/*.log
+tmp/**
+node_modules/
+.sass-cache
diff --git a/docs/slides/plpv14/reveal.js/.travis.yml b/docs/slides/plpv14/reveal.js/.travis.yml
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - 0.8
+before_script:
+  - npm install -g grunt-cli
diff --git a/docs/slides/plpv14/reveal.js/Gruntfile.js b/docs/slides/plpv14/reveal.js/Gruntfile.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/Gruntfile.js
@@ -0,0 +1,137 @@
+/* global module:false */
+module.exports = function(grunt) {
+	var port = grunt.option('port') || 8000;
+	// Project configuration
+	grunt.initConfig({
+		pkg: grunt.file.readJSON('package.json'),
+		meta: {
+			banner:
+				'/*!\n' +
+				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
+				' * http://lab.hakim.se/reveal-js\n' +
+				' * MIT licensed\n' +
+				' *\n' +
+				' * Copyright (C) 2013 Hakim El Hattab, http://hakim.se\n' +
+				' */'
+		},
+
+		qunit: {
+			files: [ 'test/*.html' ]
+		},
+
+		uglify: {
+			options: {
+				banner: '<%= meta.banner %>\n'
+			},
+			build: {
+				src: 'js/reveal.js',
+				dest: 'js/reveal.min.js'
+			}
+		},
+
+		cssmin: {
+			compress: {
+				files: {
+					'css/reveal.min.css': [ 'css/reveal.css' ]
+				}
+			}
+		},
+
+		sass: {
+			main: {
+				files: {
+					'css/theme/default.css': 'css/theme/source/default.scss',
+					'css/theme/beige.css': 'css/theme/source/beige.scss',
+					'css/theme/night.css': 'css/theme/source/night.scss',
+					'css/theme/serif.css': 'css/theme/source/serif.scss',
+					'css/theme/simple.css': 'css/theme/source/simple.scss',
+					'css/theme/sky.css': 'css/theme/source/sky.scss',
+					'css/theme/moon.css': 'css/theme/source/moon.scss',
+					'css/theme/solarized.css': 'css/theme/source/solarized.scss',
+					'css/theme/blood.css': 'css/theme/source/blood.scss'
+				}
+			}
+		},
+
+		jshint: {
+			options: {
+				curly: false,
+				eqeqeq: true,
+				immed: true,
+				latedef: true,
+				newcap: true,
+				noarg: true,
+				sub: true,
+				undef: true,
+				eqnull: true,
+				browser: true,
+				expr: true,
+				globals: {
+					head: false,
+					module: false,
+					console: false,
+					unescape: false
+				}
+			},
+			files: [ 'Gruntfile.js', 'js/reveal.js' ]
+		},
+
+		connect: {
+			server: {
+				options: {
+					port: port,
+					base: '.'
+				}
+			}
+		},
+
+		zip: {
+			'reveal-js-presentation.zip': [
+				'index.html',
+				'css/**',
+				'js/**',
+				'lib/**',
+				'images/**',
+				'plugin/**'
+			]
+		},
+
+		watch: {
+			main: {
+				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
+				tasks: 'default'
+			},
+			theme: {
+				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
+				tasks: 'themes'
+			}
+		}
+
+	});
+
+	// Dependencies
+	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
+	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
+	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
+	grunt.loadNpmTasks( 'grunt-contrib-watch' );
+	grunt.loadNpmTasks( 'grunt-contrib-sass' );
+	grunt.loadNpmTasks( 'grunt-contrib-connect' );
+	grunt.loadNpmTasks( 'grunt-zip' );
+
+	// Default task
+	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );
+
+	// Theme task
+	grunt.registerTask( 'themes', [ 'sass' ] );
+
+	// Package presentation to archive
+	grunt.registerTask( 'package', [ 'default', 'zip' ] );
+
+	// Serve presentation locally
+	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );
+
+	// Run tests
+	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );
+
+};
diff --git a/docs/slides/plpv14/reveal.js/LICENSE b/docs/slides/plpv14/reveal.js/LICENSE
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2013 Hakim El Hattab, http://hakim.se
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.eot b/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.eot
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.eot differ
diff --git a/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.svg b/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.svg
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.svg
@@ -0,0 +1,230 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="LeagueGothicRegular" horiz-adv-x="724" >
+<font-face units-per-em="2048" ascent="1505" descent="-543" />
+<missing-glyph horiz-adv-x="315" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="2048" />
+<glyph unicode="&#xd;" horiz-adv-x="682" />
+<glyph unicode=" "  horiz-adv-x="315" />
+<glyph unicode="&#x09;" horiz-adv-x="315" />
+<glyph unicode="&#xa0;" horiz-adv-x="315" />
+<glyph unicode="!" horiz-adv-x="387" d="M74 1505h239l-55 -1099h-129zM86 0v227h215v-227h-215z" />
+<glyph unicode="&#x22;" horiz-adv-x="329" d="M57 1505h215l-30 -551h-154z" />
+<glyph unicode="#" horiz-adv-x="1232" d="M49 438l27 195h198l37 258h-196l26 194h197l57 420h197l-57 -420h260l57 420h197l-58 -420h193l-27 -194h-192l-37 -258h190l-26 -195h-191l-59 -438h-197l60 438h-261l-59 -438h-197l60 438h-199zM471 633h260l37 258h-260z" />
+<glyph unicode="$" horiz-adv-x="692" d="M37 358l192 13q12 -186 129 -187q88 0 93 185q0 74 -61 175q-21 36 -34 53l-40 55q-28 38 -65.5 90t-70.5 101.5t-70.5 141.5t-37.5 170q4 293 215 342v131h123v-125q201 -23 235 -282l-192 -25q-14 129 -93 125q-80 -2 -84 -162q0 -102 94 -227l41 -59q30 -42 37 -52 t33 -48l37 -52q41 -57 68 -109l26 -55q43 -94 43 -186q-4 -338 -245 -369v-217h-123v221q-236 41 -250 352z" />
+<glyph unicode="%" horiz-adv-x="1001" d="M55 911v437q0 110 82 156q33 18 90.5 18t97.5 -44t44 -87l4 -43v-437q0 -107 -81 -157q-32 -19 -77 -19q-129 0 -156 135zM158 0l553 1505h131l-547 -1505h-137zM178 911q-4 -55 37 -55q16 0 25.5 14.5t9.5 26.5v451q2 55 -35 55q-18 0 -27.5 -13.5t-9.5 -27.5v-451z M631 158v436q0 108 81 156q33 20 79 20q125 0 153 -135l4 -41v-436q0 -110 -80 -156q-32 -18 -90.5 -18t-98.5 43t-44 88zM754 158q-4 -57 37 -58q37 0 34 58v436q2 55 -34 55q-18 0 -27.5 -13t-9.5 -28v-450z" />
+<glyph unicode="&#x26;" horiz-adv-x="854" d="M49 304q0 126 44 225.5t126 222.5q-106 225 -106 442v18q0 94 47 180q70 130 223 130q203 0 252 -215q14 -61 12 -113q0 -162 -205 -434q76 -174 148 -285q33 96 47 211l176 -33q-16 -213 -92 -358q55 -63 92 -76v-235q-23 0 -86 37.5t-123 101.5q-123 -139 -252 -139 t-216 97t-87 223zM263 325.5q1 -65.5 28.5 -107.5t78.5 -42t117 86q-88 139 -174 295q-18 -30 -34.5 -98t-15.5 -133.5zM305 1194q0 -111 55 -246q101 156 101 252q-2 2 0 15.5t-2 36t-11 42.5q-19 52 -61.5 52t-62 -38t-19.5 -75v-39z" />
+<glyph unicode="'" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="(" horiz-adv-x="561" d="M66 645q0 143 29.5 292.5t73.5 261.5q92 235 159 343l30 47l162 -84q-38 -53 -86.5 -148t-82.5 -189.5t-61.5 -238t-27.5 -284.5t26.5 -282.5t64.5 -240.5q80 -207 141 -296l26 -39l-162 -84q-41 61 -96 173t-94 217.5t-70.5 257t-31.5 294.5z" />
+<glyph unicode=")" horiz-adv-x="561" d="M41 -213q36 50 85.5 147t83.5 190t61.5 236.5t27.5 284.5t-26.5 282.5t-64.5 240.5q-78 205 -140 298l-27 39l162 84q41 -61 96 -173.5t94 -217t71 -257.5t32 -296t-30 -292.5t-74 -260.5q-92 -233 -159 -342l-30 -47z" />
+<glyph unicode="*" horiz-adv-x="677" d="M74 1251l43 148l164 -70l-19 176h154l-19 -176l164 70l43 -148l-172 -34l115 -138l-131 -80l-78 152l-76 -152l-131 80l115 138z" />
+<glyph unicode="+" horiz-adv-x="1060" d="M74 649v172h370v346h172v-346h371v-172h-371v-346h-172v346h-370z" />
+<glyph unicode="," horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="-" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="." horiz-adv-x="321" d="M53 0v227h215v-227h-215z" />
+<glyph unicode="/" horiz-adv-x="720" d="M8 -147l543 1652h162l-537 -1652h-168z" />
+<glyph unicode="0" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="1" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="2" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="3" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="4" horiz-adv-x="684" d="M25 328v194l323 983h221v-983h103v-194h-103v-328h-202v328h-342zM213 522h154v516h-13z" />
+<glyph unicode="5" horiz-adv-x="704" d="M74 438h221v-59q0 -115 14.5 -159t52 -44t53 45t15.5 156v336q0 111 -70 110q-33 0 -59.5 -40t-26.5 -70h-186v792h535v-219h-344v-313q74 55 127 51q78 0 133 -40t77 -100q35 -98 35 -171v-336q0 -393 -289 -393q-78 0 -133 29.5t-84.5 71.5t-46.5 109q-24 98 -24 244z " />
+<glyph unicode="6" horiz-adv-x="700" d="M66 309v856q0 356 288.5 356.5t288.5 -356.5v-94h-221q0 162 -11.5 210t-53.5 48t-56 -37t-14 -127v-268q59 37 124.5 37t119 -36t75.5 -93q37 -92 37 -189v-307q0 -90 -42 -187q-26 -61 -89 -99.5t-157.5 -38.5t-158 38.5t-88.5 99.5q-42 98 -42 187zM287 244 q0 -20 17.5 -44t49 -24t50 24.5t18.5 43.5v450q0 18 -18.5 43t-49 25t-48 -20.5t-19.5 -41.5v-456z" />
+<glyph unicode="7" horiz-adv-x="589" d="M8 1286v219h557v-221l-221 -1284h-229l225 1286h-332z" />
+<glyph unicode="8" horiz-adv-x="696" d="M53 322v176q0 188 115 297q-102 102 -102 276v127q0 213 147 293q57 31 135 31t135.5 -31t84 -71t42.5 -93q21 -66 21 -129v-127q0 -174 -103 -276q115 -109 115 -297v-176q0 -222 -153 -306q-60 -32 -142 -32t-141.5 32.5t-88 73.5t-44.5 96q-21 69 -21 136zM269 422 q1 -139 16.5 -187.5t57.5 -48.5t59.5 30t21.5 71t4 158t-13.5 174t-66.5 57t-66.5 -57.5t-12.5 -196.5zM284 1116q-1 -123 11 -173t53 -50t53.5 50t12.5 170t-12.5 167t-51.5 47t-52 -44t-14 -167z" />
+<glyph unicode="9" horiz-adv-x="700" d="M57 340v94h222q0 -162 11 -210t53 -48t56.5 37t14.5 127v283q-59 -37 -125 -37t-119 35.5t-76 92.5q-37 96 -37 189v293q0 87 43 188q25 60 88.5 99t157.5 39t157.5 -39t88.5 -99q43 -101 43 -188v-856q0 -356 -289 -356t-289 356zM279 825q0 -18 18 -42.5t49 -24.5 t48.5 20.5t19.5 40.5v443q0 20 -17.5 43.5t-49.5 23.5t-50 -24.5t-18 -42.5v-437z" />
+<glyph unicode=":" horiz-adv-x="362" d="M74 0v227h215v-227h-215zM74 893v227h215v-227h-215z" />
+<glyph unicode=";" horiz-adv-x="362" d="M74 0v227h215v-227l-113 -266h-102l71 266h-71zM74 893v227h215v-227h-215z" />
+<glyph unicode="&#x3c;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="=" horiz-adv-x="1058" d="M74 477v172h911v-172h-911zM74 864v172h911v-172h-911z" />
+<glyph unicode="&#x3e;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="?" horiz-adv-x="645" d="M25 1260q24 67 78 131q105 128 235 122q82 -2 138 -33.5t82 -81.5q46 -88 46 -170.5t-80 -219.5l-57 -96q-18 -32 -42 -106.5t-24 -143.5v-256h-190v256q0 102 24.5 195t48 140t65.5 118t50 105t-9 67.5t-60 34.5t-78 -48t-49 -98zM199 0h215v227h-215v-227z" />
+<glyph unicode="@" horiz-adv-x="872" d="M66 303v889q0 97 73 200q39 56 117 93t184.5 37t184 -37t116.5 -93q74 -105 74 -200v-793h-164l-20 56q-14 -28 -46 -48t-67 -20q-145 0 -145 172v485q0 170 145 170q71 0 113 -67v45q0 51 -45 104.5t-145.5 53.5t-145.5 -53.5t-45 -104.5v-889q0 -53 44 -103t153.5 -50 t160.5 63l152 -86q-109 -143 -320 -143q-106 0 -184 35.5t-117 90.5q-73 102 -73 193zM535 573q0 -53 48 -53t48 53v455q0 53 -48 53t-48 -53v-455z" />
+<glyph unicode="A" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="B" horiz-adv-x="745" d="M82 0v1505h194q205 0 304.5 -91t99.5 -308q0 -106 -29.5 -175t-107.5 -136q14 -5 47 -38.5t54 -71.5q52 -97 52 -259q0 -414 -342 -426h-272zM303 219q74 0 109 31q55 56 55 211t-63 195q-42 26 -93 26h-8v-463zM303 885q87 0 119 39q45 55 45 138t-14.5 124t-30.5 60.5 t-45 28.5q-35 11 -74 11v-401z" />
+<glyph unicode="C" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175z" />
+<glyph unicode="D" horiz-adv-x="761" d="M82 0v1505h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174zM303 221q117 0 140.5 78t23.5 399v111q0 322 -23.5 398.5t-140.5 76.5v-1063z" />
+<glyph unicode="E" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506z" />
+<glyph unicode="F" horiz-adv-x="616" d="M82 0v1505h526v-227h-305v-395h205v-228h-205v-655h-221z" />
+<glyph unicode="G" horiz-adv-x="737" d="M67 271.5q0 26.5 1 37.5v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-231h-221v231q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-905q0 -46 19.5 -78.5t54 -32.5t53 28t18.5 54l2 29v272h-88v187h309v-750h-131l-26 72 q-70 -88 -172 -88q-203 0 -250 213q-11 48 -11 74.5z" />
+<glyph unicode="H" horiz-adv-x="778" d="M82 0v1505h221v-622h172v622h221v-1505h-221v655h-172v-655h-221z" />
+<glyph unicode="I" horiz-adv-x="385" d="M82 0v1505h221v-1505h-221z" />
+<glyph unicode="J" horiz-adv-x="423" d="M12 -14v217q4 0 12.5 -1t29 2t35.5 12t28.5 34.5t13.5 62.5v1192h221v-1226q0 -137 -74 -216q-74 -78 -223 -78h-4q-19 0 -39 1z" />
+<glyph unicode="K" horiz-adv-x="768" d="M82 0v1505h221v-526h8l195 526h215l-203 -495l230 -1010h-216l-153 655l-6 31h-6l-64 -154v-532h-221z" />
+<glyph unicode="L" horiz-adv-x="604" d="M82 0v1505h221v-1300h293v-205h-514z" />
+<glyph unicode="M" horiz-adv-x="991" d="M82 0v1505h270l131 -688l11 -80h4l10 80l131 688h270v-1505h-204v1010h-13l-149 -1010h-94l-142 946l-8 64h-12v-1010h-205z" />
+<glyph unicode="N" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203z" />
+<glyph unicode="O" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5 t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="P" horiz-adv-x="720" d="M82 0v1505h221q166 0 277.5 -105.5t111.5 -345t-111.5 -346t-277.5 -106.5v-602h-221zM303 827q102 0 134 45.5t32 175.5t-33 181t-133 51v-453z" />
+<glyph unicode="Q" horiz-adv-x="729" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -94 -45 -182q33 -43 88 -53v-189q-160 0 -227 117q-55 -18 -125 -18t-130 33.5t-88 81.5q-55 94 -60 175zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887 q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="R" horiz-adv-x="739" d="M82 0v1505h221q377 0 377 -434q0 -258 -123 -342l141 -729h-221l-115 635h-59v-635h-221zM303 840q117 0 149 98q15 49 15 125t-15.5 125t-45.5 68q-44 30 -103 30v-446z" />
+<glyph unicode="S" horiz-adv-x="702" d="M37 422l217 20q0 -256 104 -256q90 0 91 166q0 59 -32 117.5t-45 79.5l-54 79q-40 58 -77 113t-73.5 117t-68 148.5t-31.5 162.5q0 139 71.5 245t216.5 108h10q88 0 152 -36t94 -100q54 -120 54 -264l-217 -20q0 217 -89 217q-75 -2 -75 -146q0 -59 23 -105 q32 -66 58 -104l197 -296q31 -49 67 -139.5t36 -166.5q0 -378 -306 -378h-2q-229 0 -290 188q-31 99 -31 250z" />
+<glyph unicode="T" horiz-adv-x="647" d="M4 1278v227h639v-227h-209v-1278h-221v1278h-209z" />
+<glyph unicode="U" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175z" />
+<glyph unicode="V" horiz-adv-x="716" d="M18 1505h215l111 -827l8 -64h13l118 891h215l-229 -1505h-221z" />
+<glyph unicode="W" horiz-adv-x="1036" d="M25 1505h204l88 -782l5 -49h16l100 831h160l100 -831h17l92 831h205l-203 -1505h-172l-115 801h-8l-115 -801h-172z" />
+<glyph unicode="X" horiz-adv-x="737" d="M16 0l244 791l-240 714h218l120 -381l7 -18h8l127 399h217l-240 -714l244 -791h-217l-127 449l-4 18h-8l-132 -467h-217z" />
+<glyph unicode="Y" horiz-adv-x="700" d="M14 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641z" />
+<glyph unicode="Z" horiz-adv-x="626" d="M20 0v238l347 1048h-297v219h536v-219l-352 -1067h352v-219h-586z" />
+<glyph unicode="[" horiz-adv-x="538" d="M82 -213v1718h399v-196h-202v-1325h202v-197h-399z" />
+<glyph unicode="\" horiz-adv-x="792" d="M8 1692h162l614 -1872h-168z" />
+<glyph unicode="]" horiz-adv-x="538" d="M57 -16h203v1325h-203v196h400v-1718h-400v197z" />
+<glyph unicode="^" horiz-adv-x="1101" d="M53 809l381 696h234l381 -696h-199l-299 543l-299 -543h-199z" />
+<glyph unicode="_" horiz-adv-x="1210" d="M74 -154h1063v-172h-1063v172z" />
+<glyph unicode="`" horiz-adv-x="1024" d="M293 1489h215l106 -184h-159z" />
+<glyph unicode="a" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="b" horiz-adv-x="686" d="M82 0v1505h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-74h-207zM289 246q0 -29 19.5 -48.5t42 -19.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -21.5t-19.5 -46.5v-628z" />
+<glyph unicode="c" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331z" />
+<glyph unicode="d" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v458h207v-1505h-207v74q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 19.5t19.5 48.5v628q0 25 -19.5 46.5t-42 21.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="e" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="f" horiz-adv-x="475" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-65 0 -65 -175v-5v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="g" horiz-adv-x="700" d="M12 -184q0 94 162 170q-125 35 -125 149q0 45 40 93t89 75q-51 35 -80.5 95.5t-34.5 105.5l-4 43v305q0 35 16.5 91t41 94t79 69t126.5 31q135 0 206 -103q102 102 170 103v-185q-72 0 -120 -24l10 -70v-317q0 -37 -17.5 -90.5t-42 -90t-79 -66.5t-104.5 -30t-62 2 q-29 -25 -29 -46t11 -33.5t42 -20.5t45.5 -10t65.5 -10.5t95 -21.5t89 -41q96 -60 96 -205t-103 -212q-100 -65 -250 -65h-9q-156 2 -240 50t-84 165zM213 -150q0 -77 132 -77h3q59 0 108.5 19t49.5 54t-20.5 52.5t-90.5 29.5l-106 21q-76 -43 -76 -99zM262 509 q0 -17 15.5 -45t44.5 -28q63 6 63 101v307q-2 0 0 10q1 3 1 7q0 8 -3 19q-4 15 -9 30q-11 36 -46 36t-50.5 -25.5t-15.5 -52.5v-359z" />
+<glyph unicode="h" horiz-adv-x="690" d="M82 0v1505h207v-479l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="i" horiz-adv-x="370" d="M82 0v1120h207v-1120h-207zM82 1298v207h207v-207h-207z" />
+<glyph unicode="j" horiz-adv-x="364" d="M-45 -182q29 -8 57 -8q64 0 64 142v1168h207v-1149q0 -186 -51 -266q-23 -35 -71 -62.5t-115 -27.5t-91 12v191zM76 1298v207h207v-207h-207z" />
+<glyph unicode="k" horiz-adv-x="641" d="M82 0v1505h207v-714h10l113 329h186l-149 -364l188 -756h-199l-102 453l-4 16h-10l-33 -82v-387h-207z" />
+<glyph unicode="l" horiz-adv-x="370" d="M82 0v1505h207v-1505h-207z" />
+<glyph unicode="m" horiz-adv-x="1021" d="M82 0v1120h207v-94q2 0 33 30q80 81 139 81q100 0 139 -125q125 125 194.5 125t109.5 -69t40 -150v-918h-194v887q-1 49 -56 49q-41 0 -78 -53v-883h-194v887q0 49 -55 49q-41 0 -78 -53v-883h-207z" />
+<glyph unicode="n" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207z" />
+<glyph unicode="o" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="p" horiz-adv-x="686" d="M82 -385v1505h207v-73q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="q" horiz-adv-x="686" d="M74 203v715q0 82 41 150.5t118 68.5q33 0 74 -22.5t66 -45.5l24 -22v73h207v-1505h-207v459q-88 -90 -165 -90t-117.5 68.5t-40.5 150.5zM281 246q0 -29 16 -48.5t38.5 -19.5t42 21.5t19.5 46.5v628q0 29 -19.5 48.5t-42 19.5t-38.5 -19.5t-16 -48.5v-628z" />
+<glyph unicode="r" horiz-adv-x="503" d="M82 0v1120h207v-125q8 41 58.5 91.5t148.5 50.5v-230q-34 11 -77 11t-86.5 -39t-43.5 -101v-778h-207z" />
+<glyph unicode="s" horiz-adv-x="630" d="M37 326h192q0 -170 97 -170q71 0 71 131q0 78 -129 202q-68 66 -98.5 99t-64 101.5t-33.5 134t12 114.5t39 95q59 100 201 104h11q161 0 211 -105q42 -86 42 -198h-193q0 131 -67 131q-63 -2 -64 -131q0 -33 23.5 -73t45 -62.5t66.5 -65.5q190 -182 191 -342 q0 -123 -64.5 -215t-199.5 -92q-197 0 -260 170q-29 76 -29 172z" />
+<glyph unicode="t" horiz-adv-x="501" d="M20 934v186h105v277h207v-277h141v-186h-141v-557q0 -184 65 -184l76 8v-203q-45 -14 -112 -14t-114.5 28.5t-70 64.5t-34.5 96q-17 79 -17 187v574h-105z" />
+<glyph unicode="u" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5z" />
+<glyph unicode="v" horiz-adv-x="602" d="M16 1120h201l68 -649l8 -72h16l76 721h201l-183 -1120h-204z" />
+<glyph unicode="w" horiz-adv-x="905" d="M20 1120h189l65 -585l9 -64h12l96 649h123l86 -585l10 -64h13l73 649h189l-166 -1120h-172l-80 535l-10 63h-8l-91 -598h-172z" />
+<glyph unicode="x" horiz-adv-x="618" d="M16 0l193 578l-176 542h194l74 -262l6 -31h4l6 31l74 262h195l-176 -542l192 -578h-201l-84 283l-6 30h-4l-6 -30l-84 -283h-201z" />
+<glyph unicode="y" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5z" />
+<glyph unicode="z" horiz-adv-x="532" d="M12 0v168l285 764h-240v188h459v-168l-285 -764h285v-188h-504z" />
+<glyph unicode="{" horiz-adv-x="688" d="M61 453v163q72 0 102 49.5t30 90.5v397q0 223 96 298t342 71v-172q-135 2 -188.5 -38t-53.5 -159v-397q0 -143 -127 -221q127 -82 127 -222v-397q0 -119 53.5 -159t188.5 -38v-172q-246 -4 -342 71t-96 298v397q0 57 -41 97.5t-91 42.5z" />
+<glyph unicode="|" horiz-adv-x="356" d="M82 -512v2204h192v-2204h-192z" />
+<glyph unicode="}" horiz-adv-x="688" d="M57 -281q135 -2 188.5 38t53.5 159v397q0 139 127 222q-127 78 -127 221v397q0 119 -53 159t-189 38v172q246 4 342.5 -71t96.5 -298v-397q0 -63 41 -101.5t90 -38.5v-163q-72 -4 -101.5 -52.5t-29.5 -87.5v-397q0 -223 -96.5 -298t-342.5 -71v172z" />
+<glyph unicode="~" horiz-adv-x="1280" d="M113 1352q35 106 115 200q34 41 94.5 74t121 33t116.5 -18.5t82 -33t83 -51.5q106 -72 174 -71q109 0 178 153l13 29l135 -57q-63 -189 -206 -276q-56 -34 -120 -34q-121 0 -272 101q-115 74 -178.5 74t-113.5 -45.5t-69 -90.5l-18 -45z" />
+<glyph unicode="&#xa1;" horiz-adv-x="387" d="M74 -385l55 1100h129l55 -1100h-239zM86 893v227h215v-227h-215z" />
+<glyph unicode="&#xa2;" horiz-adv-x="636" d="M66 508v489q0 297 208 328v242h123v-244q98 -16 144.5 -88t46.5 -227v-88h-189v135q0 90 -72.5 90t-72.5 -90v-604q0 -90 72 -91q74 0 73 91v155h189v-108q0 -156 -46 -228.5t-145 -89.5v-303h-123v301q-209 31 -208 330z" />
+<glyph unicode="&#xa3;" horiz-adv-x="817" d="M4 63q8 20 23.5 53.5t70 91.5t117.5 68q37 111 37 189t-31 184h-188v137h147l-6 21q-78 254 -78 333t15.5 140t48.5 116q72 122 231 126q190 4 267 -126q65 -108 65 -276h-213q0 201 -115 197q-47 -2 -68.5 -51t-21.5 -139.5t70 -315.5l6 -25h211v-137h-174 q25 -100 24.5 -189t-57.5 -204q16 -8 44 -24q59 -35 89 -35q74 4 82 190l188 -22q-12 -182 -81.5 -281.5t-169.5 -99.5q-51 0 -143.5 51t-127.5 51t-63.5 -25.5t-40.5 -52.5l-12 -24z" />
+<glyph unicode="&#xa5;" horiz-adv-x="720" d="M25 1505h217l110 -481l6 -14h4l7 14l110 481h217l-196 -753h147v-138h-176v-137h176v-137h-176v-340h-221v340h-176v137h176v137h-176v138h147z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1024" d="M272 1305v200h191v-200h-191zM561 1305v200h191v-200h-191z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM627 487v531q0 122 97 174q40 22 95 22 q147 0 182 -147l7 -49v-125h-138v142q0 11 -12 28.5t-37 17.5q-47 -2 -49 -63v-531q0 -63 49 -63q53 2 49 63v125h138v-125q0 -68 -40 -127q-18 -26 -57 -47.5t-108.5 -21.5t-117.5 49t-54 98z" />
+<glyph unicode="&#xaa;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xad;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#xae;" horiz-adv-x="1644" d="M53 751.5q0 317.5 225.5 544t543 226.5t543.5 -226.5t226 -544t-226 -542.5t-543.5 -225t-543 225t-225.5 542.5zM172 751.5q0 -266.5 191.5 -458t457.5 -191.5t459 191.5t193 459t-191.5 459t-459 191.5t-459 -192.5t-191.5 -459zM625 313v879h196q231 0 232 -258 q0 -76 -16.5 -125t-71.5 -96l106 -400h-151l-95 365h-55v-365h-145zM770 805h45q43 0 65.5 21.5t27.5 45t5 61.5t-5 62.5t-27.5 46t-65.5 21.5h-45v-258z" />
+<glyph unicode="&#xaf;" horiz-adv-x="1024" d="M313 1315v162h398v-162h-398z" />
+<glyph unicode="&#xb2;" horiz-adv-x="731" d="M55 0v219l39 62q25 39 88.5 152.5t112.5 220t91 241.5t44 238q0 184 -73.5 184t-73.5 -184v-105h-222v105q0 389 295 389t295 -375q0 -336 -346 -928h350v-219h-600z" />
+<glyph unicode="&#xb3;" horiz-adv-x="686" d="M45 1071q0 249 63 343q29 42 84.5 75t134.5 33t136 -31t84.5 -71t44.5 -92q22 -71 22 -130q0 -291 -108 -399q127 -100 127 -414q0 -68 -19.5 -145.5t-47 -128t-85 -89t-136.5 -38.5t-135 31.5t-86 75.5t-48 113q-23 91 -23 230h217q2 -150 17.5 -203t59.5 -53t56.5 50.5 t12.5 104.5t1 102t0 63q-6 82 -14 95l-18 33q-12 22 -29 29q-55 22 -108 25h-19v184q133 7 156 73q12 34 12 91v105q0 146 -29 177q-16 17 -40 17q-41 0 -52.5 -49t-13.5 -207h-217z" />
+<glyph unicode="&#xb4;" horiz-adv-x="1024" d="M410 1305l106 184h215l-162 -184h-159z" />
+<glyph unicode="&#xb7;" horiz-adv-x="215" d="M0 649v228h215v-228h-215z" />
+<glyph unicode="&#xb8;" horiz-adv-x="1024" d="M426 -111h172v-141l-45 -133h-104l40 133h-63v141z" />
+<glyph unicode="&#xb9;" horiz-adv-x="475" d="M25 1180v141q129 25 205 130q16 21 30 54h133v-1505h-221v1180h-147z" />
+<glyph unicode="&#xba;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM257 259q0 -17 9 -44q18 -49 62 -49q70 10 71 113v563l1 19q0 19 -10 45q-18 50 -62 50 q-68 -10 -70 -114v-563q1 -1 1 -4z" />
+<glyph unicode="&#xbf;" horiz-adv-x="645" d="M41 -106q0 82 80 219l57 95q18 32 42 106.5t24 144.5v256h190v-256q0 -102 -24.5 -195.5t-48 -140.5t-65.5 -118t-50 -104.5t9 -67.5t60 -35t78 48.5t49 98.5l179 -84q-24 -66 -78 -132q-104 -126 -236 -122q-163 4 -220 115q-46 90 -46 172zM231 893v227h215v-227h-215z " />
+<glyph unicode="&#xc0;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM141 1823h215l107 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc1;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM293 1638l106 185h215l-161 -185h-160zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc2;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM133 1638l141 185h220l141 -185h-189l-63 72l-61 -72h-189zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc3;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM184 1632v152q49 39 95.5 39t104.5 -18.5t100.5 -19.5t97.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-98 19.5t-102 -33zM307 541h152l-64 475l-6 39h-12z" />
+<glyph unicode="&#xc4;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM143 1638v201h191v-201h-191zM307 541h152l-64 475l-6 39h-12zM432 1638v201h191v-201h-191z" />
+<glyph unicode="&#xc5;" horiz-adv-x="765" d="M20 0l228 1505h270l227 -1505h-215l-41 307h-213l-40 -307h-216zM231 1761.5q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM307 541h152l-64 475l-6 39h-12zM309 1761.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50 t-23.5 50t-52.5 21.5t-52.5 -21.5t-23.5 -50z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1099" d="M16 0l420 1505h623v-227h-285v-395h205v-242h-205v-414h285v-227h-506v307h-227l-90 -307h-220zM393 541h160v514h-10z" />
+<glyph unicode="&#xc7;" horiz-adv-x="708" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-207h-206v207q-2 0 0 11.5t-3.5 27.5t-12.5 33q-17 39 -68 39q-70 -10 -78 -111v-887q0 -43 21.5 -76.5t59.5 -33.5t59.5 27.5t21.5 56.5v233h206v-207q0 -42 -17 -106t-45 -107 t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM268 -111v-141h64l-41 -133h104l45 133v141h-172z" />
+<glyph unicode="&#xc8;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM111 1823h215l106 -185h-160z" />
+<glyph unicode="&#xc9;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM236 1638l106 185h215l-162 -185h-159z" />
+<glyph unicode="&#xca;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM84 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xcb;" horiz-adv-x="628" d="M82 0v1505h506v-227h-285v-395h205v-242h-205v-414h285v-227h-506zM94 1638v201h191v-201h-191zM383 1638v201h190v-201h-190z" />
+<glyph unicode="&#xcc;" horiz-adv-x="401" d="M-6 1823h215l106 -185h-159zM98 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcd;" horiz-adv-x="401" d="M82 0v1505h221v-1505h-221zM86 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xce;" horiz-adv-x="370" d="M-66 1638l142 185h219l141 -185h-188l-64 72l-61 -72h-189zM74 0v1505h221v-1505h-221z" />
+<glyph unicode="&#xcf;" horiz-adv-x="372" d="M-53 1638v201h190v-201h-190zM76 0v1505h221v-1505h-221zM236 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd0;" horiz-adv-x="761" d="M20 655v228h62v622h174q270 0 346 -113q31 -46 50.5 -95.5t28.5 -139.5t12 -177t3 -228.5t-3 -228.5t-12 -176t-28.5 -138t-50.5 -95t-80 -68q-106 -46 -266 -46h-174v655h-62zM303 221q117 0 141.5 81t22.5 452q2 371 -22.5 450.5t-141.5 79.5v-401h84v-228h-84v-434z " />
+<glyph unicode="&#xd1;" horiz-adv-x="808" d="M82 0v1505h197l215 -784l18 -70h12v854h203v-1505h-197l-215 784l-18 70h-12v-854h-203zM207 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39t-102.5 19.5t-100 19.5t-99.5 -33z" />
+<glyph unicode="&#xd2;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM121 1823h215l106 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd3;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM285 1638l106 185h215l-162 -185h-159zM289 309q0 -46 19.5 -78t54 -32t53 27.5 t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd4;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM113 1638l141 185h219l141 -185h-188l-64 72l-61 -72h-188zM289 309q0 -46 19.5 -78 t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd5;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM164 1632v152q49 39 95 39t104.5 -18.5t102.5 -19.5t95 32v-152q-51 -39 -95 -39 t-102.5 19.5t-100 19.5t-99.5 -33zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887z" />
+<glyph unicode="&#xd6;" d="M68 309v887q0 42 17 106t45 107t88.5 78t144 35t144 -34t88.5 -81q55 -93 60 -178l2 -33v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-144 -34.5t-144 33.5t-88.5 81.5q-55 94 -60 175zM123 1638v201h190v-201h-190zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v887q0 46 -19.5 78.5t-54 32.5t-53 -28t-18.5 -54l-2 -29v-887zM412 1638v201h190v-201h-190z" />
+<glyph unicode="&#xd8;" d="M59 -20l47 157q-36 74 -36 148l-2 24v887q0 42 17 106t45 107t88.5 78t148 35t153.5 -43l15 47h122l-45 -150q43 -84 43 -155l2 -25v-887q0 -42 -17 -106t-45 -107t-88.5 -77.5t-150.5 -34.5t-153 43l-15 -47h-129zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5 l2 26v488zM289 727l147 479q-8 100 -74 101q-35 0 -53 -28t-18 -54l-2 -29v-469z" />
+<glyph unicode="&#xd9;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM145 1823h215l107 -185h-160z" />
+<glyph unicode="&#xda;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM307 1638l107 185h215l-162 -185h-160z" />
+<glyph unicode="&#xdb;" horiz-adv-x="749" d="M80 309q0 -42 17.5 -106t45 -107t88 -77.5t144.5 -34.5t144.5 33.5t88.5 81.5q55 97 60 175l2 35v1196h-221v-1196q0 -44 -19.5 -77t-54.5 -33t-53.5 27.5t-18.5 56.5l-2 26v1196h-221v-1196zM125 1638l141 185h219l142 -185h-189l-63 72l-62 -72h-188z" />
+<glyph unicode="&#xdc;" horiz-adv-x="749" d="M80 309v1196h221v-1196q0 -46 19.5 -78t54.5 -32t53 27.5t18 56.5l3 26v1196h221v-1196q0 -42 -17.5 -106t-45 -107t-88 -77.5t-144.5 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175zM135 1638v201h191v-201h-191zM424 1638v201h190v-201h-190z" />
+<glyph unicode="&#xdd;" horiz-adv-x="704" d="M16 1505l226 -864v-641h221v641l225 864h-217l-111 -481l-6 -14h-4l-6 14l-111 481h-217zM254 1638l106 185h215l-161 -185h-160z" />
+<glyph unicode="&#xde;" d="M82 0v1505h219v-241h2q166 0 277.5 -105.5t111.5 -345.5t-111.5 -346.5t-277.5 -106.5v-360h-221zM303 586q102 0 134 45t32 175t-33 181t-133 51v-452z" />
+<glyph unicode="&#xdf;" horiz-adv-x="733" d="M66 0v1235q0 123 70.5 205t206.5 82t204.5 -81t68.5 -197t-88 -181q152 -88 152 -488q0 -362 -87 -475q-46 -59 -102.5 -79.5t-144.5 -20.5v193q45 0 70 25q57 57 57 357q0 316 -57 377q-25 27 -70 27v141q35 0 60.5 33t25.5 84q0 100 -86 100q-74 0 -74 -102v-1235h-206 z" />
+<glyph unicode="&#xe0;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1489h215 l107 -184h-160zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe1;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM252 291 q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xe2;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM90 1305 l141 184h220l141 -184h-189l-63 71l-61 -71h-189zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe3;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM143 1305v151 q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250z" />
+<glyph unicode="&#xe4;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM102 1305v200 h191v-200h-191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM391 1305v200h191v-200h-191z" />
+<glyph unicode="&#xe5;" horiz-adv-x="681" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t190 88t184.5 -74t75 -180v-688q0 -109 14 -195h-202q-18 20 -19 90h-14q-20 -37 -65.5 -71.5t-102.5 -34.5t-110.5 60t-53.5 191zM188 1421.5 q0 61.5 45.5 102.5t109 41t107.5 -41t44 -102.5t-44 -102.5t-107.5 -41t-109 41t-45.5 102.5zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM266 1421.5q0 -28.5 23.5 -50t52.5 -21.5t52.5 21.5t23.5 50t-23.5 50t-52.5 21.5t-52.5 -21.5 t-23.5 -50z" />
+<glyph unicode="&#xe6;" horiz-adv-x="989" d="M49 235q0 131 34 212t83 124t98 73t88 50.5t43 36.5v123q0 102 -57 102q-41 0 -50 -42t-9 -84v-39h-207v47q0 123 80.5 211t197.5 88q84 0 152 -52q66 51 162 52q199 0 251 -197q14 -51 15 -92v-326h-342v-256q0 -60 38 -88q17 -12 38 -12q70 10 73 113v122h193v-129 q0 -37 -16.5 -93t-41 -95t-80 -69.5t-130.5 -30.5q-158 0 -226 131q-102 -131 -221 -131q-59 0 -112.5 60t-53.5 191zM252 291q0 -104 57 -105q35 0 60.5 19.5t25.5 48.5v287q-143 -62 -143 -250zM588 684h149v158q0 48 -19.5 81t-53 33t-53 -28.5t-21.5 -57.5l-2 -28v-158z " />
+<glyph unicode="&#xe7;" horiz-adv-x="645" d="M66 315v490q0 332 264 332q137 0 201.5 -71t64.5 -251v-88h-207v135q0 51 -12 70.5t-47 19.5q-58 0 -58 -90v-604q0 -90 58 -90q35 0 47 19.5t12 70.5v156h207v-109q0 -180 -64.5 -250.5t-201.5 -70.5q-264 0 -264 331zM238 -111v-141h63l-41 -133h105l45 133v141h-172z " />
+<glyph unicode="&#xe8;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM102 1489h215l107 -184 h-160zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xe9;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM258 684h150v158 q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM264 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xea;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM80 1305l141 184h219 l142 -184h-189l-63 71l-62 -71h-188zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158z" />
+<glyph unicode="&#xeb;" horiz-adv-x="659" d="M66 279v563q0 36 16 94.5t42 97.5t81 71t129 32q199 0 252 -197q14 -51 14 -92v-326h-342v-256q0 -59 39 -88q16 -12 37 -12q70 10 74 113v122h192v-129q0 -37 -16.5 -93t-41 -95t-79.5 -69.5t-130 -30.5t-130.5 30.5t-80.5 73.5q-49 87 -54 160zM90 1305v200h191v-200 h-191zM258 684h150v158q0 48 -19.5 81t-53.5 33t-53.5 -28.5t-21.5 -57.5l-2 -28v-158zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xec;" horiz-adv-x="370" d="M-33 1489h215l107 -184h-160zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xed;" horiz-adv-x="370" d="M82 0h207v1120h-207v-1120zM82 1305l106 184h215l-161 -184h-160z" />
+<glyph unicode="&#xee;" horiz-adv-x="370" d="M-66 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189zM82 0h207v1120h-207v-1120z" />
+<glyph unicode="&#xef;" horiz-adv-x="372" d="M-53 1305v200h190v-200h-190zM82 0v1120h207v-1120h-207zM236 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf0;" horiz-adv-x="673" d="M76 279v579q0 279 172 279q63 0 155 -78q-12 109 -51 203l-82 -72l-55 63l100 88l-45 66l109 100q25 -27 53 -61l94 82l56 -66l-101 -88q125 -201 125 -446v-656q0 -102 -56 -188q-26 -39 -80 -69.5t-129 -30.5t-130 30.5t-80 73.5q-53 91 -53 160zM270 267.5 q-2 -11.5 2 -29t10 -34.5q16 -38 58 -38q70 10 72 113v563q-2 0 0 11t-2 28.5t-10 34.5q-16 40 -60 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf1;" horiz-adv-x="690" d="M82 0v1120h207v-94l32 32q79 79 145.5 79t106 -69t39.5 -150v-918h-206v887q-1 49 -50 49q-41 0 -67 -53v-883h-207zM147 1305v151q49 39 95.5 39t105 -18.5t97 -19.5t100.5 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#xf2;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM98 1489h215l107 -184h-160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf3;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5 t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM260 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xf4;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM78 1305l141 184h219l142 -184h-189l-63 71l-62 -71h-188zM258 267.5q-2 -11.5 2 -29 t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf5;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM131 1305v151q49 39 95.5 39t104.5 -18.5t98.5 -19.5t98.5 32v-152q-51 -39 -95 -39 t-102 19.5t-101 19.5t-99 -32zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5z" />
+<glyph unicode="&#xf6;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t129.5 32q199 0 252 -197q14 -51 14 -92v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-129 -30.5t-130 30.5t-80.5 73.5q-52 92 -52 160zM90 1305v200h191v-200h-191zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38 q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM379 1305v200h190v-200h-190z" />
+<glyph unicode="&#xf8;" horiz-adv-x="657" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t118 32t117.5 -19l21 80h75l-30 -121q88 -84 94 -229v-576q0 -102 -56 -188q-26 -39 -80.5 -69.5t-120.5 -30.5t-112 16l-20 -78h-80l31 121q-41 39 -64.5 97.5t-25.5 97.5zM258 436l125 486q-18 35 -55 34q-68 -10 -70 -114 v-406zM274 197q17 -31 54 -31q70 10 71 113v403z" />
+<glyph unicode="&#xf9;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM113 1489h215l106 -184h-160z" />
+<glyph unicode="&#xfa;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM274 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfb;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM94 1305l142 184h219l141 -184h-188l-64 71l-61 -71h-189z" />
+<glyph unicode="&#xfc;" horiz-adv-x="690" d="M78 203v917h207v-887q0 -49 49 -49q41 0 67 54v882h207v-1120h-207v94l-31 -32q-78 -78 -145.5 -78t-107 68.5t-39.5 150.5zM106 1305v200h191v-200h-191zM395 1305v200h191v-200h-191z" />
+<glyph unicode="&#xfd;" horiz-adv-x="634" d="M25 1120l190 -1153q0 -68 -36 -123t-97 -61l-49 4v-184q70 -4 92 -4q115 0 192.5 95t94.5 222l198 1204h-202l-82 -688l-4 -57h-9l-4 57l-82 688h-202zM231 1305l107 184h215l-162 -184h-160z" />
+<glyph unicode="&#xfe;" horiz-adv-x="686" d="M82 -385v1890h207v-458q88 90 165 90t117.5 -69t40.5 -150v-715q0 -82 -41 -150.5t-118 -68.5q-33 0 -74 22.5t-66 44.5l-24 23v-459h-207zM289 246q0 -25 19.5 -46.5t42 -21.5t39 19.5t16.5 48.5v628q0 29 -16.5 48.5t-39 19.5t-42 -19.5t-19.5 -48.5v-628z" />
+<glyph unicode="&#xff;" horiz-adv-x="634" d="M25 1120h202l82 -688l4 -57h9l4 57l82 688h202l-198 -1204q-16 -127 -94 -222t-193 -95l-92 4v184q16 -4 49 -4q61 6 97 61.5t36 122.5zM78 1305v200h190v-200h-190zM367 1305v200h190v-200h-190z" />
+<glyph unicode="&#x152;" horiz-adv-x="983" d="M68 309v887q0 41 17 101.5t45 100.5t88.5 73.5t143.5 33.5h580v-227h-285v-395h205v-242h-205v-414h285v-227h-580q-84 0 -144 31.5t-88 78.5q-55 91 -60 169zM289 309q0 -46 19.5 -78t54 -32t53 27.5t18.5 56.5l2 26v901q-6 96 -74 97q-35 0 -53 -28t-18 -54l-2 -29 v-887z" />
+<glyph unicode="&#x153;" horiz-adv-x="995" d="M63 279v563q0 40 15.5 96.5t40 95.5t80 71t145.5 32t156 -60q66 59 170 60q199 0 252 -197q14 -51 14 -92v-326h-342v-250q0 -46 22.5 -76t53.5 -30q70 10 73 113v122h193v-129q0 -37 -16.5 -93t-41 -95t-80 -69.5t-146 -30.5t-154.5 57q-68 -57 -156 -57t-143.5 30.5 t-80.5 73.5q-52 92 -52 160zM258 267.5q-2 -11.5 2 -29t10 -34.5q14 -38 58 -38q70 10 71 113v563q-2 0 0 11t-2 28.5t-10 34.5q-15 40 -59 40q-68 -10 -70 -114v-563q2 0 0 -11.5zM594 684h149v158q0 48 -19 81t-58 33t-55.5 -37.5t-16.5 -70.5v-164z" />
+<glyph unicode="&#x178;" horiz-adv-x="704" d="M16 1505h217l111 -481l6 -14h4l6 14l111 481h217l-225 -864v-641h-221v641zM113 1638v201h190v-201h-190zM401 1638v201h191v-201h-191z" />
+<glyph unicode="&#x2c6;" horiz-adv-x="1021" d="M260 1305l141 184h220l141 -184h-189l-63 71l-61 -71h-189z" />
+<glyph unicode="&#x2dc;" horiz-adv-x="1024" d="M313 1305v151q49 39 95.5 39t104.5 -18.5t97 -19.5t101 32v-152q-51 -39 -95.5 -39t-102.5 19.5t-99 19.5t-101 -32z" />
+<glyph unicode="&#x2000;" horiz-adv-x="952" />
+<glyph unicode="&#x2001;" horiz-adv-x="1905" />
+<glyph unicode="&#x2002;" horiz-adv-x="952" />
+<glyph unicode="&#x2003;" horiz-adv-x="1905" />
+<glyph unicode="&#x2004;" horiz-adv-x="635" />
+<glyph unicode="&#x2005;" horiz-adv-x="476" />
+<glyph unicode="&#x2006;" horiz-adv-x="317" />
+<glyph unicode="&#x2007;" horiz-adv-x="317" />
+<glyph unicode="&#x2008;" horiz-adv-x="238" />
+<glyph unicode="&#x2009;" horiz-adv-x="381" />
+<glyph unicode="&#x200a;" horiz-adv-x="105" />
+<glyph unicode="&#x2010;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2011;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2012;" horiz-adv-x="444" d="M74 455v194h297v-194h-297z" />
+<glyph unicode="&#x2013;" horiz-adv-x="806" d="M74 649v195h659v-195h-659z" />
+<glyph unicode="&#x2014;" horiz-adv-x="972" d="M74 649v195h825v-195h-825z" />
+<glyph unicode="&#x2018;" horiz-adv-x="309" d="M49 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x2019;" horiz-adv-x="309" d="M45 1012l72 266h-72v227h215v-227l-113 -266h-102z" />
+<glyph unicode="&#x201a;" horiz-adv-x="309" d="M45 0v227h215v-227l-113 -266h-102l72 266h-72z" />
+<glyph unicode="&#x201c;" horiz-adv-x="624" d="M53 1012v227l113 266h102l-71 -266h71v-227h-215zM356 1012v227l113 266h102l-71 -266h71v-227h-215z" />
+<glyph unicode="&#x201d;" horiz-adv-x="624" d="M53 1012l72 266h-72v227h215v-227l-112 -266h-103zM356 1012l72 266h-72v227h215v-227l-112 -266h-103z" />
+<glyph unicode="&#x201e;" horiz-adv-x="624" d="M53 0v227h215v-227l-112 -266h-103l72 266h-72zM356 0v227h215v-227l-112 -266h-103l72 266h-72z" />
+<glyph unicode="&#x2022;" horiz-adv-x="663" d="M82 815q0 104 72.5 177t177 73t177.5 -72.5t73 -177t-73 -177.5t-177 -73t-177 73t-73 177z" />
+<glyph unicode="&#x2026;" horiz-adv-x="964" d="M53 0v227h215v-227h-215zM375 0v227h215v-227h-215zM696 0v227h215v-227h-215z" />
+<glyph unicode="&#x202f;" horiz-adv-x="381" />
+<glyph unicode="&#x2039;" horiz-adv-x="1058" d="M74 649v160l911 475v-199l-698 -356l698 -356v-199z" />
+<glyph unicode="&#x203a;" horiz-adv-x="1058" d="M74 174v199l698 356l-698 356v199l911 -475v-160z" />
+<glyph unicode="&#x205f;" horiz-adv-x="476" />
+<glyph unicode="&#x20ac;" horiz-adv-x="813" d="M53 547v137h107v137h-107v137h107v238q0 42 17.5 106t45 107t88 78t144.5 35t144 -34t88 -81q53 -90 61 -178l2 -33v-84h-207v84q-2 0 0 11.5t-3 27.5t-12 33q-18 39 -69 39q-70 -10 -78 -111v-238h233v-137h-233v-137h233v-137h-233v-238q0 -43 21.5 -76.5t59.5 -33.5 t58.5 27.5t20.5 56.5l2 26v84h207v-84q0 -38 -17.5 -104t-45.5 -109t-88 -77.5t-144 -34.5t-144.5 33.5t-88.5 81.5q-55 97 -60 175l-2 35v238h-107z" />
+<glyph unicode="&#x2122;" horiz-adv-x="937" d="M74 1401v104h321v-104h-104v-580h-113v580h-104zM440 821v684h138l67 -319h6l68 319h137v-684h-104v449l-78 -449h-51l-80 449v-449h-103z" />
+<glyph unicode="&#xe000;" horiz-adv-x="1120" d="M0 0v1120h1120v-1120h-1120z" />
+<glyph unicode="&#xfb01;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2v-184q-41 12 -91 12t-69.5 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h358v-1120h-207v934h-151v-934h-207v934h-105z" />
+<glyph unicode="&#xfb02;" horiz-adv-x="772" d="M20 934v186h105v31q0 172 31 231q16 31 42 67q53 71 181 71q59 0 127 -13l20 -2h164v-1505h-207v1329q-37 4 -67.5 4t-50 -18.5t-25.5 -58.5q-8 -52 -8 -107v-29h104v-186h-104v-934h-207v934h-105z" />
+<glyph unicode="&#xfb03;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1120h207v-1120h-207zM1032 1298v207h207v-207h-207z" />
+<glyph unicode="&#xfb04;" horiz-adv-x="1320" d="M20 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934h-207v934h-105zM495 934v186h105v31q0 190 51 270q23 35 71 63.5t115 28.5l97 -14v-178q-27 8 -62 8q-66 0 -65 -180v-29h104v-186h-104v-934 h-207v934h-105zM1032 0v1505h207v-1505h-207z" />
+</font>
+</defs></svg> 
diff --git a/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.ttf b/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.ttf
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.ttf differ
diff --git a/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.woff b/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.woff
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/reveal.js/lib/font/league_gothic-webfont.woff differ
diff --git a/docs/slides/plpv14/reveal.js/lib/font/league_gothic_license b/docs/slides/plpv14/reveal.js/lib/font/league_gothic_license
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/lib/font/league_gothic_license
@@ -0,0 +1,2 @@
+SIL Open Font License (OFL)
+http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
diff --git a/docs/slides/plpv14/reveal.js/plugin/highlight/highlight.js b/docs/slides/plpv14/reveal.js/plugin/highlight/highlight.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/highlight/highlight.js
@@ -0,0 +1,32 @@
+// START CUSTOM REVEAL.JS INTEGRATION
+(function() {
+	if( typeof window.addEventListener === 'function' ) {
+		var hljs_nodes = document.querySelectorAll( 'pre code' );
+
+		for( var i = 0, len = hljs_nodes.length; i < len; i++ ) {
+			var element = hljs_nodes[i];
+
+			// trim whitespace if data-trim attribute is present
+			if( element.hasAttribute( 'data-trim' ) && typeof element.innerHTML.trim === 'function' ) {
+				element.innerHTML = element.innerHTML.trim();
+			}
+
+			// Now escape html unless prevented by author
+			if( ! element.hasAttribute( 'data-noescape' )) {
+				element.innerHTML = element.innerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;");
+			}
+
+			// re-highlight when focus is lost (for edited code)
+			element.addEventListener( 'focusout', function( event ) {
+				hljs.highlightBlock( event.currentTarget );
+			}, false );
+		}
+	}
+})();
+// END CUSTOM REVEAL.JS INTEGRATION
+
+// highlight.js build includes support for:
+// All languages in master + fsharp
+
+
+var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName=="CODE"){return o}if(!(o.nodeType==3&&o.nodeValue.match(/\s+/))){break}}}function h(p,o){return Array.prototype.map.call(p.childNodes,function(q){if(q.nodeType==3){return o?q.nodeValue.replace(/\n/g,""):q.nodeValue}if(q.nodeName=="BR"){return"\n"}return h(q,o)}).join("")}function a(q){var p=(q.className+" "+(q.parentNode?q.parentNode.className:"")).split(/\s+/);p=p.map(function(r){return r.replace(/^language-/,"")});for(var o=0;o<p.length;o++){if(e[p[o]]||p[o]=="no-highlight"){return p[o]}}}function c(q){var o=[];(function p(r,s){for(var t=r.firstChild;t;t=t.nextSibling){if(t.nodeType==3){s+=t.nodeValue.length}else{if(t.nodeName=="BR"){s+=1}else{if(t.nodeType==1){o.push({event:"start",offset:s,node:t});s=p(t,s);o.push({event:"stop",offset:s,node:t})}}}}return s})(q,0);return o}function j(x,v,w){var p=0;var y="";var r=[];function t(){if(x.length&&v.length){if(x[0].offset!=v[0].offset){return(x[0].offset<v[0].offset)?x:v}else{return v[0].event=="start"?x:v}}else{return x.length?x:v}}function s(A){function z(B){return" "+B.nodeName+'="'+l(B.value)+'"'}return"<"+A.nodeName+Array.prototype.map.call(A.attributes,z).join("")+">"}while(x.length||v.length){var u=t().splice(0,1)[0];y+=l(w.substr(p,u.offset-p));p=u.offset;if(u.event=="start"){y+=s(u.node);r.push(u.node)}else{if(u.event=="stop"){var o,q=r.length;do{q--;o=r[q];y+=("</"+o.nodeName.toLowerCase()+">")}while(o!=u.node);r.splice(q,1);while(q<r.length){y+=s(r[q]);q++}}}}return y+l(w.substr(p))}function f(r){function o(s){return(s&&s.source)||s}function p(t,s){return RegExp(o(t),"m"+(r.cI?"i":"")+(s?"g":""))}function q(z,x){if(z.compiled){return}z.compiled=true;var u=[];if(z.k){var s={};function A(B,t){t.split(" ").forEach(function(C){var D=C.split("|");s[D[0]]=[B,D[1]?Number(D[1]):1];u.push(D[0])})}z.lR=p(z.l||hljs.IR+"(?!\\.)",true);if(typeof z.k=="string"){A("keyword",z.k)}else{for(var y in z.k){if(!z.k.hasOwnProperty(y)){continue}A(y,z.k[y])}}z.k=s}if(x){if(z.bWK){z.b="\\b("+u.join("|")+")\\b(?!\\.)\\s*"}z.bR=p(z.b?z.b:"\\B|\\b");if(!z.e&&!z.eW){z.e="\\B|\\b"}if(z.e){z.eR=p(z.e)}z.tE=o(z.e)||"";if(z.eW&&x.tE){z.tE+=(z.e?"|":"")+x.tE}}if(z.i){z.iR=p(z.i)}if(z.r===undefined){z.r=1}if(!z.c){z.c=[]}for(var w=0;w<z.c.length;w++){if(z.c[w]=="self"){z.c[w]=z}q(z.c[w],z)}if(z.starts){q(z.starts,x)}var v=[];for(var w=0;w<z.c.length;w++){v.push(o(z.c[w].b))}if(z.tE){v.push(o(z.tE))}if(z.i){v.push(o(z.i))}z.t=v.length?p(v.join("|"),true):{exec:function(t){return null}}}q(r)}function d(E,F,C){function o(r,N){for(var M=0;M<N.c.length;M++){var L=N.c[M].bR.exec(r);if(L&&L.index==0){return N.c[M]}}}function s(L,r){if(L.e&&L.eR.test(r)){return L}if(L.eW){return s(L.parent,r)}}function t(r,L){return !C&&L.i&&L.iR.test(r)}function y(M,r){var L=G.cI?r[0].toLowerCase():r[0];return M.k.hasOwnProperty(L)&&M.k[L]}function H(){var L=l(w);if(!A.k){return L}var r="";var O=0;A.lR.lastIndex=0;var M=A.lR.exec(L);while(M){r+=L.substr(O,M.index-O);var N=y(A,M);if(N){v+=N[1];r+='<span class="'+N[0]+'">'+M[0]+"</span>"}else{r+=M[0]}O=A.lR.lastIndex;M=A.lR.exec(L)}return r+L.substr(O)}function z(){if(A.sL&&!e[A.sL]){return l(w)}var r=A.sL?d(A.sL,w):g(w);if(A.r>0){v+=r.keyword_count;B+=r.r}return'<span class="'+r.language+'">'+r.value+"</span>"}function K(){return A.sL!==undefined?z():H()}function J(M,r){var L=M.cN?'<span class="'+M.cN+'">':"";if(M.rB){x+=L;w=""}else{if(M.eB){x+=l(r)+L;w=""}else{x+=L;w=r}}A=Object.create(M,{parent:{value:A}})}function D(L,r){w+=L;if(r===undefined){x+=K();return 0}var N=o(r,A);if(N){x+=K();J(N,r);return N.rB?0:r.length}var O=s(A,r);if(O){var M=A;if(!(M.rE||M.eE)){w+=r}x+=K();do{if(A.cN){x+="</span>"}B+=A.r;A=A.parent}while(A!=O.parent);if(M.eE){x+=l(r)}w="";if(O.starts){J(O.starts,"")}return M.rE?0:r.length}if(t(r,A)){throw new Error('Illegal lexem "'+r+'" for mode "'+(A.cN||"<unnamed>")+'"')}w+=r;return r.length||1}var G=e[E];f(G);var A=G;var w="";var B=0;var v=0;var x="";try{var u,q,p=0;while(true){A.t.lastIndex=p;u=A.t.exec(F);if(!u){break}q=D(F.substr(p,u.index-p),u[0]);p=u.index+q}D(F.substr(p));return{r:B,keyword_count:v,value:x,language:E}}catch(I){if(I.message.indexOf("Illegal")!=-1){return{r:0,keyword_count:0,value:l(F)}}else{throw I}}}function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p in e){if(!e.hasOwnProperty(p)){continue}var r=d(p,s,false);r.language=p;if(r.keyword_count+r.r>q.keyword_count+q.r){q=r}if(r.keyword_count+r.r>o.keyword_count+o.r){q=o;o=r}}if(q.language){o.second_best=q}return o}function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\t)+)/gm,function(r,v,u,t){return v.replace(/\t/g,p)})}if(o){q=q.replace(/\n/g,"<br>")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}var w=t?d(t,v,true):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match("(\\s|^)(language-)?"+t+"(\\s|$)")){s=s?(s+" "+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagName("pre"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener("DOMContentLoaded",n,false);window.addEventListener("load",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES["1c"]=function(b){var f="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*";var c="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт";var e="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку  стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон";var a={cN:"dquote",b:'""'};var d={cN:"string",b:'"',e:'"|$',c:[a],r:0};var g={cN:"string",b:"\\|",e:'"|$',c:[a]};return{cI:true,l:f,k:{keyword:c,built_in:e},c:[b.CLCM,b.NM,d,g,{cN:"function",b:"(процедура|функция)",e:"$",l:f,k:"процедура функция",c:[{cN:"title",b:f},{cN:"tail",eW:true,c:[{cN:"params",b:"\\(",e:"\\)",l:f,k:"знач",c:[d,g]},{cN:"export",b:"экспорт",eW:true,l:f,k:"экспорт",c:[b.CLCM]}]},b.CLCM]},{cN:"preprocessor",b:"#",e:"$"},{cN:"date",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}}(hljs);hljs.LANGUAGES.actionscript=function(a){var d="[a-zA-Z_$][a-zA-Z0-9_$]*";var c="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";var e={cN:"rest_arg",b:"[.]{3}",e:d,r:10};var b={cN:"title",b:d};return{k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{cN:"package",bWK:true,e:"{",k:"package",c:[b]},{cN:"class",bWK:true,e:"{",k:"class interface",c:[{bWK:true,k:"extends implements"},b]},{cN:"preprocessor",bWK:true,e:";",k:"import include"},{cN:"function",bWK:true,e:"[{;]",k:"function",i:"\\S",c:[b,{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,e]},{cN:"type",b:":",e:c,r:10}]}]}}(hljs);hljs.LANGUAGES.apache=function(a){var b={cN:"number",b:"[\\$%]\\d+"};return{cI:true,k:{keyword:"acceptfilter acceptmutex acceptpathinfo accessfilename action addalt addaltbyencoding addaltbytype addcharset adddefaultcharset adddescription addencoding addhandler addicon addiconbyencoding addiconbytype addinputfilter addlanguage addmoduleinfo addoutputfilter addoutputfilterbytype addtype alias aliasmatch allow allowconnect allowencodedslashes allowoverride anonymous anonymous_logemail anonymous_mustgiveemail anonymous_nouserid anonymous_verifyemail authbasicauthoritative authbasicprovider authdbduserpwquery authdbduserrealmquery authdbmgroupfile authdbmtype authdbmuserfile authdefaultauthoritative authdigestalgorithm authdigestdomain authdigestnccheck authdigestnonceformat authdigestnoncelifetime authdigestprovider authdigestqop authdigestshmemsize authgroupfile authldapbinddn authldapbindpassword authldapcharsetconfig authldapcomparednonserver authldapdereferencealiases authldapgroupattribute authldapgroupattributeisdn authldapremoteuserattribute authldapremoteuserisdn authldapurl authname authnprovideralias authtype authuserfile authzdbmauthoritative authzdbmtype authzdefaultauthoritative authzgroupfileauthoritative authzldapauthoritative authzownerauthoritative authzuserauthoritative balancermember browsermatch browsermatchnocase bufferedlogs cachedefaultexpire cachedirlength cachedirlevels cachedisable cacheenable cachefile cacheignorecachecontrol cacheignoreheaders cacheignorenolastmod cacheignorequerystring cachelastmodifiedfactor cachemaxexpire cachemaxfilesize cacheminfilesize cachenegotiateddocs cacheroot cachestorenostore cachestoreprivate cgimapextension charsetdefault charsetoptions charsetsourceenc checkcaseonly checkspelling chrootdir contentdigest cookiedomain cookieexpires cookielog cookiename cookiestyle cookietracking coredumpdirectory customlog dav davdepthinfinity davgenericlockdb davlockdb davmintimeout dbdexptime dbdkeep dbdmax dbdmin dbdparams dbdpersist dbdpreparesql dbdriver defaulticon defaultlanguage defaulttype deflatebuffersize deflatecompressionlevel deflatefilternote deflatememlevel deflatewindowsize deny directoryindex directorymatch directoryslash documentroot dumpioinput dumpiologlevel dumpiooutput enableexceptionhook enablemmap enablesendfile errordocument errorlog example expiresactive expiresbytype expiresdefault extendedstatus extfilterdefine extfilteroptions fileetag filterchain filterdeclare filterprotocol filterprovider filtertrace forcelanguagepriority forcetype forensiclog gracefulshutdowntimeout group header headername hostnamelookups identitycheck identitychecktimeout imapbase imapdefault imapmenu include indexheadinsert indexignore indexoptions indexorderdefault indexstylesheet isapiappendlogtoerrors isapiappendlogtoquery isapicachefile isapifakeasync isapilognotsupported isapireadaheadbuffer keepalive keepalivetimeout languagepriority ldapcacheentries ldapcachettl ldapconnectiontimeout ldapopcacheentries ldapopcachettl ldapsharedcachefile ldapsharedcachesize ldaptrustedclientcert ldaptrustedglobalcert ldaptrustedmode ldapverifyservercert limitinternalrecursion limitrequestbody limitrequestfields limitrequestfieldsize limitrequestline limitxmlrequestbody listen listenbacklog loadfile loadmodule lockfile logformat loglevel maxclients maxkeepaliverequests maxmemfree maxrequestsperchild maxrequestsperthread maxspareservers maxsparethreads maxthreads mcachemaxobjectcount mcachemaxobjectsize mcachemaxstreamingbuffer mcacheminobjectsize mcacheremovalalgorithm mcachesize metadir metafiles metasuffix mimemagicfile minspareservers minsparethreads mmapfile mod_gzip_on mod_gzip_add_header_count mod_gzip_keep_workfiles mod_gzip_dechunk mod_gzip_min_http mod_gzip_minimum_file_size mod_gzip_maximum_file_size mod_gzip_maximum_inmem_size mod_gzip_temp_dir mod_gzip_item_include mod_gzip_item_exclude mod_gzip_command_version mod_gzip_can_negotiate mod_gzip_handle_methods mod_gzip_static_suffix mod_gzip_send_vary mod_gzip_update_static modmimeusepathinfo multiviewsmatch namevirtualhost noproxy nwssltrustedcerts nwsslupgradeable options order passenv pidfile protocolecho proxybadheader proxyblock proxydomain proxyerroroverride proxyftpdircharset proxyiobuffersize proxymaxforwards proxypass proxypassinterpolateenv proxypassmatch proxypassreverse proxypassreversecookiedomain proxypassreversecookiepath proxypreservehost proxyreceivebuffersize proxyremote proxyremotematch proxyrequests proxyset proxystatus proxytimeout proxyvia readmename receivebuffersize redirect redirectmatch redirectpermanent redirecttemp removecharset removeencoding removehandler removeinputfilter removelanguage removeoutputfilter removetype requestheader require rewritebase rewritecond rewriteengine rewritelock rewritelog rewriteloglevel rewritemap rewriteoptions rewriterule rlimitcpu rlimitmem rlimitnproc satisfy scoreboardfile script scriptalias scriptaliasmatch scriptinterpretersource scriptlog scriptlogbuffer scriptloglength scriptsock securelisten seerequesttail sendbuffersize serveradmin serveralias serverlimit servername serverpath serverroot serversignature servertokens setenv setenvif setenvifnocase sethandler setinputfilter setoutputfilter ssienableaccess ssiendtag ssierrormsg ssistarttag ssitimeformat ssiundefinedecho sslcacertificatefile sslcacertificatepath sslcadnrequestfile sslcadnrequestpath sslcarevocationfile sslcarevocationpath sslcertificatechainfile sslcertificatefile sslcertificatekeyfile sslciphersuite sslcryptodevice sslengine sslhonorciperorder sslmutex ssloptions sslpassphrasedialog sslprotocol sslproxycacertificatefile sslproxycacertificatepath sslproxycarevocationfile sslproxycarevocationpath sslproxyciphersuite sslproxyengine sslproxymachinecertificatefile sslproxymachinecertificatepath sslproxyprotocol sslproxyverify sslproxyverifydepth sslrandomseed sslrequire sslrequiressl sslsessioncache sslsessioncachetimeout sslusername sslverifyclient sslverifydepth startservers startthreads substitute suexecusergroup threadlimit threadsperchild threadstacksize timeout traceenable transferlog typesconfig unsetenv usecanonicalname usecanonicalphysicalport user userdir virtualdocumentroot virtualdocumentrootip virtualscriptalias virtualscriptaliasip win32disableacceptex xbithack",literal:"on off"},c:[a.HCM,{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",b]},b,{cN:"tag",b:"</?",e:">"},a.QSM]}}(hljs);hljs.LANGUAGES.applescript=function(a){var b=a.inherit(a.QSM,{i:""});var e={cN:"title",b:a.UIR};var d={cN:"params",b:"\\(",e:"\\)",c:["self",a.CNM,b]};var c=[{cN:"comment",b:"--",e:"$",},{cN:"comment",b:"\\(\\*",e:"\\*\\)",c:["self",{b:"--",e:"$"}]},a.HCM];return{k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[b,a.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bWK:true,k:"on",i:"[${=;\\n]",c:[e,d]}].concat(c),i:"//"}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);hljs.LANGUAGES.asciidoc=function(a){return{c:[{cN:"comment",b:"^/{4,}\\n",e:"\\n/{4,}$",r:10},{cN:"comment",b:"^//",e:"$",r:0},{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"header",b:"^(={1,5}) .+?( \\1)?$",r:10},{cN:"header",b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$",r:10},{cN:"attribute",b:"^:.+?:",e:"\\s",eE:true,r:10},{cN:"attribute",b:"^\\[.+?\\]$",r:0},{cN:"blockquote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"label",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{cN:"horizontal_rule",b:"^'{4,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:true,c:[{b:"(link|image:?):",r:0},{cN:"link_url",b:"\\w",e:"[^\\[]+",r:0},{cN:"link_label",b:"\\[",e:"\\]",eB:true,eE:true,r:0}],r:10}]}}(hljs);hljs.LANGUAGES.avrasm=function(a){return{cI:true,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf"},c:[a.CBLCLM,{cN:"comment",b:";",e:"$"},a.CNM,a.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"label",b:"^[A-Za-z0-9_.$]+:"},{cN:"preprocessor",b:"#",e:"$"},{cN:"preprocessor",b:"\\.[a-zA-Z]+"},{cN:"localvars",b:"@[0-9]+"}]}}(hljs);hljs.LANGUAGES.axapta=function(a){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"{",i:":",k:"class interface",c:[{cN:"inheritance",bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]}]}}(hljs);hljs.LANGUAGES.bash=function(a){var c={cN:"variable",b:/\$[\w\d#@][\w\d_]*/};var b={cN:"variable",b:/\$\{(.*?)\}/};var e={cN:"string",b:/"/,e:/"/,c:[a.BE,c,b,{cN:"variable",b:/\$\(/,e:/\)/,c:a.BE}],r:0};var d={cN:"string",b:/'/,e:/'/,r:0};return{l:/-?[a-z]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[{cN:"title",b:/\w[\w\d_]*/}],r:0},a.HCM,a.NM,e,d,c,b]}}(hljs);hljs.LANGUAGES.brainfuck=function(a){return{c:[{cN:"comment",b:"[^\\[\\]\\.,\\+\\-<> \r\n]",eE:true,e:"[\\[\\]\\.,\\+\\-<> \r\n]",r:0},{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]"},{cN:"literal",b:"[\\+\\-]"}]}}(hljs);hljs.LANGUAGES.clojure=function(l){var e={built_in:"def cond apply if-not if-let if not not= = &lt; < > &lt;= <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for doseq dosync dotimes and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import intern refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! import use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if throw printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time ns assert re-find re-groups rand-int rand mod locking assert-valid-fdecl alias namespace resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! memfn to-array future future-call into-array aset gen-class reduce merge map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"};var f="[a-zA-Z_0-9\\!\\.\\?\\-\\+\\*\\/\\<\\=\\>\\&\\#\\$';]+";var a="[\\s:\\(\\{]+\\d+(\\.\\d+)?";var d={cN:"number",b:a,r:0};var j={cN:"string",b:'"',e:'"',c:[l.BE],r:0};var o={cN:"comment",b:";",e:"$",r:0};var n={cN:"collection",b:"[\\[\\{]",e:"[\\]\\}]"};var c={cN:"comment",b:"\\^"+f};var b={cN:"comment",b:"\\^\\{",e:"\\}"};var h={cN:"attribute",b:"[:]"+f};var m={cN:"list",b:"\\(",e:"\\)"};var g={eW:true,k:{literal:"true false nil"},r:0};var i={k:e,l:f,cN:"title",b:f,starts:g};m.c=[{cN:"comment",b:"comment"},i];g.c=[m,j,c,b,o,h,n,d];n.c=[m,j,c,o,h,n,d];return{i:"\\S",c:[o,m]}}(hljs);hljs.LANGUAGES.cmake=function(a){return{cI:true,k:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file",c:[{cN:"envvar",b:"\\${",e:"}"},a.HCM,a.QSM,a.NM]}}(hljs);hljs.LANGUAGES.coffeescript=function(c){var b={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module exports global window document"};var a="[A-Za-z$_][0-9A-Za-z$_]*";var f={cN:"title",b:a};var e={cN:"subst",b:"#\\{",e:"}",k:b,};var d=[c.BNM,c.inherit(c.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",b:"'''",e:"'''",c:[c.BE]},{cN:"string",b:"'",e:"'",c:[c.BE],r:0},{cN:"string",b:'"""',e:'"""',c:[c.BE,e]},{cN:"string",b:'"',e:'"',c:[c.BE,e],r:0},{cN:"regexp",b:"///",e:"///",c:[c.HCM]},{cN:"regexp",b:"//[gim]*",r:0},{cN:"regexp",b:"/\\S(\\\\.|[^\\n])*?/[gim]*(?=\\s|\\W|$)"},{cN:"property",b:"@"+a},{b:"`",e:"`",eB:true,eE:true,sL:"javascript"}];e.c=d;return{k:b,c:d.concat([{cN:"comment",b:"###",e:"###"},c.HCM,{cN:"function",b:"("+a+"\\s*=\\s*)?(\\(.*\\))?\\s*[-=]>",e:"[-=]>",rB:true,c:[f,{cN:"params",b:"\\(",rB:true,c:[{b:/\(/,e:/\)/,k:b,c:["self"].concat(d)}]}]},{cN:"class",bWK:true,k:"class",e:"$",i:"[:\\[\\]]",c:[{bWK:true,k:"extends",eW:true,i:":",c:[f]},f]},{cN:"attribute",b:a+":",e:":",rB:true,eE:true}])}}(hljs);hljs.LANGUAGES.cpp=function(a){var b={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long throw volatile static protected bool template mutable if public friend do return goto auto void enum else break new extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'\\\\?.",e:"'",i:"."},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},a.CNM,{cN:"preprocessor",b:"#",e:"$",c:[{b:"<",e:">",i:"\\n"},a.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,r:10,c:["self"]}]}}(hljs);hljs.LANGUAGES.cs=function(a){return{k:"abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async await ascending descending from get group into join let orderby partial select set value var where yield",c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"}]},a.CLCM,a.CBLCLM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},a.ASM,a.QSM,a.CNM]}}(hljs);hljs.LANGUAGES.css=function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.NM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}}(hljs);hljs.LANGUAGES.d=function(x){var b={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"};var c="(0|[1-9][\\d_]*)",q="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",h="0[bB][01_]+",v="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",y="0[xX]"+v,p="([eE][+-]?"+q+")",o="("+q+"(\\.\\d*|"+p+")|\\d+\\."+q+q+"|\\."+c+p+"?)",k="(0[xX]("+v+"\\."+v+"|\\.?"+v+")[pP][+-]?"+q+")",l="("+c+"|"+h+"|"+y+")",n="("+k+"|"+o+")";var z="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};";var m={cN:"number",b:"\\b"+l+"(L|u|U|Lu|LU|uL|UL)?",r:0};var j={cN:"number",b:"\\b("+n+"([fF]|L|i|[fF]i|Li)?|"+l+"(i|[fF]i|Li))",r:0};var s={cN:"string",b:"'("+z+"|.)",e:"'",i:"."};var r={b:z,r:0};var w={cN:"string",b:'"',c:[r],e:'"[cwd]?',r:0};var f={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5};var u={cN:"string",b:"`",e:"`[cwd]?"};var i={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10};var t={cN:"string",b:'q"\\{',e:'\\}"'};var e={cN:"shebang",b:"^#!",e:"$",r:5};var g={cN:"preprocessor",b:"#(line)",e:"$",r:5};var d={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"};var a={cN:"comment",b:"\\/\\+",c:["self"],e:"\\+\\/",r:10};return{l:x.UIR,k:b,c:[x.CLCM,x.CBLCLM,a,i,w,f,u,t,j,m,s,e,g,d]}}(hljs);hljs.LANGUAGES.delphi=function(b){var f="and safecall cdecl then string exports library not pascal set virtual file in array label packed end. index while const raise for to implementation with except overload destructor downto finally program exit unit inherited override if type until function do begin repeat goto nil far initialization object else var uses external resourcestring interface end finalization class asm mod case on shr shl of register xorwrite threadvar try record near stored constructor stdcall inline div out or procedure";var e="safecall stdcall pascal stored const implementation finalization except to finally program inherited override then exports string read not mod shr try div shl set library message packed index for near overload label downto exit public goto interface asm on of constructor or private array unit raise destructor var type until function else external with case default record while protected property procedure published and cdecl do threadvar file in if end virtual write far out begin repeat nil initialization object uses resourcestring class register xorwrite inline static";var a={cN:"comment",b:"{",e:"}",r:0};var g={cN:"comment",b:"\\(\\*",e:"\\*\\)",r:10};var c={cN:"string",b:"'",e:"'",c:[{b:"''"}],r:0};var d={cN:"string",b:"(#\\d+)+"};var h={cN:"function",bWK:true,e:"[:;]",k:"function constructor|10 destructor|10 procedure|10",c:[{cN:"title",b:b.IR},{cN:"params",b:"\\(",e:"\\)",k:f,c:[c,d]},a,g]};return{cI:true,k:f,i:'("|\\$[G-Zg-z]|\\/\\*|</)',c:[a,g,b.CLCM,c,d,b.NM,h,{cN:"class",b:"=\\bclass\\b",e:"end;",k:e,c:[c,d,a,g,b.CLCM,h]}]}}(hljs);hljs.LANGUAGES.diff=function(a){return{c:[{cN:"chunk",b:"^\\@\\@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +\\@\\@$",r:10},{cN:"chunk",b:"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$",r:10},{cN:"chunk",b:"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$",r:10},{cN:"header",b:"Index: ",e:"$"},{cN:"header",b:"=====",e:"=====$"},{cN:"header",b:"^\\-\\-\\-",e:"$"},{cN:"header",b:"^\\*{3} ",e:"$"},{cN:"header",b:"^\\+\\+\\+",e:"$"},{cN:"header",b:"\\*{5}",e:"\\*{5}$"},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}(hljs);hljs.LANGUAGES.django=function(c){function e(h,g){return(g==undefined||(!h.cN&&g.cN=="tag")||h.cN=="value")}function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}if(e(l,k)){m=b.concat(m)}if(m.length){g.c=m}}return g}var d={cN:"filter",b:"\\|[A-Za-z]+\\:?",k:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone",c:[{cN:"argument",b:'"',e:'"'}]};var b=[{cN:"template_comment",b:"{%\\s*comment\\s*%}",e:"{%\\s*endcomment\\s*%}"},{cN:"template_comment",b:"{#",e:"#}"},{cN:"template_tag",b:"{%",e:"%}",k:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor in ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup by as ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim",c:[d]},{cN:"variable",b:"{{",e:"}}",c:[d]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.dos=function(a){return{cI:true,k:{flow:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",keyword:"shift cd dir echo setlocal endlocal set pause copy",stream:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux",winutils:"ping net ipconfig taskkill xcopy ren del"},c:[{cN:"envvar",b:"%%[^ ]"},{cN:"envvar",b:"%[^ ]+?%"},{cN:"envvar",b:"![^ ]+?!"},{cN:"number",b:"\\b\\d+",r:0},{cN:"comment",b:"@?rem",e:"$"}]}}(hljs);hljs.LANGUAGES["erlang-repl"]=function(a){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},{cN:"comment",b:"%",e:"$"},{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a.ASM,a.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}}(hljs);hljs.LANGUAGES.erlang=function(i){var c="[a-z'][a-zA-Z0-9_']*";var o="("+c+":"+c+"|"+c+")";var f={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun let not of orelse|10 query receive rem try when xor",literal:"false true"};var l={cN:"comment",b:"%",e:"$",r:0};var e={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0};var g={b:"fun\\s+"+c+"/\\d+"};var n={b:o+"\\(",e:"\\)",rB:true,r:0,c:[{cN:"function_name",b:o,r:0},{b:"\\(",e:"\\)",eW:true,rE:true,r:0}]};var h={cN:"tuple",b:"{",e:"}",r:0};var a={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0};var m={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0};var b={b:"#",e:"}",i:".",r:0,rB:true,c:[{cN:"record_name",b:"#"+i.UIR,r:0},{b:"{",eW:true,r:0}]};var k={k:f,b:"(fun|receive|if|try|case)",e:"end"};k.c=[l,g,i.inherit(i.ASM,{cN:""}),k,n,i.QSM,e,h,a,m,b];var j=[l,g,k,n,i.QSM,e,h,a,m,b];n.c[1].c=j;h.c=j;b.c[1].c=j;var d={cN:"params",b:"\\(",e:"\\)",c:j};return{k:f,i:"(</|\\*=|\\+=|-=|/=|/\\*|\\*/|\\(\\*|\\*\\))",c:[{cN:"function",b:"^"+c+"\\s*\\(",e:"->",rB:true,i:"\\(|#|//|/\\*|\\\\|:",c:[d,{cN:"title",b:c}],starts:{e:";|\\.",k:f,c:j}},l,{cN:"pp",b:"^-",e:"\\.",r:0,eE:true,rB:true,l:"-"+i.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior",c:[d]},e,i.QSM,b,a,m,h]}}(hljs);hljs.LANGUAGES.fsharp=function(a){var b="'[a-zA-Z0-9_]+";return{k:"yield! return! let! do!abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun|10 function global if in inherit inline interface internal lazy let match member module mutable|10 namespace new null of open or override private public rec|10 return sig static struct then to true try type upcast use val void when while with yield",c:[{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},{cN:"comment",b:"//",e:"$",rB:true},{cN:"comment",b:"\\(\\*",e:"\\*\\)"},{cN:"class",bWK:true,e:"\\(|=|$",k:"type",c:[{cN:"title",b:a.UIR}]},{cN:"annotation",b:"\\[<",e:">\\]",r:10},{cN:"typeparam",b:"<",e:">",c:[{cN:"title",b:b}]},a.CLCM,a.CBLCLM,a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),a.CNM]}}(hljs);hljs.LANGUAGES.glsl=function(a){return{k:{keyword:"atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly",built_in:"gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffsetgl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse",literal:"true false"},i:'"',c:[a.CLCM,a.CBLCLM,a.CNM,{cN:"preprocessor",b:"#",e:"$"}]}}(hljs);hljs.LANGUAGES.go=function(a){var b={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer",constant:"true false iota nil",typename:"bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"string",b:"`",e:"`"},{cN:"number",b:"[^a-zA-Z_0-9](\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?",r:0},a.CNM]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.haml=function(a){return{cI:true,c:[{cN:"doctype",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},{cN:"comment",b:"^\\s*(-#|/).*$",r:0},{b:"^\\s*-(?!#)",starts:{e:"\\n",sL:"ruby"},r:0},{cN:"tag",b:"^\\s*%",c:[{cN:"title",b:"\\w+",r:0},{cN:"value",b:"[#\\.]\\w+",r:0},{b:"{\\s*",e:"\\s*}",eE:true,c:[{b:":\\w+\\s*=>",e:",\\s+",rB:true,eW:true,r:0,c:[{cN:"symbol",b:":\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0},{b:"\\(\\s*",e:"\\s*\\)",eE:true,c:[{b:"\\w+\\s*=",e:"\\s+",rB:true,eW:true,r:0,c:[{cN:"attribute",b:"\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0}],r:10},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"},r:0}]}}(hljs);hljs.LANGUAGES.handlebars=function(c){function f(l,k){var g={};for(var j in l){if(j!="contains"){g[j]=l[j]}var m=[];for(var h=0;l.c&&h<l.c.length;h++){m.push(f(l.c[h],l))}m=d.concat(m);if(m.length){g.c=m}}return g}var b="each in with if else unless bindattr action collection debugger log outlet template unbound view yield";var e={cN:"variable",b:"[a-zA-Z.]+",k:b};var d=[{cN:"expression",b:"{{",e:"}}",c:[{cN:"begin-block",b:"#[a-zA-Z .]+",k:b},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z .]+",k:b},{cN:"variable",b:"[a-zA-Z.]+",k:b}]}];var a=f(c.LANGUAGES.xml);a.cI=true;return a}(hljs);hljs.LANGUAGES.haskell=function(a){var d={cN:"type",b:"\\b[A-Z][\\w']*",r:0};var c={cN:"container",b:"\\(",e:"\\)",i:'"',c:[{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},{cN:"title",b:"[_a-z][\\w']*"}]};var b={cN:"container",b:"{",e:"}",c:c.c};return{k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance not as foreign ccall safe unsafe",c:[{cN:"comment",b:"--",e:"$"},{cN:"preprocessor",b:"{-#",e:"#-}"},{cN:"comment",c:["self"],b:"{-",e:"-}"},{cN:"string",b:"\\s+'",e:"'",c:[a.BE],r:0},a.QSM,{cN:"import",b:"\\bimport",e:"$",k:"import qualified as hiding",c:[c],i:"\\W\\.|;"},{cN:"module",b:"\\bmodule",e:"where",k:"module where",c:[c],i:"\\W\\.|;"},{cN:"class",b:"\\b(class|instance)",e:"where",k:"class where instance",c:[d]},{cN:"typedef",b:"\\b(data|(new)?type)",e:"$",k:"data type newtype deriving",c:[d,c,b]},a.CNM,{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},d,{cN:"title",b:"^[_a-z][\\w']*"},{b:"->|<-"}]}}(hljs);hljs.LANGUAGES.http=function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}}(hljs);hljs.LANGUAGES.ini=function(a){return{cI:true,i:"[^\\s]",c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:"on off true false yes no",c:[a.QSM,a.NM],r:0}]}]}}(hljs);hljs.LANGUAGES.java=function(a){return{k:"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,{cN:"class",bWK:true,e:"{",k:"class interface",eE:true,i:":",c:[{bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]},a.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}}(hljs);hljs.LANGUAGES.javascript=function(a){return{k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const",literal:"true false null undefined NaN Infinity"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,a.REGEXP_MODE,{b:/</,e:/>;/,sL:"xml"}],r:0},{cN:"function",bWK:true,e:/{/,k:"function",c:[{cN:"title",b:/[A-Za-z$_][0-9A-Za-z$_]*/},{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBLCLM],i:/["'\(]/}],i:/\[|%/}]}}(hljs);hljs.LANGUAGES.json=function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}}(hljs);hljs.LANGUAGES.lasso=function(b){var a="[a-zA-Z_][a-zA-Z0-9_.]*|&[lg]t;";var c="<\\?(lasso(script)?|=)";return{cI:true,l:a,k:{literal:"true false none minimal full all infinity nan and or not bw ew cn lt lte gt gte eq neq ft rx nrx",built_in:"array date decimal duration integer map pair string tag xml null list queue set stack staticarray local var variable data global self inherited void",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require skip split_thread sum take thread to trait type where with yield"},c:[{cN:"preprocessor",b:"\\]|\\?>",r:0,starts:{cN:"markup",e:"\\[|"+c,rE:true}},{cN:"preprocessor",b:"\\[noprocess\\]",starts:{cN:"markup",e:"\\[/noprocess\\]",rE:true}},{cN:"preprocessor",b:"\\[no_square_brackets|\\[/noprocess|"+c},{cN:"preprocessor",b:"\\[",r:0},{cN:"shebang",b:"^#!.+lasso9\\b",r:10},b.CLCM,{cN:"javadoc",b:"/\\*\\*!",e:"\\*/"},b.CBLCLM,b.CNM,b.inherit(b.ASM,{i:null}),b.inherit(b.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{cN:"variable",b:"#\\d+|[#$]"+a},{cN:"tag",b:"::",e:a},{cN:"attribute",b:"\\.\\.\\.|-"+b.UIR},{cN:"class",bWK:true,k:"define",eE:true,e:"\\(|=>",c:[{cN:"title",b:b.UIR+"=?"}]}]}}(hljs);hljs.LANGUAGES.lisp=function(i){var l="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*";var m="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?";var k={cN:"shebang",b:"^#!",e:"$"};var a={cN:"literal",b:"\\b(t{1}|nil)\\b"};var d=[{cN:"number",b:m},{cN:"number",b:"#b[0-1]+(/[0-1]+)?"},{cN:"number",b:"#o[0-7]+(/[0-7]+)?"},{cN:"number",b:"#x[0-9a-f]+(/[0-9a-f]+)?"},{cN:"number",b:"#c\\("+m+" +"+m,e:"\\)"}];var h={cN:"string",b:'"',e:'"',c:[i.BE],r:0};var n={cN:"comment",b:";",e:"$"};var g={cN:"variable",b:"\\*",e:"\\*"};var o={cN:"keyword",b:"[:&]"+l};var b={b:"\\(",e:"\\)",c:["self",a,h].concat(d)};var e={cN:"quoted",b:"['`]\\(",e:"\\)",c:d.concat([h,g,o,b])};var c={cN:"quoted",b:"\\(quote ",e:"\\)",k:{title:"quote"},c:d.concat([h,g,o,b])};var j={cN:"list",b:"\\(",e:"\\)"};var f={eW:true,r:0};j.c=[{cN:"title",b:l},f];f.c=[e,c,j,a].concat(d).concat([h,n,g,o]);return{i:"[^\\s]",c:d.concat([k,a,h,n,e,c,j])}}(hljs);hljs.LANGUAGES.lua=function(b){var a="\\[=*\\[";var e="\\]=*\\]";var c={b:a,e:e,c:["self"]};var d=[{cN:"comment",b:"--(?!"+a+")",e:"$"},{cN:"comment",b:"--"+a,e:e,c:[c],r:10}];return{l:b.UIR,k:{keyword:"and break do else elseif end false for if in local nil not or repeat return then true until while",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},c:d.concat([{cN:"function",bWK:true,e:"\\)",k:"function",c:[{cN:"title",b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"},{cN:"params",b:"\\(",eW:true,c:d}].concat(d)},b.CNM,b.ASM,b.QSM,{cN:"string",b:a,e:e,c:[c],r:10}])}}(hljs);hljs.LANGUAGES.markdown=function(a){return{c:[{cN:"header",b:"^#{1,3}",e:"$"},{cN:"header",b:"^.+?\\n[=-]{2,}$"},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",b:"\\*.+?\\*"},{cN:"emphasis",b:"_.+?_",r:0},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",b:"`.+?`"},{cN:"code",b:"^    ",e:"$",r:0},{cN:"horizontal_rule",b:"^-{3,}",e:"$"},{b:"\\[.+?\\]\\(.+?\\)",rB:true,c:[{cN:"link_label",b:"\\[.+\\]"},{cN:"link_url",b:"\\(",e:"\\)",eB:true,eE:true}]}]}}(hljs);hljs.LANGUAGES.matlab=function(a){var b=[a.CNM,{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0}];return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bWK:true,e:"$",k:"function",c:[{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)"},{cN:"params",b:"\\[",e:"\\]"}]},{cN:"transposed_variable",b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:""},{cN:"matrix",b:"\\[",e:"\\]'*[\\.']*",c:b},{cN:"cell",b:"\\{",e:"\\}'*[\\.']*",c:b},{cN:"comment",b:"\\%",e:"$"}].concat(b)}}(hljs);hljs.LANGUAGES.mel=function(a){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:"</",c:[a.CNM,a.ASM,a.QSM,{cN:"string",b:"`",e:"`",c:[a.BE]},{cN:"variable",b:"\\$\\d",r:5},{cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+|[^\\s\\w{]|{\\w+}|\\w+)"},a.CLCM,a.CBLCLM]}}(hljs);hljs.LANGUAGES.mizar=function(a){return{k:["environ vocabularies notations constructors definitions registrations theorems schemes requirements","begin end definition registration cluster existence pred func defpred deffunc theorem proof","let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from","be being by means equals implies iff redefine define now not or attr is mode suppose per cases set","thesis contradiction scheme reserve struct","correctness compatibility coherence symmetry assymetry reflexivity irreflexivity","connectedness uniqueness commutativity idempotence involutiveness projectivity"].join(" "),c:[{cN:"comment",b:"::",e:"$"}]}}(hljs);hljs.LANGUAGES.nginx=function(b){var c=[{cN:"variable",b:"\\$\\d+"},{cN:"variable",b:"\\${",e:"}"},{cN:"variable",b:"[\\$\\@]"+b.UIR}];var a={eW:true,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[b.HCM,{cN:"string",b:'"',e:'"',c:[b.BE].concat(c),r:0},{cN:"string",b:"'",e:"'",c:[b.BE].concat(c),r:0},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:true,eE:true},{cN:"regexp",b:"\\s\\^",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"~\\*?\\s+",e:"\\s|{|;",rE:true,c:[b.BE].concat(c)},{cN:"regexp",b:"\\*(\\.[a-z\\-]+)+",c:[b.BE].concat(c)},{cN:"regexp",b:"([a-z\\-]+\\.)+\\*",c:[b.BE].concat(c)},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0}].concat(c)};return{c:[b.HCM,{b:b.UIR+"\\s",e:";|{",rB:true,c:[{cN:"title",b:b.UIR,starts:a}],r:0}],i:"[^\\s\\}]"}}(hljs);hljs.LANGUAGES.objectivec=function(a){var b={keyword:"int float while private char catch export sizeof typedef const struct for union unsigned long volatile static protected bool mutable if public do return goto void enum else break extern asm case short default double throw register explicit signed typename try this switch continue wchar_t inline readonly assign property self synchronized end synthesize id optional required nonatomic super unichar finally dynamic IBOutlet IBAction selector strong weak readonly",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection UIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.CNM,a.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"preprocessor",b:"#import",e:"$",c:[{cN:"title",b:'"',e:'"'},{cN:"title",b:"<",e:">"}]},{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bWK:true,e:"({|$)",k:"interface class protocol implementation",c:[{cN:"id",b:a.UIR}]},{cN:"variable",b:"\\."+a.UIR,r:0}]}}(hljs);hljs.LANGUAGES.parser3=function(a){return{sL:"xml",r:0,c:[{cN:"comment",b:"^#",e:"$"},{cN:"comment",b:"\\^rem{",e:"}",r:10,c:[{b:"{",e:"}",c:["self"]}]},{cN:"preprocessor",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},a.CNM]}}(hljs);hljs.LANGUAGES.perl=function(e){var a="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when";var d={cN:"subst",b:"[$@]\\{",e:"\\}",k:a,r:10};var b={cN:"variable",b:"\\$\\d"};var i={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var f=[e.BE,d,b,i];var h={b:"->",c:[{b:e.IR},{b:"{",e:"}"}]};var g={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5};var c=[b,i,e.HCM,g,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:true},h,{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:f,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:f,r:5},{cN:"string",b:"'",e:"'",c:[e.BE],r:0},{cN:"string",b:'"',e:'"',c:f,r:0},{cN:"string",b:"`",e:"`",c:[e.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"("+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,g,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bWK:true,e:"(\\s*\\(.*?\\))?[;{]",k:"sub",r:5},{cN:"operator",b:"-\\w\\b",r:0}];d.c=c;h.c[1].c=c;return{k:a,c:c}}(hljs);hljs.LANGUAGES.php=function(a){var e={cN:"variable",b:"\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"};var b=[a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),{cN:"string",b:'b"',e:'"',c:[a.BE]},{cN:"string",b:"b'",e:"'",c:[a.BE]}];var c=[a.BNM,a.CNM];var d={cN:"title",b:a.UIR};return{cI:true,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return implements parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception php_user_filter default die require __FUNCTION__ enddeclare final try this switch continue endfor endif declare unset true false namespace trait goto instanceof insteadof __DIR__ __NAMESPACE__ __halt_compiler",c:[a.CLCM,a.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"}]},{cN:"comment",eB:true,b:"__halt_compiler.+?;",eW:true},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[a.BE]},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"},e,{cN:"function",bWK:true,e:"{",k:"function",i:"\\$|\\[|%",c:[d,{cN:"params",b:"\\(",e:"\\)",c:["self",e,a.CBLCLM].concat(b).concat(c)}]},{cN:"class",bWK:true,e:"{",k:"class",i:"[:\\(\\$]",c:[{bWK:true,eW:true,k:"extends",c:[d]},d]},{b:"=>"}].concat(b).concat(c)}}(hljs);hljs.LANGUAGES.profile=function(a){return{c:[a.CNM,{cN:"built_in",b:"{",e:"}$",eB:true,eE:true,c:[a.ASM,a.QSM],r:0},{cN:"filename",b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:true},{cN:"header",b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{cN:"summary",b:"function calls",e:"$",c:[a.CNM],r:10},a.ASM,a.QSM,{cN:"function",b:"\\(",e:"\\)$",c:[{cN:"title",b:a.UIR,r:0}],r:0}]}}(hljs);hljs.LANGUAGES.python=function(a){var f={cN:"prompt",b:/^(>>>|\.\.\.) /};var c=[{cN:"string",b:/(u|b)?r?'''/,e:/'''/,c:[f],r:10},{cN:"string",b:/(u|b)?r?"""/,e:/"""/,c:[f],r:10},{cN:"string",b:/(u|r|ur)'/,e:/'/,c:[a.BE],r:10},{cN:"string",b:/(u|r|ur)"/,e:/"/,c:[a.BE],r:10},{cN:"string",b:/(b|br)'/,e:/'/,c:[a.BE]},{cN:"string",b:/(b|br)"/,e:/"/,c:[a.BE]}].concat([a.ASM,a.QSM]);var e={cN:"title",b:a.UIR};var d={cN:"params",b:/\(/,e:/\)/,c:["self",a.CNM,f].concat(c)};var b={bWK:true,e:/:/,i:/[${=;\n]/,c:[e,d],r:10};return{k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10",built_in:"None True False Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:c.concat([f,a.HCM,a.inherit(b,{cN:"function",k:"def"}),a.inherit(b,{cN:"class",k:"class"}),a.CNM,{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}])}}(hljs);hljs.LANGUAGES.r=function(a){var b="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[a.HCM,{b:b,l:b,k:{keyword:"function if in break next repeat else for return switch while try tryCatch|10 stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...|10",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",b:'"',e:'"',c:[a.BE],r:0},{cN:"string",b:"'",e:"'",c:[a.BE],r:0}]}}(hljs);hljs.LANGUAGES.rib=function(a){return{k:"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd",i:"</",c:[a.HCM,a.CNM,a.ASM,a.QSM]}}(hljs);hljs.LANGUAGES.rsl=function(a){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,a.ASM,a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"shader",bWK:true,e:"\\(",k:"surface displacement light volume imager"},{cN:"shading",bWK:true,e:"\\(",k:"illuminate illuminance gather"}]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.ruleslanguage=function(a){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEMASK|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN DELETE SAVE SAVE_UPDATE CLEAR DETERMINANT LABEL REPORT REVENUE ABORT CALL DONE LEAVE EACH IN LIST NOVALUE FROM TOTAL CHARGE BLOCK AND OR CSV_FILE BILL_PERIOD RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM ABORT WARN NUMDAYS RATE_CODE READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}}(hljs);hljs.LANGUAGES.rust=function(b){var d={cN:"title",b:b.UIR};var c={cN:"number",b:"\\b(0[xb][A-Za-z0-9_]+|[0-9_]+(\\.[0-9_]+)?([uif](8|16|32|64)?)?)",r:0};var a="assert bool break char check claim comm const cont copy dir do drop else enum extern export f32 f64 fail false float fn for i16 i32 i64 i8 if impl int let log loop match mod move mut priv pub pure ref return self static str struct task true trait type u16 u32 u64 u8 uint unsafe use vec while";return{k:a,i:"</",c:[b.CLCM,b.CBLCLM,b.inherit(b.QSM,{i:null}),b.ASM,c,{cN:"function",bWK:true,e:"(\\(|<)",k:"fn",c:[d]},{cN:"preprocessor",b:"#\\[",e:"\\]"},{bWK:true,e:"(=|<)",k:"type",c:[d],i:"\\S"},{bWK:true,e:"({|<)",k:"trait enum",c:[d],i:"\\S"}]}}(hljs);hljs.LANGUAGES.scala=function(a){var c={cN:"annotation",b:"@[A-Za-z]+"};var b={cN:"string",b:'u?r?"""',e:'"""',r:10};return{k:"type yield lazy override def with val var false true sealed abstract private trait object null if for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,b,{cN:"class",b:"((case )?class |object |trait )",e:"({|$)",i:":",k:"case class trait object",c:[{bWK:true,k:"extends with",r:10},{cN:"title",b:a.UIR},{cN:"params",b:"\\(",e:"\\)",c:[a.ASM,a.QSM,b,c]}]},a.CNM,c]}}(hljs);hljs.LANGUAGES.scss=function(a){var c="[a-zA-Z-][a-zA-Z0-9_-]*";var d={cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};var b={cN:"hexcolor",b:"#[0-9A-Fa-f]+"};var e={cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[d,b,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"important",b:"!important"}]}};return{cI:true,i:"[=/|']",c:[a.CLCM,a.CBLCLM,{cN:"function",b:c+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]},{cN:"id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{cN:"pseudo",b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{cN:"pseudo",b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{cN:"value",b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{cN:"value",b:":",e:";",c:[b,a.NM,a.QSM,a.ASM,{cN:"important",b:"!important"}]},{cN:"at_rule",b:"@",e:"[{;]",k:"mixin include for extend charset import media page font-face namespace",c:[d,a.QSM,a.ASM,b,a.NM,{cN:"preprocessor",b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}}(hljs);hljs.LANGUAGES.smalltalk=function(a){var b="[a-z][a-zA-Z0-9_]*";var d={cN:"char",b:"\\$.{1}"};var c={cN:"symbol",b:"#"+a.UIR};return{k:"self super nil true false thisContext",c:[{cN:"comment",b:'"',e:'"',r:0},a.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:b+":"},a.CNM,c,d,{cN:"localvars",b:"\\|\\s*"+b+"(\\s+"+b+")*\\s*\\|"},{cN:"array",b:"\\#\\(",e:"\\)",c:[a.ASM,d,a.CNM,c]}]}}(hljs);hljs.LANGUAGES.sql=function(a){return{cI:true,c:[{cN:"operator",b:"(begin|end|start|commit|rollback|savepoint|lock|alter|create|drop|rename|call|delete|do|handler|insert|load|replace|select|truncate|update|set|show|pragma|grant)\\b(?!:)",e:";",eW:true,k:{keyword:"all partial global month current_timestamp using go revoke smallint indicator end-exec disconnect zone with character assertion to add current_user usage input local alter match collate real then rollback get read timestamp session_user not integer bit unique day minute desc insert execute like ilike|2 level decimal drop continue isolation found where constraints domain right national some module transaction relative second connect escape close system_user for deferred section cast current sqlstate allocate intersect deallocate numeric public preserve full goto initially asc no key output collation group by union session both last language constraint column of space foreign deferrable prior connection unknown action commit view or first into float year primary cascaded except restrict set references names table outer open select size are rows from prepare distinct leading create only next inner authorization schema corresponding option declare precision immediate else timezone_minute external varying translation true case exception join hour default double scroll value cursor descriptor values dec fetch procedure delete and false int is describe char as at in varchar null trailing any absolute current_time end grant privileges when cross check write current_date pad begin temporary exec time update catalog user sql date on identity timezone_hour natural whenever interval work order cascade diagnostics nchar having left call do handler load replace truncate start lock show pragma exists number trigger if before after each row",aggregate:"count sum min max avg"},c:[{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0},{cN:"string",b:'"',e:'"',c:[a.BE,{b:'""'}],r:0},{cN:"string",b:"`",e:"`",c:[a.BE]},a.CNM]},a.CBLCLM,{cN:"comment",b:"--",e:"$"}]}}(hljs);hljs.LANGUAGES.tex=function(a){var d={cN:"command",b:"\\\\[a-zA-Zа-яА-я]+[\\*]?"};var c={cN:"command",b:"\\\\[^a-zA-Zа-яА-я0-9]"};var b={cN:"special",b:"[{}\\[\\]\\&#~]",r:0};return{c:[{b:"\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",rB:true,c:[d,c,{cN:"number",b:" *=",e:"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",eB:true}],r:10},d,c,b,{cN:"formula",b:"\\$\\$",e:"\\$\\$",c:[d,c,b],r:0},{cN:"formula",b:"\\$",e:"\\$",c:[d,c,b],r:0},{cN:"comment",b:"%",e:"$",r:0}]}}(hljs);hljs.LANGUAGES.vala=function(a){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object",literal:"false true null"},c:[{cN:"class",bWK:true,e:"{",k:"class interface delegate namespace",i:"[^,:\\n\\s\\.]",c:[{cN:"title",b:a.UIR}]},a.CLCM,a.CBLCLM,{cN:"string",b:'"""',e:'"""',r:5},a.ASM,a.QSM,a.CNM,{cN:"preprocessor",b:"^#",e:"$",r:2},{cN:"constant",b:" [A-Z_]+ ",r:0}]}}(hljs);hljs.LANGUAGES.vbnet=function(a){return{cI:true,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"(//|endif|gosub|variant|wend)",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"'''|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"},]},a.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end region externalsource"},]}}(hljs);hljs.LANGUAGES.vbscript=function(a){return{cI:true,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[a.inherit(a.QSM,{c:[{b:'""'}]}),{cN:"comment",b:"'",e:"$"},a.CNM]}}(hljs);hljs.LANGUAGES.vhdl=function(a){return{cI:true,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",typename:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[a.CBLCLM,{cN:"comment",b:"--",e:"$"},a.QSM,a.CNM,{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[a.BE]},{cN:"attribute",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[a.BE]}]}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",r:0,c:[{cN:"title",b:"[^ /><]+"},b]}]}}(hljs);
diff --git a/docs/slides/plpv14/reveal.js/plugin/leap/leap.js b/docs/slides/plpv14/reveal.js/plugin/leap/leap.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/leap/leap.js
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2013, Leap Motion, Inc.
+ * 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 HOLDER 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.
+ *
+ * Version 0.2.0 - http://js.leapmotion.com/0.2.0/leap.min.js
+ * Grab latest versions from http://js.leapmotion.com/
+ */
+
+!function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i}({1:[function(require,module,exports){var chooseProtocol=require("./protocol").chooseProtocol,EventEmitter=require("events").EventEmitter,_=require("underscore");var BaseConnection=module.exports=function(opts){this.opts=_.defaults(opts||{},{host:"127.0.0.1",enableGestures:false,port:6437,enableHeartbeat:true,heartbeatInterval:100,requestProtocolVersion:3});this.host=opts.host;this.port=opts.port;this.on("ready",function(){this.enableGestures(this.opts.enableGestures);if(this.opts.enableHeartbeat)this.startHeartbeat()});this.on("disconnect",function(){if(this.opts.enableHeartbeat)this.stopHeartbeat()});this.heartbeatTimer=null};BaseConnection.prototype.getUrl=function(){return"ws://"+this.host+":"+this.port+"/v"+this.opts.requestProtocolVersion+".json"};BaseConnection.prototype.sendHeartbeat=function(){if(this.protocol){this.setHeartbeatState(true);this.protocol.sendHeartbeat(this)}};BaseConnection.prototype.handleOpen=function(){this.emit("connect")};BaseConnection.prototype.enableGestures=function(enabled){this.gesturesEnabled=enabled?true:false;this.send(this.protocol.encode({enableGestures:this.gesturesEnabled}))};BaseConnection.prototype.handleClose=function(){this.disconnect();this.startReconnection()};BaseConnection.prototype.startReconnection=function(){var connection=this;setTimeout(function(){connection.connect()},1e3)};BaseConnection.prototype.disconnect=function(){if(!this.socket)return;this.socket.close();delete this.socket;delete this.protocol;this.emit("disconnect")};BaseConnection.prototype.handleData=function(data){var message=JSON.parse(data);var messageEvent;if(this.protocol===undefined){messageEvent=this.protocol=chooseProtocol(message);this.emit("ready")}else{messageEvent=this.protocol(message)}this.emit(messageEvent.type,messageEvent)};BaseConnection.prototype.connect=function(){if(this.socket)return;this.socket=this.setupSocket();return true};BaseConnection.prototype.send=function(data){this.socket.send(data)};BaseConnection.prototype.stopHeartbeat=function(){if(!this.heartbeatTimer)return;clearInterval(this.heartbeatTimer);delete this.heartbeatTimer;this.setHeartbeatState(false)};BaseConnection.prototype.setHeartbeatState=function(state){if(this.heartbeatState===state)return;this.heartbeatState=state;this.emit(this.heartbeatState?"focus":"blur")};_.extend(BaseConnection.prototype,EventEmitter.prototype)},{"./protocol":12,events:17,underscore:20}],2:[function(require,module,exports){var CircularBuffer=module.exports=function(size){this.pos=0;this._buf=[];this.size=size};CircularBuffer.prototype.get=function(i){if(i==undefined)i=0;if(i>=this.size)return undefined;if(i>=this._buf.length)return undefined;return this._buf[(this.pos-i-1)%this.size]};CircularBuffer.prototype.push=function(o){this._buf[this.pos%this.size]=o;return this.pos++}},{}],3:[function(require,module,exports){var Connection=module.exports=require("./base_connection");Connection.prototype.setupSocket=function(){var connection=this;var socket=new WebSocket(this.getUrl());socket.onopen=function(){connection.handleOpen()};socket.onmessage=function(message){connection.handleData(message.data)};socket.onclose=function(){connection.handleClose()};return socket};Connection.prototype.startHeartbeat=function(){if(!this.protocol.sendHeartbeat||this.heartbeatTimer)return;var connection=this;var propertyName=null;if(typeof document.hidden!=="undefined"){propertyName="hidden"}else if(typeof document.mozHidden!=="undefined"){propertyName="mozHidden"}else if(typeof document.msHidden!=="undefined"){propertyName="msHidden"}else if(typeof document.webkitHidden!=="undefined"){propertyName="webkitHidden"}else{propertyName=undefined}var windowVisible=true;var focusListener=window.addEventListener("focus",function(e){windowVisible=true});var blurListener=window.addEventListener("blur",function(e){windowVisible=false});this.on("disconnect",function(){if(connection.heartbeatTimer){clearTimeout(connection.heartbeatTimer);delete connection.heartbeatTimer}window.removeEventListener(focusListener);window.removeEventListener(blurListener)});this.heartbeatTimer=setInterval(function(){var isVisible=propertyName===undefined?true:document[propertyName]===false;if(isVisible&&windowVisible){connection.sendHeartbeat()}else{connection.setHeartbeatState(false)}},this.opts.heartbeatInterval)}},{"./base_connection":1}],4:[function(require,module,exports){!function(process){var Frame=require("./frame"),CircularBuffer=require("./circular_buffer"),Pipeline=require("./pipeline"),EventEmitter=require("events").EventEmitter,gestureListener=require("./gesture").gestureListener,_=require("underscore");var Controller=module.exports=function(opts){var inNode=typeof process!=="undefined"&&process.title==="node";opts=_.defaults(opts||{},{inNode:inNode});this.inNode=opts.inNode;opts=_.defaults(opts||{},{frameEventName:this.useAnimationLoop()?"animationFrame":"deviceFrame",supressAnimationLoop:false});this.supressAnimationLoop=opts.supressAnimationLoop;this.frameEventName=opts.frameEventName;this.history=new CircularBuffer(200);this.lastFrame=Frame.Invalid;this.lastValidFrame=Frame.Invalid;this.lastConnectionFrame=Frame.Invalid;this.accumulatedGestures=[];if(opts.connectionType===undefined){this.connectionType=this.inBrowser()?require("./connection"):require("./node_connection")}else{this.connectionType=opts.connectionType}this.connection=new this.connectionType(opts);this.setupConnectionEvents()};Controller.prototype.gesture=function(type,cb){var creator=gestureListener(this,type);if(cb!==undefined){creator.stop(cb)}return creator};Controller.prototype.inBrowser=function(){return!this.inNode};Controller.prototype.useAnimationLoop=function(){return this.inBrowser()&&typeof chrome==="undefined"};Controller.prototype.connect=function(){var controller=this;if(this.connection.connect()&&this.inBrowser()&&!controller.supressAnimationLoop){var callback=function(){controller.emit("animationFrame",controller.lastConnectionFrame);window.requestAnimFrame(callback)};window.requestAnimFrame(callback)}};Controller.prototype.disconnect=function(){this.connection.disconnect()};Controller.prototype.frame=function(num){return this.history.get(num)||Frame.Invalid};Controller.prototype.loop=function(callback){switch(callback.length){case 1:this.on(this.frameEventName,callback);break;case 2:var controller=this;var scheduler=null;var immediateRunnerCallback=function(frame){callback(frame,function(){if(controller.lastFrame!=frame){immediateRunnerCallback(controller.lastFrame)}else{controller.once(controller.frameEventName,immediateRunnerCallback)}})};this.once(this.frameEventName,immediateRunnerCallback);break}this.connect()};Controller.prototype.addStep=function(step){if(!this.pipeline)this.pipeline=new Pipeline(this);this.pipeline.addStep(step)};Controller.prototype.processFrame=function(frame){if(frame.gestures){this.accumulatedGestures=this.accumulatedGestures.concat(frame.gestures)}if(this.pipeline){frame=this.pipeline.run(frame);if(!frame)frame=Frame.Invalid}this.lastConnectionFrame=frame;this.emit("deviceFrame",frame)};Controller.prototype.processFinishedFrame=function(frame){this.lastFrame=frame;if(frame.valid){this.lastValidFrame=frame}frame.controller=this;frame.historyIdx=this.history.push(frame);if(frame.gestures){frame.gestures=this.accumulatedGestures;this.accumulatedGestures=[];for(var gestureIdx=0;gestureIdx!=frame.gestures.length;gestureIdx++){this.emit("gesture",frame.gestures[gestureIdx],frame)}}this.emit("frame",frame)};Controller.prototype.setupConnectionEvents=function(){var controller=this;this.connection.on("frame",function(frame){controller.processFrame(frame)});this.on(this.frameEventName,function(frame){controller.processFinishedFrame(frame)});this.connection.on("disconnect",function(){controller.emit("disconnect")});this.connection.on("ready",function(){controller.emit("ready")});this.connection.on("connect",function(){controller.emit("connect")});this.connection.on("focus",function(){controller.emit("focus")});this.connection.on("blur",function(){controller.emit("blur")});this.connection.on("protocol",function(protocol){controller.emit("protocol",protocol)});this.connection.on("deviceConnect",function(evt){controller.emit(evt.state?"deviceConnected":"deviceDisconnected")})};_.extend(Controller.prototype,EventEmitter.prototype)}(require("__browserify_process"))},{"./circular_buffer":2,"./connection":3,"./frame":5,"./gesture":6,"./node_connection":16,"./pipeline":10,__browserify_process:18,events:17,underscore:20}],5:[function(require,module,exports){var Hand=require("./hand"),Pointable=require("./pointable"),createGesture=require("./gesture").createGesture,glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,InteractionBox=require("./interaction_box"),_=require("underscore");var Frame=module.exports=function(data){this.valid=true;this.id=data.id;this.timestamp=data.timestamp;this.hands=[];this.handsMap={};this.pointables=[];this.tools=[];this.fingers=[];if(data.interactionBox){this.interactionBox=new InteractionBox(data.interactionBox)}this.gestures=[];this.pointablesMap={};this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.data=data;this.type="frame";this.currentFrameRate=data.currentFrameRate;var handMap={};for(var handIdx=0,handCount=data.hands.length;handIdx!=handCount;handIdx++){var hand=new Hand(data.hands[handIdx]);hand.frame=this;this.hands.push(hand);this.handsMap[hand.id]=hand;handMap[hand.id]=handIdx}for(var pointableIdx=0,pointableCount=data.pointables.length;pointableIdx!=pointableCount;pointableIdx++){var pointable=new Pointable(data.pointables[pointableIdx]);pointable.frame=this;this.pointables.push(pointable);this.pointablesMap[pointable.id]=pointable;(pointable.tool?this.tools:this.fingers).push(pointable);if(pointable.handId!==undefined&&handMap.hasOwnProperty(pointable.handId)){var hand=this.hands[handMap[pointable.handId]];hand.pointables.push(pointable);(pointable.tool?hand.tools:hand.fingers).push(pointable)}}if(data.gestures){for(var gestureIdx=0,gestureCount=data.gestures.length;gestureIdx!=gestureCount;gestureIdx++){this.gestures.push(createGesture(data.gestures[gestureIdx]))}}};Frame.prototype.tool=function(id){var pointable=this.pointable(id);return pointable.tool?pointable:Pointable.Invalid};Frame.prototype.pointable=function(id){return this.pointablesMap[id]||Pointable.Invalid};Frame.prototype.finger=function(id){var pointable=this.pointable(id);return!pointable.tool?pointable:Pointable.Invalid};Frame.prototype.hand=function(id){return this.handsMap[id]||Hand.Invalid};Frame.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Frame.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceFrame._rotation[5],this._rotation[2]-sinceFrame._rotation[6],this._rotation[3]-sinceFrame._rotation[1]])};Frame.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);return mat3.multiply(mat3.create(),sinceFrame._rotation,transpose)};Frame.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;return Math.exp(this._scaleFactor-sinceFrame._scaleFactor)};Frame.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();return vec3.subtract(vec3.create(),this._translation,sinceFrame._translation)};Frame.prototype.toString=function(){var str="Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")";if(this.gestures)str+=" | Gesture count:("+this.gestures.length+")";str+=" ]";return str};Frame.prototype.dump=function(){var out="";out+="Frame Info:<br/>";out+=this.toString();out+="<br/><br/>Hands:<br/>";for(var handIdx=0,handCount=this.hands.length;handIdx!=handCount;handIdx++){out+="  "+this.hands[handIdx].toString()+"<br/>"}out+="<br/><br/>Pointables:<br/>";for(var pointableIdx=0,pointableCount=this.pointables.length;pointableIdx!=pointableCount;pointableIdx++){out+="  "+this.pointables[pointableIdx].toString()+"<br/>"}if(this.gestures){out+="<br/><br/>Gestures:<br/>";for(var gestureIdx=0,gestureCount=this.gestures.length;gestureIdx!=gestureCount;gestureIdx++){out+="  "+this.gestures[gestureIdx].toString()+"<br/>"}}out+="<br/><br/>Raw JSON:<br/>";out+=JSON.stringify(this.data);return out};Frame.Invalid={valid:false,hands:[],fingers:[],tools:[],gestures:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},hand:function(){return Hand.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"gl-matrix":19,underscore:20}],6:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3,EventEmitter=require("events").EventEmitter,_=require("underscore");var createGesture=exports.createGesture=function(data){var gesture;switch(data.type){case"circle":gesture=new CircleGesture(data);break;case"swipe":gesture=new SwipeGesture(data);break;case"screenTap":gesture=new ScreenTapGesture(data);break;case"keyTap":gesture=new KeyTapGesture(data);break;default:throw"unkown gesture type"}gesture.id=data.id;gesture.handIds=data.handIds;gesture.pointableIds=data.pointableIds;gesture.duration=data.duration;gesture.state=data.state;gesture.type=data.type;return gesture};var gestureListener=exports.gestureListener=function(controller,type){var handlers={};var gestureMap={};var gestureCreator=function(){var candidateGesture=gestureMap[gesture.id];if(candidateGesture!==undefined)gesture.update(gesture,frame);if(gesture.state=="start"||gesture.state=="stop"){if(type==gesture.type&&gestureMap[gesture.id]===undefined){gestureMap[gesture.id]=new Gesture(gesture,frame);gesture.update(gesture,frame)}if(gesture.state=="stop"){delete gestureMap[gesture.id]}}};controller.on("gesture",function(gesture,frame){if(gesture.type==type){if(gesture.state=="start"||gesture.state=="stop"){if(gestureMap[gesture.id]===undefined){var gestureTracker=new Gesture(gesture,frame);gestureMap[gesture.id]=gestureTracker;_.each(handlers,function(cb,name){gestureTracker.on(name,cb)})}}gestureMap[gesture.id].update(gesture,frame);if(gesture.state=="stop"){delete gestureMap[gesture.id]}}});var builder={start:function(cb){handlers["start"]=cb;return builder},stop:function(cb){handlers["stop"]=cb;return builder},complete:function(cb){handlers["stop"]=cb;return builder},update:function(cb){handlers["update"]=cb;return builder}};return builder};var Gesture=exports.Gesture=function(gesture,frame){this.gestures=[gesture];this.frames=[frame]};Gesture.prototype.update=function(gesture,frame){this.gestures.push(gesture);this.frames.push(frame);this.emit(gesture.state,this)};_.extend(Gesture.prototype,EventEmitter.prototype);var CircleGesture=function(data){this.center=data.center;this.normal=data.normal;this.progress=data.progress;this.radius=data.radius};CircleGesture.prototype.toString=function(){return"CircleGesture ["+JSON.stringify(this)+"]"};var SwipeGesture=function(data){this.startPosition=data.startPosition;this.position=data.position;this.direction=data.direction;this.speed=data.speed};SwipeGesture.prototype.toString=function(){return"SwipeGesture ["+JSON.stringify(this)+"]"};var ScreenTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};ScreenTapGesture.prototype.toString=function(){return"ScreenTapGesture ["+JSON.stringify(this)+"]"};var KeyTapGesture=function(data){this.position=data.position;this.direction=data.direction;this.progress=data.progress};KeyTapGesture.prototype.toString=function(){return"KeyTapGesture ["+JSON.stringify(this)+"]"}},{events:17,"gl-matrix":19,underscore:20}],7:[function(require,module,exports){var Pointable=require("./pointable"),glMatrix=require("gl-matrix"),mat3=glMatrix.mat3,vec3=glMatrix.vec3,_=require("underscore");var Hand=module.exports=function(data){this.id=data.id;this.palmPosition=data.palmPosition;this.direction=data.direction;this.palmVelocity=data.palmVelocity;this.palmNormal=data.palmNormal;this.sphereCenter=data.sphereCenter;this.sphereRadius=data.sphereRadius;this.valid=true;this.pointables=[];this.fingers=[];this.tools=[];this._translation=data.t;this._rotation=_.flatten(data.r);this._scaleFactor=data.s;this.timeVisible=data.timeVisible;this.stabilizedPalmPosition=data.stabilizedPalmPosition};Hand.prototype.finger=function(id){var finger=this.frame.finger(id);return finger&&finger.handId==this.id?finger:Pointable.Invalid};Hand.prototype.rotationAngle=function(sinceFrame,axis){if(!this.valid||!sinceFrame.valid)return 0;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 0;var rot=this.rotationMatrix(sinceFrame);var cs=(rot[0]+rot[4]+rot[8]-1)*.5;var angle=Math.acos(cs);angle=isNaN(angle)?0:angle;if(axis!==undefined){var rotAxis=this.rotationAxis(sinceFrame);angle*=vec3.dot(rotAxis,vec3.normalize(vec3.create(),axis))}return angle};Hand.prototype.rotationAxis=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return vec3.normalize(vec3.create(),[this._rotation[7]-sinceHand._rotation[5],this._rotation[2]-sinceHand._rotation[6],this._rotation[3]-sinceHand._rotation[1]])};Hand.prototype.rotationMatrix=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return mat3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return mat3.create();var transpose=mat3.transpose(mat3.create(),this._rotation);var m=mat3.multiply(mat3.create(),sinceHand._rotation,transpose);return m};Hand.prototype.scaleFactor=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return 1;var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return 1;return Math.exp(this._scaleFactor-sinceHand._scaleFactor)};Hand.prototype.translation=function(sinceFrame){if(!this.valid||!sinceFrame.valid)return vec3.create();var sinceHand=sinceFrame.hand(this.id);if(!sinceHand.valid)return vec3.create();return[this._translation[0]-sinceHand._translation[0],this._translation[1]-sinceHand._translation[1],this._translation[2]-sinceHand._translation[2]]};Hand.prototype.toString=function(){return"Hand [ id: "+this.id+" | palm velocity:"+this.palmVelocity+" | sphere center:"+this.sphereCenter+" ] "};Hand.Invalid={valid:false,fingers:[],tools:[],pointables:[],pointable:function(){return Pointable.Invalid},finger:function(){return Pointable.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return mat3.create()},rotationAxis:function(){return vec3.create()},scaleFactor:function(){return 1},translation:function(){return vec3.create()}}},{"./pointable":11,"gl-matrix":19,underscore:20}],8:[function(require,module,exports){!function(){module.exports={Controller:require("./controller"),Frame:require("./frame"),Gesture:require("./gesture"),Hand:require("./hand"),Pointable:require("./pointable"),InteractionBox:require("./interaction_box"),Connection:require("./connection"),CircularBuffer:require("./circular_buffer"),UI:require("./ui"),glMatrix:require("gl-matrix"),mat3:require("gl-matrix").mat3,vec3:require("gl-matrix").vec3,loopController:undefined,loop:function(opts,callback){if(callback===undefined){callback=opts;opts={}}if(!this.loopController)this.loopController=new this.Controller(opts);this.loopController.loop(callback)}}}()},{"./circular_buffer":2,"./connection":3,"./controller":4,"./frame":5,"./gesture":6,"./hand":7,"./interaction_box":9,"./pointable":11,"./ui":13,"gl-matrix":19}],9:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var InteractionBox=module.exports=function(data){this.valid=true;this.center=data.center;this.size=data.size;this.width=data.size[0];this.height=data.size[1];this.depth=data.size[2]};InteractionBox.prototype.denormalizePoint=function(normalizedPosition){return vec3.fromValues((normalizedPosition[0]-.5)*this.size[0]+this.center[0],(normalizedPosition[1]-.5)*this.size[1]+this.center[1],(normalizedPosition[2]-.5)*this.size[2]+this.center[2])};InteractionBox.prototype.normalizePoint=function(position,clamp){var vec=vec3.fromValues((position[0]-this.center[0])/this.size[0]+.5,(position[1]-this.center[1])/this.size[1]+.5,(position[2]-this.center[2])/this.size[2]+.5);if(clamp){vec[0]=Math.min(Math.max(vec[0],0),1);vec[1]=Math.min(Math.max(vec[1],0),1);vec[2]=Math.min(Math.max(vec[2],0),1)}return vec};InteractionBox.prototype.toString=function(){return"InteractionBox [ width:"+this.width+" | height:"+this.height+" | depth:"+this.depth+" ]"};InteractionBox.Invalid={valid:false}},{"gl-matrix":19}],10:[function(require,module,exports){var Pipeline=module.exports=function(){this.steps=[]};Pipeline.prototype.addStep=function(step){this.steps.push(step)};Pipeline.prototype.run=function(frame){var stepsLength=this.steps.length;for(var i=0;i!=stepsLength;i++){if(!frame)break;frame=this.steps[i](frame)}return frame}},{}],11:[function(require,module,exports){var glMatrix=require("gl-matrix"),vec3=glMatrix.vec3;var Pointable=module.exports=function(data){this.valid=true;this.id=data.id;this.handId=data.handId;this.length=data.length;this.tool=data.tool;this.width=data.width;this.direction=data.direction;this.stabilizedTipPosition=data.stabilizedTipPosition;this.tipPosition=data.tipPosition;this.tipVelocity=data.tipVelocity;this.touchZone=data.touchZone;this.touchDistance=data.touchDistance;this.timeVisible=data.timeVisible};Pointable.prototype.toString=function(){if(this.tool==true){return"Pointable [ id:"+this.id+" "+this.length+"mmx | with:"+this.width+"mm | direction:"+this.direction+" ]"}else{return"Pointable [ id:"+this.id+" "+this.length+"mmx | direction: "+this.direction+" ]"}};Pointable.Invalid={valid:false}},{"gl-matrix":19}],12:[function(require,module,exports){var Frame=require("./frame");var Event=function(data){this.type=data.type;this.state=data.state};var chooseProtocol=exports.chooseProtocol=function(header){var protocol;switch(header.version){case 1:protocol=JSONProtocol(1,function(data){return new Frame(data)});break;case 2:protocol=JSONProtocol(2,function(data){return new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;case 3:protocol=JSONProtocol(3,function(data){return data.event?new Event(data.event):new Frame(data)});protocol.sendHeartbeat=function(connection){connection.send(protocol.encode({heartbeat:true}))};break;default:throw"unrecognized version"}return protocol};var JSONProtocol=function(version,cb){var protocol=cb;protocol.encode=function(message){return JSON.stringify(message)};protocol.version=version;protocol.versionLong="Version "+version;protocol.type="protocol";return protocol}},{"./frame":5}],13:[function(require,module,exports){exports.UI={Region:require("./ui/region"),Cursor:require("./ui/cursor")}},{"./ui/cursor":14,"./ui/region":15}],14:[function(require,module,exports){var Cursor=module.exports=function(){return function(frame){var pointable=frame.pointables.sort(function(a,b){return a.z-b.z})[0];if(pointable&&pointable.valid){frame.cursorPosition=pointable.tipPosition}return frame}}},{}],15:[function(require,module,exports){var EventEmitter=require("events").EventEmitter,_=require("underscore");var Region=module.exports=function(start,end){this.start=new Vector(start);this.end=new Vector(end);this.enteredFrame=null};Region.prototype.hasPointables=function(frame){for(var i=0;i!=frame.pointables.length;i++){var position=frame.pointables[i].tipPosition;if(position.x>=this.start.x&&position.x<=this.end.x&&position.y>=this.start.y&&position.y<=this.end.y&&position.z>=this.start.z&&position.z<=this.end.z){return true}}return false};Region.prototype.listener=function(opts){var region=this;if(opts&&opts.nearThreshold)this.setupNearRegion(opts.nearThreshold);return function(frame){return region.updatePosition(frame)}};Region.prototype.clipper=function(){var region=this;return function(frame){region.updatePosition(frame);return region.enteredFrame?frame:null}};Region.prototype.setupNearRegion=function(distance){var nearRegion=this.nearRegion=new Region([this.start.x-distance,this.start.y-distance,this.start.z-distance],[this.end.x+distance,this.end.y+distance,this.end.z+distance]);var region=this;nearRegion.on("enter",function(frame){region.emit("near",frame)});nearRegion.on("exit",function(frame){region.emit("far",frame)});region.on("exit",function(frame){region.emit("near",frame)})};Region.prototype.updatePosition=function(frame){if(this.nearRegion)this.nearRegion.updatePosition(frame);if(this.hasPointables(frame)&&this.enteredFrame==null){this.enteredFrame=frame;this.emit("enter",this.enteredFrame)}else if(!this.hasPointables(frame)&&this.enteredFrame!=null){this.enteredFrame=null;this.emit("exit",this.enteredFrame)}return frame};Region.prototype.normalize=function(position){return new Vector([(position.x-this.start.x)/(this.end.x-this.start.x),(position.y-this.start.y)/(this.end.y-this.start.y),(position.z-this.start.z)/(this.end.z-this.start.z)])};Region.prototype.mapToXY=function(position,width,height){var normalized=this.normalize(position);var x=normalized.x,y=normalized.y;if(x>1)x=1;else if(x<-1)x=-1;if(y>1)y=1;else if(y<-1)y=-1;return[(x+1)/2*width,(1-y)/2*height,normalized.z]};_.extend(Region.prototype,EventEmitter.prototype)},{events:17,underscore:20}],16:[function(require,module,exports){},{}],17:[function(require,module,exports){!function(process){if(!process.EventEmitter)process.EventEmitter=function(){};var EventEmitter=exports.EventEmitter=process.EventEmitter;var isArray=typeof Array.isArray==="function"?Array.isArray:function(xs){return Object.prototype.toString.call(xs)==="[object Array]"};function indexOf(xs,x){if(xs.indexOf)return xs.indexOf(x);for(var i=0;i<xs.length;i++){if(x===xs[i])return i}return-1}var defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!this._events)this._events={};this._events.maxListeners=n};EventEmitter.prototype.emit=function(type){if(type==="error"){if(!this._events||!this._events.error||isArray(this._events.error)&&!this._events.error.length){if(arguments[1]instanceof Error){throw arguments[1]}else{throw new Error("Uncaught, unspecified 'error' event.")}return false}}if(!this._events)return false;var handler=this._events[type];if(!handler)return false;if(typeof handler=="function"){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:var args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}return true}else if(isArray(handler)){var args=Array.prototype.slice.call(arguments,1);var listeners=handler.slice();for(var i=0,l=listeners.length;i<l;i++){listeners[i].apply(this,args)}return true}else{return false}};EventEmitter.prototype.addListener=function(type,listener){if("function"!==typeof listener){throw new Error("addListener only takes instances of Function")}if(!this._events)this._events={};this.emit("newListener",type,listener);if(!this._events[type]){this._events[type]=listener}else if(isArray(this._events[type])){if(!this._events[type].warned){var m;if(this._events.maxListeners!==undefined){m=this._events.maxListeners}else{m=defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);console.trace()}}this._events[type].push(listener)}else{this._events[type]=[this._events[type],listener]}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){var self=this;self.on(type,function g(){self.removeListener(type,g);listener.apply(this,arguments)});return this};EventEmitter.prototype.removeListener=function(type,listener){if("function"!==typeof listener){throw new Error("removeListener only takes instances of Function")}if(!this._events||!this._events[type])return this;var list=this._events[type];if(isArray(list)){var i=indexOf(list,listener);if(i<0)return this;list.splice(i,1);if(list.length==0)delete this._events[type]}else if(this._events[type]===listener){delete this._events[type]}return this};EventEmitter.prototype.removeAllListeners=function(type){if(arguments.length===0){this._events={};return this}if(type&&this._events&&this._events[type])this._events[type]=null;return this};EventEmitter.prototype.listeners=function(type){if(!this._events)this._events={};if(!this._events[type])this._events[type]=[];if(!isArray(this._events[type])){this._events[type]=[this._events[type]]}return this._events[type]}}(require("__browserify_process"))},{__browserify_process:18}],18:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){if(ev.source===window&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}],19:[function(require,module,exports){!function(){!function(){"use strict";var shim={};if(typeof exports==="undefined"){if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){shim.exports={};define(function(){return shim.exports})}else{shim.exports=window}}else{shim.exports=exports}!function(exports){var vec2={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec2.create=function(){return new Float32Array(2)};vec2.clone=function(a){var out=new Float32Array(2);out[0]=a[0];out[1]=a[1];return out};vec2.fromValues=function(x,y){var out=new Float32Array(2);out[0]=x;out[1]=y;return out};vec2.copy=function(out,a){out[0]=a[0];out[1]=a[1];return out};vec2.set=function(out,x,y){out[0]=x;out[1]=y;return out};vec2.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];return out};vec2.sub=vec2.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];return out};vec2.mul=vec2.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];return out};vec2.div=vec2.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];return out};vec2.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);
+out[1]=Math.min(a[1],b[1]);return out};vec2.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);return out};vec2.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;return out};vec2.dist=vec2.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return Math.sqrt(x*x+y*y)};vec2.sqrDist=vec2.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1];return x*x+y*y};vec2.len=vec2.length=function(a){var x=a[0],y=a[1];return Math.sqrt(x*x+y*y)};vec2.sqrLen=vec2.squaredLength=function(a){var x=a[0],y=a[1];return x*x+y*y};vec2.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];return out};vec2.normalize=function(out,a){var x=a[0],y=a[1];var len=x*x+y*y;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len}return out};vec2.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]};vec2.cross=function(out,a,b){var z=a[0]*b[1]-a[1]*b[0];out[0]=out[1]=0;out[2]=z;return out};vec2.lerp=function(out,a,b,t){var ax=a[0],ay=a[1];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);return out};vec2.transformMat2=function(out,a,m){var x=a[0],y=a[1];out[0]=x*m[0]+y*m[1];out[1]=x*m[2]+y*m[3];return out};vec2.forEach=function(){var vec=new Float32Array(2);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=2}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1]}return a}}();vec2.str=function(a){return"vec2("+a[0]+", "+a[1]+")"};if(typeof exports!=="undefined"){exports.vec2=vec2}var vec3={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec3.create=function(){return new Float32Array(3)};vec3.clone=function(a){var out=new Float32Array(3);out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.fromValues=function(x,y,z){var out=new Float32Array(3);out[0]=x;out[1]=y;out[2]=z;return out};vec3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];return out};vec3.set=function(out,x,y,z){out[0]=x;out[1]=y;out[2]=z;return out};vec3.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];return out};vec3.sub=vec3.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];return out};vec3.mul=vec3.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];return out};vec3.div=vec3.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];return out};vec3.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);return out};vec3.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);return out};vec3.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;return out};vec3.dist=vec3.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrDist=vec3.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return x*x+y*y+z*z};vec3.len=vec3.length=function(a){var x=a[0],y=a[1],z=a[2];return Math.sqrt(x*x+y*y+z*z)};vec3.sqrLen=vec3.squaredLength=function(a){var x=a[0],y=a[1],z=a[2];return x*x+y*y+z*z};vec3.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];return out};vec3.normalize=function(out,a){var x=a[0],y=a[1],z=a[2];var len=x*x+y*y+z*z;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len}return out};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};vec3.cross=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2];out[0]=ay*bz-az*by;out[1]=az*bx-ax*bz;out[2]=ax*by-ay*bx;return out};vec3.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);return out};vec3.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12];out[1]=m[1]*x+m[5]*y+m[9]*z+m[13];out[2]=m[2]*x+m[6]*y+m[10]*z+m[14];return out};vec3.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec3.forEach=function(){var vec=new Float32Array(3);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=3}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2]}return a}}();vec3.str=function(a){return"vec3("+a[0]+", "+a[1]+", "+a[2]+")"};if(typeof exports!=="undefined"){exports.vec3=vec3}var vec4={};if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}vec4.create=function(){return new Float32Array(4)};vec4.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.fromValues=function(x,y,z,w){var out=new Float32Array(4);out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};vec4.set=function(out,x,y,z,w){out[0]=x;out[1]=y;out[2]=z;out[3]=w;return out};vec4.add=function(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];out[3]=a[3]+b[3];return out};vec4.sub=vec4.subtract=function(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];out[3]=a[3]-b[3];return out};vec4.mul=vec4.multiply=function(out,a,b){out[0]=a[0]*b[0];out[1]=a[1]*b[1];out[2]=a[2]*b[2];out[3]=a[3]*b[3];return out};vec4.div=vec4.divide=function(out,a,b){out[0]=a[0]/b[0];out[1]=a[1]/b[1];out[2]=a[2]/b[2];out[3]=a[3]/b[3];return out};vec4.min=function(out,a,b){out[0]=Math.min(a[0],b[0]);out[1]=Math.min(a[1],b[1]);out[2]=Math.min(a[2],b[2]);out[3]=Math.min(a[3],b[3]);return out};vec4.max=function(out,a,b){out[0]=Math.max(a[0],b[0]);out[1]=Math.max(a[1],b[1]);out[2]=Math.max(a[2],b[2]);out[3]=Math.max(a[3],b[3]);return out};vec4.scale=function(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;out[3]=a[3]*b;return out};vec4.dist=vec4.distance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrDist=vec4.squaredDistance=function(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2],w=b[3]-a[3];return x*x+y*y+z*z+w*w};vec4.len=vec4.length=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return Math.sqrt(x*x+y*y+z*z+w*w)};vec4.sqrLen=vec4.squaredLength=function(a){var x=a[0],y=a[1],z=a[2],w=a[3];return x*x+y*y+z*z+w*w};vec4.negate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=-a[3];return out};vec4.normalize=function(out,a){var x=a[0],y=a[1],z=a[2],w=a[3];var len=x*x+y*y+z*z+w*w;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len;out[3]=a[3]*len}return out};vec4.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]};vec4.lerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);out[3]=aw+t*(b[3]-aw);return out};vec4.transformMat4=function(out,a,m){var x=a[0],y=a[1],z=a[2],w=a[3];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12]*w;out[1]=m[1]*x+m[5]*y+m[9]*z+m[13]*w;out[2]=m[2]*x+m[6]*y+m[10]*z+m[14]*w;out[3]=m[3]*x+m[7]*y+m[11]*z+m[15]*w;return out};vec4.transformQuat=function(out,a,q){var x=a[0],y=a[1],z=a[2],qx=q[0],qy=q[1],qz=q[2],qw=q[3],ix=qw*x+qy*z-qz*y,iy=qw*y+qz*x-qx*z,iz=qw*z+qx*y-qy*x,iw=-qx*x-qy*y-qz*z;out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;return out};vec4.forEach=function(){var vec=new Float32Array(4);return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=4}if(!offset){offset=0}if(count){l=Math.min(count*stride+offset,a.length)}else{l=a.length}for(i=offset;i<l;i+=stride){vec[0]=a[i];vec[1]=a[i+1];vec[2]=a[i+2];vec[3]=a[i+3];fn(vec,vec,arg);a[i]=vec[0];a[i+1]=vec[1];a[i+2]=vec[2];a[i+3]=vec[3]}return a}}();vec4.str=function(a){return"vec4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.vec4=vec4}var mat2={};var mat2Identity=new Float32Array([1,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat2.create=function(){return new Float32Array(mat2Identity)};mat2.clone=function(a){var out=new Float32Array(4);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];return out};mat2.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=1;return out};mat2.transpose=function(out,a){if(out===a){var a1=a[1];out[1]=a[2];out[2]=a1}else{out[0]=a[0];out[1]=a[2];out[2]=a[1];out[3]=a[3]}return out};mat2.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],det=a0*a3-a2*a1;if(!det){return null}det=1/det;out[0]=a3*det;out[1]=-a1*det;out[2]=-a2*det;out[3]=a0*det;return out};mat2.adjoint=function(out,a){var a0=a[0];out[0]=a[3];out[1]=-a[1];out[2]=-a[2];out[3]=a0;return out};mat2.determinant=function(a){return a[0]*a[3]-a[2]*a[1]};mat2.mul=mat2.multiply=function(out,a,b){var a0=a[0],a1=a[1],a2=a[2],a3=a[3];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=a0*b0+a1*b2;out[1]=a0*b1+a1*b3;out[2]=a2*b0+a3*b2;out[3]=a2*b1+a3*b3;return out};mat2.rotate=function(out,a,rad){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],s=Math.sin(rad),c=Math.cos(rad);out[0]=a0*c+a1*s;out[1]=a0*-s+a1*c;out[2]=a2*c+a3*s;out[3]=a2*-s+a3*c;return out};mat2.scale=function(out,a,v){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],v0=v[0],v1=v[1];out[0]=a0*v0;out[1]=a1*v1;out[2]=a2*v0;out[3]=a3*v1;return out};mat2.str=function(a){return"mat2("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.mat2=mat2}var mat3={};var mat3Identity=new Float32Array([1,0,0,0,1,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat3.create=function(){return new Float32Array(mat3Identity)};mat3.clone=function(a){var out=new Float32Array(9);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];return out};mat3.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=1;out[5]=0;out[6]=0;out[7]=0;out[8]=1;return out};mat3.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a12=a[5];out[1]=a[3];out[2]=a[6];out[3]=a01;out[5]=a[7];out[6]=a02;out[7]=a12}else{out[0]=a[0];out[1]=a[3];out[2]=a[6];out[3]=a[1];out[4]=a[4];out[5]=a[7];out[6]=a[2];out[7]=a[5];out[8]=a[8]}return out};mat3.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b01=a22*a11-a12*a21,b11=-a22*a10+a12*a20,b21=a21*a10-a11*a20,det=a00*b01+a01*b11+a02*b21;if(!det){return null}det=1/det;out[0]=b01*det;out[1]=(-a22*a01+a02*a21)*det;out[2]=(a12*a01-a02*a11)*det;out[3]=b11*det;out[4]=(a22*a00-a02*a20)*det;out[5]=(-a12*a00+a02*a10)*det;out[6]=b21*det;out[7]=(-a21*a00+a01*a20)*det;out[8]=(a11*a00-a01*a10)*det;return out};mat3.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];out[0]=a11*a22-a12*a21;out[1]=a02*a21-a01*a22;out[2]=a01*a12-a02*a11;out[3]=a12*a20-a10*a22;out[4]=a00*a22-a02*a20;out[5]=a02*a10-a00*a12;out[6]=a10*a21-a11*a20;out[7]=a01*a20-a00*a21;out[8]=a00*a11-a01*a10;return out};mat3.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8];return a00*(a22*a11-a12*a21)+a01*(-a22*a10+a12*a20)+a02*(a21*a10-a11*a20)};mat3.mul=mat3.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a10=a[3],a11=a[4],a12=a[5],a20=a[6],a21=a[7],a22=a[8],b00=b[0],b01=b[1],b02=b[2],b10=b[3],b11=b[4],b12=b[5],b20=b[6],b21=b[7],b22=b[8];out[0]=b00*a00+b01*a10+b02*a20;out[1]=b00*a01+b01*a11+b02*a21;out[2]=b00*a02+b01*a12+b02*a22;out[3]=b10*a00+b11*a10+b12*a20;out[4]=b10*a01+b11*a11+b12*a21;out[5]=b10*a02+b11*a12+b12*a22;out[6]=b20*a00+b21*a10+b22*a20;out[7]=b20*a01+b21*a11+b22*a21;out[8]=b20*a02+b21*a12+b22*a22;return out};mat3.str=function(a){return"mat3("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+")"};if(typeof exports!=="undefined"){exports.mat3=mat3}var mat4={};var mat4Identity=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}mat4.create=function(){return new Float32Array(mat4Identity)};mat4.clone=function(a){var out=new Float32Array(16);out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.copy=function(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.identity=function(out){out[0]=1;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=1;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=1;out[11]=0;out[12]=0;out[13]=0;out[14]=0;out[15]=1;return out};mat4.transpose=function(out,a){if(out===a){var a01=a[1],a02=a[2],a03=a[3],a12=a[6],a13=a[7],a23=a[11];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a01;out[6]=a[9];out[7]=a[13];out[8]=a02;out[9]=a12;out[11]=a[14];out[12]=a03;out[13]=a13;out[14]=a23}else{out[0]=a[0];out[1]=a[4];out[2]=a[8];out[3]=a[12];out[4]=a[1];out[5]=a[5];out[6]=a[9];out[7]=a[13];out[8]=a[2];out[9]=a[6];out[10]=a[10];out[11]=a[14];out[12]=a[3];out[13]=a[7];out[14]=a[11];out[15]=a[15]}return out};mat4.invert=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32,det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;if(!det){return null}det=1/det;out[0]=(a11*b11-a12*b10+a13*b09)*det;out[1]=(a02*b10-a01*b11-a03*b09)*det;out[2]=(a31*b05-a32*b04+a33*b03)*det;out[3]=(a22*b04-a21*b05-a23*b03)*det;out[4]=(a12*b08-a10*b11-a13*b07)*det;out[5]=(a00*b11-a02*b08+a03*b07)*det;out[6]=(a32*b02-a30*b05-a33*b01)*det;out[7]=(a20*b05-a22*b02+a23*b01)*det;out[8]=(a10*b10-a11*b08+a13*b06)*det;out[9]=(a01*b08-a00*b10-a03*b06)*det;out[10]=(a30*b04-a31*b02+a33*b00)*det;out[11]=(a21*b02-a20*b04-a23*b00)*det;out[12]=(a11*b07-a10*b09-a12*b06)*det;out[13]=(a00*b09-a01*b07+a02*b06)*det;out[14]=(a31*b01-a30*b03-a32*b00)*det;out[15]=(a20*b03-a21*b01+a22*b00)*det;return out};mat4.adjoint=function(out,a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];out[0]=a11*(a22*a33-a23*a32)-a21*(a12*a33-a13*a32)+a31*(a12*a23-a13*a22);out[1]=-(a01*(a22*a33-a23*a32)-a21*(a02*a33-a03*a32)+a31*(a02*a23-a03*a22));out[2]=a01*(a12*a33-a13*a32)-a11*(a02*a33-a03*a32)+a31*(a02*a13-a03*a12);out[3]=-(a01*(a12*a23-a13*a22)-a11*(a02*a23-a03*a22)+a21*(a02*a13-a03*a12));out[4]=-(a10*(a22*a33-a23*a32)-a20*(a12*a33-a13*a32)+a30*(a12*a23-a13*a22));out[5]=a00*(a22*a33-a23*a32)-a20*(a02*a33-a03*a32)+a30*(a02*a23-a03*a22);out[6]=-(a00*(a12*a33-a13*a32)-a10*(a02*a33-a03*a32)+a30*(a02*a13-a03*a12));out[7]=a00*(a12*a23-a13*a22)-a10*(a02*a23-a03*a22)+a20*(a02*a13-a03*a12);out[8]=a10*(a21*a33-a23*a31)-a20*(a11*a33-a13*a31)+a30*(a11*a23-a13*a21);out[9]=-(a00*(a21*a33-a23*a31)-a20*(a01*a33-a03*a31)+a30*(a01*a23-a03*a21));out[10]=a00*(a11*a33-a13*a31)-a10*(a01*a33-a03*a31)+a30*(a01*a13-a03*a11);out[11]=-(a00*(a11*a23-a13*a21)-a10*(a01*a23-a03*a21)+a20*(a01*a13-a03*a11));out[12]=-(a10*(a21*a32-a22*a31)-a20*(a11*a32-a12*a31)+a30*(a11*a22-a12*a21));out[13]=a00*(a21*a32-a22*a31)-a20*(a01*a32-a02*a31)+a30*(a01*a22-a02*a21);out[14]=-(a00*(a11*a32-a12*a31)-a10*(a01*a32-a02*a31)+a30*(a01*a12-a02*a11));out[15]=a00*(a11*a22-a12*a21)-a10*(a01*a22-a02*a21)+a20*(a01*a12-a02*a11);return out};mat4.determinant=function(a){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15],b00=a00*a11-a01*a10,b01=a00*a12-a02*a10,b02=a00*a13-a03*a10,b03=a01*a12-a02*a11,b04=a01*a13-a03*a11,b05=a02*a13-a03*a12,b06=a20*a31-a21*a30,b07=a20*a32-a22*a30,b08=a20*a33-a23*a30,b09=a21*a32-a22*a31,b10=a21*a33-a23*a31,b11=a22*a33-a23*a32;return b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06};mat4.mul=mat4.multiply=function(out,a,b){var a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11],a30=a[12],a31=a[13],a32=a[14],a33=a[15];var b0=b[0],b1=b[1],b2=b[2],b3=b[3];out[0]=b0*a00+b1*a10+b2*a20+b3*a30;out[1]=b0*a01+b1*a11+b2*a21+b3*a31;out[2]=b0*a02+b1*a12+b2*a22+b3*a32;out[3]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[4];b1=b[5];b2=b[6];b3=b[7];out[4]=b0*a00+b1*a10+b2*a20+b3*a30;out[5]=b0*a01+b1*a11+b2*a21+b3*a31;out[6]=b0*a02+b1*a12+b2*a22+b3*a32;out[7]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[8];b1=b[9];b2=b[10];b3=b[11];out[8]=b0*a00+b1*a10+b2*a20+b3*a30;out[9]=b0*a01+b1*a11+b2*a21+b3*a31;out[10]=b0*a02+b1*a12+b2*a22+b3*a32;out[11]=b0*a03+b1*a13+b2*a23+b3*a33;b0=b[12];b1=b[13];b2=b[14];b3=b[15];out[12]=b0*a00+b1*a10+b2*a20+b3*a30;out[13]=b0*a01+b1*a11+b2*a21+b3*a31;out[14]=b0*a02+b1*a12+b2*a22+b3*a32;out[15]=b0*a03+b1*a13+b2*a23+b3*a33;return out};mat4.translate=function(out,a,v){var x=v[0],y=v[1],z=v[2],a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23;if(a===out){out[12]=a[0]*x+a[4]*y+a[8]*z+a[12];out[13]=a[1]*x+a[5]*y+a[9]*z+a[13];out[14]=a[2]*x+a[6]*y+a[10]*z+a[14];out[15]=a[3]*x+a[7]*y+a[11]*z+a[15]}else{a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];out[0]=a00;out[1]=a01;out[2]=a02;out[3]=a03;out[4]=a10;out[5]=a11;out[6]=a12;out[7]=a13;out[8]=a20;out[9]=a21;out[10]=a22;out[11]=a23;out[12]=a00*x+a10*y+a20*z+a[12];out[13]=a01*x+a11*y+a21*z+a[13];out[14]=a02*x+a12*y+a22*z+a[14];out[15]=a03*x+a13*y+a23*z+a[15]}return out};mat4.scale=function(out,a,v){var x=v[0],y=v[1],z=v[2];out[0]=a[0]*x;out[1]=a[1]*x;out[2]=a[2]*x;out[3]=a[3]*x;out[4]=a[4]*y;out[5]=a[5]*y;out[6]=a[6]*y;out[7]=a[7]*y;out[8]=a[8]*z;out[9]=a[9]*z;out[10]=a[10]*z;out[11]=a[11]*z;out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15];return out};mat4.rotate=function(out,a,rad,axis){var x=axis[0],y=axis[1],z=axis[2],len=Math.sqrt(x*x+y*y+z*z),s,c,t,a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23,b00,b01,b02,b10,b11,b12,b20,b21,b22;if(Math.abs(len)<GLMAT_EPSILON){return null}len=1/len;x*=len;y*=len;z*=len;s=Math.sin(rad);c=Math.cos(rad);t=1-c;a00=a[0];a01=a[1];a02=a[2];a03=a[3];a10=a[4];a11=a[5];a12=a[6];a13=a[7];a20=a[8];a21=a[9];a22=a[10];a23=a[11];b00=x*x*t+c;b01=y*x*t+z*s;b02=z*x*t-y*s;b10=x*y*t-z*s;b11=y*y*t+c;b12=z*y*t+x*s;b20=x*z*t+y*s;b21=y*z*t-x*s;b22=z*z*t+c;out[0]=a00*b00+a10*b01+a20*b02;out[1]=a01*b00+a11*b01+a21*b02;out[2]=a02*b00+a12*b01+a22*b02;out[3]=a03*b00+a13*b01+a23*b02;out[4]=a00*b10+a10*b11+a20*b12;out[5]=a01*b10+a11*b11+a21*b12;out[6]=a02*b10+a12*b11+a22*b12;out[7]=a03*b10+a13*b11+a23*b12;out[8]=a00*b20+a10*b21+a20*b22;out[9]=a01*b20+a11*b21+a21*b22;out[10]=a02*b20+a12*b21+a22*b22;out[11]=a03*b20+a13*b21+a23*b22;if(a!==out){out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}return out};mat4.rotateX=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a10=a[4],a11=a[5],a12=a[6],a13=a[7],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[0]=a[0];out[1]=a[1];out[2]=a[2];out[3]=a[3];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[4]=a10*c+a20*s;out[5]=a11*c+a21*s;out[6]=a12*c+a22*s;out[7]=a13*c+a23*s;out[8]=a20*c-a10*s;out[9]=a21*c-a11*s;out[10]=a22*c-a12*s;out[11]=a23*c-a13*s;return out};mat4.rotateY=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a20=a[8],a21=a[9],a22=a[10],a23=a[11];if(a!==out){out[4]=a[4];out[5]=a[5];out[6]=a[6];out[7]=a[7];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c-a20*s;out[1]=a01*c-a21*s;out[2]=a02*c-a22*s;out[3]=a03*c-a23*s;out[8]=a00*s+a20*c;out[9]=a01*s+a21*c;out[10]=a02*s+a22*c;out[11]=a03*s+a23*c;return out};mat4.rotateZ=function(out,a,rad){var s=Math.sin(rad),c=Math.cos(rad),a00=a[0],a01=a[1],a02=a[2],a03=a[3],a10=a[4],a11=a[5],a12=a[6],a13=a[7];if(a!==out){out[8]=a[8];out[9]=a[9];out[10]=a[10];out[11]=a[11];out[12]=a[12];out[13]=a[13];out[14]=a[14];out[15]=a[15]}out[0]=a00*c+a10*s;out[1]=a01*c+a11*s;out[2]=a02*c+a12*s;out[3]=a03*c+a13*s;out[4]=a10*c-a00*s;out[5]=a11*c-a01*s;out[6]=a12*c-a02*s;out[7]=a13*c-a03*s;return out};mat4.fromRotationTranslation=function(out,q,v){var x=q[0],y=q[1],z=q[2],w=q[3],x2=x+x,y2=y+y,z2=z+z,xx=x*x2,xy=x*y2,xz=x*z2,yy=y*y2,yz=y*z2,zz=z*z2,wx=w*x2,wy=w*y2,wz=w*z2;out[0]=1-(yy+zz);out[1]=xy+wz;out[2]=xz-wy;out[3]=0;out[4]=xy-wz;out[5]=1-(xx+zz);out[6]=yz+wx;out[7]=0;out[8]=xz+wy;out[9]=yz-wx;out[10]=1-(xx+yy);out[11]=0;out[12]=v[0];out[13]=v[1];out[14]=v[2];out[15]=1;return out};mat4.frustum=function(out,left,right,bottom,top,near,far){var rl=1/(right-left),tb=1/(top-bottom),nf=1/(near-far);out[0]=near*2*rl;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=near*2*tb;out[6]=0;out[7]=0;out[8]=(right+left)*rl;out[9]=(top+bottom)*tb;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=far*near*2*nf;out[15]=0;return out};mat4.perspective=function(out,fovy,aspect,near,far){var f=1/Math.tan(fovy/2),nf=1/(near-far);out[0]=f/aspect;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=f;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=(far+near)*nf;out[11]=-1;out[12]=0;out[13]=0;out[14]=2*far*near*nf;out[15]=0;return out};mat4.ortho=function(out,left,right,bottom,top,near,far){var lr=1/(left-right),bt=1/(bottom-top),nf=1/(near-far);out[0]=-2*lr;out[1]=0;out[2]=0;out[3]=0;out[4]=0;out[5]=-2*bt;out[6]=0;out[7]=0;out[8]=0;out[9]=0;out[10]=2*nf;out[11]=0;out[12]=(left+right)*lr;out[13]=(top+bottom)*bt;out[14]=(far+near)*nf;out[15]=1;return out};mat4.lookAt=function(out,eye,center,up){var x0,x1,x2,y0,y1,y2,z0,z1,z2,len,eyex=eye[0],eyey=eye[1],eyez=eye[2],upx=up[0],upy=up[1],upz=up[2],centerx=center[0],centery=center[1],centerz=center[2];if(Math.abs(eyex-centerx)<GLMAT_EPSILON&&Math.abs(eyey-centery)<GLMAT_EPSILON&&Math.abs(eyez-centerz)<GLMAT_EPSILON){return mat4.identity(out)}z0=eyex-centerx;z1=eyey-centery;z2=eyez-centerz;len=1/Math.sqrt(z0*z0+z1*z1+z2*z2);z0*=len;z1*=len;z2*=len;x0=upy*z2-upz*z1;x1=upz*z0-upx*z2;x2=upx*z1-upy*z0;len=Math.sqrt(x0*x0+x1*x1+x2*x2);if(!len){x0=0;x1=0;x2=0}else{len=1/len;x0*=len;x1*=len;x2*=len}y0=z1*x2-z2*x1;y1=z2*x0-z0*x2;y2=z0*x1-z1*x0;len=Math.sqrt(y0*y0+y1*y1+y2*y2);if(!len){y0=0;y1=0;y2=0}else{len=1/len;y0*=len;y1*=len;y2*=len}out[0]=x0;out[1]=y0;out[2]=z0;out[3]=0;out[4]=x1;out[5]=y1;out[6]=z1;out[7]=0;out[8]=x2;out[9]=y2;out[10]=z2;out[11]=0;out[12]=-(x0*eyex+x1*eyey+x2*eyez);out[13]=-(y0*eyex+y1*eyey+y2*eyez);out[14]=-(z0*eyex+z1*eyey+z2*eyez);out[15]=1;return out};mat4.str=function(a){return"mat4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+")"};if(typeof exports!=="undefined"){exports.mat4=mat4}var quat={};var quatIdentity=new Float32Array([0,0,0,1]);if(!GLMAT_EPSILON){var GLMAT_EPSILON=1e-6}quat.create=function(){return new Float32Array(quatIdentity)};quat.clone=vec4.clone;quat.fromValues=vec4.fromValues;quat.copy=vec4.copy;quat.set=vec4.set;quat.identity=function(out){out[0]=0;out[1]=0;out[2]=0;out[3]=1;return out};quat.setAxisAngle=function(out,axis,rad){rad=rad*.5;var s=Math.sin(rad);out[0]=s*axis[0];out[1]=s*axis[1];out[2]=s*axis[2];out[3]=Math.cos(rad);return out};quat.add=vec4.add;quat.mul=quat.multiply=function(out,a,b){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=b[3];out[0]=ax*bw+aw*bx+ay*bz-az*by;out[1]=ay*bw+aw*by+az*bx-ax*bz;out[2]=az*bw+aw*bz+ax*by-ay*bx;out[3]=aw*bw-ax*bx-ay*by-az*bz;return out};quat.scale=vec4.scale;quat.rotateX=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+aw*bx;out[1]=ay*bw+az*bx;out[2]=az*bw-ay*bx;out[3]=aw*bw-ax*bx;return out};quat.rotateY=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],by=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw-az*by;out[1]=ay*bw+aw*by;out[2]=az*bw+ax*by;out[3]=aw*bw-ay*by;return out};quat.rotateZ=function(out,a,rad){rad*=.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3],bz=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+ay*bz;out[1]=ay*bw-ax*bz;out[2]=az*bw+aw*bz;out[3]=aw*bw-az*bz;return out};quat.calculateW=function(out,a){var x=a[0],y=a[1],z=a[2];out[0]=x;out[1]=y;out[2]=z;out[3]=-Math.sqrt(Math.abs(1-x*x-y*y-z*z));return out};quat.dot=vec4.dot;quat.lerp=vec4.lerp;quat.slerp=function(out,a,b,t){var ax=a[0],ay=a[1],az=a[2],aw=a[3],bx=b[0],by=b[1],bz=b[2],bw=a[3];var cosHalfTheta=ax*bx+ay*by+az*bz+aw*bw,halfTheta,sinHalfTheta,ratioA,ratioB;if(Math.abs(cosHalfTheta)>=1){if(out!==a){out[0]=ax;out[1]=ay;out[2]=az;out[3]=aw}return out}halfTheta=Math.acos(cosHalfTheta);sinHalfTheta=Math.sqrt(1-cosHalfTheta*cosHalfTheta);if(Math.abs(sinHalfTheta)<.001){out[0]=ax*.5+bx*.5;out[1]=ay*.5+by*.5;out[2]=az*.5+bz*.5;out[3]=aw*.5+bw*.5;return out}ratioA=Math.sin((1-t)*halfTheta)/sinHalfTheta;ratioB=Math.sin(t*halfTheta)/sinHalfTheta;out[0]=ax*ratioA+bx*ratioB;out[1]=ay*ratioA+by*ratioB;out[2]=az*ratioA+bz*ratioB;out[3]=aw*ratioA+bw*ratioB;return out};quat.invert=function(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3],dot=a0*a0+a1*a1+a2*a2+a3*a3,invDot=dot?1/dot:0;out[0]=-a0*invDot;out[1]=-a1*invDot;out[2]=-a2*invDot;out[3]=a3*invDot;return out};quat.conjugate=function(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=a[3];return out};quat.len=quat.length=vec4.length;quat.sqrLen=quat.squaredLength=vec4.squaredLength;quat.normalize=vec4.normalize;quat.str=function(a){return"quat("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};if(typeof exports!=="undefined"){exports.quat=quat}}(shim.exports)}()}()},{}],20:[function(require,module,exports){!function(){!function(){var root=this;var previousUnderscore=root._;var breaker={};var ArrayProto=Array.prototype,ObjProto=Object.prototype,FuncProto=Function.prototype;var push=ArrayProto.push,slice=ArrayProto.slice,concat=ArrayProto.concat,toString=ObjProto.toString,hasOwnProperty=ObjProto.hasOwnProperty;var nativeForEach=ArrayProto.forEach,nativeMap=ArrayProto.map,nativeReduce=ArrayProto.reduce,nativeReduceRight=ArrayProto.reduceRight,nativeFilter=ArrayProto.filter,nativeEvery=ArrayProto.every,nativeSome=ArrayProto.some,nativeIndexOf=ArrayProto.indexOf,nativeLastIndexOf=ArrayProto.lastIndexOf,nativeIsArray=Array.isArray,nativeKeys=Object.keys,nativeBind=FuncProto.bind;var _=function(obj){if(obj instanceof _)return obj;if(!(this instanceof _))return new _(obj);this._wrapped=obj};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=_}exports._=_}else{root._=_}_.VERSION="1.4.4";var each=_.each=_.forEach=function(obj,iterator,context){if(obj==null)return;if(nativeForEach&&obj.forEach===nativeForEach){obj.forEach(iterator,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){if(iterator.call(context,obj[i],i,obj)===breaker)return}}else{for(var key in obj){if(_.has(obj,key)){if(iterator.call(context,obj[key],key,obj)===breaker)return}}}};_.map=_.collect=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeMap&&obj.map===nativeMap)return obj.map(iterator,context);each(obj,function(value,index,list){results[results.length]=iterator.call(context,value,index,list)});return results};var reduceError="Reduce of empty array with no initial value";_.reduce=_.foldl=_.inject=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduce&&obj.reduce===nativeReduce){if(context)iterator=_.bind(iterator,context);return initial?obj.reduce(iterator,memo):obj.reduce(iterator)}each(obj,function(value,index,list){if(!initial){memo=value;initial=true}else{memo=iterator.call(context,memo,value,index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.reduceRight=_.foldr=function(obj,iterator,memo,context){var initial=arguments.length>2;if(obj==null)obj=[];if(nativeReduceRight&&obj.reduceRight===nativeReduceRight){if(context)iterator=_.bind(iterator,context);return initial?obj.reduceRight(iterator,memo):obj.reduceRight(iterator)}var length=obj.length;if(length!==+length){var keys=_.keys(obj);length=keys.length}each(obj,function(value,index,list){index=keys?keys[--length]:--length;if(!initial){memo=obj[index];initial=true}else{memo=iterator.call(context,memo,obj[index],index,list)}});if(!initial)throw new TypeError(reduceError);return memo};_.find=_.detect=function(obj,iterator,context){var result;any(obj,function(value,index,list){if(iterator.call(context,value,index,list)){result=value;return true}});return result};_.filter=_.select=function(obj,iterator,context){var results=[];if(obj==null)return results;if(nativeFilter&&obj.filter===nativeFilter)return obj.filter(iterator,context);each(obj,function(value,index,list){if(iterator.call(context,value,index,list))results[results.length]=value});return results};_.reject=function(obj,iterator,context){return _.filter(obj,function(value,index,list){return!iterator.call(context,value,index,list)},context)};_.every=_.all=function(obj,iterator,context){iterator||(iterator=_.identity);var result=true;if(obj==null)return result;if(nativeEvery&&obj.every===nativeEvery)return obj.every(iterator,context);each(obj,function(value,index,list){if(!(result=result&&iterator.call(context,value,index,list)))return breaker});return!!result};var any=_.some=_.any=function(obj,iterator,context){iterator||(iterator=_.identity);var result=false;if(obj==null)return result;if(nativeSome&&obj.some===nativeSome)return obj.some(iterator,context);each(obj,function(value,index,list){if(result||(result=iterator.call(context,value,index,list)))return breaker});return!!result};_.contains=_.include=function(obj,target){if(obj==null)return false;if(nativeIndexOf&&obj.indexOf===nativeIndexOf)return obj.indexOf(target)!=-1;return any(obj,function(value){return value===target})};_.invoke=function(obj,method){var args=slice.call(arguments,2);var isFunc=_.isFunction(method);return _.map(obj,function(value){return(isFunc?method:value[method]).apply(value,args)})};_.pluck=function(obj,key){return _.map(obj,function(value){return value[key]})};_.where=function(obj,attrs,first){if(_.isEmpty(attrs))return first?null:[];return _[first?"find":"filter"](obj,function(value){for(var key in attrs){if(attrs[key]!==value[key])return false}return true})};_.findWhere=function(obj,attrs){return _.where(obj,attrs,true)};_.max=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.max.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return-Infinity;var result={computed:-Infinity,value:-Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed>=result.computed&&(result={value:value,computed:computed})});return result.value};_.min=function(obj,iterator,context){if(!iterator&&_.isArray(obj)&&obj[0]===+obj[0]&&obj.length<65535){return Math.min.apply(Math,obj)}if(!iterator&&_.isEmpty(obj))return Infinity;var result={computed:Infinity,value:Infinity};each(obj,function(value,index,list){var computed=iterator?iterator.call(context,value,index,list):value;computed<result.computed&&(result={value:value,computed:computed})});return result.value};_.shuffle=function(obj){var rand;var index=0;var shuffled=[];each(obj,function(value){rand=_.random(index++);shuffled[index-1]=shuffled[rand];shuffled[rand]=value});return shuffled};var lookupIterator=function(value){return _.isFunction(value)?value:function(obj){return obj[value]}};_.sortBy=function(obj,value,context){var iterator=lookupIterator(value);return _.pluck(_.map(obj,function(value,index,list){return{value:value,index:index,criteria:iterator.call(context,value,index,list)}}).sort(function(left,right){var a=left.criteria;
+var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)return-1}return left.index<right.index?-1:1}),"value")};var group=function(obj,value,context,behavior){var result={};var iterator=lookupIterator(value||_.identity);each(obj,function(value,index){var key=iterator.call(context,value,index,obj);behavior(result,key,value)});return result};_.groupBy=function(obj,value,context){return group(obj,value,context,function(result,key,value){(_.has(result,key)?result[key]:result[key]=[]).push(value)})};_.countBy=function(obj,value,context){return group(obj,value,context,function(result,key){if(!_.has(result,key))result[key]=0;result[key]++})};_.sortedIndex=function(array,obj,iterator,context){iterator=iterator==null?_.identity:lookupIterator(iterator);var value=iterator.call(context,obj);var low=0,high=array.length;while(low<high){var mid=low+high>>>1;iterator.call(context,array[mid])<value?low=mid+1:high=mid}return low};_.toArray=function(obj){if(!obj)return[];if(_.isArray(obj))return slice.call(obj);if(obj.length===+obj.length)return _.map(obj,_.identity);return _.values(obj)};_.size=function(obj){if(obj==null)return 0;return obj.length===+obj.length?obj.length:_.keys(obj).length};_.first=_.head=_.take=function(array,n,guard){if(array==null)return void 0;return n!=null&&!guard?slice.call(array,0,n):array[0]};_.initial=function(array,n,guard){return slice.call(array,0,array.length-(n==null||guard?1:n))};_.last=function(array,n,guard){if(array==null)return void 0;if(n!=null&&!guard){return slice.call(array,Math.max(array.length-n,0))}else{return array[array.length-1]}};_.rest=_.tail=_.drop=function(array,n,guard){return slice.call(array,n==null||guard?1:n)};_.compact=function(array){return _.filter(array,_.identity)};var flatten=function(input,shallow,output){each(input,function(value){if(_.isArray(value)){shallow?push.apply(output,value):flatten(value,shallow,output)}else{output.push(value)}});return output};_.flatten=function(array,shallow){return flatten(array,shallow,[])};_.without=function(array){return _.difference(array,slice.call(arguments,1))};_.uniq=_.unique=function(array,isSorted,iterator,context){if(_.isFunction(isSorted)){context=iterator;iterator=isSorted;isSorted=false}var initial=iterator?_.map(array,iterator,context):array;var results=[];var seen=[];each(initial,function(value,index){if(isSorted?!index||seen[seen.length-1]!==value:!_.contains(seen,value)){seen.push(value);results.push(array[index])}});return results};_.union=function(){return _.uniq(concat.apply(ArrayProto,arguments))};_.intersection=function(array){var rest=slice.call(arguments,1);return _.filter(_.uniq(array),function(item){return _.every(rest,function(other){return _.indexOf(other,item)>=0})})};_.difference=function(array){var rest=concat.apply(ArrayProto,slice.call(arguments,1));return _.filter(array,function(value){return!_.contains(rest,value)})};_.zip=function(){var args=slice.call(arguments);var length=_.max(_.pluck(args,"length"));var results=new Array(length);for(var i=0;i<length;i++){results[i]=_.pluck(args,""+i)}return results};_.object=function(list,values){if(list==null)return{};var result={};for(var i=0,l=list.length;i<l;i++){if(values){result[list[i]]=values[i]}else{result[list[i][0]]=list[i][1]}}return result};_.indexOf=function(array,item,isSorted){if(array==null)return-1;var i=0,l=array.length;if(isSorted){if(typeof isSorted=="number"){i=isSorted<0?Math.max(0,l+isSorted):isSorted}else{i=_.sortedIndex(array,item);return array[i]===item?i:-1}}if(nativeIndexOf&&array.indexOf===nativeIndexOf)return array.indexOf(item,isSorted);for(;i<l;i++)if(array[i]===item)return i;return-1};_.lastIndexOf=function(array,item,from){if(array==null)return-1;var hasIndex=from!=null;if(nativeLastIndexOf&&array.lastIndexOf===nativeLastIndexOf){return hasIndex?array.lastIndexOf(item,from):array.lastIndexOf(item)}var i=hasIndex?from:array.length;while(i--)if(array[i]===item)return i;return-1};_.range=function(start,stop,step){if(arguments.length<=1){stop=start||0;start=0}step=arguments[2]||1;var len=Math.max(Math.ceil((stop-start)/step),0);var idx=0;var range=new Array(len);while(idx<len){range[idx++]=start;start+=step}return range};_.bind=function(func,context){if(func.bind===nativeBind&&nativeBind)return nativeBind.apply(func,slice.call(arguments,1));var args=slice.call(arguments,2);return function(){return func.apply(context,args.concat(slice.call(arguments)))}};_.partial=function(func){var args=slice.call(arguments,1);return function(){return func.apply(this,args.concat(slice.call(arguments)))}};_.bindAll=function(obj){var funcs=slice.call(arguments,1);if(funcs.length===0)funcs=_.functions(obj);each(funcs,function(f){obj[f]=_.bind(obj[f],obj)});return obj};_.memoize=function(func,hasher){var memo={};hasher||(hasher=_.identity);return function(){var key=hasher.apply(this,arguments);return _.has(memo,key)?memo[key]:memo[key]=func.apply(this,arguments)}};_.delay=function(func,wait){var args=slice.call(arguments,2);return setTimeout(function(){return func.apply(null,args)},wait)};_.defer=function(func){return _.delay.apply(_,[func,1].concat(slice.call(arguments,1)))};_.throttle=function(func,wait){var context,args,timeout,result;var previous=0;var later=function(){previous=new Date;timeout=null;result=func.apply(context,args)};return function(){var now=new Date;var remaining=wait-(now-previous);context=this;args=arguments;if(remaining<=0){clearTimeout(timeout);timeout=null;previous=now;result=func.apply(context,args)}else if(!timeout){timeout=setTimeout(later,remaining)}return result}};_.debounce=function(func,wait,immediate){var timeout,result;return function(){var context=this,args=arguments;var later=function(){timeout=null;if(!immediate)result=func.apply(context,args)};var callNow=immediate&&!timeout;clearTimeout(timeout);timeout=setTimeout(later,wait);if(callNow)result=func.apply(context,args);return result}};_.once=function(func){var ran=false,memo;return function(){if(ran)return memo;ran=true;memo=func.apply(this,arguments);func=null;return memo}};_.wrap=function(func,wrapper){return function(){var args=[func];push.apply(args,arguments);return wrapper.apply(this,args)}};_.compose=function(){var funcs=arguments;return function(){var args=arguments;for(var i=funcs.length-1;i>=0;i--){args=[funcs[i].apply(this,args)]}return args[0]}};_.after=function(times,func){if(times<=0)return func();return function(){if(--times<1){return func.apply(this,arguments)}}};_.keys=nativeKeys||function(obj){if(obj!==Object(obj))throw new TypeError("Invalid object");var keys=[];for(var key in obj)if(_.has(obj,key))keys[keys.length]=key;return keys};_.values=function(obj){var values=[];for(var key in obj)if(_.has(obj,key))values.push(obj[key]);return values};_.pairs=function(obj){var pairs=[];for(var key in obj)if(_.has(obj,key))pairs.push([key,obj[key]]);return pairs};_.invert=function(obj){var result={};for(var key in obj)if(_.has(obj,key))result[obj[key]]=key;return result};_.functions=_.methods=function(obj){var names=[];for(var key in obj){if(_.isFunction(obj[key]))names.push(key)}return names.sort()};_.extend=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){obj[prop]=source[prop]}}});return obj};_.pick=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));each(keys,function(key){if(key in obj)copy[key]=obj[key]});return copy};_.omit=function(obj){var copy={};var keys=concat.apply(ArrayProto,slice.call(arguments,1));for(var key in obj){if(!_.contains(keys,key))copy[key]=obj[key]}return copy};_.defaults=function(obj){each(slice.call(arguments,1),function(source){if(source){for(var prop in source){if(obj[prop]==null)obj[prop]=source[prop]}}});return obj};_.clone=function(obj){if(!_.isObject(obj))return obj;return _.isArray(obj)?obj.slice():_.extend({},obj)};_.tap=function(obj,interceptor){interceptor(obj);return obj};var eq=function(a,b,aStack,bStack){if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;if(a instanceof _)a=a._wrapped;if(b instanceof _)b=b._wrapped;var className=toString.call(a);if(className!=toString.call(b))return false;switch(className){case"[object String]":return a==String(b);case"[object Number]":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case"[object Date]":case"[object Boolean]":return+a==+b;case"[object RegExp]":return a.source==b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return false;var length=aStack.length;while(length--){if(aStack[length]==a)return bStack[length]==b}aStack.push(a);bStack.push(b);var size=0,result=true;if(className=="[object Array]"){size=a.length;result=size==b.length;if(result){while(size--){if(!(result=eq(a[size],b[size],aStack,bStack)))break}}}else{var aCtor=a.constructor,bCtor=b.constructor;if(aCtor!==bCtor&&!(_.isFunction(aCtor)&&aCtor instanceof aCtor&&_.isFunction(bCtor)&&bCtor instanceof bCtor)){return false}for(var key in a){if(_.has(a,key)){size++;if(!(result=_.has(b,key)&&eq(a[key],b[key],aStack,bStack)))break}}if(result){for(key in b){if(_.has(b,key)&&!size--)break}result=!size}}aStack.pop();bStack.pop();return result};_.isEqual=function(a,b){return eq(a,b,[],[])};_.isEmpty=function(obj){if(obj==null)return true;if(_.isArray(obj)||_.isString(obj))return obj.length===0;for(var key in obj)if(_.has(obj,key))return false;return true};_.isElement=function(obj){return!!(obj&&obj.nodeType===1)};_.isArray=nativeIsArray||function(obj){return toString.call(obj)=="[object Array]"};_.isObject=function(obj){return obj===Object(obj)};each(["Arguments","Function","String","Number","Date","RegExp"],function(name){_["is"+name]=function(obj){return toString.call(obj)=="[object "+name+"]"}});if(!_.isArguments(arguments)){_.isArguments=function(obj){return!!(obj&&_.has(obj,"callee"))}}if(typeof/./!=="function"){_.isFunction=function(obj){return typeof obj==="function"}}_.isFinite=function(obj){return isFinite(obj)&&!isNaN(parseFloat(obj))};_.isNaN=function(obj){return _.isNumber(obj)&&obj!=+obj};_.isBoolean=function(obj){return obj===true||obj===false||toString.call(obj)=="[object Boolean]"};_.isNull=function(obj){return obj===null};_.isUndefined=function(obj){return obj===void 0};_.has=function(obj,key){return hasOwnProperty.call(obj,key)};_.noConflict=function(){root._=previousUnderscore;return this};_.identity=function(value){return value};_.times=function(n,iterator,context){var accum=Array(n);for(var i=0;i<n;i++)accum[i]=iterator.call(context,i);return accum};_.random=function(min,max){if(max==null){max=min;min=0}return min+Math.floor(Math.random()*(max-min+1))};var entityMap={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};entityMap.unescape=_.invert(entityMap.escape);var entityRegexes={escape:new RegExp("["+_.keys(entityMap.escape).join("")+"]","g"),unescape:new RegExp("("+_.keys(entityMap.unescape).join("|")+")","g")};_.each(["escape","unescape"],function(method){_[method]=function(string){if(string==null)return"";return(""+string).replace(entityRegexes[method],function(match){return entityMap[method][match]})}});_.result=function(object,property){if(object==null)return null;var value=object[property];return _.isFunction(value)?value.call(object):value};_.mixin=function(obj){each(_.functions(obj),function(name){var func=_[name]=obj[name];_.prototype[name]=function(){var args=[this._wrapped];push.apply(args,arguments);return result.call(this,func.apply(_,args))}})};var idCounter=0;_.uniqueId=function(prefix){var id=++idCounter+"";return prefix?prefix+id:id};_.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var noMatch=/(.)^/;var escapes={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"};var escaper=/\\|'|\r|\n|\t|\u2028|\u2029/g;_.template=function(text,data,settings){var render;settings=_.defaults({},settings,_.templateSettings);var matcher=new RegExp([(settings.escape||noMatch).source,(settings.interpolate||noMatch).source,(settings.evaluate||noMatch).source].join("|")+"|$","g");var index=0;var source="__p+='";text.replace(matcher,function(match,escape,interpolate,evaluate,offset){source+=text.slice(index,offset).replace(escaper,function(match){return"\\"+escapes[match]});if(escape){source+="'+\n((__t=("+escape+"))==null?'':_.escape(__t))+\n'"}if(interpolate){source+="'+\n((__t=("+interpolate+"))==null?'':__t)+\n'"}if(evaluate){source+="';\n"+evaluate+"\n__p+='"}index=offset+match.length;return match});source+="';\n";if(!settings.variable)source="with(obj||{}){\n"+source+"}\n";source="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+source+"return __p;\n";try{render=new Function(settings.variable||"obj","_",source)}catch(e){e.source=source;throw e}if(data)return render(data,_);var template=function(data){return render.call(this,data,_)};template.source="function("+(settings.variable||"obj")+"){\n"+source+"}";return template};_.chain=function(obj){return _(obj).chain()};var result=function(obj){return this._chain?_(obj).chain():obj};_.mixin(_);each(["pop","push","reverse","shift","sort","splice","unshift"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){var obj=this._wrapped;method.apply(obj,arguments);if((name=="shift"||name=="splice")&&obj.length===0)delete obj[0];return result.call(this,obj)}});each(["concat","join","slice"],function(name){var method=ArrayProto[name];_.prototype[name]=function(){return result.call(this,method.apply(this._wrapped,arguments))}});_.extend(_.prototype,{chain:function(){this._chain=true;return this},value:function(){return this._wrapped}})}.call(this)}()},{}],21:[function(require,module,exports){window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){window.setTimeout(callback,1e3/60)}}();Leap=require("../lib/index")},{"../lib/index":8}]},{},[21]);
+
+/*
+ * Leap Motion integration for Reveal.js.
+ * James Sun  [sun16]
+ * Rory Hardy [gneatgeek]
+ */
+
+(function () {
+  var body        = document.body,
+      controller  = new Leap.Controller({ enableGestures: true }),
+      lastGesture = 0,
+      leapConfig  = Reveal.getConfig().leap,
+      pointer     = document.createElement( 'div' ),
+      config      = {
+        autoCenter       : true,      // Center pointer around detected position.
+        gestureDelay     : 500,       // How long to delay between gestures.
+        naturalSwipe     : true,      // Swipe as if it were a touch screen.
+        pointerColor     : '#00aaff', // Default color of the pointer.
+        pointerOpacity   : 0.7,       // Default opacity of the pointer.
+        pointerSize      : 15,        // Default minimum height/width of the pointer.
+        pointerTolerance : 120        // Bigger = slower pointer.
+      },
+      entered, enteredPosition, now, size, tipPosition; // Other vars we need later, but don't need to redeclare.
+
+      // Merge user defined settings with defaults
+      if( leapConfig ) {
+        for( key in leapConfig ) {
+          config[key] = leapConfig[key];
+        }
+      }
+
+      pointer.id = 'leap';
+
+      pointer.style.position        = 'absolute';
+      pointer.style.visibility      = 'hidden';
+      pointer.style.zIndex          = 50;
+      pointer.style.opacity         = config.pointerOpacity;
+      pointer.style.backgroundColor = config.pointerColor;
+
+      body.appendChild( pointer );
+
+  // Leap's loop
+  controller.on( 'frame', function ( frame ) {
+    // Timing code to rate limit gesture execution
+    now = new Date().getTime();
+
+    // Pointer: 1 to 2 fingers. Strictly one finger works but may cause innaccuracies.
+    // The innaccuracies were observed on a development model and may not be an issue with consumer models.
+    if( frame.fingers.length > 0 && frame.fingers.length < 3 ) {
+      // Invert direction and multiply by 3 for greater effect.
+      size = -3 * frame.fingers[0].tipPosition[2];
+
+      if( size < config.pointerSize ) {
+        size = config.pointerSize;
+      }
+
+      pointer.style.width        = size     + 'px';
+      pointer.style.height       = size     + 'px';
+      pointer.style.borderRadius = size - 5 + 'px';
+      pointer.style.visibility   = 'visible';
+
+      if( config.autoCenter ) {
+        tipPosition = frame.fingers[0].tipPosition;
+
+        // Check whether the finger has entered the z range of the Leap Motion. Used for the autoCenter option.
+        if( !entered ) {
+          entered         = true;
+          enteredPosition = frame.fingers[0].tipPosition;
+        }
+
+        pointer.style.top =
+          (-1 * (( tipPosition[1] - enteredPosition[1] ) * body.offsetHeight / config.pointerTolerance )) +
+            ( body.offsetHeight / 2 ) + 'px';
+
+        pointer.style.left =
+          (( tipPosition[0] - enteredPosition[0] ) * body.offsetWidth / config.pointerTolerance ) +
+            ( body.offsetWidth / 2 ) + 'px';
+      }
+      else {
+        pointer.style.top  = ( 1 - (( tipPosition[1] - 50) / config.pointerTolerance )) *
+          body.offsetHeight + 'px';
+
+        pointer.style.left = ( tipPosition[0] * body.offsetWidth / config.pointerTolerance ) +
+          ( body.offsetWidth / 2 ) + 'px';
+      }
+    }
+    else {
+      // Hide pointer on exit
+      entered                  = false;
+      pointer.style.visibility = 'hidden';
+    }
+
+    // Gestures
+    if( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) {
+      var gesture = frame.gestures[0];
+
+      // One hand gestures
+      if( frame.hands.length === 1 ) {
+        // Swipe gestures. 3+ fingers.
+        if( frame.fingers.length > 2 && gesture.type === 'swipe' ) {
+          // Define here since some gestures will throw undefined for these.
+          var x = gesture.direction[0],
+              y = gesture.direction[1];
+
+          // Left/right swipe gestures
+          if( Math.abs( x ) > Math.abs( y )) {
+            if( x > 0 ) {
+              config.naturalSwipe ? Reveal.left() : Reveal.right();
+            }
+            else {
+              config.naturalSwipe ? Reveal.right() : Reveal.left();
+            }
+          }
+          // Up/down swipe gestures
+          else {
+            if( y > 0 ) {
+              config.naturalSwipe ? Reveal.down() : Reveal.up();
+            }
+            else {
+              config.naturalSwipe ? Reveal.up() : Reveal.down();
+            }
+          }
+
+          lastGesture = now;
+        }
+      }
+      // Two hand gestures
+      else if( frame.hands.length === 2 ) {
+        // Upward two hand swipe gesture
+        if( gesture.direction[1] > 0 && gesture.type === 'swipe' ) {
+          Reveal.toggleOverview();
+        }
+
+        lastGesture = now;
+      }
+    }
+  });
+
+  controller.connect();
+})();
diff --git a/docs/slides/plpv14/reveal.js/plugin/markdown/markdown.js b/docs/slides/plpv14/reveal.js/plugin/markdown/markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/markdown/markdown.js
@@ -0,0 +1,392 @@
+/**
+ * The reveal.js markdown plugin. Handles parsing of
+ * markdown inside of presentations as well as loading
+ * of external markdown documents.
+ */
+(function( root, factory ) {
+	if( typeof exports === 'object' ) {
+		module.exports = factory( require( './marked' ) );
+	}
+	else {
+		// Browser globals (root is window)
+		root.RevealMarkdown = factory( root.marked );
+		root.RevealMarkdown.initialize();
+	}
+}( this, function( marked ) {
+
+	if( typeof marked === 'undefined' ) {
+		throw 'The reveal.js Markdown plugin requires marked to be loaded';
+	}
+
+	if( typeof hljs !== 'undefined' ) {
+		marked.setOptions({
+			highlight: function( lang, code ) {
+				return hljs.highlightAuto( lang, code ).value;
+			}
+		});
+	}
+
+	var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$',
+		DEFAULT_NOTES_SEPARATOR = 'note:',
+		DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
+		DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
+
+
+	/**
+	 * Retrieves the markdown contents of a slide section
+	 * element. Normalizes leading tabs/whitespace.
+	 */
+	function getMarkdownFromSlide( section ) {
+
+		var template = section.querySelector( 'script' );
+
+		// strip leading whitespace so it isn't evaluated as code
+		var text = ( template || section ).textContent;
+
+		var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
+			leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
+
+		if( leadingTabs > 0 ) {
+			text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+		}
+		else if( leadingWs > 1 ) {
+			text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+		}
+
+		return text;
+
+	}
+
+	/**
+	 * Given a markdown slide section element, this will
+	 * return all arguments that aren't related to markdown
+	 * parsing. Used to forward any other user-defined arguments
+	 * to the output markdown slide.
+	 */
+	function getForwardedAttributes( section ) {
+
+		var attributes = section.attributes;
+		var result = [];
+
+		for( var i = 0, len = attributes.length; i < len; i++ ) {
+			var name = attributes[i].name,
+				value = attributes[i].value;
+
+			// disregard attributes that are used for markdown loading/parsing
+			if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
+
+			if( value ) {
+				result.push( name + '=' + value );
+			}
+			else {
+				result.push( name );
+			}
+		}
+
+		return result.join( ' ' );
+
+	}
+
+	/**
+	 * Inspects the given options and fills out default
+	 * values for what's not defined.
+	 */
+	function getSlidifyOptions( options ) {
+
+		options = options || {};
+		options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
+		options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
+		options.attributes = options.attributes || '';
+
+		return options;
+
+	}
+
+	/**
+	 * Helper function for constructing a markdown slide.
+	 */
+	function createMarkdownSlide( content, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
+
+		if( notesMatch.length === 2 ) {
+			content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
+		}
+
+		return '<script type="text/template">' + content + '</script>';
+
+	}
+
+	/**
+	 * Parses a data string into multiple slides based
+	 * on the passed in separator arguments.
+	 */
+	function slidify( markdown, options ) {
+
+		options = getSlidifyOptions( options );
+
+		var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
+			horizontalSeparatorRegex = new RegExp( options.separator );
+
+		var matches,
+			lastIndex = 0,
+			isHorizontal,
+			wasHorizontal = true,
+			content,
+			sectionStack = [];
+
+		// iterate until all blocks between separators are stacked up
+		while( matches = separatorRegex.exec( markdown ) ) {
+			notes = null;
+
+			// determine direction (horizontal by default)
+			isHorizontal = horizontalSeparatorRegex.test( matches[0] );
+
+			if( !isHorizontal && wasHorizontal ) {
+				// create vertical stack
+				sectionStack.push( [] );
+			}
+
+			// pluck slide content from markdown input
+			content = markdown.substring( lastIndex, matches.index );
+
+			if( isHorizontal && wasHorizontal ) {
+				// add to horizontal stack
+				sectionStack.push( content );
+			}
+			else {
+				// add to vertical stack
+				sectionStack[sectionStack.length-1].push( content );
+			}
+
+			lastIndex = separatorRegex.lastIndex;
+			wasHorizontal = isHorizontal;
+		}
+
+		// add the remaining slide
+		( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
+
+		var markdownSections = '';
+
+		// flatten the hierarchical stack, and insert <section data-markdown> tags
+		for( var i = 0, len = sectionStack.length; i < len; i++ ) {
+			// vertical
+			if( sectionStack[i] instanceof Array ) {
+				markdownSections += '<section '+ options.attributes +'>';
+
+				sectionStack[i].forEach( function( child ) {
+					markdownSections += '<section data-markdown>' +  createMarkdownSlide( child, options ) + '</section>';
+				} );
+
+				markdownSections += '</section>';
+			}
+			else {
+				markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
+			}
+		}
+
+		return markdownSections;
+
+	}
+
+	/**
+	 * Parses any current data-markdown slides, splits
+	 * multi-slide markdown into separate sections and
+	 * handles loading of external markdown.
+	 */
+	function processSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]'),
+			section;
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			section = sections[i];
+
+			if( section.getAttribute( 'data-markdown' ).length ) {
+
+				var xhr = new XMLHttpRequest(),
+					url = section.getAttribute( 'data-markdown' );
+
+				datacharset = section.getAttribute( 'data-charset' );
+
+				// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
+				if( datacharset != null && datacharset != '' ) {
+					xhr.overrideMimeType( 'text/html; charset=' + datacharset );
+				}
+
+				xhr.onreadystatechange = function() {
+					if( xhr.readyState === 4 ) {
+						if ( xhr.status >= 200 && xhr.status < 300 ) {
+
+							section.outerHTML = slidify( xhr.responseText, {
+								separator: section.getAttribute( 'data-separator' ),
+								verticalSeparator: section.getAttribute( 'data-vertical' ),
+								notesSeparator: section.getAttribute( 'data-notes' ),
+								attributes: getForwardedAttributes( section )
+							});
+
+						}
+						else {
+
+							section.outerHTML = '<section data-state="alert">' +
+								'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
+								'Check your browser\'s JavaScript console for more details.' +
+								'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
+								'</section>';
+
+						}
+					}
+				};
+
+				xhr.open( 'GET', url, false );
+
+				try {
+					xhr.send();
+				}
+				catch ( e ) {
+					alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
+				}
+
+			}
+			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) {
+
+				section.outerHTML = slidify( getMarkdownFromSlide( section ), {
+					separator: section.getAttribute( 'data-separator' ),
+					verticalSeparator: section.getAttribute( 'data-vertical' ),
+					notesSeparator: section.getAttribute( 'data-notes' ),
+					attributes: getForwardedAttributes( section )
+				});
+
+			}
+			else {
+				section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
+			}
+		}
+
+	}
+
+	/**
+	 * Check if a node value has the attributes pattern.
+	 * If yes, extract it and add that value as one or several attributes
+	 * the the terget element.
+	 *
+	 * You need Cache Killer on Chrome to see the effect on any FOM transformation
+	 * directly on refresh (F5)
+	 * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
+	 */
+	function addAttributeInElement( node, elementTarget, separator ) {
+
+		var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
+		var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
+		var nodeValue = node.nodeValue;
+		if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
+
+			var classes = matches[1];
+			nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
+			node.nodeValue = nodeValue;
+			while( matchesClass = mardownClassRegex.exec( classes ) ) {
+				elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Add attributes to the parent element of a text node,
+	 * or the element of an attribute node.
+	 */
+	function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
+
+		if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
+			previousParentElement = element;
+			for( var i = 0; i < element.childNodes.length; i++ ) {
+				childElement = element.childNodes[i];
+				if ( i > 0 ) {
+					j = i - 1;
+					while ( j >= 0 ) {
+						aPreviousChildElement = element.childNodes[j];
+						if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
+							previousParentElement = aPreviousChildElement;
+							break;
+						}
+						j = j - 1;
+					}
+				}
+				parentSection = section;
+				if( childElement.nodeName ==  "section" ) {
+					parentSection = childElement ;
+					previousParentElement = childElement ;
+				}
+				if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
+					addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
+				}
+			}
+		}
+
+		if ( element.nodeType == Node.COMMENT_NODE ) {
+			if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
+				addAttributeInElement( element, section, separatorSectionAttributes );
+			}
+		}
+	}
+
+	/**
+	 * Converts any current data-markdown slides in the
+	 * DOM to HTML.
+	 */
+	function convertSlides() {
+
+		var sections = document.querySelectorAll( '[data-markdown]');
+
+		for( var i = 0, len = sections.length; i < len; i++ ) {
+
+			var section = sections[i];
+
+			// Only parse the same slide once
+			if( !section.getAttribute( 'data-markdown-parsed' ) ) {
+
+				section.setAttribute( 'data-markdown-parsed', true )
+
+				var notes = section.querySelector( 'aside.notes' );
+				var markdown = getMarkdownFromSlide( section );
+
+				section.innerHTML = marked( markdown );
+				addAttributes( 	section, section, null, section.getAttribute( 'data-element-attributes' ) ||
+								section.parentNode.getAttribute( 'data-element-attributes' ) ||
+								DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
+								section.getAttribute( 'data-attributes' ) ||
+								section.parentNode.getAttribute( 'data-attributes' ) ||
+								DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
+
+				// If there were notes, we need to re-add them after
+				// having overwritten the section's HTML
+				if( notes ) {
+					section.appendChild( notes );
+				}
+
+			}
+
+		}
+
+	}
+
+	// API
+	return {
+
+		initialize: function() {
+			processSlides();
+			convertSlides();
+		},
+
+		// TODO: Do these belong in the API?
+		processSlides: processSlides,
+		convertSlides: convertSlides,
+		slidify: slidify
+
+	};
+
+}));
diff --git a/docs/slides/plpv14/reveal.js/plugin/markdown/marked.js b/docs/slides/plpv14/reveal.js/plugin/markdown/marked.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/markdown/marked.js
@@ -0,0 +1,37 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){3,} *\n*/,blockquote:/^( *>[^\n]+(\n[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr",/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";block.html=replace(block.html)("comment",/\x3c!--[\s\S]*?--\x3e/)("closed",
+/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1",
+"\\2")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm)if(this.options.tables)this.rules=block.tables;else this.rules=block.gfm}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};
+Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1)this.tokens.push({type:"space"})}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,
+"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,
+"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]="center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].split(/ *\| */);this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=
+src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);
+bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+
+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item[item.length-1]==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:cap[1]==="pre"||cap[1]==="script",text:cap[0]});continue}if(top&&
+(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]=
+"center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */);this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1][cap[1].length-1]==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",
+text:cap[0]});continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^\x3c!--[\s\S]*?--\x3e|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;
+if(!this.links)throw new Error("Tokens array requires a `links` property.");if(this.options.gfm)if(this.options.breaks)this.rules=inline.breaks;else this.rules=inline.gfm;else if(this.options.pedantic)this.rules=inline.pedantic}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);
+out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1][6]===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.url.exec(src)){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.tag.exec(src)){src=src.substring(cap[0].length);
+out+=this.options.sanitize?escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);out+=this.outputLink(cap,{href:cap[2],title:cap[3]});continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0][0];src=cap[0].substring(1)+src;continue}out+=this.outputLink(cap,link);continue}if(cap=this.rules.strong.exec(src)){src=
+src.substring(cap[0].length);out+="<strong>"+this.output(cap[2]||cap[1])+"</strong>";continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+="<em>"+this.output(cap[2]||cap[1])+"</em>";continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+="<code>"+escape(cap[2],true)+"</code>";continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+="<br>";continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+="<del>"+
+this.output(cap[1])+"</del>";continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=escape(cap[0]);continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return out};InlineLexer.prototype.outputLink=function(cap,link){if(cap[0][0]!=="!")return'<a href="'+escape(link.href)+'"'+(link.title?' title="'+escape(link.title)+'"':"")+">"+this.output(cap[1])+"</a>";else return'<img src="'+escape(link.href)+'" alt="'+escape(cap[1])+'"'+(link.title?' title="'+
+escape(link.title)+'"':"")+">"};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/--/g,"\u2014").replace(/'([^']*)'/g,"\u2018$1\u2019").replace(/"([^"]*)"/g,"\u201c$1\u201d").replace(/\.{3}/g,"\u2026")};InlineLexer.prototype.mangle=function(text){var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>0.5)ch="x"+ch.toString(16);out+="&#"+ch+";"}return out};function Parser(options){this.tokens=[];this.token=null;
+this.options=options||marked.defaults}Parser.parse=function(src,options){var parser=new Parser(options);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options);this.tokens=src.reverse();var out="";while(this.next())out+=this.tok();return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;
+while(this.peek().type==="text")body+="\n"+this.next().text;return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case "space":return"";case "hr":return"<hr>\n";case "heading":return"<h"+this.token.depth+">"+this.inline.output(this.token.text)+"</h"+this.token.depth+">\n";case "code":if(this.options.highlight){var code=this.options.highlight(this.token.text,this.token.lang);if(code!=null&&code!==this.token.text){this.token.escaped=true;this.token.text=code}}if(!this.token.escaped)this.token.text=
+escape(this.token.text,true);return"<pre><code"+(this.token.lang?' class="'+this.options.langPrefix+this.token.lang+'"':"")+">"+this.token.text+"</code></pre>\n";case "table":var body="",heading,i,row,cell,j;body+="<thead>\n<tr>\n";for(i=0;i<this.token.header.length;i++){heading=this.inline.output(this.token.header[i]);body+=this.token.align[i]?'<th align="'+this.token.align[i]+'">'+heading+"</th>\n":"<th>"+heading+"</th>\n"}body+="</tr>\n</thead>\n";body+="<tbody>\n";for(i=0;i<this.token.cells.length;i++){row=
+this.token.cells[i];body+="<tr>\n";for(j=0;j<row.length;j++){cell=this.inline.output(row[j]);body+=this.token.align[j]?'<td align="'+this.token.align[j]+'">'+cell+"</td>\n":"<td>"+cell+"</td>\n"}body+="</tr>\n"}body+="</tbody>\n";return"<table>\n"+body+"</table>\n";case "blockquote_start":var body="";while(this.next().type!=="blockquote_end")body+=this.tok();return"<blockquote>\n"+body+"</blockquote>\n";case "list_start":var type=this.token.ordered?"ol":"ul",body="";while(this.next().type!=="list_end")body+=
+this.tok();return"<"+type+">\n"+body+"</"+type+">\n";case "list_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.token.type==="text"?this.parseText():this.tok();return"<li>"+body+"</li>\n";case "loose_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.tok();return"<li>"+body+"</li>\n";case "html":return!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;case "paragraph":return"<p>"+this.inline.output(this.token.text)+
+"</p>\n";case "text":return"<p>"+this.parseText()+"</p>\n"}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=
+1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target)if(Object.prototype.hasOwnProperty.call(target,key))obj[key]=target[key]}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}if(opt)opt=merge({},marked.defaults,opt);var tokens=Lexer.lex(tokens,opt),highlight=opt.highlight,pending=0,l=tokens.length,i=0;if(!highlight||highlight.length<3)return callback(null,Parser.parse(tokens,opt));var done=function(){delete opt.highlight;
+var out=Parser.parse(tokens,opt);opt.highlight=highlight;return callback(null,out)};for(;i<l;i++)(function(token){if(token.type!=="code")return;pending++;return highlight(token.text,token.lang,function(err,code){if(code==null||code===token.text)return--pending||done();token.text=code;token.escaped=true;--pending||done()})})(tokens[i]);return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";
+if((opt||marked.defaults).silent)return"<p>An error occured:</p><pre>"+escape(e.message+"",true)+"</pre>";throw e;}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,smartLists:false,silent:false,highlight:null,langPrefix:""};marked.Parser=Parser;marked.parser=Parser.parse;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;
+marked.parse=marked;if(typeof exports==="object")module.exports=marked;else if(typeof define==="function"&&define.amd)define(function(){return marked});else this.marked=marked}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
diff --git a/docs/slides/plpv14/reveal.js/plugin/math/math.js b/docs/slides/plpv14/reveal.js/plugin/math/math.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/math/math.js
@@ -0,0 +1,64 @@
+/**
+ * A plugin which enables rendering of math equations inside
+ * of reveal.js slides. Essentially a thin wrapper for MathJax.
+ *
+ * @author Hakim El Hattab
+ */
+var RevealMath = window.RevealMath || (function(){
+
+	var options = Reveal.getConfig().math || {};
+	options.mathjax = options.mathjax || 'http://cdn.mathjax.org/mathjax/latest/MathJax.js';
+	options.config = options.config || 'TeX-AMS_HTML-full';
+
+	loadScript( options.mathjax + '?config=' + options.config, function() {
+
+		MathJax.Hub.Config({
+			messageStyle: 'none',
+			tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] },
+			skipStartupTypeset: true
+		});
+
+		// Typeset followed by an immediate reveal.js layout since
+		// the typesetting process could affect slide height
+		MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
+		MathJax.Hub.Queue( Reveal.layout );
+
+		// Reprocess equations in slides when they turn visible
+		Reveal.addEventListener( 'slidechanged', function( event ) {
+
+			MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
+
+		} );
+
+	} );
+
+	function loadScript( url, callback ) {
+
+		var head = document.querySelector( 'head' );
+		var script = document.createElement( 'script' );
+		script.type = 'text/javascript';
+		script.src = url;
+
+		// Wrapper for callback to make sure it only fires once
+		var finish = function() {
+			if( typeof callback === 'function' ) {
+				callback.call();
+				callback = null;
+			}
+		}
+
+		script.onload = finish;
+
+		// IE
+		script.onreadystatechange = function() {
+			if ( this.readyState === 'loaded' ) {
+				finish();
+			}
+		}
+
+		// Normal browsers
+		head.appendChild( script );
+
+	}
+
+})();
diff --git a/docs/slides/plpv14/reveal.js/plugin/multiplex/client.js b/docs/slides/plpv14/reveal.js/plugin/multiplex/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/multiplex/client.js
@@ -0,0 +1,13 @@
+(function() {
+	var multiplex = Reveal.getConfig().multiplex;
+	var socketId = multiplex.id;
+	var socket = io.connect(multiplex.url);
+
+	socket.on(multiplex.id, function(data) {
+		// ignore data from sockets that aren't ours
+		if (data.socketId !== socketId) { return; }
+		if( window.location.host === 'localhost:1947' ) return;
+
+		Reveal.slide(data.indexh, data.indexv, data.indexf, 'remote');
+	});
+}());
diff --git a/docs/slides/plpv14/reveal.js/plugin/multiplex/index.js b/docs/slides/plpv14/reveal.js/plugin/multiplex/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/multiplex/index.js
@@ -0,0 +1,56 @@
+var express		= require('express');
+var fs			= require('fs');
+var io			= require('socket.io');
+var crypto		= require('crypto');
+
+var app			= express.createServer();
+var staticDir	= express.static;
+
+io				= io.listen(app);
+
+var opts = {
+	port: 1948,
+	baseDir : __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		if (typeof slideData.secret == 'undefined' || slideData.secret == null || slideData.secret === '') return;
+		if (createHash(slideData.secret) === slideData.socketId) {
+			slideData.secret = null;
+			socket.broadcast.emit(slideData.socketId, slideData);
+		};
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/token", function(req,res) {
+	var ts = new Date().getTime();
+	var rand = Math.floor(Math.random()*9999999);
+	var secret = ts.toString() + rand.toString();
+	res.send({secret: secret, socketId: createHash(secret)});
+});
+
+var createHash = function(secret) {
+	var cipher = crypto.createCipher('blowfish', secret);
+	return(cipher.final('hex'));
+};
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset );
diff --git a/docs/slides/plpv14/reveal.js/plugin/multiplex/master.js b/docs/slides/plpv14/reveal.js/plugin/multiplex/master.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/multiplex/master.js
@@ -0,0 +1,51 @@
+(function() {
+	// Don't emit events from inside of notes windows
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var multiplex = Reveal.getConfig().multiplex;
+
+	var socket = io.connect(multiplex.url);
+
+	var notify = function( slideElement, indexh, indexv, origin ) {
+		if( typeof origin === 'undefined' && origin !== 'remote' ) {
+			var nextindexh;
+			var nextindexv;
+
+			var fragmentindex = Reveal.getIndices().f;
+			if (typeof fragmentindex == 'undefined') {
+				fragmentindex = 0;
+			}
+
+			if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+				nextindexh = indexh;
+				nextindexv = indexv + 1;
+			} else {
+				nextindexh = indexh + 1;
+				nextindexv = 0;
+			}
+
+			var slideData = {
+				indexh : indexh,
+				indexv : indexv,
+				indexf : fragmentindex,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				secret: multiplex.secret,
+				socketId : multiplex.id
+			};
+
+			socket.emit('slidechanged', slideData);
+		}
+	}
+
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		notify( event.currentSlide, event.indexh, event.indexv, event.origin );
+	} );
+
+	var fragmentNotify = function( event ) {
+		notify( Reveal.getCurrentSlide(), Reveal.getIndices().h, Reveal.getIndices().v, event.origin );
+	};
+
+	Reveal.addEventListener( 'fragmentshown', fragmentNotify );
+	Reveal.addEventListener( 'fragmenthidden', fragmentNotify );
+}());
diff --git a/docs/slides/plpv14/reveal.js/plugin/notes-server/client.js b/docs/slides/plpv14/reveal.js/plugin/notes-server/client.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/notes-server/client.js
@@ -0,0 +1,57 @@
+(function() {
+	// don't emit events from inside the previews themselves
+	if ( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var socket = io.connect(window.location.origin);
+	var socketId = Math.random().toString().slice(2);
+	
+	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
+	window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId);
+
+	// Fires when a fragment is shown
+	Reveal.addEventListener( 'fragmentshown', function( event ) {
+		var fragmentData = {
+			fragment : 'next',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when a fragment is hidden
+	Reveal.addEventListener( 'fragmenthidden', function( event ) {
+		var fragmentData = {
+			fragment : 'previous',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when slide is changed
+	Reveal.addEventListener( 'slidechanged', function( event ) {
+		var nextindexh;
+		var nextindexv;
+		var slideElement = event.currentSlide;
+
+		if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
+			nextindexh = event.indexh;
+			nextindexv = event.indexv + 1;
+		} else {
+			nextindexh = event.indexh + 1;
+			nextindexv = 0;
+		}
+
+		var notes = slideElement.querySelector('aside.notes');
+		var slideData = {
+			notes : notes ? notes.innerHTML : '',
+			indexh : event.indexh,
+			indexv : event.indexv,
+			nextindexh : nextindexh,
+			nextindexv : nextindexv,
+			socketId : socketId,
+			markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false
+
+		};
+
+		socket.emit('slidechanged', slideData);
+	} );
+}());
diff --git a/docs/slides/plpv14/reveal.js/plugin/notes-server/index.js b/docs/slides/plpv14/reveal.js/plugin/notes-server/index.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/notes-server/index.js
@@ -0,0 +1,59 @@
+var express   = require('express');
+var fs        = require('fs');
+var io        = require('socket.io');
+var _         = require('underscore');
+var Mustache  = require('mustache');
+
+var app       = express.createServer();
+var staticDir = express.static;
+
+io            = io.listen(app);
+
+var opts = {
+	port :      1947,
+	baseDir :   __dirname + '/../../'
+};
+
+io.sockets.on('connection', function(socket) {
+	socket.on('slidechanged', function(slideData) {
+		socket.broadcast.emit('slidedata', slideData);
+	});
+	socket.on('fragmentchanged', function(fragmentData) {
+		socket.broadcast.emit('fragmentdata', fragmentData);
+	});
+});
+
+app.configure(function() {
+	[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) {
+		app.use('/' + dir, staticDir(opts.baseDir + dir));
+	});
+});
+
+app.get("/", function(req, res) {
+	res.writeHead(200, {'Content-Type': 'text/html'});
+	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+});
+
+app.get("/notes/:socketId", function(req, res) {
+
+	fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) {
+		res.send(Mustache.to_html(data.toString(), {
+			socketId : req.params.socketId
+		}));
+	});
+	// fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res);
+});
+
+// Actually listen
+app.listen(opts.port || null);
+
+var brown = '\033[33m',
+	green = '\033[32m',
+	reset = '\033[0m';
+
+var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
+
+console.log( brown + "reveal.js - Speaker Notes" + reset );
+console.log( "1. Open the slides at " + green + slidesLocation + reset );
+console.log( "2. Click on the link your JS console to go to the notes page" );
+console.log( "3. Advance through your slides and your notes will advance automatically" );
diff --git a/docs/slides/plpv14/reveal.js/plugin/notes/notes.js b/docs/slides/plpv14/reveal.js/plugin/notes/notes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/notes/notes.js
@@ -0,0 +1,78 @@
+/**
+ * Handles opening of and synchronization with the reveal.js
+ * notes window.
+ */
+var RevealNotes = (function() {
+
+	function openNotes() {
+		var jsFileLocation = document.querySelector('script[src$="notes.js"]').src;  // this js file path
+		jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, '');   // the js folder path
+		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' );
+
+		// Fires when slide is changed
+		Reveal.addEventListener( 'slidechanged', post );
+
+		// Fires when a fragment is shown
+		Reveal.addEventListener( 'fragmentshown', post );
+
+		// Fires when a fragment is hidden
+		Reveal.addEventListener( 'fragmenthidden', post );
+
+		/**
+		 * Posts the current slide data to the notes window
+		 */
+		function post() {
+			var slideElement = Reveal.getCurrentSlide(),
+				slideIndices = Reveal.getIndices(),
+				messageData;
+
+			var notes = slideElement.querySelector( 'aside.notes' ),
+				nextindexh,
+				nextindexv;
+
+			if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
+				nextindexh = slideIndices.h;
+				nextindexv = slideIndices.v + 1;
+			} else {
+				nextindexh = slideIndices.h + 1;
+				nextindexv = 0;
+			}
+
+			messageData = {
+				notes : notes ? notes.innerHTML : '',
+				indexh : slideIndices.h,
+				indexv : slideIndices.v,
+				indexf : slideIndices.f,
+				nextindexh : nextindexh,
+				nextindexv : nextindexv,
+				markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
+			};
+
+			notesPopup.postMessage( JSON.stringify( messageData ), '*' );
+		}
+
+		// Navigate to the current slide when the notes are loaded
+		notesPopup.addEventListener( 'load', function( event ) {
+			post();
+		}, false );
+	}
+
+	// If the there's a 'notes' query set, open directly
+	if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
+		openNotes();
+	}
+
+	// Open the notes when the 's' key is hit
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openNotes();
+		}
+	}, false );
+
+	return { open: openNotes };
+})();
diff --git a/docs/slides/plpv14/reveal.js/plugin/postmessage/postmessage.js b/docs/slides/plpv14/reveal.js/plugin/postmessage/postmessage.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/postmessage/postmessage.js
@@ -0,0 +1,42 @@
+/*
+
+	simple postmessage plugin
+
+	Useful when a reveal slideshow is inside an iframe.
+	It allows to call reveal methods from outside.
+
+	Example:
+		 var reveal =  window.frames[0];
+
+		 // Reveal.prev(); 
+		 reveal.postMessage(JSON.stringify({method: 'prev', args: []}), '*');
+		 // Reveal.next(); 
+		 reveal.postMessage(JSON.stringify({method: 'next', args: []}), '*');
+		 // Reveal.slide(2, 2); 
+		 reveal.postMessage(JSON.stringify({method: 'slide', args: [2,2]}), '*');
+
+	Add to the slideshow:
+
+		dependencies: [
+			...
+			{ src: 'plugin/postmessage/postmessage.js', async: true, condition: function() { return !!document.body.classList; } }
+		]
+
+*/
+
+(function (){
+
+	window.addEventListener( "message", function ( event ) {
+		var data = JSON.parse( event.data ),
+				method = data.method,
+				args = data.args;
+
+		if( typeof Reveal[method] === 'function' ) {
+			Reveal[method].apply( Reveal, data.args );
+		}
+	}, false);
+
+}());
+
+
+
diff --git a/docs/slides/plpv14/reveal.js/plugin/print-pdf/print-pdf.js b/docs/slides/plpv14/reveal.js/plugin/print-pdf/print-pdf.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/print-pdf/print-pdf.js
@@ -0,0 +1,44 @@
+/**
+ * phantomjs script for printing presentations to PDF.
+ *
+ * Example:
+ * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf
+ *
+ * By Manuel Bieh (https://github.com/manuelbieh)
+ */
+
+// html2pdf.js
+var page = new WebPage();
+var system = require( 'system' );
+
+page.viewportSize  = {
+	width: 1024,
+	height: 768
+};
+
+page.paperSize = {
+	format: 'letter',
+	orientation: 'landscape',
+	margin: {
+		left: '0',
+		right: '0',
+		top: '0',
+		bottom: '0'
+	}
+};
+
+var revealFile = system.args[1] || 'index.html?print-pdf';
+var slideFile = system.args[2] || 'slides.pdf';
+
+if( slideFile.match( /\.pdf$/gi ) === null ) {
+	slideFile += '.pdf';
+}
+
+console.log( 'Printing PDF...' );
+
+page.open( revealFile, function( status ) {
+	console.log( 'Printed succesfully' );
+	page.render( slideFile );
+	phantom.exit();
+} );
+
diff --git a/docs/slides/plpv14/reveal.js/plugin/remotes/remotes.js b/docs/slides/plpv14/reveal.js/plugin/remotes/remotes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/remotes/remotes.js
@@ -0,0 +1,39 @@
+/**
+ * Touch-based remote controller for your presentation courtesy 
+ * of the folks at http://remotes.io
+ */
+
+(function(window){
+
+    /**
+     * Detects if we are dealing with a touch enabled device (with some false positives)
+     * Borrowed from modernizr: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touch.js   
+     */
+    var hasTouch  = (function(){
+        return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
+    })();
+
+    /**
+     * Detects if notes are enable and the current page is opened inside an /iframe
+     * this prevents loading Remotes.io several times
+     */
+    var isNotesAndIframe = (function(){
+        return window.RevealNotes && !(self == top);
+    })();
+
+    if(!hasTouch && !isNotesAndIframe){
+        head.ready( 'remotes.ne.min.js', function() {
+            new Remotes("preview")
+                .on("swipe-left", function(e){ Reveal.right(); })
+                .on("swipe-right", function(e){ Reveal.left(); })
+                .on("swipe-up", function(e){ Reveal.down(); })
+                .on("swipe-down", function(e){ Reveal.up(); })
+                .on("tap", function(e){ Reveal.next(); })
+                .on("zoom-out", function(e){ Reveal.toggleOverview(true); })
+                .on("zoom-in", function(e){ Reveal.toggleOverview(false); })
+            ;
+        } );
+
+        head.js('https://hakim-static.s3.amazonaws.com/reveal-js/remotes.ne.min.js');
+    }
+})(window);
diff --git a/docs/slides/plpv14/reveal.js/plugin/search/search.js b/docs/slides/plpv14/reveal.js/plugin/search/search.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/search/search.js
@@ -0,0 +1,196 @@
+/*
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
+ * by navigatating to that slide and highlighting it.
+ *
+ * By Jon Snyder <snyder.jon@gmail.com>, February 2013
+ */
+
+var RevealSearch = (function() {
+
+	var matchedSlides;
+	var currentMatchedIndex;
+	var searchboxDirty;
+	var myHilitor;
+
+// Original JavaScript code by Chirp Internet: www.chirp.com.au
+// Please acknowledge use of this code by including this header.
+// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
+
+function Hilitor(id, tag)
+{
+
+  var targetNode = document.getElementById(id) || document.body;
+  var hiliteTag = tag || "EM";
+  var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
+  var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
+  var wordColor = [];
+  var colorIdx = 0;
+  var matchRegex = "";
+  var matchingSlides = [];
+
+  this.setRegex = function(input)
+  {
+    input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
+    matchRegex = new RegExp("(" + input + ")","i");
+  }
+
+  this.getRegex = function()
+  {
+    return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
+  }
+
+  // recursively apply word highlighting
+  this.hiliteWords = function(node)
+  {
+    if(node == undefined || !node) return;
+    if(!matchRegex) return;
+    if(skipTags.test(node.nodeName)) return;
+
+    if(node.hasChildNodes()) {
+      for(var i=0; i < node.childNodes.length; i++)
+        this.hiliteWords(node.childNodes[i]);
+    }
+    if(node.nodeType == 3) { // NODE_TEXT
+      if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
+      	//find the slide's section element and save it in our list of matching slides
+      	var secnode = node.parentNode;
+      	while (secnode.nodeName != 'SECTION') {
+      		secnode = secnode.parentNode;
+      	}
+      	
+      	var slideIndex = Reveal.getIndices(secnode);
+      	var slidelen = matchingSlides.length;
+      	var alreadyAdded = false;
+      	for (var i=0; i < slidelen; i++) {
+      		if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
+      			alreadyAdded = true;
+      		}
+      	}
+      	if (! alreadyAdded) {
+      		matchingSlides.push(slideIndex);
+      	}
+      	
+        if(!wordColor[regs[0].toLowerCase()]) {
+          wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
+        }
+
+        var match = document.createElement(hiliteTag);
+        match.appendChild(document.createTextNode(regs[0]));
+        match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
+        match.style.fontStyle = "inherit";
+        match.style.color = "#000";
+
+        var after = node.splitText(regs.index);
+        after.nodeValue = after.nodeValue.substring(regs[0].length);
+        node.parentNode.insertBefore(match, after);
+      }
+    }
+  };
+
+  // remove highlighting
+  this.remove = function()
+  {
+    var arr = document.getElementsByTagName(hiliteTag);
+    while(arr.length && (el = arr[0])) {
+      el.parentNode.replaceChild(el.firstChild, el);
+    }
+  };
+
+  // start highlighting at target node
+  this.apply = function(input)
+  {
+    if(input == undefined || !input) return;
+    this.remove();
+    this.setRegex(input);
+    this.hiliteWords(targetNode);
+    return matchingSlides;
+  };
+
+}
+
+	function openSearch() {
+		//ensure the search term input dialog is visible and has focus:
+		var inputbox = document.getElementById("searchinput");
+		inputbox.style.display = "inline";
+		inputbox.focus();
+		inputbox.select();
+	}
+
+	function toggleSearch() {
+		var inputbox = document.getElementById("searchinput");
+		if (inputbox.style.display !== "inline") {
+			openSearch();
+		}
+		else {
+			inputbox.style.display = "none";
+			myHilitor.remove();
+		}
+	}
+
+	function doSearch() {
+		//if there's been a change in the search term, perform a new search:
+		if (searchboxDirty) {
+			var searchstring = document.getElementById("searchinput").value;
+
+			//find the keyword amongst the slides
+			myHilitor = new Hilitor("slidecontent");
+			matchedSlides = myHilitor.apply(searchstring);
+			currentMatchedIndex = 0;
+		}
+
+		//navigate to the next slide that has the keyword, wrapping to the first if necessary
+		if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
+			currentMatchedIndex = 0;
+		}
+		if (matchedSlides.length > currentMatchedIndex) {
+			Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
+			currentMatchedIndex++;
+		}
+	}
+
+	var dom = {};
+	dom.wrapper = document.querySelector( '.reveal' );
+
+	if( !dom.wrapper.querySelector( '.searchbox' ) ) {
+			var searchElement = document.createElement( 'div' );
+			searchElement.id = "searchinputdiv";
+			searchElement.classList.add( 'searchdiv' );
+      searchElement.style.position = 'absolute';
+      searchElement.style.top = '10px';
+      searchElement.style.left = '10px';
+      //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
+			searchElement.innerHTML = '<span><input type="search" id="searchinput" class="searchinput" style="vertical-align: top;"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJiSURBVHjatFZNaxNBGH5md+Mmu92NVdKDRipSAyqCghgQD4L4cRe86UUtAQ+eFCxoa4/25EXBFi8eBE+eRPoDhB6KgiiixdAPCEkx2pjvTXadd9yNsflwuyUDD/O+u8PzzDPvzOwyx3EwyCZhwG3gAkp7MnpjgbopjsltcD4gjuXZZKeAR348MYLYTm3LzOs/y3j3JTfZxgXWXmTuwPHIc4VmoOmv5IrI53+AO2DdHLjkDWQ3GoEEVFXtXQOvkSnPWcyUceviLhwbDYv8/XIVj97kse7TodLvZXxYxrPUHkQ1ufXs3FEdybEIxucySOesoNvUgWU1cP3MkCBfTFdw9fGaAMVmRELq7LBw2Q3/FaAxxWIRpw+ZIr/7IouPqzUBiqmdHAv7EuhRAwf1er2Vy4x1jW3b2d5Jfvu5IPp7l2LYbcgCFFNb+FoJ7oBqEAqFMPNqFcmEgVMJDfMT+1tvN0pNjERlMS6QA5pFOKxiKVPFhakPeL3It+WGJUDxt2wFR+JhzI7v5ctkd8DXOZAkCYYxhO+lKm4+Xfqz/rIixBuNBl7eOYzkQQNzqX249mRl6zUgEcYkaJrGhUwBinVdh6IouPzwE6/DL5w4oLkH8y981aDf+uq6hlKpJESiUdNfDZi7/ehG9K6KfiA3pml0PLcsq+cSMTj2NL9ukc4UOmz7AZ3+crkC4mHujFvXNaMFB3bEr8xPS6p5O+jXxq4VZtaen7/PwzrntjcLUE0iHPS1Ud1cdiEJl/8WivZk0wXd7zWOMkeF8s0CcAmkNrC2nvXZDbbbN73ccYnZoH9bfgswAFzAe9/h3dbKAAAAAElFTkSuQmCC" id="searchbutton" class="searchicon" style="vertical-align: top; margin-top: -1px;"/></span>';
+			dom.wrapper.appendChild( searchElement );
+	}
+
+	document.getElementById("searchbutton").addEventListener( 'click', function(event) {
+		doSearch();
+	}, false );
+
+	document.getElementById("searchinput").addEventListener( 'keyup', function( event ) {
+		switch (event.keyCode) {
+			case 13:
+				event.preventDefault();
+				doSearch();
+				searchboxDirty = false;
+				break;
+			default:
+				searchboxDirty = true;
+		}
+	}, false );
+
+	// Open the search when the 's' key is hit (yes, this conflicts with the notes plugin, disabling for now)
+	/*
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openSearch();
+		}
+	}, false );
+*/
+	return { open: openSearch };
+})();
diff --git a/docs/slides/plpv14/reveal.js/plugin/zoom-js/zoom.js b/docs/slides/plpv14/reveal.js/plugin/zoom-js/zoom.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/plugin/zoom-js/zoom.js
@@ -0,0 +1,258 @@
+// Custom reveal.js integration
+(function(){
+	var isEnabled = true;
+
+	document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) {
+		var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key';
+
+		if( event[ modifier ] && isEnabled ) {
+			event.preventDefault();
+			zoom.to({ element: event.target, pan: false });
+		}
+	} );
+
+	Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
+	Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
+})();
+
+/*!
+ * zoom.js 0.2 (modified version for use with reveal.js)
+ * http://lab.hakim.se/zoom-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var zoom = (function(){
+
+	// The current zoom level (scale)
+	var level = 1;
+
+	// The current mouse position, used for panning
+	var mouseX = 0,
+		mouseY = 0;
+
+	// Timeout before pan is activated
+	var panEngageTimeout = -1,
+		panUpdateInterval = -1;
+
+	var currentOptions = null;
+
+	// Check for transform support so that we can fallback otherwise
+	var supportsTransforms = 	'WebkitTransform' in document.body.style ||
+								'MozTransform' in document.body.style ||
+								'msTransform' in document.body.style ||
+								'OTransform' in document.body.style ||
+								'transform' in document.body.style;
+
+	if( supportsTransforms ) {
+		// The easing that will be applied when we zoom in/out
+		document.body.style.transition = 'transform 0.8s ease';
+		document.body.style.OTransition = '-o-transform 0.8s ease';
+		document.body.style.msTransition = '-ms-transform 0.8s ease';
+		document.body.style.MozTransition = '-moz-transform 0.8s ease';
+		document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
+	}
+
+	// Zoom out if the user hits escape
+	document.addEventListener( 'keyup', function( event ) {
+		if( level !== 1 && event.keyCode === 27 ) {
+			zoom.out();
+		}
+	}, false );
+
+	// Monitor mouse movement for panning
+	document.addEventListener( 'mousemove', function( event ) {
+		if( level !== 1 ) {
+			mouseX = event.clientX;
+			mouseY = event.clientY;
+		}
+	}, false );
+
+	/**
+	 * Applies the CSS required to zoom in, prioritizes use of CSS3
+	 * transforms but falls back on zoom for IE.
+	 *
+	 * @param {Number} pageOffsetX
+	 * @param {Number} pageOffsetY
+	 * @param {Number} elementOffsetX
+	 * @param {Number} elementOffsetY
+	 * @param {Number} scale
+	 */
+	function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) {
+
+		if( supportsTransforms ) {
+			var origin = pageOffsetX +'px '+ pageOffsetY +'px',
+				transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')';
+
+			document.body.style.transformOrigin = origin;
+			document.body.style.OTransformOrigin = origin;
+			document.body.style.msTransformOrigin = origin;
+			document.body.style.MozTransformOrigin = origin;
+			document.body.style.WebkitTransformOrigin = origin;
+
+			document.body.style.transform = transform;
+			document.body.style.OTransform = transform;
+			document.body.style.msTransform = transform;
+			document.body.style.MozTransform = transform;
+			document.body.style.WebkitTransform = transform;
+		}
+		else {
+			// Reset all values
+			if( scale === 1 ) {
+				document.body.style.position = '';
+				document.body.style.left = '';
+				document.body.style.top = '';
+				document.body.style.width = '';
+				document.body.style.height = '';
+				document.body.style.zoom = '';
+			}
+			// Apply scale
+			else {
+				document.body.style.position = 'relative';
+				document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px';
+				document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px';
+				document.body.style.width = ( scale * 100 ) + '%';
+				document.body.style.height = ( scale * 100 ) + '%';
+				document.body.style.zoom = scale;
+			}
+		}
+
+		level = scale;
+
+		if( level !== 1 && document.documentElement.classList ) {
+			document.documentElement.classList.add( 'zoomed' );
+		}
+		else {
+			document.documentElement.classList.remove( 'zoomed' );
+		}
+	}
+
+	/**
+	 * Pan the document when the mosue cursor approaches the edges
+	 * of the window.
+	 */
+	function pan() {
+		var range = 0.12,
+			rangeX = window.innerWidth * range,
+			rangeY = window.innerHeight * range,
+			scrollOffset = getScrollOffset();
+
+		// Up
+		if( mouseY < rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
+		}
+		// Down
+		else if( mouseY > window.innerHeight - rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
+		}
+
+		// Left
+		if( mouseX < rangeX ) {
+			window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
+		}
+		// Right
+		else if( mouseX > window.innerWidth - rangeX ) {
+			window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
+		}
+	}
+
+	function getScrollOffset() {
+		return {
+			x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
+			y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset
+		}
+	}
+
+	return {
+		/**
+		 * Zooms in on either a rectangle or HTML element.
+		 *
+		 * @param {Object} options
+		 *   - element: HTML element to zoom in on
+		 *   OR
+		 *   - x/y: coordinates in non-transformed space to zoom in on
+		 *   - width/height: the portion of the screen to zoom in on
+		 *   - scale: can be used instead of width/height to explicitly set scale
+		 */
+		to: function( options ) {
+			// Due to an implementation limitation we can't zoom in
+			// to another element without zooming out first
+			if( level !== 1 ) {
+				zoom.out();
+			}
+			else {
+				options.x = options.x || 0;
+				options.y = options.y || 0;
+
+				// If an element is set, that takes precedence
+				if( !!options.element ) {
+					// Space around the zoomed in element to leave on screen
+					var padding = 20;
+
+					options.width = options.element.getBoundingClientRect().width + ( padding * 2 );
+					options.height = options.element.getBoundingClientRect().height + ( padding * 2 );
+					options.x = options.element.getBoundingClientRect().left - padding;
+					options.y = options.element.getBoundingClientRect().top - padding;
+				}
+
+				// If width/height values are set, calculate scale from those values
+				if( options.width !== undefined && options.height !== undefined ) {
+					options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
+				}
+
+				if( options.scale > 1 ) {
+					options.x *= options.scale;
+					options.y *= options.scale;
+
+					var scrollOffset = getScrollOffset();
+
+					if( options.element ) {
+						scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2;
+					}
+
+					magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale );
+
+					if( options.pan !== false ) {
+
+						// Wait with engaging panning as it may conflict with the
+						// zoom transition
+						panEngageTimeout = setTimeout( function() {
+							panUpdateInterval = setInterval( pan, 1000 / 60 );
+						}, 800 );
+
+					}
+				}
+
+				currentOptions = options;
+			}
+		},
+
+		/**
+		 * Resets the document zoom state to its default.
+		 */
+		out: function() {
+			clearTimeout( panEngageTimeout );
+			clearInterval( panUpdateInterval );
+
+			var scrollOffset = getScrollOffset();
+
+			if( currentOptions && currentOptions.element ) {
+				scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2;
+			}
+
+			magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 );
+
+			level = 1;
+		},
+
+		// Alias
+		magnify: function( options ) { this.to( options ) },
+		reset: function() { this.out() },
+
+		zoomLevel: function() {
+			return level;
+		}
+	}
+
+})();
+
diff --git a/docs/slides/plpv14/reveal.js/test/examples/assets/image1.png b/docs/slides/plpv14/reveal.js/test/examples/assets/image1.png
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/reveal.js/test/examples/assets/image1.png differ
diff --git a/docs/slides/plpv14/reveal.js/test/examples/assets/image2.png b/docs/slides/plpv14/reveal.js/test/examples/assets/image2.png
new file mode 100644
Binary files /dev/null and b/docs/slides/plpv14/reveal.js/test/examples/assets/image2.png differ
diff --git a/docs/slides/plpv14/reveal.js/test/qunit-1.12.0.css b/docs/slides/plpv14/reveal.js/test/qunit-1.12.0.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/test/qunit-1.12.0.css
@@ -0,0 +1,244 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+	margin: 0;
+	padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+	padding: 0.5em 0 0.5em 1em;
+
+	color: #8699a4;
+	background-color: #0d3349;
+
+	font-size: 1.5em;
+	line-height: 1em;
+	font-weight: normal;
+
+	border-radius: 5px 5px 0 0;
+	-moz-border-radius: 5px 5px 0 0;
+	-webkit-border-top-right-radius: 5px;
+	-webkit-border-top-left-radius: 5px;
+}
+
+#qunit-header a {
+	text-decoration: none;
+	color: #c2ccd1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+	color: #fff;
+}
+
+#qunit-testrunner-toolbar label {
+	display: inline-block;
+	padding: 0 .5em 0 .1em;
+}
+
+#qunit-banner {
+	height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+	padding: 0.5em 0 0.5em 2em;
+	color: #5E740B;
+	background-color: #eee;
+	overflow: hidden;
+}
+
+#qunit-userAgent {
+	padding: 0.5em 0 0.5em 2.5em;
+	background-color: #2b81af;
+	color: #fff;
+	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+#qunit-modulefilter-container {
+	float: right;
+}
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+	list-style-position: inside;
+}
+
+#qunit-tests li {
+	padding: 0.4em 0.5em 0.4em 2.5em;
+	border-bottom: 1px solid #fff;
+	list-style-position: inside;
+}
+
+#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
+	display: none;
+}
+
+#qunit-tests li strong {
+	cursor: pointer;
+}
+
+#qunit-tests li a {
+	padding: 0.5em;
+	color: #c2ccd1;
+	text-decoration: none;
+}
+#qunit-tests li a:hover,
+#qunit-tests li a:focus {
+	color: #000;
+}
+
+#qunit-tests li .runtime {
+	float: right;
+	font-size: smaller;
+}
+
+.qunit-assert-list {
+	margin-top: 0.5em;
+	padding: 0.5em;
+
+	background-color: #fff;
+
+	border-radius: 5px;
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+}
+
+.qunit-collapsed {
+	display: none;
+}
+
+#qunit-tests table {
+	border-collapse: collapse;
+	margin-top: .2em;
+}
+
+#qunit-tests th {
+	text-align: right;
+	vertical-align: top;
+	padding: 0 .5em 0 0;
+}
+
+#qunit-tests td {
+	vertical-align: top;
+}
+
+#qunit-tests pre {
+	margin: 0;
+	white-space: pre-wrap;
+	word-wrap: break-word;
+}
+
+#qunit-tests del {
+	background-color: #e0f2be;
+	color: #374e0c;
+	text-decoration: none;
+}
+
+#qunit-tests ins {
+	background-color: #ffcaca;
+	color: #500;
+	text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts                       { color: black; }
+#qunit-tests b.passed                       { color: #5E740B; }
+#qunit-tests b.failed                       { color: #710909; }
+
+#qunit-tests li li {
+	padding: 5px;
+	background-color: #fff;
+	border-bottom: none;
+	list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+	color: #3c510c;
+	background-color: #fff;
+	border-left: 10px solid #C6E746;
+}
+
+#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name               { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected           { color: #999999; }
+
+#qunit-banner.qunit-pass                    { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+	color: #710909;
+	background-color: #fff;
+	border-left: 10px solid #EE5757;
+	white-space: pre;
+}
+
+#qunit-tests > li:last-child {
+	border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-webkit-border-bottom-right-radius: 5px;
+	-webkit-border-bottom-left-radius: 5px;
+}
+
+#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name             { color: #000000; }
+
+#qunit-tests .fail .test-actual             { color: #EE5757; }
+#qunit-tests .fail .test-expected           { color: green;   }
+
+#qunit-banner.qunit-fail                    { background-color: #EE5757; }
+
+
+/** Result */
+
+#qunit-testresult {
+	padding: 0.5em 0.5em 0.5em 2.5em;
+
+	color: #2b81af;
+	background-color: #D2E0E6;
+
+	border-bottom: 1px solid white;
+}
+#qunit-testresult .module-name {
+	font-weight: bold;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+	position: absolute;
+	top: -10000px;
+	left: -10000px;
+	width: 1000px;
+	height: 1000px;
+}
diff --git a/docs/slides/plpv14/reveal.js/test/qunit-1.12.0.js b/docs/slides/plpv14/reveal.js/test/qunit-1.12.0.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/test/qunit-1.12.0.js
@@ -0,0 +1,2212 @@
+/**
+ * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * https://jquery.org/license/
+ */
+
+(function( window ) {
+
+var QUnit,
+	assert,
+	config,
+	onErrorFnPrev,
+	testId = 0,
+	fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	// Keep a local reference to Date (GH-283)
+	Date = window.Date,
+	setTimeout = window.setTimeout,
+	defined = {
+		setTimeout: typeof window.setTimeout !== "undefined",
+		sessionStorage: (function() {
+			var x = "qunit-test-string";
+			try {
+				sessionStorage.setItem( x, x );
+				sessionStorage.removeItem( x );
+				return true;
+			} catch( e ) {
+				return false;
+			}
+		}())
+	},
+	/**
+	 * Provides a normalized error string, correcting an issue
+	 * with IE 7 (and prior) where Error.prototype.toString is
+	 * not properly implemented
+	 *
+	 * Based on http://es5.github.com/#x15.11.4.4
+	 *
+	 * @param {String|Error} error
+	 * @return {String} error message
+	 */
+	errorString = function( error ) {
+		var name, message,
+			errorString = error.toString();
+		if ( errorString.substring( 0, 7 ) === "[object" ) {
+			name = error.name ? error.name.toString() : "Error";
+			message = error.message ? error.message.toString() : "";
+			if ( name && message ) {
+				return name + ": " + message;
+			} else if ( name ) {
+				return name;
+			} else if ( message ) {
+				return message;
+			} else {
+				return "Error";
+			}
+		} else {
+			return errorString;
+		}
+	},
+	/**
+	 * Makes a clone of an object using only Array or Object as base,
+	 * and copies over the own enumerable properties.
+	 *
+	 * @param {Object} obj
+	 * @return {Object} New object with only the own properties (recursively).
+	 */
+	objectValues = function( obj ) {
+		// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
+		/*jshint newcap: false */
+		var key, val,
+			vals = QUnit.is( "array", obj ) ? [] : {};
+		for ( key in obj ) {
+			if ( hasOwn.call( obj, key ) ) {
+				val = obj[key];
+				vals[key] = val === Object(val) ? objectValues(val) : val;
+			}
+		}
+		return vals;
+	};
+
+function Test( settings ) {
+	extend( this, settings );
+	this.assertions = [];
+	this.testNumber = ++Test.count;
+}
+
+Test.count = 0;
+
+Test.prototype = {
+	init: function() {
+		var a, b, li,
+			tests = id( "qunit-tests" );
+
+		if ( tests ) {
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml;
+
+			// `a` initialized at top of scope
+			a = document.createElement( "a" );
+			a.innerHTML = "Rerun";
+			a.href = QUnit.url({ testNumber: this.testNumber });
+
+			li = document.createElement( "li" );
+			li.appendChild( b );
+			li.appendChild( a );
+			li.className = "running";
+			li.id = this.id = "qunit-test-output" + testId++;
+
+			tests.appendChild( li );
+		}
+	},
+	setup: function() {
+		if (
+			// Emit moduleStart when we're switching from one module to another
+			this.module !== config.previousModule ||
+				// They could be equal (both undefined) but if the previousModule property doesn't
+				// yet exist it means this is the first test in a suite that isn't wrapped in a
+				// module, in which case we'll just emit a moduleStart event for 'undefined'.
+				// Without this, reporters can get testStart before moduleStart  which is a problem.
+				!hasOwn.call( config, "previousModule" )
+		) {
+			if ( hasOwn.call( config, "previousModule" ) ) {
+				runLoggingCallbacks( "moduleDone", QUnit, {
+					name: config.previousModule,
+					failed: config.moduleStats.bad,
+					passed: config.moduleStats.all - config.moduleStats.bad,
+					total: config.moduleStats.all
+				});
+			}
+			config.previousModule = this.module;
+			config.moduleStats = { all: 0, bad: 0 };
+			runLoggingCallbacks( "moduleStart", QUnit, {
+				name: this.module
+			});
+		}
+
+		config.current = this;
+
+		this.testEnvironment = extend({
+			setup: function() {},
+			teardown: function() {}
+		}, this.moduleTestEnvironment );
+
+		this.started = +new Date();
+		runLoggingCallbacks( "testStart", QUnit, {
+			name: this.testName,
+			module: this.module
+		});
+
+		/*jshint camelcase:false */
+
+
+		/**
+		 * Expose the current test environment.
+		 *
+		 * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
+		 */
+		QUnit.current_testEnvironment = this.testEnvironment;
+
+		/*jshint camelcase:true */
+
+		if ( !config.pollution ) {
+			saveGlobal();
+		}
+		if ( config.notrycatch ) {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+			return;
+		}
+		try {
+			this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+		} catch( e ) {
+			QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+		}
+	},
+	run: function() {
+		config.current = this;
+
+		var running = id( "qunit-testresult" );
+
+		if ( running ) {
+			running.innerHTML = "Running: <br/>" + this.nameHtml;
+		}
+
+		if ( this.async ) {
+			QUnit.stop();
+		}
+
+		this.callbackStarted = +new Date();
+
+		if ( config.notrycatch ) {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+			return;
+		}
+
+		try {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+		} catch( e ) {
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+
+			QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
+			// else next test will carry the responsibility
+			saveGlobal();
+
+			// Restart the tests if they're blocking
+			if ( config.blocking ) {
+				QUnit.start();
+			}
+		}
+	},
+	teardown: function() {
+		config.current = this;
+		if ( config.notrycatch ) {
+			if ( typeof this.callbackRuntime === "undefined" ) {
+				this.callbackRuntime = +new Date() - this.callbackStarted;
+			}
+			this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			return;
+		} else {
+			try {
+				this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+			} catch( e ) {
+				QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+			}
+		}
+		checkPollution();
+	},
+	finish: function() {
+		config.current = this;
+		if ( config.requireExpects && this.expected === null ) {
+			QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
+		} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
+			QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
+		} else if ( this.expected === null && !this.assertions.length ) {
+			QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
+		}
+
+		var i, assertion, a, b, time, li, ol,
+			test = this,
+			good = 0,
+			bad = 0,
+			tests = id( "qunit-tests" );
+
+		this.runtime = +new Date() - this.started;
+		config.stats.all += this.assertions.length;
+		config.moduleStats.all += this.assertions.length;
+
+		if ( tests ) {
+			ol = document.createElement( "ol" );
+			ol.className = "qunit-assert-list";
+
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				assertion = this.assertions[i];
+
+				li = document.createElement( "li" );
+				li.className = assertion.result ? "pass" : "fail";
+				li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
+				ol.appendChild( li );
+
+				if ( assertion.result ) {
+					good++;
+				} else {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+
+			// store result when possible
+			if ( QUnit.config.reorder && defined.sessionStorage ) {
+				if ( bad ) {
+					sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
+				} else {
+					sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
+				}
+			}
+
+			if ( bad === 0 ) {
+				addClass( ol, "qunit-collapsed" );
+			}
+
+			// `b` initialized at top of scope
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+
+			addEvent(b, "click", function() {
+				var next = b.parentNode.lastChild,
+					collapsed = hasClass( next, "qunit-collapsed" );
+				( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
+			});
+
+			addEvent(b, "dblclick", function( e ) {
+				var target = e && e.target ? e.target : window.event.srcElement;
+				if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
+					target = target.parentNode;
+				}
+				if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
+					window.location = QUnit.url({ testNumber: test.testNumber });
+				}
+			});
+
+			// `time` initialized at top of scope
+			time = document.createElement( "span" );
+			time.className = "runtime";
+			time.innerHTML = this.runtime + " ms";
+
+			// `li` initialized at top of scope
+			li = id( this.id );
+			li.className = bad ? "fail" : "pass";
+			li.removeChild( li.firstChild );
+			a = li.firstChild;
+			li.appendChild( b );
+			li.appendChild( a );
+			li.appendChild( time );
+			li.appendChild( ol );
+
+		} else {
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				if ( !this.assertions[i].result ) {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+		}
+
+		runLoggingCallbacks( "testDone", QUnit, {
+			name: this.testName,
+			module: this.module,
+			failed: bad,
+			passed: this.assertions.length - bad,
+			total: this.assertions.length,
+			duration: this.runtime
+		});
+
+		QUnit.reset();
+
+		config.current = undefined;
+	},
+
+	queue: function() {
+		var bad,
+			test = this;
+
+		synchronize(function() {
+			test.init();
+		});
+		function run() {
+			// each of these can by async
+			synchronize(function() {
+				test.setup();
+			});
+			synchronize(function() {
+				test.run();
+			});
+			synchronize(function() {
+				test.teardown();
+			});
+			synchronize(function() {
+				test.finish();
+			});
+		}
+
+		// `bad` initialized at top of scope
+		// defer when previous test run passed, if storage is available
+		bad = QUnit.config.reorder && defined.sessionStorage &&
+						+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
+
+		if ( bad ) {
+			run();
+		} else {
+			synchronize( run, true );
+		}
+	}
+};
+
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+QUnit = {
+
+	// call on start of module test to prepend name to all tests
+	module: function( name, testEnvironment ) {
+		config.currentModule = name;
+		config.currentModuleTestEnvironment = testEnvironment;
+		config.modules[name] = true;
+	},
+
+	asyncTest: function( testName, expected, callback ) {
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		QUnit.test( testName, expected, callback, true );
+	},
+
+	test: function( testName, expected, callback, async ) {
+		var test,
+			nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
+
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		if ( config.currentModule ) {
+			nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
+		}
+
+		test = new Test({
+			nameHtml: nameHtml,
+			testName: testName,
+			expected: expected,
+			async: async,
+			callback: callback,
+			module: config.currentModule,
+			moduleTestEnvironment: config.currentModuleTestEnvironment,
+			stack: sourceFromStacktrace( 2 )
+		});
+
+		if ( !validTest( test ) ) {
+			return;
+		}
+
+		test.queue();
+	},
+
+	// Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
+	expect: function( asserts ) {
+		if (arguments.length === 1) {
+			config.current.expected = asserts;
+		} else {
+			return config.current.expected;
+		}
+	},
+
+	start: function( count ) {
+		// QUnit hasn't been initialized yet.
+		// Note: RequireJS (et al) may delay onLoad
+		if ( config.semaphore === undefined ) {
+			QUnit.begin(function() {
+				// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+				setTimeout(function() {
+					QUnit.start( count );
+				});
+			});
+			return;
+		}
+
+		config.semaphore -= count || 1;
+		// don't start until equal number of stop-calls
+		if ( config.semaphore > 0 ) {
+			return;
+		}
+		// ignore if start is called more often then stop
+		if ( config.semaphore < 0 ) {
+			config.semaphore = 0;
+			QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
+			return;
+		}
+		// A slight delay, to avoid any current callbacks
+		if ( defined.setTimeout ) {
+			setTimeout(function() {
+				if ( config.semaphore > 0 ) {
+					return;
+				}
+				if ( config.timeout ) {
+					clearTimeout( config.timeout );
+				}
+
+				config.blocking = false;
+				process( true );
+			}, 13);
+		} else {
+			config.blocking = false;
+			process( true );
+		}
+	},
+
+	stop: function( count ) {
+		config.semaphore += count || 1;
+		config.blocking = true;
+
+		if ( config.testTimeout && defined.setTimeout ) {
+			clearTimeout( config.timeout );
+			config.timeout = setTimeout(function() {
+				QUnit.ok( false, "Test timed out" );
+				config.semaphore = 1;
+				QUnit.start();
+			}, config.testTimeout );
+		}
+	}
+};
+
+// `assert` initialized at top of scope
+// Assert helpers
+// All of these must either call QUnit.push() or manually do:
+// - runLoggingCallbacks( "log", .. );
+// - config.current.assertions.push({ .. });
+// We attach it to the QUnit object *after* we expose the public API,
+// otherwise `assert` will become a global variable in browsers (#341).
+assert = {
+	/**
+	 * Asserts rough true-ish result.
+	 * @name ok
+	 * @function
+	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+	 */
+	ok: function( result, msg ) {
+		if ( !config.current ) {
+			throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+		result = !!result;
+		msg = msg || (result ? "okay" : "failed" );
+
+		var source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: msg
+			};
+
+		msg = "<span class='test-message'>" + escapeText( msg ) + "</span>";
+
+		if ( !result ) {
+			source = sourceFromStacktrace( 2 );
+			if ( source ) {
+				details.source = source;
+				msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
+			}
+		}
+		runLoggingCallbacks( "log", QUnit, details );
+		config.current.assertions.push({
+			result: result,
+			message: msg
+		});
+	},
+
+	/**
+	 * Assert that the first two arguments are equal, with an optional message.
+	 * Prints out both actual and expected values.
+	 * @name equal
+	 * @function
+	 * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
+	 */
+	equal: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected == actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notEqual
+	 * @function
+	 */
+	notEqual: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected != actual, actual, expected, message );
+	},
+
+	/**
+	 * @name propEqual
+	 * @function
+	 */
+	propEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notPropEqual
+	 * @function
+	 */
+	notPropEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name deepEqual
+	 * @function
+	 */
+	deepEqual: function( actual, expected, message ) {
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notDeepEqual
+	 * @function
+	 */
+	notDeepEqual: function( actual, expected, message ) {
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name strictEqual
+	 * @function
+	 */
+	strictEqual: function( actual, expected, message ) {
+		QUnit.push( expected === actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notStrictEqual
+	 * @function
+	 */
+	notStrictEqual: function( actual, expected, message ) {
+		QUnit.push( expected !== actual, actual, expected, message );
+	},
+
+	"throws": function( block, expected, message ) {
+		var actual,
+			expectedOutput = expected,
+			ok = false;
+
+		// 'expected' is optional
+		if ( typeof expected === "string" ) {
+			message = expected;
+			expected = null;
+		}
+
+		config.current.ignoreGlobalErrors = true;
+		try {
+			block.call( config.current.testEnvironment );
+		} catch (e) {
+			actual = e;
+		}
+		config.current.ignoreGlobalErrors = false;
+
+		if ( actual ) {
+			// we don't want to validate thrown error
+			if ( !expected ) {
+				ok = true;
+				expectedOutput = null;
+			// expected is a regexp
+			} else if ( QUnit.objectType( expected ) === "regexp" ) {
+				ok = expected.test( errorString( actual ) );
+			// expected is a constructor
+			} else if ( actual instanceof expected ) {
+				ok = true;
+			// expected is a validation function which returns true is validation passed
+			} else if ( expected.call( {}, actual ) === true ) {
+				expectedOutput = null;
+				ok = true;
+			}
+
+			QUnit.push( ok, actual, expectedOutput, message );
+		} else {
+			QUnit.pushFailure( message, null, "No exception was thrown." );
+		}
+	}
+};
+
+/**
+ * @deprecated since 1.8.0
+ * Kept assertion helpers in root for backwards compatibility.
+ */
+extend( QUnit, assert );
+
+/**
+ * @deprecated since 1.9.0
+ * Kept root "raises()" for backwards compatibility.
+ * (Note that we don't introduce assert.raises).
+ */
+QUnit.raises = assert[ "throws" ];
+
+/**
+ * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
+ * Kept to avoid TypeErrors for undefined methods.
+ */
+QUnit.equals = function() {
+	QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
+};
+QUnit.same = function() {
+	QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
+};
+
+// We want access to the constructor's prototype
+(function() {
+	function F() {}
+	F.prototype = QUnit;
+	QUnit = new F();
+	// Make F QUnit's constructor so that we can add to the prototype later
+	QUnit.constructor = F;
+}());
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+	// The queue of tests to run
+	queue: [],
+
+	// block until document ready
+	blocking: true,
+
+	// when enabled, show only failing tests
+	// gets persisted through sessionStorage and can be changed in UI via checkbox
+	hidepassed: false,
+
+	// by default, run previously failed tests first
+	// very useful in combination with "Hide passed tests" checked
+	reorder: true,
+
+	// by default, modify document.title when suite is done
+	altertitle: true,
+
+	// when enabled, all tests must call expect()
+	requireExpects: false,
+
+	// add checkboxes that are persisted in the query-string
+	// when enabled, the id is set to `true` as a `QUnit.config` property
+	urlConfig: [
+		{
+			id: "noglobals",
+			label: "Check for Globals",
+			tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
+		},
+		{
+			id: "notrycatch",
+			label: "No try-catch",
+			tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
+		}
+	],
+
+	// Set of all modules.
+	modules: {},
+
+	// logging callback queues
+	begin: [],
+	done: [],
+	log: [],
+	testStart: [],
+	testDone: [],
+	moduleStart: [],
+	moduleDone: []
+};
+
+// Export global variables, unless an 'exports' object exists,
+// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
+if ( typeof exports === "undefined" ) {
+	extend( window, QUnit.constructor.prototype );
+
+	// Expose QUnit object
+	window.QUnit = QUnit;
+}
+
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+	var i,
+		location = window.location || { search: "", protocol: "file:" },
+		params = location.search.slice( 1 ).split( "&" ),
+		length = params.length,
+		urlParams = {},
+		current;
+
+	if ( params[ 0 ] ) {
+		for ( i = 0; i < length; i++ ) {
+			current = params[ i ].split( "=" );
+			current[ 0 ] = decodeURIComponent( current[ 0 ] );
+			// allow just a key to turn on a flag, e.g., test.html?noglobals
+			current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
+			urlParams[ current[ 0 ] ] = current[ 1 ];
+		}
+	}
+
+	QUnit.urlParams = urlParams;
+
+	// String search anywhere in moduleName+testName
+	config.filter = urlParams.filter;
+
+	// Exact match of the module name
+	config.module = urlParams.module;
+
+	config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
+
+	// Figure out if we're running the tests from a server or not
+	QUnit.isLocal = location.protocol === "file:";
+}());
+
+// Extend QUnit object,
+// these after set here because they should not be exposed as global functions
+extend( QUnit, {
+	assert: assert,
+
+	config: config,
+
+	// Initialize the configuration options
+	init: function() {
+		extend( config, {
+			stats: { all: 0, bad: 0 },
+			moduleStats: { all: 0, bad: 0 },
+			started: +new Date(),
+			updateRate: 1000,
+			blocking: false,
+			autostart: true,
+			autorun: false,
+			filter: "",
+			queue: [],
+			semaphore: 1
+		});
+
+		var tests, banner, result,
+			qunit = id( "qunit" );
+
+		if ( qunit ) {
+			qunit.innerHTML =
+				"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+				"<h2 id='qunit-banner'></h2>" +
+				"<div id='qunit-testrunner-toolbar'></div>" +
+				"<h2 id='qunit-userAgent'></h2>" +
+				"<ol id='qunit-tests'></ol>";
+		}
+
+		tests = id( "qunit-tests" );
+		banner = id( "qunit-banner" );
+		result = id( "qunit-testresult" );
+
+		if ( tests ) {
+			tests.innerHTML = "";
+		}
+
+		if ( banner ) {
+			banner.className = "";
+		}
+
+		if ( result ) {
+			result.parentNode.removeChild( result );
+		}
+
+		if ( tests ) {
+			result = document.createElement( "p" );
+			result.id = "qunit-testresult";
+			result.className = "result";
+			tests.parentNode.insertBefore( result, tests );
+			result.innerHTML = "Running...<br/>&nbsp;";
+		}
+	},
+
+	// Resets the test setup. Useful for tests that modify the DOM.
+	/*
+	DEPRECATED: Use multiple tests instead of resetting inside a test.
+	Use testStart or testDone for custom cleanup.
+	This method will throw an error in 2.0, and will be removed in 2.1
+	*/
+	reset: function() {
+		var fixture = id( "qunit-fixture" );
+		if ( fixture ) {
+			fixture.innerHTML = config.fixture;
+		}
+	},
+
+	// Trigger an event on an element.
+	// @example triggerEvent( document.body, "click" );
+	triggerEvent: function( elem, type, event ) {
+		if ( document.createEvent ) {
+			event = document.createEvent( "MouseEvents" );
+			event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+				0, 0, 0, 0, 0, false, false, false, false, 0, null);
+
+			elem.dispatchEvent( event );
+		} else if ( elem.fireEvent ) {
+			elem.fireEvent( "on" + type );
+		}
+	},
+
+	// Safe object type checking
+	is: function( type, obj ) {
+		return QUnit.objectType( obj ) === type;
+	},
+
+	objectType: function( obj ) {
+		if ( typeof obj === "undefined" ) {
+				return "undefined";
+		// consider: typeof null === object
+		}
+		if ( obj === null ) {
+				return "null";
+		}
+
+		var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+			type = match && match[1] || "";
+
+		switch ( type ) {
+			case "Number":
+				if ( isNaN(obj) ) {
+					return "nan";
+				}
+				return "number";
+			case "String":
+			case "Boolean":
+			case "Array":
+			case "Date":
+			case "RegExp":
+			case "Function":
+				return type.toLowerCase();
+		}
+		if ( typeof obj === "object" ) {
+			return "object";
+		}
+		return undefined;
+	},
+
+	push: function( result, actual, expected, message ) {
+		if ( !config.current ) {
+			throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
+		}
+
+		var output, source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: message,
+				actual: actual,
+				expected: expected
+			};
+
+		message = escapeText( message ) || ( result ? "okay" : "failed" );
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		if ( !result ) {
+			expected = escapeText( QUnit.jsDump.parse(expected) );
+			actual = escapeText( QUnit.jsDump.parse(actual) );
+			output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
+
+			if ( actual !== expected ) {
+				output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
+				output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
+			}
+
+			source = sourceFromStacktrace();
+
+			if ( source ) {
+				details.source = source;
+				output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+			}
+
+			output += "</table>";
+		}
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: !!result,
+			message: output
+		});
+	},
+
+	pushFailure: function( message, source, actual ) {
+		if ( !config.current ) {
+			throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+
+		var output,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: false,
+				message: message
+			};
+
+		message = escapeText( message ) || "error";
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		output += "<table>";
+
+		if ( actual ) {
+			output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
+		}
+
+		if ( source ) {
+			details.source = source;
+			output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+		}
+
+		output += "</table>";
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: false,
+			message: output
+		});
+	},
+
+	url: function( params ) {
+		params = extend( extend( {}, QUnit.urlParams ), params );
+		var key,
+			querystring = "?";
+
+		for ( key in params ) {
+			if ( hasOwn.call( params, key ) ) {
+				querystring += encodeURIComponent( key ) + "=" +
+					encodeURIComponent( params[ key ] ) + "&";
+			}
+		}
+		return window.location.protocol + "//" + window.location.host +
+			window.location.pathname + querystring.slice( 0, -1 );
+	},
+
+	extend: extend,
+	id: id,
+	addEvent: addEvent,
+	addClass: addClass,
+	hasClass: hasClass,
+	removeClass: removeClass
+	// load, equiv, jsDump, diff: Attached later
+});
+
+/**
+ * @deprecated: Created for backwards compatibility with test runner that set the hook function
+ * into QUnit.{hook}, instead of invoking it and passing the hook function.
+ * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
+ * Doing this allows us to tell if the following methods have been overwritten on the actual
+ * QUnit object.
+ */
+extend( QUnit.constructor.prototype, {
+
+	// Logging callbacks; all receive a single argument with the listed properties
+	// run test/logs.html for any related changes
+	begin: registerLoggingCallback( "begin" ),
+
+	// done: { failed, passed, total, runtime }
+	done: registerLoggingCallback( "done" ),
+
+	// log: { result, actual, expected, message }
+	log: registerLoggingCallback( "log" ),
+
+	// testStart: { name }
+	testStart: registerLoggingCallback( "testStart" ),
+
+	// testDone: { name, failed, passed, total, duration }
+	testDone: registerLoggingCallback( "testDone" ),
+
+	// moduleStart: { name }
+	moduleStart: registerLoggingCallback( "moduleStart" ),
+
+	// moduleDone: { name, failed, passed, total }
+	moduleDone: registerLoggingCallback( "moduleDone" )
+});
+
+if ( typeof document === "undefined" || document.readyState === "complete" ) {
+	config.autorun = true;
+}
+
+QUnit.load = function() {
+	runLoggingCallbacks( "begin", QUnit, {} );
+
+	// Initialize the config, saving the execution queue
+	var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
+		urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
+		numModules = 0,
+		moduleNames = [],
+		moduleFilterHtml = "",
+		urlConfigHtml = "",
+		oldconfig = extend( {}, config );
+
+	QUnit.init();
+	extend(config, oldconfig);
+
+	config.blocking = false;
+
+	len = config.urlConfig.length;
+
+	for ( i = 0; i < len; i++ ) {
+		val = config.urlConfig[i];
+		if ( typeof val === "string" ) {
+			val = {
+				id: val,
+				label: val,
+				tooltip: "[no tooltip available]"
+			};
+		}
+		config[ val.id ] = QUnit.urlParams[ val.id ];
+		urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
+			"' name='" + escapeText( val.id ) +
+			"' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
+			" title='" + escapeText( val.tooltip ) +
+			"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
+			"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
+	}
+	for ( i in config.modules ) {
+		if ( config.modules.hasOwnProperty( i ) ) {
+			moduleNames.push(i);
+		}
+	}
+	numModules = moduleNames.length;
+	moduleNames.sort( function( a, b ) {
+		return a.localeCompare( b );
+	});
+	moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+		( config.module === undefined  ? "selected='selected'" : "" ) +
+		">< All Modules ></option>";
+
+
+	for ( i = 0; i < numModules; i++) {
+			moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " +
+				( config.module === moduleNames[i] ? "selected='selected'" : "" ) +
+				">" + escapeText(moduleNames[i]) + "</option>";
+	}
+	moduleFilterHtml += "</select>";
+
+	// `userAgent` initialized at top of scope
+	userAgent = id( "qunit-userAgent" );
+	if ( userAgent ) {
+		userAgent.innerHTML = navigator.userAgent;
+	}
+
+	// `banner` initialized at top of scope
+	banner = id( "qunit-header" );
+	if ( banner ) {
+		banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
+	}
+
+	// `toolbar` initialized at top of scope
+	toolbar = id( "qunit-testrunner-toolbar" );
+	if ( toolbar ) {
+		// `filter` initialized at top of scope
+		filter = document.createElement( "input" );
+		filter.type = "checkbox";
+		filter.id = "qunit-filter-pass";
+
+		addEvent( filter, "click", function() {
+			var tmp,
+				ol = document.getElementById( "qunit-tests" );
+
+			if ( filter.checked ) {
+				ol.className = ol.className + " hidepass";
+			} else {
+				tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
+				ol.className = tmp.replace( / hidepass /, " " );
+			}
+			if ( defined.sessionStorage ) {
+				if (filter.checked) {
+					sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+				} else {
+					sessionStorage.removeItem( "qunit-filter-passed-tests" );
+				}
+			}
+		});
+
+		if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
+			filter.checked = true;
+			// `ol` initialized at top of scope
+			ol = document.getElementById( "qunit-tests" );
+			ol.className = ol.className + " hidepass";
+		}
+		toolbar.appendChild( filter );
+
+		// `label` initialized at top of scope
+		label = document.createElement( "label" );
+		label.setAttribute( "for", "qunit-filter-pass" );
+		label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
+		label.innerHTML = "Hide passed tests";
+		toolbar.appendChild( label );
+
+		urlConfigCheckboxesContainer = document.createElement("span");
+		urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
+		urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
+		// For oldIE support:
+		// * Add handlers to the individual elements instead of the container
+		// * Use "click" instead of "change"
+		// * Fallback from event.target to event.srcElement
+		addEvents( urlConfigCheckboxes, "click", function( event ) {
+			var params = {},
+				target = event.target || event.srcElement;
+			params[ target.name ] = target.checked ? true : undefined;
+			window.location = QUnit.url( params );
+		});
+		toolbar.appendChild( urlConfigCheckboxesContainer );
+
+		if (numModules > 1) {
+			moduleFilter = document.createElement( "span" );
+			moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+			moduleFilter.innerHTML = moduleFilterHtml;
+			addEvent( moduleFilter.lastChild, "change", function() {
+				var selectBox = moduleFilter.getElementsByTagName("select")[0],
+					selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+				window.location = QUnit.url({
+					module: ( selectedModule === "" ) ? undefined : selectedModule,
+					// Remove any existing filters
+					filter: undefined,
+					testNumber: undefined
+				});
+			});
+			toolbar.appendChild(moduleFilter);
+		}
+	}
+
+	// `main` initialized at top of scope
+	main = id( "qunit-fixture" );
+	if ( main ) {
+		config.fixture = main.innerHTML;
+	}
+
+	if ( config.autostart ) {
+		QUnit.start();
+	}
+};
+
+addEvent( window, "load", QUnit.load );
+
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will suppress the default browser handler,
+// returning false will let it run.
+window.onerror = function ( error, filePath, linerNr ) {
+	var ret = false;
+	if ( onErrorFnPrev ) {
+		ret = onErrorFnPrev( error, filePath, linerNr );
+	}
+
+	// Treat return value as window.onerror itself does,
+	// Only do our handling if not suppressed.
+	if ( ret !== true ) {
+		if ( QUnit.config.current ) {
+			if ( QUnit.config.current.ignoreGlobalErrors ) {
+				return true;
+			}
+			QUnit.pushFailure( error, filePath + ":" + linerNr );
+		} else {
+			QUnit.test( "global failure", extend( function() {
+				QUnit.pushFailure( error, filePath + ":" + linerNr );
+			}, { validTest: validTest } ) );
+		}
+		return false;
+	}
+
+	return ret;
+};
+
+function done() {
+	config.autorun = true;
+
+	// Log the last module results
+	if ( config.currentModule ) {
+		runLoggingCallbacks( "moduleDone", QUnit, {
+			name: config.currentModule,
+			failed: config.moduleStats.bad,
+			passed: config.moduleStats.all - config.moduleStats.bad,
+			total: config.moduleStats.all
+		});
+	}
+	delete config.previousModule;
+
+	var i, key,
+		banner = id( "qunit-banner" ),
+		tests = id( "qunit-tests" ),
+		runtime = +new Date() - config.started,
+		passed = config.stats.all - config.stats.bad,
+		html = [
+			"Tests completed in ",
+			runtime,
+			" milliseconds.<br/>",
+			"<span class='passed'>",
+			passed,
+			"</span> assertions of <span class='total'>",
+			config.stats.all,
+			"</span> passed, <span class='failed'>",
+			config.stats.bad,
+			"</span> failed."
+		].join( "" );
+
+	if ( banner ) {
+		banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
+	}
+
+	if ( tests ) {
+		id( "qunit-testresult" ).innerHTML = html;
+	}
+
+	if ( config.altertitle && typeof document !== "undefined" && document.title ) {
+		// show ✖ for good, ✔ for bad suite result in title
+		// use escape sequences in case file gets loaded with non-utf-8-charset
+		document.title = [
+			( config.stats.bad ? "\u2716" : "\u2714" ),
+			document.title.replace( /^[\u2714\u2716] /i, "" )
+		].join( " " );
+	}
+
+	// clear own sessionStorage items if all tests passed
+	if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
+		// `key` & `i` initialized at top of scope
+		for ( i = 0; i < sessionStorage.length; i++ ) {
+			key = sessionStorage.key( i++ );
+			if ( key.indexOf( "qunit-test-" ) === 0 ) {
+				sessionStorage.removeItem( key );
+			}
+		}
+	}
+
+	// scroll back to top to show results
+	if ( window.scrollTo ) {
+		window.scrollTo(0, 0);
+	}
+
+	runLoggingCallbacks( "done", QUnit, {
+		failed: config.stats.bad,
+		passed: passed,
+		total: config.stats.all,
+		runtime: runtime
+	});
+}
+
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+	var include,
+		filter = config.filter && config.filter.toLowerCase(),
+		module = config.module && config.module.toLowerCase(),
+		fullName = (test.module + ": " + test.testName).toLowerCase();
+
+	// Internally-generated tests are always valid
+	if ( test.callback && test.callback.validTest === validTest ) {
+		delete test.callback.validTest;
+		return true;
+	}
+
+	if ( config.testNumber ) {
+		return test.testNumber === config.testNumber;
+	}
+
+	if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
+		return false;
+	}
+
+	if ( !filter ) {
+		return true;
+	}
+
+	include = filter.charAt( 0 ) !== "!";
+	if ( !include ) {
+		filter = filter.slice( 1 );
+	}
+
+	// If the filter matches, we need to honour include
+	if ( fullName.indexOf( filter ) !== -1 ) {
+		return include;
+	}
+
+	// Otherwise, do the opposite
+	return !include;
+}
+
+// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
+// Later Safari and IE10 are supposed to support error.stack as well
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+	offset = offset === undefined ? 3 : offset;
+
+	var stack, include, i;
+
+	if ( e.stacktrace ) {
+		// Opera
+		return e.stacktrace.split( "\n" )[ offset + 3 ];
+	} else if ( e.stack ) {
+		// Firefox, Chrome
+		stack = e.stack.split( "\n" );
+		if (/^error$/i.test( stack[0] ) ) {
+			stack.shift();
+		}
+		if ( fileName ) {
+			include = [];
+			for ( i = offset; i < stack.length; i++ ) {
+				if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+					break;
+				}
+				include.push( stack[ i ] );
+			}
+			if ( include.length ) {
+				return include.join( "\n" );
+			}
+		}
+		return stack[ offset ];
+	} else if ( e.sourceURL ) {
+		// Safari, PhantomJS
+		// hopefully one day Safari provides actual stacktraces
+		// exclude useless self-reference for generated Error objects
+		if ( /qunit.js$/.test( e.sourceURL ) ) {
+			return;
+		}
+		// for actual exceptions, this is useful
+		return e.sourceURL + ":" + e.line;
+	}
+}
+function sourceFromStacktrace( offset ) {
+	try {
+		throw new Error();
+	} catch ( e ) {
+		return extractStacktrace( e, offset );
+	}
+}
+
+/**
+ * Escape text for attribute or text content.
+ */
+function escapeText( s ) {
+	if ( !s ) {
+		return "";
+	}
+	s = s + "";
+	// Both single quotes and double quotes (for attributes)
+	return s.replace( /['"<>&]/g, function( s ) {
+		switch( s ) {
+			case "'":
+				return "&#039;";
+			case "\"":
+				return "&quot;";
+			case "<":
+				return "&lt;";
+			case ">":
+				return "&gt;";
+			case "&":
+				return "&amp;";
+		}
+	});
+}
+
+function synchronize( callback, last ) {
+	config.queue.push( callback );
+
+	if ( config.autorun && !config.blocking ) {
+		process( last );
+	}
+}
+
+function process( last ) {
+	function next() {
+		process( last );
+	}
+	var start = new Date().getTime();
+	config.depth = config.depth ? config.depth + 1 : 1;
+
+	while ( config.queue.length && !config.blocking ) {
+		if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
+			config.queue.shift()();
+		} else {
+			setTimeout( next, 13 );
+			break;
+		}
+	}
+	config.depth--;
+	if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+		done();
+	}
+}
+
+function saveGlobal() {
+	config.pollution = [];
+
+	if ( config.noglobals ) {
+		for ( var key in window ) {
+			if ( hasOwn.call( window, key ) ) {
+				// in Opera sometimes DOM element ids show up here, ignore them
+				if ( /^qunit-test-output/.test( key ) ) {
+					continue;
+				}
+				config.pollution.push( key );
+			}
+		}
+	}
+}
+
+function checkPollution() {
+	var newGlobals,
+		deletedGlobals,
+		old = config.pollution;
+
+	saveGlobal();
+
+	newGlobals = diff( config.pollution, old );
+	if ( newGlobals.length > 0 ) {
+		QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
+	}
+
+	deletedGlobals = diff( old, config.pollution );
+	if ( deletedGlobals.length > 0 ) {
+		QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
+	}
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+	var i, j,
+		result = a.slice();
+
+	for ( i = 0; i < result.length; i++ ) {
+		for ( j = 0; j < b.length; j++ ) {
+			if ( result[i] === b[j] ) {
+				result.splice( i, 1 );
+				i--;
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+function extend( a, b ) {
+	for ( var prop in b ) {
+		if ( hasOwn.call( b, prop ) ) {
+			// Avoid "Member not found" error in IE8 caused by messing with window.constructor
+			if ( !( prop === "constructor" && a === window ) ) {
+				if ( b[ prop ] === undefined ) {
+					delete a[ prop ];
+				} else {
+					a[ prop ] = b[ prop ];
+				}
+			}
+		}
+	}
+
+	return a;
+}
+
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+	// Standards-based browsers
+	if ( elem.addEventListener ) {
+		elem.addEventListener( type, fn, false );
+	// IE
+	} else {
+		elem.attachEvent( "on" + type, fn );
+	}
+}
+
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+	var i = elems.length;
+	while ( i-- ) {
+		addEvent( elems[i], type, fn );
+	}
+}
+
+function hasClass( elem, name ) {
+	return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
+}
+
+function addClass( elem, name ) {
+	if ( !hasClass( elem, name ) ) {
+		elem.className += (elem.className ? " " : "") + name;
+	}
+}
+
+function removeClass( elem, name ) {
+	var set = " " + elem.className + " ";
+	// Class name may appear multiple times
+	while ( set.indexOf(" " + name + " ") > -1 ) {
+		set = set.replace(" " + name + " " , " ");
+	}
+	// If possible, trim it for prettiness, but not necessarily
+	elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
+}
+
+function id( name ) {
+	return !!( typeof document !== "undefined" && document && document.getElementById ) &&
+		document.getElementById( name );
+}
+
+function registerLoggingCallback( key ) {
+	return function( callback ) {
+		config[key].push( callback );
+	};
+}
+
+// Supports deprecated method of completely overwriting logging callbacks
+function runLoggingCallbacks( key, scope, args ) {
+	var i, callbacks;
+	if ( QUnit.hasOwnProperty( key ) ) {
+		QUnit[ key ].call(scope, args );
+	} else {
+		callbacks = config[ key ];
+		for ( i = 0; i < callbacks.length; i++ ) {
+			callbacks[ i ].call( scope, args );
+		}
+	}
+}
+
+// Test for equality any JavaScript type.
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = (function() {
+
+	// Call the o related callback with the given arguments.
+	function bindCallbacks( o, callbacks, args ) {
+		var prop = QUnit.objectType( o );
+		if ( prop ) {
+			if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
+				return callbacks[ prop ].apply( callbacks, args );
+			} else {
+				return callbacks[ prop ]; // or undefined
+			}
+		}
+	}
+
+	// the real equiv function
+	var innerEquiv,
+		// stack to decide between skip/abort functions
+		callers = [],
+		// stack to avoiding loops from circular referencing
+		parents = [],
+		parentsB = [],
+
+		getProto = Object.getPrototypeOf || function ( obj ) {
+			/*jshint camelcase:false */
+			return obj.__proto__;
+		},
+		callbacks = (function () {
+
+			// for string, boolean, number and null
+			function useStrictEquality( b, a ) {
+				/*jshint eqeqeq:false */
+				if ( b instanceof a.constructor || a instanceof b.constructor ) {
+					// to catch short annotation VS 'new' annotation of a
+					// declaration
+					// e.g. var i = 1;
+					// var j = new Number(1);
+					return a == b;
+				} else {
+					return a === b;
+				}
+			}
+
+			return {
+				"string": useStrictEquality,
+				"boolean": useStrictEquality,
+				"number": useStrictEquality,
+				"null": useStrictEquality,
+				"undefined": useStrictEquality,
+
+				"nan": function( b ) {
+					return isNaN( b );
+				},
+
+				"date": function( b, a ) {
+					return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
+				},
+
+				"regexp": function( b, a ) {
+					return QUnit.objectType( b ) === "regexp" &&
+						// the regex itself
+						a.source === b.source &&
+						// and its modifiers
+						a.global === b.global &&
+						// (gmi) ...
+						a.ignoreCase === b.ignoreCase &&
+						a.multiline === b.multiline &&
+						a.sticky === b.sticky;
+				},
+
+				// - skip when the property is a method of an instance (OOP)
+				// - abort otherwise,
+				// initial === would have catch identical references anyway
+				"function": function() {
+					var caller = callers[callers.length - 1];
+					return caller !== Object && typeof caller !== "undefined";
+				},
+
+				"array": function( b, a ) {
+					var i, j, len, loop, aCircular, bCircular;
+
+					// b could be an object literal here
+					if ( QUnit.objectType( b ) !== "array" ) {
+						return false;
+					}
+
+					len = a.length;
+					if ( len !== b.length ) {
+						// safe and faster
+						return false;
+					}
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+					for ( i = 0; i < len; i++ ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									parents.pop();
+									parentsB.pop();
+									return false;
+								}
+							}
+						}
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							parents.pop();
+							parentsB.pop();
+							return false;
+						}
+					}
+					parents.pop();
+					parentsB.pop();
+					return true;
+				},
+
+				"object": function( b, a ) {
+					/*jshint forin:false */
+					var i, j, loop, aCircular, bCircular,
+						// Default to true
+						eq = true,
+						aProperties = [],
+						bProperties = [];
+
+					// comparing constructors is more strict than using
+					// instanceof
+					if ( a.constructor !== b.constructor ) {
+						// Allow objects with no prototype to be equivalent to
+						// objects with Object as their constructor.
+						if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
+							( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
+								return false;
+						}
+					}
+
+					// stack constructor before traversing properties
+					callers.push( a.constructor );
+
+					// track reference to avoid circular references
+					parents.push( a );
+					parentsB.push( b );
+
+					// be strict: don't ensure hasOwnProperty and go deep
+					for ( i in a ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							aCircular = parents[j] === a[i];
+							bCircular = parentsB[j] === b[i];
+							if ( aCircular || bCircular ) {
+								if ( a[i] === b[i] || aCircular && bCircular ) {
+									loop = true;
+								} else {
+									eq = false;
+									break;
+								}
+							}
+						}
+						aProperties.push(i);
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							eq = false;
+							break;
+						}
+					}
+
+					parents.pop();
+					parentsB.pop();
+					callers.pop(); // unstack, we are done
+
+					for ( i in b ) {
+						bProperties.push( i ); // collect b's properties
+					}
+
+					// Ensures identical properties name
+					return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
+				}
+			};
+		}());
+
+	innerEquiv = function() { // can take multiple arguments
+		var args = [].slice.apply( arguments );
+		if ( args.length < 2 ) {
+			return true; // end transition
+		}
+
+		return (function( a, b ) {
+			if ( a === b ) {
+				return true; // catch the most you can
+			} else if ( a === null || b === null || typeof a === "undefined" ||
+					typeof b === "undefined" ||
+					QUnit.objectType(a) !== QUnit.objectType(b) ) {
+				return false; // don't lose time with error prone cases
+			} else {
+				return bindCallbacks(a, callbacks, [ b, a ]);
+			}
+
+			// apply transition with (1..n) arguments
+		}( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) );
+	};
+
+	return innerEquiv;
+}());
+
+/**
+ * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
+ * http://flesler.blogspot.com Licensed under BSD
+ * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
+ *
+ * @projectDescription Advanced and extensible data dumping for Javascript.
+ * @version 1.0.0
+ * @author Ariel Flesler
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
+ */
+QUnit.jsDump = (function() {
+	function quote( str ) {
+		return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
+	}
+	function literal( o ) {
+		return o + "";
+	}
+	function join( pre, arr, post ) {
+		var s = jsDump.separator(),
+			base = jsDump.indent(),
+			inner = jsDump.indent(1);
+		if ( arr.join ) {
+			arr = arr.join( "," + s + inner );
+		}
+		if ( !arr ) {
+			return pre + post;
+		}
+		return [ pre, inner + arr, base + post ].join(s);
+	}
+	function array( arr, stack ) {
+		var i = arr.length, ret = new Array(i);
+		this.up();
+		while ( i-- ) {
+			ret[i] = this.parse( arr[i] , undefined , stack);
+		}
+		this.down();
+		return join( "[", ret, "]" );
+	}
+
+	var reName = /^function (\w+)/,
+		jsDump = {
+			// type is used mostly internally, you can fix a (custom)type in advance
+			parse: function( obj, type, stack ) {
+				stack = stack || [ ];
+				var inStack, res,
+					parser = this.parsers[ type || this.typeOf(obj) ];
+
+				type = typeof parser;
+				inStack = inArray( obj, stack );
+
+				if ( inStack !== -1 ) {
+					return "recursion(" + (inStack - stack.length) + ")";
+				}
+				if ( type === "function" )  {
+					stack.push( obj );
+					res = parser.call( this, obj, stack );
+					stack.pop();
+					return res;
+				}
+				return ( type === "string" ) ? parser : this.parsers.error;
+			},
+			typeOf: function( obj ) {
+				var type;
+				if ( obj === null ) {
+					type = "null";
+				} else if ( typeof obj === "undefined" ) {
+					type = "undefined";
+				} else if ( QUnit.is( "regexp", obj) ) {
+					type = "regexp";
+				} else if ( QUnit.is( "date", obj) ) {
+					type = "date";
+				} else if ( QUnit.is( "function", obj) ) {
+					type = "function";
+				} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
+					type = "window";
+				} else if ( obj.nodeType === 9 ) {
+					type = "document";
+				} else if ( obj.nodeType ) {
+					type = "node";
+				} else if (
+					// native arrays
+					toString.call( obj ) === "[object Array]" ||
+					// NodeList objects
+					( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
+				) {
+					type = "array";
+				} else if ( obj.constructor === Error.prototype.constructor ) {
+					type = "error";
+				} else {
+					type = typeof obj;
+				}
+				return type;
+			},
+			separator: function() {
+				return this.multiline ?	this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
+			},
+			// extra can be a number, shortcut for increasing-calling-decreasing
+			indent: function( extra ) {
+				if ( !this.multiline ) {
+					return "";
+				}
+				var chr = this.indentChar;
+				if ( this.HTML ) {
+					chr = chr.replace( /\t/g, "   " ).replace( / /g, "&nbsp;" );
+				}
+				return new Array( this.depth + ( extra || 0 ) ).join(chr);
+			},
+			up: function( a ) {
+				this.depth += a || 1;
+			},
+			down: function( a ) {
+				this.depth -= a || 1;
+			},
+			setParser: function( name, parser ) {
+				this.parsers[name] = parser;
+			},
+			// The next 3 are exposed so you can use them
+			quote: quote,
+			literal: literal,
+			join: join,
+			//
+			depth: 1,
+			// This is the list of parsers, to modify them, use jsDump.setParser
+			parsers: {
+				window: "[Window]",
+				document: "[Document]",
+				error: function(error) {
+					return "Error(\"" + error.message + "\")";
+				},
+				unknown: "[Unknown]",
+				"null": "null",
+				"undefined": "undefined",
+				"function": function( fn ) {
+					var ret = "function",
+						// functions never have name in IE
+						name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
+
+					if ( name ) {
+						ret += " " + name;
+					}
+					ret += "( ";
+
+					ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
+					return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
+				},
+				array: array,
+				nodelist: array,
+				"arguments": array,
+				object: function( map, stack ) {
+					/*jshint forin:false */
+					var ret = [ ], keys, key, val, i;
+					QUnit.jsDump.up();
+					keys = [];
+					for ( key in map ) {
+						keys.push( key );
+					}
+					keys.sort();
+					for ( i = 0; i < keys.length; i++ ) {
+						key = keys[ i ];
+						val = map[ key ];
+						ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
+					}
+					QUnit.jsDump.down();
+					return join( "{", ret, "}" );
+				},
+				node: function( node ) {
+					var len, i, val,
+						open = QUnit.jsDump.HTML ? "&lt;" : "<",
+						close = QUnit.jsDump.HTML ? "&gt;" : ">",
+						tag = node.nodeName.toLowerCase(),
+						ret = open + tag,
+						attrs = node.attributes;
+
+					if ( attrs ) {
+						for ( i = 0, len = attrs.length; i < len; i++ ) {
+							val = attrs[i].nodeValue;
+							// IE6 includes all attributes in .attributes, even ones not explicitly set.
+							// Those have values like undefined, null, 0, false, "" or "inherit".
+							if ( val && val !== "inherit" ) {
+								ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
+							}
+						}
+					}
+					ret += close;
+
+					// Show content of TextNode or CDATASection
+					if ( node.nodeType === 3 || node.nodeType === 4 ) {
+						ret += node.nodeValue;
+					}
+
+					return ret + open + "/" + tag + close;
+				},
+				// function calls it internally, it's the arguments part of the function
+				functionArgs: function( fn ) {
+					var args,
+						l = fn.length;
+
+					if ( !l ) {
+						return "";
+					}
+
+					args = new Array(l);
+					while ( l-- ) {
+						// 97 is 'a'
+						args[l] = String.fromCharCode(97+l);
+					}
+					return " " + args.join( ", " ) + " ";
+				},
+				// object calls it internally, the key part of an item in a map
+				key: quote,
+				// function calls it internally, it's the content of the function
+				functionCode: "[code]",
+				// node calls it internally, it's an html attribute value
+				attribute: quote,
+				string: quote,
+				date: quote,
+				regexp: literal,
+				number: literal,
+				"boolean": literal
+			},
+			// if true, entities are escaped ( <, >, \t, space and \n )
+			HTML: false,
+			// indentation unit
+			indentChar: "  ",
+			// if true, items in a collection, are separated by a \n, else just a space.
+			multiline: true
+		};
+
+	return jsDump;
+}());
+
+// from jquery.js
+function inArray( elem, array ) {
+	if ( array.indexOf ) {
+		return array.indexOf( elem );
+	}
+
+	for ( var i = 0, length = array.length; i < length; i++ ) {
+		if ( array[ i ] === elem ) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/*
+ * Javascript Diff Algorithm
+ *  By John Resig (http://ejohn.org/)
+ *  Modified by Chu Alan "sprite"
+ *
+ * Released under the MIT license.
+ *
+ * More Info:
+ *  http://ejohn.org/projects/javascript-diff-algorithm/
+ *
+ * Usage: QUnit.diff(expected, actual)
+ *
+ * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
+ */
+QUnit.diff = (function() {
+	/*jshint eqeqeq:false, eqnull:true */
+	function diff( o, n ) {
+		var i,
+			ns = {},
+			os = {};
+
+		for ( i = 0; i < n.length; i++ ) {
+			if ( !hasOwn.call( ns, n[i] ) ) {
+				ns[ n[i] ] = {
+					rows: [],
+					o: null
+				};
+			}
+			ns[ n[i] ].rows.push( i );
+		}
+
+		for ( i = 0; i < o.length; i++ ) {
+			if ( !hasOwn.call( os, o[i] ) ) {
+				os[ o[i] ] = {
+					rows: [],
+					n: null
+				};
+			}
+			os[ o[i] ].rows.push( i );
+		}
+
+		for ( i in ns ) {
+			if ( hasOwn.call( ns, i ) ) {
+				if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
+					n[ ns[i].rows[0] ] = {
+						text: n[ ns[i].rows[0] ],
+						row: os[i].rows[0]
+					};
+					o[ os[i].rows[0] ] = {
+						text: o[ os[i].rows[0] ],
+						row: ns[i].rows[0]
+					};
+				}
+			}
+		}
+
+		for ( i = 0; i < n.length - 1; i++ ) {
+			if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
+						n[ i + 1 ] == o[ n[i].row + 1 ] ) {
+
+				n[ i + 1 ] = {
+					text: n[ i + 1 ],
+					row: n[i].row + 1
+				};
+				o[ n[i].row + 1 ] = {
+					text: o[ n[i].row + 1 ],
+					row: i + 1
+				};
+			}
+		}
+
+		for ( i = n.length - 1; i > 0; i-- ) {
+			if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
+						n[ i - 1 ] == o[ n[i].row - 1 ]) {
+
+				n[ i - 1 ] = {
+					text: n[ i - 1 ],
+					row: n[i].row - 1
+				};
+				o[ n[i].row - 1 ] = {
+					text: o[ n[i].row - 1 ],
+					row: i - 1
+				};
+			}
+		}
+
+		return {
+			o: o,
+			n: n
+		};
+	}
+
+	return function( o, n ) {
+		o = o.replace( /\s+$/, "" );
+		n = n.replace( /\s+$/, "" );
+
+		var i, pre,
+			str = "",
+			out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
+			oSpace = o.match(/\s+/g),
+			nSpace = n.match(/\s+/g);
+
+		if ( oSpace == null ) {
+			oSpace = [ " " ];
+		}
+		else {
+			oSpace.push( " " );
+		}
+
+		if ( nSpace == null ) {
+			nSpace = [ " " ];
+		}
+		else {
+			nSpace.push( " " );
+		}
+
+		if ( out.n.length === 0 ) {
+			for ( i = 0; i < out.o.length; i++ ) {
+				str += "<del>" + out.o[i] + oSpace[i] + "</del>";
+			}
+		}
+		else {
+			if ( out.n[0].text == null ) {
+				for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
+					str += "<del>" + out.o[n] + oSpace[n] + "</del>";
+				}
+			}
+
+			for ( i = 0; i < out.n.length; i++ ) {
+				if (out.n[i].text == null) {
+					str += "<ins>" + out.n[i] + nSpace[i] + "</ins>";
+				}
+				else {
+					// `pre` initialized at top of scope
+					pre = "";
+
+					for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
+						pre += "<del>" + out.o[n] + oSpace[n] + "</del>";
+					}
+					str += " " + out.n[i].text + nSpace[i] + pre;
+				}
+			}
+		}
+
+		return str;
+	};
+}());
+
+// for CommonJS environments, export everything
+if ( typeof exports !== "undefined" ) {
+	extend( exports, QUnit.constructor.prototype );
+}
+
+// get at whatever the global object is, like window in browsers
+}( (function() {return this;}.call()) ));
diff --git a/docs/slides/plpv14/reveal.js/test/test-markdown-element-attributes.js b/docs/slides/plpv14/reveal.js/test/test-markdown-element-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/test/test-markdown-element-attributes.js
@@ -0,0 +1,46 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
+	});
+
+
+	test( 'Attributes on element header in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
+	});
+
+	test( 'Attributes on element paragraphs in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
+	});
+
+	test( 'Attributes on element list items in vertical slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.roll-in' ).length, 3, 'found a vertical slide with three list items with class fragment.roll-in' );
+	});
+
+	test( 'Attributes on element paragraphs in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
+	});
+	test( 'Attributes on element list items in horizontal slides', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
+	});
+
+	test( 'Attributes on elements in vertical slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
+	});
+
+	test( 'Attributes on elements in single slides with default element attribute separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/plpv14/reveal.js/test/test-markdown-slide-attributes.js b/docs/slides/plpv14/reveal.js/test/test-markdown-slide-attributes.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/test/test-markdown-slide-attributes.js
@@ -0,0 +1,47 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' );
+	});
+
+	test( 'Id on slide', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' );
+	});
+
+	test( 'data-background attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-background attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	});
+
+	test( 'data-transition attributes with default separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	});
+
+	test( 'data-transition attributes with inline content', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' );
+	});
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/plpv14/reveal.js/test/test-markdown.js b/docs/slides/plpv14/reveal.js/test/test-markdown.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/test/test-markdown.js
@@ -0,0 +1,15 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/plpv14/reveal.js/test/test.js b/docs/slides/plpv14/reveal.js/test/test.js
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/reveal.js/test/test.js
@@ -0,0 +1,438 @@
+
+// These tests expect the DOM to contain a presentation
+// with the following slide structure:
+//
+// 1
+// 2 - Three sub-slides
+// 3 - Three fragment elements
+// 3 - Two fragments with same data-fragment-index
+// 4
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	// ---------------------------------------------------------------
+	// DOM TESTS
+
+	QUnit.module( 'DOM' );
+
+	test( 'Initial slides classes', function() {
+		var horizontalSlides = document.querySelectorAll( '.reveal .slides>section' )
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.past' ).length, 0, 'no .past slides' );
+		strictEqual( document.querySelectorAll( '.reveal .slides section.present' ).length, 1, 'one .present slide' );
+		strictEqual( document.querySelectorAll( '.reveal .slides>section.future' ).length, horizontalSlides.length - 1, 'remaining horizontal slides are .future' );
+
+		strictEqual( document.querySelectorAll( '.reveal .slides section.stack' ).length, 2, 'two .stacks' );
+
+		ok( document.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length > 0, 'vertical slides are given .future' );
+	});
+
+	// ---------------------------------------------------------------
+	// API TESTS
+
+	QUnit.module( 'API' );
+
+	test( 'Reveal.isReady', function() {
+		strictEqual( Reveal.isReady(), true, 'returns true' );
+	});
+
+	test( 'Reveal.isOverview', function() {
+		strictEqual( Reveal.isOverview(), false, 'false by default' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), true, 'true after toggling on' );
+
+		Reveal.toggleOverview();
+		strictEqual( Reveal.isOverview(), false, 'false after toggling off' );
+	});
+
+	test( 'Reveal.isPaused', function() {
+		strictEqual( Reveal.isPaused(), false, 'false by default' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), true, 'true after pausing' );
+
+		Reveal.togglePause();
+		strictEqual( Reveal.isPaused(), false, 'false after resuming' );
+	});
+
+	test( 'Reveal.isFirstSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+
+		Reveal.slide( 1, 0 );
+		strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.isLastSlide', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+
+		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
+
+		Reveal.slide( lastSlideIndex, 0 );
+		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( ', 0+ lastSlideIndex +' )' );
+
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+	});
+
+	test( 'Reveal.getIndices', function() {
+		var indices = Reveal.getIndices();
+
+		ok( typeof indices.hasOwnProperty( 'h' ), 'h exists' );
+		ok( typeof indices.hasOwnProperty( 'v' ), 'v exists' );
+		ok( typeof indices.hasOwnProperty( 'f' ), 'f exists' );
+
+		Reveal.slide( 1, 0 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 0, 'h 1, v 0' );
+
+		Reveal.slide( 1, 2 );
+		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 2, 'h 1, v 2' );
+
+		Reveal.slide( 0, 0 );
+	});
+
+	test( 'Reveal.getSlide', function() {
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+
+		equal( Reveal.getSlide( 0 ), firstSlide, 'gets correct first slide' );
+
+		strictEqual( Reveal.getSlide( 100 ), undefined, 'returns undefined when slide can\'t be found' );
+	});
+
+	test( 'Reveal.getPreviousSlide/getCurrentSlide', function() {
+		Reveal.slide( 0, 0 );
+		Reveal.slide( 1, 0 );
+
+		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+		var secondSlide = document.querySelector( '.reveal .slides>section:nth-child(2)>section' );
+
+		equal( Reveal.getPreviousSlide(), firstSlide, 'previous is slide #0' );
+		equal( Reveal.getCurrentSlide(), secondSlide, 'current is slide #1' );
+	});
+
+	test( 'Reveal.getScale', function() {
+		ok( typeof Reveal.getScale() === 'number', 'has scale' );
+	});
+
+	test( 'Reveal.getConfig', function() {
+		ok( typeof Reveal.getConfig() === 'object', 'has config' );
+	});
+
+	test( 'Reveal.configure', function() {
+		strictEqual( Reveal.getConfig().loop, false, '"loop" is false to start with' );
+
+		Reveal.configure({ loop: true });
+		strictEqual( Reveal.getConfig().loop, true, '"loop" has changed to true' );
+
+		Reveal.configure({ loop: false, customTestValue: 1 });
+		strictEqual( Reveal.getConfig().customTestValue, 1, 'supports custom values' );
+	});
+
+	test( 'Reveal.availableRoutes', function() {
+		Reveal.slide( 0, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: false, up: false, down: false, right: true }, 'correct for first slide' );
+
+		Reveal.slide( 1, 0 );
+		deepEqual( Reveal.availableRoutes(), { left: true, up: false, down: true, right: true }, 'correct for vertical slide' );
+	});
+
+	test( 'Reveal.next', function() {
+		Reveal.slide( 0, 0 );
+
+		// Step through vertical child slides
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 1, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } );
+
+		// Step through fragments
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } );
+	});
+
+	test( 'Reveal.next at end', function() {
+		Reveal.slide( 3 );
+
+		// We're at the end, this should have no effect
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+	});
+
+
+	// ---------------------------------------------------------------
+	// FRAGMENT TESTS
+
+	QUnit.module( 'Fragments' );
+
+	test( 'Sliding to fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'Reveal.slide( 2, 0, -1 )' );
+
+		Reveal.slide( 2, 0, 0 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'Reveal.slide( 2, 0, 0 )' );
+
+		Reveal.slide( 2, 0, 2 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'Reveal.slide( 2, 0, 2 )' );
+
+		Reveal.slide( 2, 0, 1 );
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'Reveal.slide( 2, 0, 1 )' );
+	});
+
+	test( 'Hiding all fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' );
+
+		Reveal.slide( 2, 0, -1 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index is -1' );
+	});
+
+	test( 'Current fragment', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 2, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
+
+		Reveal.slide( 2, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 1, 'one current fragment at index 0' );
+
+		Reveal.slide( 1, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
+	});
+
+	test( 'Stepping through fragments', function() {
+		Reveal.slide( 2, 0, -1 );
+
+		// forwards:
+
+		Reveal.next();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'next() goes to next fragment' );
+
+		Reveal.right();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'right() goes to next fragment' );
+
+		Reveal.down();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'down() goes to next fragment' );
+
+		Reveal.down(); // moves to f #3
+
+		// backwards:
+
+		Reveal.prev();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'prev() goes to prev fragment' );
+
+		Reveal.left();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'left() goes to prev fragment' );
+
+		Reveal.up();
+		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'up() goes to prev fragment' );
+	});
+
+	test( 'Stepping past fragments', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		Reveal.slide( 0, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 3, 'all fragments visible when on future slide' );
+	});
+
+	test( 'Fragment indices', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(2)' );
+
+		Reveal.slide( 3, 0, 0 );
+		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 2, 'both fragments of same index are shown' );
+	});
+
+	test( 'Index generation', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+
+		// These have no indices defined to start with
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' );
+	});
+
+	test( 'Index normalization', function() {
+		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(3)' );
+
+		// These start out as 1-4-4 and should normalize to 0-1-1
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' );
+	});
+
+	asyncTest( 'fragmentshown event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmentshown', _onEvent );
+
+		Reveal.slide( 2, 0 );
+		Reveal.slide( 2, 0 ); // should do nothing
+		Reveal.slide( 2, 0, 0 ); // should do nothing
+		Reveal.next();
+		Reveal.next();
+		Reveal.prev(); // shouldn't fire fragmentshown
+
+		start();
+
+		Reveal.removeEventListener( 'fragmentshown', _onEvent );
+	});
+
+	asyncTest( 'fragmenthidden event', function() {
+		expect( 2 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'fragmenthidden', _onEvent );
+
+		Reveal.slide( 2, 0, 2 );
+		Reveal.slide( 2, 0, 2 ); // should do nothing
+		Reveal.prev();
+		Reveal.prev();
+		Reveal.next(); // shouldn't fire fragmenthidden
+
+		start();
+
+		Reveal.removeEventListener( 'fragmenthidden', _onEvent );
+	});
+
+
+	// ---------------------------------------------------------------
+	// CONFIGURATION VALUES
+
+	QUnit.module( 'Configuration' );
+
+	test( 'Controls', function() {
+		var controlsElement = document.querySelector( '.reveal>.controls' );
+
+		Reveal.configure({ controls: false });
+		equal( controlsElement.style.display, 'none', 'controls are hidden' );
+
+		Reveal.configure({ controls: true });
+		equal( controlsElement.style.display, 'block', 'controls are visible' );
+	});
+
+	test( 'Progress', function() {
+		var progressElement = document.querySelector( '.reveal>.progress' );
+
+		Reveal.configure({ progress: false });
+		equal( progressElement.style.display, 'none', 'progress are hidden' );
+
+		Reveal.configure({ progress: true });
+		equal( progressElement.style.display, 'block', 'progress are visible' );
+	});
+
+	test( 'Loop', function() {
+		Reveal.configure({ loop: true });
+
+		Reveal.slide( 0, 0 );
+
+		Reveal.left();
+		notEqual( Reveal.getIndices().h, 0, 'looped from start to end' );
+
+		Reveal.right();
+		equal( Reveal.getIndices().h, 0, 'looped from end to start' );
+
+		Reveal.configure({ loop: false });
+	});
+
+
+	// ---------------------------------------------------------------
+	// EVENT TESTS
+
+	QUnit.module( 'Events' );
+
+	asyncTest( 'slidechanged', function() {
+		expect( 3 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'slidechanged', _onEvent );
+
+		Reveal.slide( 1, 0 ); // should trigger
+		Reveal.slide( 1, 0 ); // should do nothing
+		Reveal.next(); // should trigger
+		Reveal.slide( 3, 0 ); // should trigger
+		Reveal.next(); // should do nothing
+
+		start();
+
+		Reveal.removeEventListener( 'slidechanged', _onEvent );
+
+	});
+
+	asyncTest( 'paused', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'paused', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'paused', _onEvent );
+	});
+
+	asyncTest( 'resumed', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'resumed', _onEvent );
+
+		Reveal.togglePause();
+		Reveal.togglePause();
+
+		start();
+
+		Reveal.removeEventListener( 'resumed', _onEvent );
+	});
+
+
+} );
+
+Reveal.initialize();
+
diff --git a/docs/slides/plpv14/tmp/Foo.hs b/docs/slides/plpv14/tmp/Foo.hs
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/tmp/Foo.hs
@@ -0,0 +1,20 @@
+module Loop (listSum) where
+
+{-@ LIQUID "--no-termination"@-}
+
+-- listSum     :: [Int] -> Int
+-- listNatSum  :: [Int] -> Int
+-- listEvenSum :: [Int] -> Int
+-- add         :: Int -> Int -> Int
+
+loop :: Int -> Int -> a -> (Int -> a -> a) -> a
+loop lo hi base f = go lo base
+  where 
+    go i acc 
+      | i < hi    = go (i+1) (f i acc)
+      | otherwise = acc
+      
+listSum xs  = loop 0 n 0 body 
+  where 
+    body    = \i acc -> acc + (xs !! i) -- replace !! with `poo` and its safe? wtf.
+    n       = length xs
diff --git a/docs/slides/plpv14/tmp/liquid.css b/docs/slides/plpv14/tmp/liquid.css
new file mode 100644
--- /dev/null
+++ b/docs/slides/plpv14/tmp/liquid.css
@@ -0,0 +1,105 @@
+.hs-linenum {
+  color: #B2B2B2; 
+  font-style: italic;
+}
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+  // font-weight: bold;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   /* color: #00FFFF; color: #0E84B5; */
+  //font-weight: bold;  
+}
+
+.hs-definition { 
+  color: #06287E 
+  /* font-weight: bold; */ 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  // font-size: 120%;
+  // font-family: Bitstream Vera Sans Mono,monospace;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/external/hsmisc/Graphs.hs b/external/hsmisc/Graphs.hs
new file mode 100644
--- /dev/null
+++ b/external/hsmisc/Graphs.hs
@@ -0,0 +1,69 @@
+module Graphs where
+
+import qualified Data.Set as S
+import qualified Data.Map as M
+import Text.Printf
+import Data.Foldable (find)
+import Data.List (intercalate, sort, sortBy, foldl', nubBy)
+
+type Graph = M.Map Int [Int]
+
+ofList :: [(Int, Int)] -> Graph
+ofList uvs = sort `fmap` foldl' adds M.empty uvs
+  where adds g (u, v) = M.insert u (v: (M.findWithDefault [] u g)) g
+
+readGraph :: FilePath -> IO Graph
+readGraph f 
+  = do s     <- readFile f
+       let es = filter ((4 ==) . length) (words `fmap` lines s)
+       return $ ofList [((read u) :: Int, (read v) :: Int) | [u,_,v,_] <- es]
+  
+writeGraph :: FilePath -> Graph -> IO ()
+writeGraph f = writeFile f . showGraph 
+
+showGraph :: Graph -> String
+showGraph g  = intercalate "\n" [ printf "%d -> %d ;" u v | (u, vs) <- M.toList g, v <- vs] 
+
+postStar :: Graph -> S.Set Int -> Graph
+postStar g vs = go vs S.empty
+  where 
+    go new reach
+      | S.null new = project reach g
+      | otherwise  = let vs'    = posts g new 
+                         reach' = S.union reach new
+                         new'   = S.difference vs' reach' 
+                     in go new' reach'
+
+project :: S.Set Int -> Graph -> Graph
+project reach = M.map (filter (`S.member` reach)) . M.filterWithKey (\u _ -> S.member u reach)
+
+posts      :: Graph -> S.Set Int -> S.Set Int 
+posts g us = S.unions [post g u | u <- S.toList us]  
+
+post     :: Graph -> Int -> S.Set Int 
+post g u = S.fromList $ M.findWithDefault [] u g
+
+
+findPath :: Graph -> Int -> Int -> Maybe [Int]
+findPath g src dst = go M.empty (M.fromList [(src, [])]) 
+  where 
+    go :: M.Map Int [Int] -> M.Map Int [Int] -> Maybe [Int]
+    go reach frnt 
+      | M.null frnt = Nothing 
+      | otherwise   = case find ((dst ==) . fst) (M.assocs frnt) of
+                        Just (_, path) -> Just (reverse path)
+                        Nothing        -> let reach' = updReach reach frnt -- (S.fromList $ fst `fmap` S.elems frnt) 
+                                              frnt'  = postFront g reach frnt
+                                        in go reach' frnt'
+   
+updReach = M.unionWith  (\p1 p2 -> if length p1 < length p2 then p1 else p2)
+
+postFront g reach frnt 
+  = M.fromList 
+  $ nubBy (\x y -> fst x == fst y) 
+  $ sortBy (\x y -> let m = length . snd in compare (m x) (m y))
+      [ (v, u:path) | (u, path) <- M.assocs frnt
+                    , v         <- S.elems (post g u)
+                    , not (M.member v reach) 
+      ]
+
diff --git a/external/hsmisc/Lhs2Hs.hs b/external/hsmisc/Lhs2Hs.hs
new file mode 100644
--- /dev/null
+++ b/external/hsmisc/Lhs2Hs.hs
@@ -0,0 +1,36 @@
+#!/usr/bin/env runhaskell
+
+import System.Environment   (getArgs)
+import System.FilePath      (replaceExtension)
+import Data.Char            (isSpace)
+
+main         = getArgs >>= mapM lhs2hsFile
+
+lhs2hsFile f = do str <- readFile f
+                  writeFile (replaceExtension f ".hs") $ lhs2hs txBeginEnd {- txBird -} $ str
+
+lhs2hs tx    = unlines . tx . map trimSpaces . lines 
+trimSpaces   = reverse . dropWhile isSpace . reverse 
+
+--------------------------------------------------------------------------
+txBeginEnd   = stepFold step Comment 
+
+data Mode = Code | Comment
+
+step Comment "\\begin{code}" = (Code   , "")
+step Comment ""              = (Comment, "")
+step Comment s               = (Comment, "-- " ++ s)
+step Code    "\\end{code}"   = (Comment, "")
+step Code    s               = (Code   , s )
+
+
+stepFold f b []     = []
+stepFold f b (x:xs) = y : stepFold f b' xs 
+                      where (b', y) = f b x 
+--------------------------------------------------------------------------
+
+txBird  = map dropTrack 
+  where 
+    dropTrack ('>' : ' ' : l) = l
+    dropTrack l               = "--" ++ l
+
diff --git a/include/Control/Exception.spec b/include/Control/Exception.spec
--- a/include/Control/Exception.spec
+++ b/include/Control/Exception.spec
@@ -1,5 +1,5 @@
 module spec Control.Exception where
 
 // Useless as compiled into GHC primitive, which is ignored
-assume assert :: {v:Bool | Prop v } -> a -> a
+assume assert :: {v:Bool | v } -> a -> a
 
diff --git a/include/Control/Parallel/Strategies.spec b/include/Control/Parallel/Strategies.spec
new file mode 100644
--- /dev/null
+++ b/include/Control/Parallel/Strategies.spec
@@ -0,0 +1,3 @@
+module spec Control.Parallel.Strategies where
+
+assume withStrategy :: Control.Parallel.Strategies.Strategy a -> x:a -> {v:a | v == x}
diff --git a/include/CoreToLogic.lg b/include/CoreToLogic.lg
--- a/include/CoreToLogic.lg
+++ b/include/CoreToLogic.lg
@@ -12,3 +12,10 @@
 
 define Data.Map.Base.insert k v m     = (Map_store m k v)
 define Data.Map.Base.select k v       = (Map_select m k)
+
+define Language.Haskell.Liquid.String.stringEmp = (stringEmp)
+define Data.RString.RString.stringEmp = (stringEmp)
+define String.stringEmp  = (stringEmp)
+define Main.mempty       = (mempty)
+define Language.Haskell.Liquid.ProofCombinators.cast x y = (y)
+define Control.Parallel.Strategies.withStrategy s x = (x)
diff --git a/include/Data/ByteString.spec b/include/Data/ByteString.spec
new file mode 100644
--- /dev/null
+++ b/include/Data/ByteString.spec
@@ -0,0 +1,378 @@
+module spec Data.ByteString where
+
+measure bslen :: Data.ByteString.ByteString -> { n : Int | 0 <= n }
+
+invariant { bs : Data.ByteString.ByteString  | 0 <= bslen bs }
+
+empty :: { bs : Data.ByteString.ByteString | bslen bs == 0 }
+
+singleton
+    :: Data.Word.Word8 -> { bs : Data.ByteString.ByteString | bslen bs == 1 }
+
+pack
+    :: w8s : [Data.Word.Word8]
+    -> { bs : Data.ByteString.ByteString | bslen bs == len w8s }
+
+unpack
+    :: bs : Data.ByteString.ByteString
+    -> { w8s : [Data.Word.Word8] | len w8s == bslen bs }
+
+cons
+    :: Data.Word.Word8
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i + 1 }
+
+snoc
+    :: i : Data.ByteString.ByteString
+    -> Data.Word.Word8
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i + 1 }
+
+append
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen l + bslen r }
+
+head :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Data.Word.Word8
+
+unsnoc
+    :: i : Data.ByteString.ByteString
+    -> Maybe ({ o : Data.ByteString.ByteString | bslen o == bslen i - 1 }, Data.Word.Word8)
+
+last :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Data.Word.Word8
+
+tail :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Data.Word.Word8
+
+init :: {i:Data.ByteString.ByteString | 1 <= bslen i } 
+     -> {o:Data.ByteString.ByteString | bslen o == bslen i - 1 }
+
+null
+    :: bs : Data.ByteString.ByteString
+    -> { b : Bool | b <=> bslen bs == 0 }
+
+length :: bs : Data.ByteString.ByteString -> { n : Int | bslen bs == n }
+
+map
+    :: (Data.Word.Word8 -> Data.Word.Word8)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+reverse
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+intersperse
+    :: Data.Word.Word8
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | (bslen i == 0 <=> bslen o == 0) && (1 <= bslen i <=> bslen o == 2 * bslen i - 1) }
+
+intercalate
+    :: l : Data.ByteString.ByteString
+    -> rs : [Data.ByteString.ByteString]
+    -> { o : Data.ByteString.ByteString | len rs == 0 ==> bslen o == 0 }
+
+transpose
+    :: is : [Data.ByteString.ByteString]
+    -> { os : [{ bs : Data.ByteString.ByteString | bslen bs <= len is }] | len is == 0 ==> len os == 0}
+
+foldl1
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> { bs : Data.ByteString.ByteString | 1 <= bslen bs }
+    -> Data.Word.Word8
+
+foldl1'
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> { bs : Data.ByteString.ByteString | 1 <= bslen bs }
+    -> Data.Word.Word8
+
+foldr1
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> { bs : Data.ByteString.ByteString | 1 <= bslen bs }
+    -> Data.Word.Word8
+
+foldr1'
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> { bs : Data.ByteString.ByteString | 1 <= bslen bs }
+    -> Data.Word.Word8
+
+concat
+    :: is : [Data.ByteString.ByteString]
+    -> { o : Data.ByteString.ByteString | len is == 0 ==> bslen o }
+
+concatMap
+    :: (Data.Word.Word8 -> Data.ByteString.ByteString)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen i == 0 ==> bslen o == 0 }
+
+any :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> { b : Bool | bslen bs == 0 ==> not b }
+
+all :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> { b : Bool | bslen bs == 0 ==> b }
+
+maximum
+    :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Data.Word.Word8
+
+minimum
+    :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Data.Word.Word8
+
+scanl
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> Data.Word.Word8
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+scanl1
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> i : { i : Data.ByteString.ByteString | 1 <= bslen i }
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+scanr
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> Data.Word.Word8
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+scanr1
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> i : { i : Data.ByteString.ByteString | 1 <= bslen i }
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+mapAccumL
+    :: (acc -> Data.Word.Word8 -> (acc, Data.Word.Word8))
+    -> acc
+    -> i : Data.ByteString.ByteString
+    -> (acc, { o : Data.ByteString.ByteString | bslen o == bslen i })
+
+mapAccumR
+    :: (acc -> Data.Word.Word8 -> (acc, Data.Word.Word8))
+    -> acc
+    -> i : Data.ByteString.ByteString
+    -> (acc, { o : Data.ByteString.ByteString | bslen o == bslen i })
+
+replicate
+    :: n : Int
+    -> Data.Word.Word8
+    -> { bs : Data.ByteString.ByteString | bslen bs == n }
+
+unfoldrN
+    :: n : Int
+    -> (a -> Maybe (Data.Word.Word8, a))
+    -> a
+    -> ({ bs : Data.ByteString.ByteString | bslen bs <= n }, Maybe a)
+
+take
+    :: n : Int
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | (n <= 0 <=> bslen o == 0) &&
+                                          ((0 <= n && n <= bslen i) <=> bslen o == n) &&
+                                          (bslen i <= n <=> bslen o = bslen i) }
+
+drop
+    :: n : Int
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | (n <= 0 <=> bslen o == bslen i) &&
+                                          ((0 <= n && n <= bslen i) <=> bslen o == bslen i - n) &&
+                                          (bslen i <= n <=> bslen o == 0) }
+
+splitAt
+    :: n : Int
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | (n <= 0 <=> bslen l == 0) &&
+                                            ((0 <= n && n <= bslen i) <=> bslen l == n) &&
+                                            (bslen i <= n <=> bslen l == bslen i) }
+       , { r : Data.ByteString.ByteString | (n <= 0 <=> bslen r == bslen i) &&
+                                            ((0 <= n && n <= bslen i) <=> bslen r == bslen i - n) &&
+                                            (bslen i <= n <=> bslen r == 0) }
+       )
+
+takeWhile
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o <= bslen i }
+
+dropWhile
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o <= bslen i }
+
+span
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+spanEnd
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+break
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+breakEnd
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+group
+    :: i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | 1 <= bslen o && bslen o <= bslen i }]
+
+groupBy
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | 1 <= bslen o && bslen o <= bslen i }]
+
+inits
+    :: i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+tails
+    :: i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+split
+    :: Data.Word.Word8
+    -> i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+splitWith
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+isPrefixOf
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { b : Bool | bslen l >= bslen r ==> not b }
+
+isSuffixOf
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { b : Bool | bslen l > bslen r ==> not b }
+
+isInfixOf
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { b : Bool | bslen l > bslen r ==> not b }
+
+breakSubstring
+    :: il : Data.ByteString.ByteString
+    -> ir : Data.ByteString.ByteString
+    -> ( { ol : Data.ByteString.ByteString | bslen ol <= bslen ir && (bslen il > bslen ir ==> bslen ol == bslen ir)}
+       , { or : Data.ByteString.ByteString | bslen or <= bslen ir && (bslen il > bslen ir ==> bslen or == 0) }
+       )
+
+elem
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.ByteString
+    -> { b : Bool | bslen b == 0 ==> not b }
+
+notElem
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.ByteString
+    -> { b : Bool | bslen b == 0 ==> b }
+
+find
+    :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> Maybe { w8 : Data.Word.Word8 | bslen bs /= 0 }
+
+filter
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o <= bslen i }
+
+partition
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+index :: bs : Data.ByteString.ByteString -> { n : Int | 0 <= n && n < bslen bs } -> Data.Word.Word8
+
+elemIndex
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.ByteString
+    -> Maybe { n : Int | 0 <= n && n < bslen bs }
+
+elemIndices
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.ByteString
+    -> [{ n : Int | 0 <= n && n < bslen bs }]
+
+elemIndexEnd
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.ByteString
+    -> Maybe { n : Int | 0 <= n && n < bslen bs }
+
+findIndex
+    :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> Maybe { n : Int | 0 <= n && n < bslen bs }
+
+findIndices
+    :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> [{ n : Int | 0 <= n && n < bslen bs }]
+
+count
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.ByteString
+    -> { n : Int | 0 <= n && n < bslen bs }
+
+zip
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { o : [(Data.Word.Word8, Data.Word.Word8)] | len o <= bslen l && len o <= bslen r }
+
+zipWith
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> a)
+    -> l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { o : [a] | len o <= bslen l && len o <= bslen r }
+
+unzip
+    :: i : [(Data.Word.Word8, Data.Word.Word8)]
+    -> ( { l : Data.ByteString.ByteString | bslen l == len i }
+       , { r : Data.ByteString.ByteString | bslen r == len i }
+       )
+
+sort
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+copy
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+hGet
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.ByteString | bslen bs == n || bslen bs == 0 }
+
+hGetSome
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.ByteString | bslen bs <= n }
+
+hGetNonBlocking
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.ByteString | bslen bs <= n }
+
+uncons
+    :: i : Data.ByteString.ByteString
+    -> Maybe (Data.Word.Word8, { o : Data.ByteString.ByteString | bslen o == bslen i - 1 })
diff --git a/include/Data/ByteString/Char8.spec b/include/Data/ByteString/Char8.spec
new file mode 100644
--- /dev/null
+++ b/include/Data/ByteString/Char8.spec
@@ -0,0 +1,400 @@
+module spec Data.ByteString.Char8 where
+
+assume empty :: { bs : Data.ByteString.ByteString | bslen bs == 0 }
+
+assume singleton
+    :: Char -> { bs : Data.ByteString.ByteString | bslen bs == 1 }
+
+assume pack
+    :: w8s : [Char]
+    -> { bs : Data.ByteString.ByteString | bslen bs == len w8s }
+
+assume unpack
+    :: bs : Data.ByteString.ByteString
+    -> { w8s : [Char] | len w8s == bslen bs }
+
+assume cons
+    :: Char
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i + 1 }
+
+assume snoc
+    :: i : Data.ByteString.ByteString
+    -> Char
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i + 1 }
+
+assume append
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen l + bslen r }
+
+head :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char
+
+assume uncons
+    :: i : Data.ByteString.ByteString
+    -> Maybe (Char, { o : Data.ByteString.ByteString | bslen o == bslen i - 1 })
+
+assume unsnoc
+    :: i : Data.ByteString.ByteString
+    -> Maybe ({ o : Data.ByteString.ByteString | bslen o == bslen i - 1 }, Char)
+
+last :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char
+
+tail :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char
+
+init :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char
+
+assume null
+    :: bs : Data.ByteString.ByteString
+    -> { b : Bool | b <=> bslen bs == 0 }
+
+assume length :: bs : Data.ByteString.ByteString -> { n : Int | bslen bs == n }
+
+assume map
+    :: (Char -> Char)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+assume reverse
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+assume intersperse
+    :: Char
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | (bslen i == 0 <=> bslen o == 0) && (1 <= bslen i <=> bslen o == 2 * bslen i - 1) }
+
+assume intercalate
+    :: l : Data.ByteString.ByteString
+    -> rs : [Data.ByteString.ByteString]
+    -> { o : Data.ByteString.ByteString | len rs == 0 ==> bslen o == 0 }
+
+assume transpose
+    :: is : [Data.ByteString.ByteString]
+    -> { os : [{ bs : Data.ByteString.ByteString | bslen bs <= len is }] | len is == 0 ==> len os == 0}
+
+foldl1
+    :: (Char -> Char -> Char)
+    -> { bs : Data.ByteString.ByteString | 1 <= bslen bs }
+    -> Char
+
+foldl1'
+    :: (Char -> Char -> Char)
+    -> { bs : Data.ByteString.ByteString | 1 <= bslen bs }
+    -> Char
+
+foldr1
+    :: (Char -> Char -> Char)
+    -> { bs : Data.ByteString.ByteString | 1 <= bslen bs }
+    -> Char
+
+foldr1'
+    :: (Char -> Char -> Char)
+    -> { bs : Data.ByteString.ByteString | 1 <= bslen bs }
+    -> Char
+
+assume concat
+    :: is : [Data.ByteString.ByteString]
+    -> { o : Data.ByteString.ByteString | len is == 0 ==> bslen o }
+
+assume concatMap
+    :: (Char -> Data.ByteString.ByteString)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen i == 0 ==> bslen o == 0 }
+
+assume any :: (Char -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> { b : Bool | bslen bs == 0 ==> not b }
+
+assume all :: (Char -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> { b : Bool | bslen bs == 0 ==> b }
+
+maximum
+    :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char
+
+minimum
+    :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char
+
+assume scanl
+    :: (Char -> Char -> Char)
+    -> Char
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+assume scanl1
+    :: (Char -> Char -> Char)
+    -> i : { i : Data.ByteString.ByteString | 1 <= bslen i }
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+assume scanr
+    :: (Char -> Char -> Char)
+    -> Char
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+assume scanr1
+    :: (Char -> Char -> Char)
+    -> i : { i : Data.ByteString.ByteString | 1 <= bslen i }
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+assume mapAccumL
+    :: (acc -> Char -> (acc, Char))
+    -> acc
+    -> i : Data.ByteString.ByteString
+    -> (acc, { o : Data.ByteString.ByteString | bslen o == bslen i })
+
+assume mapAccumR
+    :: (acc -> Char -> (acc, Char))
+    -> acc
+    -> i : Data.ByteString.ByteString
+    -> (acc, { o : Data.ByteString.ByteString | bslen o == bslen i })
+
+assume replicate
+    :: n : Int
+    -> Char
+    -> { bs : Data.ByteString.ByteString | bslen bs == n }
+
+assume unfoldrN
+    :: n : Int
+    -> (a -> Maybe (Char, a))
+    -> a
+    -> ({ bs : Data.ByteString.ByteString | bslen bs <= n }, Maybe a)
+
+assume take
+    :: n : Int
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | (n <= 0 <=> bslen o == 0) &&
+                                          ((0 <= n && n <= bslen i) <=> bslen o == n) &&
+                                          (bslen i <= n <=> bslen o = bslen i) }
+
+assume drop
+    :: n : Int
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | (n <= 0 <=> bslen o == bslen i) &&
+                                          ((0 <= n && n <= bslen i) <=> bslen o == bslen i - n) &&
+                                          (bslen i <= n <=> bslen o == 0) }
+
+assume splitAt
+    :: n : Int
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | (n <= 0 <=> bslen l == 0) &&
+                                            ((0 <= n && n <= bslen i) <=> bslen l == n) &&
+                                            (bslen i <= n <=> bslen l == bslen i) }
+       , { r : Data.ByteString.ByteString | (n <= 0 <=> bslen r == bslen i) &&
+                                            ((0 <= n && n <= bslen i) <=> bslen r == bslen i - n) &&
+                                            (bslen i <= n <=> bslen r == 0) }
+       )
+
+assume takeWhile
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o <= bslen i }
+
+assume dropWhile
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o <= bslen i }
+
+assume span
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+assume spanEnd
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+assume break
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+assume breakEnd
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+assume group
+    :: i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | 1 <= bslen o && bslen o <= bslen i }]
+
+assume groupBy
+    :: (Char -> Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | 1 <= bslen o && bslen o <= bslen i }]
+
+assume inits
+    :: i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+assume tails
+    :: i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+assume split
+    :: Char
+    -> i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+assume splitWith
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+assume lines
+    :: i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+assume words
+    :: i : Data.ByteString.ByteString
+    -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }]
+
+assume unlines
+    :: is : [Data.ByteString.ByteString]
+    -> { o : Data.ByteString.ByteString | (len is == 0 <=> bslen o == 0) && bslen o >= len is }
+
+assume unwords
+    :: is : [Data.ByteString.ByteString]
+    -> { o : Data.ByteString.ByteString | (len is == 0 ==> bslen o == 0) && (1 <= len is ==> bslen o >= len is - 1) }
+
+assume isPrefixOf
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { b : Bool | bslen l >= bslen r ==> not b }
+
+assume isSuffixOf
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { b : Bool | bslen l > bslen r ==> not b }
+
+assume isInfixOf
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { b : Bool | bslen l > bslen r ==> not b }
+
+assume breakSubstring
+    :: il : Data.ByteString.ByteString
+    -> ir : Data.ByteString.ByteString
+    -> ( { ol : Data.ByteString.ByteString | bslen ol <= bslen ir && (bslen il > bslen ir ==> bslen ol == bslen ir)}
+       , { or : Data.ByteString.ByteString | bslen or <= bslen ir && (bslen il > bslen ir ==> bslen or == 0) }
+       )
+
+assume elem
+    :: Char
+    -> bs : Data.ByteString.ByteString
+    -> { b : Bool | bslen b == 0 ==> not b }
+
+assume notElem
+    :: Char
+    -> bs : Data.ByteString.ByteString
+    -> { b : Bool | bslen b == 0 ==> b }
+
+assume find
+    :: (Char -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> Maybe { w8 : Char | bslen bs /= 0 }
+
+assume filter
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o <= bslen i }
+
+assume partition
+    :: (Char -> Bool)
+    -> i : Data.ByteString.ByteString
+    -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i }
+       , { r : Data.ByteString.ByteString | bslen r <= bslen i }
+       )
+
+index
+    :: bs : Data.ByteString.ByteString
+    -> { n : Int | 0 <= n && n < bslen bs }
+    -> Char
+
+assume elemIndex
+    :: Char
+    -> bs : Data.ByteString.ByteString
+    -> Maybe { n : Int | 0 <= n && n < bslen bs }
+
+assume elemIndices
+    :: Char
+    -> bs : Data.ByteString.ByteString
+    -> [{ n : Int | 0 <= n && n < bslen bs }]
+
+assume elemIndexEnd
+    :: Char
+    -> bs : Data.ByteString.ByteString
+    -> Maybe { n : Int | 0 <= n && n < bslen bs }
+
+assume findIndex
+    :: (Char -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> Maybe { n : Int | 0 <= n && n < bslen bs }
+
+assume findIndices
+    :: (Char -> Bool)
+    -> bs : Data.ByteString.ByteString
+    -> [{ n : Int | 0 <= n && n < bslen bs }]
+
+assume count
+    :: Char
+    -> bs : Data.ByteString.ByteString
+    -> { n : Int | 0 <= n && n < bslen bs }
+
+assume zip
+    :: l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { o : [(Char, Char)] | len o <= bslen l && len o <= bslen r }
+
+assume zipWith
+    :: (Char -> Char -> a)
+    -> l : Data.ByteString.ByteString
+    -> r : Data.ByteString.ByteString
+    -> { o : [a] | len o <= bslen l && len o <= bslen r }
+
+assume unzip
+    :: i : [(Char, Char)]
+    -> ( { l : Data.ByteString.ByteString | bslen l == len i }
+       , { r : Data.ByteString.ByteString | bslen r == len i }
+       )
+
+assume sort
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+assume readInt
+    :: i : Data.ByteString.ByteString
+    -> Maybe { p : (Int, { o : Data.ByteString.ByteString | bslen o < bslen i}) | bslen i /= 0 }
+
+assume readInteger
+    :: i : Data.ByteString.ByteString
+    -> Maybe { p : (Integer, { o : Data.ByteString.ByteString | bslen o < bslen i}) | bslen i /= 0 }
+
+assume copy
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i }
+
+assume hGet
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.ByteString | bslen bs == n || bslen bs == 0 }
+
+assume hGetSome
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.ByteString | bslen bs <= n }
+
+assume hGetNonBlocking
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.ByteString | bslen bs <= n }
diff --git a/include/Data/ByteString/Lazy.spec b/include/Data/ByteString/Lazy.spec
new file mode 100644
--- /dev/null
+++ b/include/Data/ByteString/Lazy.spec
@@ -0,0 +1,397 @@
+module spec Data.ByteString.Lazy where
+
+measure bllen :: Data.ByteString.Lazy.ByteString -> { n : Data.Int.Int64 | 0 <= n }
+
+invariant { bs : Data.ByteString.Lazy.ByteString | 0 <= bllen bs }
+
+assume empty :: { bs : Data.ByteString.Lazy.ByteString | bllen bs == 0 }
+
+assume singleton
+    :: Data.Word.Word8 -> { bs : Data.ByteString.Lazy.ByteString | bllen bs == 1 }
+
+assume pack
+    :: w8s : [Data.Word.Word8]
+    -> { bs : Data.ByteString.ByteString | bllen bs == len w8s }
+
+assume unpack
+    :: bs : Data.ByteString.Lazy.ByteString
+    -> { w8s : [Data.Word.Word8] | len w8s == bllen bs }
+
+assume fromStrict
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bslen i }
+
+assume toStrict
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bllen i }
+
+assume fromChunks
+    :: i : [Data.ByteString.ByteString]
+    -> { o : Data.ByteString.Lazy.ByteString | len i == 0 <=> bllen o == 0 }
+
+assume toChunks
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { os : [{ o : Data.ByteString.ByteString | bslen o <= bllen i}] | len os == 0 <=> bllen i == 0 }
+
+assume cons
+    :: Data.Word.Word8
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i + 1 }
+
+assume snoc
+    :: i : Data.ByteString.Lazy.ByteString
+    -> Data.Word.Word8
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i + 1 }
+
+assume append
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen l + bllen r }
+
+head
+    :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Data.Word.Word8
+
+assume uncons
+    :: i : Data.ByteString.Lazy.ByteString
+    -> Maybe (Data.Word.Word8, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i - 1 })
+
+assume unsnoc
+    :: i : Data.ByteString.Lazy.ByteString
+    -> Maybe ({ o : Data.ByteString.Lazy.ByteString | bllen o == bllen i - 1 }, Data.Word.Word8)
+
+last
+    :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Data.Word.Word8
+
+tail
+    :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Data.Word.Word8
+
+init
+    :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Data.Word.Word8
+
+assume null
+    :: bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | b <=> bllen bs == 0 }
+
+assume length
+    :: bs : Data.ByteString.Lazy.ByteString -> { n : Data.Int.Int64 | bllen bs == n }
+
+assume map
+    :: (Data.Word.Word8 -> Data.Word.Word8)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume reverse
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume intersperse
+    :: Data.Word.Word8
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | (bllen i == 0 <=> bllen o == 0) && (1 <= bllen i <=> bllen o == 2 * bllen i - 1) }
+
+assume intercalate
+    :: l : Data.ByteString.Lazy.ByteString
+    -> rs : [Data.ByteString.Lazy.ByteString]
+    -> { o : Data.ByteString.Lazy.ByteString | len rs == 0 ==> bllen o == 0 }
+
+assume transpose
+    :: is : [Data.ByteString.Lazy.ByteString]
+    -> { os : [{ bs : Data.ByteString.Lazy.ByteString | bllen bs <= len is }] | len is == 0 ==> len os == 0}
+
+foldl1
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Data.Word.Word8
+
+foldl1'
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Data.Word.Word8
+
+foldr1
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Data.Word.Word8
+
+foldr1'
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Data.Word.Word8
+
+assume concat
+    :: is : [Data.ByteString.Lazy.ByteString]
+    -> { o : Data.ByteString.Lazy.ByteString | len is == 0 ==> bllen o }
+
+assume concatMap
+    :: (Data.Word.Word8 -> Data.ByteString.Lazy.ByteString)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen i == 0 ==> bllen o == 0 }
+
+assume any :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen bs == 0 ==> not b }
+
+assume all :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen bs == 0 ==> b }
+
+maximum :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> Data.Word.Word8
+
+minimum :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> Data.Word.Word8
+
+assume scanl
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> Data.Word.Word8
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume scanl1
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> i : { i : Data.ByteString.Lazy.ByteString | 1 <= bllen i }
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume scanr
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> Data.Word.Word8
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume scanr1
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Data.Word.Word8)
+    -> i : { i : Data.ByteString.Lazy.ByteString | 1 <= bllen i }
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume mapAccumL
+    :: (acc -> Data.Word.Word8 -> (acc, Data.Word.Word8))
+    -> acc
+    -> i : Data.ByteString.Lazy.ByteString
+    -> (acc, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i })
+
+assume mapAccumR
+    :: (acc -> Data.Word.Word8 -> (acc, Data.Word.Word8))
+    -> acc
+    -> i : Data.ByteString.Lazy.ByteString
+    -> (acc, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i })
+
+assume replicate
+    :: n : Data.Int.Int64
+    -> Data.Word.Word8
+    -> { bs : Data.ByteString.Lazy.ByteString | bllen bs == n }
+
+assume unfoldrN
+    :: n : Int
+    -> (a -> Maybe (Data.Word.Word8, a))
+    -> a
+    -> ({ bs : Data.ByteString.Lazy.ByteString | bllen bs <= n }, Maybe a)
+
+assume take
+    :: n : Data.Int.Int64
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | (n <= 0 ==> bllen o == 0) &&
+                                               ((0 <= n && n <= bllen i) <=> bllen o == n) &&
+                                               (bllen i <= n <=> bllen o = bllen i) }
+
+assume drop
+    :: n : Data.Int.Int64
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen o == bllen i) &&
+                                               ((0 <= n && n <= bllen i) <=> bllen o == bllen i - n) &&
+                                               (bllen i <= n <=> bllen o == 0) }
+
+assume splitAt
+    :: n : Data.Int.Int64
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen l == 0) &&
+                                                 ((0 <= n && n <= bllen i) <=> bllen l == n) &&
+                                                 (bllen i <= n <=> bllen l == bllen i) }
+       , { r : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen r == bllen i) &&
+                                                 ((0 <= n && n <= bllen i) <=> bllen r == bllen i - n) &&
+                                                 (bllen i <= n <=> bllen r == 0) }
+       )
+
+assume takeWhile
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }
+
+assume dropWhile
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }
+
+assume span
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+
+assume spanEnd
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+
+assume break
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+
+assume breakEnd
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+assume group
+    :: i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | 1 <= bllen o && bllen o <= bllen i }]
+
+assume groupBy
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | 1 <= bllen o && bllen o <= bllen i }]
+
+assume inits
+    :: i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume tails
+    :: i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume split
+    :: Data.Word.Word8
+    -> i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume splitWith
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume isPrefixOf
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen l >= bllen r ==> not b }
+
+assume isSuffixOf
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen l >= bllen r ==> not b }
+
+assume isInfixOf
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen l >= bllen r ==> not b }
+
+assume breakSubstring
+    :: il : Data.ByteString.Lazy.ByteString
+    -> ir : Data.ByteString.Lazy.ByteString
+    -> ( { ol : Data.ByteString.Lazy.ByteString | bllen ol <= bllen ir && (bllen il > bllen ir ==> bllen ol == bllen ir)}
+       , { or : Data.ByteString.Lazy.ByteString | bllen or <= bllen ir && (bllen il > bllen ir ==> bllen or == 0) }
+       )
+
+assume elem
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen b == 0 ==> not b }
+
+assume notElem
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen b == 0 ==> b }
+
+assume find
+    :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> Maybe { w8 : Data.Word.Word8 | bllen bs /= 0 }
+
+assume filter
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }
+
+assume partition
+    :: (Data.Word.Word8 -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+
+index
+    :: bs : Data.ByteString.Lazy.ByteString
+    -> { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+    -> Data.Word.Word8
+
+assume elemIndex
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+
+assume elemIndices
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> [{ n : Data.Int.Int64 | 0 <= n && n < bllen bs }]
+
+assume elemIndexEnd
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+
+assume findIndex
+    :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+
+assume findIndices
+    :: (Data.Word.Word8 -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> [{ n : Data.Int.Int64 | 0 <= n && n < bllen bs }]
+
+assume count
+    :: Data.Word.Word8
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+
+assume zip
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { o : [(Data.Word.Word8, Data.Word.Word8)] | len o <= bllen l && len o <= bllen r }
+
+assume zipWith
+    :: (Data.Word.Word8 -> Data.Word.Word8 -> a)
+    -> l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { o : [a] | len o <= bllen l && len o <= bllen r }
+
+assume unzip
+    :: i : [(Data.Word.Word8, Data.Word.Word8)]
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l == len i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r == len i }
+       )
+
+assume sort
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume copy
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume hGet
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.Lazy.ByteString | bllen bs == n || bllen bs == 0 }
+
+assume hGetNonBlocking
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.Lazy.ByteString | bllen bs <= n }
diff --git a/include/Data/ByteString/Lazy/Char8.spec b/include/Data/ByteString/Lazy/Char8.spec
new file mode 100644
--- /dev/null
+++ b/include/Data/ByteString/Lazy/Char8.spec
@@ -0,0 +1,417 @@
+module spec Data.ByteString.Lazy where
+
+assume empty :: { bs : Data.ByteString.Lazy.ByteString | bllen bs == 0 }
+
+assume singleton
+    :: Char -> { bs : Data.ByteString.Lazy.ByteString | bllen bs == 1 }
+
+assume pack
+    :: w8s : [Char]
+    -> { bs : Data.ByteString.ByteString | bllen bs == len w8s }
+
+assume unpack
+    :: bs : Data.ByteString.Lazy.ByteString
+    -> { w8s : [Char] | len w8s == bllen bs }
+
+assume fromStrict
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bslen i }
+
+assume toStrict
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.ByteString | bslen o == bllen i }
+
+assume fromChunks
+    :: i : [Data.ByteString.ByteString]
+    -> { o : Data.ByteString.Lazy.ByteString | len i == 0 <=> bllen o == 0 }
+
+assume toChunks
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { os : [{ o : Data.ByteString.ByteString | bslen o <= bllen i}] | len os == 0 <=> bllen i == 0 }
+
+assume cons
+    :: Char
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i + 1 }
+
+assume snoc
+    :: i : Data.ByteString.Lazy.ByteString
+    -> Char
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i + 1 }
+
+assume append
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen l + bllen r }
+
+head
+    :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Char
+
+assume uncons
+    :: i : Data.ByteString.Lazy.ByteString
+    -> Maybe (Char, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i - 1 })
+
+assume unsnoc
+    :: i : Data.ByteString.Lazy.ByteString
+    -> Maybe ({ o : Data.ByteString.Lazy.ByteString | bllen o == bllen i - 1 }, Char)
+
+last
+    :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Char
+
+tail
+    :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Char
+
+init
+    :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Char
+
+assume null
+    :: bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | b <=> bllen bs == 0 }
+
+assume length
+    :: bs : Data.ByteString.Lazy.ByteString -> { n : Data.Int.Int64 | bllen bs == n }
+
+assume map
+    :: (Char -> Char)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume reverse
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume intersperse
+    :: Char
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | (bllen i == 0 <=> bllen o == 0) && (1 <= bllen i <=> bllen o == 2 * bllen i - 1) }
+
+assume intercalate
+    :: l : Data.ByteString.Lazy.ByteString
+    -> rs : [Data.ByteString.Lazy.ByteString]
+    -> { o : Data.ByteString.Lazy.ByteString | len rs == 0 ==> bllen o == 0 }
+
+assume transpose
+    :: is : [Data.ByteString.Lazy.ByteString]
+    -> { os : [{ bs : Data.ByteString.Lazy.ByteString | bllen bs <= len is }] | len is == 0 ==> len os == 0}
+
+foldl1
+    :: (Char -> Char -> Char)
+    -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Char
+
+foldl1'
+    :: (Char -> Char -> Char)
+    -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Char
+
+foldr1
+    :: (Char -> Char -> Char)
+    -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Char
+
+foldr1'
+    :: (Char -> Char -> Char)
+    -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs }
+    -> Char
+
+assume concat
+    :: is : [Data.ByteString.Lazy.ByteString]
+    -> { o : Data.ByteString.Lazy.ByteString | len is == 0 ==> bllen o }
+
+assume concatMap
+    :: (Char -> Data.ByteString.Lazy.ByteString)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen i == 0 ==> bllen o == 0 }
+
+assume any :: (Char -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen bs == 0 ==> not b }
+
+assume all :: (Char -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen bs == 0 ==> b }
+
+maximum :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> Char
+
+minimum :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> Char
+
+assume scanl
+    :: (Char -> Char -> Char)
+    -> Char
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume scanl1
+    :: (Char -> Char -> Char)
+    -> i : { i : Data.ByteString.Lazy.ByteString | 1 <= bllen i }
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume scanr
+    :: (Char -> Char -> Char)
+    -> Char
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume scanr1
+    :: (Char -> Char -> Char)
+    -> i : { i : Data.ByteString.Lazy.ByteString | 1 <= bllen i }
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume mapAccumL
+    :: (acc -> Char -> (acc, Char))
+    -> acc
+    -> i : Data.ByteString.Lazy.ByteString
+    -> (acc, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i })
+
+assume mapAccumR
+    :: (acc -> Char -> (acc, Char))
+    -> acc
+    -> i : Data.ByteString.Lazy.ByteString
+    -> (acc, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i })
+
+assume replicate
+    :: n : Data.Int.Int64
+    -> Char
+    -> { bs : Data.ByteString.Lazy.ByteString | bllen bs == n }
+
+assume unfoldrN
+    :: n : Int
+    -> (a -> Maybe (Char, a))
+    -> a
+    -> ({ bs : Data.ByteString.Lazy.ByteString | bllen bs <= n }, Maybe a)
+
+assume take
+    :: n : Data.Int.Int64
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | (n <= 0 ==> bllen o == 0) &&
+                                               ((0 <= n && n <= bllen i) <=> bllen o == n) &&
+                                               (bllen i <= n <=> bllen o = bllen i) }
+
+assume drop
+    :: n : Data.Int.Int64
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen o == bllen i) &&
+                                               ((0 <= n && n <= bllen i) <=> bllen o == bllen i - n) &&
+                                               (bllen i <= n <=> bllen o == 0) }
+
+assume splitAt
+    :: n : Data.Int.Int64
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen l == 0) &&
+                                                 ((0 <= n && n <= bllen i) <=> bllen l == n) &&
+                                                 (bllen i <= n <=> bllen l == bllen i) }
+       , { r : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen r == bllen i) &&
+                                                 ((0 <= n && n <= bllen i) <=> bllen r == bllen i - n) &&
+                                                 (bllen i <= n <=> bllen r == 0) }
+       )
+
+assume takeWhile
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }
+
+assume dropWhile
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }
+
+assume span
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+
+assume spanEnd
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+
+assume break
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+
+assume breakEnd
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+assume group
+    :: i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | 1 <= bllen o && bllen o <= bllen i }]
+
+assume groupBy
+    :: (Char -> Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | 1 <= bllen o && bllen o <= bllen i }]
+
+assume inits
+    :: i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume tails
+    :: i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume split
+    :: Char
+    -> i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume splitWith
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume lines
+    :: i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume words
+    :: i : Data.ByteString.Lazy.ByteString
+    -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }]
+
+assume unlines
+    :: is : [Data.ByteString.Lazy.ByteString]
+    -> { o : Data.ByteString.Lazy.ByteString | (len is == 0 <=> bllen o == 0) && bllen o >= len is }
+
+assume unwords
+    :: is : [Data.ByteString.Lazy.ByteString]
+    -> { o : Data.ByteString.Lazy.ByteString | (len is == 0 ==> bllen o == 0) && (1 <= len is ==> bllen o >= len is - 1) }
+
+assume isPrefixOf
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen l >= bllen r ==> not b }
+
+assume isSuffixOf
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen l >= bllen r ==> not b }
+
+assume isInfixOf
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen l >= bllen r ==> not b }
+
+assume breakSubstring
+    :: il : Data.ByteString.Lazy.ByteString
+    -> ir : Data.ByteString.Lazy.ByteString
+    -> ( { ol : Data.ByteString.Lazy.ByteString | bllen ol <= bllen ir && (bllen il > bllen ir ==> bllen ol == bllen ir)}
+       , { or : Data.ByteString.Lazy.ByteString | bllen or <= bllen ir && (bllen il > bllen ir ==> bllen or == 0) }
+       )
+
+assume elem
+    :: Char
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen b == 0 ==> not b }
+
+assume notElem
+    :: Char
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { b : Bool | bllen b == 0 ==> b }
+
+assume find
+    :: (Char -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> Maybe { w8 : Char | bllen bs /= 0 }
+
+assume filter
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }
+
+assume partition
+    :: (Char -> Bool)
+    -> i : Data.ByteString.Lazy.ByteString
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i }
+       )
+
+index
+    :: bs : Data.ByteString.Lazy.ByteString
+    -> { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+    -> Char
+
+assume elemIndex
+    :: Char
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+
+assume elemIndices
+    :: Char
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> [{ n : Data.Int.Int64 | 0 <= n && n < bllen bs }]
+
+assume elemIndexEnd
+    :: Char
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+
+assume findIndex
+    :: (Char -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+
+assume findIndices
+    :: (Char -> Bool)
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> [{ n : Data.Int.Int64 | 0 <= n && n < bllen bs }]
+
+assume count
+    :: Char
+    -> bs : Data.ByteString.Lazy.ByteString
+    -> { n : Data.Int.Int64 | 0 <= n && n < bllen bs }
+
+assume zip
+    :: l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { o : [(Char, Char)] | len o <= bllen l && len o <= bllen r }
+
+assume zipWith
+    :: (Char -> Char -> a)
+    -> l : Data.ByteString.Lazy.ByteString
+    -> r : Data.ByteString.Lazy.ByteString
+    -> { o : [a] | len o <= bllen l && len o <= bllen r }
+
+assume unzip
+    :: i : [(Char, Char)]
+    -> ( { l : Data.ByteString.Lazy.ByteString | bllen l == len i }
+       , { r : Data.ByteString.Lazy.ByteString | bllen r == len i }
+       )
+
+assume sort
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume readInt
+    :: i : Data.ByteString.Lazy.ByteString
+    -> Maybe { p : (Int, { o : Data.ByteString.Lazy.ByteString | bllen o < bllen i}) | bllen i /= 0 }
+
+assume readInteger
+    :: i : Data.ByteString.Lazy.ByteString
+    -> Maybe { p : (Integer, { o : Data.ByteString.Lazy.ByteString | bllen o < bllen i}) | bllen i /= 0 }
+
+assume copy
+    :: i : Data.ByteString.Lazy.ByteString
+    -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }
+
+assume hGet
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.Lazy.ByteString | bllen bs == n || bllen bs == 0 }
+
+assume hGetNonBlocking
+    :: System.IO.Handle
+    -> n : { n : Int | 0 <= n }
+    -> IO { bs : Data.ByteString.Lazy.ByteString | bllen bs <= n }
diff --git a/include/Data/ByteString/Short.spec b/include/Data/ByteString/Short.spec
new file mode 100644
--- /dev/null
+++ b/include/Data/ByteString/Short.spec
@@ -0,0 +1,35 @@
+module spec Data.ByteString.Short where
+
+measure sbslen :: Data.ByteString.Short.ShortByteString -> { n : Int | 0 <= n }
+
+invariant { bs : Data.ByteString.Short.ShortByteString  | 0 <= sbslen bs }
+
+assume toShort
+    :: i : Data.ByteString.ByteString
+    -> { o : Data.ByteString.Short.ShortByteString | sbslen o == bslen i }
+
+assume fromShort
+    :: o : Data.ByteString.Short.ShortByteString
+    -> { i : Data.ByteString.ByteString | bslen i == sbslen o }
+
+assume pack
+    :: w8s : [Data.Word.Word8]
+    -> { bs : Data.ByteString.Short.ShortByteString | sbslen bs == len w8s }
+
+assume unpack
+    :: bs : Data.ByteString.Short.ShortByteString
+    -> { w8s : [Data.Word.Word8] | len w8s == sbslen bs }
+
+assume empty :: { bs : Data.ByteString.Short.ShortByteString | sbslen bs == 0 }
+
+assume null
+    :: bs : Data.ByteString.Short.ShortByteString
+    -> { b : Bool | b <=> sbslen bs == 0 }
+
+assume length
+    :: bs : Data.ByteString.Short.ShortByteString -> { n : Int | sbslen bs == n }
+
+index
+    :: bs : Data.ByteString.Short.ShortByteString
+    -> { n : Int | 0 <= n && n < sbslen bs }
+    -> Data.Word.Word8
diff --git a/include/Data/ByteString/Unsafe.spec b/include/Data/ByteString/Unsafe.spec
new file mode 100644
--- /dev/null
+++ b/include/Data/ByteString/Unsafe.spec
@@ -0,0 +1,29 @@
+module spec Data.ByteString.Unsafe where
+
+unsafeHead
+    :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Data.Word.Word8
+
+unsafeTail
+    :: bs : { v : Data.ByteString.ByteString | bslen v > 0 }
+    -> { v : Data.ByteString.ByteString | bslen v = bslen bs - 1 }
+
+unsafeInit
+    :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Data.Word.Word8
+
+unsafeLast
+    :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Data.Word.Word8
+
+unsafeIndex
+    :: bs : Data.ByteString.ByteString
+    -> { n : Int | 0 <= n && n < bslen bs }
+    -> Data.Word.Word8
+
+assume unsafeTake
+    :: n : { n : Int | 0 <= n }
+    -> i : { i : Data.ByteString.ByteString | n <= bslen i }
+    -> { o : Data.ByteString.ByteString | bslen o == n }
+
+assume unsafeDrop
+    :: n : { n : Int | 0 <= n }
+    -> i : { i : Data.ByteString.ByteString | n <= bslen i }
+    -> { o : Data.ByteString.ByteString | bslen o == bslen i - n }
diff --git a/include/Data/Either.spec b/include/Data/Either.spec
--- a/include/Data/Either.spec
+++ b/include/Data/Either.spec
@@ -6,10 +6,10 @@
 lenRight (x:xs) = if (isLeft x) then (lenRight xs) else (lenRight xs + 1)
 lenRight ([])   = 0
 
-measure isLeftHd :: [Data.Either.Either a b] -> Prop
+measure isLeftHd :: [Data.Either.Either a b] -> Bool 
 isLeftHd (x:xs) = (isLeft x)
 isLeftHd ([])   = false
 
-measure isLeft :: Data.Either.Either a b -> Prop 
+measure isLeft :: Data.Either.Either a b -> Bool
 isLeft (Left x)  = true
 isLeft (Right x) = false
diff --git a/include/Data/Map.hiddenspec b/include/Data/Map.hiddenspec
new file mode 100644
--- /dev/null
+++ b/include/Data/Map.hiddenspec
@@ -0,0 +1,27 @@
+module spec Data.Map where
+
+embed Data.Map.Map as Map_t
+
+---------------------------------------------------------------------------------------
+-- | Logical Map Operators: Interpreted "natively" by the SMT solver ------------------
+---------------------------------------------------------------------------------------
+
+measure Map_select :: forall k v. Data.Map.Map k v -> k -> v
+
+measure Map_store  :: forall k v. Data.Map.Map k v -> k -> v -> Data.Map.Map k v
+
+
+insert :: Ord k => k:k -> v:v -> m:Data.Map.Map k v -> {n:Data.Map.Map k v | n = Map_store m k v}
+
+lookup :: Ord k => k:k -> m:Data.Map.Map k v -> Maybe {v:v | v = Map_select m k}
+
+(!)    :: Ord k => m:Data.Map.Map k v -> k:k -> {v:v | v = Map_select m k}
+
+
+
+
+
+
+
+
+
diff --git a/include/Data/Maybe.spec b/include/Data/Maybe.spec
--- a/include/Data/Maybe.spec
+++ b/include/Data/Maybe.spec
@@ -1,8 +1,8 @@
 module spec Data.Maybe where
 
-measure isJust :: forall a. Data.Maybe.Maybe a -> Prop
-isJust (Data.Maybe.Just x)  = true
-isJust (Data.Maybe.Nothing) = false
+measure isJust :: forall a. Data.Maybe.Maybe a -> Bool
+isJust (Data.Maybe.Just x)  = true 
+isJust (Data.Maybe.Nothing) = false 
 
 measure fromJust :: forall a. Data.Maybe.Maybe a -> a
 fromJust (Data.Maybe.Just x) = x
diff --git a/include/Data/Set.spec b/include/Data/Set.spec
--- a/include/Data/Set.spec
+++ b/include/Data/Set.spec
@@ -19,36 +19,36 @@
 measure Set_sng   :: a -> (Data.Set.Set a)
 
 // emptiness test
-measure Set_emp   :: (Data.Set.Set a) -> Prop
+measure Set_emp   :: (Data.Set.Set a) -> GHC.Types.Bool
 
 // empty set
 measure Set_empty :: forall a. GHC.Types.Int -> (Data.Set.Set a)
 
 
 // membership test
-measure Set_mem  :: a -> (Data.Set.Set a) -> Prop
+measure Set_mem  :: a -> (Data.Set.Set a) -> GHC.Types.Bool
 
 // inclusion test
-measure Set_sub  :: (Data.Set.Set a) -> (Data.Set.Set a) -> Prop
+measure Set_sub  :: (Data.Set.Set a) -> (Data.Set.Set a) -> GHC.Types.Bool
 
 // ---------------------------------------------------------------------------------------------
 // -- | Refined Types for Data.Set Operations --------------------------------------------------
 // ---------------------------------------------------------------------------------------------
 
-isSubsetOf    :: (GHC.Classes.Ord a) => x:(Data.Set.Set a) -> y:(Data.Set.Set a) -> {v:Bool | ((Prop v) <=> (Set_sub x y))}
-member        :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Set a) -> {v:Bool | ((Prop v) <=> (Set_mem x xs))}
-null          :: (GHC.Classes.Ord a) => xs:(Data.Set.Set a) -> {v:Bool | ((Prop v) <=> (Set_emp xs))}
+isSubsetOf    :: (GHC.Classes.Ord a) => x:(Data.Set.Set a) -> y:(Data.Set.Set a) -> {v:Bool | v <=> Set_sub x y}
+member        :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Set a) -> {v:Bool | v <=> Set_mem x xs}
+null          :: (GHC.Classes.Ord a) => xs:(Data.Set.Set a) -> {v:Bool | v <=> Set_emp xs}
 
-empty         :: {v:(Data.Set.Set a) | (Set_emp v)}
+empty         :: {v:(Data.Set.Set a) | Set_emp v}
 singleton     :: x:a -> {v:(Data.Set.Set a) | v = (Set_sng x)}
-insert        :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = (Set_cup xs (Set_sng x))}
-delete        :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = (Set_dif xs (Set_sng x))}
+insert        :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = Set_cup xs (Set_sng x)}
+delete        :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = Set_dif xs (Set_sng x)}
 
-union         :: GHC.Classes.Ord a => xs:(Data.Set.Set a) -> ys:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = (Set_cup xs ys)}
-intersection  :: GHC.Classes.Ord a => xs:(Data.Set.Set a) -> ys:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = (Set_cap xs ys)}
-difference    :: GHC.Classes.Ord a => xs:(Data.Set.Set a) -> ys:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = (Set_dif xs ys)}
+union         :: GHC.Classes.Ord a => xs:(Data.Set.Set a) -> ys:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = Set_cup xs ys}
+intersection  :: GHC.Classes.Ord a => xs:(Data.Set.Set a) -> ys:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = Set_cap xs ys}
+difference    :: GHC.Classes.Ord a => xs:(Data.Set.Set a) -> ys:(Data.Set.Set a) -> {v:(Data.Set.Set a) | v = Set_dif xs ys}
 
-fromList :: GHC.Classes.Ord a => xs:[a] -> {v:Data.Set.Set a | v = (listElts xs)}
+fromList :: GHC.Classes.Ord a => xs:[a] -> {v:Data.Set.Set a | v = listElts xs}
 
 // ---------------------------------------------------------------------------------------------
 // -- | The set of elements in a list ----------------------------------------------------------
@@ -56,4 +56,4 @@
 
 measure listElts :: [a] -> (Data.Set.Set a)
 listElts([])   = {v | (Set_emp v)}
-listElts(x:xs) = {v | v = (Set_cup (Set_sng x) (listElts xs)) }
+listElts(x:xs) = {v | v = Set_cup (Set_sng x) (listElts xs) }
diff --git a/include/Data/Text/Fusion/Common.spec b/include/Data/Text/Fusion/Common.spec
--- a/include/Data/Text/Fusion/Common.spec
+++ b/include/Data/Text/Fusion/Common.spec
@@ -6,6 +6,7 @@
 cons :: GHC.Types.Char
      -> s:Data.Text.Fusion.Internal.Stream Char
      -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (1 + (slen s))}
+
 snoc :: s:Data.Text.Fusion.Internal.Stream Char
      -> GHC.Types.Char
      -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (1 + (slen s))}
@@ -15,18 +16,21 @@
                -> {v:GHC.Types.Ordering | ((v = GHC.Types.EQ) <=> ((slen s) = l))}
 
 isSingleton :: s:Data.Text.Fusion.Internal.Stream Char
-            -> {v:GHC.Types.Bool | ((Prop v) <=> ((slen s) = 1))}
+            -> {v:GHC.Types.Bool | (v <=> ((slen s) = 1))}
+
 singleton   :: GHC.Types.Char
             -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = 1}
 
 streamList   :: l:[a]
              -> {v:Data.Text.Fusion.Internal.Stream a | (slen v) = (len l)}
+
 unstreamList :: s:Data.Text.Fusion.Internal.Stream a
              -> {v:[a] | (len v) = (slen s)}
 
 map :: (GHC.Types.Char -> GHC.Types.Char)
     -> s:Data.Text.Fusion.Internal.Stream Char
     -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (slen s)}
+
 filter :: (GHC.Types.Char -> GHC.Types.Bool)
        -> s:Data.Text.Fusion.Internal.Stream Char
        -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) <= (slen s)}
@@ -41,6 +45,7 @@
 
 toCaseFold :: s:Data.Text.Fusion.Internal.Stream Char
            -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) >= (slen s)}
+
 toUpper    :: s:Data.Text.Fusion.Internal.Stream Char
            -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) >= (slen s)}
 toLower    :: s:Data.Text.Fusion.Internal.Stream Char
diff --git a/include/Data/Vector.hquals b/include/Data/Vector.hquals
--- a/include/Data/Vector.hquals
+++ b/include/Data/Vector.hquals
@@ -1,13 +1,13 @@
-qualif VecEmpty(v: Vector a)             : (vlen v)  =  0 
-qualif VecEmpty(v: Vector a)             : (vlen v)  >  0 
-qualif VecEmpty(v: Vector a)             : (vlen v)  >= 0 
+qualif VecEmpty(v: Data.Vector.Vector a)    : (vlen v)  =  0 
+qualif VecEmpty(v: Data.Vector.Vector a)    : (vlen v)  >  0 
+qualif VecEmpty(v: Data.Vector.Vector a)    : (vlen v)  >= 0 
 
-qualif Vlen(v:int, x: Vector a)          : (v  =  vlen x)
-qualif Vlen(v:int, x: Vector a)          : (v <=  vlen x) 
-qualif Vlen(v:int, x: Vector a)          : (v  <  vlen x) 
+qualif Vlen(v:int, x: Data.Vector.Vector a) : (v  =  vlen x)
+qualif Vlen(v:int, x: Data.Vector.Vector a) : (v <=  vlen x) 
+qualif Vlen(v:int, x: Data.Vector.Vector a) : (v  <  vlen x) 
 
-qualif CmpVlen(v: Vector a, x: Vector b) : (vlen v <  vlen x) 
-qualif CmpVlen(v: Vector a, x: Vector b) : (vlen v <= vlen x) 
-qualif CmpVlen(v: Vector a, x: Vector b) : (vlen v >  vlen x) 
-qualif CmpVlen(v: Vector a, x: Vector b) : (vlen v >= vlen x) 
-qualif CmpVlen(v: Vector a, x: Vector b) : (vlen v =  vlen x) 
+qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v <  vlen x) 
+qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v <= vlen x) 
+qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v >  vlen x) 
+qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v >= vlen x) 
+qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v =  vlen x) 
diff --git a/include/Data/Vector.spec b/include/Data/Vector.spec
--- a/include/Data/Vector.spec
+++ b/include/Data/Vector.spec
@@ -2,7 +2,7 @@
 
 import GHC.Base
 
-data variance Vector covariant
+data variance Data.Vector.Vector covariant
 
 
 measure vlen    :: forall a. (Data.Vector.Vector a) -> Int
diff --git a/include/Data/Word.spec b/include/Data/Word.spec
--- a/include/Data/Word.spec
+++ b/include/Data/Word.spec
@@ -1,3 +1,6 @@
 module spec Data.Word where
 
 import GHC.Word
+
+invariant {v:GHC.Word.Word32 | 0 <= v }
+invariant {v:GHC.Word.Word16 | 0 <= v }
diff --git a/include/Data/Word8.spec b/include/Data/Word8.spec
new file mode 100644
--- /dev/null
+++ b/include/Data/Word8.spec
@@ -0,0 +1,5 @@
+module spec Data.Word8 where
+
+import GHC.Word
+
+invariant {v:GHC.Word.Word8 | 0 <= v }
diff --git a/include/Foreign/C/String.spec b/include/Foreign/C/String.spec
--- a/include/Foreign/C/String.spec
+++ b/include/Foreign/C/String.spec
@@ -5,5 +5,5 @@
 type CStringLen    = ((GHC.Ptr.Ptr Foreign.C.Types.CChar), Nat)<{\p v -> (v <= (plen p))}>
 type CStringLenN N = ((GHC.Ptr.Ptr Foreign.C.Types.CChar), {v:Nat | v = N})<{\p v -> (v <= (plen p))}>
 
-measure cStringLen :: Foreign.C.String.CStringLen -> Int
+measure cStringLen :: Foreign.C.String.CStringLen -> GHC.Types.Int
 cStringLen (c, n) = n
diff --git a/include/Foreign/ForeignPtr.spec b/include/Foreign/ForeignPtr.spec
--- a/include/Foreign/ForeignPtr.spec
+++ b/include/Foreign/ForeignPtr.spec
@@ -3,7 +3,9 @@
 import GHC.ForeignPtr
 import Foreign.Ptr
 
-Foreign.ForeignPtr.withForeignPtr :: fp:(GHC.ForeignPtr.ForeignPtr a) -> ((PtrN a (fplen fp)) -> GHC.Types.IO b) -> (GHC.Types.IO b)
+Foreign.ForeignPtr.withForeignPtr :: fp:(GHC.ForeignPtr.ForeignPtr a) 
+  -> ((PtrN a (fplen fp)) -> GHC.Types.IO b) 
+  -> (GHC.Types.IO b)
 GHC.ForeignPtr.newForeignPtr_     :: p:(GHC.Ptr.Ptr a) -> (GHC.Types.IO (ForeignPtrN a (plen p)))
 Foreign.Concurrent.newForeignPtr  :: p:(PtrV a) -> GHC.Types.IO () -> (GHC.Types.IO (ForeignPtrN a (plen p)))
 
diff --git a/include/GHC/Base.hquals b/include/GHC/Base.hquals
--- a/include/GHC/Base.hquals
+++ b/include/GHC/Base.hquals
@@ -1,8 +1,8 @@
 //qualif NonNull(v: [a])        : (? (nonnull([v])))
 //qualif Null(v: [a])           : (~ (? (nonnull([v]))))
-//qualif EqNull(v:Bool, ~A: [a]): (Prop(v) <=> (? (nonnull([~A]))))
+//qualif EqNull(v:Bool, ~A: [a]): (v <=> (? (nonnull([~A]))))
 
-// qualif IsEmp(v:GHC.Types.Bool, ~A: [a]) : (Prop(v) <=> len([~A]) [ > ;  = ] 0)
+// qualif IsEmp(v:GHC.Types.Bool, ~A: [a]) : ((v) <=> len([~A]) [ > ;  = ] 0)
 // qualif ListZ(v: [a])          : len([v]) [ = ; >= ; > ] 0 
 // qualif CmpLen(v:[a], ~A:[b])  : len([v]) [= ; >=; >; <=; <] len([~A]) 
 // qualif EqLen(v:int, ~A: [a])  : v = len([~A]) 
@@ -10,8 +10,8 @@
 // qualif LenAcc(v:int, ~A:[a], ~B: int): v = len([~A]) + ~B
 // qualif LenDiff(v:[a], ~A:int): len([v]) = (~A [ +; - ] 1)
 
-qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (Prop(v) <=> len([xs]) > 0)
-qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (Prop(v) <=> len([xs]) = 0)
+qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (v <=> (len xs > 0))
+qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (v <=> (len xs = 0))
 
 qualif ListZ(v: [a])          : (len([v]) =  0) 
 qualif ListZ(v: [a])          : (len([v]) >= 0) 
diff --git a/include/GHC/Base.spec b/include/GHC/Base.spec
--- a/include/GHC/Base.spec
+++ b/include/GHC/Base.spec
@@ -6,9 +6,7 @@
 import GHC.Types
 
 embed GHC.Types.Int      as int
-embed Prop               as bool
-
-measure Prop   :: GHC.Types.Bool -> Prop
+embed GHC.Types.Bool     as bool
 
 measure autolen :: forall a. a -> GHC.Types.Int
 class measure len :: forall f a. f a -> GHC.Types.Int
@@ -16,23 +14,26 @@
 len []     = 0
 len (y:ys) = 1 + len ys
 
-measure null :: forall a. [a] -> Prop
-null []     = true
-null (x:xs) = false
 
+measure null :: [a] -> Bool
+null []     = true 
+null (y:ys) = false
+
 measure fst :: (a,b) -> a
 fst (a,b) = a
 
 measure snd :: (a,b) -> b
 snd (a,b) = b
 
-qualif Fst(v:a, y:b): (v = (fst y)) 
+qualif Fst(v:a, y:b): (v = (fst y))
 qualif Snd(v:a, y:b): (v = (snd y))
 
-
-invariant {v: [a] | len(v) >= 0 }
-map       :: (a -> b) -> xs:[a] -> {v: [b] | len(v) = len(xs)}
-(++)      :: xs:[a] -> ys:[a] -> {v:[a] | (len v) = (len xs) + (len ys)}
+invariant {v: [a] | len v >= 0 }
+map       :: (a -> b) -> xs:[a] -> {v: [b] | len v == len xs}
+(++)      :: xs:[a] -> ys:[a] -> {v:[a] | len v == len xs + len ys}
 
 ($)       :: (a -> b) -> a -> b
 id        :: x:a -> {v:a | v = x}
+
+data variance Text.ParserCombinators.ReadPrec.ReadPrec contravariant
+
diff --git a/include/GHC/CString.spec b/include/GHC/CString.spec
--- a/include/GHC/CString.spec
+++ b/include/GHC/CString.spec
@@ -2,6 +2,9 @@
 
 import GHC.Prim 
 
+measure strLen :: GHC.Base.String -> GHC.Types.Int
+embed GHC.Types.Char as Char
+
 GHC.CString.unpackCString#
   :: x:GHC.Prim.Addr#
   -> {v:[Char] | v ~~ x && len v == strLen x}
diff --git a/include/GHC/Classes.spec b/include/GHC/Classes.spec
--- a/include/GHC/Classes.spec
+++ b/include/GHC/Classes.spec
@@ -2,23 +2,23 @@
 
 import GHC.Types
 
-not     :: x:GHC.Types.Bool -> {v:GHC.Types.Bool | (Prop(v) <=> ~Prop(x))}
+not     :: x:GHC.Types.Bool -> {v:GHC.Types.Bool | ((v) <=> ~(x))}
 (&&)    :: x:GHC.Types.Bool -> y:GHC.Types.Bool
-        -> {v:GHC.Types.Bool | (Prop(v) <=> (Prop(x) && Prop(y)))}
+        -> {v:GHC.Types.Bool | ((v) <=> ((x) && (y)))}
 (||)    :: x:GHC.Types.Bool -> y:GHC.Types.Bool
-        -> {v:GHC.Types.Bool | (Prop(v) <=> (Prop(x) || Prop(y)))}
+        -> {v:GHC.Types.Bool | ((v) <=> ((x) || (y)))}
 (==)    :: (GHC.Classes.Eq  a) => x:a -> y:a
-        -> {v:GHC.Types.Bool | (Prop(v) <=> x = y)}
+        -> {v:GHC.Types.Bool | ((v) <=> x = y)}
 (/=)    :: (GHC.Classes.Eq  a) => x:a -> y:a
-        -> {v:GHC.Types.Bool | (Prop(v) <=> x != y)}
+        -> {v:GHC.Types.Bool | ((v) <=> x != y)}
 (>)     :: (GHC.Classes.Ord a) => x:a -> y:a
-        -> {v:GHC.Types.Bool | (Prop(v) <=> x > y)}
+        -> {v:GHC.Types.Bool | ((v) <=> x > y)}
 (>=)    :: (GHC.Classes.Ord a) => x:a -> y:a
-        -> {v:GHC.Types.Bool | (Prop(v) <=> x >= y)}
+        -> {v:GHC.Types.Bool | ((v) <=> x >= y)}
 (<)     :: (GHC.Classes.Ord a) => x:a -> y:a
-        -> {v:GHC.Types.Bool | (Prop(v) <=> x < y)}
+        -> {v:GHC.Types.Bool | ((v) <=> x < y)}
 (<=)    :: (GHC.Classes.Ord a) => x:a -> y:a
-        -> {v:GHC.Types.Bool | (Prop(v) <=> x <= y)}
+        -> {v:GHC.Types.Bool | ((v) <=> x <= y)}
 
 compare :: (GHC.Classes.Ord a) => x:a -> y:a
         -> {v:GHC.Types.Ordering | (((v = GHC.Types.EQ) <=> (x = y)) &&
diff --git a/include/GHC/ForeignPtr.spec b/include/GHC/ForeignPtr.spec
--- a/include/GHC/ForeignPtr.spec
+++ b/include/GHC/ForeignPtr.spec
@@ -2,8 +2,8 @@
 
 measure fplen :: GHC.ForeignPtr.ForeignPtr a -> GHC.Types.Int
 
-type ForeignPtrV a   = {v: (GHC.ForeignPtr.ForeignPtr  a) | 0 <= (fplen v)}
-type ForeignPtrN a N = {v: (ForeignPtrV a) | (fplen v) = N }
+type ForeignPtrV a   = {v: GHC.ForeignPtr.ForeignPtr a | 0 <= fplen v}
+type ForeignPtrN a N = {v: GHC.ForeignPtr.ForeignPtr a | 0 <= fplen v && fplen v == N }
 
 mallocPlainForeignPtrBytes :: n:{v:GHC.Types.Int  | v >= 0 } -> (GHC.Types.IO (ForeignPtrN a n))
 
diff --git a/include/GHC/List.spec b/include/GHC/List.spec
--- a/include/GHC/List.spec
+++ b/include/GHC/List.spec
@@ -1,12 +1,12 @@
 module spec GHC.List where 
 
-head         :: xs:{v: [a] | len(v) > 0} -> a
+head         :: xs:{v: [a] | len(v) > 0} -> {v:a | v = head xs}
 
-tail         :: xs:{v: [a] | len(v) > 0} -> {v: [a] | len(v) = (len(xs) - 1)}
+tail         :: xs:{v: [a] | len(v) > 0} -> {v: [a] | len(v) = (len(xs) - 1) && v = tail xs}
 last         :: xs:{v: [a] | len(v) > 0} -> a
 
 init         :: xs:{v: [a] | len(v) > 0} -> {v: [a] | len(v) = len(xs) - 1}
-null         :: xs:[a] -> {v: Bool | (Prop(v) <=> len(xs) = 0) }
+null         :: xs:[a] -> {v: Bool | ((v) <=> len(xs) = 0) }
 length       :: xs:[a] -> {v: GHC.Types.Int | v = len(xs)}
 filter       :: (a -> GHC.Types.Bool) -> xs:[a] -> {v: [a] | len(v) <= len(xs)}
 scanl        :: (a -> b -> a) -> a -> xs:[b] -> {v: [a] | len(v) = 1 + len(xs) }
@@ -15,16 +15,16 @@
 scanr        :: (a -> b -> b) -> b -> xs:[a] -> {v: [b] | len(v) = 1 + len(xs) }
 scanr1       :: (a -> a -> a) -> xs:{v: [a] | len(v) > 0} -> {v: [a] | len(v) = len(xs) }
 
-Lazy GHC.List.iterate
+lazy GHC.List.iterate
 iterate :: (a -> a) -> a -> [a]
 
 repeat :: a -> [a]
-Lazy GHC.List.repeat
+lazy GHC.List.repeat
 
 replicate    :: n:Nat -> x:a -> {v: [{v:a | v = x}] | len(v) = n}
 
 cycle        :: {v: [a] | len(v) > 0 } -> [a]
-Lazy cycle
+lazy cycle
 
 takeWhile    :: (a -> Bool) -> xs:[a] -> {v: [a] | len(v) <= len(xs)}
 
diff --git a/include/GHC/Prim.spec b/include/GHC/Prim.spec
--- a/include/GHC/Prim.spec
+++ b/include/GHC/Prim.spec
@@ -2,7 +2,7 @@
 
 embed GHC.Prim.Int#  as int
 embed GHC.Prim.Word# as int
-embed GHC.Prim.Addr# as int
+embed GHC.Prim.Addr# as Str
 
 embed GHC.Prim.Double#  as real
 
diff --git a/include/GHC/Ptr.spec b/include/GHC/Ptr.spec
--- a/include/GHC/Ptr.spec
+++ b/include/GHC/Ptr.spec
@@ -2,20 +2,23 @@
 
 measure pbase     :: Foreign.Ptr.Ptr a -> GHC.Types.Int
 measure plen      :: Foreign.Ptr.Ptr a -> GHC.Types.Int
-measure isNullPtr :: Foreign.Ptr.Ptr a -> Prop
+measure isNullPtr :: Foreign.Ptr.Ptr a -> Bool 
 
-type PtrN a N = {v: (PtrV a)        | (plen v)  = N }
-type PtrV a   = {v: (GHC.Ptr.Ptr a) | 0 <= (plen v) }
+invariant {v:Foreign.Ptr.Ptr a | 0 <= plen  v }
+invariant {v:Foreign.Ptr.Ptr a | 0 <= pbase v }
 
+type PtrN a N = {v: PtrV a        | plen v == N }
+type PtrV a   = {v: GHC.Ptr.Ptr a | 0 <= plen v }
+
 GHC.Ptr.castPtr :: p:(PtrV a) -> (PtrN b (plen p))
 
 GHC.Ptr.plusPtr :: base:(PtrV a)
-                -> off:{v:GHC.Types.Int | v <= (plen base) }
-                -> {v:(PtrV b) | (((pbase v) = (pbase base)) && ((plen v) = (plen base) - off))}
+                -> off:{v:GHC.Types.Int | v <= plen base }
+                -> {v:(PtrV b) | pbase v = pbase base && plen v = plen base - off}
 
 GHC.Ptr.minusPtr :: q:(PtrV a)
-                 -> p:{v:(PtrV b) | (((pbase v) = (pbase q)) && ((plen v) >= (plen q)))}
-                 -> {v:Nat | v = (plen p) - (plen q)}
+                 -> p:{v:(PtrV b) | pbase v == pbase q && plen v >= plen q}
+                 -> {v:Nat | v == plen p - plen q}
 
 measure deref     :: GHC.Ptr.Ptr a -> a
 
diff --git a/include/GHC/Real.spec b/include/GHC/Real.spec
--- a/include/GHC/Real.spec
+++ b/include/GHC/Real.spec
@@ -1,5 +1,7 @@
 module spec GHC.Real where
 
+(GHC.Real.^) :: (GHC.Num.Num a, GHC.Real.Integral b) => a:a -> n:b -> {v:a | v == 0 <=> a == 0 }
+
 GHC.Real.fromIntegral    :: (GHC.Real.Integral a, GHC.Num.Num b) => x:a -> {v:b|v=x}
 
 class (GHC.Num.Num a) => GHC.Real.Fractional a where
@@ -13,9 +15,13 @@
                                                      ((x >= 0 && y >= 1) => v <= x) }
   GHC.Real.rem :: x:a -> y:{v:a | v /= 0} -> {v:a | ((v >= 0) && (v < y))}
   GHC.Real.mod :: x:a -> y:{v:a | v /= 0} -> {v:a | v = x mod y && ((0 <= x && 0 < y) => (0 <= v && v < y))}
+
   GHC.Real.div :: x:a -> y:{v:a | v /= 0} -> {v:a | (v = (x / y)) &&
                                                     ((x >= 0 && y >= 0) => v >= 0) &&
-                                                    ((x >= 0 && y >= 1) => v <= x) }
+                                                    ((x >= 0 && y >= 1) => v <= x) && 
+                                                    ((1 < y)            => v < x ) && 
+                                                    ((y >= 1)           => v <= x)  
+                                                    }
   GHC.Real.quotRem :: x:a -> y:{v:a | v /= 0} -> ( {v:a | (v = (x / y)) &&
                                                           ((x >= 0 && y >= 0) => v >= 0) &&
                                                           ((x >= 0 && y >= 1) => v <= x)}
diff --git a/include/GHC/Types.spec b/include/GHC/Types.spec
--- a/include/GHC/Types.spec
+++ b/include/GHC/Types.spec
@@ -11,11 +11,11 @@
 cmp GHC.Types.GT = { v | v = GHC.Types.GT }
 
 
-GHC.Types.True  :: {v:GHC.Types.Bool | (Prop(v))}
-GHC.Types.False :: {v:GHC.Types.Bool | (~ (Prop(v)))}
+GHC.Types.True  :: {v:GHC.Types.Bool | ((v))}
+GHC.Types.False :: {v:GHC.Types.Bool | (~ ((v)))}
 
 
-GHC.Types.isTrue#  :: n:_ -> {v:GHC.Types.Bool | ((n = 1) <=> (Prop(v)))}
+GHC.Types.isTrue#  :: n:_ -> {v:GHC.Types.Bool | ((n = 1) <=> ((v)))}
 
 
 GHC.Types.W# :: w:_ -> {v:GHC.Types.Word | v == w }
diff --git a/include/Language/Haskell/Liquid/Foreign.hs b/include/Language/Haskell/Liquid/Foreign.hs
--- a/include/Language/Haskell/Liquid/Foreign.hs
+++ b/include/Language/Haskell/Liquid/Foreign.hs
@@ -36,7 +36,7 @@
 mkPtr = undefined -- Ptr x
 
 
-{-@ isNullPtr :: p:(Ptr a) -> {v:Bool | ((Prop v) <=> (isNullPtr p)) } @-}
+{-@ isNullPtr :: p:(Ptr a) -> {v:Bool | (v <=> (isNullPtr p)) } @-}
 isNullPtr :: Ptr a -> Bool
 isNullPtr p = (p == nullPtr)
 {-# INLINE isNullPtr #-}
@@ -55,7 +55,7 @@
 
 {-@ eqPtr :: p:PtrV a
           -> q:{v:PtrV a | (((pbase v) = (pbase p)) && ((plen v) <= (plen p)))}
-          -> {v:Bool | ((Prop v) <=> ((plen p) = (plen q)))}
+          -> {v:Bool | (v <=> ((plen p) = (plen q)))}
   @-}
 eqPtr :: Ptr a -> Ptr a -> Bool
 eqPtr = undefined
diff --git a/include/Language/Haskell/Liquid/Prelude.hs b/include/Language/Haskell/Liquid/Prelude.hs
--- a/include/Language/Haskell/Liquid/Prelude.hs
+++ b/include/Language/Haskell/Liquid/Prelude.hs
@@ -1,9 +1,5 @@
 {-# LANGUAGE MagicHash      #-}
-{-# LANGUAGE EmptyDataDecls #-}
 
-{- OPTIONS_GHC -cpp #-}
-{- OPTIONS_GHC -cpp -fglasgow-exts -}
-
 module Language.Haskell.Liquid.Prelude where
 
 -------------------------------------------------------------------
@@ -13,12 +9,12 @@
 {-@ assume plus   :: x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x + y}  @-}
 {-@ assume minus  :: x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x - y} @-}
 {-@ assume times  :: x:Int -> y:Int -> Int                           @-}
-{-@ assume eq     :: x:Int -> y:Int -> {v:Bool | ((Prop v) <=> x = y)}  @-}
-{-@ assume neq    :: x:Int -> y:Int -> {v:Bool | ((Prop v) <=> x != y)} @-}
-{-@ assume leq    :: x:Int -> y:Int -> {v:Bool | ((Prop v) <=> x <= y)} @-}
-{-@ assume geq    :: x:Int -> y:Int -> {v:Bool | ((Prop v) <=> x >= y)} @-}
-{-@ assume lt     :: x:Int -> y:Int -> {v:Bool | ((Prop v) <=> x < y)}  @-}
-{-@ assume gt     :: x:Int -> y:Int -> {v:Bool | ((Prop v) <=> x > y)}  @-}
+{-@ assume eq     :: x:Int -> y:Int -> {v:Bool | ((v) <=> x = y)}  @-}
+{-@ assume neq    :: x:Int -> y:Int -> {v:Bool | ((v) <=> x != y)} @-}
+{-@ assume leq    :: x:Int -> y:Int -> {v:Bool | ((v) <=> x <= y)} @-}
+{-@ assume geq    :: x:Int -> y:Int -> {v:Bool | ((v) <=> x >= y)} @-}
+{-@ assume lt     :: x:Int -> y:Int -> {v:Bool | ((v) <=> x < y)}  @-}
+{-@ assume gt     :: x:Int -> y:Int -> {v:Bool | ((v) <=> x > y)}  @-}
 
 {-# NOINLINE plus #-}
 plus :: Int -> Int -> Int
@@ -65,22 +61,22 @@
 -------------------------------------------------------------------
 
 
-{-@ assume liquidAssertB :: x:{v:Bool | (Prop v)} -> {v: Bool | (Prop v)} @-}
+{-@ assume liquidAssertB :: x:{v:Bool | v} -> {v: Bool | v} @-}
 {-# NOINLINE liquidAssertB #-}
 liquidAssertB :: Bool -> Bool
 liquidAssertB b = b
 
-{-@ assume liquidAssert :: {v:Bool | (Prop v)} -> a -> a  @-}
+{-@ assume liquidAssert :: {v:Bool | v} -> a -> a  @-}
 {-# NOINLINE liquidAssert #-}
-liquidAssert :: Bool -> a -> a 
+liquidAssert :: Bool -> a -> a
 liquidAssert _ x = x
 
-{-@ assume liquidAssume :: b:Bool -> a -> {v: a | (Prop b)}  @-}
+{-@ assume liquidAssume :: b:Bool -> a -> {v: a | b}  @-}
 {-# NOINLINE liquidAssume #-}
-liquidAssume :: Bool -> a -> a 
-liquidAssume _ x = x
+liquidAssume :: Bool -> a -> a
+liquidAssume b x = if b then x else error "liquidAssume fails"
 
-{-@ assume liquidAssumeB :: forall <p :: a -> Prop>. (a<p> -> {v:Bool| ((Prop v) <=> true)}) -> a -> a<p> @-}
+{-@ assume liquidAssumeB :: forall <p :: a -> Bool>. (a<p> -> {v:Bool| v}) -> a -> a<p> @-}
 liquidAssumeB :: (a -> Bool) -> a -> a
 liquidAssumeB p x | p x = x
                   | otherwise = error "liquidAssumeB fails"
@@ -90,31 +86,32 @@
 {-@ assume liquidError :: {v: String | 0 = 1} -> a  @-}
 {-# NOINLINE liquidError #-}
 liquidError :: String -> a
-liquidError = error 
+liquidError = error
 
-{-@ assume crash  :: forall a . x:{v:Bool | (Prop v)} -> a @-}
+{-@ assume crash  :: forall a . x:{v:Bool | v} -> a @-}
 {-# NOINLINE crash #-}
-crash :: Bool -> a 
-crash = undefined 
+crash :: Bool -> a
+crash = undefined
 
 {-# NOINLINE force #-}
-force = True 
+force :: Bool
+force = True
 
 {-# NOINLINE choose #-}
 choose :: Int -> Int
-choose = undefined 
+choose = undefined
 
 -------------------------------------------------------------------
 ----------- Modular Arithmetic Wrappers ---------------------------
 -------------------------------------------------------------------
 
 -- tedium because fixpoint doesnt want to deal with (x mod y) only (x mod c)
-{-@ assume isEven :: x:Int -> {v:Bool | ((Prop v) <=> ((x mod 2) = 0))} @-}
+{-@ assume isEven :: x:Int -> {v:Bool | ((v) <=> ((x mod 2) = 0))} @-}
 {-# NOINLINE isEven #-}
 isEven   :: Int -> Bool
 isEven x = x `mod` 2 == 0
 
-{-@ assume isOdd :: x:Int -> {v:Bool | ((Prop v) <=> ((x mod 2) = 1))} @-}
+{-@ assume isOdd :: x:Int -> {v:Bool | ((v) <=> ((x mod 2) = 1))} @-}
 {-# NOINLINE isOdd #-}
 isOdd   :: Int -> Bool
 isOdd x = x `mod` 2 == 1
@@ -125,12 +122,12 @@
 safeZipWith :: (a->b->c) -> [a]->[b]->[c]
 safeZipWith f (a:as) (b:bs) = f a b : safeZipWith f as bs
 safeZipWith _ []     []     = []
-safeZipWith _ _ _ = error "safeZipWith: cannot happen!"      
+safeZipWith _ _ _ = error "safeZipWith: cannot happen!"
 
 
 
 
-{-@ (==>) :: p:Bool -> q:Bool -> {v:Bool | Prop v <=> (Prop p =>  Prop q)} @-}
+{-@ (==>) :: p:Bool -> q:Bool -> {v:Bool | v <=> (p =>  q)} @-}
 infixr 8 ==>
 (==>) :: Bool -> Bool -> Bool
 False ==> False = True
diff --git a/include/Language/Haskell/Liquid/ProofCombinators.hs b/include/Language/Haskell/Liquid/ProofCombinators.hs
new file mode 100644
--- /dev/null
+++ b/include/Language/Haskell/Liquid/ProofCombinators.hs
@@ -0,0 +1,258 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE IncoherentInstances   #-}
+module Language.Haskell.Liquid.ProofCombinators (
+
+    (==:), (<=:), (<:), (>:)
+
+  , (==?)
+
+  , (==.), (<=.), (<.), (>.), (>=.)
+
+  , (?), (***)
+
+  , (==>), (&&&), (∵)
+
+  , proof, toProof, simpleProof, trivial
+
+  , QED(..)
+
+  , Proof
+
+  , byTheorem, castWithTheorem, cast 
+
+  -- Function Equality 
+  , Arg
+
+  , (=*=.)
+  ) where
+
+
+type Proof = ()
+
+trivial :: Proof
+trivial = ()
+
+
+data QED = QED
+
+infixl 2 ***
+
+(***) :: a -> QED -> Proof
+_ *** _ = ()
+
+
+-- | Because provide lemmata ? or ∵
+
+infixl 3 ∵
+
+(∵) :: (Proof -> a) -> Proof -> a
+f ∵ y = f y
+
+
+infixl 3 ?
+
+(?) :: (Proof -> a) -> Proof -> a
+f ? y = f y
+
+
+
+{-@ measure proofBool :: Proof -> Bool @-}
+
+-- | Proof combinators (are Proofean combinators)
+{-@ (==>) :: p:Proof
+          -> q:Proof
+          -> {v:Proof |
+          (((proofBool p)) && ((proofBool p) => (proofBool q)))
+          =>
+          (((proofBool p) && (proofBool q)))
+          } @-}
+(==>) :: Proof -> Proof -> Proof
+_ ==> _ = ()
+
+
+{- (&&&) :: p:{Proof | (proofBool p) }
+          -> q:{Proof | (proofBool q) }
+          -> {v:Proof | (proofBool p) && (proofBool q) } @-}
+(&&&) :: Proof -> Proof -> Proof
+_ &&& _ = ()
+
+
+-- | proof goes from Int to resolve types for the optional proof combinators
+proof :: Int -> Proof
+proof _ = ()
+
+toProof :: a -> Proof
+toProof _ = ()
+
+simpleProof :: Proof
+simpleProof = ()
+
+-- | proof operators requiring proof terms
+infixl 3 ==:, <=:, <:, >:, ==?
+
+
+-- | Comparison operators requiring proof terms
+
+(<=:) :: a -> a -> Proof -> a
+{-@ (<=:) :: x:a -> y:a -> {v:Proof | x <= y } -> {v:a | v == x } @-}
+(<=:) x _ _ = x
+
+(<:) :: a -> a -> Proof -> a
+{-@ (<:) :: x:a -> y:a -> {v:Proof | x < y } -> {v:a | v == x } @-}
+(<:) x _ _ = x
+
+
+(>:) :: a -> a -> Proof -> a
+{-@ (>:) :: x:a -> y:a -> {v:Proof | x >y } -> {v:a | v == x } @-}
+(>:) x _ _ = x
+
+
+(==:) :: a -> a -> Proof -> a
+{-@ (==:) :: x:a -> y:a -> {v:Proof| x == y} -> {v:a | v == x && v == y } @-}
+(==:) x _ _ = x
+
+
+-- | proof operators with optional proof terms
+infixl 3 ==., <=., <., >., >=.
+
+
+-- | Comparison operators requiring proof terms optionally
+
+class ToProve a r where
+  (==?) :: a -> a -> r
+
+
+instance (a~b) => ToProve a b where
+{-@ instance ToProve a b where
+  ==? :: x:a -> y:a -> {v:b | v ~~ x }
+  @-}
+  (==?)  = undefined
+
+instance (a~b) => ToProve a (Proof -> b) where
+{-@ instance ToProve a (Proof -> b) where
+  ==? :: x:a -> y:a -> Proof -> {v:b | v ~~ x  }
+  @-}
+  (==?) = undefined
+
+
+
+class OptEq a r where
+  (==.) :: a -> a -> r
+
+instance (a~b) => OptEq a (Proof -> b) where
+{-@ instance OptEq a (Proof -> b) where
+  ==. :: x:a -> y:a -> {v:Proof | x == y} -> {v:b | v ~~ x && v ~~ y}
+  @-}
+  (==.) x _ _ = x
+
+instance (a~b) => OptEq a b where
+{-@ instance OptEq a b where
+  ==. :: x:a -> y:{a| x == y} -> {v:b | v ~~ x && v ~~ y }
+  @-}
+  (==.) x _ = x
+
+
+class OptLEq a r where
+  (<=.) :: a -> a -> r
+
+
+instance (a~b) => OptLEq a (Proof -> b) where
+{-@ instance OptLEq a (Proof -> b) where
+  <=. :: x:a -> y:a -> {v:Proof | x <= y} -> {v:b | v ~~ x }
+  @-}
+  (<=.) x _ _ = x
+
+instance (a~b) => OptLEq a b where
+{-@ instance OptLEq a b where
+  <=. :: x:a -> y:{a | x <= y} -> {v:b | v ~~ x }
+  @-}
+  (<=.) x _ = x
+
+class OptGEq a r where
+  (>=.) :: a -> a -> r
+
+instance OptGEq a (Proof -> a) where
+{-@ instance OptGEq a (Proof -> a) where
+  >=. :: x:a -> y:a -> {v:Proof| x >= y} -> {v:a | v == x }
+  @-}
+  (>=.) x _ _ = x
+
+instance OptGEq a a where
+{-@ instance OptGEq a a where
+  >=. :: x:a -> y:{a| x >= y} -> {v:a | v == x  }
+  @-}
+  (>=.) x _ = x
+
+
+class OptLess a r where
+  (<.) :: a -> a -> r
+
+instance (a~b) => OptLess a (Proof -> b) where
+{-@ instance OptLess a (Proof -> b) where
+  <. :: x:a -> y:a -> {v:Proof | x < y} -> {v:b | v ~~ x  }
+  @-}
+  (<.) x _ _ = x
+
+instance (a~b) => OptLess a b where
+{-@ instance OptLess a b where
+  <. :: x:a -> y:{a| x < y} -> {v:b | v ~~ x  }
+  @-}
+  (<.) x _ = x
+
+
+class OptGt a r where
+  (>.) :: a -> a -> r
+
+instance (a~b) => OptGt a (Proof -> b) where
+{-@ instance OptGt a (Proof -> b) where
+  >. :: x:a -> y:a -> {v:Proof| x > y} -> {v:b | v ~~ x }
+  @-}
+  (>.) x _ _ = x
+
+instance (a~b) => OptGt a b where
+{-@ instance OptGt a b where
+  >. :: x:a -> y:{a| x > y} -> {v:b | v ~~ x  }
+  @-}
+  (>.) x _ = x
+
+
+-------------------------------------------------------------------------------
+----------  Casting -----------------------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ measure castWithTheorem :: a -> b -> b @-}
+castWithTheorem :: a -> b -> b 
+castWithTheorem _ x = x 
+
+
+{-@ measure cast :: b -> a -> a @-}
+{-@ cast :: b -> x:a -> {v:a | v == x } @-}
+cast :: b -> a -> a 
+cast _ x = x 
+
+
+byTheorem :: a -> Proof -> a
+byTheorem a _ = a
+
+-- | Function Equality 
+
+{- TO REFINE 
+class FunEq a b r where
+  (=*=.) :: (a -> b) -> (a -> b) -> r
+
+instance (c~(a -> b)) => FunEq a b ((a -> Proof) -> c) where
+  {-@ instance FunEq a b ((a -> Proof) -> a -> b) where
+   =*=. :: f:(a -> b) -> g:(a -> b) -> (r:a -> {f r == g r}) -> {v:_ | f == g && v ~~ f && v ~~ g}
+   @-} 
+   f =*=. g = undefined  
+-}
+
+class Arg a where 
+
+
+{-@ assume (=*=.) :: Arg a => f:(a -> b) -> g:(a -> b) -> (r:a -> {f r == g r}) -> {v:(a -> b) | f == g} @-}
+(=*=.) :: Arg a => (a -> b) -> (a -> b) -> (a -> Proof) -> (a -> b)
+(=*=.) f _ _ = f
diff --git a/include/Language/Haskell/Liquid/String.hs b/include/Language/Haskell/Liquid/String.hs
new file mode 100644
--- /dev/null
+++ b/include/Language/Haskell/Liquid/String.hs
@@ -0,0 +1,62 @@
+-- Support for Strings for SMT 
+
+{-# LANGUAGE OverloadedStrings   #-}
+
+module Language.Haskell.Liquid.String where
+
+import qualified Data.ByteString as BS
+import qualified Data.String     as ST
+
+{-@ embed SMTString as Str @-}
+
+data SMTString = S BS.ByteString 
+  deriving (Eq, Show)
+
+{-@ invariant {s:SMTString | 0 <= stringLen s } @-}
+
+{-@ measure stringEmp    :: SMTString @-}
+{-@ measure stringLen    :: SMTString -> Int @-}
+{-@ measure subString    :: SMTString -> Int -> Int -> SMTString @-}
+{-@ measure concatString :: SMTString -> SMTString -> SMTString @-}
+{-@ measure fromString   :: String -> SMTString @-}
+{-@ measure takeString   :: Int -> SMTString -> SMTString @-}
+{-@ measure dropString   :: Int -> SMTString -> SMTString @-}
+
+----------------------------------
+
+{-@ assume concatString :: x:SMTString -> y:SMTString 
+                 -> {v:SMTString | v == concatString x y && stringLen v == stringLen x + stringLen y } @-}
+concatString :: SMTString -> SMTString -> SMTString
+concatString (S s1) (S s2) = S (s1 `BS.append` s2)
+
+{-@ assume stringEmp :: {v:SMTString | v == stringEmp  && stringLen v == 0 } @-}
+stringEmp :: SMTString
+stringEmp = S (BS.empty)
+
+stringLen :: SMTString -> Int  
+{-@ assume stringLen :: x:SMTString -> {v:Nat | v == stringLen x} @-}
+stringLen (S s) = BS.length s 
+
+
+{-@ assume subString  :: s:SMTString -> offset:Int -> ln:Int -> {v:SMTString | v == subString s offset ln } @-}
+subString :: SMTString -> Int -> Int -> SMTString 
+subString (S s) o l = S (BS.take l $ BS.drop o s) 
+
+
+{-@ takeString :: i:Nat -> xs:{SMTString | i <= stringLen xs } -> {v:SMTString | stringLen v == i && v == takeString i xs } @-} 
+takeString :: Int -> SMTString -> SMTString
+takeString i (S s) = S (BS.take i s)
+
+{-@ dropString :: i:Nat -> xs:{SMTString | i <= stringLen xs } -> {v:SMTString | stringLen v == stringLen xs - i && v == dropString i xs } @-} 
+dropString :: Int -> SMTString -> SMTString
+dropString i (S s) = S (BS.drop i s)
+
+
+{-@ assume fromString :: i:String -> {o:SMTString | i == o && o == fromString i} @-}
+fromString :: String -> SMTString
+fromString = S . ST.fromString 
+
+
+{-@ isNullString :: i:SMTString -> {b:Bool | b <=> stringLen i == 0 } @-} 
+isNullString :: SMTString -> Bool 
+isNullString (S s) = BS.length s == 0 
diff --git a/include/Prelude.hquals b/include/Prelude.hquals
--- a/include/Prelude.hquals
+++ b/include/Prelude.hquals
@@ -1,19 +1,19 @@
 //BOT: Do not delete EVER!
 
-qualif Bot(v:@(0))    : (0 = 1) 
-qualif Bot(v:obj)     : (0 = 1) 
-qualif Bot(v:a)       : (0 = 1) 
-qualif Bot(v:bool)    : (0 = 1) 
-qualif Bot(v:int)     : (0 = 1) 
+qualif Bot(v:@(0))    : (0 = 1)
+qualif Bot(v:obj)     : (0 = 1)
+qualif Bot(v:a)       : (0 = 1)
+qualif Bot(v:bool)    : (0 = 1)
+qualif Bot(v:int)     : (0 = 1)
 
-qualif CmpZ(v:a)      : (v <  0) 
+qualif CmpZ(v:a)      : (v <  0)
 qualif CmpZ(v:a)      : (v <= 0)
 qualif CmpZ(v:a)      : (v >  0)
 qualif CmpZ(v:a)      : (v >= 0)
 qualif CmpZ(v:a)      : (v  = 0)
 qualif CmpZ(v:a)      : (v != 0)
 
-qualif Cmp(v:a, x:a)  : (v <  x) 
+qualif Cmp(v:a, x:a)  : (v <  x)
 qualif Cmp(v:a, x:a)  : (v <= x)
 qualif Cmp(v:a, x:a)  : (v >  x)
 qualif Cmp(v:a, x:a)  : (v >= x)
@@ -26,10 +26,8 @@
 
 
 qualif One(v:int)     : v = 1
-qualif True(v:bool)   : (? v) 
-qualif False(v:bool)  : ~ (? v) 
-qualif True1(v:GHC.Types.Bool)   : (Prop(v))
-qualif False1(v:GHC.Types.Bool)  : (~ Prop(v))
+qualif True1(v:GHC.Types.Bool)   : (v)
+qualif False1(v:GHC.Types.Bool)  : (~ v)
 
 
 constant papp1 : func(1, [Pred @(0); @(0); bool])
@@ -44,9 +42,4 @@
 // qualif Papp4(v:a,x:b, y:c, z:d, p:Pred a b c d) : papp4(p, v, x, y, z)
 constant papp4 : func(8, [Pred @(0) @(1) @(2) @(6); @(3); @(4); @(5); @(7); bool])
 
-
-constant Prop : func(0, [GHC.Types.Bool; bool])
 constant runFun : func(2, [Arrow @(0) @(1); @(0); @(1)])
-
-
-
diff --git a/include/Prelude.spec b/include/Prelude.spec
--- a/include/Prelude.spec
+++ b/include/Prelude.spec
@@ -14,7 +14,7 @@
 
 GHC.Exts.D# :: x:_ -> {v:_ | v = x}
 
-assume GHC.Base.. :: forall <p :: b -> c -> Prop, q :: a -> b -> Prop, r :: a -> c -> Prop>. 
+assume GHC.Base.. :: forall <p :: b -> c -> Bool, q :: a -> b -> Bool, r :: a -> c -> Bool>. 
                      {xcmp::a, wcmp::b<q xcmp> |- c<p wcmp> <: c<r xcmp>}
                      (ycmp:b -> c<p ycmp>)
                   -> (zcmp:a -> b<q zcmp>)
@@ -22,9 +22,14 @@
 assume GHC.Integer.smallInteger :: x:GHC.Prim.Int#
                                 -> { v:GHC.Integer.Type.Integer |
                                      v = (x :: int) }
-assume GHC.Num.+                :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x + y }
-assume GHC.Num.-                :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x - y }
 
+assume GHC.Num.+ :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x + y }
+assume GHC.Num.- :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x - y }
+
+
+
+
+
 embed GHC.Types.Double          as real
 embed GHC.Integer.Type.Integer  as int
 
@@ -34,8 +39,8 @@
 type Even    = {v: GHC.Types.Int | (v mod 2) = 0 }
 type Odd     = {v: GHC.Types.Int | (v mod 2) = 1 }
 type BNat N  = {v: Nat           | v <= N }    
-type TT      = {v: Bool          | Prop v}
-type FF      = {v: Bool          | not (Prop v)}
+type TT      = {v: Bool          | v}
+type FF      = {v: Bool          | not v}
 
 predicate Max V X Y = if X > Y then V = X else V = Y
 predicate Min V X Y = if X < Y then V = X else V = Y
diff --git a/liquid-fixpoint/.ghci b/liquid-fixpoint/.ghci
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/.ghci
@@ -0,0 +1,1 @@
+:set -isrc
diff --git a/liquid-fixpoint/.git b/liquid-fixpoint/.git
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/.git
@@ -0,0 +1,1 @@
+gitdir: ../.git/modules/liquid-fixpoint
diff --git a/liquid-fixpoint/.gitignore b/liquid-fixpoint/.gitignore
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/.gitignore
@@ -0,0 +1,30 @@
+.depend
+*.cmi
+*.cmo
+*.cmx
+*.o
+/dist*
+.liquid
+/.vagrant/
+/.stack-work/
+/build.sh
+/external/fixpoint/config.make
+/external/fixpoint/fixpoint.native
+/external/fixpoint/misc
+/external/fixpoint/smtZ3.ml
+/external/ocamlgraph/META
+/external/ocamlgraph/Makefile
+/external/ocamlgraph/config.status
+/external/ocamlgraph/graph.a
+/external/ocamlgraph/graph.cma
+/external/ocamlgraph/graph.cmxa
+/external/ocamlgraph/src/dot_lexer.ml
+/external/ocamlgraph/src/dot_parser.ml
+/external/ocamlgraph/src/dot_parser.mli
+/external/ocamlgraph/src/dot_parser.output
+/external/ocamlgraph/src/gml.ml
+/external/ocamlgraph/src/version.ml
+/tests/neg/.liquid/
+/tests/pos/.liquid/
+/external/ocamlgraph/config.log
+/TAGS
diff --git a/liquid-fixpoint/.travis.yml b/liquid-fixpoint/.travis.yml
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/.travis.yml
@@ -0,0 +1,51 @@
+language: c
+sudo: false
+
+# Only build master, develop, and PRs
+branches:
+  only:
+  - master
+  - develop
+  - parser-az
+
+matrix:
+  include:
+    - env: SMT="z3" CABAL=1.22 GHC=7.10.3
+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,],sources: [hvr-ghc]}}
+    - env: SMT="z3" CABAL=1.24 GHC=8.0.1
+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,],sources: [hvr-ghc]}}
+    - env: SMT="z3" CABAL=1.24 GHC=8.0.2
+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2,],sources: [hvr-ghc]}}
+    - env: CABALVER=head GHCVER=head
+      addons: {apt: {packages: [cabal-install-head,ghc-head],  sources: [hvr-ghc]}}
+
+  allow_failures:
+   - env: CABALVER=head GHCVER=head
+
+cache:
+  directories:
+  - $HOME/.cabal
+  - $HOME/.ghc
+
+before_install:
+ - export PATH="$HOME/.cabal/bin:/opt/ghc/$GHC/bin:/opt/cabal/$CABAL/bin:$PATH"
+ - scripts/travis clean_cache "$SMT"
+
+install:
+ - scripts/travis install_cabal_deps
+ - scripts/travis install_smt "$SMT"
+
+script:
+ - scripts/travis do_build && scripts/travis do_test "$SMT"
+ - scripts/travis clean_cache "$SMT"
+
+after_failure:
+ - scripts/travis dump_fail_logs
+
+notifications:
+  slack:
+    rooms:
+      secure: VT1SqW+4WQKb2PXgObQ/rNdQN8pFK5LaFacxB0fEvRZ2FSbM3qp1NGgii7WHlQdr598+L5qYhkpy1B8ssgNeR7iMmYP4GV/fhCoMd8nTQHLSrTMH8iQgT0D7SnuKdk5FQq1IXWtHjUzXtTIhnkfwOJF/xYf6BMMrO0sCta5JZgg=
+    on_success: change
+    on_failure: always
+    on_start: never
diff --git a/liquid-fixpoint/CHANGES.md b/liquid-fixpoint/CHANGES.md
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/CHANGES.md
@@ -0,0 +1,29 @@
+# CHANGES
+
+## NEXT
+
+## 0.3.0.0
+
+- Make interpreted mul and div the default, when `solver = z3`
+- Use `higherorder` flag to allow higher order binders into the environment 
+
+## 0.2.2.0
+
+- Added support for theory of Arrays `Map_t`, `Map_select`, `Map_store`
+
+- Added support for theory of Bitvectors -- see `Language.Fixpoint.Smt.Bitvector`
+
+- Added support for string literals
+
+## 0.2.1.0
+
+- Pre-compiled binaries of the underlying ocaml solver are now
+  provided for Linux, Mac OSX, and Windows.
+
+  No more need to install Ocaml!
+
+## 0.2.0.0
+
+- Parsing has been improved to require *much* fewer parentheses.
+
+- Experimental support for Z3's theory of real numbers with the `--real` flag.
diff --git a/liquid-fixpoint/LICENSE b/liquid-fixpoint/LICENSE
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013-2014, Ranjit Jhala
+
+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 Ranjit Jhala 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/liquid-fixpoint/Makefile b/liquid-fixpoint/Makefile
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/Makefile
@@ -0,0 +1,59 @@
+
+OPTS="-W -O2 -XStandaloneDeriving"
+PROFOPTS="-O2 -rtsopts -prof -auto-all -caf-all -XStandaloneDeriving -XDeriveDataTypeable"
+
+CABAL=cabal
+CABALI=$(CABAL) install --ghc-options=$(OPTS)
+CABALP=$(CABAL) install --ghc-options=$(OPTS) -p
+
+DEPS=unix-compat transformers mtl filemanip text parsec ghc-paths deepseq comonad contravariant semigroupoids semigroups bifunctors hscolour ansi-terminal hashable unordered-containers
+
+TASTY=./dist/build/test/test
+
+all:
+	$(CABAL) install --ghc-options=$(OPTS)
+
+force:
+	$(CABAL) install --force-reinstalls --ghc-options=$(OPTS)
+
+rebuild: ocaml
+	make
+
+igoto:
+	$(CABAL) configure --ghc-options=$(OPTS)
+
+goto:
+	$(CABAL) build --ghc-options=$(OPTS)
+	cp dist/build/liquid/liquid ~/.cabal/bin/
+
+prof:
+	$(CABAL) install --enable-executable-profiling --enable-library-profiling --ghc-options=$(PROFOPTS)
+
+clean:
+	cabal clean
+
+docs:
+	$(CABAL) haddock --executables --internal --hoogle --hyperlink-source #--html-location=http://goto.ucsd.edu/~rjhala/llvm-haskell/
+
+
+deps:
+	$(CABALI) $(DEPS)
+
+pdeps:
+	$(CABALP) $(DEPS)
+
+lint:
+	hlint --colour --report .
+
+tags:
+	hasktags -c src/
+	hasktags -e src/
+	hasktags -x -c src/
+
+test:
+	cabal configure -fdevel --enable-tests --disable-library-profiling -O2
+	cabal build
+	cabal exec $(TASTY)
+
+test710:
+	$(TASTY)
diff --git a/liquid-fixpoint/README.md b/liquid-fixpoint/README.md
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/README.md
@@ -0,0 +1,303 @@
+Liquid Fixpoint [![Hackage](https://img.shields.io/hackage/v/liquid-fixpoint.svg)](https://hackage.haskell.org/package/liquid-fixpoint) [![Hackage-Deps](https://img.shields.io/hackage-deps/v/liquid-fixpoint.svg)](http://packdeps.haskellers.com/feed?needle=liquid-fixpoint) [![Build Status](https://img.shields.io/travis/ucsd-progsys/liquid-fixpoint/master.svg)](https://travis-ci.org/ucsd-progsys/liquid-fixpoint)
+===============
+
+
+This package implements a Horn-Clause/Logical Implication constraint solver used
+for various Liquid Types. The solver uses SMTLIB2 to implement an algorithm similar to:
+
++ [Houdini](https://users.soe.ucsc.edu/~cormac/papers/fme01.pdf)
++ [cartesian predicate abstraction](http://swt.informatik.uni-freiburg.de/berit/papers/boolean-and-cartesian-....pdf)
+
+
+Requirements
+------------
+
+In addition to the .cabal dependencies you require an SMTLIB2 compatible solver binary:
+
+- [Z3](http://z3.codeplex.com)
+- [CVC4](http://cvc4.cs.nyu.edu)
+- [MathSat](http://mathsat.fbk.eu/download.html)
+
+If on Windows, please make sure to place the binary and any associated DLLs somewhere
+in your path.
+
+How To Build and Install
+------------------------
+
+Simply do:
+
+    git clone https://github.com/ucsd-progsys/liquid-fixpoint.git
+    cd liquid-fixpoint
+    stack install
+
+or (`cabal` instead of `stack` if you prefer.)
+
+
+Using SMTLIB-based SMT Solvers
+------------------------------
+
+You can use one of several SMTLIB2 compliant solvers, by:
+
+    fixpoint --smtsolver=z3 path/to/file.hs
+
+Currently, we support
+
+    * Z3
+    * CVC4
+    * MathSat
+
+
+
+Configuration Management
+------------------------
+
+It is very important that the version of Liquid Fixpoint be maintained properly.
+
+Suppose that the current version of Liquid Haskell is `A.B.C.D`:
+
++ After a release to hackage is made, if any of the components `B`, `C`, or `D` are missing, they shall be added and set to `0`. Then the `D` component of Liquid Fixpoint shall be incremented by `1`. The version of Liquid Fixpoint is now `A.B.C.(D + 1)`
+
++ The first time a new function or type is exported from Liquid Fixpoint, if any of the components `B`, or `C` are missing, they shall be added and set to `0`. Then the `C` component shall be incremented by `1`, and the `D` component shall stripped. The version of Liquid Fixpoint is now `A.B.(C + 1)`
+
++ The first time the signature of an exported function or type is changed, or an exported function or type is removed (this includes functions or types that Liquid Fixpoint re-exports from its own dependencies), if the `B` component is missing, it shall be added and set to `0`. Then the `B` component shall be incremented by `1`, and the `C` and `D` components shall be stripped. The version of Liquid Fixpoint is now `A.(B + 1)`
+
++ The `A` component shall be updated at the sole discretion of the project owners.
+
+It is recommended to use the [Bumper](https://hackage.haskell.org/package/bumper) utility to manage the versioning of Liquid Fixpoint. Bumper will automatically do the correct update to the cabal file. Additionally, it will update any packages that you have the source for that depend on Liquid Fixpoint.
+
+To update Liquid Fixpoint and Liquid Haskell, first clone Liquid Haskell and Liquid Fixpoint to a common location:
+
+```
+git clone https://github.com/ucsd-progsys/liquidhaskell.git
+git clone https://github.com/ucsd-progsys/liquid-fixpoint.git
+```
+
+To increment the `D` component of Liquid Fixpoint:
+
+```
+./path/to/bumper -3 liquid-fixpoint
+```
+
+This will update the `D` component of Liquid Fixpoint. If necessary, this will update the `Build-Depends` of Liquid Haskell. If the `Build-Depends` was updated, Liquid Haskell's `D` component will be incremented.
+
+To increment the `C` component of Liquid Fixpoint, and strip the `D` component:
+
+```
+./path/to/bumper --minor liquid-fixpoint
+```
+
+As before, this will update Liquid Fixpoint and, if necessary, Liquid Haskell.
+
+To increment the `B` component of Liquid Fixpoint, and strip the `D` and `C` components:
+
+```
+./path/to/bumper --major liquid-fixpoint
+```
+
+As before, this will update Liquid Fixpoint and, if necessary, Liquid Haskell
+
+SMTLIB2 Interface
+-----------------
+
+There is a new SMTLIB2 interface directly from Haskell:
+
++ Language.Fixpoint.SmtLib2
+
+See `tests/smt2/{Smt.hs, foo.smt2}` for an example of how to use it.
+
+Options
+-------
+
+`--higherorder` allows higher order binders into the environment
+
+`--extsolver` runs the **deprecated** external solver.
+
+`--parts` Partitions an `FInfo` into a `[FInfo]` and emits a bunch of files. So:
+
+    $ fixpoint -n -p path/to/foo.fq
+
+will now emit files:
+
+    path/to/.liquid/foo.1.fq
+    path/to/.liquid/foo.2.fq
+    . . .
+    path/to/.liquid/foo.k.fq
+
+and also a dot file with the constraint dependency graph:
+
+    path/to/.liquid/foo.fq.dot
+
+
+## FInfo Invariants
+
+### Binders
+
+This is the field
+
+```
+     , bs       :: !BindEnv         -- ^ Bind  |-> (Symbol, SortedReft)
+```
+
+or in the .fq files as
+
+```
+bind 1 x : ...
+bind 2 y : ...
+```
+
+* Each `BindId` must be a distinct `Int`,
+* Each `BindId` that appears in a constraint
+  environment i.e. inside _any_ `IBindEnv`
+  must appear inside the `bs`
+
+### Environments
+
+* Each constraint's environment is a set of `BindId`
+  which must be defined in the `bindInfo`. Furthermore
+
+* Each constraint should not have _duplicate_ names in its
+  environment, that is if you have two binders
+
+```
+  bind 1 x : ...
+  bind 12 x : ...
+```
+
+  Then a single `IBindEnv` should only mention _at most_
+  one of `1` or `12`.
+
+* There is also a "tree-shape" property that its a bit hard
+  to describe ... TODO     
+
+### LHS
+
+Each `slhs` of a constraint is a `SortedReft`.
+
+- Each `SortredReft` is basically a `Reft` -- a logical predicate.
+  The important bit is that a `KVar` i.e. terms of the formalized
+
+```
+     $k1[x1:=y1][x2:=y2]...[xn:=yn]
+```
+
+  That is represented in the `Expr` type as
+
+```
+  | PKVar  !KVar !Subst
+```
+
+  must appear _only_ at the **top-level** that is not under _any_
+  other operators, i.e. not as a sub-`Expr` of other expressions.
+
+
+- This is basically a predicate that needs to be "well sorted"
+  with respect to the `BindId`, intuitively
+
+```
+    x:int, y:int |- x + y : int
+```
+
+  is well sorted. but
+
+```
+    x:int  |- x + y : int
+```
+
+  is not, and
+
+```
+    x:int, y: list |- x + y : int
+```
+
+  is not. The exact definition is formalized in `Language.Fixpoint.SortCheck`
+
+
+### RHS
+
+Similarly each `rhs` of a `SubC` must either be a single `$k[...]` or an plain `$k`-free `Expr`.
+
+### Global vs. Distinct Literals
+
+```
+     , gLits    :: !(SEnv Sort)               -- ^ Global Constant symbols
+     , dLits    :: !(SEnv Sort)       
+```
+
+The _global_ literals `gLits` are symbols that
+are in scope _everywhere_ i.e. need not be separately
+defined in individual environments. These include things like
+
+- uninterpreted _measure_ functions `len`, `height`,
+- uninterpreted _data constructor_ literals `True`, `False`
+
+Suppose you have an enumerated type like:
+
+```
+data Day = Sun | Mon | Tue | Wed | ... | Sat
+```
+
+You can model the above values in fixpoint as:
+
+```
+constant lit#Sun : Day
+constant lit#Mon : Day
+constant lit#Tue : Day
+constant lit#Wed : Day
+```
+
+The _distinct_ literals are a subset of the above where we
+want to tell the SMT solver that the values are *distinct*
+i.e. **not equal** to each other, for example, you can
+**additionally** specify this as:
+
+```
+distinct lit#Sun : Day
+distinct lit#Mon : Day
+distinct lit#Tue : Day
+distinct lit#Wed : Day
+```
+
+The above two are represented programmatically by generating   
+suitable `Symbol` values (for the literals  see `litSymbol`)
+and `Sort` values as `FTC FTycon` and then making an `SEnv`
+from the `[(Symbol, Sort)]`.
+
+### Sorts
+
+> What's the difference between an FTC and an FObj?
+
+In early versions of fixpoint, there was support for 
+three sorts for expressions (`Expr`) that were sent 
+to the SMT solver:
+
+1. `int`
+2. `bool`
+3. "other"
+
+The `FObj` sort was introduced to represent essentially _all_ 
+non-int and non-bool values (e.g. tuples, lists, trees, pointers...)
+
+However, we later realized that it is valuable to keep _more_
+precise information for `Expr`s and so we introduced the `FTC`
+(fixpoint type constructor), which lets us represent the above
+respectively as:
+
+- `FTC "String" []`                   -- in Haskell `String`
+- `FTC "Tuple"  [FInt, Bool]`         -- in Haskell `(Int, Bool)`
+- `FTC "List" [FTC "List" [FInt]]`    -- in Haskell `[[Int]]`
+
+> There is a comment that says FObj's are uninterpretted types;
+> so probably a type the SMT solver doesn't know about?
+> Does that then make FTC types that the SMT solver does
+> know about (bools, ints, lists, sets, etc.)?
+
+The SMT solver knows about `bool`, `int` and `set` (also `bitvector` 
+and `map`) but _all_ other types are _currently_ represented as plain 
+`Int` inside the SMT solver. However, we _will be_ changing this 
+to make use of SMT support for ADTs ...
+
+To sum up: the `FObj` is there for historical reasons; it has been 
+subsumed by `FTC` which is what I recomend you use. However `FObj` 
+is there if you want a simple "unitype" / "any" type for terms 
+that are not "interpreted".
+
diff --git a/liquid-fixpoint/Setup.hs b/liquid-fixpoint/Setup.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/liquid-fixpoint/TODO.md b/liquid-fixpoint/TODO.md
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/TODO.md
@@ -0,0 +1,37 @@
+# TODO
+
+## Proper Encoding of DataTypes
+
+```
+(declare-datatypes (T) ((LL lnil (lcons (lhd T) (ltl LL)))))
+(declare-fun l1 () (LL Int))
+(declare-fun l2 () (LL Int))
+(declare-fun l3 () (LL Int))
+(declare-fun x  () Int)
+(declare-fun zzz () Int)
+
+(assert (not (= l1 (as lnil (LL Int)))))
+(assert (not (= l2 (as lnil (LL Int)))))
+
+(assert (= (lhd l1) (lhd l2)))
+(assert (not (= l1 l2)))
+(assert (= l3 (lcons x l2)))
+(assert (> x 100))
+(check-sat)
+
+(get-model)
+
+
+(declare-fun xs () (LL Int))
+(declare-fun ys () (LL Int))
+(declare-fun y  () Int)
+
+(assert (= xs (as lnil (LL Int))))
+(assert (= ys (lcons y ys)))
+(assert (= xs ys))
+(check-sat)
+
+
+;; (assert (= (ltl l1) (ltl l2)))
+;; (check-sat)
+```
diff --git a/liquid-fixpoint/bin/Fixpoint.hs b/liquid-fixpoint/bin/Fixpoint.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/bin/Fixpoint.hs
@@ -0,0 +1,11 @@
+import Language.Fixpoint.Solver        (solveFQ)
+import Language.Fixpoint.Types.Config  (getOpts)
+import System.Exit
+import Language.Fixpoint.Misc    (writeLoud)
+
+main = do
+  cfg <- getOpts
+  writeLoud $  "Options: " ++ show cfg
+  e <- solveFQ cfg
+  exitWith e
+
diff --git a/liquid-fixpoint/default.nix b/liquid-fixpoint/default.nix
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/default.nix
@@ -0,0 +1,32 @@
+{ fetchgitLocal }:
+{ mkDerivation, ansi-terminal, array, ascii-progress, async
+, attoparsec, base, bifunctors, binary, boxes, bytestring, cereal
+, cmdargs, containers, deepseq, directory, filemanip, filepath
+, ghc-prim, hashable, intern, located-base, mtl, parallel, parsec, pretty
+, process, stdenv, syb, tasty, tasty-hunit, tasty-rerun, text
+, text-format, transformers, unordered-containers, z3
+, dotgen, fgl, fgl-visualize
+}:
+mkDerivation {
+  pname = "liquid-fixpoint";
+  version = "9.9.9.9";
+  src = fetchgitLocal ./.;
+  isLibrary = true;
+  isExecutable = true;
+  libraryHaskellDepends = [
+    ansi-terminal array ascii-progress async attoparsec base bifunctors
+    binary boxes bytestring cereal cmdargs containers deepseq directory
+    filemanip filepath ghc-prim hashable intern located-base mtl parallel parsec
+    pretty process syb text text-format transformers
+    unordered-containers
+    dotgen fgl fgl-visualize
+  ];
+  executableHaskellDepends = [ base ];
+  testHaskellDepends = [
+    base directory filepath process tasty tasty-hunit tasty-rerun text
+  ];
+  testSystemDepends = [ z3 ];
+  homepage = "https://github.com/ucsd-progsys/liquid-fixpoint";
+  description = "Predicate Abstraction-based Horn-Clause/Implication Constraint Solver";
+  license = stdenv.lib.licenses.bsd3;
+}
diff --git a/liquid-fixpoint/liquid-fixpoint.cabal b/liquid-fixpoint/liquid-fixpoint.cabal
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/liquid-fixpoint.cabal
@@ -0,0 +1,226 @@
+name:                liquid-fixpoint
+version:             0.6.0.1
+Copyright:           2010-17 Ranjit Jhala, University of California, San Diego.
+synopsis:            Predicate Abstraction-based Horn-Clause/Implication Constraint Solver
+homepage:            https://github.com/ucsd-progsys/liquid-fixpoint
+license:             BSD3
+license-file:        LICENSE
+author:              Ranjit Jhala, Niki Vazou, Eric Seidel
+maintainer:          jhala@cs.ucsd.edu
+category:            Language
+build-type:          Simple
+cabal-version:       >=1.10
+Tested-With:         GHC == 7.10.3, GHC == 8.0.1
+
+
+
+description:     This package is a Haskell wrapper to the SMTLIB-based
+                 Horn-Clause/Logical Implication constraint solver used
+                 for Liquid Types.
+                 .
+                 The package includes:
+                 .
+                 1. Types for Expressions, Predicates, Constraints, Solutions
+                 .
+                 2. Code for solving constraints
+                 .
+                 Requirements
+                 .
+                 In addition to the .cabal dependencies you require
+                 .
+                 - A Z3 (<http://z3.codeplex.com>) or CVC4 (<http://cvc4.cs.nyu.edu>) binary.
+
+Extra-Source-Files: tests/neg/*.fq
+                  , tests/pos/*.fq
+                  , unix/Language/Fixpoint/Utils/*.hs
+                  , win/Language/Fixpoint/Utils/*.hs
+
+Source-Repository head
+  Type:        git
+  Location:    https://github.com/ucsd-progsys/liquid-fixpoint/
+
+Flag devel
+  Description: turn on stricter error reporting for development
+  Default:     False
+  Manual:      True
+
+Executable fixpoint
+  default-language: Haskell98
+  Main-is:       Fixpoint.hs
+  ghc-options:   -threaded -W -fno-warn-missing-methods
+  if flag(devel)
+    ghc-options: -Werror
+  hs-source-dirs: bin
+  Build-Depends: base >= 4.8 && < 5
+               , liquid-fixpoint
+
+Library
+  default-language: Haskell98
+  ghc-options:     -W -fno-warn-missing-methods
+  if flag(devel)
+    ghc-options:   -Werror
+  ghc-prof-options: -fprof-auto
+  hs-source-dirs:  src
+  Exposed-Modules: Language.Fixpoint.Types.Names,
+                   Language.Fixpoint.Types.Errors,
+                   Language.Fixpoint.Types.Config,
+                   Language.Fixpoint.Types.Visitor,
+                   Language.Fixpoint.Types.PrettyPrint,
+                   Language.Fixpoint.Types.Spans,
+                   Language.Fixpoint.Types.Sorts,
+                   Language.Fixpoint.Types.Refinements,
+                   Language.Fixpoint.Types.Substitutions,
+                   Language.Fixpoint.Types.Environments,
+                   Language.Fixpoint.Types.Constraints,
+                   Language.Fixpoint.Types.Triggers,
+                   Language.Fixpoint.Types.Solutions,
+                   Language.Fixpoint.Types.Utils,
+                   Language.Fixpoint.Types,
+                   Language.Fixpoint.Graph.Types,
+                   Language.Fixpoint.Graph.Reducible,
+                   Language.Fixpoint.Graph.Indexed,
+                   Language.Fixpoint.Graph.Partition,
+                   Language.Fixpoint.Graph.Deps,
+                   Language.Fixpoint.Graph,
+                   Language.Fixpoint.Defunctionalize,
+                   Language.Fixpoint.Smt.Types,
+                   Language.Fixpoint.Smt.Bitvector,
+                   Language.Fixpoint.Smt.Theories,
+                   Language.Fixpoint.Smt.Serialize,
+                   Language.Fixpoint.Smt.Interface,
+                   Language.Fixpoint.Minimize,
+                   Language.Fixpoint.Solver,
+                   Language.Fixpoint.Parse,
+                   Language.Fixpoint.SortCheck,
+                   Language.Fixpoint.Misc,
+                   Language.Fixpoint.Utils.Progress,
+                   Language.Fixpoint.Utils.Files,
+                   Language.Fixpoint.Solver.GradualSolution,
+                   Language.Fixpoint.Solver.Solution,
+                   Language.Fixpoint.Solver.Worklist,
+                   Language.Fixpoint.Solver.Monad,
+                   Language.Fixpoint.Solver.TrivialSort,
+                   Language.Fixpoint.Solver.UniqifyKVars,
+                   Language.Fixpoint.Solver.UniqifyBinds,
+                   Language.Fixpoint.Solver.Eliminate,
+                   Language.Fixpoint.Solver.Instantiate,
+                   Language.Fixpoint.Solver.Sanitize,
+                   Language.Fixpoint.Utils.Statistics,
+                   Language.Fixpoint.Solver.GradualSolve,
+                   Language.Fixpoint.Solver.Solve
+
+  Build-Depends: base >= 4.8 && < 5
+               , array
+               , async
+               , attoparsec
+               , syb
+               , cmdargs
+               , ansi-terminal
+               , bifunctors
+               , binary
+               , bytestring
+               , containers
+               , deepseq
+               , directory
+               , filemanip
+               , filepath
+               , ghc-prim
+               , intern
+               , mtl
+               , parsec
+               , pretty
+               , boxes
+               , parallel
+               , process
+               , syb
+               , text
+               , transformers
+               , hashable
+               , unordered-containers
+               , cereal
+               , text-format
+               , fgl
+               , fgl-visualize
+               , dotgen
+               , time
+
+  if impl(ghc >= 7.10.2)
+    Build-Depends: located-base
+  if !os(windows)
+    Build-Depends: ascii-progress >= 0.3
+    hs-source-dirs: unix
+  if os(windows)
+    hs-source-dirs: win
+
+test-suite test
+  default-language: Haskell98
+  type:             exitcode-stdio-1.0
+  hs-source-dirs:   tests
+  ghc-options:      -threaded
+  if flag(devel)
+    ghc-options:    -Werror
+  main-is:          test.hs
+  build-depends:    base,
+                    directory,
+                    filepath,
+                    process,
+                    tasty >= 0.10,
+                    tasty-hunit,
+                    tasty-rerun >= 1.1,
+                    text
+
+test-suite testparser
+  default-language: Haskell98
+  type:             exitcode-stdio-1.0
+  hs-source-dirs:   tests
+  ghc-options:      -threaded
+  if flag(devel)
+    ghc-options:    -Werror
+  main-is:          testParser.hs
+  build-depends:    base,
+                    directory,
+                    filepath,
+                    tasty >= 0.10,
+                    tasty-hunit,
+                    tasty-rerun >= 1.1,
+                    text
+  if flag(devel)
+    hs-source-dirs:   tests src
+    build-depends:
+                 array
+               , async
+               , attoparsec
+               , syb
+               , cmdargs
+               , ansi-terminal
+               , bifunctors
+               , binary
+               , bytestring
+               , containers
+               , deepseq
+               , directory
+               , filemanip
+               , filepath
+               , ghc-prim
+               , intern
+               , mtl
+               , parsec
+               , pretty
+               , boxes
+               , parallel
+               , process
+               , syb
+               , text
+               , transformers
+               , hashable
+               , unordered-containers
+               , cereal
+               , text-format
+               , fgl
+               , fgl-visualize
+               , dotgen
+               , time
+    if impl(ghc >= 7.10.2)
+      Build-Depends: located-base
+  else
+    build-depends: liquid-fixpoint
diff --git a/liquid-fixpoint/scripts/travis b/liquid-fixpoint/scripts/travis
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/scripts/travis
@@ -0,0 +1,137 @@
+#!/bin/bash
+
+set -eu
+set -o pipefail
+
+## Helper Functions
+
+function loud {
+  echo "$ $@"
+  $@
+}
+
+# Source: https://github.com/travis-ci/travis-build/blob/fc4ae8a2ffa1f2b3a2f62533bbc4f8a9be19a8ae/lib/travis/build/script/templates/header.sh#L104-L123
+RED="\033[31;1m"
+GREEN="\033[32;1m"
+RESET="\033[0m"
+function travis_retry {
+  local result=0
+  local count=1
+  while [ $count -le 3 ]; do
+    [ $result -ne 0 ] && {
+      echo -e "\n${RED}The command \"$@\" failed. Retrying, $count of 3.${RESET}\n" >&2
+    }
+    set +e
+    "$@"
+    result=$?
+    set -e
+    [ $result -eq 0 ] && break
+    count=$(($count + 1))
+    sleep 1
+  done
+
+  [ $count -eq 4 ] && {
+    echo "\n${RED}The command \"$@\" failed 3 times.${RESET}\n" >&2
+  }
+
+  return $result
+}
+
+function prevent_timeout {
+  local cmd="$@"
+
+  $cmd &
+  local cmd_pid=$!
+
+  poke_stdout &
+  local poke_pid=$!
+
+  wait $cmd_pid
+  exit_code=$?
+
+  kill $poke_pid
+  (wait $poke_pid 2>/dev/null) || true
+
+  return $exit_code
+}
+
+function poke_stdout {
+  # Print an invisible character every minute
+  while true; do
+    echo -ne "\xE2\x80\x8B"
+    sleep 60
+  done
+}
+
+function pastebin {
+  curl -s -F 'clbin=<-' https://clbin.com
+}
+
+## Testing Stages
+
+function clean_cache {
+  local smt="$1"
+
+  loud ghc-pkg unregister liquid-fixpoint --force || true
+  loud rm "$HOME/.cabal/bin/$smt" || true
+}
+
+function install_smt {
+  local smt="$1"
+
+  mkdir -p "$HOME/.cabal/bin"
+  loud curl "http://goto.ucsd.edu/~gridaphobe/$smt" -o "$HOME/.cabal/bin/$smt"
+  loud chmod a+x "$HOME/.cabal/bin/$smt"
+}
+
+function install_cabal_deps {
+  if ! _install_cabal_deps; then
+    echo " ==> Cabal install failed. Clearing dependency cache and retrying."
+    loud rm -rf "$HOME/.cabal"
+    loud rm -rf "$HOME/.ghc"
+    _install_cabal_deps
+  fi
+}
+
+function _install_cabal_deps {
+  loud travis_retry cabal update || return 1
+  loud travis_retry cabal install --only-dependencies --enable-tests || return 1
+}
+
+function do_build {
+  loud cabal configure -fbuild-external --enable-tests -v2
+  loud prevent_timeout cabal build -j2
+  loud cabal haddock
+}
+
+function do_test {
+  loud prevent_timeout ./dist/build/test/test
+}
+
+function dump_fail_logs {
+  find . -type f -wholename '*/.liquid/*' -name '*.log' -print0 | while IFS= read -r -d $'\0' file; do
+    echo "${file}:"
+    echo "    $(pastebin < "${file}")"
+  done
+}
+
+function test_source_pkg {
+  loud cabal sdist
+
+  local src_tgz="dist/$(cabal info . | awk '{print $2 ".tar.gz";exit}')"
+
+  if [ -f "$src_tgz" ]; then
+    loud prevent_timeout cabal install -j4 "$src_tgz"
+  else
+    echo "expected '$src_tgz' not found"
+    return 1
+  fi
+}
+
+## Run Test Stage
+
+stage="$1"
+shift
+
+$stage "$@"
+
diff --git a/liquid-fixpoint/shell.nix b/liquid-fixpoint/shell.nix
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/shell.nix
@@ -0,0 +1,17 @@
+{ nixpkgs ? import <nixpkgs> {}, compiler ? "default" }:
+
+let
+
+  inherit (nixpkgs) pkgs;
+
+  f = import ./default.nix { inherit (pkgs) fetchgitLocal; };
+
+  haskellPackages = if compiler == "default"
+                       then pkgs.haskellPackages
+                       else pkgs.haskell.packages.${compiler};
+
+  drv = haskellPackages.callPackage f { inherit (pkgs) z3; };
+
+in
+
+  if pkgs.lib.inNixShell then drv.env else drv
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Defunctionalize.hs b/liquid-fixpoint/src/Language/Fixpoint/Defunctionalize.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Defunctionalize.hs
@@ -0,0 +1,368 @@
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE TupleSections        #-}
+{-# LANGUAGE PatternGuards        #-}
+{-# LANGUAGE OverloadedStrings    #-}
+
+--------------------------------------------------------------------------------
+-- | `defunctionalize` traverses the query to:
+--      1. "normalize" lambda terms by renaming binders,
+--      2. generate alpha- and beta-equality axioms for
+--   The lambdas and redexes found in the query.
+--
+--   NOTE: `defunctionalize` should happen **BEFORE**
+--   `elaborate` as the latter converts all actual `EApp`
+--   into the (uninterpreted) `smt_apply`.
+--   We cannot elaborate prior to `defunc` as we need the
+--   `EApp` and `ELam` to determine the lambdas and redexes.
+--------------------------------------------------------------------------------
+
+module Language.Fixpoint.Defunctionalize (defunctionalize, Defunc(..), defuncAny, makeLamArg) where
+
+import qualified Data.HashMap.Strict as M
+import           Data.Hashable
+import           Data.Maybe             (isJust, maybeToList)
+import qualified Data.List           as L
+
+import           Control.Monad.State
+import           Language.Fixpoint.Misc            (sortNub, fM, whenM, secondM, mapSnd)
+import           Language.Fixpoint.Solver.Sanitize (symbolEnv)
+import           Language.Fixpoint.Types        hiding (allowHO)
+import           Language.Fixpoint.Types.Config
+import           Language.Fixpoint.SortCheck       (checkSortExpr)
+import           Language.Fixpoint.Types.Visitor   (mapMExpr, stripCasts)
+-- import Debug.Trace (trace)
+
+defunctionalize :: (Fixpoint a) => Config -> SInfo a -> SInfo a
+defunctionalize cfg si = evalState (defunc si) (makeInitDFState cfg si)
+
+defuncAny :: Defunc a => Config -> SEnv Sort -> a -> a 
+defuncAny cfg env e = evalState (defunc e) (makeDFState cfg env emptyIBindEnv)
+
+
+--------------------------------------------------------------------------------
+-- | Expressions defunctionalization -------------------------------------------
+--------------------------------------------------------------------------------
+txExpr :: Expr -> DF Expr
+txExpr e = do
+  hoFlag <- gets dfHO
+  if hoFlag then defuncExpr e else return e
+
+defuncExpr :: Expr -> DF Expr
+defuncExpr = mapMExpr reBind
+         >=> mapMExpr logLam
+         >=> mapMExpr logRedex
+         >=> mapMExpr (fM normalizeLams)
+
+reBind :: Expr -> DF Expr
+reBind (ELam (x, s) e) = (\y -> ELam (y, s) (subst1 e (x, EVar y))) <$> freshSym s
+reBind e               = return e
+
+maxLamArg :: Int
+maxLamArg = 7
+
+-- NIKI TODO: allow non integer lambda arguments
+-- sorts = [setSort intSort, bitVecSort intSort, mapSort intSort intSort, boolSort, realSort, intSort]
+makeLamArg :: Sort -> Int -> Symbol
+makeLamArg _ = intArgName
+
+--------------------------------------------------------------------------------
+
+makeAxioms :: DF [Expr]
+makeAxioms = do
+  alphEqs <- concatMap makeAlphaAxioms <$> getLams
+  betaEqs <- concatMap makeBetaAxioms  <$> getRedexes
+  env     <- gets dfEnv
+  return   $ filter (validAxiom env) (alphEqs ++ betaEqs)
+
+validAxiom :: SEnv Sort -> Expr -> Bool
+validAxiom env = isJust . checkSortExpr env
+
+--------------------------------------------------------------------------------
+-- | Alpha Equivalence ---------------------------------------------------------
+--------------------------------------------------------------------------------
+makeAlphaAxioms ::  Expr -> [Expr]
+makeAlphaAxioms = makeAlphaEq . normalizeLams
+
+makeAlphaEq :: Expr -> [Expr]
+makeAlphaEq e = go e ++ go' e
+  where
+    go ee
+      = makeEqForAll ee (normalize ee)
+    go' ee@(ELam (x, s) e)
+      = [makeEq ee ee'
+         | (i, ee') <- map (\j -> normalizeLamsFromTo j (ELam (x, s) e)) [1..maxLamArg-1]
+         , i <= maxLamArg ]
+    go' _
+      = []
+
+--------------------------------------------------------------------------------
+-- | Normalizations ------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- head normal form [TODO: example]
+
+normalize :: Expr -> Expr
+normalize = snd . go
+  where
+    go (ELam (y, sy) e) = let (i', e') = go e
+                              y'      = makeLamArg sy i'
+                          in (i'+1, ELam (y', sy) (e' `subst1` (y, EVar y')))
+    go (EApp e e2)
+      |  (ELam (x, _) bd) <- unECst e
+                        = let (i1, e1') = go bd
+                              (i2, e2') = go e2
+                          in (max i1 i2, e1' `subst1` (x, e2'))
+    go (EApp e1 e2)     = let (i1, e1') = go e1
+                              (i2, e2') = go e2
+                          in (max i1 i2, EApp e1' e2')
+    go (ECst e s)       = mapSnd (`ECst` s) (go e)
+    go (PAll bs e)      = mapSnd (PAll bs)  (go e)
+    go e                = (1, e)
+
+    unECst (ECst e _) = unECst e
+    unECst e          = e
+
+-- normalize lambda arguments [TODO: example]
+
+normalizeLams :: Expr -> Expr
+normalizeLams e = snd $ normalizeLamsFromTo 1 e
+
+normalizeLamsFromTo :: Int -> Expr -> (Int, Expr)
+normalizeLamsFromTo i   = go
+  where
+    go (ELam (y, sy) e) = let (i', e') = go e
+                              y'      = makeLamArg sy i'
+                          in (i' + 1, ELam (y', sy) (e' `subst1` (y, EVar y')))
+    go (EApp e1 e2)     = let (i1, e1') = go e1
+                              (i2, e2') = go e2
+                          in (max i1 i2, EApp e1' e2')
+    go (ECst e s)       = mapSnd (`ECst` s) (go e)
+    go (PAll bs e)      = mapSnd (PAll bs) (go e)
+    go e                = (i, e)
+
+--------------------------------------------------------------------------------
+-- | Beta Equivalence ----------------------------------------------------------
+--------------------------------------------------------------------------------
+makeBetaAxioms :: Expr -> [Expr]
+makeBetaAxioms e = makeEqForAll (normalizeLams e) (normalize e)
+  -- where
+  --  e             = trace ("BETA-NL e = " ++ showpp e0) e0
+
+makeEq :: Expr -> Expr -> Expr
+makeEq e1 e2
+  | e1 == e2  = PTrue
+  | otherwise = EEq e1 e2
+
+makeEqForAll :: Expr -> Expr -> [Expr]
+makeEqForAll e1 e2 = [ makeEq (closeLam su e1') (closeLam su e2') | su <- instantiate xs]
+  where
+    (xs1, e1')     = splitPAll [] e1
+    (xs2, e2')     = splitPAll [] e2
+    xs             = L.nub (xs1 ++ xs2)
+
+closeLam :: [(Symbol, (Symbol, Sort))] -> Expr -> Expr
+closeLam ((x,(y,s)):su) e = ELam (y,s) (subst1 (closeLam su e) (x, EVar y))
+closeLam []             e = e
+
+splitPAll :: [(Symbol, Sort)] -> Expr -> ([(Symbol, Sort)], Expr)
+splitPAll acc (PAll xs e) = splitPAll (acc ++ xs) e
+splitPAll acc e           = (acc, e)
+
+-- NOPROP instantiate :: [(Symbol, Sort)] -> [[(Symbol, (Symbol,Sort))]]
+-- NOPROP instantiate []     = [[]]
+-- NOPROP instantiate xs     = L.foldl' (\acc x -> combine (instOne x) acc) [] xs
+  -- NOPROP where
+    -- NOPROP instOne (x, s) = [(x, (makeLamArg s i, s)) | i <- [1..maxLamArg]]
+    -- NOPROP combine xs []  = [[x] | x <- xs]
+    -- NOPROP combine xs acc = concat [(x:) <$> acc | x <- xs]
+
+instantiate    :: [(Symbol, Sort)] -> [[(Symbol, (Symbol,Sort))]]
+instantiate     = choices . map inst1
+  where
+    inst1 (x,s) = [(x, (makeLamArg s i, s)) | i <- [1..maxLamArg]]
+
+choices :: [[a]] -> [[a]]
+choices []       = [[]]
+choices (xs:xss) = [a:as | a <- xs, as <- choices xss]
+
+--------------------------------------------------------------------------------
+-- | Containers defunctionalization --------------------------------------------
+--------------------------------------------------------------------------------
+
+class Defunc a where
+  defunc :: a -> DF a
+
+instance (Defunc (c a), TaggedC c a) => Defunc (GInfo c a) where
+  defunc fi = do
+    cm'    <- defunc $ cm    fi
+    ws'    <- defunc $ ws    fi
+    -- NOPROP setBinds $ mconcat ((senv <$> M.elems (cm fi)) ++ (wenv <$> M.elems (ws fi)))
+    gLits' <- defunc $ gLits fi
+    dLits' <- defunc $ dLits fi
+    bs'    <- defunc $ bs    fi
+    ass'   <- defunc $ asserts fi 
+    -- NOPROP quals' <- defunc $ quals fi
+    axioms <- makeAxioms
+    return $ fi { cm      = cm'
+                , ws      = ws'
+                , gLits   = gLits'
+                , dLits   = dLits'
+                , bs      = bs'
+                -- NOPROP , quals   = quals'
+                , asserts = (noTrigger <$> axioms) ++ ass' 
+                }
+
+instance (Defunc a) => Defunc (Triggered a) where
+  defunc (TR t e) = TR t <$> defunc e 
+
+instance Defunc (SimpC a) where
+  defunc sc = do crhs' <- defunc $ _crhs sc
+                 return $ sc {_crhs = crhs'}
+
+instance Defunc (WfC a)   where
+  defunc wf@(WfC {}) = do
+    let (x, t, k) = wrft wf
+    t' <- defunc t
+    return $ wf { wrft = (x, t', k) }
+  defunc wf@(GWfC {}) = do
+    let (x, t, k) = wrft wf
+    t' <- defunc t
+    e' <- defunc $ wexpr wf
+    return $ wf { wrft = (x, t', k), wexpr = e' }
+
+instance Defunc SortedReft where
+  defunc (RR s r) = RR s <$> defunc r
+
+instance Defunc (Symbol, SortedReft) where
+  defunc (x, sr) = (x,) <$> defunc sr
+
+instance Defunc (Symbol, Sort) where
+  defunc (x, t) = (x,) <$> defunc t
+
+instance Defunc Reft where
+  defunc (Reft (x, e)) = Reft . (x,) <$> defunc e
+
+instance Defunc Expr where
+  defunc = txExpr
+
+instance Defunc a => Defunc (SEnv a) where
+  defunc = mapMSEnv defunc
+
+instance Defunc BindEnv   where
+  defunc bs = do dfbs <- gets dfBEnv
+                 let f (i, xs) = if i `memberIBindEnv` dfbs
+                                       then  (i,) <$> defunc xs
+                                       else  (i,) <$> matchSort xs
+                 mapWithKeyMBindEnv f bs
+   where
+    -- The refinement cannot be elaborated thus defunc-ed because
+    -- the bind does not appear in any contraint,
+    -- thus unique binders does not perform properly
+    -- The sort should be defunc, to ensure same sort on double binders
+    matchSort (x, RR s r) = ((x,) . (`RR` r)) <$> defunc s
+
+-- Sort defunctionalization [should be done by elaboration]
+instance Defunc Sort where
+  defunc = return
+
+instance Defunc a => Defunc [a] where
+  defunc = mapM defunc
+
+instance (Defunc a, Eq k, Hashable k) => Defunc (M.HashMap k a) where
+  defunc m = M.fromList <$> mapM (secondM defunc) (M.toList m)
+
+type DF    = State DFST
+
+data DFST = DFST
+  { dfFresh   :: !Int
+  , dfEnv   :: !(SEnv Sort)
+  , dfBEnv  :: !IBindEnv
+  , dfLam   :: !Bool        -- ^ normalize lams
+  , dfExt   :: !Bool        -- ^ enable extensionality axioms
+  , dfAEq   :: !Bool        -- ^ enable alpha equivalence axioms
+  , dfBEq   :: !Bool        -- ^ enable beta equivalence axioms
+  , dfNorm  :: !Bool        -- ^ enable normal form axioms
+  , dfHO    :: !Bool        -- ^ allow higher order thus defunctionalize
+  , dfLNorm :: !Bool
+  , dfLams  :: ![Expr]      -- ^ lambda expressions appearing in the expressions
+  , dfRedex :: ![Expr]      -- ^ redexes appearing in the expressions
+  , dfBinds :: !(SEnv Sort) -- ^ sorts of new lambda-binders
+  }
+
+
+makeDFState :: Config -> SEnv Sort -> IBindEnv -> DFST
+makeDFState cfg senv ibind = DFST
+  { dfFresh = 0
+  , dfEnv   = senv 
+  , dfBEnv  = ibind
+  , dfLam   = True
+  , dfExt   = False 
+  , dfAEq   = alphaEquivalence cfg
+  , dfBEq   = betaEquivalence  cfg
+  , dfNorm  = normalForm       cfg
+  , dfHO    = allowHO cfg  || defunction cfg
+  , dfLNorm = True
+  -- INVARIANT: lambads and redexes are not defunctionalized
+  , dfLams  = []
+  , dfRedex = []
+  , dfBinds = mempty
+  }
+
+
+makeInitDFState :: Config -> SInfo a -> DFST
+makeInitDFState cfg si 
+  = makeDFState cfg 
+         (symbolEnv cfg si) 
+         (mconcat ((senv <$> M.elems (cm si)) ++ (wenv <$> M.elems (ws si))))
+
+--------------------------------------------------------------------------------
+-- | Low level monad manipulation ----------------------------------------------
+--------------------------------------------------------------------------------
+freshSym :: Sort -> DF Symbol
+freshSym t = do
+  n    <- gets dfFresh
+  let x = intSymbol "lambda_fun_" n
+  modify $ \s -> s {dfFresh = n + 1, dfBinds = insertSEnv x t (dfBinds s)}
+  return x
+
+logLam :: Expr -> DF Expr
+logLam e = whenM (gets dfAEq) (putLam e) >> return e
+
+logRedex :: Expr -> DF Expr
+logRedex e = whenM (gets dfBEq) (putRedex e) >> return e
+
+putLam :: Expr -> DF ()
+putLam e@(ELam {}) = modify $ \s -> s { dfLams = e : dfLams s}
+putLam _           = return ()
+
+putRedex :: Expr -> DF ()
+putRedex e@(EApp f _)
+  | ELam _ _ <- stripCasts f
+  = modify $ \s -> s { dfRedex = e : dfRedex s }
+putRedex _
+  = return ()
+
+
+-- | getLams and getRedexes return the (previously seen) lambdas and redexes,
+--   after "closing" them by quantifying out free vars corresponding to the
+--   fresh binders in `dfBinds`.
+getLams    :: DF [Expr]
+getLams    = getClosedField dfLams
+
+getRedexes :: DF [Expr]
+getRedexes = getClosedField dfRedex
+
+getClosedField :: (DFST -> [Expr]) -> DF [Expr]
+getClosedField fld = do
+  env <- gets dfBinds
+  es  <- gets fld
+  return (closeLams env <$> es)
+
+closeLams :: SEnv Sort -> Expr -> Expr
+closeLams env e = PAll (freeBinds env e) e
+
+freeBinds :: SEnv Sort -> Expr -> [(Symbol, Sort)]
+freeBinds env e = [ (y, t) | y <- sortNub (syms e)
+                           , t <- maybeToList (lookupSEnv y env) ]
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Graph.hs b/liquid-fixpoint/src/Language/Fixpoint/Graph.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Graph.hs
@@ -0,0 +1,10 @@
+-- | This module re-exports the data types, operations and
+--   serialization functions for representing and computing
+--   with constraint dependencies.
+
+module Language.Fixpoint.Graph (module X ) where
+
+import Language.Fixpoint.Graph.Types     as X
+import Language.Fixpoint.Graph.Partition as X
+import Language.Fixpoint.Graph.Reducible as X
+import Language.Fixpoint.Graph.Deps      as X
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Graph/Deps.hs b/liquid-fixpoint/src/Language/Fixpoint/Graph/Deps.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Graph/Deps.hs
@@ -0,0 +1,549 @@
+{-# LANGUAGE TupleSections         #-}
+{-# LANGUAGE OverloadedStrings     #-}
+{-# LANGUAGE ConstraintKinds       #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE RecordWildCards       #-}
+
+module Language.Fixpoint.Graph.Deps (
+       -- * Remove Constraints that don't affect Targets
+         slice
+
+       -- * Predicate describing Targets
+       , isTarget
+
+      -- * Eliminatable KVars
+      , Elims (..)
+      , elimVars
+      , elimDeps
+
+      -- * Compute Raw Dependencies
+      , kvEdges
+
+      -- * Partition
+      , decompose
+
+      -- * Debug
+      , graphStatistics
+      ) where
+
+import           Prelude hiding (init)
+import           Data.Maybe                       (mapMaybe, fromMaybe)
+import           Data.Tree (flatten)
+import           Language.Fixpoint.Misc
+import           Language.Fixpoint.Utils.Files
+import           Language.Fixpoint.Types.Config
+import qualified Language.Fixpoint.Types.Visitor      as V
+import           Language.Fixpoint.Types.PrettyPrint
+import qualified Language.Fixpoint.Types              as F
+import           Language.Fixpoint.Graph.Types
+import           Language.Fixpoint.Graph.Reducible  (isReducible)
+import           Language.Fixpoint.Graph.Indexed
+
+import           Control.Monad             (when)
+import qualified Data.HashSet                         as S
+import qualified Data.List                            as L
+import qualified Data.HashMap.Strict                  as M
+import qualified Data.Graph                           as G
+import           Data.Function (on)
+import           Data.Hashable
+import           Text.PrettyPrint.HughesPJ
+import           Debug.Trace (trace)
+
+--------------------------------------------------------------------------------
+-- | Compute constraints that transitively affect target constraints,
+--   and delete everything else from F.SInfo a
+--------------------------------------------------------------------------------
+slice :: (F.TaggedC c a) => Config -> F.GInfo c a -> F.GInfo c a
+--------------------------------------------------------------------------------
+slice cfg fi 
+  | noslice cfg 
+  = fi 
+  | otherwise
+  = fi { F.cm = cm'
+       , F.ws = ws' }
+  where
+     cm' = M.filterWithKey inC (F.cm fi)
+     ws' = M.filterWithKey inW (F.ws fi)
+     ks  = sliceKVars fi sl
+     is  = S.fromList (slKVarCs sl ++ slConcCs sl)
+     sl  = mkSlice fi
+     inC i _ = S.member i is
+     inW k _ = S.member k ks
+
+sliceKVars :: (F.TaggedC c a) => F.GInfo c a -> Slice -> S.HashSet F.KVar
+sliceKVars fi sl = S.fromList $ concatMap (subcKVars be) cs
+  where
+    cs           = lookupCMap cm <$> slKVarCs sl ++ slConcCs sl
+    be           = F.bs fi
+    cm           = F.cm fi
+
+subcKVars :: (F.TaggedC c a) => F.BindEnv -> c a -> [F.KVar]
+subcKVars be c = V.envKVars be c ++ V.rhsKVars c
+
+--------------------------------------------------------------------------------
+mkSlice :: (F.TaggedC c a) => F.GInfo c a -> Slice
+--------------------------------------------------------------------------------
+mkSlice fi        = mkSlice_ (F.cm fi) g' es v2i i2v
+  where
+    g'            = G.transposeG g  -- "inverse" of g (reverse the dep-edges)
+    (g, vf, cf)   = G.graphFromEdges es
+    es            = gEdges $ cGraph fi
+    v2i           = fst3 . vf
+    i2v i         = fromMaybe (errU i) $ cf i
+    errU i        = errorstar $ "graphSlice: Unknown constraint " ++ show i
+
+mkSlice_ :: F.TaggedC c a
+         => M.HashMap F.SubcId (c a)
+         -> G.Graph
+         -> [DepEdge]
+         -> (G.Vertex -> F.SubcId)
+         -> (F.SubcId -> G.Vertex)
+         -> Slice
+mkSlice_ cm g' es v2i i2v = Slice { slKVarCs = kvarCs
+                                  , slConcCs = concCs
+                                  , slEdges  = sliceEdges kvarCs es
+                                  }
+  where
+    -- n                  = length kvarCs
+    concCs             = [ i | (i, c) <- M.toList cm, isTarget c ]
+    kvarCs             = v2i <$> reachVs
+    rootVs             = i2v <$> concCs
+    reachVs            = concatMap flatten $ G.dfs g' rootVs
+
+sliceEdges :: [F.SubcId] -> [DepEdge] -> [DepEdge]
+sliceEdges is es = [ (i, i, filter inSlice js) | (i, _, js) <- es, inSlice i ]
+  where
+    inSlice i    = M.member i im
+    im           = M.fromList $ (, ()) <$> is
+
+-- | DO NOT DELETE!
+-- sliceCSucc :: Slice -> CSucc
+-- sliceCSucc sl = \i -> M.lookupDefault [] i im
+  -- where
+    -- im        = M.fromList [(i, is) | (i,_,is) <- slEdges sl]
+
+--------------------------------------------------------------------------------
+isTarget :: (F.TaggedC c a) => c a -> Bool
+--------------------------------------------------------------------------------
+isTarget c   = V.isConcC c && isNonTriv c
+  where
+   isNonTriv = not .  F.isTautoPred . F.crhs
+
+
+--------------------------------------------------------------------------------
+-- | Constraint Graph ----------------------------------------------------------
+--------------------------------------------------------------------------------
+cGraph :: (F.TaggedC c a) => F.GInfo c a -> CGraph
+---------------------------------------------------------------------------
+cGraph fi = CGraph { gEdges = es
+                   , gRanks = outRs
+                   , gSucc  = next
+                   , gSccs  = length sccs }
+  where
+    es             = [(i, i, M.lookupDefault [] i next) | i <- M.keys $ F.cm fi]
+    next           = kvSucc fi
+    (g, vf, _)     = G.graphFromEdges es
+    (outRs, sccs)  = graphRanks g vf
+
+--------------------------------------------------------------------------------
+-- | Ranks from Graph ----------------------------------------------------------
+--------------------------------------------------------------------------------
+graphRanks :: G.Graph -> (G.Vertex -> DepEdge) -> (CMap Int, [[G.Vertex]])
+---------------------------------------------------------------------------
+graphRanks g vf = (M.fromList irs, sccs)
+  where
+    irs        = [(v2i v, r) | (r, vs) <- rvss, v <- vs ]
+    rvss       = zip [0..] sccs
+    sccs       = L.reverse $ map flatten $ G.scc g
+    v2i        = fst3 . vf
+
+--------------------------------------------------------------------------------
+-- | Dependencies --------------------------------------------------------------
+--------------------------------------------------------------------------------
+kvSucc :: (F.TaggedC c a) => F.GInfo c a -> CMap [F.SubcId]
+--------------------------------------------------------------------------------
+kvSucc fi = succs cm rdBy
+  where
+    rdBy  = kvReadBy fi
+    cm    = F.cm     fi
+
+succs :: (F.TaggedC c a) => CMap (c a) -> KVRead -> CMap [F.SubcId]
+succs cm rdBy = (sortNub . concatMap kvReads . kvWrites) <$> cm
+  where
+    kvReads k = M.lookupDefault [] k rdBy
+    kvWrites  = V.kvars . F.crhs
+
+--------------------------------------------------------------------------------
+kvWriteBy :: (F.TaggedC c a) => CMap (c a) -> F.SubcId -> [F.KVar]
+--------------------------------------------------------------------------------
+kvWriteBy cm = V.kvars . F.crhs . lookupCMap cm
+
+--------------------------------------------------------------------------------
+kvReadBy :: (F.TaggedC c a) => F.GInfo c a -> KVRead
+--------------------------------------------------------------------------------
+kvReadBy fi = group [ (k, i) | (i, ci) <- M.toList cm
+                             , k       <- V.envKVars bs ci]
+  where
+    cm      = F.cm fi
+    bs      = F.bs fi
+
+--------------------------------------------------------------------------------
+decompose :: (F.TaggedC c a) => F.GInfo c a -> KVComps
+--------------------------------------------------------------------------------
+decompose = componentsWith (kvgEdges . kvGraph)
+
+--------------------------------------------------------------------------------
+kvGraph :: (F.TaggedC c a) => F.GInfo c a -> KVGraph
+--------------------------------------------------------------------------------
+kvGraph = edgeGraph . kvEdges
+
+edgeGraph :: [CEdge] -> KVGraph
+edgeGraph es = KVGraph [(v, v, vs) | (v, vs) <- groupList es ]
+
+kvEdges :: (F.TaggedC c a) => F.GInfo c a -> [CEdge]
+kvEdges fi = selfes ++ concatMap (subcEdges bs) cs
+  where
+    bs     = F.bs fi
+    cs     = M.elems (F.cm fi)
+    ks     = fiKVars fi
+    selfes =  [(Cstr i , Cstr  i) | c <- cs, let i = F.subcId c]
+           ++ [(KVar k , DKVar k) | k <- ks]
+           ++ [(DKVar k, DKVar k) | k <- ks]
+
+fiKVars :: F.GInfo c a -> [F.KVar]
+fiKVars = M.keys . F.ws
+
+subcEdges :: (F.TaggedC c a) => F.BindEnv -> c a -> [CEdge]
+subcEdges bs c =  [(KVar k, Cstr i ) | k  <- V.envKVars bs c]
+               ++ [(Cstr i, KVar k') | k' <- V.rhsKVars c ]
+  where
+    i          = F.subcId c
+
+--------------------------------------------------------------------------------
+-- | Eliminated Dependencies
+--------------------------------------------------------------------------------
+elimDeps :: F.SInfo a -> [CEdge] -> S.HashSet F.KVar -> CDeps
+elimDeps si es nonKutVs = graphDeps si es'
+  where
+    es'                 = graphElim es nonKutVs
+    _msg                = "graphElim: " ++ show (length es')
+
+{- | `graphElim` "eliminates" a kvar k by replacing every "path"
+
+          ki -> ci -> k -> c
+
+      with an edge
+
+          ki ------------> c
+-}
+graphElim :: [CEdge] -> S.HashSet F.KVar -> [CEdge]
+graphElim es ks = ikvgEdges $ elimKs ks $ edgesIkvg es
+  where
+    elimKs      = flip (S.foldl' elimK)
+
+elimK  :: IKVGraph -> F.KVar -> IKVGraph
+elimK g k   = (g `addLinks` es') `delNodes` (kV : cis)
+  where
+   es'      = [(ki, c) | ki@(KVar _) <- kis, c@(Cstr _) <- cs]
+   cs       = getSuccs g kV
+   cis      = getPreds g kV
+   kis      = concatMap (getPreds g) cis
+   kV       = KVar k
+
+--------------------------------------------------------------------------------
+-- | Generic Dependencies ------------------------------------------------------
+--------------------------------------------------------------------------------
+data Elims a
+  = Deps { depCuts    :: !(S.HashSet a)
+         , depNonCuts :: !(S.HashSet a)
+         }
+    deriving (Show)
+
+instance PPrint (Elims a) where
+  pprintTidy _ d = "#Cuts ="    <+> ppSize (depCuts d) <+>
+                   "#NonCuts =" <+> ppSize (depNonCuts d)
+    where
+      ppSize     = pprint . S.size
+
+instance (Eq a, Hashable a) => Monoid (Elims a) where
+  mempty                            = Deps S.empty S.empty
+  mappend (Deps d1 n1) (Deps d2 n2) = Deps (S.union d1 d2) (S.union n1 n2)
+
+dCut, dNonCut :: (Hashable a) => a -> Elims a
+dNonCut v = Deps S.empty (S.singleton v)
+dCut    v = Deps (S.singleton v) S.empty
+
+--------------------------------------------------------------------------------
+-- | Compute Dependencies and Cuts ---------------------------------------------
+--------------------------------------------------------------------------------
+elimVars :: (F.TaggedC c a) => Config -> F.GInfo c a -> ([CEdge], Elims F.KVar)
+--------------------------------------------------------------------------------
+elimVars cfg si = (es, ds)
+  where
+    ds          = edgeDeps cfg si es
+    es          = kvEdges si
+
+removeKutEdges ::  S.HashSet F.KVar -> [CEdge] -> [CEdge]
+removeKutEdges ks = filter (not . isKut . snd)
+  where
+    cutVs         = S.map KVar ks
+    isKut         = (`S.member` cutVs)
+
+cutVars :: (F.TaggedC c a) => Config -> F.GInfo c a -> S.HashSet F.KVar
+cutVars cfg si
+  | autoKuts cfg = S.empty
+  | otherwise    = F.ksVars . F.kuts $ si
+
+forceKuts :: (Hashable a, Eq a) => S.HashSet a -> Elims a  -> Elims a
+forceKuts xs (Deps cs ns) = Deps (S.union cs xs) (S.difference ns xs)
+
+edgeDeps :: (F.TaggedC c a) => Config -> F.GInfo c a -> [CEdge] -> Elims F.KVar
+edgeDeps cfg si  = forceKuts ks
+                 . edgeDeps' cfg
+                 . removeKutEdges ks
+                 . filter isRealEdge
+  where
+    ks           = givenKs `S.union` nlKs
+    givenKs      = cutVars cfg    si
+    nlKs
+      | nonLinCuts cfg = nonLinearKVars si
+      | otherwise      = mempty
+
+edgeDeps' :: Config -> [CEdge] -> Elims F.KVar
+edgeDeps' cfg es = Deps (takeK cs) (takeK ns)
+  where
+    Deps cs ns   = gElims cfg kF cutF g
+    g            = kvgEdges    (edgeGraph es)
+    cutF         = edgeRankCut (edgeRank es)
+    takeK        = sMapMaybe tx
+    tx (KVar z)  = Just z
+    tx _         = Nothing
+    kF (KVar _)  = True
+    kF _         = False
+
+sMapMaybe :: (Hashable b, Eq b) => (a -> Maybe b) -> S.HashSet a -> S.HashSet b
+sMapMaybe f = S.fromList . mapMaybe f . S.toList
+
+--------------------------------------------------------------------------------
+type EdgeRank = M.HashMap F.KVar Integer
+--------------------------------------------------------------------------------
+edgeRank :: [CEdge] -> EdgeRank
+edgeRank es = minimum . (n :) <$> kiM
+  where
+    n       = 1 + maximum [ i | (Cstr i, _)     <- es ]
+    kiM     = group [ (k, i) | (KVar k, Cstr i) <- es ]
+
+edgeRankCut :: EdgeRank -> Cutter CVertex
+edgeRankCut km vs = case ks of
+                      []  -> Nothing
+                      k:_ -> Just (KVar k, [x | x@(u,_,_) <- vs, u /= KVar k])
+  where
+    ks            = orderBy [k | (KVar k, _ ,_) <- vs]
+    rank          = (km M.!)
+    orderBy       = L.sortBy (compare `on` rank)
+
+--------------------------------------------------------------------------------
+type Cutter a = [(a, a, [a])] -> Maybe (a, [(a, a, [a])])
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+type Cutable a = (Eq a, Ord a, Hashable a, Show a)
+--------------------------------------------------------------------------------
+gElims :: (Cutable a) => Config -> (a -> Bool) -> Cutter a -> [(a, a, [a])] -> Elims a
+--------------------------------------------------------------------------------
+gElims cfg kF cutF g = boundElims cfg kF g $ sccElims cutF g
+
+--------------------------------------------------------------------------------
+-- | `sccElims` returns an `Elims` that renders the dependency graph acyclic
+--    by picking _at least one_ kvar from each non-trivial SCC in the graph
+--------------------------------------------------------------------------------
+
+sccElims :: (Cutable a) => Cutter a -> [(a, a, [a])] -> Elims a
+sccElims f = sccsToDeps f . G.stronglyConnCompR
+
+sccsToDeps :: (Cutable a) => Cutter a -> [G.SCC (a, a, [a])] -> Elims a
+sccsToDeps f xs = mconcat $ sccDep f <$> xs
+
+sccDep :: (Cutable a) =>  Cutter a -> G.SCC (a, a, [a]) -> Elims a
+sccDep _ (G.AcyclicSCC (v,_,_)) = dNonCut v
+sccDep f (G.CyclicSCC vs)      = cycleDep f vs
+
+cycleDep :: (Cutable a) => Cutter a -> [(a, a, [a])] -> Elims a
+cycleDep _ [] = mempty
+cycleDep f vs = addCut f (f vs)
+
+addCut :: (Cutable a) => Cutter a -> Maybe (a, [(a, a, [a])]) -> Elims a
+addCut _ Nothing         = mempty
+addCut f (Just (v, vs')) = mconcat $ dCut v : (sccDep f <$> sccs)
+  where
+    sccs                 = G.stronglyConnCompR vs'
+
+
+--------------------------------------------------------------------------------
+-- | `boundElims` extends the input `Elims` by adding kuts that ensure that
+--   the *maximum distance* between an eliminated KVar and a cut KVar is
+--   *upper bounded* by a given threshold.
+--------------------------------------------------------------------------------
+boundElims :: (Cutable a) => Config -> (a -> Bool) -> [(a, a, [a])] -> Elims a -> Elims a
+--------------------------------------------------------------------------------
+boundElims cfg isK es ds = maybe ds (bElims isK es ds) (elimBound cfg)
+
+bElims :: (Cutable a) => (a -> Bool) -> [(a, a, [a])] -> Elims a -> Int -> Elims a
+bElims isK es ds dMax   = forceKuts kS' ds
+  where
+    (_ , kS')           = L.foldl' step (M.empty, depCuts ds) vs
+    vs                  = topoSort ds es
+    predM               = invertEdges es
+    addK v ks
+      | isK v           = S.insert v ks
+      | otherwise       = ks
+
+    zero                = (0, S.empty)
+
+    step (dM, kS) v
+      | v `S.member` kS = (M.insert v zero  dM,        kS)
+      | vDist < dMax    = (M.insert v dv    dM,        kS)
+      | otherwise       = (M.insert v zero  dM, addK v kS)
+      where
+        dv              = trace msg dv_
+        msg             = show v ++ " DIST =" ++ show vDist ++ " SIZE = " ++ show vSize
+        dv_@(vDist, s)  = distV predM v dM
+        vSize           = S.size s
+
+distV :: (Cutable a) => M.HashMap a [a] -> a -> M.HashMap a (Int, S.HashSet a) -> (Int, S.HashSet a)
+distV predM v dM = (d, s)
+  where
+    d            = 1 + maximumDef 0 (fst . du <$> us)
+    s            = S.insert v (S.unions (snd . du <$> us))
+    du u         = fromMaybe (oops u) $ M.lookup u dM
+    us           = M.lookupDefault [] v predM
+    oops u       = errorstar $ "dist: don't have dist for " ++ show u ++ " when checking " ++ show v
+
+topoSort :: (Cutable a) => Elims a -> [(a, a, [a])] -> [a]
+topoSort ds = G.flattenSCCs . reverse . G.stronglyConnComp . ripKuts ds
+
+ripKuts :: (Cutable a) => Elims a -> [(a, a, [a])] -> [(a, a, [a])]
+ripKuts ds es = [ (u, x, notKuts vs) | (u, x, vs) <- es ]
+  where
+    notKuts   = filter (not . (`S.member` ks))
+    ks        = depCuts ds
+
+invertEdges :: (Cutable a) => [(a, a, [a])] -> M.HashMap a [a]
+invertEdges es = group [ (v, u) | (u, _, vs) <- es, v <- vs ]
+
+maximumDef :: (Ord a) => a -> [a] -> a
+maximumDef d [] = d
+maximumDef _ xs = maximum xs
+
+
+---------------------------------------------------------------------------
+graphDeps :: F.SInfo a -> [CEdge] -> CDeps
+---------------------------------------------------------------------------
+graphDeps fi cs = CDs { cSucc   = gSucc cg
+                      , cPrev   = cPrevM
+                      , cNumScc = gSccs cg
+                      , cRank   = M.fromList [(i, rf i) | i <- is ]
+                      }
+  where
+    rf          = rankF (F.cm fi) outRs inRs
+    inRs        = inRanks fi es outRs
+    outRs       = gRanks cg
+    es          = gEdges cg
+    cg          = cGraphCE cs
+    is          = [i | (Cstr i, _) <- cs]
+    cPrevM      = sortNub <$> group [ (i, k) | (KVar k, Cstr i) <- cs ]
+
+--TODO merge these with cGraph and kvSucc
+cGraphCE :: [CEdge] -> CGraph
+cGraphCE cs = CGraph { gEdges = es
+                     , gRanks = outRs
+                     , gSucc  = next
+                     , gSccs  = length sccs }
+  where
+    es             = [(i, i, M.lookupDefault [] i next) | (Cstr i, _) <- cs]
+    next           = cSuccM cs
+    (g, vf, _)     = G.graphFromEdges es
+    (outRs, sccs)  = graphRanks g vf
+
+cSuccM      :: [CEdge] -> CMap [F.SubcId]
+cSuccM es    = (sortNub . concatMap kRdBy) <$> iWrites
+  where
+    kRdBy k  = M.lookupDefault [] k kReads
+    iWrites  = group [ (i, k) | (Cstr i, KVar k) <- es ]
+    kReads   = group [ (k, j) | (KVar k, Cstr j) <- es ]
+
+rankF :: CMap (F.SimpC a) -> CMap Int -> CMap Int -> F.SubcId -> Rank
+rankF cm outR inR = \i -> Rank (outScc i) (inScc i) (tag i)
+  where
+    outScc        = lookupCMap outR
+    inScc         = lookupCMap inR
+    tag           = F._ctag . lookupCMap cm
+
+---------------------------------------------------------------------------
+inRanks :: F.SInfo a -> [DepEdge] -> CMap Int -> CMap Int
+---------------------------------------------------------------------------
+inRanks fi es outR
+  | ks == mempty      = outR
+  | otherwise         = fst $ graphRanks g' vf'
+  where
+    ks                = F.kuts fi
+    cm                = F.cm fi
+    (g', vf', _)      = G.graphFromEdges es'
+    es'               = [(i, i, filter (not . isCut i) js) | (i,_,js) <- es ]
+    isCut i j         = S.member i cutCIds && isEqOutRank i j
+    isEqOutRank i j   = lookupCMap outR i == lookupCMap outR j
+    cutCIds           = S.fromList [i | i <- M.keys cm, isKutWrite i ]
+    isKutWrite        = any (`F.ksMember` ks) . kvWriteBy cm
+
+--------------------------------------------------------------------------------
+graphStatistics :: Config -> F.SInfo a -> IO ()
+--------------------------------------------------------------------------------
+graphStatistics cfg si = when (elimStats cfg) $ do
+  -- writeGraph f  (kvGraph si)
+  writeEdges f es'
+  appendFile f . ppc . ptable $ graphStats cfg si
+  where
+    f        = queryFile Dot cfg
+    es'      = removeKutEdges (depCuts ds) es
+    (es, ds) = elimVars cfg si
+    ppc d    = showpp $ vcat [" ", " ", "/*", pprint d, "*/"]
+
+data Stats = Stats {
+    stNumKVCuts   :: !Int   -- ^ number of kvars whose removal makes deps acyclic
+  , stNumKVNonLin :: !Int   -- ^ number of kvars that appear >= 2 in some LHS
+  , stNumKVTotal  :: !Int   -- ^ number of kvars
+  , stIsReducible :: !Bool  -- ^ is dep-graph reducible
+  , stSetKVNonLin :: !(S.HashSet F.KVar) -- ^ set of non-linear kvars
+  }
+
+instance PTable Stats where
+  ptable (Stats {..})  = DocTable [
+      ("# KVars [Cut]"    , pprint stNumKVCuts)
+    , ("# KVars [NonLin]" , pprint stNumKVNonLin)
+    , ("# KVars [All]"    , pprint stNumKVTotal)
+    , ("# Reducible"      , pprint stIsReducible)
+    , ("KVars NonLin"     , pprint stSetKVNonLin)
+    ]
+
+graphStats :: Config -> F.SInfo a -> Stats
+graphStats cfg si = Stats {
+    stNumKVCuts   = S.size $ F.tracepp "CUTS:" (depCuts d)
+  , stNumKVNonLin = S.size  nlks
+  , stNumKVTotal  = S.size (depCuts d) + S.size (depNonCuts d)
+  , stIsReducible = isReducible si
+  , stSetKVNonLin = nlks
+  }
+  where
+    nlks          = nonLinearKVars si
+    d             = snd $ elimVars cfg si
+
+--------------------------------------------------------------------------------
+nonLinearKVars :: (F.TaggedC c a) => F.GInfo c a -> S.HashSet F.KVar
+--------------------------------------------------------------------------------
+nonLinearKVars fi = S.unions $ nlKVarsC bs <$> cs
+  where
+    bs            = F.bs fi
+    cs            = M.elems (F.cm fi)
+
+nlKVarsC :: (F.TaggedC c a) => F.BindEnv -> c a -> S.HashSet F.KVar
+nlKVarsC bs c = S.fromList [ k |  (k, n) <- V.envKVarsN bs c, n >= 2]
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Graph/Indexed.hs b/liquid-fixpoint/src/Language/Fixpoint/Graph/Indexed.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Graph/Indexed.hs
@@ -0,0 +1,100 @@
+--------------------------------------------------------------------------------
+-- | This module implements Indexed KV Graphs,
+--   a representation of the KVGraph with a fast
+--   succ, pred lookup
+--------------------------------------------------------------------------------
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Language.Fixpoint.Graph.Indexed (
+  -- * (Abstract) Indexed Graphs
+    IKVGraph (..)
+
+  -- * Constructor
+  , edgesIkvg
+
+  -- * Destructor
+  , ikvgEdges
+
+  -- * Modify
+  , addLinks
+  , delNodes
+
+  -- * Lookup
+  , getSuccs
+  , getPreds
+  ) where
+
+import           Language.Fixpoint.Graph.Types
+import qualified Data.HashSet              as S
+import qualified Data.HashMap.Strict       as M
+import qualified Data.List as L
+import           Data.Hashable (Hashable)
+
+--------------------------------------------------------------------------------
+-- | `IKVGraph` is representation of the KVGraph with a fast succ, pred lookup
+--------------------------------------------------------------------------------
+
+data IKVGraph = IKVGraph
+  { igSucc :: !(M.HashMap CVertex (S.HashSet CVertex))  -- ^ out-edges of a `CVertex`
+  , igPred :: !(M.HashMap CVertex (S.HashSet CVertex))  -- ^ in-edges  of a `CVertex`
+  } deriving (Show)
+
+
+addLinks :: IKVGraph -> [CEdge] -> IKVGraph
+addLinks = L.foldl' addLink
+
+addLink :: IKVGraph -> CEdge -> IKVGraph
+addLink g (u, v) = addSucc (u, v) . addPred (u, v) $ g
+
+delNodes :: IKVGraph -> [CVertex] -> IKVGraph
+delNodes = L.foldl' delNode
+
+delNode :: IKVGraph -> CVertex -> IKVGraph
+delNode g v = delVtx v . txMany delSucc uvs . txMany delPred vws $ g
+  where
+    uvs     = [ (u, v) | u <- getPreds g v ]
+    vws     = [ (v, w) | w <- getSuccs g v ]
+
+edgesIkvg :: [CEdge] -> IKVGraph
+edgesIkvg = addLinks empty
+
+ikvgEdges :: IKVGraph -> [CEdge]
+ikvgEdges g = [ (u, v) | (u, vs) <- M.toList (igSucc g), v <- S.toList vs]
+
+getSuccs :: IKVGraph -> CVertex -> [CVertex]
+getSuccs g u = S.toList $ M.lookupDefault S.empty u (igSucc g)
+
+getPreds :: IKVGraph -> CVertex -> [CVertex]
+getPreds g v = S.toList $ M.lookupDefault S.empty v (igPred g)
+
+--------------------------------------------------------------------------------
+empty :: IKVGraph
+empty = IKVGraph M.empty M.empty
+
+txMany :: (a -> b -> b) -> [a] -> b -> b
+txMany op es g = L.foldl' (flip op) g es
+
+addSucc :: CEdge -> IKVGraph -> IKVGraph
+addSucc (u, v) g = g { igSucc = inserts u v (igSucc g) }
+
+addPred :: CEdge -> IKVGraph -> IKVGraph
+addPred (u, v) g = g { igPred = inserts v u (igPred g) }
+
+delSucc :: CEdge -> IKVGraph -> IKVGraph
+delSucc (u, v) g = g { igSucc = removes u v (igSucc g)}
+
+delPred :: (CVertex, CVertex) -> IKVGraph -> IKVGraph
+delPred (u, v) g = g { igPred = removes v u (igPred g)}
+
+delVtx :: CVertex -> IKVGraph -> IKVGraph
+delVtx v g = g { igSucc = M.delete v (igSucc g) }
+               { igPred = M.delete v (igPred g) }
+
+inserts :: (Eq k, Eq v, Hashable k, Hashable v)
+        => k -> v -> M.HashMap k (S.HashSet v) -> M.HashMap k (S.HashSet v)
+inserts k v m = M.insert k (S.insert v $ M.lookupDefault S.empty k m) m
+
+removes :: (Eq k, Eq v, Hashable k, Hashable v)
+        => k -> v -> M.HashMap k (S.HashSet v) -> M.HashMap k (S.HashSet v)
+removes k v m = M.insert k (S.delete v (M.lookupDefault S.empty k m)) m
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Graph/Partition.hs b/liquid-fixpoint/src/Language/Fixpoint/Graph/Partition.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Graph/Partition.hs
@@ -0,0 +1,213 @@
+{-# LANGUAGE ConstraintKinds   #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | This module implements functions to build constraint / kvar
+--   dependency graphs, partition them and print statistics about
+--   their structure.
+
+module Language.Fixpoint.Graph.Partition (
+
+  -- * Split constraints
+    CPart (..)
+  , partition, partition', partitionN
+
+  -- * Information about cores
+  , MCInfo (..)
+  , mcInfo
+
+  -- * Debug
+  , dumpPartitions
+
+  ) where
+
+import           GHC.Conc                  (getNumProcessors)
+import           Control.Monad             (forM_)
+-- import           GHC.Generics              (Generic)
+import           Language.Fixpoint.Misc         -- hiding (group)
+import           Language.Fixpoint.Utils.Files
+import           Language.Fixpoint.Types.Config
+-- import           Language.Fixpoint.Types.PrettyPrint
+-- import qualified Language.Fixpoint.Types.Visitor      as V
+import qualified Language.Fixpoint.Types              as F
+import           Language.Fixpoint.Graph.Types
+import           Language.Fixpoint.Graph.Deps
+
+import qualified Data.HashMap.Strict                  as M
+-- import qualified Data.Graph                           as G
+-- import qualified Data.Tree                            as T
+-- import           Data.Function (on)
+import           Data.Maybe                     (fromMaybe)
+import           Data.Hashable
+import           Text.PrettyPrint.HughesPJ
+import           Data.List (sortBy)
+-- import qualified Data.HashSet              as S
+
+-- import qualified Language.Fixpoint.Solver.Solution    as So
+-- import Data.Graph.Inductive
+
+
+
+--------------------------------------------------------------------------------
+-- | Constraint Partition Container --------------------------------------------
+--------------------------------------------------------------------------------
+
+data CPart a = CPart { pws :: !(M.HashMap F.KVar (F.WfC a))
+                     , pcm :: !(M.HashMap Integer (F.SubC a))
+                     }
+
+instance Monoid (CPart a) where
+   mempty = CPart mempty mempty
+   mappend l r = CPart { pws = pws l `mappend` pws r
+                       , pcm = pcm l `mappend` pcm r
+                       }
+
+--------------------------------------------------------------------------------
+-- | Multicore info ------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+data MCInfo = MCInfo { mcCores       :: !Int
+                     , mcMinPartSize :: !Int
+                     , mcMaxPartSize :: !Int
+                     } deriving (Show)
+
+mcInfo :: Config -> IO MCInfo
+mcInfo c = do
+   np <- getNumProcessors
+   let nc = fromMaybe np (cores c)
+   return MCInfo { mcCores = nc
+                 , mcMinPartSize = minPartSize c
+                 , mcMaxPartSize = maxPartSize c
+                 }
+
+partition :: (F.Fixpoint a) => Config -> F.FInfo a -> IO (F.Result (Integer, a))
+partition cfg fi
+  = do dumpPartitions cfg fis
+       -- writeGraph      f   g
+       return mempty
+    where
+      --f   = queryFile Dot cfg
+      fis = partition' Nothing fi
+
+------------------------------------------------------------------------------
+-- | Partition an FInfo into multiple disjoint FInfos. Info is Nothing to
+--   produce the maximum possible number of partitions. Or a MultiCore Info
+--   to control the partitioning
+------------------------------------------------------------------------------
+partition' :: Maybe MCInfo -> F.FInfo a -> [F.FInfo a]
+------------------------------------------------------------------------------
+partition' mn fi  = case mn of
+   Nothing -> fis mkPartition id
+   Just mi -> partitionN mi fi $ fis mkPartition' finfoToCpart
+  where
+    css            = decompose fi
+    fis partF ctor = applyNonNull [ctor fi] (pbc partF) css
+    pbc partF      = partitionByConstraints partF fi
+
+-- | Partition an FInfo into a specific number of partitions of roughly equal
+-- amounts of work
+partitionN :: MCInfo    -- ^ describes thresholds and partiton amounts
+           -> F.FInfo a   -- ^ The originial FInfo
+           -> [CPart a] -- ^ A list of the smallest possible CParts
+           -> [F.FInfo a] -- ^ At most N partitions of at least thresh work
+partitionN mi fi cp
+   | cpartSize (finfoToCpart fi) <= minThresh = [fi]
+   | otherwise = map (cpartToFinfo fi) $ toNParts sortedParts
+   where
+      toNParts p
+         | isDone p = p
+         | otherwise = toNParts $ insertSorted firstTwo rest
+            where (firstTwo, rest) = unionFirstTwo p
+      isDone [] = True
+      isDone [_] = True
+      isDone fi'@(a:b:_) = length fi' <= prts
+                            && (cpartSize a >= minThresh
+                                || cpartSize a + cpartSize b >= maxThresh)
+      sortedParts = sortBy sortPredicate cp
+      unionFirstTwo (a:b:xs) = (a `mappend` b, xs)
+      unionFirstTwo _        = errorstar "Partition.partitionN.unionFirstTwo called on bad arguments"
+      sortPredicate lhs rhs
+         | cpartSize lhs < cpartSize rhs = GT
+         | cpartSize lhs > cpartSize rhs = LT
+         | otherwise = EQ
+      insertSorted a []     = [a]
+      insertSorted a (x:xs) = if sortPredicate a x == LT
+                              then x : insertSorted a xs
+                              else a : x : xs
+      prts      = mcCores mi
+      minThresh = mcMinPartSize mi
+      maxThresh = mcMaxPartSize mi
+
+
+-- | Return the "size" of a CPart. Used to determine if it's
+-- substantial enough to be worth parallelizing.
+cpartSize :: CPart a -> Int
+cpartSize c = (M.size . pcm) c + (length . pws) c
+
+-- | Convert a CPart to an FInfo
+cpartToFinfo :: F.FInfo a -> CPart a -> F.FInfo a
+cpartToFinfo fi p = fi { F.cm = pcm p
+                       , F.ws = pws p
+                       }
+
+-- | Convert an FInfo to a CPart
+finfoToCpart :: F.FInfo a -> CPart a
+finfoToCpart fi = CPart { pcm = F.cm fi
+                        , pws = F.ws fi
+                        }
+
+-------------------------------------------------------------------------------------
+dumpPartitions :: (F.Fixpoint a) => Config -> [F.FInfo a] -> IO ()
+-------------------------------------------------------------------------------------
+dumpPartitions cfg fis =
+  forM_ (zip [0..] fis) $ \(i, fi) ->
+    writeFile (queryFile (Part i) cfg) (render $ F.toFixpoint cfg fi)
+
+
+-- | Type alias for a function to construct a partition. mkPartition and
+--   mkPartition' are the two primary functions that conform to this interface
+type PartitionCtor a b = F.FInfo a
+                       -> M.HashMap Int [(Integer, F.SubC a)]
+                       -> M.HashMap Int [(F.KVar, F.WfC a)]
+                       -> Int
+                       -> b -- ^ typically a F.FInfo a or F.CPart a
+
+partitionByConstraints :: PartitionCtor a b -- ^ mkPartition or mkPartition'
+                          -> F.FInfo a
+                          -> KVComps
+                          -> ListNE b -- ^ [F.FInfo a] or [F.CPart a]
+partitionByConstraints f fi kvss = f fi icM iwM <$> js
+  where
+    js   = fst <$> jkvs                                -- groups
+    gc   = groupFun cM                                 -- (i, ci) |-> j
+    gk   = groupFun kM                                 -- k       |-> j
+
+    iwM  = groupMap (gk . fst) (M.toList (F.ws fi))    -- j |-> [w]
+    icM  = groupMap (gc . fst) (M.toList (F.cm fi))    -- j |-> [(i, ci)]
+
+    jkvs = zip [1..] kvss
+    kvI  = [ (x, j) | (j, kvs) <- jkvs, x <- kvs ]
+    kM   = M.fromList [ (k, i) | (KVar k, i) <- kvI ]
+    cM   = M.fromList [ (c, i) | (Cstr c, i) <- kvI ]
+
+mkPartition :: F.GInfo F.SubC a
+            -> M.HashMap Int [(Integer, c a)]
+            -> M.HashMap Int [(F.KVar, F.WfC a)]
+            -> Int
+            -> F.GInfo c a
+mkPartition fi icM iwM j
+  = fi { F.cm       = M.fromList $ M.lookupDefault [] j icM
+       , F.ws       = M.fromList $ M.lookupDefault [] j iwM
+       }
+
+mkPartition' :: F.FInfo a1
+             -> M.HashMap Int [(Integer, F.SubC a)]
+             -> M.HashMap Int [(F.KVar, F.WfC a)]
+             -> Int
+             -> CPart a
+mkPartition' _ icM iwM j
+  = CPart { pcm       = M.fromList $ M.lookupDefault [] j icM
+          , pws       = M.fromList $ M.lookupDefault [] j iwM
+          }
+
+groupFun :: (Show k, Eq k, Hashable k) => M.HashMap k Int -> k -> Int
+groupFun m k = safeLookup ("groupFun: " ++ show k) k m
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Graph/Reducible.hs b/liquid-fixpoint/src/Language/Fixpoint/Graph/Reducible.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Graph/Reducible.hs
@@ -0,0 +1,62 @@
+{-# LANGUAGE ConstraintKinds   #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | This module a test for whether the constraint dependencies form a
+--   reducible graph.
+
+module Language.Fixpoint.Graph.Reducible ( isReducible ) where
+
+import qualified Data.Tree                            as T
+import qualified Data.HashMap.Strict                  as M
+import           Data.Graph.Inductive
+
+import           Language.Fixpoint.Misc         -- hiding (group)
+import qualified Language.Fixpoint.Types.Visitor      as V
+import qualified Language.Fixpoint.Types              as F
+
+
+--------------------------------------------------------------------------------
+isReducible :: F.SInfo a -> Bool
+--------------------------------------------------------------------------------
+isReducible fi = all (isReducibleWithStart g) vs
+  where
+    g  = convertToGraph fi
+    vs = {- trace (showDot $ fglToDotGeneric g show (const "") id) -} nodes g
+
+isReducibleWithStart :: Gr a b -> Node -> Bool
+isReducibleWithStart g x = all (isBackEdge domList) rEdges
+  where
+    dfsTree              = head $ dff [x] g --head because only care about nodes reachable from 'start node'?
+    rEdges               = [ e | e@(a,b) <- edges g, isDescendant a b dfsTree]
+    domList              = dom g x
+
+
+
+convertToGraph :: F.SInfo a -> Gr Int ()
+convertToGraph fi = mkGraph vs es
+  where
+    subCs        = M.elems (F.cm fi)
+    es           = lUEdge <$> concatMap (subcEdges' kvI $ F.bs fi) subCs
+    ks           = M.keys (F.ws fi)
+    kiM          = M.fromList $ zip ks [0..]
+    kvI k        = safeLookup ("convertToGraph: " ++ show k) k kiM
+    vs           = lNode . kvI <$> M.keys (F.ws fi)
+    lNode i      = (i, i)
+    lUEdge (i,j) = (i, j, ())
+
+isDescendant :: Node -> Node -> T.Tree Node -> Bool
+isDescendant x y (T.Node z f) | z == y    = f `contains` x
+                              | z == x    = False
+                              | otherwise = any (isDescendant x y) f
+
+contains :: [T.Tree Node] -> Node -> Bool
+contains t x = x `elem` concatMap T.flatten t
+
+isBackEdge :: [(Node, [Node])] -> Edge -> Bool
+isBackEdge t (u,v) = v `elem` xs
+  where
+    (Just xs) = lookup u t
+
+subcEdges' :: (F.KVar -> Node) -> F.BindEnv -> F.SimpC a -> [(Node, Node)]
+subcEdges' kvI be c = [(kvI k1, kvI k2) | k1 <- V.envKVars be c
+                                        , k2 <- V.kvars $ F.crhs c]
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Graph/Types.hs b/liquid-fixpoint/src/Language/Fixpoint/Graph/Types.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Graph/Types.hs
@@ -0,0 +1,184 @@
+
+-- | This module contains the types for representing dependency
+--   graphs between kvars and constraints.
+
+{-# LANGUAGE ImplicitParams        #-}
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Language.Fixpoint.Graph.Types (
+
+  -- * Graphs
+    CVertex (..)
+  , CEdge
+  , isRealEdge
+  , KVGraph (..)
+
+  -- * Components
+  , Comps
+  , KVComps
+
+  -- * Printing
+  , writeGraph
+  , writeEdges
+
+  -- * Constraints
+  , F.SubcId
+  , KVRead
+  , DepEdge
+
+  -- * Slice of relevant constraints
+  , Slice (..)
+
+  -- * Constraint Dependency Graphs
+  , CGraph (..)
+
+  -- * Alias for Constraint Maps
+  , F.CMap
+  , lookupCMap
+
+  -- * Ranks
+  , Rank (..)
+
+  -- * Constraint Dependencies
+  , CDeps (..)
+
+  -- * Solver Info
+  , SolverInfo (..)
+  )
+  where
+
+import           GHC.Generics              (Generic)
+import           Data.Hashable
+import           Text.PrettyPrint.HughesPJ
+
+import           Language.Fixpoint.Misc         -- hiding (group)
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Refinements -- Constraints
+import qualified Language.Fixpoint.Types.Solutions as F
+-- import           Language.Fixpoint.Misc (safeLookup)
+import qualified Language.Fixpoint.Types   as F
+import qualified Data.HashMap.Strict       as M
+import qualified Data.HashSet              as S
+
+import GHC.Stack
+--------------------------------------------------------------------------------
+
+data CVertex = KVar  !KVar    -- ^ real kvar vertex
+             | DKVar !KVar    -- ^ dummy to ensure each kvar has a successor
+             | Cstr  !Integer -- ^ constraint-id which creates a dependency
+               deriving (Eq, Ord, Show, Generic)
+
+instance PPrint CVertex where
+  pprintTidy _ (KVar k)  = doubleQuotes $ pprint $ kv k
+  pprintTidy _ (Cstr i)  = text "id_" <> pprint i
+  pprintTidy _ (DKVar k) = pprint k   <> text "*"
+
+
+instance Hashable CVertex
+
+data KVGraph    = KVGraph { kvgEdges :: [(CVertex, CVertex, [CVertex])] }
+type CEdge      = (CVertex, CVertex)
+type Comps a    = [[a]]
+type KVComps    = Comps CVertex
+
+instance PPrint KVGraph where
+  pprintTidy _ = pprint . kvgEdges
+
+--------------------------------------------------------------------------------
+writeGraph :: FilePath -> KVGraph -> IO ()
+--------------------------------------------------------------------------------
+writeGraph f = writeEdges f . graphEdges
+  where
+    graphEdges :: KVGraph -> [CEdge]
+    graphEdges (KVGraph g) = [ (v, v') | (v,_,vs) <- g, v' <- vs]
+
+--------------------------------------------------------------------------------
+writeEdges :: FilePath -> [CEdge] -> IO ()
+--------------------------------------------------------------------------------
+writeEdges f = writeFile f . render . ppEdges
+
+ppEdges :: [CEdge] -> Doc
+ppEdges             = vcat . wrap ["digraph Deps {"] ["}"]
+                           . map ppE
+                           . (if True then filter isRealEdge else txEdges)  -- RJ: use this to collapse "constraint" vertices
+  where
+    ppE (v, v')     = pprint v <+> "->" <+> pprint v'
+
+isRealEdge :: CEdge -> Bool
+isRealEdge (DKVar _, _)     = False
+isRealEdge (_, DKVar _)     = False
+isRealEdge (Cstr _, Cstr _) = False
+isRealEdge _                = True
+
+txEdges    :: [CEdge] -> [CEdge]
+txEdges es = concatMap iEs is
+  where
+    is     = [i | (Cstr i, Cstr _) <- es]
+    kvInM  = group [ (i, k) | (KVar k, Cstr i) <- es]
+    kvOutM = group [ (i, k') | (Cstr i, KVar k') <- es]
+    ins i  = M.lookupDefault [] i kvInM
+    outs i = M.lookupDefault [] i kvOutM
+    iEs i  = case (ins i, outs i) of
+                 (ks, [] ) -> [(KVar k, Cstr i ) | k  <- ks ]
+                 ([], ks') -> [(Cstr i, KVar k') | k' <- ks']
+                 (ks, ks') -> [(KVar k, KVar k') | k  <- ks, k' <- ks']
+
+
+
+---------------------------------------------------------------------------
+-- | Dramatis Personae
+---------------------------------------------------------------------------
+type KVRead  = M.HashMap F.KVar [F.SubcId]
+type DepEdge = (F.SubcId, F.SubcId, [F.SubcId])
+
+data Slice = Slice { slKVarCs :: [F.SubcId]     -- ^ F.SubcIds that transitively "reach" below
+                   , slConcCs :: [F.SubcId]     -- ^ F.SubcIds with Concrete RHS
+                   , slEdges  :: [DepEdge] -- ^ Dependencies between slKVarCs
+                   } deriving (Eq, Show)
+
+data CGraph = CGraph { gEdges :: [DepEdge]
+                     , gRanks :: !(F.CMap Int)
+                     , gSucc  :: !(F.CMap [F.SubcId])
+                     , gSccs  :: !Int
+                     }
+
+---------------------------------------------------------------------------
+-- | CMap API -------------------------------------------------------------
+---------------------------------------------------------------------------
+lookupCMap :: (?callStack :: CallStack) => F.CMap a -> F.SubcId -> a
+lookupCMap rm i = safeLookup err i rm
+  where
+    err      = "lookupCMap: cannot find info for " ++ show i
+
+--------------------------------------------------------------------------------
+-- | Constraint Dependencies ---------------------------------------------------
+--------------------------------------------------------------------------------
+
+data CDeps = CDs { cSucc   :: !(F.CMap [F.SubcId]) -- ^ Constraints *written by* a SubcId
+                 , cPrev   :: !(F.CMap [F.KVar])   -- ^ (Cut) KVars *read by*    a SubcId
+                 , cRank   :: !(F.CMap Rank)       -- ^ SCC rank of a SubcId
+                 , cNumScc :: !Int                 -- ^ Total number of Sccs
+                 }
+
+
+-- | Ranks ---------------------------------------------------------------------
+
+data Rank = Rank { rScc  :: !Int    -- ^ SCC number with ALL dependencies
+                 , rIcc  :: !Int    -- ^ SCC number without CUT dependencies
+                 , rTag  :: !F.Tag  -- ^ The constraint's Tag
+                 } deriving (Eq, Show)
+
+instance PPrint Rank where
+  pprintTidy _ = text . show
+
+--------------------------------------------------------------------------------
+-- | `SolverInfo` contains all the stuff needed to produce a result, and is the
+--   the essential ingredient of the state needed by solve_
+--------------------------------------------------------------------------------
+data SolverInfo a b = SI
+  { siSol     :: !(F.Sol b F.QBind)             -- ^ the initial solution
+  , siQuery   :: !(F.SInfo a)                   -- ^ the whole input query
+  , siDeps    :: !CDeps                         -- ^ dependencies between constraints/ranks etc.
+  , siVars    :: !(S.HashSet F.KVar)            -- ^ set of KVars to actually solve for
+  }
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Minimize.hs b/liquid-fixpoint/src/Language/Fixpoint/Minimize.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Minimize.hs
@@ -0,0 +1,132 @@
+-- | This module implements a "delta-debugging" based query minimizer.
+--   Exported clients of that minimizer include one that attempts to
+--   shrink UNSAT queries down to a minimal subset of constraints,
+--   one that shrinks SAT queries down to a minimal subset of qualifiers,
+--   and one that shrinks SAT queries down to a minimal subset of KVars
+--   (replacing all others by True).
+
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Language.Fixpoint.Minimize ( minQuery, minQuals, minKvars ) where
+
+import qualified Data.HashMap.Strict                as M
+import           Control.Monad                      (filterM)
+import           Language.Fixpoint.Types.Visitor    (mapKVars)
+import           Language.Fixpoint.Types.Config     (Config (..), queryFile)
+import           Language.Fixpoint.Types.Errors
+import           Language.Fixpoint.Misc             (safeHead)
+import           Language.Fixpoint.Utils.Files      hiding (Result)
+import           Language.Fixpoint.Graph
+import           Language.Fixpoint.Types
+import           Control.DeepSeq
+
+---------------------------------------------------------------------------
+-- polymorphic delta debugging implementation
+---------------------------------------------------------------------------
+deltaDebug :: Bool -> Oracle a c -> Config -> Solver a -> FInfo a -> [c] -> [c] -> IO [c]
+deltaDebug min testSet cfg solve finfo set r = do
+  let (s1, s2) = splitAt (length set `div` 2) set
+  if length set == 1
+    then deltaDebug1 min testSet cfg solve finfo set r
+    else do
+      test1 <- testSet cfg solve finfo (s1 ++ r)
+      if test1
+        then deltaDebug min testSet cfg solve finfo s1 r
+        else do
+          test2 <- testSet cfg solve finfo (s2 ++ r)
+          if test2
+            then deltaDebug min testSet cfg solve finfo s2 r
+            else do
+              d1 <- deltaDebug min testSet cfg solve finfo s1 (s2 ++ r)
+              d2 <- deltaDebug min testSet cfg solve finfo s2 (d1 ++ r)
+              return (d1 ++ d2)
+
+deltaDebug1 :: Bool -> (a -> b -> c -> d -> IO Bool)
+            -> a -> b -> c -> [e] -> d
+            -> IO [e]
+deltaDebug1 True  _       _   _     _     set _ = return set
+deltaDebug1 False testSet cfg solve finfo set r = do
+  test <- testSet cfg solve finfo r
+  if test then return [] else return set
+
+type Oracle a c = (Config -> Solver a -> FInfo a -> [c] -> IO Bool)
+
+commonDebug :: (NFData a, Fixpoint a) => (FInfo a -> [c])
+                                      -> (FInfo a -> [c] -> FInfo a)
+                                      -> (Result (Integer, a) -> Bool)
+                                      -> Bool
+                                      -> Config
+                                      -> Solver a
+                                      -> FInfo a
+                                      -> Ext
+                                      -> (FInfo a -> [c] -> String)
+                                      -> IO (Result (Integer, a))
+commonDebug init updateFi checkRes min cfg solve fi ext formatter = do
+  let cs0 = init fi
+  let oracle = mkOracle updateFi checkRes
+  cs <- deltaDebug min oracle cfg solve fi cs0 []
+  let minFi = updateFi fi cs
+  saveQuery (addExt ext cfg) minFi
+  putStrLn $ formatter fi cs
+  return mempty
+
+---------------------------------------------------------------------------
+minQuery :: (NFData a, Fixpoint a) => Config -> Solver a -> FInfo a
+         -> IO (Result (Integer, a))
+---------------------------------------------------------------------------
+minQuery cfg solve fi = do
+  let cfg'  = cfg { minimize = False }
+  let fis   = partition' Nothing fi
+  failFis  <- filterM (fmap (not . isSafe) . solve cfg') fis
+  let failFi = safeHead "--minimize can only be called on UNSAT fq" failFis
+  let format _ cs = "Minimized Constraints: " ++ show (fst <$> cs)
+  let update fi cs = fi { cm = M.fromList cs }
+  commonDebug (M.toList . cm) update (not . isSafe) True cfg' solve failFi Min format
+
+---------------------------------------------------------------------------
+minQuals :: (NFData a, Fixpoint a) => Config -> Solver a -> FInfo a
+         -> IO (Result (Integer, a))
+---------------------------------------------------------------------------
+minQuals cfg solve fi = do
+  let cfg'  = cfg { minimizeQs = False }
+  let format fi qs = "Required Qualifiers: " ++ show (length qs)
+                  ++ "; Total Qualifiers: "  ++ show (length $ quals fi)
+  let update fi qs = fi { quals = qs }
+  commonDebug quals update isSafe False cfg' solve fi MinQuals format
+
+---------------------------------------------------------------------------
+minKvars :: (NFData a, Fixpoint a) => Config -> Solver a -> FInfo a
+         -> IO (Result (Integer, a))
+---------------------------------------------------------------------------
+minKvars cfg solve fi = do
+  let cfg'  = cfg { minimizeKs = False }
+  let format fi ks = "Required KVars: " ++ show (length ks)
+                  ++ "; Total KVars: "  ++ show (length $ ws fi)
+  commonDebug (M.keys . ws) removeOtherKs isSafe False cfg' solve fi MinKVars format
+
+removeOtherKs :: FInfo a -> [KVar] -> FInfo a
+removeOtherKs fi0 ks = fi1 { ws = ws', cm = cm' }
+  where
+    fi1 = mapKVars go fi0
+    go k | k `elem` ks = Nothing
+         | otherwise   = Just PTrue
+    ws' = M.filterWithKey (\k _ -> k `elem` ks) $ ws fi1
+    cm' = M.filter (isNonTrivial . srhs) $ cm fi1
+
+---------------------------------------------------------------------------
+-- Helper functions
+---------------------------------------------------------------------------
+isSafe :: Result a -> Bool
+isSafe (Result Safe _ _) = True
+isSafe _                 = False
+
+addExt :: Ext -> Config -> Config
+addExt ext cfg = cfg { srcFile = queryFile ext cfg }
+
+mkOracle :: (NFData a, Fixpoint a) => (FInfo a -> [c] -> FInfo a)
+                                   -> (Result (Integer, a) -> Bool)
+                                   -> Oracle a c
+mkOracle updateFi checkRes cfg solve fi qs = do
+  let fi' = updateFi fi qs
+  res <- solve cfg fi'
+  return $ checkRes res
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Misc.hs b/liquid-fixpoint/src/Language/Fixpoint/Misc.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Misc.hs
@@ -0,0 +1,353 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE ScopedTypeVariables       #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE ConstraintKinds           #-}
+{-# LANGUAGE TypeOperators             #-}
+{-# LANGUAGE ImplicitParams            #-} -- ignore hlint
+
+module Language.Fixpoint.Misc where
+
+-- import           System.IO.Unsafe            (unsafePerformIO)
+import           Control.Exception                (bracket_)
+import           Data.Hashable
+-- import           Data.IORef
+import           Control.Arrow                    (second)
+import           Control.Monad                    (when, forM_)
+import qualified Data.HashMap.Strict              as M
+import qualified Data.List                        as L
+import           Data.Tuple                       (swap)
+import           Data.Maybe
+import           Data.Array                       hiding (indices)
+import           Data.Function                    (on)
+import qualified Data.Graph                       as G
+import qualified Data.Tree                        as T
+import           Data.Unique
+import           Debug.Trace                      (trace)
+import           System.Console.ANSI
+import           System.Console.CmdArgs.Verbosity (whenLoud)
+import           System.Process                   (system)
+import           System.Directory                 (createDirectoryIfMissing)
+import           System.FilePath                  (takeDirectory)
+import           Text.PrettyPrint.HughesPJ        hiding (first)
+import           System.IO                        (stdout, hFlush )
+import           System.Exit                      (ExitCode)
+import           Control.Concurrent.Async
+
+#ifdef MIN_VERSION_located_base
+import Prelude hiding (error, undefined)
+import GHC.Err.Located
+import GHC.Stack
+#endif
+
+type (|->) a b = M.HashMap a b
+
+firstMaybe :: (a -> Maybe b) -> [a] -> Maybe b
+firstMaybe f = listToMaybe . mapMaybe f
+
+
+asyncMapM :: (a -> IO b) -> [a] -> IO [b]
+asyncMapM f xs = mapM (async . f) xs >>= mapM wait
+
+traceShow     ::  Show a => String -> a -> a
+traceShow s x = trace ("\nTrace: [" ++ s ++ "] : " ++ show x)  x
+
+hashMapToAscList :: Ord a => M.HashMap a b -> [(a, b)]
+hashMapToAscList = L.sortBy (compare `on` fst) . M.toList
+
+---------------------------------------------------------------
+-- | Unique Int -----------------------------------------------
+---------------------------------------------------------------
+
+getUniqueInt :: IO Int
+getUniqueInt = do
+  n1 <- hashUnique <$> newUnique
+  n2 <- hashUnique <$> newUnique
+  return (n1 * n2)
+
+---------------------------------------------------------------
+-- | Edit Distance --------------------------------------------
+---------------------------------------------------------------
+
+editDistance :: Eq a => [a] -> [a] -> Int
+editDistance xs ys = table ! (m, n)
+    where
+    (m,n) = (length xs, length ys)
+    x     = array (1,m) (zip [1..] xs)
+    y     = array (1,n) (zip [1..] ys)
+
+    table :: Array (Int,Int) Int
+    table = array bnds [(ij, dist ij) | ij <- range bnds]
+    bnds  = ((0,0),(m,n))
+
+    dist (0,j) = j
+    dist (i,0) = i
+    dist (i,j) = minimum [table ! (i-1,j) + 1, table ! (i,j-1) + 1,
+        if x ! i == y ! j then table ! (i-1,j-1) else 1 + table ! (i-1,j-1)]
+
+-----------------------------------------------------------------------------------
+------------ Support for Colored Logging ------------------------------------------
+-----------------------------------------------------------------------------------
+
+data Moods = Ok | Loud | Sad | Happy | Angry
+
+moodColor :: Moods -> Color
+moodColor Ok    = Black
+moodColor Loud  = Blue
+moodColor Sad   = Magenta
+moodColor Happy = Green
+moodColor Angry = Red
+
+wrapStars :: String -> String
+wrapStars msg = "\n**** " ++ msg ++ " " ++ replicate (74 - length msg) '*'
+
+withColor :: Color -> IO () -> IO ()
+-- withColor _ act = act
+withColor c act
+   = do setSGR [ SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid c]
+        act
+        setSGR [ Reset]
+
+colorStrLn :: Moods -> String -> IO ()
+colorStrLn c       = withColor (moodColor c) . putStrLn
+
+colorPhaseLn :: Moods -> String -> String -> IO ()
+colorPhaseLn c msg = colorStrLn c . wrapStars .  (msg ++)
+
+startPhase :: Moods -> String -> IO ()
+startPhase c msg   = colorPhaseLn c "START: " msg >> colorStrLn Ok " "
+
+doneLine   :: Moods -> String -> IO ()
+doneLine   c msg   = colorPhaseLn c "DONE:  " msg >> colorStrLn Ok " "
+
+donePhase :: Moods -> String -> IO ()
+donePhase c str
+  = case lines str of
+      (l:ls) -> doneLine c l >> forM_ ls (colorPhaseLn c "") >> hFlush stdout
+      _      -> return ()
+
+putBlankLn :: IO ()
+putBlankLn = putStrLn "" >> hFlush stdout
+
+--------------------------------------------------------------------------------
+wrap :: [a] -> [a] -> [a] -> [a]
+wrap l r s = l ++ s ++ r
+
+repeats :: Int -> [a] -> [a]
+repeats n  = concat . replicate n
+
+#ifdef MIN_VERSION_located_base
+errorstar :: (?callStack :: CallStack) => String -> a
+#endif
+
+errorstar  = error . wrap (stars ++ "\n") (stars ++ "\n")
+  where
+    stars = repeats 3 $ wrapStars "ERROR"
+
+fst3 ::  (a, b, c) -> a
+fst3 (x,_,_) = x
+
+snd3 ::  (a, b, c) -> b
+snd3 (_,x,_) = x
+
+thd3 ::  (a, b, c) -> c
+thd3 (_,_,x) = x
+
+secondM :: Functor f => (b -> f c) -> (a, b) -> f (a, c)
+secondM act (x, y) = (x,) <$> act y
+
+#ifdef MIN_VERSION_located_base
+mlookup    :: (?callStack :: CallStack, Eq k, Show k, Hashable k) => M.HashMap k v -> k -> v
+safeLookup :: (?callStack :: CallStack, Eq k, Hashable k) => String -> k -> M.HashMap k v -> v
+mfromJust  :: (?callStack :: CallStack) => String -> Maybe a -> a
+#else
+mlookup    :: (Eq k, Show k, Hashable k) => M.HashMap k v -> k -> v
+safeLookup :: (Eq k, Hashable k) => String -> k -> M.HashMap k v -> v
+mfromJust  :: String -> Maybe a -> a
+#endif
+
+mlookup m k = fromMaybe err $ M.lookup k m
+  where
+    err     = errorstar $ "mlookup: unknown key " ++ show k
+
+safeLookup msg k m   = fromMaybe (errorstar msg) (M.lookup k m)
+mfromJust _ (Just x) = x
+mfromJust s Nothing  = errorstar $ "mfromJust: Nothing " ++ s
+
+inserts ::  (Eq k, Hashable k) => k -> v -> M.HashMap k [v] -> M.HashMap k [v]
+inserts k v m = M.insert k (v : M.lookupDefault [] k m) m
+
+removes ::  (Eq k, Hashable k, Eq v) => k -> v -> M.HashMap k [v] -> M.HashMap k [v]
+removes k v m = M.insert k (L.delete v (M.lookupDefault [] k m)) m
+
+count :: (Eq k, Hashable k) => [k] -> [(k, Int)]
+count = M.toList . fmap sum . group . fmap (, 1)
+
+group :: (Eq k, Hashable k) => [(k, v)] -> M.HashMap k [v]
+group = groupBase M.empty
+
+groupBase :: (Eq k, Hashable k) => M.HashMap k [v] -> [(k, v)] -> M.HashMap k [v]
+groupBase = L.foldl' (\m (k, v) -> inserts k v m)
+
+groupList :: (Eq k, Hashable k) => [(k, v)] -> [(k, [v])]
+groupList = M.toList . group
+
+groupMap   :: (Eq k, Hashable k) => (a -> k) -> [a] -> M.HashMap k [a]
+groupMap f = L.foldl' (\m x -> inserts (f x) x m) M.empty
+
+allMap :: (Eq k, Hashable k) => (v -> Bool) -> M.HashMap k v -> Bool
+allMap p = L.foldl' (\a v -> a && p v) True
+
+sortNub :: (Ord a) => [a] -> [a]
+sortNub = nubOrd . L.sort
+  where
+    nubOrd (x:t@(y:_))
+      | x == y    = nubOrd t
+      | otherwise = x : nubOrd t
+    nubOrd xs     = xs
+
+
+#ifdef MIN_VERSION_located_base
+safeZip :: (?callStack :: CallStack) => String -> [a] -> [b] -> [(a,b)]
+safeZipWith :: (?callStack :: CallStack) => String -> (a -> b -> c) -> [a] -> [b] -> [c]
+#endif
+
+safeZip msg xs ys
+  | nxs == nys
+  = zip xs ys
+  | otherwise
+  = errorstar $ "safeZip called on non-eq-sized lists (nxs = " ++ show nxs ++ ", nys = " ++ show nys ++ ") : " ++ msg
+  where
+    nxs = length xs
+    nys = length ys
+
+safeZipWith msg f xs ys
+  | nxs == nys
+  = zipWith f xs ys
+  | otherwise
+  = errorstar $ "safeZipWith called on non-eq-sized lists (nxs = " ++ show nxs ++ ", nys = " ++ show nys ++ ") : " ++ msg
+    where nxs = length xs
+          nys = length ys
+
+
+{-@ type ListNE a = {v:[a] | 0 < len v} @-}
+type ListNE a = [a]
+
+#ifdef MIN_VERSION_located_base
+safeHead   :: (?callStack :: CallStack) => String -> ListNE a -> a
+safeLast   :: (?callStack :: CallStack) => String -> ListNE a -> a
+safeInit   :: (?callStack :: CallStack) => String -> ListNE a -> [a]
+safeUncons :: (?callStack :: CallStack) => String -> ListNE a -> (a, [a])
+safeUnsnoc :: (?callStack :: CallStack) => String -> ListNE a -> ([a], a)
+#else
+safeHead   :: String -> ListNE a -> a
+safeLast   :: String -> ListNE a -> a
+safeInit   :: String -> ListNE a -> [a]
+safeUncons :: String -> ListNE a -> (a, [a])
+safeUnsnoc :: String -> ListNE a -> ([a], a)
+#endif
+
+
+safeHead _   (x:_) = x
+safeHead msg _     = errorstar $ "safeHead with empty list " ++ msg
+
+safeLast _ xs@(_:_) = last xs
+safeLast msg _      = errorstar $ "safeLast with empty list " ++ msg
+
+safeInit _ xs@(_:_) = init xs
+safeInit msg _      = errorstar $ "safeInit with empty list " ++ msg
+
+safeUncons _ (x:xs) = (x, xs)
+safeUncons msg _    = errorstar $ "safeUncons with empty list " ++ msg
+
+safeUnsnoc msg = swap . second reverse . safeUncons msg . reverse
+
+executeShellCommand :: String -> String -> IO ExitCode
+executeShellCommand phase cmd
+  = do writeLoud $ "EXEC: " ++ cmd
+       bracket_ (startPhase Loud phase) (donePhase Loud phase) $ system cmd
+
+applyNonNull :: b -> ([a] -> b) -> [a] -> b
+applyNonNull def _ [] = def
+applyNonNull _   f xs = f xs
+
+arrow, dcolon :: Doc
+arrow              = text "->"
+dcolon             = colon <> colon
+
+intersperse :: Doc -> [Doc] -> Doc
+intersperse d ds   = hsep $ punctuate d ds
+
+tshow :: (Show a) => a -> Doc
+tshow              = text . show
+
+-- | If loud, write a string to stdout
+writeLoud :: String -> IO ()
+writeLoud s = whenLoud $ putStrLn s >> hFlush stdout
+
+ensurePath :: FilePath -> IO ()
+ensurePath = createDirectoryIfMissing True . takeDirectory
+
+singleton :: a -> [a]
+singleton x = [x]
+
+fM :: (Monad m) => (a -> b) -> a -> m b
+fM f = return . f
+
+whenM :: (Monad m) => m Bool -> m () -> m ()
+whenM cond act = do
+  b <- cond
+  when b act
+
+
+mapEither :: (a -> Either b c) -> [a] -> ([b], [c])
+mapEither _ []     = ([], [])
+mapEither f (x:xs) = case f x of
+                       Left y  -> (y:ys, zs)
+                       Right z -> (ys, z:zs)
+                     where
+                       (ys, zs) = mapEither f xs
+
+componentsWith :: (Ord c) => (a -> [(b, c, [c])]) -> a -> [[b]]
+componentsWith eF x = map (fst3 . f) <$> vss
+  where
+    (g,f,_)         = G.graphFromEdges . eF $ x
+    vss             = T.flatten <$> G.components g
+
+
+type EqHash a = (Eq a, Ord a, Hashable a)
+
+-- >>> coalesce [[1], [2,1], [5], [5, 6], [5, 7], [9, 6], [10], [10,100]]
+-- [[1,2],[5,7,6,9],[10,100]]
+
+coalesce :: (EqHash v) => [ListNE v] -> [ListNE v]
+coalesce = componentsWith coalesceEdges
+
+coalesceEdges :: (EqHash v) => [ListNE v] -> [(v, v, [v])]
+coalesceEdges vss = [ (u, u, vs) | (u, vs) <- groupList (uvs ++ vus) ]
+  where
+    vus           = swap <$> uvs
+    uvs           = [ (u, v) | (u : vs) <- vss, v <- vs ]
+
+{-
+exitColorStrLn :: Moods -> String -> IO ()
+exitColorStrLn c s = do
+  writeIORef pbRef Nothing --(Just pr)
+  putStrLn "\n"
+  colorStrLn c s
+-}
+
+mapFst :: (a -> c) -> (a, b) -> (c, b)
+mapFst f (x, y) = (f x, y)
+
+mapSnd :: (b -> c) -> (a, b) -> (a, c)
+mapSnd f (x, y) = (x, f y)
+
+
+{-@ allCombinations :: xss:[[a]] -> [{v:[a]| len v == len xss}] @-}
+allCombinations :: [[a]] -> [[a]]
+allCombinations []          = [[]]
+allCombinations [[]]        = [[]]
+allCombinations ([]:_)     = []
+allCombinations ((x:xs):ys) = ((x:) <$> allCombinations ys) ++ allCombinations (xs:ys)
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Parse.hs b/liquid-fixpoint/src/Language/Fixpoint/Parse.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Parse.hs
@@ -0,0 +1,1005 @@
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE TypeSynonymInstances      #-}
+{-# LANGUAGE UndecidableInstances      #-}
+{-# LANGUAGE DeriveGeneric             #-}
+{-# LANGUAGE OverloadedStrings         #-}
+
+module Language.Fixpoint.Parse (
+
+  -- * Top Level Class for Parseable Values
+    Inputable (..)
+
+  -- * Top Level Class for Parseable Values
+  , Parser
+
+  -- * Lexer to add new tokens
+  , lexer
+
+  -- * Some Important keyword and parsers
+  , reserved, reservedOp
+  , parens  , brackets, angles, braces
+  , semi    , comma
+  , colon   , dcolon
+  , whiteSpace
+  , blanks
+  , pairP
+
+  -- * Parsing basic entities
+
+  --   fTyConP  -- Type constructors
+  , lowerIdP    -- Lower-case identifiers
+  , upperIdP    -- Upper-case identifiers
+  , infixIdP    -- String Haskell infix Id
+  , symbolP     -- Arbitrary Symbols
+  , constantP   -- (Integer) Constants
+  , integer     -- Integer
+  , bindP       -- Binder (lowerIdP <* colon)
+  , sortP       -- Sort
+  , mkQual      -- constructing qualifiers
+
+  -- * Parsing recursive entities
+  , exprP       -- Expressions
+  , predP       -- Refinement Predicates
+  , funAppP     -- Function Applications
+  , qualifierP  -- Qualifiers
+  , refaP       -- Refa
+  , refP        -- (Sorted) Refinements
+  , refDefP     -- (Sorted) Refinements with default binder
+  , refBindP    -- (Sorted) Refinements with configurable sub-parsers
+  , bvSortP     -- Bit-Vector Sort
+
+  -- * Some Combinators
+  , condIdP     --  condIdP  :: [Char] -> (Text -> Bool) -> Parser Text
+
+  -- * Add a Location to a parsed value
+  , locParserP
+  , locLowerIdP
+  , locUpperIdP
+
+  -- * Getting a Fresh Integer while parsing
+  , freshIntP
+
+  -- * Parsing Function
+  , doParse'
+  , parseFromFile
+  , remainderP
+
+  -- * Utilities
+  , isSmall
+
+  , initPState, PState
+
+  , Fixity(..), Assoc(..), addOperatorP
+
+  -- * For testing
+  , expr0P
+  ) where
+
+import qualified Data.HashMap.Strict         as M
+import qualified Data.HashSet                as S
+import qualified Data.Text                   as T
+import           Data.Maybe                  (fromJust, fromMaybe)
+import           Text.Parsec       hiding (State)
+import           Text.Parsec.Expr
+import qualified Text.Parsec.Token           as Token
+-- import           Text.Printf                 (printf)
+import           GHC.Generics                (Generic)
+
+import           Data.Char                   (isLower)
+import           Language.Fixpoint.Smt.Bitvector
+import           Language.Fixpoint.Types.Errors
+import           Language.Fixpoint.Misc      (tshow, thd3)
+import           Language.Fixpoint.Smt.Types
+-- import           Language.Fixpoint.Types.Names     (headSym)
+-- import           Language.Fixpoint.Types.Visitor   (foldSort, mapSort)
+import           Language.Fixpoint.Types hiding    (mapSort)
+import           Text.PrettyPrint.HughesPJ         (text, nest, vcat, (<+>))
+
+import Control.Monad.State
+
+type Parser = ParsecT String Integer (State PState)
+type ParserT u a = ParsecT String u (State PState) a
+
+data PState = PState {fixityTable :: OpTable}
+
+
+--------------------------------------------------------------------
+
+
+emptyDef :: Monad m => Token.GenLanguageDef String a m
+emptyDef    = Token.LanguageDef
+               { Token.commentStart   = ""
+               , Token.commentEnd     = ""
+               , Token.commentLine    = ""
+               , Token.nestedComments = True
+               , Token.identStart     = letter <|> char '_'
+               , Token.identLetter    = alphaNum <|> oneOf "_"
+               , Token.opStart        = Token.opLetter emptyDef
+               , Token.opLetter       = oneOf ":!#$%&*+./<=>?@\\^|-~'"
+               , Token.reservedOpNames= []
+               , Token.reservedNames  = []
+               , Token.caseSensitive  = True
+               }
+
+languageDef :: Monad m => Token.GenLanguageDef String a m
+languageDef =
+  emptyDef { Token.commentStart    = "/* "
+           , Token.commentEnd      = " */"
+           , Token.commentLine     = "//"
+           -- , Token.identStart      = satisfy (const False)
+           -- , Token.identLetter     = satisfy (const False)
+           , Token.reservedNames   = [ "SAT"
+                                     , "UNSAT"
+                                     , "true"
+                                     , "false"
+                                     , "mod"
+                                     , "data"
+                                     , "Bexp"
+                                     , "True"
+                                     , "Int"
+                                     , "import"
+                                     , "if", "then", "else"
+                                     , "func"
+
+                                     -- reserved words used in liquid haskell
+                                     , "forall"
+                                     , "exists"
+                                     , "module"
+                                     , "spec"
+                                     , "where"
+
+                                     , "decrease"
+                                     , "lazyvar"
+                                     , "LIQUID"
+                                     , "lazy"
+                                     , "local"
+                                     , "assert"
+                                     , "assume"
+                                     , "automatic-instances"
+                                     , "autosize"
+                                     , "axiomatize"
+                                     , "bound"
+                                     , "class"
+                                     , "data"
+                                     , "define"
+                                     , "defined"
+                                     , "embed"
+                                     , "expression"
+                                     , "import"
+                                     , "include"
+                                     , "infix"
+                                     , "infixl"
+                                     , "infixr"
+                                     , "inline"
+                                     , "instance"
+                                     , "invariant"
+                                     , "measure"
+                                     , "newtype"
+                                     , "predicate"
+                                     , "qualif"
+                                     , "reflect"
+                                     , "type"
+                                     , "using"
+                                     , "with"
+
+
+                                     ]
+           , Token.reservedOpNames = [ "+", "-", "*", "/", "\\", ":"
+                                     , "<", ">", "<=", ">=", "=", "!=" , "/="
+                                     , "mod", "and", "or"
+                                  --, "is"
+                                     , "&&", "||"
+                                     , "~", "=>", "==>", "<=>"
+                                     , "->"
+                                     , ":="
+                                     , "&", "^", "<<", ">>", "--"
+                                     , "?", "Bexp"
+                                     , "'"
+                                     , "_|_"
+                                     , "|"
+                                     , "<:"
+                                     , "|-"
+                                     , "::"
+                                     , "."
+                                     ]
+           }
+
+lexer :: Monad m => Token.GenTokenParser String u m
+lexer = Token.makeTokenParser languageDef
+
+
+reserved :: String -> Parser ()
+reserved      = Token.reserved      lexer
+
+reservedOp :: String -> Parser ()
+reservedOp    = Token.reservedOp    lexer
+
+parens, brackets, angles, braces :: ParserT u a -> ParserT u a
+parens        = Token.parens        lexer
+brackets      = Token.brackets      lexer
+angles        = Token.angles        lexer
+braces        = Token.braces        lexer
+
+semi, colon, comma, stringLiteral :: Parser String
+semi          = Token.semi          lexer
+colon         = Token.colon         lexer
+comma         = Token.comma         lexer
+stringLiteral = Token.stringLiteral lexer
+
+whiteSpace :: Parser ()
+whiteSpace    = Token.whiteSpace    lexer
+
+double :: Parser Double
+double        = Token.float         lexer
+-- integer       = Token.integer       lexer
+
+-- identifier = Token.identifier lexer
+
+-- TODO:AZ: pretty sure there is already a whitespace eater in parsec,
+blanks :: Parser String
+blanks  = many (satisfy (`elem` [' ', '\t']))
+
+-- | Integer
+integer :: Parser Integer
+integer = posInteger
+
+--  try (char '-' >> (negate <$> posInteger))
+--       <|> posInteger
+posInteger :: Parser Integer
+posInteger = toI <$> (many1 digit <* spaces)
+  where
+    toI :: String -> Integer
+    toI = read
+
+----------------------------------------------------------------
+------------------------- Expressions --------------------------
+----------------------------------------------------------------
+
+locParserP :: Parser a -> Parser (Located a)
+locParserP p = do l1 <- getPosition
+                  x  <- p
+                  l2 <- getPosition
+                  return $ Loc l1 l2 x
+
+
+-- FIXME: we (LH) rely on this parser being dumb and *not* consuming trailing
+-- whitespace, in order to avoid some parsers spanning multiple lines..
+
+condIdP  :: S.HashSet Char -> (String -> Bool) -> Parser Symbol
+condIdP chars f
+  = do c  <- letter <|> char '_'
+       cs <- many (satisfy (`S.member` chars))
+       blanks
+       if f (c:cs) then return (symbol $ c:cs) else parserZero
+
+-- | Lower-case identifiers
+upperIdP :: Parser Symbol
+upperIdP = do
+  c <- upper
+  cs <- many (satisfy (`S.member` symChars))
+  blanks
+  return (symbol $ c:cs)
+
+-- | Lower-case identifiers
+lowerIdP :: Parser Symbol
+lowerIdP = do
+  c <- satisfy (\c -> isLower c || c == '_' )
+  cs <- many (satisfy (`S.member` symChars))
+  blanks
+  return (symbol $ c:cs)
+
+symCharsP :: Parser Symbol
+symCharsP = condIdP symChars (`notElem` keyWordSyms)
+  where
+    keyWordSyms = ["if", "then", "else", "mod"]
+
+-- | String Haskell infix Id
+infixIdP :: Parser String
+infixIdP = many (satisfy (`notElem` [' ', '.']))
+
+isSmall :: Char -> Bool
+isSmall c = isLower c || c == '_'
+
+locLowerIdP, locUpperIdP :: Parser LocSymbol
+locLowerIdP = locParserP lowerIdP
+locUpperIdP = locParserP upperIdP
+
+-- | Arbitrary Symbols
+symbolP :: Parser Symbol
+symbolP = symbol <$> symCharsP
+
+-- | (Integer) Constants
+constantP :: Parser Constant
+constantP =  try (R <$> double)
+         <|> I <$> integer
+
+symconstP :: Parser SymConst
+symconstP = SL . T.pack <$> stringLiteral
+
+expr0P :: Parser Expr
+expr0P
+  =  (fastIfP EIte exprP)
+ <|> (ESym <$> symconstP)
+ <|> (ECon <$> constantP)
+ <|> (reservedOp "_|_" >> return EBot)
+ <|> lamP
+  -- TODO:AZ get rid of these try, after the rest
+ <|> try (parens exprP)
+ <|> try (parens exprCastP)
+ <|> (charsExpr <$> symCharsP)
+  where
+
+exprCastP :: Parser Expr
+exprCastP
+  = do e  <- exprP
+       (try dcolon) <|> colon
+       so <- sortP
+       return $ ECst e so
+
+charsExpr :: Symbol -> Expr
+charsExpr cs
+  | isSmall (headSym cs) = expr cs
+  | otherwise            = EVar cs
+
+fastIfP :: (Expr -> a -> a -> a) -> Parser a -> Parser a
+fastIfP f bodyP
+  = do reserved "if"
+       p <- predP
+       reserved "then"
+       b1 <- bodyP
+       reserved "else"
+       b2 <- bodyP
+       return $ f p b1 b2
+
+{-
+qmIfP f bodyP
+  = parens $ do
+      p  <- predP
+      reserved "?"
+      b1 <- bodyP
+      colon
+      b2 <- bodyP
+      return $ f p b1 b2
+-}
+
+-- | Used as input to @Text.Parsec.Expr.buildExpressionParser@ to create @exprP@
+expr1P :: Parser Expr
+expr1P
+  =  try funAppP
+ <|> expr0P
+
+-- | Expressions
+exprP :: Parser Expr
+exprP = (fixityTable <$> get) >>= (`buildExpressionParser` expr1P)
+
+data Fixity
+  = FInfix   {fpred :: Maybe Int, fname :: String, fop2 :: Maybe (Expr -> Expr -> Expr), fassoc :: Assoc}
+  | FPrefix  {fpred :: Maybe Int, fname :: String, fop1 :: Maybe (Expr -> Expr)}
+  | FPostfix {fpred :: Maybe Int, fname :: String, fop1 :: Maybe (Expr -> Expr)}
+
+
+-- Invariant : OpTable has 10 elements
+type OpTable = OperatorTable String Integer (State PState) Expr
+
+addOperatorP :: Fixity -> Parser ()
+addOperatorP op
+  = modify $ \s -> s{fixityTable =  addOperator op (fixityTable s)}
+
+addOperator :: Fixity -> OpTable -> OpTable
+addOperator (FInfix p x f assoc) ops
+ = insertOperator (makePrec p) (Infix (reservedOp x >> return (makeInfixFun x f)) assoc) ops
+addOperator (FPrefix p x f) ops
+ = insertOperator (makePrec p) (Prefix (reservedOp x >> return (makePrefixFun x f))) ops
+addOperator (FPostfix p x f) ops
+ = insertOperator (makePrec p) (Postfix (reservedOp x >> return (makePrefixFun x f))) ops
+
+makePrec :: Maybe Int -> Int
+makePrec = fromMaybe 9
+
+makeInfixFun :: String -> Maybe (Expr -> Expr -> Expr) -> Expr -> Expr -> Expr
+makeInfixFun x = fromMaybe (\e1 e2 -> EApp (EApp (EVar $ symbol x) e1) e2)
+
+makePrefixFun :: String -> Maybe (Expr -> Expr) -> Expr -> Expr
+makePrefixFun x = fromMaybe (EApp (EVar $ symbol x))
+
+insertOperator :: Int -> Operator String Integer (State PState) Expr -> OpTable -> OpTable
+insertOperator i op ops = go (9 - i) ops
+  where
+    go _ []       = die $ err dummySpan (text "insertOperator on empty ops")
+    go 0 (xs:xss) = (xs++[op]):xss
+    go i (xs:xss) = xs:go (i-1) xss
+
+initOpTable :: OpTable
+initOpTable = replicate 10 [] --  take 10 (repeat [])
+
+bops :: OpTable
+bops = foldl (flip addOperator) initOpTable buildinOps
+  where
+-- Build in Haskell ops https://www.haskell.org/onlinereport/decls.html#fixity
+    buildinOps = [ FPrefix (Just 9) "-"   (Just ENeg)
+                 , FInfix  (Just 7) "*"   (Just $ EBin Times) AssocLeft
+                 , FInfix  (Just 7) "/"   (Just $ EBin Div)   AssocLeft
+                 , FInfix  (Just 6) "-"   (Just $ EBin Minus) AssocLeft
+                 , FInfix  (Just 6) "+"   (Just $ EBin Plus)  AssocLeft
+                 , FInfix  (Just 5) "mod" (Just $ EBin Mod)   AssocLeft -- Haskell gives mod 7
+                 ]
+
+-- | Function Applications
+funAppP :: Parser Expr
+funAppP            =  litP <|> exprFunP <|> simpleAppP
+  where
+    exprFunP = mkEApp <$> funSymbolP <*> funRhsP
+    funRhsP  =  sepBy1 expr0P blanks
+            <|> parens innerP
+    innerP =   brackets (sepBy exprP semi)
+           <|> sepBy exprP comma
+
+    -- TODO:AZ the parens here should be superfluous, but it hits an infinite loop if removed
+    simpleAppP     = EApp <$> parens exprP <*> parens exprP
+    funSymbolP     = locParserP symbolP
+
+
+-- TODO:AZ: The comment says BitVector literal, but it accepts any @Sort@
+-- | BitVector literal: lit "#x00000001" (BitVec (Size32 obj))
+litP :: Parser Expr
+litP = do reserved "lit"
+          l <- stringLiteral
+          t <- sortP
+          return $ ECon $ L (T.pack l) t
+
+-- parenBrackets :: Parser a -> Parser a
+-- parenBrackets  = parens . brackets
+
+-- eMinus     = EBin Minus (expr (0 :: Integer))
+-- eCons x xs = EApp (dummyLoc consName) [x, xs]
+-- eNil       = EVar nilName
+
+lamP :: Parser Expr
+lamP
+  = do reservedOp "\\"
+       x <- symbolP
+       colon
+       t <- sortP
+       reservedOp "->"
+       e  <- exprP
+       return $ ELam (x, t) e
+
+dcolon :: Parser String
+dcolon = string "::" <* spaces
+
+varSortP :: Parser Sort
+varSortP  = FVar  <$> parens intP
+
+funcSortP :: Parser Sort
+funcSortP = parens $ mkFFunc <$> intP <* comma <*> sortsP
+
+sortsP :: Parser [Sort]
+sortsP = brackets $ sepBy sortP semi
+
+-- | Sort
+sortP    :: Parser Sort
+sortP    = sortP' (sepBy sortArgP blanks)
+
+sortArgP :: Parser Sort
+sortArgP = sortP' (return [])
+
+{-
+sortFunP :: Parser Sort
+sortFunP
+   =  try (string "@" >> varSortP)
+  <|> (fTyconSort <$> fTyConP)
+-}
+
+sortP' :: Parser [Sort] -> Parser Sort
+sortP' appArgsP
+   =  parens sortP
+  <|> (reserved "func" >> funcSortP)
+  <|> (fAppTC listFTyCon . single <$> brackets sortP)
+  <|> bvSortP
+  <|> (fAppTC <$> fTyConP <*> appArgsP)
+  <|> (fApp   <$> tvarP   <*> appArgsP)
+
+single :: a -> [a]
+single x = [x]
+
+tvarP :: Parser Sort
+tvarP
+   =  (string "@" >> varSortP)
+  <|> (FObj . symbol <$> lowerIdP)
+
+
+fTyConP :: Parser FTycon
+fTyConP
+  =   (reserved "int"     >> return intFTyCon)
+  <|> (reserved "Integer" >> return intFTyCon)
+  <|> (reserved "Int"     >> return intFTyCon)
+  <|> (reserved "int"     >> return intFTyCon) -- TODO:AZ duplicate?
+  <|> (reserved "real"    >> return realFTyCon)
+  <|> (reserved "bool"    >> return boolFTyCon)
+  <|> (reserved "num"     >> return numFTyCon)
+  <|> (reserved "Str"     >> return strFTyCon)
+  <|> (symbolFTycon      <$> locUpperIdP)
+
+-- | Bit-Vector Sort
+bvSortP :: Parser Sort
+bvSortP = mkSort <$> (bvSizeP "Size32" S32 <|> bvSizeP "Size64" S64)
+  where
+    bvSizeP ss s = do
+      parens (reserved "BitVec" >> reserved ss)
+      return s
+
+
+--------------------------------------------------------------------------------
+-- | Predicates ----------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+pred0P :: Parser Expr
+pred0P =  trueP
+      <|> falseP
+      <|> (reservedOp "??" >> makeUniquePGrad)
+      <|> kvarPredP
+      <|> (fastIfP pIte predP)
+      <|> try predrP
+      <|> (parens predP)
+      <|> (reservedOp "?" *> exprP)
+      <|> try funAppP
+      <|> (eVar <$> symbolP)
+      <|> (reservedOp "&&" >> pGAnds <$> predsP)
+      <|> (reservedOp "||" >> POr  <$> predsP)
+
+makeUniquePGrad :: Parser Expr 
+makeUniquePGrad
+  = do uniquePos <- getPosition
+       return $ PGrad (KV $ symbol $ show uniquePos) mempty mempty
+
+-- qmP    = reserved "?" <|> reserved "Bexp"
+
+trueP, falseP :: Parser Expr
+trueP  = reserved "true"  >> return PTrue
+falseP = reserved "false" >> return PFalse
+
+kvarPredP :: Parser Expr
+kvarPredP = PKVar <$> kvarP <*> substP
+
+kvarP :: Parser KVar
+kvarP = KV <$> (char '$' *> symbolP <* spaces)
+
+substP :: Parser Subst
+substP = mkSubst <$> many (brackets $ pairP symbolP aP exprP)
+  where
+    aP = reservedOp ":="
+
+predsP :: Parser [Expr]
+predsP = brackets $ sepBy predP semi
+
+predP  :: Parser Expr
+predP  = buildExpressionParser lops pred0P
+  where
+    lops = [ [Prefix (reservedOp "~"    >> return PNot)]
+           , [Prefix (reservedOp "not " >> return PNot)]
+           , [Infix  (reservedOp "&&"   >> return (\x y -> pGAnd x y)) AssocRight]
+           , [Infix  (reservedOp "||"   >> return (\x y -> POr  [x,y])) AssocRight]
+           , [Infix  (reservedOp "=>"   >> return PImp) AssocRight]
+           , [Infix  (reservedOp "==>"  >> return PImp) AssocRight]
+           , [Infix  (reservedOp "<=>"  >> return PIff) AssocRight]]
+
+predrP :: Parser Expr
+predrP = do e1    <- exprP
+            r     <- brelP
+            e2    <- exprP
+            return $ r e1 e2
+
+brelP ::  Parser (Expr -> Expr -> Expr)
+brelP =  (reservedOp "==" >> return (PAtom Eq))
+     <|> (reservedOp "="  >> return (PAtom Eq))
+     <|> (reservedOp "~~" >> return (PAtom Ueq))
+     <|> (reservedOp "!=" >> return (PAtom Ne))
+     <|> (reservedOp "/=" >> return (PAtom Ne))
+     <|> (reservedOp "!~" >> return (PAtom Une))
+     <|> (reservedOp "<"  >> return (PAtom Lt))
+     <|> (reservedOp "<=" >> return (PAtom Le))
+     <|> (reservedOp ">"  >> return (PAtom Gt))
+     <|> (reservedOp ">=" >> return (PAtom Ge))
+
+--------------------------------------------------------------------------------
+-- | BareTypes -----------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- | Refa
+refaP :: Parser Expr
+refaP =  try (pAnd <$> brackets (sepBy predP semi))
+     <|> predP
+
+
+-- | (Sorted) Refinements with configurable sub-parsers
+refBindP :: Parser Symbol -> Parser Expr -> Parser (Reft -> a) -> Parser a
+refBindP bp rp kindP
+  = braces $ do
+      x  <- bp
+      t  <- kindP
+      reservedOp "|"
+      ra <- rp <* spaces
+      return $ t (Reft (x, ra))
+
+
+-- bindP      = symbol    <$> (lowerIdP <* colon)
+-- | Binder (lowerIdP <* colon)
+bindP :: Parser Symbol
+bindP = symbolP <* colon
+
+optBindP :: Symbol -> Parser Symbol
+optBindP x = try bindP <|> return x
+
+-- | (Sorted) Refinements
+refP :: Parser (Reft -> a) -> Parser a
+refP       = refBindP bindP refaP
+
+-- | (Sorted) Refinements with default binder
+refDefP :: Symbol -> Parser Expr -> Parser (Reft -> a) -> Parser a
+refDefP x  = refBindP (optBindP x)
+
+---------------------------------------------------------------------
+-- | Parsing Qualifiers ---------------------------------------------
+---------------------------------------------------------------------
+
+-- | Qualifiers
+qualifierP :: Parser Sort -> Parser Qualifier
+qualifierP tP = do
+  pos    <- getPosition
+  n      <- upperIdP
+  params <- parens $ sepBy1 (sortBindP tP) comma
+  _      <- colon
+  body   <- predP
+  return  $ mkQual n params body pos
+  where
+    sortBindP = pairP symbolP colon
+
+pairP :: Parser a -> Parser z -> Parser b -> Parser (a, b)
+pairP xP sepP yP = (,) <$> xP <* sepP <*> yP
+
+-- mkParam :: Symbol -> Symbol
+-- mkParam s       = unsafeTextSymbol ('~' `T.cons` toUpper c `T.cons` cs)
+--  where
+--    Just (c,cs) = T.uncons $ symbolSafeText s
+
+
+---------------------------------------------------------------------
+-- | Parsing Constraints (.fq files) --------------------------------
+---------------------------------------------------------------------
+
+-- Entities in Query File
+data Def a
+  = Srt !Sort
+  | Axm !Expr
+  | Cst !(SubC a)
+  | Wfc !(WfC a)
+  | Con !Symbol !Sort
+  | Dis !Symbol !Sort
+  | Qul !Qualifier
+  | Kut !KVar
+  | Pack !KVar !Int
+  | IBind !Int !Symbol !SortedReft
+  | Opt !String
+  deriving (Show, Generic)
+  --  Sol of solbind
+  --  Dep of FixConstraint.dep
+
+fInfoOptP :: Parser (FInfoWithOpts ())
+fInfoOptP = do ps <- many defP
+               return $ FIO (defsFInfo ps) [s | Opt s <- ps]
+
+fInfoP :: Parser (FInfo ())
+fInfoP = defsFInfo <$> {-# SCC "many-defP" #-} many defP
+
+defP :: Parser (Def ())
+defP =  Srt   <$> (reserved "sort"       >> colon >> sortP)
+    <|> Axm   <$> (reserved "axiom"      >> colon >> predP)
+    <|> Cst   <$> (reserved "constraint" >> colon >> {-# SCC "subCP" #-} subCP)
+    <|> Wfc   <$> (reserved "wf"         >> colon >> {-# SCC "wfCP"  #-} wfCP)
+    <|> Con   <$> (reserved "constant"   >> symbolP) <*> (colon >> sortP)
+    <|> Dis   <$> (reserved "distinct"   >> symbolP) <*> (colon >> sortP)
+    <|> Pack  <$> (reserved "pack"       >> kvarP)   <*> (colon >> intP)
+    <|> Qul   <$> (reserved "qualif"     >> qualifierP sortP)
+    <|> Kut   <$> (reserved "cut"        >> kvarP)
+    <|> IBind <$> (reserved "bind"       >> intP) <*> symbolP <*> (colon >> {-# SCC "sortedReftP" #-} sortedReftP)
+    <|> Opt   <$> (reserved "fixpoint"   >> stringLiteral)
+
+sortedReftP :: Parser SortedReft
+sortedReftP = refP (RR <$> (sortP <* spaces))
+
+wfCP :: Parser (WfC ())
+wfCP = do reserved "env"
+          env <- envP
+          reserved "reft"
+          r   <- sortedReftP
+          let [w] = wfC env r ()
+          return w
+
+subCP :: Parser (SubC ())
+subCP = do pos <- getPosition
+           reserved "env"
+           env <- envP
+           reserved "lhs"
+           lhs <- sortedReftP
+           reserved "rhs"
+           rhs <- sortedReftP
+           reserved "id"
+           i   <- integer <* spaces
+           tag <- tagP
+           pos' <- getPosition
+           return $ subC' env lhs rhs i tag pos pos'
+
+subC' :: IBindEnv
+      -> SortedReft
+      -> SortedReft
+      -> Integer
+      -> Tag
+      -> SourcePos
+      -> SourcePos
+      -> SubC ()
+subC' env lhs rhs i tag l l'
+  = case cs of
+      [c] -> c
+      _   -> die $ err sp $ "RHS without single conjunct at" <+> pprint l'
+    where
+       cs = subC env lhs rhs (Just i) tag ()
+       sp = SS l l'
+
+
+tagP  :: Parser [Int]
+tagP  = reserved "tag" >> spaces >> brackets (sepBy intP semi)
+
+envP  :: Parser IBindEnv
+envP  = do binds <- brackets $ sepBy (intP <* spaces) semi
+           return $ insertsIBindEnv binds emptyIBindEnv
+
+intP :: Parser Int
+intP = fromInteger <$> integer
+
+defsFInfo :: [Def a] -> FInfo a
+defsFInfo defs = {-# SCC "defsFI" #-} FI cm ws bs lts dts kts qs mempty mempty mempty mempty
+  where
+    cm         = M.fromList         [(cid c, c)         | Cst c       <- defs]
+    ws         = M.fromList         [(thd3 $ wrft w, w) | Wfc w       <- defs]
+    bs         = bindEnvFromList    [(n, x, r)          | IBind n x r <- defs]
+    lts        = fromListSEnv       [(x, t)             | Con x t     <- defs]
+    dts        = fromListSEnv       [(x, t)             | Dis x t     <- defs]
+    kts        = KS $ S.fromList    [k                  | Kut k       <- defs]
+    -- pks        = Packs $ M.fromList [(k, i)             | Pack k i    <- defs]
+    qs         =                    [q                  | Qul q       <- defs]
+    cid        = fromJust . sid
+    -- msg    = show $ "#Lits = " ++ (show $ length consts)
+
+---------------------------------------------------------------------
+-- | Interacting with Fixpoint --------------------------------------
+---------------------------------------------------------------------
+
+fixResultP :: Parser a -> Parser (FixResult a)
+fixResultP pp
+  =  (reserved "SAT"   >> return Safe)
+ <|> (reserved "UNSAT" >> Unsafe <$> brackets (sepBy pp comma))
+ <|> (reserved "CRASH" >> crashP pp)
+
+crashP :: Parser a -> Parser (FixResult a)
+crashP pp = do
+  i   <- pp
+  msg <- many anyChar
+  return $ Crash [i] msg
+
+predSolP :: Parser Expr
+predSolP = parens (predP  <* (comma >> iQualP))
+
+iQualP :: Parser [Symbol]
+iQualP = upperIdP >> parens (sepBy symbolP comma)
+
+solution1P :: Parser (KVar, Expr)
+solution1P = do
+  reserved "solution:"
+  k  <- kvP
+  reservedOp ":="
+  ps <- brackets $ sepBy predSolP semi
+  return (k, simplify $ PAnd ps)
+  where
+    kvP = try kvarP <|> (KV <$> symbolP)
+
+solutionP :: Parser (M.HashMap KVar Expr)
+solutionP = M.fromList <$> sepBy solution1P whiteSpace
+
+solutionFileP :: Parser (FixResult Integer, M.HashMap KVar Expr)
+solutionFileP = (,) <$> fixResultP integer <*> solutionP
+
+--------------------------------------------------------------------------------
+remainderP :: Parser a -> Parser (a, String, SourcePos)
+remainderP p
+  = do res <- p
+       str <- getInput
+       pos <- getPosition
+       return (res, str, pos)
+
+
+initPState :: PState
+initPState = PState {fixityTable = bops}
+
+doParse' :: Parser a -> SourceName -> String -> a
+doParse' parser f s
+  = case evalState (runParserT (remainderP (whiteSpace >> parser)) 0 f s) initPState of
+      Left e            -> die $ err (errorSpan e) (dErr e)
+      Right (r, "", _)  -> r
+      Right (_, r, l)   -> die $ err (SS l l) (dRem r)
+    where
+      dErr e = vcat [ "parseError"        <+> tshow e
+                    , "when parsing from" <+> text f ]
+      dRem r = vcat [ "doParse has leftover"
+                    , nest 4 (text r)
+                    , "when parsing from" <+> text f ]
+
+
+errorSpan :: ParseError -> SrcSpan
+errorSpan e = SS l l where l = errorPos e
+
+parseFromFile :: Parser b -> SourceName -> IO b
+parseFromFile p f = doParse' p f <$> readFile f
+
+freshIntP :: Parser Integer
+freshIntP = do n <- getState
+               updateState (+ 1)
+               return n
+
+---------------------------------------------------------------------
+-- Standalone SMTLIB2 commands --------------------------------------
+---------------------------------------------------------------------
+commandsP :: Parser [Command]
+commandsP = sepBy commandP semi
+
+commandP :: Parser Command
+commandP
+  =  (reserved "var"      >> cmdVarP)
+ <|> (reserved "push"     >> return Push)
+ <|> (reserved "pop"      >> return Pop)
+ <|> (reserved "check"    >> return CheckSat)
+ <|> (reserved "assert"   >> (Assert Nothing <$> predP))
+ <|> (reserved "distinct" >> (Distinct <$> brackets (sepBy exprP comma)))
+
+cmdVarP :: Parser Command
+cmdVarP = do
+  x <- bindP
+  t <- sortP
+  return $ Declare x [] t
+
+---------------------------------------------------------------------
+-- Bundling Parsers into a Typeclass --------------------------------
+---------------------------------------------------------------------
+
+class Inputable a where
+  rr  :: String -> a
+  rr' :: String -> String -> a
+  rr' _ = rr
+  rr    = rr' ""
+
+instance Inputable Symbol where
+  rr' = doParse' symbolP
+
+instance Inputable Constant where
+  rr' = doParse' constantP
+
+instance Inputable Expr where
+  rr' = doParse' exprP
+
+instance Inputable (FixResult Integer) where
+  rr' = doParse' $ fixResultP integer
+
+instance Inputable (FixResult Integer, FixSolution) where
+  rr' = doParse' solutionFileP
+
+instance Inputable (FInfo ()) where
+  rr' = {-# SCC "fInfoP" #-} doParse' fInfoP
+
+instance Inputable (FInfoWithOpts ()) where
+  rr' = {-# SCC "fInfoWithOptsP" #-} doParse' fInfoOptP
+
+instance Inputable Command where
+  rr' = doParse' commandP
+
+instance Inputable [Command] where
+  rr' = doParse' commandsP
+
+{-
+---------------------------------------------------------------
+--------------------------- Testing ---------------------------
+---------------------------------------------------------------
+
+-- A few tricky predicates for parsing
+-- myTest1 = "((((v >= 56320) && (v <= 57343)) => (((numchars a o ((i - o) + 1)) == (1 + (numchars a o ((i - o) - 1)))) && (((numchars a o (i - (o -1))) >= 0) && (((i - o) - 1) >= 0)))) && ((not (((v >= 56320) && (v <= 57343)))) => (((numchars a o ((i - o) + 1)) == (1 + (numchars a o (i - o)))) && ((numchars a o (i - o)) >= 0))))"
+--
+-- myTest2 = "len x = len y - 1"
+-- myTest3 = "len x y z = len a b c - 1"
+-- myTest4 = "len x y z = len a b (c - 1)"
+-- myTest5 = "x >= -1"
+-- myTest6 = "(bLength v) = if n > 0 then n else 0"
+-- myTest7 = "(bLength v) = (if n > 0 then n else 0)"
+-- myTest8 = "(bLength v) = (n > 0 ? n : 0)"
+
+
+sa  = "0"
+sb  = "x"
+sc  = "(x0 + y0 + z0) "
+sd  = "(x+ y * 1)"
+se  = "_|_ "
+sf  = "(1 + x + _|_)"
+sg  = "f(x,y,z)"
+sh  = "(f((x+1), (y * a * b - 1), _|_))"
+si  = "(2 + f((x+1), (y * a * b - 1), _|_))"
+
+s0  = "true"
+s1  = "false"
+s2  = "v > 0"
+s3  = "(0 < v && v < 100)"
+s4  = "(x < v && v < y+10 && v < z)"
+s6  = "[(v > 0)]"
+s6' = "x"
+s7' = "(x <=> y)"
+s8' = "(x <=> a = b)"
+s9' = "(x <=> (a <= b && b < c))"
+
+s7  = "{ v: Int | [(v > 0)] }"
+s8  = "x:{ v: Int | v > 0 } -> {v : Int | v >= x}"
+s9  = "v = x+y"
+s10 = "{v: Int | v = x + y}"
+
+s11 = "x:{v:Int | true } -> {v:Int | true }"
+s12 = "y : {v:Int | true } -> {v:Int | v = x }"
+s13 = "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x + y}"
+s14 = "x:{v:a  | true} -> y:{v:b | true } -> {v:a | (x < v && v < y) }"
+s15 = "x:Int -> Bool"
+s16 = "x:Int -> y:Int -> {v:Int | v = x + y}"
+s17 = "a"
+s18 = "x:a -> Bool"
+s20 = "forall a . x:Int -> Bool"
+
+s21 = "x:{v : GHC.Prim.Int# | true } -> {v : Int | true }"
+
+r0  = (rr s0) :: Pred
+r0' = (rr s0) :: [Refa]
+r1  = (rr s1) :: [Refa]
+
+
+e1, e2  :: Expr
+e1  = rr "(k_1 + k_2)"
+e2  = rr "k_1"
+
+o1, o2, o3 :: FixResult Integer
+o1  = rr "SAT "
+o2  = rr "UNSAT [1, 2, 9,10]"
+o3  = rr "UNSAT []"
+
+-- sol1 = doParse solution1P "solution: k_5 := [0 <= VV_int]"
+-- sol2 = doParse solution1P "solution: k_4 := [(0 <= VV_int)]"
+
+b0, b1, b2, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13 :: BareType
+b0  = rr "Int"
+b1  = rr "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x + y}"
+b2  = rr "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x - y}"
+b4  = rr "forall a . x : a -> Bool"
+b5  = rr "Int -> Int -> Int"
+b6  = rr "(Int -> Int) -> Int"
+b7  = rr "({v: Int | v > 10} -> Int) -> Int"
+b8  = rr "(x:Int -> {v: Int | v > x}) -> {v: Int | v > 10}"
+b9  = rr "x:Int -> {v: Int | v > x} -> {v: Int | v > 10}"
+b10 = rr "[Int]"
+b11 = rr "x:[Int] -> {v: Int | v > 10}"
+b12 = rr "[Int] -> String"
+b13 = rr "x:(Int, [Bool]) -> [(String, String)]"
+
+-- b3 :: BareType
+-- b3  = rr "x:Int -> y:Int -> {v:Bool | ((v is True) <=> x = y)}"
+
+m1 = ["len :: [a] -> Int", "len (Nil) = 0", "len (Cons x xs) = 1 + len(xs)"]
+m2 = ["tog :: LL a -> Int", "tog (Nil) = 100", "tog (Cons y ys) = 200"]
+
+me1, me2 :: Measure.Measure BareType Symbol
+me1 = (rr $ intercalate "\n" m1)
+me2 = (rr $ intercalate "\n" m2)
+-}
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Smt/Bitvector.hs b/liquid-fixpoint/src/Language/Fixpoint/Smt/Bitvector.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Smt/Bitvector.hs
@@ -0,0 +1,69 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+
+module Language.Fixpoint.Smt.Bitvector
+       ( -- * Constructor
+         Bv (..)
+
+         -- * Sizes
+       , BvSize (..)
+
+         -- * Operators
+       , BvOp (..)
+
+         -- * BitVector Sort Constructor
+       , mkSort
+
+         -- * BitVector Expression Constructor
+       , eOp
+
+         -- * BitVector Type Constructor
+       , bvTyCon
+
+       ) where
+
+import           Data.Generics           (Data)
+import qualified Data.Text               as T
+import           Data.Typeable           (Typeable)
+import           GHC.Generics            (Generic)
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Types
+
+data Bv     = Bv !BvSize !String
+
+data BvSize = S32   | S64
+              deriving (Eq, Ord, Show, Data, Typeable, Generic)
+
+data BvOp   = BvAnd | BvOr
+              deriving (Eq, Ord, Show, Data, Typeable, Generic)
+
+-- | Construct the bitvector `Sort` from its `BvSize`
+mkSort :: BvSize -> Sort
+mkSort s = fApp (fTyconSort bvTyCon) [ fTyconSort (sizeTyCon s) ]
+
+bvTyCon :: FTycon
+bvTyCon = symbolFTycon $ dummyLoc bitVecName
+
+sizeTyCon    :: BvSize -> FTycon
+sizeTyCon    = symbolFTycon . dummyLoc . sizeName
+
+sizeName :: BvSize -> Symbol
+sizeName S32 = size32Name
+sizeName S64 = size64Name
+
+-- | Construct an `Expr` using a raw string, e.g. (Bv S32 "#x02000000")
+instance Expression Bv where
+  expr (Bv sz v) = ECon $ L (T.pack v) (mkSort sz)
+
+-- | Apply some bitvector operator to a list of arguments
+eOp :: BvOp -> [Expr] -> Expr
+eOp b es = foldl EApp (EVar $ opName b) es
+
+opName :: BvOp -> Symbol
+opName BvAnd = bvAndName
+opName BvOr  = bvOrName
+
+
+-- sizeSort     = (`FApp` [fObj $ dummyLoc $ symbol "obj"]) . sizeTC
+-- s32TyCon     = symbolFTycon $ dummyLoc size32Name
+-- s64TyCon     = symbolFTycon $ dummyLoc size64Name
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Smt/Interface.hs b/liquid-fixpoint/src/Language/Fixpoint/Smt/Interface.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Smt/Interface.hs
@@ -0,0 +1,412 @@
+{-# LANGUAGE BangPatterns              #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE RecordWildCards           #-}
+{-# LANGUAGE UndecidableInstances      #-}
+{-# LANGUAGE ScopedTypeVariables       #-}
+
+-- | This module contains an SMTLIB2 interface for
+--   1. checking the validity, and,
+--   2. computing satisfying assignments
+--   for formulas.
+--   By implementing a binary interface over the SMTLIB2 format defined at
+--   http://www.smt-lib.org/
+--   http://www.grammatech.com/resource/smt/SMTLIBTutorial.pdf
+
+module Language.Fixpoint.Smt.Interface (
+
+    -- * Commands
+      Command  (..)
+
+    -- * Responses
+    , Response (..)
+
+    -- * Typeclass for SMTLIB2 conversion
+    , SMTLIB2 (..)
+
+    -- * Creating and killing SMTLIB2 Process
+    , Context (..)
+    , makeContext
+    , makeContextNoLog
+    , makeContextWithSEnv
+    , cleanupContext
+
+    -- * Execute Queries
+    , command
+    , smtWrite
+
+    -- * Query API
+    , smtDecl
+    , smtDecls
+    , smtAssert
+    , smtAssertAxiom
+    , smtCheckUnsat
+    , smtCheckSat
+    , smtBracket
+    , smtDistinct
+    , smtPush, smtPop
+
+    -- * Check Validity
+    , checkValid
+    , checkValid'
+    , checkValidWithContext
+    , checkValids
+    , makeSmtContext
+
+    ) where
+
+import           Language.Fixpoint.Types.Config ( SMTSolver (..)
+                                                , Config
+                                                , solver
+                                                , extensionality
+                                                , alphaEquivalence
+                                                , betaEquivalence
+                                                , normalForm
+                                                , stringTheory)
+import           Language.Fixpoint.Misc         (errorstar)
+import           Language.Fixpoint.Types.Errors
+-- import           Language.Fixpoint.SortCheck    (elaborate)
+import           Language.Fixpoint.Utils.Files
+import           Language.Fixpoint.Types hiding (allowHO)
+import           Language.Fixpoint.Smt.Types
+import qualified Language.Fixpoint.Smt.Theories as Thy
+import           Language.Fixpoint.Smt.Serialize ()
+
+import           Control.Applicative      ((<|>))
+import           Control.Monad
+import           Control.Exception
+import           Data.Char
+import           Data.Monoid
+import qualified Data.Text                as T
+import           Data.Text.Format
+import qualified Data.Text.IO             as TIO
+import qualified Data.Text.Lazy           as LT
+import qualified Data.Text.Lazy.Builder   as Builder
+import qualified Data.Text.Lazy.IO        as LTIO
+import           System.Directory
+import           System.Console.CmdArgs.Verbosity
+import           System.Exit              hiding (die)
+import           System.FilePath
+import           System.IO                (Handle, IOMode (..), hClose, hFlush, openFile)
+import           System.Process
+import qualified Data.Attoparsec.Text     as A
+import qualified Data.HashMap.Strict      as M
+import           Data.Attoparsec.Internal.Types (Parser)
+import           Text.PrettyPrint.HughesPJ (text)
+{-
+runFile f
+  = readFile f >>= runString
+
+runString str
+  = runCommands $ rr str
+
+runCommands cmds
+  = do me   <- makeContext Z3
+       mapM_ (T.putStrLn . smt2) cmds
+       zs   <- mapM (command me) cmds
+       return zs
+-}
+
+
+-- TODO take makeContext's Bool from caller instead of always using False?
+makeSmtContext :: Config -> FilePath -> [(Symbol, Sort)] -> IO Context
+makeSmtContext cfg f xts = do
+  me <- makeContextWithSEnv cfg f $ fromListSEnv xts
+  smtDecls me theoryDecls
+  smtDecls me xts
+  return me
+
+theoryDecls :: [(Symbol, Sort)]
+theoryDecls = [ (x, tsSort ty) | (x, ty) <- M.toList Thy.theorySymbols, not (tsInterp ty)]
+
+checkValidWithContext :: Context -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool
+checkValidWithContext me xts p q =
+  smtBracket me "checkValidWithContext" $
+    checkValid' me xts p q
+
+-- | type ClosedPred E = {v:Pred | subset (vars v) (keys E) }
+-- checkValid :: e:Env -> ClosedPred e -> ClosedPred e -> IO Bool
+checkValid :: Config -> FilePath -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool
+checkValid cfg f xts p q = do
+  me <- makeContext cfg f
+  checkValid' me xts p q
+
+checkValid' :: Context -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool
+checkValid' me xts p q = do
+  smtDecls me xts
+  smtAssert me $ pAnd [p, PNot q]
+  smtCheckUnsat me
+
+-- | If you already HAVE a context, where all the variables have declared types
+--   (e.g. if you want to make MANY repeated Queries)
+
+-- checkValid :: e:Env -> [ClosedPred e] -> IO [Bool]
+checkValids :: Config -> FilePath -> [(Symbol, Sort)] -> [Expr] -> IO [Bool]
+checkValids cfg f xts ps
+  = do me <- makeContext cfg f
+       smtDecls me xts
+       forM ps $ \p ->
+          smtBracket me "checkValids" $
+            smtAssert me (PNot p) >> smtCheckUnsat me
+
+-- debugFile :: FilePath
+-- debugFile = "DEBUG.smt2"
+
+--------------------------------------------------------------------------
+-- | SMT IO --------------------------------------------------------------
+--------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------
+command              :: Context -> Command -> IO Response
+--------------------------------------------------------------------------
+command me !cmd       = say cmd >> hear cmd
+  where
+    say               = smtWrite me . Builder.toLazyText . runSmt2
+    hear CheckSat     = smtRead me
+    hear (GetValue _) = smtRead me
+    hear _            = return Ok
+
+
+smtWrite :: Context -> Raw -> IO ()
+smtWrite me !s = smtWriteRaw me s
+
+smtRead :: Context -> IO Response
+smtRead me = {-# SCC "smtRead" #-}
+    do ln  <- smtReadRaw me
+       res <- A.parseWith (smtReadRaw me) responseP ln
+       case A.eitherResult res of
+         Left e  -> errorstar $ "SMTREAD:" ++ e
+         Right r -> do
+           maybe (return ()) (\h -> hPutStrLnNow h $ format "; SMT Says: {}" (Only $ show r)) (ctxLog me)
+           -- when (verbose me) $ TIO.putStrLn $ format "SMT Says: {}" (Only $ show r)
+           return r
+
+type SmtParser a = Parser T.Text a
+
+responseP :: SmtParser Response
+responseP = {-# SCC "responseP" #-} A.char '(' *> sexpP
+         <|> A.string "sat"     *> return Sat
+         <|> A.string "unsat"   *> return Unsat
+         <|> A.string "unknown" *> return Unknown
+
+sexpP :: SmtParser Response
+sexpP = {-# SCC "sexpP" #-} A.string "error" *> (Error <$> errorP)
+     <|> Values <$> valuesP
+
+errorP :: SmtParser T.Text
+errorP = A.skipSpace *> A.char '"' *> A.takeWhile1 (/='"') <* A.string "\")"
+
+valuesP :: SmtParser [(Symbol, T.Text)]
+valuesP = A.many1' pairP <* A.char ')'
+
+pairP :: SmtParser (Symbol, T.Text)
+pairP = {-# SCC "pairP" #-}
+  do A.skipSpace
+     A.char '('
+     !x <- symbolP
+     A.skipSpace
+     !v <- valueP
+     A.char ')'
+     return (x,v)
+
+symbolP :: SmtParser Symbol
+symbolP = {-# SCC "symbolP" #-} symbol <$> A.takeWhile1 (not . isSpace)
+
+valueP :: SmtParser T.Text
+valueP = {-# SCC "valueP" #-} negativeP
+      <|> A.takeWhile1 (\c -> not (c == ')' || isSpace c))
+
+negativeP :: SmtParser T.Text
+negativeP
+  = do v <- A.char '(' *> A.takeWhile1 (/=')') <* A.char ')'
+       return $ "(" <> v <> ")"
+
+smtWriteRaw      :: Context -> Raw -> IO ()
+smtWriteRaw me !s = {-# SCC "smtWriteRaw" #-} do
+  -- whenLoud $ do LTIO.appendFile debugFile (s <> "\n")
+  --               LTIO.putStrLn ("CMD-RAW:" <> s <> ":CMD-RAW:DONE")
+  hPutStrLnNow (ctxCout me) s
+  maybe (return ()) (`hPutStrLnNow` s) (ctxLog me)
+
+smtReadRaw       :: Context -> IO T.Text
+smtReadRaw me    = {-# SCC "smtReadRaw" #-} TIO.hGetLine (ctxCin me)
+
+hPutStrLnNow     :: Handle -> LT.Text -> IO ()
+hPutStrLnNow h !s = LTIO.hPutStrLn h s >> hFlush h
+
+--------------------------------------------------------------------------
+-- | SMT Context ---------------------------------------------------------
+--------------------------------------------------------------------------
+
+--------------------------------------------------------------------------
+makeContext   :: Config -> FilePath -> IO Context
+--------------------------------------------------------------------------
+makeContext cfg f
+  = do me   <- makeProcess cfg
+       pre  <- smtPreamble cfg (solver cfg) me
+       createDirectoryIfMissing True $ takeDirectory smtFile
+       hLog <- openFile smtFile WriteMode
+       let me' = me { ctxLog = Just hLog }
+       mapM_ (smtWrite me') pre
+       return me'
+    where
+       smtFile = extFileName Smt2 f
+
+makeContextWithSEnv :: Config -> FilePath -> SMTEnv -> IO Context
+makeContextWithSEnv cfg f env
+  = (\cxt -> cxt {ctxSmtEnv = env}) <$> makeContext cfg f
+  -- where msg = "makeContextWithSEnv" ++ show env
+
+makeContextNoLog :: Config -> IO Context
+makeContextNoLog cfg
+  = do me  <- makeProcess cfg
+       pre <- smtPreamble cfg (solver cfg) me
+       mapM_ (smtWrite me) pre
+       return me
+
+makeProcess :: Config -> IO Context
+makeProcess cfg
+  = do (hOut, hIn, _ ,pid) <- runInteractiveCommand $ smtCmd (solver cfg)
+       loud <- isLoud
+       return Ctx { ctxPid     = pid
+                  , ctxCin     = hIn
+                  , ctxCout    = hOut
+                  , ctxLog     = Nothing
+                  , ctxVerbose = loud
+                  , ctxExt     = extensionality cfg
+                  , ctxAeq     = alphaEquivalence cfg
+                  , ctxBeq     = betaEquivalence  cfg
+                  , ctxNorm    = normalForm       cfg
+                  , ctxSmtEnv  = Thy.theorySEnv
+                  }
+
+--------------------------------------------------------------------------
+cleanupContext :: Context -> IO ExitCode
+--------------------------------------------------------------------------
+cleanupContext (Ctx {..}) = do
+  hCloseMe "ctxCin"  ctxCin
+  hCloseMe "ctxCout" ctxCout
+  maybe (return ()) (hCloseMe "ctxLog") ctxLog
+  waitForProcess ctxPid
+
+hCloseMe :: String -> Handle -> IO ()
+hCloseMe msg h = hClose h `catch` (\(exn :: IOException) -> putStrLn $ "OOPS, hClose breaks: " ++ msg ++ show exn)
+
+{- "z3 -smt2 -in"                   -}
+{- "z3 -smtc SOFT_TIMEOUT=1000 -in" -}
+{- "z3 -smtc -in MBQI=false"        -}
+
+smtCmd         :: SMTSolver -> String --  T.Text
+smtCmd Z3      = "z3 -smt2 -in"
+smtCmd Mathsat = "mathsat -input=smt2"
+smtCmd Cvc4    = "cvc4 --incremental -L smtlib2"
+
+-- DON'T REMOVE THIS! z3 changed the names of options between 4.3.1 and 4.3.2...
+smtPreamble :: Config -> SMTSolver -> Context -> IO [LT.Text]
+smtPreamble cfg Z3 me
+  = do smtWrite me "(get-info :version)"
+       v:_ <- T.words . (!!1) . T.splitOn "\"" <$> smtReadRaw me
+       checkValidStringFlag Z3 v cfg
+       if T.splitOn "." v `versionGreaterEq` ["4", "3", "2"]
+         then return $ z3_432_options ++ makeMbqi cfg ++ Thy.preamble cfg Z3
+         else return $ z3_options     ++ makeMbqi cfg ++ Thy.preamble cfg Z3
+smtPreamble cfg s _
+  = checkValidStringFlag s "" cfg >> return (Thy.preamble cfg s)
+
+checkValidStringFlag :: SMTSolver -> T.Text -> Config -> IO ()
+checkValidStringFlag smt v cfg
+  = when (noString smt v cfg) $
+      die $ err dummySpan (text "stringTheory is only supported by z3 version >=4.2.2")
+
+noString :: SMTSolver -> T.Text -> Config -> Bool
+noString smt v cfg
+  =  stringTheory cfg
+  && not (smt == Z3 && (T.splitOn "." v `versionGreaterEq` ["4", "4", "2"]))
+
+
+versionGreaterEq :: Ord a => [a] -> [a] -> Bool
+versionGreaterEq (x:xs) (y:ys)
+  | x >  y = True
+  | x == y = versionGreaterEq xs ys
+  | x <  y = False
+versionGreaterEq _  [] = True
+versionGreaterEq [] _  = False
+versionGreaterEq _ _ = errorstar "Interface.versionGreater called with bad arguments"
+
+-----------------------------------------------------------------------------
+-- | SMT Commands -----------------------------------------------------------
+-----------------------------------------------------------------------------
+
+smtPush, smtPop   :: Context -> IO ()
+smtPush me        = interact' me Push
+smtPop me         = interact' me Pop
+
+smtDecls :: Context -> [(Symbol, Sort)] -> IO ()
+smtDecls = mapM_ . uncurry . smtDecl
+
+smtDecl :: Context -> Symbol -> Sort -> IO ()
+smtDecl me x t = interact' me (Declare x ins out)
+  where
+    (ins, out) = deconSort t
+
+deconSort :: Sort -> ([Sort], Sort)
+deconSort t = case functionSort t of
+                Just (_, ins, out) -> (ins, out)
+                Nothing            -> ([] , t  )
+
+-- hack now this is used only for checking gradual condition.
+smtCheckSat :: Context -> Expr -> IO Bool
+smtCheckSat me p
+ = smtAssert me p >> (ans <$> command me CheckSat)
+ where
+   ans Sat = True
+   ans _   = False
+
+smtAssert :: Context -> Expr -> IO ()
+smtAssert me p  = interact' me (Assert Nothing p)
+
+
+smtAssertAxiom :: Context -> Triggered Expr -> IO ()
+smtAssertAxiom me p  = interact' me (AssertAxiom p)
+
+smtDistinct :: Context -> [Expr] -> IO ()
+smtDistinct me az = interact' me (Distinct az)
+
+smtCheckUnsat :: Context -> IO Bool
+smtCheckUnsat me  = respSat <$> command me CheckSat
+
+smtBracket :: Context -> String -> IO a -> IO a
+smtBracket me _msg a   = do
+  smtPush me
+  r <- a
+  smtPop me
+  return r
+
+respSat :: Response -> Bool
+respSat Unsat   = True
+respSat Sat     = False
+respSat Unknown = False
+respSat r       = die $ err dummySpan $ text ("crash: SMTLIB2 respSat = " ++ show r)
+
+interact' :: Context -> Command -> IO ()
+interact' me cmd  = void $ command me cmd
+
+makeMbqi :: Config -> [LT.Text]
+makeMbqi cfg
+  | extensionality cfg = [""]
+  | otherwise          = ["\n(set-option :smt.mbqi false)"]
+
+-- DON'T REMOVE THIS! z3 changed the names of options between 4.3.1 and 4.3.2...
+z3_432_options :: [LT.Text]
+z3_432_options
+  = [ "(set-option :auto-config false)"
+    , "(set-option :model true)"
+    , "(set-option :model.partial false)"]
+
+z3_options :: [LT.Text]
+z3_options
+  = [ "(set-option :auto-config false)"
+    , "(set-option :model true)"
+    , "(set-option :model-partial false)"]
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Smt/Serialize.hs b/liquid-fixpoint/src/Language/Fixpoint/Smt/Serialize.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Smt/Serialize.hs
@@ -0,0 +1,175 @@
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE PatternGuards        #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE DoAndIfThenElse      #-}
+
+-- | This module contains the code for serializing Haskell values
+--   into SMTLIB2 format, that is, the instances for the @SMTLIB2@
+--   typeclass. We split it into a separate module as it depends on
+--   Theories (see @smt2App@).
+
+module Language.Fixpoint.Smt.Serialize () where
+
+import           Language.Fixpoint.Types
+import           Language.Fixpoint.Smt.Types
+import qualified Language.Fixpoint.Smt.Theories as Thy
+import           Data.Monoid
+import qualified Data.Text.Lazy.Builder         as Builder
+import           Data.Text.Format
+import           Language.Fixpoint.Misc (errorstar)
+import           Data.Maybe (fromMaybe)
+
+-- instance SMTLIB2 Sort where
+--   smt2 s@(FFunc _ _)           = errorstar $ "smt2 FFunc: " ++ showpp s
+--   smt2 FInt                    = "Int"
+--   smt2 FReal                   = "Real"
+--   smt2 t
+--     | t == boolSort            = "Bool"
+--   smt2 t
+--     | Just d <- Thy.smt2Sort t = d
+--   smt2 _                       = "Int"
+
+instance SMTLIB2 (Symbol, Sort) where
+  smt2 c@(sym, t) = build "({} {})" (smt2 sym, smt2Sort c t)
+
+smt2Sort :: (PPrint a) => a -> Sort -> Builder.Builder
+smt2Sort msg = go
+  where
+    go s@(FFunc _ _)             = errorstar $ unwords ["smt2 FFunc:", showpp msg, showpp s]
+    go FInt                      = "Int"
+    go FReal                     = "Real"
+    go t
+      | t == boolSort            = "Bool"
+    go t
+      | Just d <- Thy.smt2Sort t = d
+    go _                         = "Int"
+
+instance SMTLIB2 Symbol where
+  smt2 s
+    | Just t <- Thy.smt2Symbol s = t
+  smt2 s                         = Builder.fromText $ symbolSafeText  s
+
+instance SMTLIB2 SymConst where
+  smt2 = smt2 . symbol
+
+instance SMTLIB2 Constant where
+  smt2 (I n)   = build "{}" (Only n)
+  smt2 (R d)   = build "{}" (Only d)
+  smt2 (L t _) = build "{}" (Only t)
+
+instance SMTLIB2 LocSymbol where
+  smt2 = smt2 . val
+
+instance SMTLIB2 Bop where
+  smt2 Plus   = "+"
+  smt2 Minus  = "-"
+  smt2 Times  = Builder.fromText $ symbolSafeText mulFuncName
+  smt2 Div    = Builder.fromText $ symbolSafeText divFuncName
+  smt2 RTimes = "*"
+  smt2 RDiv   = "/"
+  smt2 Mod    = "mod"
+
+instance SMTLIB2 Brel where
+  smt2 Eq    = "="
+  smt2 Ueq   = "="
+  smt2 Gt    = ">"
+  smt2 Ge    = ">="
+  smt2 Lt    = "<"
+  smt2 Le    = "<="
+  smt2 _     = errorstar "SMTLIB2 Brel"
+
+-- NV TODO: change the way EApp is printed
+instance SMTLIB2 Expr where
+  smt2 (ESym z)         = smt2 z
+  smt2 (ECon c)         = smt2 c
+  smt2 (EVar x)         = smt2 x
+  smt2 e@(EApp _ _)     = smt2App e
+  smt2 (ENeg e)         = build "(- {})" (Only $ smt2 e)
+  smt2 (EBin o e1 e2)   = build "({} {} {})" (smt2 o, smt2 e1, smt2 e2)
+  smt2 (EIte e1 e2 e3)  = build "(ite {} {} {})" (smt2 e1, smt2 e2, smt2 e3)
+  smt2 (ECst e _)       = smt2 e
+  smt2 (PTrue)          = "true"
+  smt2 (PFalse)         = "false"
+  smt2 (PAnd [])        = "true"
+  smt2 (PAnd ps)        = build "(and {})"   (Only $ smt2s ps)
+  smt2 (POr [])         = "false"
+  smt2 (POr ps)         = build "(or  {})"   (Only $ smt2s ps)
+  smt2 (PNot p)         = build "(not {})"   (Only $ smt2  p)
+  smt2 (PImp p q)       = build "(=> {} {})" (smt2 p, smt2 q)
+  smt2 (PIff p q)       = build "(= {} {})"  (smt2 p, smt2 q)
+  smt2 (PExist [] p)    = smt2 p
+  smt2 (PExist bs p)    = build "(exists ({}) {})"  (smt2s bs, smt2 p)
+  smt2 (PAll   [] p)    = smt2 p
+  smt2 (PAll   bs p)    = build "(forall ({}) {})"  (smt2s bs, smt2 p)
+
+  smt2 (PAtom r e1 e2)  = mkRel r e1 e2
+  smt2 (ELam (x, _) e)  = smt2Lam x e
+  smt2  e               = errorstar ("smtlib2 Pred  " ++ show e)
+
+
+smt2Lam :: Symbol -> Expr -> Builder.Builder
+smt2Lam x e = build "({} {} {})" (smt2 lambdaName, smt2 x, smt2 e)
+
+smt2App :: Expr -> Builder.Builder
+smt2App e = fromMaybe (build "({} {})" (smt2 f, smt2s es)) $ Thy.smt2App (eliminate f) $ map smt2 es
+  where
+    (f, es) = splitEApp' e
+
+
+splitEApp' :: Expr -> (Expr, [Expr])
+splitEApp'            = go []
+  where
+    go acc (EApp f e) = go (e:acc) f
+    go acc (ECst e _) = go acc e
+    go acc e          = (e, acc)
+
+eliminate :: Expr -> Expr
+eliminate (ECst e _) = eliminate e
+eliminate e          = e
+
+mkRel :: Brel -> Expr -> Expr -> Builder.Builder
+mkRel Ne  e1 e2 = mkNe e1 e2
+mkRel Une e1 e2 = mkNe e1 e2
+mkRel r   e1 e2 = build "({} {} {})" (smt2 r, smt2 e1, smt2 e2)
+
+mkNe :: Expr -> Expr -> Builder.Builder
+mkNe  e1 e2              = build "(not (= {} {}))" (smt2 e1, smt2 e2)
+
+instance SMTLIB2 Command where
+  -- NIKI TODO: formalize this transformation
+  smt2 c@(Declare x ts t)  = build "(declare-fun {} ({}) {})"     (smt2 x, smt2many (smt2Sort c <$> ts), smt2Sort c t) -- HEREHEREHERE (smt2 x, smt2s ts, smt2 t)
+  smt2 c@(Define t)        = build "(declare-sort {})"            (Only $ smt2Sort c t)
+  smt2 (Assert Nothing p)  = build "(assert {})"                  (Only $ smt2 p)
+  smt2 (Assert (Just i) p) = build "(assert (! {} :named p-{}))"  (smt2 p, i)
+  smt2 (Distinct az)
+    -- Distinct must have at least 2 arguments
+    | length az < 2        = ""
+    | otherwise            = build "(assert (distinct {}))"       (Only $ smt2s az)
+  smt2 (AssertAxiom t)     = build "(assert {})"                  (Only $ smt2 t)
+  smt2 (Push)              = "(push 1)"
+  smt2 (Pop)               = "(pop 1)"
+  smt2 (CheckSat)          = "(check-sat)"
+  smt2 (GetValue xs)       = "(get-value (" <> smt2s xs <> "))"
+  smt2 (CMany cmds)        = smt2many (smt2 <$> cmds)
+
+instance SMTLIB2 (Triggered Expr) where
+  smt2 (TR NoTrigger e)       = smt2 e  
+  smt2 (TR _ (PExist [] p))   = smt2 p
+  smt2 t@(TR _ (PExist bs p)) = build "(exists ({}) (! {} :pattern({})))"  (smt2s bs, smt2 p, smt2s $ makeTriggers t)
+  smt2 (TR _ (PAll   [] p))   = smt2 p
+  smt2 t@(TR _ (PAll   bs p)) = build "(forall ({}) (! {} :pattern({})))"  (smt2s bs, smt2 p, smt2s $ makeTriggers t)
+  smt2 (TR _ e)               = smt2 e
+
+
+
+{-# INLINE smt2s #-}
+smt2s    :: SMTLIB2 a => [a] -> Builder.Builder
+smt2s as = smt2many (map smt2 as)
+
+smt2many :: [Builder.Builder] -> Builder.Builder
+smt2many []     = mempty
+smt2many [b]    = b
+smt2many (b:bs) = b <> mconcat [ " " <> b | b <- bs ]
+{-# INLINE smt2many #-}
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Smt/Theories.hs b/liquid-fixpoint/src/Language/Fixpoint/Smt/Theories.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Smt/Theories.hs
@@ -0,0 +1,417 @@
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE UndecidableInstances      #-}
+{-# LANGUAGE PatternGuards             #-}
+
+module Language.Fixpoint.Smt.Theories
+     (
+       -- * Convert theory applications TODO: merge with smt2symbol
+       smt2App
+       -- * Convert theory sorts
+     , smt2Sort
+       -- * Convert theory symbols
+     , smt2Symbol
+       -- * Preamble to initialize SMT
+     , preamble
+
+       -- * Bit Vector Operations
+     , sizeBv
+     , toInt
+
+       -- * Theory Symbols
+     , theorySymbols
+     , theorySEnv
+
+     -- * String
+     -- , string
+     -- , genLen
+
+       -- * Theories
+     , setEmpty, setEmp, setCap, setSub, setAdd, setMem
+     , setCom, setCup, setDif, setSng, mapSel, mapSto
+
+      -- * Query Theories
+     , isSmt2App
+     , isConName
+     , axiomLiterals
+     ) where
+
+import           Prelude hiding (map)
+import           Language.Fixpoint.Types.Sorts
+import           Language.Fixpoint.Types.Config
+import           Language.Fixpoint.Types
+import           Language.Fixpoint.Smt.Types
+import qualified Data.HashMap.Strict      as M
+import           Data.Maybe (catMaybes, isJust)
+import           Data.Monoid
+import qualified Data.Text.Lazy           as T
+import qualified Data.Text.Lazy.Builder   as Builder
+import           Data.Text.Format
+import qualified Data.Text
+import           Data.String                 (IsString(..))
+
+--------------------------------------------------------------------------
+-- | Set Theory ----------------------------------------------------------
+--------------------------------------------------------------------------
+
+elt, set, map :: Raw
+elt  = "Elt"
+set  = "Set"
+map  = "Map"
+
+emp, add, cup, cap, mem, dif, sub, com, sel, sto :: Raw
+emp   = "smt_set_emp"
+add   = "smt_set_add"
+cup   = "smt_set_cup"
+cap   = "smt_set_cap"
+mem   = "smt_set_mem"
+dif   = "smt_set_dif"
+sub   = "smt_set_sub"
+com   = "smt_set_com"
+sel   = "smt_map_sel"
+sto   = "smt_map_sto"
+
+setEmpty, setEmp, setCap, setSub, setAdd, setMem, setCom, setCup, setDif, setSng, mapSel, mapSto :: Symbol
+setEmpty = "Set_empty"
+setEmp   = "Set_emp"
+setCap   = "Set_cap"
+setSub   = "Set_sub"
+setAdd   = "Set_add"
+setMem   = "Set_mem"
+setCom   = "Set_com"
+setCup   = "Set_cup"
+setDif   = "Set_dif"
+setSng   = "Set_sng"
+mapSel   = "Map_select"
+mapSto   = "Map_store"
+
+
+strLen, strSubstr, strConcat :: (IsString a) => a -- Symbol
+strLen    = "strLen"
+strSubstr = "subString"
+strConcat = "concatString"
+-- NOPROP genLen :: Symbol
+-- NOPROP genLen = "len"
+
+-- NOPROP strlen, strsubstr, strconcat :: Raw
+-- NOPROP strlen    = "strLen"
+-- NOPROP strsubstr = "subString"
+-- NOPROP strconcat = "concatString"
+
+z3strlen, z3strsubstr, z3strconcat :: Raw
+z3strlen    = "str.len"
+z3strsubstr = "str.substr"
+z3strconcat = "str.++"
+
+strLenSort, substrSort, concatstrSort :: Sort
+strLenSort    = FFunc strSort intSort
+substrSort    = mkFFunc 0 [strSort, intSort, intSort, strSort]
+concatstrSort = mkFFunc 0 [strSort, strSort, strSort]
+
+string :: Raw
+string = strConName
+
+z3Preamble :: Config -> [T.Text]
+z3Preamble u
+  = stringPreamble u ++
+    [ format "(define-sort {} () Int)"
+        (Only elt)
+    , format "(define-sort {} () (Array {} Bool))"
+        (set, elt)
+    , format "(define-fun {} () {} ((as const {}) false))"
+        (emp, set, set)
+    , format "(define-fun {} ((x {}) (s {})) Bool (select s x))"
+        (mem, elt, set)
+    , format "(define-fun {} ((s {}) (x {})) {} (store s x true))"
+        (add, set, elt, set)
+    , format "(define-fun {} ((s1 {}) (s2 {})) {} ((_ map or) s1 s2))"
+        (cup, set, set, set)
+    , format "(define-fun {} ((s1 {}) (s2 {})) {} ((_ map and) s1 s2))"
+        (cap, set, set, set)
+    , format "(define-fun {} ((s {})) {} ((_ map not) s))"
+        (com, set, set)
+    , format "(define-fun {} ((s1 {}) (s2 {})) {} ({} s1 ({} s2)))"
+        (dif, set, set, set, cap, com)
+    , format "(define-fun {} ((s1 {}) (s2 {})) Bool (= {} ({} s1 s2)))"
+        (sub, set, set, emp, dif)
+    , format "(define-sort {} () (Array {} {}))"
+        (map, elt, elt)
+    , format "(define-fun {} ((m {}) (k {})) {} (select m k))"
+        (sel, map, elt, elt)
+    , format "(define-fun {} ((m {}) (k {}) (v {})) {} (store m k v))"
+        (sto, map, elt, elt, map)
+    , format "(define-fun {} ((b Bool)) Int (ite b 1 0))"
+        (Only (boolToIntName :: T.Text))
+    , uifDef u (symbolText mulFuncName) ("*"   :: T.Text)
+    , uifDef u (symbolText divFuncName) "div"
+    ]
+
+-- RJ: Am changing this to `Int` not `Real` as (1) we usually want `Int` and
+-- (2) have very different semantics. TODO: proper overloading, post genEApp
+uifDef :: Config -> Data.Text.Text -> T.Text -> T.Text
+uifDef cfg f op
+  | linear cfg || Z3 /= solver cfg
+  = format "(declare-fun {} (Int Int) Int)" (Only f)
+  | otherwise
+  = format "(define-fun {} ((x Int) (y Int)) Int ({} x y))" (f, op)
+
+cvc4Preamble :: Config -> [T.Text]
+cvc4Preamble _ --TODO use uif flag u (see z3Preamble)
+  = [        "(set-logic ALL_SUPPORTED)"
+    , format "(define-sort {} () Int)"       (Only elt)
+    , format "(define-sort {} () Int)"       (Only set)
+    , format "(define-sort {} () Int)"       (Only string)
+    , format "(declare-fun {} () {})"        (emp, set)
+    , format "(declare-fun {} ({} {}) {})"   (add, set, elt, set)
+    , format "(declare-fun {} ({} {}) {})"   (cup, set, set, set)
+    , format "(declare-fun {} ({} {}) {})"   (cap, set, set, set)
+    , format "(declare-fun {} ({} {}) {})"   (dif, set, set, set)
+    , format "(declare-fun {} ({} {}) Bool)" (sub, set, set)
+    , format "(declare-fun {} ({} {}) Bool)" (mem, elt, set)
+    , format "(define-sort {} () (Array {} {}))"
+        (map, elt, elt)
+    , format "(define-fun {} ((m {}) (k {})) {} (select m k))"
+        (sel, map, elt, elt)
+    , format "(define-fun {} ((m {}) (k {}) (v {})) {} (store m k v))"
+        (sto, map, elt, elt, map)
+    , format "(define-fun {} ((b Bool)) Int (ite b 1 0))"
+        (Only (boolToIntName :: Raw))
+    ]
+
+smtlibPreamble :: Config -> [T.Text]
+smtlibPreamble _ --TODO use uif flag u (see z3Preamble)
+  = [       --  "(set-logic QF_AUFRIA)",
+      format "(define-sort {} () Int)"       (Only elt)
+    , format "(define-sort {} () Int)"       (Only set)
+    , format "(declare-fun {} () {})"        (emp, set)
+    , format "(declare-fun {} ({} {}) {})"   (add, set, elt, set)
+    , format "(declare-fun {} ({} {}) {})"   (cup, set, set, set)
+    , format "(declare-fun {} ({} {}) {})"   (cap, set, set, set)
+    , format "(declare-fun {} ({} {}) {})"   (dif, set, set, set)
+    , format "(declare-fun {} ({} {}) Bool)" (sub, set, set)
+    , format "(declare-fun {} ({} {}) Bool)" (mem, elt, set)
+    , format "(define-sort {} () Int)"       (Only map)
+    , format "(declare-fun {} ({} {}) {})"    (sel, map, elt, elt)
+    , format "(declare-fun {} ({} {} {}) {})" (sto, map, elt, elt, map)
+    , format "(declare-fun {} ({} {} {}) {})" (sto, map, elt, elt, map)
+    , format "(define-fun {} ((b Bool)) Int (ite b 1 0))" (Only (boolToIntName :: Raw))
+    ]
+
+
+stringPreamble :: Config -> [T.Text]
+stringPreamble cfg | stringTheory cfg
+  = [
+      format "(define-sort {} () String)" (Only string)
+    , format "(define-fun {} ((s {})) Int ({} s))"
+        (strLen :: Raw, string, z3strlen)
+    , format "(define-fun {} ((s {}) (i Int) (j Int)) {} ({} s i j))"
+        (strSubstr :: Raw, string, string, z3strsubstr)
+    , format "(define-fun {} ((x {}) (y {})) {} ({} x y))"
+        (strConcat :: Raw, string, string, string, z3strconcat)
+    ]
+stringPreamble _
+  = [
+      format "(define-sort {} () Int)" (Only string)
+    , format "(declare-fun {} ({}) Int)"
+        (strLen :: Raw, string)
+    , format "(declare-fun {} ({} Int Int) {})"
+        (strSubstr :: Raw, string, string)
+    , format "(declare-fun {} ({} {}) {})"
+        (strConcat :: Raw, string, string, string)
+    ]
+
+
+
+-------------------------------------------------------------------------------
+-- | Exported API -------------------------------------------------------------
+-------------------------------------------------------------------------------
+smt2Symbol :: Symbol -> Maybe Builder.Builder
+smt2Symbol x = Builder.fromLazyText . tsRaw <$> M.lookup x theorySymbols
+
+smt2Sort :: Sort -> Maybe Builder.Builder
+smt2Sort (FApp (FTC c) _)
+  | isConName setConName c      = Just $ build "{}" (Only set)
+smt2Sort (FApp (FApp (FTC c) _) _)
+  | isConName mapConName c      = Just $ build "{}" (Only map)
+smt2Sort (FApp (FTC bv) (FTC s))
+  | isConName bitVecName bv
+  , Just n <- sizeBv s          = Just $ build "(_ BitVec {})" (Only n)
+smt2Sort s
+  | isString s                  = Just $ build "{}" (Only string)
+smt2Sort _                      = Nothing
+
+smt2App :: Expr -> [Builder.Builder] -> Maybe Builder.Builder
+smt2App (EVar f) [d]
+  | f == setEmpty = Just $ build "{}"             (Only emp)
+  | f == setEmp   = Just $ build "(= {} {})"      (emp, d)
+  | f == setSng   = Just $ build "({} {} {})"     (add, emp, d)
+smt2App (EVar f) (d:ds)
+  | Just s <- M.lookup f theorySymbols
+  = Just $ build "({} {})" (tsRaw s, d <> mconcat [ " " <> d | d <- ds])
+smt2App _ _           = Nothing
+
+-- isSmt2App :: Expr -> [a] -> Bool
+-- isSmt2App e xs = tracepp ("isSmt2App e := " ++ show e) (isSmt2App' e xs)
+
+isSmt2App :: Expr -> [a] -> Bool
+isSmt2App (EVar f) [_]
+  | f == setEmpty = True
+  | f == setEmp   = True
+  | f == setSng   = True
+isSmt2App (EVar f) _
+  =  isJust $ M.lookup f theorySymbols
+isSmt2App _ _
+  = False
+
+
+preamble :: Config -> SMTSolver -> [T.Text]
+preamble u Z3   = z3Preamble u
+preamble u Cvc4 = cvc4Preamble u
+preamble u _    = smtlibPreamble u
+
+--------------------------------------------------------------------------------
+-- | Converting Non-Int types to Int -------------------------------------------
+--------------------------------------------------------------------------------
+-- toInt :: Expr -> Sort -> Expr
+-- toInt e s = tracepp msg (toInt' e s)
+  -- where
+    -- msg   = "toInt e = " ++ show e ++ ", t = " ++ show s
+
+toInt :: Expr -> Sort -> Expr
+toInt e s
+  |  (FApp (FTC c) _) <- s
+  , isConName setConName c
+  = castWith setToIntName e
+  | (FApp (FApp (FTC c) _) _) <- s
+  , isConName mapConName c
+  = castWith mapToIntName e
+  | (FApp (FTC bv) (FTC s)) <- s
+  , isConName bitVecName bv
+  , Just _ <- sizeBv s
+  = castWith bitVecToIntName e
+  | FTC c <- s
+  , c == boolFTyCon
+  = castWith boolToIntName e
+  | FTC c <- s
+  , c == realFTyCon
+  = castWith realToIntName e
+  | otherwise
+  = e
+
+castWith :: Symbol -> Expr -> Expr
+castWith s = eAppC intSort (EVar s)
+
+--------------------------------------------------------------------------------
+-- | Theory Symbols : `uninterpSEnv` should be disjoint from see `interpSEnv`
+--   to avoid duplicate SMT definitions.  `uninterpSEnv` is for uninterpreted
+--   symbols, and `interpSEnv` is for interpreted symbols.
+--------------------------------------------------------------------------------
+theorySEnv :: SEnv Sort
+theorySEnv = fromListSEnv . M.toList . fmap tsSort $ theorySymbols
+
+-- | `theorySymbols` contains the list of ALL SMT symbols with interpretations,
+--   i.e. which are given via `define-fun` (as opposed to `declare-fun`)
+theorySymbols :: M.HashMap Symbol TheorySymbol
+theorySymbols = M.fromList $ uninterpSymbols ++ interpSymbols
+
+-- isTheorySymbol :: Symbol -> Bool
+-- isTheorySymbol x = M.member x theorySymbols
+
+interpSymbols :: [(Symbol, TheorySymbol)]
+interpSymbols =
+  [ interpSym setEmp   emp  (FAbs 0 $ FFunc (setSort $ FVar 0) boolSort)
+  , interpSym setEmpty emp  (FAbs 0 $ FFunc intSort (setSort $ FVar 0))
+  , interpSym setAdd   add   setBopSort
+  , interpSym setCup   cup   setBopSort
+  , interpSym setCap   cap   setBopSort
+  , interpSym setMem   mem   setMemSort
+  , interpSym setDif   dif   setBopSort
+  , interpSym setSub   sub   setCmpSort
+  , interpSym setCom   com   setCmpSort
+  , interpSym mapSel   sel   mapSelSort
+  , interpSym mapSto   sto   mapStoSort
+  , interpSym bvOrName "bvor"   bvBopSort
+  , interpSym bvAndName "bvand" bvBopSort
+  , interpSym strLen    strLen    strLenSort
+  , interpSym strSubstr strSubstr substrSort
+  , interpSym strConcat strConcat concatstrSort
+  , interpSym boolInt   boolInt   (FFunc boolSort intSort)
+  ]
+  where
+    boolInt    = boolToIntName
+    setBopSort = FAbs 0 $ FFunc (setSort $ FVar 0) $ FFunc (setSort $ FVar 0) (setSort $ FVar 0)
+    setMemSort = FAbs 0 $ FFunc (FVar 0) $ FFunc (setSort $ FVar 0) boolSort
+    setCmpSort = FAbs 0 $ FFunc (setSort $ FVar 0) $ FFunc (setSort $ FVar 0) boolSort
+    mapSelSort = FAbs 0 $ FAbs 1 $ FFunc (mapSort (FVar 0) (FVar 1)) $ FFunc (FVar 0) (FVar 1)
+    mapStoSort = FAbs 0 $ FAbs 1 $ FFunc (mapSort (FVar 0) (FVar 1))
+                                 $ FFunc (FVar 0)
+                                 $ FFunc (FVar 1)
+                                         (mapSort (FVar 0) (FVar 1))
+    bvBopSort  = FFunc bitVecSort $ FFunc bitVecSort bitVecSort
+
+
+interpSym :: Symbol -> Raw -> Sort -> (Symbol, TheorySymbol)
+interpSym x n t = (x, Thy x n t True)
+
+isConName :: Symbol -> FTycon -> Bool
+isConName s = (s ==) . val . fTyconSymbol
+
+sizeBv :: FTycon -> Maybe Int
+sizeBv tc
+  | s == size32Name = Just 32
+  | s == size64Name = Just 64
+  | otherwise       = Nothing
+  where
+    s               = val $ fTyconSymbol tc
+
+uninterpSymbols :: [(Symbol, TheorySymbol)]
+uninterpSymbols = [ (x, uninterpSym x t) | (x, t) <- uninterpSymbols']
+
+uninterpSym :: Symbol -> Sort -> TheorySymbol
+uninterpSym x t =  Thy x (lt x) t False
+  where
+    lt           = T.fromStrict . symbolSafeText
+
+uninterpSymbols' :: [(Symbol, Sort)]
+uninterpSymbols' =
+  [ (setToIntName,    FFunc (setSort intSort)   intSort)
+  , (bitVecToIntName, FFunc bitVecSort intSort)
+  , (mapToIntName,    FFunc (mapSort intSort intSort) intSort)
+  , (realToIntName,   FFunc realSort   intSort)
+  , (lambdaName   ,   FFunc intSort (FFunc intSort intSort))
+  ]
+  ++ concatMap makeApplies [1..maxLamArg]
+  ++ [(makeLamArg s i, s) | i <- [1..maxLamArg], s <- sorts]
+
+-- THESE ARE DUPLICATED IN DEFUNCTIONALIZATION
+maxLamArg :: Int
+maxLamArg = 7
+
+sorts :: [Sort]
+sorts = [intSort]
+
+-- NIKI TODO: allow non integer lambda arguments
+-- sorts = [setSort intSort, bitVecSort intSort, mapSort intSort intSort, boolSort, realSort, intSort]
+
+makeLamArg :: Sort -> Int  -> Symbol
+makeLamArg _ = intArgName
+
+makeApplies :: Int -> [(Symbol, Sort)]
+makeApplies i =
+  [ (intApplyName i,    go i intSort)
+  , (setApplyName i,    go i (setSort intSort))
+  , (bitVecApplyName i, go i bitVecSort)
+  , (mapApplyName i,    go i $ mapSort intSort intSort)
+  , (realApplyName i,   go i realSort)
+  , (boolApplyName i,   go i boolSort)
+  ]
+  where
+    go 0 s = FFunc intSort s
+    go i s = FFunc intSort $ go (i-1) s
+
+axiomLiterals :: [(Symbol, Sort)] -> [Expr]
+axiomLiterals lts = catMaybes [ lenAxiom l <$> litLen l | (l, t) <- lts, isString t ]
+  where
+    lenAxiom l n  = EEq (EApp (expr (strLen :: Symbol)) (expr l)) (expr n `ECst` intSort)
+    litLen        = fmap (Data.Text.length .  symbolText) . unLitSymbol
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Smt/Types.hs b/liquid-fixpoint/src/Language/Fixpoint/Smt/Types.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Smt/Types.hs
@@ -0,0 +1,121 @@
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE UndecidableInstances      #-}
+
+-- | This module contains the types defining an SMTLIB2 interface.
+
+module Language.Fixpoint.Smt.Types (
+
+    -- * Serialized Representation
+      Raw
+    , symbolBuilder
+
+    -- * Commands
+    , Command  (..)
+
+    -- * Responses
+    , Response (..)
+
+    -- * Typeclass for SMTLIB2 conversion
+    , SMTLIB2 (..)
+    , runSmt2
+
+    -- * SMTLIB2 Process Context
+    , Context (..)
+
+    -- * Theory Symbol
+    , TheorySymbol (..)
+    , SMTEnv
+    ) where
+
+import           Language.Fixpoint.Types
+-- import           Language.Fixpoint.Misc   (traceShow)
+import qualified Data.Text                as T
+import qualified Data.Text.Lazy           as LT
+import qualified Data.Text.Lazy.Builder   as LT
+import           Text.PrettyPrint.HughesPJ 
+
+import           System.IO                (Handle)
+import           System.Process
+
+--------------------------------------------------------------------------------
+-- | Types ---------------------------------------------------------------------
+--------------------------------------------------------------------------------
+type Raw          = LT.Text
+
+symbolBuilder :: Symbol -> LT.Builder
+symbolBuilder = LT.fromText . symbolSafeText
+
+-- | Commands issued to SMT engine
+data Command      = Push
+                  | Pop
+                  | CheckSat
+                  | Declare   !Symbol [Sort] !Sort
+                  | Define    !Sort
+                  | Assert    !(Maybe Int) !Expr
+                  | AssertAxiom  !(Triggered Expr)
+                  | Distinct  [Expr] -- {v:[Expr] | 2 <= len v}
+                  | GetValue  [Symbol]
+                  | CMany [Command]
+                  deriving (Eq, Show)
+
+instance PPrint Command where
+  pprintTidy _ = ppCmd
+
+ppCmd :: Command -> Doc
+ppCmd Push          = text "Push"
+ppCmd Pop           = text "Pop"
+ppCmd CheckSat      = text "CheckSat"
+ppCmd (Declare {})  = text "Declare ..."
+ppCmd (Define {})   = text "Define ..."
+ppCmd (Assert _ e)  = text "Assert" <+> pprint e
+ppCmd (AssertAxiom _) = text "AssertAxiom ..."
+ppCmd (Distinct {}) = text "Distinct ..."
+ppCmd (GetValue {}) = text "GetValue ..."
+ppCmd (CMany {})    = text "CMany ..."
+
+-- | Responses received from SMT engine
+data Response     = Ok
+                  | Sat
+                  | Unsat
+                  | Unknown
+                  | Values [(Symbol, T.Text)]
+                  | Error !T.Text
+                  deriving (Eq, Show)
+
+-- | Information about the external SMT process
+data Context = Ctx
+  { ctxPid     :: !ProcessHandle
+  , ctxCin     :: !Handle
+  , ctxCout    :: !Handle
+  , ctxLog     :: !(Maybe Handle)
+  , ctxVerbose :: !Bool
+  , ctxExt     :: !Bool              -- ^ flag to enable function extentionality axioms
+  , ctxAeq     :: !Bool              -- ^ flag to enable lambda a-equivalence axioms
+  , ctxBeq     :: !Bool              -- ^ flag to enable lambda b-equivalence axioms
+  , ctxNorm    :: !Bool              -- ^ flag to enable lambda normal form equivalence axioms
+  , ctxSmtEnv  :: !SMTEnv
+  }
+
+type SMTEnv = SEnv Sort
+
+-- | Theory Symbol
+data TheorySymbol  = Thy
+  { tsSym    :: !Symbol    -- ^ name
+  , tsRaw    :: !Raw       -- ^ serialized SMTLIB2 name
+  , tsSort   :: !Sort      -- ^ sort
+  , tsInterp :: !Bool      -- ^ TRUE = defined (interpreted), FALSE = declared (uninterpreted)
+  }
+  deriving (Eq, Ord, Show)
+
+--------------------------------------------------------------------------------
+-- | AST Conversion: Types that can be serialized ------------------------------
+--------------------------------------------------------------------------------
+
+class SMTLIB2 a where
+  smt2 :: a -> LT.Builder
+
+runSmt2 :: (SMTLIB2 a) => a -> LT.Builder
+runSmt2 = smt2
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver.hs
@@ -0,0 +1,235 @@
+-- | This module implements the top-level API for interfacing with Fixpoint
+--   In particular it exports the functions that solve constraints supplied
+--   either as .fq files or as FInfo.
+{-# LANGUAGE BangPatterns        #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Language.Fixpoint.Solver (
+    -- * Invoke Solver on an FInfo
+    solve, Solver
+
+    -- * Invoke Solver on a .fq file
+  , solveFQ
+
+    -- * Function to determine outcome
+  , resultExit
+
+    -- * Parse Qualifiers from File
+  , parseFInfo
+) where
+
+import           Control.Concurrent
+import           Data.Binary
+import           System.Exit                        (ExitCode (..))
+import           System.Console.CmdArgs.Verbosity   (whenNormal)
+import           Text.PrettyPrint.HughesPJ          (render)
+import           Control.Monad                      (when)
+import           Control.Exception                  (catch)
+import           Language.Fixpoint.Solver.Sanitize  (symbolEnv, sanitize)
+import           Language.Fixpoint.Solver.UniqifyBinds (renameAll)
+import           Language.Fixpoint.Defunctionalize (defunctionalize)
+import           Language.Fixpoint.SortCheck            (Elaborate (..))
+import           Language.Fixpoint.Solver.UniqifyKVars (wfcUniqify)
+import qualified Language.Fixpoint.Solver.Solve     as Sol
+import           Language.Fixpoint.Types.Config
+import           Language.Fixpoint.Types.Errors
+import           Language.Fixpoint.Utils.Files            hiding (Result)
+import           Language.Fixpoint.Misc
+import           Language.Fixpoint.Utils.Statistics (statistics)
+import           Language.Fixpoint.Graph
+import           Language.Fixpoint.Parse            (rr')
+import           Language.Fixpoint.Types
+import           Language.Fixpoint.Minimize (minQuery, minQuals, minKvars)
+import           Language.Fixpoint.Solver.Instantiate (instantiateFInfo)
+import           Language.Fixpoint.Smt.Interface (makeSmtContext, smtPush)
+import           Control.DeepSeq
+
+---------------------------------------------------------------------------
+-- | Solve an .fq file ----------------------------------------------------
+---------------------------------------------------------------------------
+solveFQ :: Config -> IO ExitCode
+---------------------------------------------------------------------------
+solveFQ cfg = do
+    (fi, opts) <- readFInfo file
+    cfg'       <- withPragmas cfg opts
+    let fi'     = ignoreQualifiers cfg' fi
+    r          <- solve cfg' fi'
+    let stat    = resStatus $!! r
+    -- let str  = render $ resultDoc $!! (const () <$> stat)
+    -- putStrLn "\n"
+    whenNormal $ colorStrLn (colorResult stat) (statStr $!! stat)
+    return $ eCode r
+  where
+    file    = srcFile      cfg
+    eCode   = resultExit . resStatus
+    statStr = render . resultDoc . fmap fst
+
+ignoreQualifiers :: Config -> FInfo a -> FInfo a
+ignoreQualifiers cfg fi
+  | eliminate cfg == All = fi { quals = [] }
+  | otherwise            = fi
+
+
+--------------------------------------------------------------------------------
+-- | Solve FInfo system of horn-clause constraints -----------------------------
+--------------------------------------------------------------------------------
+solve :: (NFData a, Fixpoint a) => Solver a
+--------------------------------------------------------------------------------
+solve cfg q
+  | parts cfg      = partition  cfg        $!! q
+  | stats cfg      = statistics cfg        $!! q
+  | minimize cfg   = minQuery   cfg solve' $!! q
+  | minimizeQs cfg = minQuals cfg solve'   $!! q
+  | minimizeKs cfg = minKvars cfg solve'   $!! q
+  | otherwise      = solve'     cfg        $!! q
+
+solve' :: (NFData a, Fixpoint a) => Solver a
+solve' cfg q = do
+  when (save cfg) $ saveQuery   cfg q
+  configSW  cfg     solveNative cfg q
+
+configSW :: (NFData a, Fixpoint a) => Config -> Solver a -> Solver a
+configSW cfg
+  | multicore cfg = solveParWith
+  | otherwise     = solveSeqWith
+
+--------------------------------------------------------------------------------
+readFInfo :: FilePath -> IO (FInfo (), [String])
+--------------------------------------------------------------------------------
+readFInfo f
+  | isBinary f = (,) <$> readBinFq f <*> return []
+  | otherwise  = readFq f
+
+readFq :: FilePath -> IO (FInfo (), [String])
+readFq file = do
+  str   <- readFile file
+  let q  = {-# SCC "parsefq" #-} rr' file str :: FInfoWithOpts ()
+  return (fioFI q, fioOpts q)
+
+readBinFq :: FilePath -> IO (FInfo ())
+readBinFq file = {-# SCC "parseBFq" #-} decodeFile file
+
+--------------------------------------------------------------------------------
+-- | Solve in parallel after partitioning an FInfo to indepdendant parts
+--------------------------------------------------------------------------------
+solveSeqWith :: (Fixpoint a) => Solver a -> Solver a
+solveSeqWith s c fi0 = {- withProgressFI fi $ -} s c fi
+  where
+    fi               = slice c fi0
+
+--------------------------------------------------------------------------------
+-- | Solve in parallel after partitioning an FInfo to indepdendant parts
+--------------------------------------------------------------------------------
+solveParWith :: (Fixpoint a) => Solver a -> Solver a
+--------------------------------------------------------------------------------
+solveParWith s c fi0 = do
+  -- putStrLn "Using Parallel Solver \n"
+  let fi    = slice c fi0
+  mci      <- mcInfo c
+  let fis   = partition' (Just mci) fi
+  writeLoud $ "Number of partitions : " ++ show (length fis)
+  writeLoud $ "number of cores      : " ++ show (cores c)
+  writeLoud $ "minimum part size    : " ++ show (minPartSize c)
+  writeLoud $ "maximum part size    : " ++ show (maxPartSize c)
+  case fis of
+    []        -> errorstar "partiton' returned empty list!"
+    [onePart] -> s c onePart
+    _         -> inParallelUsing (f s c) $ zip [1..] fis
+    where
+      f s c (j, fi) = s (c {srcFile = queryFile (Part j) c}) fi
+
+--------------------------------------------------------------------------------
+-- | Solve a list of FInfos using the provided solver function in parallel
+--------------------------------------------------------------------------------
+inParallelUsing :: (a -> IO (Result b)) -> [a] -> IO (Result b)
+--------------------------------------------------------------------------------
+inParallelUsing f xs = do
+   setNumCapabilities (length xs)
+   rs <- asyncMapM f xs
+   return $ mconcat rs
+
+--------------------------------------------------------------------------------
+-- | Native Haskell Solver -----------------------------------------------------
+--------------------------------------------------------------------------------
+solveNative, solveNative' :: (NFData a, Fixpoint a) => Solver a
+--------------------------------------------------------------------------------
+solveNative !cfg !fi0 = (solveNative' cfg fi0)
+                          `catch`
+                             (return . result)
+
+result :: Error -> Result a
+result e = Result (Crash [] msg) mempty mempty
+  where
+    msg  = showpp e
+
+loudDump :: (Fixpoint a) => Int -> Config -> SInfo a -> IO ()
+loudDump i cfg si = writeLoud $ msg ++ render (toFixpoint cfg si)
+  where
+    msg           = "fq file after Uniqify & Rename " ++ show i ++ "\n"
+
+solveNative' !cfg !fi0 = do
+  -- writeLoud $ "fq file in: \n" ++ render (toFixpoint cfg fi)
+  -- rnf fi0 `seq` donePhase Loud "Read Constraints"
+  -- let qs   = quals fi0
+  -- whenLoud $ print qs
+  -- TODO: make this less of a hack
+  ctx <- makeSmtContext cfg (srcFile cfg ++ ".evals") []
+  smtPush ctx
+  fi1 <- instantiateFInfo cfg ctx $ fi0 { quals = remakeQual <$> quals fi0 }
+  -- whenLoud $ putStrLn $ showFix (quals fi1)
+  let si0   = {-# SCC "convertFormat" #-} convertFormat fi1
+  -- writeLoud $ "fq file after format convert: \n" ++ render (toFixpoint cfg si0)
+  -- rnf si0 `seq` donePhase Loud "Format Conversion"
+  let si1 = either die id $ {-# SCC "sanitize" #-} sanitize $!! si0
+  -- writeLoud $ "fq file after sanitize: \n" ++ render (toFixpoint cfg si1)
+  -- rnf si1 `seq` donePhase Loud "Validated Constraints"
+  graphStatistics cfg si1
+  let si2  = {-# SCC "wfcUniqify" #-} wfcUniqify $!! si1
+  let si3  = {-# SCC "renameAll"  #-} renameAll  $!! si2
+  rnf si3 `seq` donePhase Loud "Uniqify & Rename"
+  loudDump 1 cfg si3
+  let si4  = {-# SCC "defunction" #-} defunctionalize cfg $!! si3
+  -- putStrLn $ "AXIOMS: " ++ showpp (asserts si4)
+  loudDump 2 cfg si4
+  let si5  = {-# SCC "elaborate"  #-} elaborate "solver" (symbolEnv cfg si4) si4
+  loudDump 3 cfg si5
+  res <- {-# SCC "Sol.solve" #-} Sol.solve cfg $!! si5
+  -- rnf soln `seq` donePhase Loud "Solve2"
+  --let stat = resStatus res
+  saveSolution cfg res
+  -- when (save cfg) $ saveSolution cfg
+  -- writeLoud $ "\nSolution:\n"  ++ showpp (resSolution res)
+  -- colorStrLn (colorResult stat) (show stat)
+  return res
+
+--------------------------------------------------------------------------------
+-- | Extract ExitCode from Solver Result ---------------------------------------
+--------------------------------------------------------------------------------
+resultExit :: FixResult a -> ExitCode
+--------------------------------------------------------------------------------
+resultExit Safe        = ExitSuccess
+resultExit (Unsafe _)  = ExitFailure 1
+resultExit _           = ExitFailure 2
+
+--------------------------------------------------------------------------------
+-- | Parse External Qualifiers -------------------------------------------------
+--------------------------------------------------------------------------------
+parseFInfo :: [FilePath] -> IO (FInfo a)
+--------------------------------------------------------------------------------
+parseFInfo fs = mconcat <$> mapM parseFI fs
+
+parseFI :: FilePath -> IO (FInfo a)
+parseFI f = do
+  str   <- readFile f
+  let fi = rr' f str :: FInfo ()
+  return $ mempty { quals = quals  fi
+                  , gLits = gLits  fi
+                  , dLits = dLits  fi }
+
+saveSolution :: Config -> Result a -> IO ()
+saveSolution cfg res = when (save cfg) $ do
+  let f = queryFile Out cfg
+  putStrLn $ "Saving Solution: " ++ f ++ "\n"
+  ensurePath f
+  writeFile f $ "\nSolution:\n" ++ showpp (resSolution  res)
+                ++ (if (gradual cfg) then ("\n\n" ++ showpp (gresSolution res)) else mempty)
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/Eliminate.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/Eliminate.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/Eliminate.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE FlexibleContexts     #-}
+
+-- | This module exports a single function that computes the dependency
+-- information needed to eliminate non-cut KVars, and then transitively
+-- collapse the resulting constraint dependencies.
+-- See the type of `SolverInfo` for details.
+
+module Language.Fixpoint.Solver.Eliminate (solverInfo) where
+
+import qualified Data.HashSet        as S
+import qualified Data.HashMap.Strict as M
+
+import           Language.Fixpoint.Types.Config    (Config)
+import qualified Language.Fixpoint.Types.Solutions as Sol
+import           Language.Fixpoint.Types
+import           Language.Fixpoint.Types.Visitor   (kvars, isConcC)
+import           Language.Fixpoint.Graph
+import           Language.Fixpoint.Misc            (safeLookup, group, errorstar)
+import           Language.Fixpoint.Solver.Sanitize
+
+--------------------------------------------------------------------------------
+-- | `solverInfo` constructs a `SolverInfo` comprising the Solution and various
+--   indices needed by the worklist-based refinement loop
+--------------------------------------------------------------------------------
+solverInfo :: Config -> SInfo a -> SolverInfo a b
+--------------------------------------------------------------------------------
+solverInfo cfg sI = SI sHyp sI' cD cKs
+  where
+    cD             = elimDeps     sI es nKs
+    sI'            = cutSInfo     sI kI cKs
+    sHyp           = Sol.fromList sE mempty mempty kHyps kS
+    kHyps          = nonCutHyps   sI kI nKs
+    kI             = kIndex       sI
+    (es, cKs, nKs) = kutVars cfg  sI
+    kS             = kvScopes     sI es
+    sE             = symbolEnv   cfg sI
+
+
+--------------------------------------------------------------------------------
+kvScopes :: SInfo a -> [CEdge] -> M.HashMap KVar IBindEnv
+kvScopes sI es = is2env <$> kiM
+  where
+    is2env = foldr1 intersectionIBindEnv . fmap (senv . getSubC sI)
+    kiM    = group $ [(k, i) | (Cstr i, KVar k) <- es ] ++
+                     [(k, i) | (KVar k, Cstr i) <- es ]
+
+--------------------------------------------------------------------------------
+
+cutSInfo :: SInfo a -> KIndex -> S.HashSet KVar -> SInfo a
+cutSInfo si kI cKs = si { ws = ws', cm = cm' }
+  where
+    ws'   = M.filterWithKey (\k _ -> S.member k cKs) (ws si)
+    cm'   = M.filterWithKey (\i c -> S.member i cs || isConcC c) (cm si)
+    cs    = S.fromList      (concatMap kCs cKs)
+    kCs k = M.lookupDefault [] k kI
+
+kutVars :: Config -> SInfo a -> ([CEdge], S.HashSet KVar, S.HashSet KVar)
+kutVars cfg si   = (es, depCuts ds, depNonCuts ds)
+  where
+    (es, ds)     = elimVars cfg si
+
+--------------------------------------------------------------------------------
+-- | Map each `KVar` to the list of constraints on which it appears on RHS
+--------------------------------------------------------------------------------
+type KIndex = M.HashMap KVar [Integer]
+
+--------------------------------------------------------------------------------
+kIndex     :: SInfo a -> KIndex
+--------------------------------------------------------------------------------
+kIndex si  = group [(k, i) | (i, c) <- iCs, k <- rkvars c]
+  where
+    iCs    = M.toList (cm si)
+    rkvars = kvars . crhs
+
+nonCutHyps :: SInfo a -> KIndex -> S.HashSet KVar -> [(KVar, Sol.Hyp)]
+nonCutHyps si kI nKs = [ (k, nonCutHyp kI si k) | k <- S.toList nKs ]
+
+
+nonCutHyp  :: KIndex -> SInfo a -> KVar -> Sol.Hyp
+nonCutHyp kI si k = nonCutCube <$> cs
+  where
+    cs            = getSubC   si <$> M.lookupDefault [] k kI
+
+nonCutCube :: SimpC a -> Sol.Cube
+nonCutCube c = Sol.Cube (senv c) (rhsSubst c) (subcId c) (stag c)
+
+rhsSubst :: SimpC a -> Subst
+rhsSubst             = rsu . crhs
+  where
+    rsu (PKVar _ su) = su
+    rsu _            = errorstar "Eliminate.rhsSubst called on bad input"
+
+getSubC :: SInfo a -> Integer -> SimpC a
+getSubC si i = safeLookup msg i (cm si)
+  where
+    msg = "getSubC: " ++ show i
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/GradualSolution.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/GradualSolution.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/GradualSolution.hs
@@ -0,0 +1,420 @@
+{-# LANGUAGE FlexibleInstances  #-}
+{-# LANGUAGE TupleSections      #-}
+
+module Language.Fixpoint.Solver.GradualSolution
+  ( -- * Create Initial Solution
+    init
+
+    -- * Update Solution
+  , Sol.update
+
+  -- * Lookup Solution
+  , lhsPred
+  ) where
+
+import           Control.Parallel.Strategies
+import           Control.Arrow (second)
+import qualified Data.HashSet                   as S
+import qualified Data.HashMap.Strict            as M
+import qualified Data.List                      as L
+import           Data.Maybe                     (fromMaybe, maybeToList, isNothing, catMaybes)
+import           Data.Monoid                    ((<>))
+import           Language.Fixpoint.Types.PrettyPrint ()
+import           Language.Fixpoint.Types.Visitor      as V
+import qualified Language.Fixpoint.SortCheck          as So
+import           Language.Fixpoint.Misc
+import qualified Language.Fixpoint.Smt.Theories       as Thy
+import           Language.Fixpoint.Types.Config
+import qualified Language.Fixpoint.Types              as F
+import           Language.Fixpoint.Types                 ((&.&))
+import qualified Language.Fixpoint.Types.Solutions    as Sol
+import           Language.Fixpoint.Types.Constraints  hiding (ws, bs)
+import           Prelude                              hiding (init, lookup)
+import           Language.Fixpoint.Solver.Sanitize
+
+
+--------------------------------------------------------------------------------
+-- | Initial Gradual Solution (from Qualifiers and WF constraints) -------------
+--------------------------------------------------------------------------------
+init :: Config -> F.SInfo a -> S.HashSet F.KVar -> Sol.GSolution
+--------------------------------------------------------------------------------
+init cfg si ks = Sol.fromList senv geqs keqs [] mempty
+  where
+    keqs       = map (refine si qs genv)  ws `using` parList rdeepseq
+    geqs       = map (refineG si qs genv) gs `using` parList rdeepseq 
+    qs         = F.quals si
+    ws         = [ w | (k, w) <- ws0, k `S.member` ks]
+    gs         = snd <$> gs0
+    genv       = instConstants si
+    senv       = symbolEnv cfg si
+
+    (gs0,ws0)  = L.partition (isGWfc . snd) $ M.toList (F.ws si)
+
+
+--------------------------------------------------------------------------------
+refineG :: F.SInfo a -> [F.Qualifier] -> F.SEnv F.Sort -> F.WfC a -> (F.KVar, (((F.Symbol,F.Sort), F.Expr), Sol.GBind))
+refineG fi qs genv w = (k, (((fst3 $ wrft w, snd3 $ wrft w), wexpr w), Sol.qbToGb qb))
+  where 
+    (k, qb) = refine fi qs genv w 
+
+refine :: F.SInfo a -> [F.Qualifier] -> F.SEnv F.Sort -> F.WfC a -> (F.KVar, Sol.QBind)
+refine fi qs genv w = refineK (allowHOquals fi) env qs $ F.wrft w
+  where
+    env             = wenv <> genv
+    wenv            = F.sr_sort <$> F.fromListSEnv (F.envCs (F.bs fi) (F.wenv w))
+
+instConstants :: F.SInfo a -> F.SEnv F.Sort
+instConstants = F.fromListSEnv . filter notLit . F.toListSEnv . F.gLits
+  where
+    notLit    = not . F.isLitSymbol . fst
+
+
+refineK :: Bool -> F.SEnv F.Sort -> [F.Qualifier] -> (F.Symbol, F.Sort, F.KVar) -> (F.KVar, Sol.QBind)
+refineK ho env qs (v, t, k) = (k, eqs')
+   where
+    eqs                     = instK ho env v t qs
+    eqs'                    = Sol.qbFilter (okInst env v t) eqs
+
+--------------------------------------------------------------------------------
+instK :: Bool
+      -> F.SEnv F.Sort
+      -> F.Symbol
+      -> F.Sort
+      -> [F.Qualifier]
+      -> Sol.QBind
+--------------------------------------------------------------------------------
+instK ho env v t = Sol.qb . unique . concatMap (instKQ ho env v t)
+  where
+    unique       = L.nubBy ((. Sol.eqPred) . (==) . Sol.eqPred)
+
+instKQ :: Bool
+       -> F.SEnv F.Sort
+       -> F.Symbol
+       -> F.Sort
+       -> F.Qualifier
+       -> [Sol.EQual]
+instKQ ho env v t q
+  = do (su0, v0) <- candidates senv [(t, [v])] qt
+       xs        <- match senv tyss [v0] (So.apply su0 <$> qts)
+       return     $ Sol.eQual q (reverse xs)
+    where
+       qt : qts   = snd <$> F.qParams q
+       tyss       = instCands ho env
+       senv       = (`F.lookupSEnvWithDistance` env)
+
+instCands :: Bool -> F.SEnv F.Sort -> [(F.Sort, [F.Symbol])]
+instCands ho env = filter isOk tyss
+  where
+    tyss      = groupList [(t, x) | (x, t) <- xts]
+    isOk      = if ho then const True else isNothing . F.functionSort . fst
+    xts       = F.toListSEnv env
+
+match :: So.Env -> [(F.Sort, [F.Symbol])] -> [F.Symbol] -> [F.Sort] -> [[F.Symbol]]
+match env tyss xs (t : ts)
+  = do (su, x) <- candidates env tyss t
+       match env tyss (x : xs) (So.apply su <$> ts)
+match _   _   xs []
+  = return xs
+
+--------------------------------------------------------------------------------
+candidates :: So.Env -> [(F.Sort, [F.Symbol])] -> F.Sort -> [(So.TVSubst, F.Symbol)]
+--------------------------------------------------------------------------------
+candidates env tyss tx = 
+    [(su, y) | (t, ys) <- tyss
+             , su      <- maybeToList $ So.unifyFast mono env tx t
+             , y       <- ys                                   ]
+  where
+    mono = So.isMono tx
+
+--------------------------------------------------------------------------------
+okInst :: F.SEnv F.Sort -> F.Symbol -> F.Sort -> Sol.EQual -> Bool
+--------------------------------------------------------------------------------
+okInst env v t eq = isNothing tc
+  where
+    sr            = F.RR t (F.Reft (v, p))
+    p             = Sol.eqPred eq
+    tc            = So.checkSorted env sr 
+
+
+--------------------------------------------------------------------------------
+-- | Predicate corresponding to LHS of constraint in current solution
+--------------------------------------------------------------------------------
+lhsPred :: F.SolEnv -> Sol.GSolution -> F.SimpC a ->  [([(F.KVar, Sol.QBind)], F.Expr)]
+lhsPred be s c = gSelectToList (fst <$> applyGradual g s bs)
+  where
+    g                 = (ci, be, bs)
+    bs                = F.senv c
+    ci                = sid c
+
+type Cid         = Maybe Integer
+type CombinedEnv = (Cid, F.SolEnv, F.IBindEnv)
+type ExprInfo    = (F.Expr, KInfo)
+
+applyGradual        :: CombinedEnv -> Sol.GSolution -> F.IBindEnv -> GSelect ExprInfo
+applyGradual g s bs = mappendGSelect mappendExprInfo pks (applyKVarsGrad g s ks)
+  where
+    pgs           = allCombinations $ applyGVars g s gs
+    pks           = if null gs 
+                        then GNone (F.pAnd ps, mempty) 
+                        else GOpt [(fst (unzip l) , (F.pAnd (ps++snd (unzip l)), mempty)) | l <- pgs ]
+    (ps,  ks, gs) = envConcKVars g bs
+
+    mappendExprInfo (e1, i1) (e2, i2) = (F.pAnd [e1, e2], mappend i1 i2)
+
+
+envConcKVars :: CombinedEnv -> F.IBindEnv -> ([F.Expr], [F.KVSub], [F.KVSub])
+envConcKVars g bs = (concat pss, concat kss, L.nubBy (\x y -> F.ksuKVar x == F.ksuKVar y) $ concat gss)
+  where
+    (pss, kss, gss) = unzip3 [ F.sortedReftConcKVars x sr | (x, sr) <- xrs ]
+    xrs             = (\i -> F.lookupBindEnv i be) <$> is
+    is              = F.elemsIBindEnv bs
+    be              = F.soeBinds (snd3 g)
+
+applyGVars :: CombinedEnv -> Sol.GSolution -> [F.KVSub] -> [[((F.KVar, Sol.QBind), F.Expr)]]
+applyGVars g s = map (applyGVar g s)
+
+
+applyGVar :: CombinedEnv -> Sol.GSolution -> F.KVSub -> [((F.KVar, Sol.QBind), F.Expr)]
+applyGVar g s ksu = case Sol.glookup s (F.ksuKVar ksu) of
+  Right (Right (e,eqss)) -> [((F.ksuKVar ksu, eqs), F.pAnd ((F.subst su (snd e)):(fst <$> Sol.qbPreds msg s su eqs))) | eqs <- Sol.gbToQbs eqss]
+  _                      -> []
+  where
+    msg     = "applyGVar: " ++ show (fst3 g)
+    su      = F.ksuSubst ksu
+
+applyKVarsGrad :: CombinedEnv -> Sol.GSolution -> [F.KVSub] -> GSelect ExprInfo
+applyKVarsGrad g s xs = (f <$> (collapseGSelect $ map (applyKVarGrad g s) xs))
+  where
+    f xs = let (es, is) = unzip xs  in (F.pAnd es, mconcat is)
+
+applyKVarGrad :: CombinedEnv -> Sol.GSolution -> F.KVSub -> GSelect ExprInfo
+applyKVarGrad g s ksu = case Sol.glookup s (F.ksuKVar ksu) of
+  Left cs                -> hypPredGrad g s ksu cs
+  Right (Left eqs)       -> GNone (F.pAnd $ fst <$> Sol.qbPreds msg s (F.ksuSubst ksu) eqs, mempty)
+  Right (Right (e,eqss)) -> GOpt [([(F.ksuKVar ksu, eqs)]
+                                  , (, mempty) $ F.pAnd ((F.subst su (snd e)):(fst <$> Sol.qbPreds msg s su eqs))) 
+                                  | eqs <- Sol.gbToQbs eqss]
+  where
+    msg     = "applyKVar: " ++ show (fst3 g) 
+    su      = F.ksuSubst ksu
+
+
+hypPredGrad :: CombinedEnv -> Sol.GSolution -> F.KVSub -> Sol.Hyp  -> GSelect ExprInfo
+hypPredGrad g s ksu xs = f <$> (collapseGSelect $ map (cubePredGrad g s ksu) xs)
+  where
+    f xs = let (es, is) = unzip xs  in (F.pOr es, mconcatPlus is)
+
+
+{- | `cubePred g s k su c` returns the predicate for
+
+        (k . su)
+
+      defined by using cube
+
+        c := [b1,...,bn] |- (k . su')
+
+      in the binder environment `g`.
+
+        bs' := the subset of "extra" binders in [b1...bn] that are *not* in `g`
+        p'  := the predicate corresponding to the "extra" binders
+
+ -}
+
+elabExist :: Sol.Sol a Sol.QBind -> [(F.Symbol, F.Sort)] -> F.Expr -> F.Expr
+elabExist s xts = F.pExist xts'
+  where
+    xts'        = [ (x, elab t) | (x, t) <- xts]
+    elab        = So.elaborate "elabExist" env
+    env         = Sol.sEnv s
+
+
+cubePredGrad :: CombinedEnv -> Sol.GSolution -> F.KVSub -> Sol.Cube -> GSelect ExprInfo
+cubePredGrad g s ksu c  = ((\((xts,psu,p), kI) -> (elabExist s xts (psu &.& p) , kI)) <$> cubePredExcGrad g s ksu c bs')
+  where
+    bs'               = delCEnv s k bs
+    bs                = Sol.cuBinds c
+    k                 = F.ksuKVar ksu
+
+
+type Binders = [(F.Symbol, F.Sort)]
+
+-- | @cubePredExc@ computes the predicate for the subset of binders bs'.
+--   The output is a tuple, `(xts, psu, p, kI)` such that the actual predicate
+--   we want is `Exists xts. (psu /\ p)`.
+
+
+cubePredExcGrad :: CombinedEnv -> Sol.GSolution -> F.KVSub -> Sol.Cube -> F.IBindEnv
+            -> GSelect ((Binders, F.Pred, F.Pred), KInfo)
+cubePredExcGrad g s ksu c bs' 
+  = f <$> (applyGradual g' s bs')
+  where
+    f (p', kI)      = ((xts, psu, elabExist s yts' (p' &.& psu') ), extendKInfo kI (Sol.cuTag c))
+    yts'            = symSorts g bs'
+    g'              = addCEnv  g bs
+    
+    (_  , psu')     = substElim sEnv g' k su'
+    (xts, psu)      = substElim sEnv g  k su
+    su'             = Sol.cuSubst c
+    bs              = Sol.cuBinds c
+    k               = F.ksuKVar   ksu
+    su              = F.ksuSubst  ksu
+    sEnv            = F.insertSEnv (F.ksuVV ksu) (F.ksuSort ksu) (Sol.sEnv s)
+
+
+-- TODO: SUPER SLOW! Decorate all substitutions with Sorts in a SINGLE pass.
+
+{- | @substElim@ returns the binders that must be existentially quantified,
+     and the equality predicate relating the kvar-"parameters" and their
+     actual values. i.e. given
+
+        K[x1 := e1]...[xn := en]
+
+     where e1 ... en have types t1 ... tn
+     we want to quantify out
+
+       x1:t1 ... xn:tn
+
+     and generate the equality predicate && [x1 ~~ e1, ... , xn ~~ en]
+     we use ~~ because the param and value may have different sorts, see:
+
+        tests/pos/kvar-param-poly-00.hs
+
+     Finally, we filter out binders if they are
+
+     1. "free" in e1...en i.e. in the outer environment.
+        (Hmm, that shouldn't happen...?)
+
+     2. are binders corresponding to sorts (e.g. `a : num`, currently used
+        to hack typeclasses current.)
+ -}
+substElim :: F.SEnv F.Sort -> CombinedEnv -> F.KVar -> F.Subst -> ([(F.Symbol, F.Sort)], F.Pred)
+substElim sEnv g _ (F.Su m) = (xts, p)
+  where
+    p      = F.pAnd [ mkSubst x (substSort sEnv frees x t) e t | (x, e, t) <- xets  ]
+    xts    = [ (x, t)    | (x, _, t) <- xets, not (S.member x frees) ]
+    xets   = [ (x, e, t) | (x, e)    <- xes, t <- sortOf e, not (isClass t)]
+    xes    = M.toList m
+    env    = combinedSEnv g
+    frees  = S.fromList (concatMap (F.syms . snd) xes)
+    sortOf = maybeToList . So.checkSortExpr env
+
+substSort :: F.SEnv F.Sort -> S.HashSet F.Symbol -> F.Symbol -> F.Sort -> F.Sort
+substSort sEnv _frees x _t = fromMaybe (err x) $ F.lookupSEnv x sEnv
+  where
+    err x            = error $ "Solution.mkSubst: unknown binder " ++ F.showpp x
+
+mkSubst :: F.Symbol -> F.Sort -> F.Expr -> F.Sort -> F.Expr
+mkSubst x tx ey ty
+  | tx == ty    = F.EEq ex ey
+  | otherwise   = F.notracepp msg (F.EEq ex' ey')
+  where
+    msg         = "mkSubst-DIFF:" ++ F.showpp (tx, ty) ++ F.showpp (ex', ey')
+    ex          = F.expr x
+    ex'         = Thy.toInt ex tx
+    ey'         = Thy.toInt ey ty
+
+isClass :: F.Sort -> Bool
+isClass F.FNum  = True
+isClass F.FFrac = True
+isClass _       = False
+
+--badExpr :: CombinedEnv -> F.KVar -> F.Expr -> a
+--badExpr g@(i,_,_) k e
+  -- = errorstar $ "substSorts has a badExpr: "
+              -- ++ show e
+              -- ++ " in cid = "
+              -- ++ show i
+              -- ++ " for kvar " ++ show k
+              -- ++ " in env \n"
+              -- ++ show (combinedSEnv g)
+
+-- substPred :: F.Subst -> F.Pred
+-- substPred (F.Su m) = F.pAnd [ F.PAtom F.Eq (F.eVar x) e | (x, e) <- M.toList m]
+
+combinedSEnv :: CombinedEnv -> F.SEnv F.Sort
+combinedSEnv (_, se, bs) = F.sr_sort <$> F.fromListSEnv (F.envCs be bs)
+  where
+    be                   = F.soeBinds se
+
+addCEnv :: CombinedEnv -> F.IBindEnv -> CombinedEnv
+addCEnv (x, be, bs) bs' = (x, be, F.unionIBindEnv bs bs')
+
+-- delCEnv :: F.IBindEnv -> CombinedEnv -> F.IBindEnv
+-- delCEnv bs (_, _, bs')  = F.diffIBindEnv bs bs'
+
+delCEnv :: Sol.Sol a Sol.QBind -> F.KVar -> F.IBindEnv -> F.IBindEnv
+delCEnv s k bs  = F.diffIBindEnv bs _kbs
+                                                -- ORIG: bs'
+  where
+    _kbs = safeLookup "delCEnv" k (Sol.sScp s)
+
+symSorts :: CombinedEnv -> F.IBindEnv -> [(F.Symbol, F.Sort)]
+symSorts (_, se, _) bs = second F.sr_sort <$> F.envCs be  bs
+  where
+    be                 = F.soeBinds se
+
+_noKvars :: F.Expr -> Bool
+_noKvars = null . V.kvars
+
+--------------------------------------------------------------------------------
+-- | Information about size of formula corresponding to an "eliminated" KVar.
+--------------------------------------------------------------------------------
+data KInfo = KI { kiTags  :: [Tag]
+                , kiDepth :: !Int
+                , kiCubes :: !Integer
+                } deriving (Eq, Ord, Show)
+
+instance Monoid KInfo where
+  mempty         = KI [] 0 1
+  mappend ki ki' = KI ts d s
+    where
+      ts         = appendTags (kiTags  ki) (kiTags  ki')
+      d          = max        (kiDepth ki) (kiDepth ki')
+      s          = (*)        (kiCubes ki) (kiCubes ki')
+
+mplus :: KInfo -> KInfo -> KInfo
+mplus ki ki' = (mappend ki ki') { kiCubes = kiCubes ki + kiCubes ki'}
+
+mconcatPlus :: [KInfo] -> KInfo
+mconcatPlus = foldr mplus mempty
+
+appendTags :: [Tag] -> [Tag] -> [Tag]
+appendTags ts ts' = sortNub (ts ++ ts')
+
+extendKInfo :: KInfo -> F.Tag -> KInfo
+extendKInfo ki t = ki { kiTags  = appendTags [t] (kiTags  ki)
+                      , kiDepth = 1  +            kiDepth ki }
+
+
+--------------------------------------------------------------------------------
+-- | Gradual Selection Interface -----------------------------------------------
+--------------------------------------------------------------------------------
+data GSelect a = GNone a | GOpt [([(F.KVar, Sol.QBind)], a)] deriving (Show)
+
+
+gSelectToList :: GSelect a -> [([(F.KVar, Sol.QBind)], a)]
+gSelectToList (GNone a) = [([], a)]
+gSelectToList (GOpt xs) = xs 
+
+
+instance Functor GSelect where
+  fmap f (GNone a) = GNone  (f a)
+  fmap f (GOpt xs) = GOpt [(p, f a) | (p, a) <- xs]
+
+mappendGSelect :: (a -> a -> b) -> GSelect a -> GSelect a -> GSelect b 
+mappendGSelect f (GNone x) (GNone y) = GNone (f x y)
+mappendGSelect f (GNone x) (GOpt ys) = GOpt [(i, f x y) | (i, y) <- ys] 
+mappendGSelect f (GOpt xs) (GNone y) = GOpt [(i, f x y) | (i, x) <- xs]
+mappendGSelect f (GOpt xs) (GOpt ys) = GOpt $ concatMap (\y -> (catMaybes $ map (\x -> g x y) xs)) ys 
+  where
+    g (xs, x) (ys, y)
+      | null [ () | (k1, _) <- xs, (k2, _) <- ys, k1 == k2 ]  
+      =  Just (xs ++ ys, f x y)
+      | and [v1 == v2 | (k1, v1) <- xs, (k2, v2) <- ys, k1 == k2 ] 
+      = Just (xs ++ [(k, v) | (k, v) <- ys, not (k `elem` (fst <$> xs))], f x y)
+      | otherwise
+      = Nothing 
+
+collapseGSelect :: [GSelect a] -> GSelect [a]
+collapseGSelect = foldl (mappendGSelect (\x y -> (x ++ y))) (GNone []) . fmap (fmap (:[]))
+
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/GradualSolve.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/GradualSolve.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/GradualSolve.hs
@@ -0,0 +1,319 @@
+{-# LANGUAGE PatternGuards     #-}
+{-# LANGUAGE TupleSections     #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+--------------------------------------------------------------------------------
+-- | Solve a system of horn-clause constraints ---------------------------------
+--------------------------------------------------------------------------------
+
+module Language.Fixpoint.Solver.GradualSolve (solveGradual) where
+
+import           Control.Monad (when, filterM, foldM)
+import           Control.Monad.State.Strict (lift)
+import           Language.Fixpoint.Misc
+import qualified Language.Fixpoint.Types           as F
+import qualified Language.Fixpoint.Types.Solutions as Sol
+import qualified Language.Fixpoint.SortCheck       as So
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Config hiding (stats)
+import qualified Language.Fixpoint.Solver.GradualSolution  as S
+import qualified Language.Fixpoint.Solver.Worklist  as W
+import qualified Language.Fixpoint.Solver.Eliminate as E
+import           Language.Fixpoint.Solver.Monad
+import           Language.Fixpoint.Utils.Progress
+import           Language.Fixpoint.Graph
+import           Text.PrettyPrint.HughesPJ
+import           Text.Printf
+import           System.Console.CmdArgs.Verbosity (whenNormal, whenLoud)
+import           Control.DeepSeq
+import qualified Data.HashMap.Strict as M
+import qualified Data.HashSet        as S
+
+--------------------------------------------------------------------------------
+-- | Progress Bar
+--------------------------------------------------------------------------------
+withProgressFI :: SolverInfo a b -> IO b -> IO b
+withProgressFI = withProgress . fromIntegral . cNumScc . siDeps
+--------------------------------------------------------------------------------
+
+printStats :: F.SInfo a ->  W.Worklist a -> Stats -> IO ()
+printStats fi w s = putStrLn "\n" >> ppTs [ ptable fi, ptable s, ptable w ]
+  where
+    ppTs          = putStrLn . showpp . mconcat
+
+--------------------------------------------------------------------------------
+solverInfo :: Config -> F.SInfo a -> SolverInfo a b
+--------------------------------------------------------------------------------
+solverInfo cfg fI
+  | useElim cfg = E.solverInfo cfg fI
+  | otherwise   = SI mempty fI cD (siKvars fI)
+  where
+    cD          = elimDeps fI (kvEdges fI) mempty
+
+siKvars :: F.SInfo a -> S.HashSet F.KVar
+siKvars = S.fromList . M.keys . F.ws
+
+
+--------------------------------------------------------------------------------
+-- | tidyResult ensures we replace the temporary kVarArg names introduced to
+--   ensure uniqueness with the original names in the given WF constraints.
+--------------------------------------------------------------------------------
+tidyResult :: F.Result a -> F.Result a
+tidyResult r = r { F.resSolution  =  tidySolution  (F.resSolution r)
+                 , F.gresSolution =  gtidySolution (F.gresSolution r) 
+                 }
+
+tidySolution :: F.FixSolution -> F.FixSolution
+tidySolution = fmap tidyPred
+
+gtidySolution :: F.GFixSolution -> F.GFixSolution
+gtidySolution = fmap tidyPred --  (\(e, es) -> (tidyPred e, tidyPred <$> es))
+
+tidyPred :: F.Expr -> F.Expr
+tidyPred = F.substf (F.eVar . F.tidySymbol)
+
+
+predKs :: F.Expr -> [(F.KVar, F.Subst)]
+predKs (F.PAnd ps)    = concatMap predKs ps
+predKs (F.PKVar k su) = [(k, su)]
+predKs _              = []
+
+
+
+--------------------------------------------------------------------------------
+minimizeResult :: Config -> M.HashMap F.KVar F.Expr
+               -> SolveM (M.HashMap F.KVar F.Expr)
+--------------------------------------------------------------------------------
+minimizeResult cfg s
+  | minimalSol cfg = mapM minimizeConjuncts s
+  | otherwise      = return s
+
+minimizeConjuncts :: F.Expr -> SolveM F.Expr
+minimizeConjuncts p = F.pAnd <$> go (F.conjuncts p) []
+  where
+    go []     acc   = return acc
+    go (p:ps) acc   = do b <- isValid (F.pAnd (acc ++ ps)) p
+                         if b then go ps acc
+                              else go ps (p:acc)
+
+
+
+showUnsat :: Bool -> Integer -> F.Pred -> F.Pred -> IO ()
+showUnsat u i lP rP = {- when u $ -} do
+  putStrLn $ printf   "UNSAT id %s %s" (show i) (show u)
+  putStrLn $ showpp $ "LHS:" <+> pprint lP
+  putStrLn $ showpp $ "RHS:" <+> pprint rP
+
+--------------------------------------------------------------------------------
+-- | Predicate corresponding to RHS of constraint in current solution
+--------------------------------------------------------------------------------
+rhsPred :: F.SimpC a -> F.Expr
+--------------------------------------------------------------------------------
+rhsPred c
+  | isTarget c = F.crhs c
+  | otherwise  = errorstar $ "rhsPred on non-target: " ++ show (F.sid c)
+
+isValid :: F.Expr -> F.Expr -> SolveM Bool
+isValid p q = (not . null) <$> filterValid p [(q, ())]
+
+
+-------------------------------------------------------------------------------
+-- | solve with edits to allow Gradual types ----------------------------------
+-------------------------------------------------------------------------------
+
+solveGradual :: (NFData a, F.Fixpoint a) => Config -> F.SInfo a -> IO (F.Result (Integer, a))
+
+solveGradual cfg fi = do
+    (res, stat) <- withProgressFI sI $ runSolverM cfg sI n act
+    when (solverStats cfg) $ printStats fi wkl stat
+    return res
+  where
+    act  = solveGradual_ cfg fi s0 ks  wkl
+    sI   = solverInfo cfg fi
+    wkl  = W.init sI
+    n    = fromIntegral $ W.wRanks wkl
+    s0   = siSol  sI
+    ks   = siVars sI
+
+--------------------------------------------------------------------------------
+solveGradual_ :: (NFData a, F.Fixpoint a)
+       => Config
+       -> F.SInfo a
+       -> Sol.GSolution 
+       -> S.HashSet F.KVar
+       -> W.Worklist a
+       -> SolveM (F.Result (Integer, a), Stats)
+--------------------------------------------------------------------------------
+solveGradual_ cfg fi s0 ks wkl = do
+  let s1  = mappend s0 $ {-# SCC "sol-init" #-} S.init cfg fi ks
+  s2      <- {-# SCC "sol-local"  #-} filterLocal s1
+  s       <- {-# SCC "sol-refine" #-} refine s2 wkl
+  res     <- {-# SCC "sol-result" #-} result cfg wkl s
+  st      <- stats
+  let res' = {-# SCC "sol-tidy"   #-} tidyResult res
+  return $!! (res', st)
+
+filterLocal :: Sol.GSolution -> SolveM Sol.GSolution 
+filterLocal sol = do 
+  gs' <- mapM (initGBind sol) gs 
+  return $ Sol.updateGMap sol $ M.fromList gs'
+  where 
+    gs = M.toList $ Sol.gMap sol 
+
+initGBind :: Sol.GSolution -> (F.KVar, (((F.Symbol, F.Sort), F.Expr), Sol.GBind)) -> SolveM (F.KVar, (((F.Symbol, F.Sort), F.Expr), Sol.GBind))
+initGBind sol (k, (e, gb)) = do  
+   elems0  <- filterM (isLocal e) (Sol.gbEquals gb)
+   elems   <- sortEquals elems0 
+   lattice <- makeLattice [] (map (:[]) elems) elems
+   return $ ((k,) . (e,) . Sol.equalsGb) lattice
+  where
+    makeLattice acc new elems
+      | null new
+      = return acc 
+      | otherwise
+      = do let cands = [e:es |e<-elems, es<-new]
+           localCans <- filterM (isLocal e) cands
+           newElems  <- filterM (notTrivial (new ++ acc)) localCans 
+           makeLattice (acc ++ new) newElems elems
+
+    notTrivial [] _     = return True 
+    notTrivial (x:xs) p = do v <- isValid (mkPred x) (mkPred p)
+                             if v then return False 
+                                  else notTrivial xs p 
+
+    mkPred eq = So.elaborate "initBGind.mkPred" (Sol.sEnv sol) (F.pAnd (Sol.eqPred <$> eq))
+    isLocal (v, e) eqs = do 
+      let pp = So.elaborate "filterLocal" (Sol.sEnv sol) $ F.PExist [v] $ F.pAnd (e:(Sol.eqPred <$> eqs)) 
+      isValid mempty pp
+
+    root      = Sol.trueEqual
+    sortEquals xs = (bfs [0]) <$> makeEdges vs [] vs 
+      where 
+       vs        = zip [0..] (root:(head <$> xs))
+
+       bfs []     _  = [] 
+       bfs (i:is) es = (snd $ (vs!!i)) : bfs (is++map snd (filter (\(j,k) ->  (j==i && notElem k is)) es)) es
+
+       makeEdges _   acc []    = return acc
+       makeEdges vs acc (x:xs) = do ves  <- concat <$> mapM (makeEdgesOne x) vs
+                                    if any (\(i,j) -> elem (j,i) acc) ves 
+                                      then makeEdges (filter ((/= fst x) . fst) vs) (filter (\(i,j) -> ((i /= fst x) && (j /= fst x))) acc) xs 
+                                      else makeEdges vs (mergeEdges (ves ++ acc)) xs 
+
+    makeEdgesOne (i,_) (j,_) | i == j = return [] 
+    makeEdgesOne (i,x) (j,y) = do 
+      ij <- isValid (mkPred [x]) (mkPred [y])
+      return (if ij then [(j,i)] else [])
+
+    mergeEdges es = filter (\(i,j) -> (not (any (\k -> ((i,k) `elem` es && (k,j) `elem` es)) (fst <$> es)))) es
+
+
+--------------------------------------------------------------------------------
+refine :: Sol.GSolution -> W.Worklist a -> SolveM Sol.GSolution
+--------------------------------------------------------------------------------
+refine s w
+  | Just (c, w', newScc, rnk) <- W.pop w = do
+     i       <- tickIter newScc
+     (b, s') <- refineC i s c
+     lift $ writeLoud $ refineMsg i c b rnk
+     let w'' = if b then W.push c w' else w'
+     refine s' w''
+  | otherwise = return s
+  where
+    -- DEBUG
+    refineMsg i c b rnk = printf "\niter=%d id=%d change=%s rank=%d\n"
+                            i (F.subcId c) (show b) rnk
+
+---------------------------------------------------------------------------
+-- | Single Step Refinement -----------------------------------------------
+---------------------------------------------------------------------------
+refineC :: Int -> Sol.GSolution -> F.SimpC a -> SolveM (Bool, Sol.GSolution)
+---------------------------------------------------------------------------
+refineC _i s c
+  | null rhs  = return (False, s)
+  | otherwise = do be      <- getBinds
+                   let lhss = snd <$> S.lhsPred be s c
+                   kqs     <- filterValidGradual lhss rhs
+                   return   $ S.update s ks kqs
+  where
+    _ci       = F.subcId c
+    (ks, rhs) = rhsCands s c
+    -- msg       = printf "refineC: iter = %d, sid = %s, soln = \n%s\n"
+    --               _i (show (F.sid c)) (showpp s)
+    _msg ks xs ys = printf "refineC: iter = %d, sid = %s, s = %s, rhs = %d, rhs' = %d \n"
+                     _i (show _ci) (showpp ks) (length xs) (length ys)
+
+
+rhsCands :: Sol.GSolution -> F.SimpC a -> ([F.KVar], Sol.Cand (F.KVar, Sol.EQual))
+rhsCands s c    = (fst <$> ks, kqs)
+  where
+    kqs         = [ (p, (k, q)) | (k, su) <- ks, (p, q)  <- cnd k su ]
+    ks          = predKs . F.crhs $ c
+    cnd k su    = Sol.qbPreds msg s su (Sol.lookupQBind s k)
+    msg         = "rhsCands: " ++ show (F.sid c)
+
+--------------------------------------------------------------------------------
+-- | Gradual Convert Solution into Result ----------------------------------------------
+--------------------------------------------------------------------------------
+result :: (F.Fixpoint a) => Config -> W.Worklist a -> Sol.GSolution
+       -> SolveM (F.Result (Integer, a))
+--------------------------------------------------------------------------------
+result cfg wkl s = do
+  lift $ writeLoud "Computing Result"
+  stat    <- result_ wkl s 
+  lift $ whenNormal $ putStrLn $ "RESULT: " ++ show (F.sid <$> stat)
+  F.Result (ci <$> stat) <$> solResult cfg s <*> solResultGradual wkl cfg s 
+  where
+    ci c = (F.subcId c, F.sinfo c)
+
+result_ :: Fixpoint a =>  W.Worklist a -> Sol.GSolution -> SolveM (F.FixResult (F.SimpC a))
+result_  w s = res <$> filterM (isUnsat s) cs
+  where
+    cs       = W.unsatCandidates w
+    res []   = F.Safe
+    res cs'  = F.Unsafe cs'
+
+solResult :: Config -> Sol.GSolution -> SolveM (M.HashMap F.KVar F.Expr)
+solResult cfg
+  = minimizeResult cfg . Sol.result
+
+
+solResultGradual :: W.Worklist a -> Config -> Sol.GSolution -> SolveM F.GFixSolution
+solResultGradual w _cfg sol 
+  = F.toGFixSol . Sol.resultGradual <$> updateGradualSolution (W.unsatCandidates w) sol
+
+--------------------------------------------------------------------------------
+updateGradualSolution :: [F.SimpC a] -> Sol.GSolution -> SolveM (Sol.GSolution)
+--------------------------------------------------------------------------------
+updateGradualSolution cs sol = foldM f (Sol.emptyGMap sol) cs
+  where
+   f s c = do
+    be <- getBinds
+    let lpi = S.lhsPred be sol c 
+    let rp  = rhsPred c 
+    gbs    <- firstValid rp lpi 
+    return $ Sol.updateGMapWithKey gbs s 
+
+
+firstValid :: Monoid a =>  F.Expr -> [(a, F.Expr)] -> SolveM a 
+firstValid _   [] = return mempty 
+firstValid rhs ((y,lhs):xs) = do
+  v <- isValid lhs rhs
+  if v then return y else firstValid rhs xs 
+
+
+--------------------------------------------------------------------------------
+isUnsat :: Fixpoint a => Sol.GSolution -> F.SimpC a -> SolveM Bool
+--------------------------------------------------------------------------------
+isUnsat s c = do
+  -- lift   $ printf "isUnsat %s" (show (F.subcId c))
+  _     <- tickIter True -- newScc
+  be    <- getBinds
+  let lpi = S.lhsPred be s c
+  let rp = rhsPred        c
+  res   <- (not . or) <$> mapM (`isValid` rp) (snd <$> lpi)
+  lift   $ whenLoud $ showUnsat res (F.subcId c) (F.pOr (snd <$> lpi)) rp
+  return res
+
+
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/Instantiate.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/Instantiate.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/Instantiate.hs
@@ -0,0 +1,533 @@
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE PartialTypeSignatures     #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE BangPatterns              #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE ViewPatterns              #-}
+{-# LANGUAGE PatternGuards             #-}
+{-# LANGUAGE ExistentialQuantification #-}
+
+--------------------------------------------------------------------------------
+-- | Axiom Instantiation  ------------------------------------------------------
+--------------------------------------------------------------------------------
+
+module Language.Fixpoint.Solver.Instantiate (
+
+  instantiateAxioms,
+  instantiateFInfo,
+
+  ) where
+
+import           Language.Fixpoint.Types
+import           Language.Fixpoint.Types.Config as FC
+import qualified Language.Fixpoint.Smt.Theories as FT
+import           Language.Fixpoint.Types.Visitor (eapps, kvars, mapMExpr)
+import           Language.Fixpoint.Misc          (mapFst)
+
+import Language.Fixpoint.Smt.Interface          ( smtPop, smtPush
+                                                , smtDecls, smtAssert
+                                                , checkValid', Context(..) )
+import Language.Fixpoint.Defunctionalize        (defuncAny, makeLamArg)
+import Language.Fixpoint.SortCheck              (elaborate)
+
+import Control.Monad.State
+
+-- AT: I've inlined this, but we should have a more elegant solution
+--     (track predicates instead of selectors!)
+-- import           Language.Haskell.Liquid.GHC.Misc (dropModuleNames)
+import qualified Data.Text            as T
+import qualified Data.HashMap.Strict  as M
+import qualified Data.List            as L
+import           Data.Maybe           (catMaybes, fromMaybe)
+import           Data.Char            (isUpper)
+import           Data.Foldable        (foldlM)
+-- import           Data.Monoid          ((<>))
+
+(~>) :: (Expr, String) -> Expr -> EvalST Expr
+(_e,_str) ~> e' = do
+    modify (\st -> st{evId = evId st + 1})
+    -- traceM $ showpp _str ++ " : " ++ showpp _e ++ showpp e'
+    return (η e')
+
+---------------------
+-- Instantiate Axioms
+---------------------
+instantiateFInfo :: Config -> Context -> FInfo c -> IO (FInfo c)
+instantiateFInfo cfg ctx fi = do
+    cm' <- sequence $ M.mapWithKey instantiateOne (cm fi)
+    return $ fi { cm = cm' }
+  where instantiateOne = instantiateAxioms cfg ctx (bs fi) (gLits fi) (ae fi)
+
+instantiateAxioms :: Config -> Context -> BindEnv -> SEnv Sort -> AxiomEnv
+                     -> Integer -> SubC c
+                     -> IO (SubC c)
+instantiateAxioms _ _ _ _ aenv sid sub
+  | not (M.lookupDefault False sid (aenvExpand aenv))
+  = return sub
+instantiateAxioms cfg ctx bds fenv aenv sid sub
+  = flip strengthenLhs sub . pAnd . (is0 ++) .
+    (if arithmeticAxioms cfg then (is ++) else id) <$>
+    if rewriteAxioms cfg then evalEqs else return []
+  where
+    is0              = eqBody <$> L.filter (null . eqArgs) eqs
+    is               = instances maxNumber aenv initOccurences
+    evalEqs          =
+       map (uncurry (PAtom Eq)) .
+       filter (uncurry (/=)) <$>
+       evaluate cfg ctx ((vv Nothing, slhs sub):binds) fenv aenv initExpressions
+    initExpressions  = expr (slhs sub) : expr (srhs sub) : (expr <$> binds)
+    binds            = envCs bds (senv sub)
+    initOccurences   = concatMap (makeInitOccurences as eqs) initExpressions
+
+    eqs = aenvEqs aenv
+
+    -- fuel calculated and used only by `instances` arith rewrite method
+    fuelNumber = M.lookupDefault 0 sid (aenvFuel aenv)
+    as         = (,fuelNumber) . eqName <$> filter (not . null . eqArgs) eqs
+    maxNumber  = (length (aenvSyms aenv) * length initOccurences) ^ fuelNumber
+
+
+------------------------------
+-- Knowledge (SMT Interaction)
+------------------------------
+-- AT:@TODO: knSels and knEqs should reall just be the same thing. In this way,
+-- we should also unify knSims and knAms, as well as their analogues in AxiomEnv
+data Knowledge
+  = KN { knSels    :: ![(Expr, Expr)]
+       , knEqs     :: ![(Expr, Expr)]
+       , knSims    :: ![Rewrite]
+       , knAms     :: ![Equation]
+       , knContext :: IO Context
+       , knPreds   :: !([(Symbol, Sort)] -> Expr -> Context -> IO Bool)
+       , knLams    :: [(Symbol, Sort)]
+       }
+
+emptyKnowledge :: IO Context -> Knowledge
+emptyKnowledge cxt = KN [] [] [] [] cxt (\_ _ _ -> return False) []
+
+lookupKnowledge :: Knowledge -> Expr -> Maybe Expr
+lookupKnowledge γ e
+  -- Zero argument axioms like `mempty = N`
+  | Just e' <- L.lookup e (knEqs γ)
+  = Just e'
+  | Just e' <- L.lookup e (knSels γ)
+  = Just e'
+  | otherwise
+  = Nothing
+
+isValid :: Knowledge -> Expr -> IO Bool
+isValid γ b = knPreds γ (knLams γ) b =<< knContext γ
+
+makeKnowledge :: Config -> Context -> AxiomEnv -> SEnv Sort
+                 -> [(Symbol, SortedReft)]
+                 -> ([(Expr, Expr)], Knowledge)
+makeKnowledge cfg ctx aenv fenv es = (simpleEqs,) $ (emptyKnowledge context)
+                                     { knSels   = sels
+                                     , knEqs    = eqs
+                                     , knSims   = aenvSimpl aenv
+                                     , knAms    = aenvEqs aenv
+                                     , knPreds  = \bs e c -> askSMT c bs e
+                                     }
+  where
+    (xv, sv) = (vv Nothing, sr_sort $ snd $ head es)
+    fbinds = toListSEnv fenv ++ [(x, s) | (x, RR s _) <- es]
+    senv = fromListSEnv fbinds
+
+    context :: IO Context
+    context = do
+      smtPop ctx
+      smtPush ctx
+      smtDecls ctx $ L.nub [(x, toSMT [] s) | (x, s) <- fbinds
+                                            , not (M.member x FT.theorySymbols)]
+      smtAssert ctx (pAnd ([toSMT [] (PAtom Eq e1 e2) | (e1, e2) <- simpleEqs]
+                           ++ filter (null.kvars) ((toSMT [] . expr) <$> es)
+                          ))
+      return ctx
+
+    -- This creates the rewrite rule e1 -> e2
+    -- when should I apply it?
+    -- 1. when e2 is a data con and can lead to further reductions
+    -- 2. when size e2 < size e1
+    -- @TODO: Can this be generalized?
+    atms = splitPAnd =<< (expr <$> filter isProof es)
+    simpleEqs = makeSimplifications (aenvSimpl aenv) =<<
+                L.nub (catMaybes [getDCEquality e1 e2 | PAtom Eq e1 e2 <- atms])
+    sels = (go . expr) =<< es
+    go e = let es   = splitPAnd e
+               su   = mkSubst [(x, EVar y)  | PAtom Eq (EVar x) (EVar y) <- es ]
+               sels = [(EApp (EVar s) x, e) | PAtom Eq (EApp (EVar s) x) e <- es
+                                            , isSelector s ]
+           in L.nub (sels ++ subst su sels)
+
+    eqs = [(EVar x, ex) | Equ a _ bd <- filter (null . eqArgs) $ aenvEqs aenv
+                        , PAtom Eq (EVar x) ex <- splitPAnd bd
+                        , x == a
+                        -- AT: no test needs this
+                        --, EVar x /= ex
+                        ]
+
+    toSMT xs = defuncAny cfg (insertSEnv xv sv senv) .
+               elaborate "symbolic evaluation"
+               (foldl (\env (x,s) -> insertSEnv x s (deleteSEnv x env))
+                      (insertSEnv xv sv senv)
+                      xs)
+
+    -- AT: Non-obvious needed invariant: askSMT True is always the
+    -- totality-effecting one
+    askSMT :: Context -> [(Symbol, Sort)] -> Expr -> IO Bool
+    askSMT cxt xss e
+      | isTautoPred  e = return True
+      | isContraPred e = return False
+      | null (kvars e) = do
+          smtPush cxt
+          b <- checkValid' cxt [] PTrue (toSMT xss e)
+          smtPop cxt
+          return b
+      | otherwise      = return False
+
+    -- TODO: Stringy hacks
+    isSelector :: Symbol -> Bool
+    isSelector  = L.isPrefixOf "select" . symbolString
+    isProof (_, RR s _) =  showpp s == "Tuple"
+
+
+makeSimplifications :: [Rewrite] -> (Symbol, [Expr], Expr) -> [(Expr, Expr)]
+makeSimplifications sis (dc, es, e)
+ = go =<< sis
+ where
+   go (SMeasure f dc' xs bd)
+     | dc == dc', length xs == length es
+     = [(EApp (EVar f) e, subst (mkSubst $ zip xs es) bd)]
+   go _
+     = []
+
+getDCEquality :: Expr -> Expr -> Maybe (Symbol, [Expr], Expr)
+getDCEquality e1 e2
+    | Just dc1 <- f1
+    , Just dc2 <- f2
+    = if dc1 == dc2
+         then Nothing
+         else error ("isDCEquality on" ++ showpp e1 ++ "\n" ++ showpp e2)
+    | Just dc1 <- f1
+    = Just (dc1, es1, e2)
+    | Just dc2 <- f2
+    = Just (dc2, es2, e1)
+    | otherwise
+    = Nothing
+  where
+    (f1, es1) = mapFst getDC $ splitEApp e1
+    (f2, es2) = mapFst getDC $ splitEApp e2
+
+    -- TODO: Stringy hacks
+    getDC (EVar x)
+      = if isUpper $ head $ symbolString $ dropModuleNames x
+           then Just x
+           else Nothing
+    getDC _
+      = Nothing
+
+    dropModuleNames = mungeNames (symbol . last) "."
+
+    mungeNames _ _ ""  = ""
+    mungeNames f d s'@(symbolText -> s)
+      | s' == tupConName = tupConName
+      | otherwise        = f $ T.splitOn d $ stripParens s
+
+    stripParens t = fromMaybe t ((T.stripPrefix "(" >=> T.stripSuffix ")") t)
+
+splitPAnd :: Expr -> [Expr]
+splitPAnd (PAnd es) = concatMap splitPAnd es
+splitPAnd e         = [e]
+
+------------------------
+-- Creating Measure Info
+------------------------
+-- AT@TODO do this for all reflected functions, not just DataCons
+
+-- Insert measure info for every constructor
+-- that appears in the expression e
+-- required by PMEquivalence.mconcatChunk
+assertSelectors :: Knowledge -> Expr -> EvalST ()
+assertSelectors γ e = do
+   EvalEnv _ _ evaenv <- get
+   let sims = aenvSimpl evaenv
+   _ <- foldlM (\_ s -> mapMExpr (go s) e) e sims
+   return ()
+  where
+    go :: Rewrite -> Expr -> EvalST Expr
+    go (SMeasure f dc xs bd) e@(EApp _ _)
+      | (EVar dc', es) <- splitEApp e
+      , dc == dc', length xs == length es
+      = addSMTEquality γ (EApp (EVar f) e) (subst (mkSubst $ zip xs es) bd)
+      >> return e
+    go _ e
+      = return e
+
+addSMTEquality :: Knowledge -> Expr -> Expr -> EvalST (IO ())
+addSMTEquality γ e1 e2 =
+  return $ do ctx <- knContext γ
+              smtAssert ctx (PAtom Eq (makeLam γ e1) (makeLam γ e2))
+
+-------------------------------
+-- Symbolic Evaluation with SMT
+-------------------------------
+data EvalEnv = EvalEnv { evId        :: Int
+                       , evSequence  :: [(Expr,Expr)]
+                       , _evAEnv     :: AxiomEnv
+                       }
+
+type EvalST a = StateT EvalEnv IO a
+
+evaluate :: Config -> Context -> [(Symbol, SortedReft)] -> SEnv Sort -> AxiomEnv
+            -> [Expr]
+            -> IO [(Expr, Expr)]
+evaluate cfg ctx facts fenv aenv einit
+  = (eqs ++) <$>
+    (fmap join . sequence)
+    (evalOne <$> L.nub (grepTopApps =<< einit))
+  where
+    (eqs, γ) = makeKnowledge cfg ctx aenv fenv facts
+    initEvalSt = EvalEnv 0 [] aenv
+    -- This adds all intermediate unfoldings into the assumptions
+    -- no test needs it
+    -- TODO: add a flag to enable it
+    evalOne :: Expr -> IO [(Expr, Expr)]
+    evalOne e = do
+      (e', st) <- runStateT (eval γ e) initEvalSt
+      if e' == e then return [] else return ((e, e'):evSequence st)
+
+grepTopApps :: Expr -> [Expr]
+grepTopApps (PAnd es) = concatMap grepTopApps es
+grepTopApps (PAtom _ e1 e2) = grepTopApps e1 ++ grepTopApps e2
+grepTopApps e@(EApp _ _) = [e]
+grepTopApps _ = []
+-- POr    ![Expr]
+-- PNot   !Expr
+-- PImp   !Expr !Expr
+-- PIff   !Expr !Expr
+
+-- AT: I think makeLam is the adjoint of splitEApp?
+makeLam :: Knowledge -> Expr -> Expr
+makeLam γ e = foldl (flip ELam) e (knLams γ)
+
+eval :: Knowledge -> Expr -> EvalST Expr
+eval γ e | Just e' <- lookupKnowledge γ e
+   = (e, "Knowledge") ~> e'
+eval γ (ELam (x,s) e)
+  = do let x' = makeLamArg s (1+ length (knLams γ))
+       e'    <- eval γ{knLams = (x',s):knLams γ} (subst1 e (x, EVar x'))
+       return $ ELam (x,s) $ subst1 e' (x', EVar x)
+eval γ e@(EIte b e1 e2)
+  = do b' <- eval γ b
+       evalIte γ e b' e1 e2
+eval γ e@(EApp _ _)
+  = evalArgs γ e >>= evalApp γ e
+eval γ (PAtom r e1 e2)
+  = PAtom r <$> eval γ e1 <*> eval γ e2
+eval γ (ENeg e)
+  = ENeg <$> eval γ e
+eval γ (EBin o e1 e2)
+  = EBin o <$> eval γ e1 <*> eval γ e2
+eval γ (ETApp e t)
+  = flip ETApp t <$> eval γ e
+eval γ (ETAbs e s)
+  = flip ETAbs s <$> eval γ e
+eval γ (PNot e)
+  = PNot <$> eval γ e
+eval γ (PImp e1 e2)
+  = PImp <$> eval γ e1 <*> eval γ e2
+eval γ (PIff e1 e2)
+  = PIff <$> eval γ e1 <*> eval γ e2
+eval _ e = return e
+
+evalArgs :: Knowledge -> Expr -> EvalST (Expr, [Expr])
+evalArgs γ = go []
+  where
+    go acc (EApp f e)
+      = do f' <- eval γ f
+           e' <- eval γ e
+           go (e':acc) f'
+    go acc e
+      = (,acc) <$> eval γ e
+
+evalApp :: Knowledge -> Expr -> (Expr, [Expr]) -> EvalST Expr
+evalApp γ e (EVar f, [ex])
+  | (EVar dc, es) <- splitEApp ex
+  , Just simp <- L.find (\simp -> (smName simp == f) && (smDC simp == dc))
+                        (knSims γ)
+  , length (smArgs simp) == length es
+  = do e'    <- eval γ $ η $ substPopIf (zip (smArgs simp) es) (smBody simp)
+       (e, "Rewrite -" ++ showpp f) ~> e'
+evalApp γ _ (EVar f, es)
+  | Just eq <- L.find ((==f) . eqName) (knAms γ)
+  , Just bd <- getEqBody eq
+  , length (eqArgs eq) == length es
+  , f `notElem` syms bd -- not recursive
+  = eval γ $ η $ substPopIf (zip (eqArgs eq) es) bd
+evalApp γ _e (EVar f, es)
+  | Just eq <- L.find ((==f) . eqName) (knAms γ)
+  , Just bd <- getEqBody eq
+  , length (eqArgs eq) == length es  --  recursive
+  = evalRecApplication γ (eApps (EVar f) es) $
+    subst (mkSubst $ zip (eqArgs eq) es) bd
+evalApp _ _ (f, es)
+  = return $ eApps f es
+
+substPopIf :: [(Symbol, Expr)] -> Expr -> Expr
+substPopIf xes e = η $ foldl go e xes
+  where
+    go e (x, EIte b e1 e2) = EIte b (subst1 e (x, e1)) (subst1 e (x, e2))
+    go e (x, ex)           = subst1 e (x, ex)
+
+evalRecApplication :: Knowledge ->  Expr -> Expr -> EvalST Expr
+evalRecApplication γ e (EIte b e1 e2)
+  = do b' <- eval γ b
+       b'' <- liftIO (isValid γ b')
+       if b''
+          then addApplicationEq γ e e1 >>
+               assertSelectors γ e1 >>
+               eval γ e1 >>=
+               ((e, "App") ~>)
+          else do b''' <- liftIO (isValid γ (PNot b'))
+                  if b'''
+                     then addApplicationEq γ e e2 >>
+                          assertSelectors γ e2 >>
+                          eval γ e2 >>=
+                          ((e, "App") ~>)
+                     else return e
+evalRecApplication _ _ e
+  = return e
+
+addApplicationEq :: Knowledge -> Expr -> Expr -> EvalST ()
+addApplicationEq γ e1 e2 =
+  modify (\st -> st{evSequence = (makeLam γ e1, makeLam γ e2):evSequence st})
+
+evalIte :: Knowledge -> Expr -> Expr -> Expr -> Expr -> EvalST Expr
+evalIte γ e b e1 e2 = join $
+                      evalIte' γ e b e1 e2 <$>
+                      liftIO (isValid γ b) <*>
+                      liftIO (isValid γ (PNot b))
+
+evalIte' :: Knowledge -> Expr -> Expr -> Expr -> Expr -> Bool -> Bool
+            -> EvalST Expr
+evalIte' γ e _ e1 _ b _
+  | b
+  = do e' <- eval γ e1
+       (e, "If-True of:" ++ showpp b)  ~> e'
+evalIte' γ e _ _ e2 _ b'
+  | b'
+  = do e' <- eval γ e2
+       (e, "If-False") ~> e'
+evalIte' γ _ b e1 e2 _ _
+  = do e1' <- eval γ e1
+       e2' <- eval γ e2
+       return $ EIte b e1' e2'
+
+-- normalization required by ApplicativeMaybe.composition
+---------------------------------------------------------
+η :: Expr -> Expr
+η = snd . go
+  where
+    go (EIte b t f)
+      | isTautoPred t && isFalse f
+      = (True, b)
+    go (EIte b e1 e2)
+      = let (fb, b') = go b
+            (f1, e1') = go e1
+            (f2, e2') = go e2
+            in
+        (fb || f1 || f2, EIte b' e1' e2')
+    go (EApp (EIte b f1 f2) e)
+      = (True, EIte b (snd $ go $ EApp f1 e) (snd $ go $ EApp f2 e))
+    go (EApp f (EIte b e1 e2))
+      = (True, EIte b (snd $ go $ EApp f e1) (snd $ go $ EApp f e2))
+    go (EApp e1 e2)
+      = let (f1, e1') = go e1
+            (f2, e2') = go e2
+            in
+        if f1 || f2
+              then go $ EApp e1' e2'
+              else (False, EApp e1' e2')
+    go e = (False, e)
+
+
+-- Fuel
+-------
+type Fuel = Int
+type FuelMap = [(Symbol, Fuel)]
+
+goodFuelMap :: FuelMap -> Bool
+goodFuelMap = any ((>0) . snd)
+
+hasFuel :: FuelMap -> Symbol -> Bool
+hasFuel fm x = maybe True (\x -> 0 < x) (L.lookup x fm)
+
+makeFuelMap :: (Fuel -> Fuel) -> FuelMap -> Symbol -> FuelMap
+makeFuelMap f ((x, fx):fs) y
+  | x == y    = (x, f fx) : fs
+  | otherwise = (x, fx)   : makeFuelMap f fs y
+makeFuelMap _ _ _ = error "makeFuelMap"
+
+----------------------------
+-- Naive evaluation strategy
+----------------------------
+data Occurence = Occ {_ofun :: Symbol, _oargs :: [Expr], ofuel :: FuelMap}
+ deriving (Show)
+
+instances :: Int -> AxiomEnv -> [Occurence] -> [Expr]
+instances maxIs aenv !occs
+  = instancesLoop aenv maxIs eqs occs -- (eqBody <$> eqsZero) ++ is
+  where
+    eqs = filter (not . null . eqArgs) (aenvEqs  aenv)
+
+-- Naively: Instantiation happens arbitrary times (in recursive functions it
+-- diverges)
+-- Step 1 [done] : Hack it so that instantiation of axiom A happens from an
+-- occurences and its subsequent instances <= FUEL times
+-- How? Hack expressions to contatin fuel info within eg Cst Step 2: Compute
+-- fuel based on Ranjit's algorithm
+
+instancesLoop :: AxiomEnv ->  Int -> [Equation] -> [Occurence] -> [Expr]
+instancesLoop _ _ eqs = go 0 []
+  where
+    go :: Int -> [Expr] -> [Occurence] -> [Expr]
+    go !i acc occs
+       = let is      = concatMap (unfold eqs) occs
+             newIs   = findNewEqs is acc
+             newOccs = concatMap (grepOccurences eqs) newIs
+             in
+         if null newIs
+            then acc
+            else go (i + length newIs) ((fst <$> newIs) ++ acc) newOccs
+
+findNewEqs :: [(Expr, FuelMap)] -> [Expr] -> [(Expr, FuelMap)]
+findNewEqs [] _ = []
+findNewEqs ((e, f):xss) es
+  | e `elem` es = findNewEqs xss es
+  | otherwise   = (e,f):findNewEqs xss es
+
+makeInitOccurences :: [(Symbol, Fuel)] -> [Equation] -> Expr -> [Occurence]
+makeInitOccurences xs eqs e
+  = [Occ x es xs | (EVar x, es) <- splitEApp <$> eapps e
+                 , Equ x' xs' _ <- eqs, x == x'
+                 , length xs' == length es]
+
+grepOccurences :: [Equation] -> (Expr, FuelMap) -> [Occurence]
+grepOccurences eqs (e, fs)
+  = filter (goodFuelMap . ofuel)
+           [Occ x es fs | (EVar x, es) <- splitEApp <$> eapps e
+                        , Equ x' xs' _ <- eqs, x == x'
+                        , length xs' == length es]
+
+unfold :: [Equation] -> Occurence -> [(Expr, FuelMap)]
+unfold eqs (Occ x es fs)
+  = catMaybes [if hasFuel fs x
+                  then Just (subst (mkSubst $ zip  xs' es) e
+                            , makeFuelMap (\x -> x-1) fs x)
+                  else Nothing
+              | Equ x' xs' e <- eqs
+              , x == x'
+              , length xs' == length es]
+
+instance Expression (Symbol, SortedReft) where
+  expr (x, RR _ (Reft (v, r))) = subst1 (expr r) (v, EVar x)
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/Monad.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/Monad.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/Monad.hs
@@ -0,0 +1,307 @@
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | This is a wrapper around IO that permits SMT queries
+
+module Language.Fixpoint.Solver.Monad
+       ( -- * Type
+         SolveM
+
+         -- * Execution
+       , runSolverM
+
+         -- * Get Binds
+       , getBinds
+
+         -- * SMT Query
+       , filterRequired
+       , filterValid
+       , filterValidGradual
+       , checkSat
+       , smtEnablembqi
+
+         -- * Debug
+       , Stats
+       , tickIter
+       , stats
+       , numIter
+       )
+       where
+
+import           Control.DeepSeq
+import           GHC.Generics
+import           Language.Fixpoint.Utils.Progress
+import           Language.Fixpoint.Misc    (mapSnd, groupList)
+import qualified Language.Fixpoint.Types.Config  as C
+import           Language.Fixpoint.Types.Config  (Config)
+import qualified Language.Fixpoint.Types   as F
+import qualified Language.Fixpoint.Types.Solutions as F
+import           Language.Fixpoint.Types   (pprint)
+-- import qualified Language.Fixpoint.Types.Errors  as E
+import qualified Language.Fixpoint.Smt.Theories as Thy
+import           Language.Fixpoint.Smt.Types (tsInterp)
+import           Language.Fixpoint.Smt.Serialize ()
+import           Language.Fixpoint.Types.PrettyPrint ()
+import           Language.Fixpoint.Smt.Interface
+import           Language.Fixpoint.Solver.Sanitize
+import           Language.Fixpoint.SortCheck
+import           Language.Fixpoint.Graph.Types (SolverInfo (..))
+-- import           Language.Fixpoint.Solver.Solution
+-- import           Data.Maybe           (catMaybes)
+import           Data.List            (partition)
+-- import           Data.Char            (isUpper)
+import           Text.PrettyPrint.HughesPJ (text)
+import           Control.Monad.State.Strict
+import qualified Data.HashMap.Strict as M
+import           Data.Maybe (catMaybes)
+import           Control.Exception.Base (bracket)
+
+--------------------------------------------------------------------------------
+-- | Solver Monadic API --------------------------------------------------------
+--------------------------------------------------------------------------------
+
+type SolveM = StateT SolverState IO
+
+data SolverState = SS { ssCtx     :: !Context          -- ^ SMT Solver Context
+                      , ssBinds   :: !F.SolEnv         -- ^ All variables and types
+                      , ssStats   :: !Stats            -- ^ Solver Statistics
+                      }
+
+data Stats = Stats { numCstr :: !Int -- ^ # Horn Constraints
+                   , numIter :: !Int -- ^ # Refine Iterations
+                   , numBrkt :: !Int -- ^ # smtBracket    calls (push/pop)
+                   , numChck :: !Int -- ^ # smtCheckUnsat calls
+                   , numVald :: !Int -- ^ # times SMT said RHS Valid
+                   } deriving (Show, Generic)
+
+instance NFData Stats
+
+stats0    :: F.GInfo c b -> Stats
+stats0 fi = Stats nCs 0 0 0 0
+  where
+    nCs   = M.size $ F.cm fi
+
+
+instance F.PTable Stats where
+  ptable s = F.DocTable [ (text "# Constraints"         , pprint (numCstr s))
+                        , (text "# Refine Iterations"   , pprint (numIter s))
+                        , (text "# SMT Brackets"        , pprint (numBrkt s))
+                        , (text "# SMT Queries (Valid)" , pprint (numVald s))
+                        , (text "# SMT Queries (Total)" , pprint (numChck s))
+                        ]
+
+--------------------------------------------------------------------------------
+runSolverM :: Config -> SolverInfo b c -> Int -> SolveM a -> IO a
+--------------------------------------------------------------------------------
+runSolverM cfg sI _ act =
+  bracket acquire release $ \ctx -> do
+    res <- runStateT act' (s0 ctx)
+    smtWrite ctx "(exit)"
+    return $ fst res
+  where
+    s0 ctx   = SS ctx be (stats0 fi)
+    act'     = declare initEnv lts {- ess -} >> assumesAxioms (F.asserts fi) >> act
+    release  = cleanupContext
+    acquire  = makeContextWithSEnv cfg file initEnv
+    initEnv  = symbolEnv   cfg fi
+    lts      = F.toListSEnv (F.dLits fi)
+    -- ess   = distinctLiterals fi
+    be       = F.SolEnv (F.bs fi)
+    file     = C.srcFile cfg
+    -- only linear arithmentic when: linear flag is on or solver /= Z3
+    -- lar     = linear cfg || Z3 /= solver cfg
+    fi       = (siQuery sI) {F.hoInfo = F.HOI (C.allowHO cfg) (C.allowHOqs cfg)}
+
+
+
+--------------------------------------------------------------------------------
+getBinds :: SolveM F.SolEnv
+--------------------------------------------------------------------------------
+getBinds = ssBinds <$> get
+
+--------------------------------------------------------------------------------
+getIter :: SolveM Int
+--------------------------------------------------------------------------------
+getIter = numIter . ssStats <$> get
+
+--------------------------------------------------------------------------------
+incIter, incBrkt :: SolveM ()
+--------------------------------------------------------------------------------
+incIter   = modifyStats $ \s -> s {numIter = 1 + numIter s}
+incBrkt   = modifyStats $ \s -> s {numBrkt = 1 + numBrkt s}
+
+--------------------------------------------------------------------------------
+incChck, incVald :: Int -> SolveM ()
+--------------------------------------------------------------------------------
+incChck n = modifyStats $ \s -> s {numChck = n + numChck s}
+incVald n = modifyStats $ \s -> s {numVald = n + numVald s}
+
+withContext :: (Context -> IO a) -> SolveM a
+withContext k = (lift . k) =<< getContext
+
+getContext :: SolveM Context
+getContext = ssCtx <$> get
+
+modifyStats :: (Stats -> Stats) -> SolveM ()
+modifyStats f = modify $ \s -> s { ssStats = f (ssStats s) }
+
+--------------------------------------------------------------------------------
+-- | SMT Interface -------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | `filterRequired [(x1, p1),...,(xn, pn)] q` returns a minimal list [xi] s.t.
+--   /\ [pi] => q
+--------------------------------------------------------------------------------
+filterRequired :: F.Cand a -> F.Expr -> SolveM [a]
+--------------------------------------------------------------------------------
+filterRequired = error "TBD:filterRequired"
+
+{-
+(set-option :produce-unsat-cores true)
+(declare-fun x () Int)
+(declare-fun y () Int)
+(declare-fun z () Int)
+
+; Z3 will only track assertions that are named.
+
+(assert (< 0 x))
+(assert (! (< 0 y)       :named b2))
+(assert (! (< x 10)      :named b3))
+(assert (! (< y 10)      :named b4))
+(assert (! (< (+ x y) 0) :named bR))
+(check-sat)
+(get-unsat-core)
+
+> unsat (b2 bR)
+-}
+
+--------------------------------------------------------------------------------
+-- | `filterValid p [(x1, q1),...,(xn, qn)]` returns the list `[ xi | p => qi]`
+--------------------------------------------------------------------------------
+filterValid :: F.Expr -> F.Cand a -> SolveM [a]
+--------------------------------------------------------------------------------
+filterValid p qs = do
+  qs' <- withContext $ \me ->
+           smtBracket me "filterValidLHS" $
+             filterValid_ p qs me
+  -- stats
+  incBrkt
+  incChck (length qs)
+  incVald (length qs')
+  return qs'
+
+filterValid_ :: F.Expr -> F.Cand a -> Context -> IO [a]
+filterValid_ p qs me = catMaybes <$> do
+  smtAssert me p
+  forM qs $ \(q, x) ->
+    smtBracket me "filterValidRHS" $ do
+      smtAssert me (F.PNot q)
+      valid <- smtCheckUnsat me
+      return $ if valid then Just x else Nothing
+
+
+
+--------------------------------------------------------------------------------
+-- | `filterValidGradual ps [(x1, q1),...,(xn, qn)]` returns the list `[ xi | p => qi]`
+-- | for some p in the list ps 
+--------------------------------------------------------------------------------
+filterValidGradual :: [F.Expr] -> F.Cand a -> SolveM [a]
+--------------------------------------------------------------------------------
+filterValidGradual p qs = do
+  qs' <- withContext $ \me ->
+           smtBracket me "filterValidGradualLHS" $
+             filterValidGradual_ p qs me
+  -- stats
+  incBrkt
+  incChck (length qs)
+  incVald (length qs')
+  return qs'
+
+filterValidGradual_ :: [F.Expr] -> F.Cand a -> Context -> IO [a]
+filterValidGradual_ ps qs me 
+  = (map snd . fst) <$> foldM partitionCandidates ([], qs) ps
+  where
+    partitionCandidates :: (F.Cand a, F.Cand a) -> F.Expr -> IO (F.Cand a, F.Cand a)
+    partitionCandidates (ok, candidates) p = do 
+      (valids', invalids')  <- partition snd <$> filterValidOne_ p candidates me 
+      let (valids, invalids) = (fst <$> valids', fst <$> invalids')
+      return (ok ++ valids, invalids)
+
+filterValidOne_ :: F.Expr -> F.Cand a -> Context -> IO [((F.Expr, a), Bool)]
+filterValidOne_ p qs me = do
+  smtAssert me p
+  forM qs $ \(q, x) ->
+    smtBracket me "filterValidRHS" $ do
+      smtAssert me (F.PNot q)
+      valid <- smtCheckUnsat me
+      return $ ((q, x), valid)
+
+smtEnablembqi :: SolveM ()
+smtEnablembqi
+  = withContext $ \me ->
+      smtWrite me "(set-option :smt.mbqi true)"
+
+--------------------------------------------------------------------------------
+checkSat :: F.Expr -> SolveM  Bool
+--------------------------------------------------------------------------------
+checkSat p
+  = withContext $ \me ->
+      smtBracket me "checkSat" $
+        smtCheckSat me p
+
+--------------------------------------------------------------------------------
+declare :: F.SEnv F.Sort -> [(F.Symbol, F.Sort)] -> SolveM ()
+--------------------------------------------------------------------------------
+declare env lts = withContext $ \me -> do
+  forM_ thyXTs $ uncurry $ smtDecl     me
+  forM_ qryXTs $ uncurry $ smtDecl     me
+  forM_ ess    $           smtDistinct me
+  forM_ axs    $           smtAssert   me
+  return ()
+  where
+    ess        = distinctLiterals  lts
+    axs        = Thy.axiomLiterals lts
+    thyXTs     =               filter (isKind 1) xts
+    qryXTs     = mapSnd tx <$> filter (isKind 2) xts
+    isKind n   = (n ==)  . symKind . fst
+    xts        = F.toListSEnv           env
+    tx         = elaborate    "declare" env
+
+-- | symKind returns {0, 1, 2} where:
+--   0 = Theory-Definition,
+--   1 = Theory-Declaration,
+--   2 = Query-Binder
+
+symKind :: F.Symbol -> Int
+symKind x = case M.lookup x Thy.theorySymbols of
+              Just t  -> if tsInterp t then 0 else 1
+              Nothing -> 2
+
+assumesAxioms :: [F.Triggered F.Expr] -> SolveM ()
+assumesAxioms es = withContext $ \me -> forM_  es $ smtAssertAxiom me
+
+-- assumes :: [F.Expr] -> SolveM ()
+-- assumes es = withContext $ \me -> forM_  es $ smtAssert me
+
+-- | `distinctLiterals` is used solely to determine the set of literals
+--   (of each sort) that are *disequal* to each other, e.g. EQ, LT, GT,
+--   or string literals "cat", "dog", "mouse". These should only include
+--   non-function sorted values.
+distinctLiterals :: [(F.Symbol, F.Sort)] -> [[F.Expr]]
+distinctLiterals xts = [ es | (_, es) <- tess ]
+   where
+    tess             = groupList [(t, F.expr x) | (x, t) <- xts, notFun t]
+    notFun           = not . F.isFunctionSortedReft . (`F.RR` F.trueReft)
+    -- _notStr          = not . (F.strSort ==) . F.sr_sort . (`F.RR` F.trueReft)
+
+---------------------------------------------------------------------------
+stats :: SolveM Stats
+---------------------------------------------------------------------------
+stats = ssStats <$> get
+
+---------------------------------------------------------------------------
+tickIter :: Bool -> SolveM Int
+---------------------------------------------------------------------------
+tickIter newScc = progIter newScc >> incIter >> getIter
+
+progIter :: Bool -> SolveM ()
+progIter newScc = lift $ when newScc progressTick
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/Sanitize.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/Sanitize.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/Sanitize.hs
@@ -0,0 +1,425 @@
+-- | Validate and Transform Constraints to Ensure various Invariants -------------------------
+--   1. Each binder must be associated with a UNIQUE sort
+{-# LANGUAGE TupleSections     #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Language.Fixpoint.Solver.Sanitize
+  ( -- * Transform FInfo to enforce invariants
+    sanitize
+
+    -- * Sorts for each Symbol (move elsewhere)
+  , symbolEnv
+
+    -- * Remove substitutions K[x := e] where `x` is not in dom(K)
+  , dropDeadSubsts
+  ) where
+
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Visitor (symConsts, isConcC, isKvarC, mapKVars, mapKVarSubsts)
+import           Language.Fixpoint.SortCheck     (isFirstOrder)
+import qualified Language.Fixpoint.Misc                            as Misc
+import qualified Language.Fixpoint.Types                           as F
+import           Language.Fixpoint.Types.Config (Config, allowHO)
+import qualified Language.Fixpoint.Types.Errors                    as E
+import qualified Language.Fixpoint.Smt.Theories                    as Thy
+import           Language.Fixpoint.Graph (kvEdges, CVertex (..))
+import qualified Data.HashMap.Strict                               as M
+import qualified Data.HashSet                                      as S
+import qualified Data.List                                         as L
+import qualified Data.Text                                         as T
+import           Data.Maybe          (isNothing, mapMaybe)
+import           Control.Monad       ((>=>))
+import           Text.PrettyPrint.HughesPJ
+
+type SanitizeM a = Either E.Error a
+
+--------------------------------------------------------------------------------
+sanitize :: F.SInfo a -> SanitizeM (F.SInfo a)
+--------------------------------------------------------------------------------
+sanitize =    -- banIllScopedKvars
+             Misc.fM dropFuncSortedShadowedBinders
+         >=> Misc.fM sanitizeWfC
+         >=> Misc.fM replaceDeadKvars
+         >=> Misc.fM (dropDeadSubsts . restrictKVarDomain)
+         >=>         banMixedRhs
+         >=>         banQualifFreeVars
+         >=>         banConstraintFreeVars
+         >=> Misc.fM addLiterals
+
+
+--------------------------------------------------------------------------------
+-- | `addLiterals` traverses the constraints to find (string) literals that
+--   are then added to the `dLits` field.
+--------------------------------------------------------------------------------
+addLiterals :: F.SInfo a -> F.SInfo a
+--------------------------------------------------------------------------------
+addLiterals si = si { F.dLits = F.unionSEnv (F.dLits si) lits'
+                    , F.gLits = F.unionSEnv (F.gLits si) lits'
+                    }
+  where
+    lits'      = M.fromList [ (F.symbol x, F.strSort) | x <- symConsts si ]
+
+--------------------------------------------------------------------------------
+-- | See issue liquid-fixpoint issue #230. This checks that whenever we have,
+--      G1        |- K.su1
+--      G2, K.su2 |- rhs
+--   then
+--      G1 \cap G2 \subseteq wenv(k)
+--------------------------------------------------------------------------------
+_banIllScopedKvars :: F.SInfo a ->  SanitizeM (F.SInfo a)
+--------------------------------------------------------------------------------
+_banIllScopedKvars si = Misc.applyNonNull (Right si) (Left . badKs) errs
+  where
+    errs              = concatMap (checkIllScope si kDs) ks
+    kDs               = kvarDefUses si
+    ks                = filter notKut $ M.keys (F.ws si)
+    notKut            = not . (`F.ksMember` F.kuts si)
+
+badKs :: [(F.KVar, F.SubcId, F.SubcId, F.IBindEnv)] -> F.Error
+badKs = E.catErrors . map E.errIllScopedKVar
+
+type KvConstrM = M.HashMap F.KVar [Integer]
+type KvDefs    = (KvConstrM, KvConstrM)
+
+checkIllScope :: F.SInfo a -> KvDefs -> F.KVar -> [(F.KVar, F.SubcId, F.SubcId, F.IBindEnv)]
+checkIllScope si (inM, outM) k = mapMaybe (uncurry (isIllScope si k)) ios
+  where
+    ios                        = [(i, o) | i <- ins, o <- outs, i /= o ]
+    ins                        = M.lookupDefault [] k inM
+    outs                       = M.lookupDefault [] k outM
+
+isIllScope :: F.SInfo a -> F.KVar -> F.SubcId -> F.SubcId -> Maybe (F.KVar, F.SubcId, F.SubcId, F.IBindEnv)
+isIllScope si k inI outI
+  | F.nullIBindEnv badXs = Nothing
+  | otherwise            = Just (k, inI, outI, badXs)
+  where
+    badXs                = F.diffIBindEnv commonXs kXs
+    kXs                  = {- F.tracepp ("kvarBinds " ++ show k) $ -} kvarBinds si k
+    commonXs             = F.intersectionIBindEnv inXs outXs
+    inXs                 = subcBinds si inI
+    outXs                = subcBinds si outI
+
+subcBinds :: F.SInfo a -> F.SubcId -> F.IBindEnv
+subcBinds si i = F._cenv $ F.cm si M.! i
+
+kvarBinds :: F.SInfo a -> F.KVar -> F.IBindEnv
+kvarBinds si = F.wenv . (F.ws si M.!)
+
+kvarDefUses :: F.SInfo a -> KvDefs
+kvarDefUses si = (Misc.group ins, Misc.group outs)
+  where
+    es         = kvEdges si
+    outs       = [(k, o) | (KVar k, Cstr o) <- es ]
+    ins        = [(k, i) | (Cstr i, KVar k) <- es ]
+
+--------------------------------------------------------------------------------
+-- | `dropDeadSubsts` removes dead `K[x := e]` where `x` NOT in the domain of K.
+--------------------------------------------------------------------------------
+dropDeadSubsts :: F.SInfo a -> F.SInfo a
+dropDeadSubsts si = mapKVarSubsts (F.filterSubst . f) si
+  where
+    kvsM          = M.mapWithKey (\k _ -> kvDom k) (F.ws si)
+    kvDom         = S.fromList . F.kvarDomain si
+    f k x _       = S.member x (M.lookupDefault mempty k kvsM)
+
+--------------------------------------------------------------------------------
+-- | `restrictKVarDomain` updates the kvar-domains in the wf constraints
+--   to a subset of the original binders, where we DELETE the parameters
+--   `x` which appear in substitutions of the form `K[x := y]` where `y`
+--   is not in the env.
+--------------------------------------------------------------------------------
+restrictKVarDomain :: F.SInfo a -> F.SInfo a
+restrictKVarDomain si = si { F.ws = M.mapWithKey (restrictWf kvm) (F.ws si) }
+  where
+    kvm               = safeKvarEnv si
+
+-- | `restrictWf kve k w` restricts the env of `w` to the parameters in `kve k`.
+restrictWf :: KvDom -> F.KVar -> F.WfC a -> F.WfC a
+restrictWf kve k w = w { F.wenv = F.filterIBindEnv f (F.wenv w) }
+  where
+    f i            = S.member i kis
+    kis            = S.fromList [ i | (_, i) <- F.toListSEnv kEnv ]
+    kEnv           = M.lookupDefault mempty k kve
+
+-- | `safeKvarEnv` computes the "real" domain of each kvar, which is
+--   a SUBSET of the input domain, in which we KILL the parameters
+--   `x` which appear in substitutions of the form `K[x := y]`
+--   where `y` is not in the env.
+
+type KvDom     = M.HashMap F.KVar (F.SEnv F.BindId)
+type KvBads    = M.HashMap F.KVar [F.Symbol]
+
+safeKvarEnv :: F.SInfo a -> KvDom
+safeKvarEnv si = L.foldl' (dropKvarEnv si) env0 cs
+  where
+    cs         = M.elems  (F.cm si)
+    env0       = initKvarEnv si
+
+dropKvarEnv :: F.SInfo a -> KvDom -> F.SimpC a -> KvDom
+dropKvarEnv si kve c = M.mapWithKey (dropBadParams kBads) kve
+  where
+    kBads            = badParams si c
+
+dropBadParams :: KvBads -> F.KVar -> F.SEnv F.BindId -> F.SEnv F.BindId
+dropBadParams kBads k kEnv = L.foldl' (flip F.deleteSEnv) kEnv xs
+  where
+    xs                     = M.lookupDefault mempty k kBads
+
+badParams :: F.SInfo a -> F.SimpC a -> M.HashMap F.KVar [F.Symbol]
+badParams si c = Misc.group bads
+  where
+    bads       = [ (k, x) | (v, k, F.Su su) <- subcKSubs xsrs c
+                          , let vEnv = maybe sEnv (`S.insert` sEnv) v
+                          , (x, e)          <- M.toList su
+                          , badArg vEnv e
+                 ]
+    sEnv       = S.fromList (fst <$> xsrs)
+    xsrs       = F.envCs (F.bs si) (F.senv c)
+
+badArg :: S.HashSet F.Symbol -> F.Expr -> Bool
+badArg sEnv (F.EVar y) = not (y `S.member` sEnv)
+badArg _    _          = True
+
+type KSub = (Maybe F.Symbol, F.KVar, F.Subst)
+
+subcKSubs :: [(F.Symbol, F.SortedReft)] -> F.SimpC a -> [KSub]
+subcKSubs xsrs c = rhs ++ lhs
+  where
+    lhs          = [ (Just v, k, su) | (_, sr) <- xsrs
+                                     , let rs   = F.reftConjuncts (F.sr_reft sr)
+                                     , F.Reft (v, F.PKVar k su) <- rs
+                   ]
+    rhs          = [(Nothing, k, su) | F.PKVar k su <- [F.crhs c]]
+
+
+initKvarEnv :: F.SInfo a -> KvDom
+initKvarEnv si = initEnv si <$> F.ws si
+
+initEnv :: F.SInfo a -> F.WfC a -> F.SEnv F.BindId
+initEnv si w = F.fromListSEnv [ (bind i, i) | i <- is ]
+  where
+    is       = F.elemsIBindEnv $ F.wenv w
+    bind i   = fst (F.lookupBindEnv i be)
+    be       = F.bs si
+
+--------------------------------------------------------------------------------
+-- | check that no constraint has free variables (ignores kvars)
+--------------------------------------------------------------------------------
+banConstraintFreeVars :: F.SInfo a -> SanitizeM (F.SInfo a)
+banConstraintFreeVars fi0 = Misc.applyNonNull (Right fi0) (Left . badCs) bads
+  where
+    fi = mapKVars (const $ Just F.PTrue) fi0
+    bads = [(c, fs) | c <- M.elems $ F.cm fi, Just fs <- [cNoFreeVars fi c]]
+
+cNoFreeVars :: F.SInfo a -> F.SimpC a -> Maybe [F.Symbol]
+cNoFreeVars fi c = if S.null fv then Nothing else Just (S.toList fv)
+  where
+    be   = F.bs fi
+    lits = fst <$> F.toListSEnv (F.gLits fi)
+    ids  = F.elemsIBindEnv $ F.senv c
+    cDom = [fst $ F.lookupBindEnv i be | i <- ids]
+    cRng = concat [S.toList . F.reftFreeVars . F.sr_reft . snd $ F.lookupBindEnv i be | i <- ids]
+    fv   = cRng `nubDiff` (lits ++ cDom ++ F.prims)
+
+badCs :: Misc.ListNE (F.SimpC a, [F.Symbol]) -> E.Error
+badCs = E.catErrors . map (E.errFreeVarInConstraint . Misc.mapFst F.subcId)
+
+
+--------------------------------------------------------------------------------
+-- | check that no qualifier has free variables
+--------------------------------------------------------------------------------
+banQualifFreeVars :: F.SInfo a -> SanitizeM (F.SInfo a)
+--------------------------------------------------------------------------------
+banQualifFreeVars fi = Misc.applyNonNull (Right fi) (Left . badQuals) bads
+  where
+    bads   = [ (q, xs) | q <- F.quals fi, let xs = free q, not (null xs) ]
+    lits   = fst <$> F.toListSEnv (F.gLits fi)
+    free q = S.toList $ F.syms (F.qBody q) `nubDiff` (lits ++ F.prims ++ F.syms (fst <$> F.qParams q))
+
+
+badQuals     :: Misc.ListNE (F.Qualifier, Misc.ListNE F.Symbol) -> E.Error
+badQuals bqs = E.catErrors [ E.errFreeVarInQual q xs | (q, xs) <- bqs]
+
+-- Null if first is a subset of second
+nubDiff :: [F.Symbol] -> [F.Symbol] -> S.HashSet F.Symbol
+nubDiff a b = a' `S.difference` b'
+  where
+    a' = S.fromList a
+    b' = S.fromList b
+
+--------------------------------------------------------------------------------
+-- | check that each constraint has RHS of form [k1,...,kn] or [p]
+--------------------------------------------------------------------------------
+banMixedRhs :: F.SInfo a -> SanitizeM (F.SInfo a)
+--------------------------------------------------------------------------------
+banMixedRhs fi = Misc.applyNonNull (Right fi) (Left . badRhs) bads
+  where
+    ics        = M.toList $ F.cm fi
+    bads       = [(i, c) | (i, c) <- ics, not $ isOk c]
+    isOk c     = isKvarC c || isConcC c
+
+badRhs :: Misc.ListNE (Integer, F.SimpC a) -> E.Error
+badRhs = E.catErrors . map badRhs1
+
+badRhs1 :: (Integer, F.SimpC a) -> E.Error
+badRhs1 (i, c) = E.err E.dummySpan $ vcat [ "Malformed RHS for constraint id" <+> pprint i
+                                          , nest 4 (pprint (F.crhs c)) ]
+
+--------------------------------------------------------------------------------
+-- | symbol |-> sort for EVERY variable in the FInfo
+--------------------------------------------------------------------------------
+symbolEnv :: Config -> F.SInfo a -> F.SEnv F.Sort
+symbolEnv cfg si = Thy.theorySEnv
+                   `mappend`
+                   F.fromListSEnv (symbolSorts cfg si)
+
+symbolSorts :: Config -> F.GInfo c a -> [(F.Symbol, F.Sort)]
+symbolSorts cfg fi = either E.die id $ symbolSorts' cfg fi
+
+symbolSorts' :: Config -> F.GInfo c a -> SanitizeM [(F.Symbol, F.Sort)]
+symbolSorts' cfg fi  = (normalize . compact . (defs ++)) =<< bindSorts fi
+  where
+    normalize       = fmap (map (unShadow txFun dm))
+    dm              = M.fromList defs
+    defs            = F.toListSEnv . F.gLits $ fi
+    txFun
+      | allowHO cfg = id
+      | otherwise   = defuncSort
+
+unShadow :: (F.Sort -> F.Sort) -> M.HashMap F.Symbol a -> (F.Symbol, F.Sort) -> (F.Symbol, F.Sort)
+unShadow tx dm (x, t)
+  | M.member x dm  = (x, t)
+  | otherwise      = (x, tx t)
+
+defuncSort :: F.Sort -> F.Sort
+defuncSort (F.FFunc {}) = F.funcSort
+defuncSort t            = t
+
+compact :: [(F.Symbol, F.Sort)] -> Either E.Error [(F.Symbol, F.Sort)]
+compact xts
+  | null bad  = Right [(x, t) | (x, [t]) <- ok ]
+  | otherwise = Left $ dupBindErrors bad'
+  where
+    bad'      = [(x, (, []) <$> ts) | (x, ts) <- bad]
+    (bad, ok) = L.partition multiSorted . binds $ xts
+    binds     = M.toList . M.map Misc.sortNub . Misc.group
+
+--------------------------------------------------------------------------------
+bindSorts  :: F.GInfo c a -> Either E.Error [(F.Symbol, F.Sort)]
+--------------------------------------------------------------------------------
+bindSorts fi
+  | null bad   = Right [ (x, t) | (x, [(t, _)]) <- ok ]
+  | otherwise  = Left $ dupBindErrors [ (x, ts) | (x, ts) <- bad]
+  where
+    (bad, ok)  = L.partition multiSorted . binds $ fi
+    binds      = symBinds . F.bs
+
+
+multiSorted :: (x, [t]) -> Bool
+multiSorted = (1 <) . length . snd
+
+dupBindErrors :: [(F.Symbol, [(F.Sort, [F.BindId] )])] -> E.Error
+dupBindErrors = foldr1 E.catError . map dbe
+  where
+   dbe (x, y) = E.err E.dummySpan $ vcat [ "Multiple sorts for" <+> pprint x
+                                         , nest 4 (pprint y) ]
+
+--------------------------------------------------------------------------------
+symBinds  :: F.BindEnv -> [SymBinds]
+--------------------------------------------------------------------------------
+symBinds  = {- THIS KILLS ELEM: tracepp "symBinds" . -}
+            M.toList
+          . M.map Misc.groupList
+          . Misc.group
+          . binders
+
+type SymBinds = (F.Symbol, [(F.Sort, [F.BindId])])
+
+binders :: F.BindEnv -> [(F.Symbol, (F.Sort, F.BindId))]
+binders be = [(x, (F.sr_sort t, i)) | (i, x, t) <- F.bindEnvToList be]
+
+
+--------------------------------------------------------------------------------
+-- | Drop func-sorted `bind` that are shadowed by `constant` (if same type, else error)
+--------------------------------------------------------------------------------
+dropFuncSortedShadowedBinders :: F.SInfo a -> F.SInfo a
+--------------------------------------------------------------------------------
+dropFuncSortedShadowedBinders fi = dropBinders f (const True) fi
+  where
+    f x t  = not (M.member x defs) || F.allowHO fi || isFirstOrder t
+    defs   = M.fromList $ F.toListSEnv $ F.gLits fi
+
+--------------------------------------------------------------------------------
+-- | Drop irrelevant binders from WfC Environments
+--------------------------------------------------------------------------------
+sanitizeWfC :: F.SInfo a -> F.SInfo a
+sanitizeWfC si = si { F.ws = ws' }
+  where
+    ws'        = deleteWfCBinds drops <$> F.ws si
+    (_,drops)  = filterBindEnv keepF   $  F.bs si
+    keepF      = conjKF [nonConstantF si, nonFunctionF si, _nonDerivedLH]
+    -- drops   = F.tracepp "sanitizeWfC: dropping" $ L.sort drops'
+
+conjKF :: [KeepBindF] -> KeepBindF
+conjKF fs x t = and [f x t | f <- fs]
+
+-- | `nonDerivedLH` keeps a bind x if it does not start with `$` which is used
+--   typically for names that are automatically "derived" by GHC (and which can)
+--   blow up the environments thereby clogging instantiation, etc.
+--   NOTE: This is an LH specific hack and should be moved there.
+
+_nonDerivedLH :: KeepBindF
+_nonDerivedLH x _ = not . T.isPrefixOf "$" . last . T.split ('.' ==) . F.symbolText $ x
+
+nonConstantF :: F.SInfo a -> KeepBindF
+nonConstantF si = \x _ -> not (x `F.memberSEnv` cEnv)
+  where
+    cEnv        = F.gLits si
+
+nonFunctionF :: F.SInfo a -> KeepBindF
+nonFunctionF si
+  | F.allowHO si    = \_ _ -> True
+  | otherwise       = \_ t -> isNothing (F.functionSort t)
+
+--------------------------------------------------------------------------------
+-- | Generic API for Deleting Binders from FInfo
+--------------------------------------------------------------------------------
+dropBinders :: KeepBindF -> KeepSortF -> F.SInfo a -> F.SInfo a
+--------------------------------------------------------------------------------
+dropBinders f g fi  = fi { F.bs    = bs'
+                         , F.cm    = cm'
+                         , F.ws    = ws'
+                         , F.gLits = lits' }
+  where
+    discards        = diss
+    (bs', diss)     = filterBindEnv f $ F.bs fi
+    cm'             = deleteSubCBinds discards   <$> F.cm fi
+    ws'             = deleteWfCBinds  discards   <$> F.ws fi
+    lits'           = F.filterSEnv g (F.gLits fi)
+
+type KeepBindF = F.Symbol -> F.Sort -> Bool
+type KeepSortF = F.Sort -> Bool
+
+deleteSubCBinds :: [F.BindId] -> F.SimpC a -> F.SimpC a
+deleteSubCBinds bs sc = sc { F._cenv = foldr F.deleteIBindEnv (F.senv sc) bs }
+
+deleteWfCBinds :: [F.BindId] -> F.WfC a -> F.WfC a
+deleteWfCBinds bs wf = wf { F.wenv = foldr F.deleteIBindEnv (F.wenv wf) bs }
+
+filterBindEnv :: KeepBindF -> F.BindEnv -> (F.BindEnv, [F.BindId])
+filterBindEnv f be  = (F.bindEnvFromList keep, discard')
+  where
+    (keep, discard) = L.partition f' $ F.bindEnvToList be
+    discard'        = Misc.fst3     <$> discard
+    f' (_, x, t)    = f x (F.sr_sort t)
+
+
+---------------------------------------------------------------------------
+-- | Replace KVars that do not have a WfC with PFalse
+---------------------------------------------------------------------------
+replaceDeadKvars :: F.SInfo a -> F.SInfo a
+---------------------------------------------------------------------------
+replaceDeadKvars fi = mapKVars go fi
+  where
+    go k | k `M.member` F.ws fi = Nothing
+         | otherwise            = Just F.PFalse
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/Solution.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/Solution.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/Solution.hs
@@ -0,0 +1,360 @@
+{-# LANGUAGE FlexibleInstances  #-}
+{-# LANGUAGE TupleSections      #-}
+
+module Language.Fixpoint.Solver.Solution
+  ( -- * Create Initial Solution
+    init
+
+    -- * Update Solution
+  , Sol.update
+
+  -- * Lookup Solution
+  , lhsPred
+  ) where
+
+import           Control.Parallel.Strategies
+import           Control.Arrow (second)
+import qualified Data.HashSet                   as S
+import qualified Data.HashMap.Strict            as M
+import qualified Data.List                      as L
+import           Data.Maybe                     (fromMaybe, maybeToList, isNothing)
+import           Data.Monoid                    ((<>))
+import           Language.Fixpoint.Types.PrettyPrint ()
+import           Language.Fixpoint.Types.Visitor      as V
+import qualified Language.Fixpoint.SortCheck          as So
+import           Language.Fixpoint.Misc
+import qualified Language.Fixpoint.Smt.Theories       as Thy
+import           Language.Fixpoint.Types.Config
+import qualified Language.Fixpoint.Types              as F
+import           Language.Fixpoint.Types                 ((&.&))
+import qualified Language.Fixpoint.Types.Solutions    as Sol
+import           Language.Fixpoint.Types.Constraints  hiding (ws, bs)
+import           Prelude                              hiding (init, lookup)
+import           Language.Fixpoint.Solver.Sanitize
+
+-- DEBUG
+-- import Text.Printf (printf)
+-- import           Debug.Trace (trace)
+
+
+--------------------------------------------------------------------------------
+-- | Initial Solution (from Qualifiers and WF constraints) ---------------------
+--------------------------------------------------------------------------------
+init :: Config -> F.SInfo a -> S.HashSet F.KVar -> Sol.Solution
+--------------------------------------------------------------------------------
+init cfg si ks = Sol.fromList senv mempty keqs [] mempty
+  where
+    keqs       = map (refine si qs genv) ws `using` parList rdeepseq
+    qs         = F.quals si
+    ws         = [ w | (k, w) <- M.toList (F.ws si), not (isGWfc w) , k `S.member` ks]
+    genv       = instConstants si
+    senv       = symbolEnv cfg si
+
+--------------------------------------------------------------------------------
+refine :: F.SInfo a -> [F.Qualifier] -> F.SEnv F.Sort -> F.WfC a -> (F.KVar, Sol.QBind)
+refine fi qs genv w = refineK (allowHOquals fi) env qs $ F.wrft w
+  where
+    env             = wenv <> genv
+    wenv            = F.sr_sort <$> F.fromListSEnv (F.envCs (F.bs fi) (F.wenv w))
+
+instConstants :: F.SInfo a -> F.SEnv F.Sort
+instConstants = F.fromListSEnv . filter notLit . F.toListSEnv . F.gLits
+  where
+    notLit    = not . F.isLitSymbol . fst
+
+
+refineK :: Bool -> F.SEnv F.Sort -> [F.Qualifier] -> (F.Symbol, F.Sort, F.KVar) -> (F.KVar, Sol.QBind)
+refineK ho env qs (v, t, k) = {- F.tracepp _msg -} (k, eqs')
+   where
+    eqs                     = instK ho env v t qs
+    eqs'                    = Sol.qbFilter (okInst env v t) eqs
+    -- _msg                    = printf "\n\nrefineK: k = %s, eqs = %s" (F.showpp k) (F.showpp eqs)
+
+--------------------------------------------------------------------------------
+instK :: Bool
+      -> F.SEnv F.Sort
+      -> F.Symbol
+      -> F.Sort
+      -> [F.Qualifier]
+      -> Sol.QBind
+--------------------------------------------------------------------------------
+instK ho env v t = Sol.qb . unique . concatMap (instKQ ho env v t)
+  where
+    unique       = L.nubBy ((. Sol.eqPred) . (==) . Sol.eqPred)
+
+instKQ :: Bool
+       -> F.SEnv F.Sort
+       -> F.Symbol
+       -> F.Sort
+       -> F.Qualifier
+       -> [Sol.EQual]
+instKQ ho env v t q
+  = do (su0, v0) <- candidates senv [(t, [v])] qt
+       xs        <- match senv tyss [v0] (So.apply su0 <$> qts)
+       return     $ Sol.eQual q (reverse xs)
+    where
+       qt : qts   = snd <$> F.qParams q
+       tyss       = instCands ho env
+       senv       = (`F.lookupSEnvWithDistance` env)
+
+instCands :: Bool -> F.SEnv F.Sort -> [(F.Sort, [F.Symbol])]
+instCands ho env = filter isOk tyss
+  where
+    tyss      = groupList [(t, x) | (x, t) <- xts]
+    isOk      = if ho then const True else isNothing . F.functionSort . fst
+    xts       = F.toListSEnv env
+
+match :: So.Env -> [(F.Sort, [F.Symbol])] -> [F.Symbol] -> [F.Sort] -> [[F.Symbol]]
+match env tyss xs (t : ts)
+  = do (su, x) <- candidates env tyss t
+       match env tyss (x : xs) (So.apply su <$> ts)
+match _   _   xs []
+  = return xs
+
+--------------------------------------------------------------------------------
+candidates :: So.Env -> [(F.Sort, [F.Symbol])] -> F.Sort -> [(So.TVSubst, F.Symbol)]
+--------------------------------------------------------------------------------
+candidates env tyss tx = -- traceShow _msg
+    [(su, y) | (t, ys) <- tyss
+             , su      <- maybeToList $ So.unifyFast mono env tx t
+             , y       <- ys                                   ]
+  where
+    mono = So.isMono tx
+    _msg  = "candidates tyss :=" ++ F.showpp tyss ++ "tx := " ++ F.showpp tx
+
+--------------------------------------------------------------------------------
+okInst :: F.SEnv F.Sort -> F.Symbol -> F.Sort -> Sol.EQual -> Bool
+--------------------------------------------------------------------------------
+okInst env v t eq = isNothing tc
+  where
+    sr            = F.RR t (F.Reft (v, p))
+    p             = Sol.eqPred eq
+    tc            = So.checkSorted env sr -- (F.tracepp _msg sr)
+    -- _msg          = printf "okInst: t = %s, eq = %s, env = %s" (F.showpp t) (F.showpp eq) (F.showpp env)
+
+
+--------------------------------------------------------------------------------
+-- | Predicate corresponding to LHS of constraint in current solution
+--------------------------------------------------------------------------------
+lhsPred :: F.SolEnv -> Sol.Solution -> F.SimpC a -> F.Expr
+lhsPred be s c = F.notracepp _msg $ fst $ apply g s bs
+  where
+    g          = (ci, be, bs)
+    bs         = F.senv c
+    ci         = sid c
+    _msg       = "LhsPred for id = " ++ show (sid c)
+
+type Cid         = Maybe Integer
+type CombinedEnv = (Cid, F.SolEnv, F.IBindEnv)
+type ExprInfo    = (F.Expr, KInfo)
+
+apply :: CombinedEnv -> Sol.Sol a Sol.QBind -> F.IBindEnv -> ExprInfo
+apply g s bs      = (F.pAnd (pks:ps), kI)
+  where
+    (pks, kI)     = applyKVars g s ks  -- RJ: switch to applyKVars' to revert to old behavior
+    (ps,  ks, _)  = envConcKVars g bs
+
+
+envConcKVars :: CombinedEnv -> F.IBindEnv -> ([F.Expr], [F.KVSub], [F.KVSub])
+envConcKVars g bs = (concat pss, concat kss, L.nubBy (\x y -> F.ksuKVar x == F.ksuKVar y) $ concat gss)
+  where
+    (pss, kss, gss) = unzip3 [ F.notracepp ("sortedReftConcKVars" ++ F.showpp sr) $ F.sortedReftConcKVars x sr | (x, sr) <- xrs ]
+    xrs             = (\i -> F.notracepp  ("lookupBE i := " ++ show i) $ F.lookupBindEnv i be) <$> is
+    is              = F.elemsIBindEnv bs
+    be              = F.soeBinds (snd3 g)
+
+applyKVars :: CombinedEnv -> Sol.Sol a Sol.QBind -> [F.KVSub] -> ExprInfo
+applyKVars g s = mrExprInfos (applyKVar g s) F.pAnd mconcat 
+
+applyKVar :: CombinedEnv -> Sol.Sol a Sol.QBind -> F.KVSub -> ExprInfo
+applyKVar g s ksu = case Sol.lookup s (F.ksuKVar ksu) of
+  Left cs          -> hypPred g s ksu cs
+  Right eqs -> (F.pAnd $ fst <$> Sol.qbPreds msg s (F.ksuSubst ksu) eqs, mempty) -- TODO: don't initialize kvars that have a hyp solution
+  where
+    msg     = "applyKVar: " ++ show (fst3 g) 
+
+hypPred :: CombinedEnv -> Sol.Sol a Sol.QBind -> F.KVSub -> Sol.Hyp  -> ExprInfo
+hypPred g s ksu = mrExprInfos (cubePred g s ksu) F.pOr mconcatPlus
+
+{- | `cubePred g s k su c` returns the predicate for
+
+        (k . su)
+
+      defined by using cube
+
+        c := [b1,...,bn] |- (k . su')
+
+      in the binder environment `g`.
+
+        bs' := the subset of "extra" binders in [b1...bn] that are *not* in `g`
+        p'  := the predicate corresponding to the "extra" binders
+
+ -}
+
+elabExist :: Sol.Sol a Sol.QBind -> [(F.Symbol, F.Sort)] -> F.Expr -> F.Expr
+elabExist s xts = F.pExist xts'
+  where
+    xts'        = [ (x, elab t) | (x, t) <- xts]
+    elab        = So.elaborate "elabExist" env
+    env         = Sol.sEnv s
+
+cubePred :: CombinedEnv -> Sol.Sol a Sol.QBind -> F.KVSub -> Sol.Cube -> ExprInfo
+cubePred g s ksu c    = (elabExist s xts (psu &.& p), kI)
+  where
+    ((xts,psu,p), kI) = cubePredExc g s ksu c bs'
+    bs'               = delCEnv s k bs
+    bs                = Sol.cuBinds c
+    k                 = F.ksuKVar ksu
+
+type Binders = [(F.Symbol, F.Sort)]
+
+-- | @cubePredExc@ computes the predicate for the subset of binders bs'.
+--   The output is a tuple, `(xts, psu, p, kI)` such that the actual predicate
+--   we want is `Exists xts. (psu /\ p)`.
+
+cubePredExc :: CombinedEnv -> Sol.Sol a Sol.QBind -> F.KVSub -> Sol.Cube -> F.IBindEnv
+            -> ((Binders, F.Pred, F.Pred), KInfo)
+
+cubePredExc g s ksu c bs' = (cubeP, extendKInfo kI (Sol.cuTag c))
+  where
+    cubeP           = (xts, psu, elabExist s yts' (p' &.& psu') )
+    yts'            = symSorts g bs'
+    g'              = addCEnv  g bs
+    (p', kI)        = apply g' s bs'
+    (_  , psu')     = substElim sEnv g' k su'
+    (xts, psu)      = substElim sEnv g  k su
+    su'             = Sol.cuSubst c
+    bs              = Sol.cuBinds c
+    k               = F.ksuKVar   ksu
+    su              = F.ksuSubst  ksu
+    sEnv            = F.insertSEnv (F.ksuVV ksu) (F.ksuSort ksu) (Sol.sEnv s)
+
+-- TODO: SUPER SLOW! Decorate all substitutions with Sorts in a SINGLE pass.
+
+{- | @substElim@ returns the binders that must be existentially quantified,
+     and the equality predicate relating the kvar-"parameters" and their
+     actual values. i.e. given
+
+        K[x1 := e1]...[xn := en]
+
+     where e1 ... en have types t1 ... tn
+     we want to quantify out
+
+       x1:t1 ... xn:tn
+
+     and generate the equality predicate && [x1 ~~ e1, ... , xn ~~ en]
+     we use ~~ because the param and value may have different sorts, see:
+
+        tests/pos/kvar-param-poly-00.hs
+
+     Finally, we filter out binders if they are
+
+     1. "free" in e1...en i.e. in the outer environment.
+        (Hmm, that shouldn't happen...?)
+
+     2. are binders corresponding to sorts (e.g. `a : num`, currently used
+        to hack typeclasses current.)
+ -}
+substElim :: F.SEnv F.Sort -> CombinedEnv -> F.KVar -> F.Subst -> ([(F.Symbol, F.Sort)], F.Pred)
+substElim sEnv g _ (F.Su m) = (xts, p)
+  where
+    p      = F.pAnd [ mkSubst x (substSort sEnv frees x t) e t | (x, e, t) <- xets  ]
+    xts    = [ (x, t)    | (x, _, t) <- xets, not (S.member x frees) ]
+    xets   = [ (x, e, t) | (x, e)    <- xes, t <- sortOf e, not (isClass t)]
+    xes    = M.toList m
+    env    = combinedSEnv g
+    frees  = S.fromList (concatMap (F.syms . snd) xes)
+    sortOf = maybeToList . So.checkSortExpr env
+
+substSort :: F.SEnv F.Sort -> S.HashSet F.Symbol -> F.Symbol -> F.Sort -> F.Sort
+substSort sEnv _frees x _t = fromMaybe (err x) $ F.lookupSEnv x sEnv
+  where
+    err x            = error $ "Solution.mkSubst: unknown binder " ++ F.showpp x
+
+mkSubst :: F.Symbol -> F.Sort -> F.Expr -> F.Sort -> F.Expr
+mkSubst x tx ey ty
+  | tx == ty    = F.EEq ex ey
+  | otherwise   = F.notracepp msg (F.EEq ex' ey')
+  where
+    msg         = "mkSubst-DIFF:" ++ F.showpp (tx, ty) ++ F.showpp (ex', ey')
+    ex          = F.expr x
+    ex'         = Thy.toInt ex tx
+    ey'         = Thy.toInt ey ty
+
+isClass :: F.Sort -> Bool
+isClass F.FNum  = True
+isClass F.FFrac = True
+isClass _       = False
+
+--badExpr :: CombinedEnv -> F.KVar -> F.Expr -> a
+--badExpr g@(i,_,_) k e
+  -- = errorstar $ "substSorts has a badExpr: "
+              -- ++ show e
+              -- ++ " in cid = "
+              -- ++ show i
+              -- ++ " for kvar " ++ show k
+              -- ++ " in env \n"
+              -- ++ show (combinedSEnv g)
+
+-- substPred :: F.Subst -> F.Pred
+-- substPred (F.Su m) = F.pAnd [ F.PAtom F.Eq (F.eVar x) e | (x, e) <- M.toList m]
+
+combinedSEnv :: CombinedEnv -> F.SEnv F.Sort
+combinedSEnv (_, se, bs) = F.sr_sort <$> F.fromListSEnv (F.envCs be bs)
+  where
+    be                   = F.soeBinds se
+
+addCEnv :: CombinedEnv -> F.IBindEnv -> CombinedEnv
+addCEnv (x, be, bs) bs' = (x, be, F.unionIBindEnv bs bs')
+
+-- delCEnv :: F.IBindEnv -> CombinedEnv -> F.IBindEnv
+-- delCEnv bs (_, _, bs')  = F.diffIBindEnv bs bs'
+
+delCEnv :: Sol.Sol a Sol.QBind -> F.KVar -> F.IBindEnv -> F.IBindEnv
+delCEnv s k bs  = F.diffIBindEnv bs _kbs
+                                                -- ORIG: bs'
+  where
+    _kbs = safeLookup "delCEnv" k (Sol.sScp s)
+
+symSorts :: CombinedEnv -> F.IBindEnv -> [(F.Symbol, F.Sort)]
+symSorts (_, se, _) bs = second F.sr_sort <$> F.envCs be  bs
+  where
+    be                 = F.soeBinds se
+
+_noKvars :: F.Expr -> Bool
+_noKvars = null . V.kvars
+
+--------------------------------------------------------------------------------
+-- | Information about size of formula corresponding to an "eliminated" KVar.
+--------------------------------------------------------------------------------
+data KInfo = KI { kiTags  :: [Tag]
+                , kiDepth :: !Int
+                , kiCubes :: !Integer
+                } deriving (Eq, Ord, Show)
+
+instance Monoid KInfo where
+  mempty         = KI [] 0 1
+  mappend ki ki' = KI ts d s
+    where
+      ts         = appendTags (kiTags  ki) (kiTags  ki')
+      d          = max        (kiDepth ki) (kiDepth ki')
+      s          = (*)        (kiCubes ki) (kiCubes ki')
+
+mplus :: KInfo -> KInfo -> KInfo
+mplus ki ki' = (mappend ki ki') { kiCubes = kiCubes ki + kiCubes ki'}
+
+mconcatPlus :: [KInfo] -> KInfo
+mconcatPlus = foldr mplus mempty
+
+appendTags :: [Tag] -> [Tag] -> [Tag]
+appendTags ts ts' = sortNub (ts ++ ts')
+
+extendKInfo :: KInfo -> F.Tag -> KInfo
+extendKInfo ki t = ki { kiTags  = appendTags [t] (kiTags  ki)
+                      , kiDepth = 1  +            kiDepth ki }
+
+-- mrExprInfos :: (a -> ExprInfo) -> ([F.Expr] -> F.Expr) -> ([KInfo] -> KInfo) -> [a] -> ExprInfo
+mrExprInfos :: (a -> (b, c)) -> ([b] -> b1) -> ([c] -> c1) -> [a] -> (b1, c1)
+mrExprInfos mF erF irF xs = (erF es, irF is)
+  where
+    (es, is)              = unzip $ map mF xs
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/Solve.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/Solve.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/Solve.hs
@@ -0,0 +1,247 @@
+{-# LANGUAGE PatternGuards     #-}
+{-# LANGUAGE TupleSections     #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+--------------------------------------------------------------------------------
+-- | Solve a system of horn-clause constraints ---------------------------------
+--------------------------------------------------------------------------------
+
+module Language.Fixpoint.Solver.Solve (solve) where
+
+import           Control.Monad (when, filterM)
+import           Control.Monad.State.Strict (lift)
+import           Language.Fixpoint.Misc
+import qualified Language.Fixpoint.Types           as F
+import qualified Language.Fixpoint.Types.Solutions as Sol
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Config hiding (stats)
+import qualified Language.Fixpoint.Solver.Solution  as S
+import qualified Language.Fixpoint.Solver.Worklist  as W
+import qualified Language.Fixpoint.Solver.Eliminate as E
+import           Language.Fixpoint.Solver.Monad
+import           Language.Fixpoint.Solver.GradualSolve
+import           Language.Fixpoint.Utils.Progress
+import           Language.Fixpoint.Graph
+import           Text.PrettyPrint.HughesPJ
+import           Text.Printf
+import           System.Console.CmdArgs.Verbosity (whenNormal, whenLoud)
+import           Control.DeepSeq
+import qualified Data.HashMap.Strict as M
+import qualified Data.HashSet        as S
+
+-- DEBUG
+-- import           Debug.Trace (trace)
+
+--------------------------------------------------------------------------------
+solve :: (NFData a, F.Fixpoint a) => Config -> F.SInfo a -> IO (F.Result (Integer, a))
+--------------------------------------------------------------------------------
+solve cfg fi | gradual cfg 
+  = solveGradual cfg fi 
+
+solve cfg fi = do
+    -- donePhase Loud "Worklist Initialize"
+    (res, stat) <- withProgressFI sI $ runSolverM cfg sI n act
+    when (solverStats cfg) $ printStats fi wkl stat
+    -- print (numIter stat)
+    return res
+  where
+    act  = solve_ cfg fi s0 ks  wkl
+    sI   = solverInfo cfg fi
+    wkl  = W.init sI
+    n    = fromIntegral $ W.wRanks wkl
+    s0   = siSol  sI
+    ks   = siVars sI
+
+--------------------------------------------------------------------------------
+-- | Progress Bar
+--------------------------------------------------------------------------------
+withProgressFI :: SolverInfo a b -> IO b -> IO b
+withProgressFI = withProgress . fromIntegral . cNumScc . siDeps
+--------------------------------------------------------------------------------
+
+printStats :: F.SInfo a ->  W.Worklist a -> Stats -> IO ()
+printStats fi w s = putStrLn "\n" >> ppTs [ ptable fi, ptable s, ptable w ]
+  where
+    ppTs          = putStrLn . showpp . mconcat
+
+--------------------------------------------------------------------------------
+solverInfo :: Config -> F.SInfo a -> SolverInfo a b
+--------------------------------------------------------------------------------
+solverInfo cfg fI
+  | useElim cfg = E.solverInfo cfg fI
+  | otherwise   = SI mempty fI cD (siKvars fI)
+  where
+    cD          = elimDeps fI (kvEdges fI) mempty
+
+siKvars :: F.SInfo a -> S.HashSet F.KVar
+siKvars = S.fromList . M.keys . F.ws
+
+--------------------------------------------------------------------------------
+solve_ :: (NFData a, F.Fixpoint a)
+       => Config
+       -> F.SInfo a
+       -> Sol.Solution
+       -> S.HashSet F.KVar
+       -> W.Worklist a
+       -> SolveM (F.Result (Integer, a), Stats)
+--------------------------------------------------------------------------------
+solve_ cfg fi s0 ks wkl = do 
+  let s1  = mappend s0 $ {-# SCC "sol-init" #-} S.init cfg fi ks
+  s       <- {-# SCC "sol-refine" #-} refine s1 wkl
+  res     <- {-# SCC "sol-result" #-} result cfg wkl s
+  st      <- stats
+  let res' = {-# SCC "sol-tidy"   #-} tidyResult res
+  return $!! (res', st)
+
+--------------------------------------------------------------------------------
+-- | tidyResult ensures we replace the temporary kVarArg names introduced to
+--   ensure uniqueness with the original names in the given WF constraints.
+--------------------------------------------------------------------------------
+tidyResult :: F.Result a -> F.Result a
+tidyResult r = r { F.resSolution = tidySolution (F.resSolution r) }
+
+tidySolution :: F.FixSolution -> F.FixSolution
+tidySolution = fmap tidyPred
+
+tidyPred :: F.Expr -> F.Expr
+tidyPred = F.substf (F.eVar . F.tidySymbol)
+
+--------------------------------------------------------------------------------
+refine :: Sol.Solution -> W.Worklist a -> SolveM Sol.Solution
+--------------------------------------------------------------------------------
+refine s w
+  | Just (c, w', newScc, rnk) <- W.pop w = do
+     i       <- tickIter newScc
+     (b, s') <- refineC i s c
+     lift $ writeLoud $ refineMsg i c b rnk
+     let w'' = if b then W.push c w' else w'
+     refine s' w''
+  | otherwise = return s
+  where
+    -- DEBUG
+    refineMsg i c b rnk = printf "\niter=%d id=%d change=%s rank=%d\n"
+                            i (F.subcId c) (show b) rnk
+
+---------------------------------------------------------------------------
+-- | Single Step Refinement -----------------------------------------------
+---------------------------------------------------------------------------
+refineC :: Int -> Sol.Solution -> F.SimpC a -> SolveM (Bool, Sol.Solution)
+---------------------------------------------------------------------------
+refineC _i s c
+  | null rhs  = return (False, s)
+  | otherwise = do be     <- getBinds
+                   let lhs = S.lhsPred be s c
+                   kqs    <- filterValid lhs rhs
+                   return  $ S.update s ks kqs
+  where
+    _ci       = F.subcId c
+    (ks, rhs) = rhsCands s c
+    -- msg       = printf "refineC: iter = %d, sid = %s, soln = \n%s\n"
+    --               _i (show (F.sid c)) (showpp s)
+    _msg ks xs ys = printf "refineC: iter = %d, sid = %s, s = %s, rhs = %d, rhs' = %d \n"
+                     _i (show _ci) (showpp ks) (length xs) (length ys)
+
+rhsCands :: Sol.Solution -> F.SimpC a -> ([F.KVar], Sol.Cand (F.KVar, Sol.EQual))
+rhsCands s c    = (fst <$> ks, kqs)
+  where
+    kqs         = [ (p, (k, q)) | (k, su) <- ks, (p, q)  <- cnd k su ]
+    ks          = predKs . F.crhs $ c
+    cnd k su    = Sol.qbPreds msg s su (Sol.lookupQBind s k)
+    msg         = "rhsCands: " ++ show (F.sid c)
+
+predKs :: F.Expr -> [(F.KVar, F.Subst)]
+predKs (F.PAnd ps)    = concatMap predKs ps
+predKs (F.PKVar k su) = [(k, su)]
+predKs _              = []
+
+--------------------------------------------------------------------------------
+-- | Convert Solution into Result ----------------------------------------------
+--------------------------------------------------------------------------------
+result :: (F.Fixpoint a) => Config -> W.Worklist a -> Sol.Solution
+       -> SolveM (F.Result (Integer, a))
+--------------------------------------------------------------------------------
+result cfg wkl s = do
+  lift $ writeLoud "Computing Result"
+  stat    <- result_ wkl s 
+  lift $ whenNormal $ putStrLn $ "RESULT: " ++ show (F.sid <$> stat)
+  F.Result (ci <$> stat) <$> solResult cfg s <*> return mempty
+  where
+    ci c = (F.subcId c, F.sinfo c)
+
+solResult :: Config -> Sol.Solution -> SolveM (M.HashMap F.KVar F.Expr)
+solResult cfg = minimizeResult cfg . Sol.result 
+
+result_ :: W.Worklist a -> Sol.Solution -> SolveM (F.FixResult (F.SimpC a))
+result_  w s = res <$> filterM (isUnsat s) cs
+  where
+    cs       = W.unsatCandidates w
+    res []   = F.Safe
+    res cs'  = F.Unsafe cs'
+
+--------------------------------------------------------------------------------
+-- | `minimizeResult` transforms each KVar's result by removing
+--   conjuncts that are implied by others. That is,
+--
+--      minimizeConjuncts :: ps:[Pred] -> {qs:[Pred] | subset qs ps}
+--
+--   such that `minimizeConjuncts ps` is a minimal subset of ps where no
+--   is implied by /\_{q' in qs \ qs}
+--   see: tests/pos/min00.fq for an example. 
+--------------------------------------------------------------------------------
+minimizeResult :: Config -> M.HashMap F.KVar F.Expr
+               -> SolveM (M.HashMap F.KVar F.Expr)
+--------------------------------------------------------------------------------
+minimizeResult cfg s
+  | minimalSol cfg = mapM minimizeConjuncts s
+  | otherwise      = return s
+
+minimizeConjuncts :: F.Expr -> SolveM F.Expr
+minimizeConjuncts p = F.pAnd <$> go (F.conjuncts p) []
+  where
+    go []     acc   = return acc
+    go (p:ps) acc   = do b <- isValid (F.pAnd (acc ++ ps)) p
+                         if b then go ps acc
+                              else go ps (p:acc)
+
+--------------------------------------------------------------------------------
+isUnsat :: Sol.Solution -> F.SimpC a -> SolveM Bool
+--------------------------------------------------------------------------------
+isUnsat s c = do
+  -- lift   $ printf "isUnsat %s" (show (F.subcId c))
+  _     <- tickIter True -- newScc
+  be    <- getBinds
+  let lp = S.lhsPred be s c
+  let rp = rhsPred        c
+  res   <- not <$> isValid lp rp
+  lift   $ whenLoud $ showUnsat res (F.subcId c) lp rp
+  return res
+
+showUnsat :: Bool -> Integer -> F.Pred -> F.Pred -> IO ()
+showUnsat u i lP rP = {- when u $ -} do
+  putStrLn $ printf   "UNSAT id %s %s" (show i) (show u)
+  putStrLn $ showpp $ "LHS:" <+> pprint lP
+  putStrLn $ showpp $ "RHS:" <+> pprint rP
+
+--------------------------------------------------------------------------------
+-- | Predicate corresponding to RHS of constraint in current solution
+--------------------------------------------------------------------------------
+rhsPred :: F.SimpC a -> F.Expr
+--------------------------------------------------------------------------------
+rhsPred c
+  | isTarget c = F.crhs c
+  | otherwise  = errorstar $ "rhsPred on non-target: " ++ show (F.sid c)
+
+isValid :: F.Expr -> F.Expr -> SolveM Bool
+isValid p q = (not . null) <$> filterValid p [(q, ())]
+
+
+{-
+---------------------------------------------------------------------------
+donePhase' :: String -> SolveM ()
+---------------------------------------------------------------------------
+donePhase' msg = lift $ do
+  threadDelay 25000
+  putBlankLn
+  donePhase Loud msg
+-}
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/TrivialSort.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/TrivialSort.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/TrivialSort.hs
@@ -0,0 +1,176 @@
+{-# LANGUAGE DeriveGeneric #-}
+
+module Language.Fixpoint.Solver.TrivialSort (nontrivsorts) where
+
+import           GHC.Generics        (Generic)
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Visitor
+import           Language.Fixpoint.Types.Config
+import           Language.Fixpoint.Types hiding (simplify)
+import           Language.Fixpoint.Utils.Files
+import           Language.Fixpoint.Misc
+import qualified Data.HashSet            as S
+import           Data.Hashable
+import qualified Data.HashMap.Strict     as M
+import           Data.List (foldl')
+import qualified Data.Graph              as G
+import           Data.Maybe
+import           Text.Printf
+import           Debug.Trace
+
+-------------------------------------------------------------------------
+nontrivsorts :: (Fixpoint a) => Config -> FInfo a -> IO (Result a)
+-------------------------------------------------------------------------
+nontrivsorts cfg fi = do
+  let fi' = simplify' cfg fi
+  writeFInfo cfg fi' $ queryFile Out cfg
+  return mempty
+
+simplify' :: Config -> FInfo a -> FInfo a
+simplify' _ fi = simplifyFInfo (mkNonTrivSorts fi) fi
+
+--------------------------------------------------------------------
+-- | The main data types
+--------------------------------------------------------------------
+type NonTrivSorts = S.HashSet Sort
+type KVarMap      = M.HashMap KVar [Sort]
+data Polarity     = Lhs | Rhs
+type TrivInfo     = (NonTrivSorts, KVarMap)
+--------------------------------------------------------------------
+
+--------------------------------------------------------------------
+mkNonTrivSorts :: FInfo a -> NonTrivSorts
+--------------------------------------------------------------------
+mkNonTrivSorts = {- tracepp "mkNonTrivSorts: " . -}  nonTrivSorts . trivInfo
+
+--------------------------------------------------------------------
+nonTrivSorts :: TrivInfo -> NonTrivSorts
+--------------------------------------------------------------------
+nonTrivSorts ti = S.fromList [s | S s <- ntvs]
+  where
+    ntvs        = [fst3 (f v) | v <- G.reachable g root]
+    (g, f, fv)  = G.graphFromEdges $ ntGraph ti
+    root        = fromMaybe err    $ fv NTV
+    err         = errorstar "nonTrivSorts: cannot find root!"
+
+ntGraph :: TrivInfo -> NTG
+ntGraph ti = [(v,v,vs) | (v, vs) <- groupList $ ntEdges ti]
+
+ntEdges :: TrivInfo -> [(NTV, NTV)]
+ntEdges (nts, kvm) = es ++ [(v, u) | (u, v) <- es]
+  where
+    es = [(NTV, S s) | s       <- S.toList nts         ]
+      ++ [(K k, S s) | (k, ss) <- M.toList kvm, s <- ss]
+
+type NTG = [(NTV, NTV, [NTV])]
+
+data NTV = NTV
+         | K !KVar
+         | S !Sort
+         deriving (Eq, Ord, Show, Generic)
+
+instance Hashable NTV
+
+--------------------------------------------------------------------
+trivInfo :: FInfo a -> TrivInfo
+--------------------------------------------------------------------
+trivInfo fi = updTISubCs (M.elems $ cm fi)
+            . updTIBinds (bs fi)
+            $ (S.empty, M.empty)
+
+updTISubCs :: [SubC a] -> TrivInfo -> TrivInfo
+updTISubCs cs ti = foldl' (flip updTISubC) ti cs
+
+updTISubC :: SubC a -> TrivInfo -> TrivInfo
+updTISubC c = updTI Lhs (slhs c) . updTI Rhs (srhs c)
+
+updTIBinds :: BindEnv -> TrivInfo -> TrivInfo
+updTIBinds be ti = foldl' (flip (updTI Lhs)) ti ts
+  where
+    ts           = [t | (_,_,t) <- bindEnvToList be]
+
+--------------------------------------------------------------------
+updTI :: Polarity -> SortedReft -> TrivInfo -> TrivInfo
+--------------------------------------------------------------------
+updTI p (RR t r) = addKVs t (kvars r) . addNTS p r t
+
+addNTS :: Polarity -> Reft -> Sort -> TrivInfo -> TrivInfo
+addNTS p r t ti
+  | isNTR p r = addSort t ti
+  | otherwise = ti
+
+addKVs :: Sort -> [KVar] -> TrivInfo -> TrivInfo
+addKVs t ks ti     = foldl' addK ti ks
+  where
+    addK (ts, m) k = (ts, inserts k t m)
+
+addSort :: Sort -> TrivInfo -> TrivInfo
+addSort t (ts, m) = (S.insert t ts, m)
+
+--------------------------------------------------------------------
+isNTR :: Polarity -> Reft -> Bool
+--------------------------------------------------------------------
+isNTR Rhs = not . trivR
+isNTR Lhs = not . trivOrSingR
+
+trivR :: Reft -> Bool
+trivR = all trivP . conjuncts . reftPred
+
+trivOrSingR :: Reft -> Bool
+trivOrSingR (Reft (v, p)) = all trivOrSingP $ conjuncts p
+  where
+    trivOrSingP p         = trivP p || singP v p
+
+trivP :: Expr -> Bool
+trivP (PKVar {}) = True
+trivP p          = isTautoPred p
+
+singP :: Symbol -> Expr -> Bool
+singP v (PAtom Eq (EVar x) _)
+  | v == x                    = True
+singP v (PAtom Eq _ (EVar x))
+  | v == x                    = True
+singP _ _                     = False
+
+-------------------------------------------------------------------------
+simplifyFInfo :: NonTrivSorts -> FInfo a -> FInfo a
+-------------------------------------------------------------------------
+simplifyFInfo tm fi = fi {
+     cm   = simplifySubCs   tm $ cm fi
+   , ws   = simplifyWfCs    tm $ ws fi
+   , bs   = simplifyBindEnv tm $ bs fi
+}
+
+simplifyBindEnv :: NonTrivSorts -> BindEnv -> BindEnv
+simplifyBindEnv tm = mapBindEnv (\_ (x, sr) -> (x, simplifySortedReft tm sr))
+
+simplifyWfCs :: NonTrivSorts -> M.HashMap KVar (WfC a) -> M.HashMap KVar (WfC a)
+simplifyWfCs tm = M.filter (isNonTrivialSort tm . snd3 . wrft)
+
+simplifySubCs :: (Eq k, Hashable k)
+              => NonTrivSorts -> M.HashMap k (SubC a) -> M.HashMap k (SubC a)
+simplifySubCs ti cm = trace msg cm'
+  where
+    cm' = tx cm
+    tx  = M.fromList . mapMaybe (simplifySubC ti) . M.toList
+    msg = printf "simplifySUBC: before = %d, after = %d \n" n n'
+    n   = M.size cm
+    n'  = M.size cm'
+
+simplifySubC :: NonTrivSorts -> (b, SubC a) -> Maybe (b, SubC a)
+simplifySubC tm (i, c)
+ | isNonTrivial srhs' = Just (i, c { slhs = slhs' , srhs = srhs' })
+ | otherwise          = Nothing
+  where
+    slhs'             = simplifySortedReft tm (slhs c)
+    srhs'             = simplifySortedReft tm (srhs c)
+
+simplifySortedReft :: NonTrivSorts -> SortedReft -> SortedReft
+simplifySortedReft tm sr
+  | nonTrivial = sr
+  | otherwise  = sr { sr_reft = mempty }
+  where
+    nonTrivial = isNonTrivialSort tm (sr_sort sr)
+
+isNonTrivialSort :: NonTrivSorts -> Sort -> Bool
+isNonTrivialSort tm t = S.member t tm
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/UniqifyBinds.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/UniqifyBinds.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/UniqifyBinds.hs
@@ -0,0 +1,155 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE PatternGuards #-}
+
+-- This module makes it so no binds with different sorts have the same name.
+
+module Language.Fixpoint.Solver.UniqifyBinds (renameAll) where
+
+import           Language.Fixpoint.Types
+import           Language.Fixpoint.Solver.Sanitize (dropDeadSubsts)
+import           Language.Fixpoint.Misc          (fst3, mlookup)
+
+import qualified Data.HashMap.Strict as M
+import qualified Data.HashSet        as S
+import qualified Data.List           as L
+import           Data.Foldable       (foldl')
+import           Data.Maybe          (catMaybes, fromJust, isJust)
+import           Data.Hashable       (Hashable)
+import           GHC.Generics        (Generic)
+import           Control.Arrow       (second)
+import           Control.DeepSeq     (NFData, ($!!))
+-- import Debug.Trace (trace)
+
+--------------------------------------------------------------------------------
+renameAll    :: SInfo a -> SInfo a
+--------------------------------------------------------------------------------
+renameAll fi2 = fi6
+  where
+    fi6       = {-# SCC "dropDead"    #-} dropDeadSubsts  fi5
+    fi5       = {-# SCC "dropUnused"  #-} dropUnusedBinds fi4
+    fi4       = {-# SCC "renameBinds" #-} renameBinds fi3 $!! rnm
+    fi3       = {-# SCC "renameVars"  #-} renameVars fi2 rnm $!! idm
+    rnm       = {-# SCC "mkRenameMap" #-} mkRenameMap $!! bs fi2
+    idm       = {-# SCC "mkIdMap"     #-} mkIdMap fi2
+
+
+--------------------------------------------------------------------------------
+-- | `dropUnusedBinds` replaces the refinements of "unused" binders with "true".
+--   see tests/pos/unused.fq for an example of why this phase is needed.
+--------------------------------------------------------------------------------
+dropUnusedBinds :: SInfo a -> SInfo a
+dropUnusedBinds fi = fi {bs = filterBindEnv isUsed (bs fi)}-- { bs = mapBindEnv tx (bs fi) }
+  where
+    -- _tx i (x, r)
+    -- | isUsed i    = (x, r)
+    -- | otherwise   = (x, top r)
+    isUsed i _x r  = {- tracepp (unwords ["isUsed", show i, showpp _x]) $ -} memberIBindEnv i usedBinds || isTauto r
+    usedBinds      = L.foldl' unionIBindEnv emptyIBindEnv (cEnvs ++ wEnvs)
+    wEnvs          = wenv <$> M.elems (ws fi)
+    cEnvs          = senv <$> M.elems (cm fi)
+
+data Ref
+  = RB !BindId    -- ^ Bind identifier
+  | RI !Integer   -- ^ Constraint identifier?
+    deriving (Eq, Generic)
+
+instance NFData   Ref
+instance Hashable Ref
+
+-- | An `IdMap` stores for each constraint and BindId the
+--   set of other BindIds that it references, i.e. those
+--   where it needs to know when their names gets changed
+type IdMap = M.HashMap Ref (S.HashSet BindId)
+
+-- | A `RenameMap` maps an old name and sort to new name,
+--   represented by a hashmap containing association lists.
+--   `Nothing` as new name means the name is the same as the old.
+type RenameMap = M.HashMap Symbol [(Sort, Maybe Symbol)]
+
+--------------------------------------------------------------------------------
+mkIdMap :: SInfo a -> IdMap
+--------------------------------------------------------------------------------
+mkIdMap fi = M.foldlWithKey' (updateIdMap $ bs fi) M.empty $ cm fi
+
+updateIdMap :: BindEnv -> IdMap -> Integer -> SimpC a -> IdMap
+updateIdMap be m scId s = M.insertWith S.union (RI scId) refSet m'
+  where
+    ids                 = elemsIBindEnv (senv s)
+    nameMap             = M.fromList [(fst $ lookupBindEnv i be, i) | i <- ids]
+    m'                  = foldl' (insertIdIdLinks be nameMap) m ids
+    symSet              = S.fromList $ syms $ crhs s
+    refSet              = namesToIds symSet nameMap
+
+insertIdIdLinks :: BindEnv -> M.HashMap Symbol BindId -> IdMap -> BindId -> IdMap
+insertIdIdLinks be nameMap m i = M.insertWith S.union (RB i) refSet m
+  where
+    sr     = snd $ lookupBindEnv i be
+    symSet = reftFreeVars $ sr_reft sr
+    refSet = namesToIds symSet nameMap
+
+namesToIds :: S.HashSet Symbol -> M.HashMap Symbol BindId -> S.HashSet BindId
+namesToIds xs m = S.fromList $ catMaybes [M.lookup x m | x <- S.toList xs] --TODO why any Nothings?
+
+--------------------------------------------------------------------------------
+mkRenameMap :: BindEnv -> RenameMap
+--------------------------------------------------------------------------------
+mkRenameMap be = foldl' (addId be) M.empty ids
+  where
+    ids = fst3 <$> bindEnvToList be
+
+addId :: BindEnv -> RenameMap -> BindId -> RenameMap
+addId be m i
+  | M.member sym m = addDupId m sym t i
+  | otherwise      = M.insert sym [(t, Nothing)] m
+  where
+    (sym, t)       = second sr_sort $ lookupBindEnv i be
+
+addDupId :: RenameMap -> Symbol -> Sort -> BindId -> RenameMap
+addDupId m sym t i
+  | isJust $ L.lookup t mapping = m
+  | otherwise                   = M.insert sym ((t, Just $ renameSymbol sym i) : mapping) m
+  where
+    mapping = fromJust $ M.lookup sym m
+
+--------------------------------------------------------------------------------
+-- | `renameVars` seems to do the actual work of renaming all the binders
+--   to use their sort-specific names.
+--------------------------------------------------------------------------------
+renameVars :: SInfo a -> RenameMap -> IdMap -> SInfo a
+--------------------------------------------------------------------------------
+renameVars fi rnMap idMap = M.foldlWithKey' (updateRef rnMap) fi idMap
+
+updateRef :: RenameMap -> SInfo a -> Ref -> S.HashSet BindId -> SInfo a
+updateRef rnMap fi rf bset = applySub (mkSubst subs) fi rf
+  where
+    symTList = [second sr_sort $ lookupBindEnv i $ bs fi | i <- S.toList bset]
+    subs     = catMaybes $ mkSubUsing rnMap <$> symTList
+
+mkSubUsing :: RenameMap -> (Symbol, Sort) -> Maybe (Symbol, Expr)
+mkSubUsing m (sym, t) = do
+  newName <- fromJust $ L.lookup t $ mlookup m sym
+  return (sym, eVar newName)
+
+applySub :: Subst -> SInfo a -> Ref -> SInfo a
+applySub sub fi (RB i) = fi { bs = adjustBindEnv go i (bs fi) }
+  where
+    go (sym, sr)       = (sym, subst sub sr)
+
+applySub sub fi (RI i) = fi { cm = M.adjust go i (cm fi) }
+  where
+    go c               = c { _crhs = subst sub (_crhs c) }
+
+--------------------------------------------------------------------------------
+renameBinds :: SInfo a -> RenameMap -> SInfo a
+--------------------------------------------------------------------------------
+renameBinds fi m = fi { bs = bindEnvFromList $ renameBind m <$> beList }
+  where
+    beList       = bindEnvToList $ bs fi
+
+renameBind :: RenameMap -> (BindId, Symbol, SortedReft) -> (BindId, Symbol, SortedReft)
+renameBind m (i, sym, sr)
+  | Just newSym <- mnewSym = (i, newSym, sr)
+  | otherwise              = (i, sym,    sr)
+  where
+    t                      = sr_sort sr
+    mnewSym                = fromJust $ L.lookup t $ mlookup m sym
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/UniqifyKVars.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/UniqifyKVars.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/UniqifyKVars.hs
@@ -0,0 +1,116 @@
+{- | This module creates new bindings for each argument of each kvar.
+     It also makes sure that all arguments to each kvar are explicit.
+
+     For example,
+
+```
+bind 0 x
+bind 1 v
+constraint:
+  env [0; 1]
+  rhs $k_42 // implicit substitutions [x:=x], [v:=v]
+wf:
+  env [0]
+  reft {v : int | [$k_42]}
+```
+
+becomes
+
+```
+bind 0 x
+bind 1 v
+bind 2 lq_karg$x$k_42
+constraint:
+  env [0; 1]
+  rhs $k_42[lq_karg$x$k_42:=x][lq_karg$v$k_42:=v]
+
+wf:
+  env [2]
+  reft {lq_karg$v$k_42 : int | [$k_42]}
+```
+
+-}
+
+module Language.Fixpoint.Solver.UniqifyKVars (wfcUniqify) where
+
+import           Language.Fixpoint.Types
+import           Language.Fixpoint.Types.Visitor (mapKVarSubsts)
+import qualified Data.HashMap.Strict as M
+import           Data.Foldable       (foldl')
+
+--------------------------------------------------------------------------------
+wfcUniqify    :: SInfo a -> SInfo a
+wfcUniqify fi = updateWfcs $ remakeSubsts fi
+
+
+
+-- mapKVarSubsts (\k su -> restrict table k su xs)
+--------------------------------------------------------------------------------
+remakeSubsts :: SInfo a -> SInfo a
+--------------------------------------------------------------------------------
+remakeSubsts fi = mapKVarSubsts (remakeSubst fi) fi
+
+remakeSubst :: SInfo a -> KVar -> Subst -> Subst
+remakeSubst fi k su = foldl' (updateSubst k) su (kvarDomain fi k)
+
+updateSubst :: KVar -> Subst -> Symbol -> Subst
+updateSubst k (Su su) sym
+  = case M.lookup sym su of
+      Just z  -> Su $ M.delete sym $ M.insert ksym z          su
+      Nothing -> Su $                M.insert ksym (eVar sym) su
+    where
+      kx      = kv k
+      ksym    = kArgSymbol sym kx
+
+-- / | sym `M.member` su = Su $ M.delete sym $ M.insert ksym (su M.! sym) su
+-- /  | otherwise         = Su $                M.insert ksym (eVar sym)   su
+
+--------------------------------------------------------------------------------
+updateWfcs :: SInfo a -> SInfo a
+--------------------------------------------------------------------------------
+updateWfcs fi = M.foldl' updateWfc fi (ws fi)
+
+updateWfc :: SInfo a -> WfC a -> SInfo a
+updateWfc fi w    = fi'' { ws = M.insert k w' (ws fi) }
+  where
+    w'            = updateWfCExpr (subst su) w'' 
+    w''           = w { wenv = insertsIBindEnv newIds mempty, wrft = (v', t, k) }
+    (_, fi'')     = newTopBind v' (trueSortedReft t) fi'
+    (fi', newIds) = foldl' (accumBindsIfValid k) (fi, []) (elemsIBindEnv $ wenv w)
+    (v, t, k)     = wrft w
+    v'            = kArgSymbol v (kv k)
+    su            = mkSubst ((v, EVar v'):[(x, eVar $ kArgSymbol x (kv k)) | x <- kvarDomain fi k])
+
+accumBindsIfValid :: KVar -> (SInfo a, [BindId]) -> BindId -> (SInfo a, [BindId])
+accumBindsIfValid k (fi, ids) i = if renamable then accumBinds k (fi, ids) i else (fi, i : ids)
+  where
+    (_, sr)                     = lookupBindEnv i      (bs fi)
+    renamable                   = isValidInRefinements (sr_sort sr)
+
+accumBinds :: KVar -> (SInfo a, [BindId]) -> BindId -> (SInfo a, [BindId])
+accumBinds k (fi, ids) i = (fi', i' : ids)
+  where
+    (oldSym, sr) = lookupBindEnv i (bs fi)
+    newSym       = {- tracepp "kArgSymbol" $ -}  kArgSymbol oldSym (kv k)
+    (i', fi')    = newTopBind newSym sr fi
+
+-- | `newTopBind` ignores the actual refinements as they are not relevant
+--   in the kvar parameters (as suggested by BLC.)
+newTopBind :: Symbol -> SortedReft -> SInfo a -> (BindId, SInfo a)
+newTopBind x sr fi = (i', fi {bs = be'})
+  where
+    (i', be')   = insertBindEnv x (top sr) (bs fi)
+
+--------------------------------------------------------------
+
+isValidInRefinements :: Sort -> Bool
+isValidInRefinements FInt        = True
+isValidInRefinements FReal       = True
+isValidInRefinements FNum        = False
+isValidInRefinements FFrac       = False
+isValidInRefinements (FObj _)    = True
+isValidInRefinements (FVar _)    = True
+isValidInRefinements (FFunc _ _) = False
+isValidInRefinements (FAbs  _ t) = isValidInRefinements t
+isValidInRefinements (FTC _)     = True --TODO is this true? seems to be required for e.g. ResolvePred.hs
+isValidInRefinements (FApp _ _)  = True
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Solver/Worklist.hs b/liquid-fixpoint/src/Language/Fixpoint/Solver/Worklist.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Solver/Worklist.hs
@@ -0,0 +1,200 @@
+{-# LANGUAGE BangPatterns          #-}
+{-# LANGUAGE TupleSections         #-}
+
+module Language.Fixpoint.Solver.Worklist
+       ( -- * Worklist type is opaque
+         Worklist, Stats
+
+         -- * Initialize
+       , init
+
+         -- * Pop off a constraint
+       , pop
+
+         -- * Add a constraint and all its dependencies
+       , push
+
+         -- * Constraints with Concrete RHS
+       , unsatCandidates
+
+         -- * Statistics
+       , wRanks
+       )
+       where
+
+import           Prelude hiding (init)
+import           Language.Fixpoint.Types.PrettyPrint
+import qualified Language.Fixpoint.Types   as F
+import           Language.Fixpoint.Graph.Types
+import           Language.Fixpoint.Graph   (isTarget)
+
+import           Control.Arrow             (first)
+import qualified Data.HashMap.Strict       as M
+import qualified Data.Set                  as S
+import qualified Data.List                 as L
+import           Text.PrettyPrint.HughesPJ (text)
+
+-- | Worklist ------------------------------------------------------------------
+
+data Worklist a = WL { wCs     :: !WorkSet
+                     , wPend   :: !(CMap ())
+                     , wDeps   :: !(CMap [F.SubcId])
+                     , wCm     :: !(CMap (F.SimpC a))
+                     , wRankm  :: !(CMap Rank)
+                     , wLast   :: !(Maybe F.SubcId)
+                     , wRanks  :: !Int
+                     , wTime   :: !Int
+                     , wConcCs :: ![F.SubcId]
+                     }
+
+data Stats = Stats { numKvarCs  :: !Int
+                   , numConcCs  :: !Int
+                   , _numSccs   :: !Int
+                   } deriving (Eq, Show)
+
+instance PPrint (Worklist a) where
+  pprintTidy k = pprintTidy k . S.toList . wCs
+
+instance PTable Stats where
+  ptable s = DocTable [ (text "# Sliced Constraints", pprint (numKvarCs s))
+                      , (text "# Target Constraints", pprint (numConcCs s))
+                      ]
+
+instance PTable (Worklist a) where
+  ptable = ptable . stats
+
+
+-- | WorkItems ------------------------------------------------------------
+
+type WorkSet  = S.Set WorkItem
+
+data WorkItem = WorkItem { wiCId  :: !F.SubcId   -- ^ Constraint Id
+                         , wiTime :: !Int   -- ^ Time at which inserted
+                         , wiRank :: !Rank  -- ^ Rank of constraint
+                         } deriving (Eq, Show)
+
+instance PPrint WorkItem where
+  pprintTidy _ = text . show
+
+instance Ord WorkItem where
+  compare (WorkItem i1 t1 r1) (WorkItem i2 t2 r2)
+    = mconcat [ compare (rScc r1) (rScc r2)   -- SCC
+              , compare t1 t2                 -- TimeStamp
+              , compare (rIcc r1) (rIcc r2)   -- Inner SCC
+              , compare (rTag r1) (rTag r2)   -- Tag
+              , compare i1         i2         -- Otherwise Set drops items
+              ]
+
+--------------------------------------------------------------------------------
+-- | Initialize worklist and slice out irrelevant constraints ------------------
+--------------------------------------------------------------------------------
+init :: SolverInfo a b -> Worklist a
+--------------------------------------------------------------------------------
+init sI    = WL { wCs     = items
+                , wPend   = addPends M.empty kvarCs
+                , wDeps   = cSucc cd
+                , wCm     = cm
+                , wRankm  = {- F.tracepp "W.init ranks" -} rankm
+                , wLast   = Nothing
+                , wRanks  = cNumScc cd
+                , wTime   = 0
+                , wConcCs = concCs
+                }
+  where
+    cm        = F.cm  (siQuery sI)
+    cd        = siDeps sI
+    rankm     = cRank cd
+    items     = S.fromList $ workItemsAt rankm 0 <$> kvarCs
+    concCs    = fst <$> ics
+    kvarCs    = fst <$> iks
+    (ics,iks) = L.partition (isTarget . snd) (M.toList cm)
+
+---------------------------------------------------------------------------
+-- | Candidate Constraints to be checked AFTER computing Fixpoint ---------
+---------------------------------------------------------------------------
+unsatCandidates   :: Worklist a -> [F.SimpC a]
+---------------------------------------------------------------------------
+unsatCandidates w = [ lookupCMap (wCm w) i | i <- wConcCs w ]
+
+
+---------------------------------------------------------------------------
+pop  :: Worklist a -> Maybe (F.SimpC a, Worklist a, Bool, Int)
+---------------------------------------------------------------------------
+pop w = do
+  (i, is) <- sPop $ wCs w
+  Just ( lookupCMap (wCm w) i
+       , popW w i is
+       , newSCC w i
+       , rank w i
+       )
+
+popW :: Worklist a -> F.SubcId -> WorkSet -> Worklist a
+popW w i is = w { wCs   = is
+                , wLast = Just i
+                , wPend = remPend (wPend w) i }
+
+
+newSCC :: Worklist a -> F.SubcId -> Bool
+newSCC oldW i = (rScc <$> oldRank) /= (rScc <$> newRank)
+  where
+    oldRank   = lookupCMap rankm <$> wLast oldW
+    newRank   = Just              $  lookupCMap rankm i
+    rankm     = wRankm oldW
+
+rank :: Worklist a -> F.SubcId -> Int
+rank w i = rScc $ lookupCMap (wRankm w) i
+
+---------------------------------------------------------------------------
+push :: F.SimpC a -> Worklist a -> Worklist a
+---------------------------------------------------------------------------
+push c w = w { wCs   = sAdds (wCs w) wis'
+             , wTime = 1 + t
+             , wPend = addPends wp is'
+             }
+  where
+    i    = F.subcId c
+    is'  = filter (not . isPend wp) $ M.lookupDefault [] i (wDeps w)
+    wis' = workItemsAt (wRankm w) t <$> is'
+    t    = wTime w
+    wp   = wPend w
+
+workItemsAt :: CMap Rank -> Int -> F.SubcId -> WorkItem
+workItemsAt !r !t !i = WorkItem { wiCId  = i
+                                , wiTime = t
+                                , wiRank = lookupCMap r i }
+
+
+
+---------------------------------------------------------------------------
+stats :: Worklist a -> Stats
+---------------------------------------------------------------------------
+stats w = Stats (kn w) (cn w) (wRanks w)
+  where
+    kn  = M.size . wCm
+    cn  = length . wConcCs
+
+---------------------------------------------------------------------------
+-- | Pending API
+---------------------------------------------------------------------------
+
+addPends :: CMap () -> [F.SubcId] -> CMap ()
+addPends = L.foldl' addPend
+
+addPend :: CMap () -> F.SubcId -> CMap ()
+addPend m i = M.insert i () m
+
+remPend :: CMap () -> F.SubcId -> CMap ()
+remPend m i = M.delete i m
+
+isPend :: CMap () -> F.SubcId -> Bool
+isPend w i = M.member i w
+
+---------------------------------------------------------------------------
+-- | Set API --------------------------------------------------------------
+---------------------------------------------------------------------------
+
+sAdds :: WorkSet -> [WorkItem] -> WorkSet
+sAdds = L.foldl' (flip S.insert)
+
+sPop :: WorkSet -> Maybe (F.SubcId, WorkSet)
+sPop = fmap (first wiCId) . S.minView
diff --git a/liquid-fixpoint/src/Language/Fixpoint/SortCheck.hs b/liquid-fixpoint/src/Language/Fixpoint/SortCheck.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/SortCheck.hs
@@ -0,0 +1,1015 @@
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE TypeSynonymInstances  #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TupleSections         #-}
+{-# LANGUAGE OverloadedStrings     #-}
+{-# LANGUAGE PatternGuards         #-}
+
+-- | This module has the functions that perform sort-checking, and related
+-- operations on Fixpoint expressions and predicates.
+
+module Language.Fixpoint.SortCheck  (
+  -- * Sort Substitutions
+    TVSubst
+  , Env
+
+  -- * Checking Well-Formedness
+  , checkSorted
+  , checkSortedReft
+  , checkSortedReftFull
+  , checkSortFull
+  , pruneUnsortedReft
+
+  -- * Sort inference
+  , sortExpr
+  , checkSortExpr
+  , exprSort
+
+  -- * Unify
+  , unifyFast
+  , unifySorts
+
+  -- * Apply Substitution
+  , apply
+
+  -- * Exported Sorts
+  , boolSort
+  , strSort
+
+  -- * Sort-Directed Transformations
+  , Elaborate (..)
+
+  -- * Predicates on Sorts
+  , isFirstOrder
+  , isMono
+  ) where
+
+
+import           Control.Monad
+import           Control.Monad.Except      (MonadError(..))
+import qualified Data.HashMap.Strict       as M
+import qualified Data.List                 as L
+import           Data.Maybe                (mapMaybe, fromMaybe)
+
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Misc
+import           Language.Fixpoint.Types hiding   (subst)
+import           Language.Fixpoint.Types.Visitor  (mapExpr, stripCasts, foldSort)
+import qualified Language.Fixpoint.Smt.Theories   as Thy
+import           Text.PrettyPrint.HughesPJ
+import           Text.Printf
+
+-- import Debug.Trace
+
+--------------------------------------------------------------------------------
+-- | Predicates on Sorts -------------------------------------------------------
+--------------------------------------------------------------------------------
+isMono :: Sort -> Bool
+--------------------------------------------------------------------------------
+isMono             = null . foldSort fv []
+  where
+    fv vs (FVar i) = i : vs
+    fv vs _        = vs
+
+
+--------------------------------------------------------------------------------
+-- | Elaborate: make polymorphic instantiation explicit via casts,
+--   make applications monomorphic for SMTLIB. This deals with
+--   polymorphism by `elaborate`-ing all refinements except for
+--   KVars. THIS IS NOW MANDATORY as sort-variables can be instantiated
+--   to `int` and `bool`.
+--------------------------------------------------------------------------------
+class Elaborate a where
+  elaborate :: String -> SEnv Sort -> a -> a
+
+instance Elaborate (SInfo a) where
+  elaborate x senv si = si
+    { cm      = elaborate x senv <$> cm      si
+    , bs      = elaborate x senv  $  bs      si
+    , asserts = elaborate x senv <$> asserts si
+    }
+
+instance (Elaborate e) => (Elaborate (Triggered e)) where
+  elaborate x env t = fmap (elaborate x env) t
+
+instance Elaborate Sort where
+  elaborate _ _ = go
+   where
+      go s | isString s = strSort
+      go (FAbs i s)    = FAbs i $ go s
+      go (FFunc s1 s2) = funSort (go s1) (go s2)
+      go (FApp s1 s2)  = FApp    (go s1) (go s2)
+      go s             = s
+      funSort :: Sort -> Sort -> Sort
+      funSort = FApp . FApp funcSort
+
+instance Elaborate Expr where
+  elaborate msg env = elabNumeric . elabApply . elabExpr msg env
+
+instance Elaborate (Symbol, Sort) where
+  elaborate msg env (x, s) = (x,) (elaborate msg env s)
+
+instance Elaborate a => Elaborate [a]  where
+  elaborate msg env xs = elaborate msg env <$> xs
+
+elabNumeric :: Expr -> Expr
+elabNumeric = mapExpr go
+  where
+    go (ETimes e1 e2)
+      | exprSort "txn1" e1 == FReal
+      , exprSort "txn2" e2 == FReal
+      = ERTimes e1 e2
+    go (EDiv   e1 e2)
+      | exprSort ("txn3: " ++ showpp e1) e1 == FReal
+      , exprSort "txn4" e2 == FReal
+      = ERDiv   e1 e2
+    go e
+      = e
+
+instance Elaborate SortedReft where
+  elaborate x env (RR s (Reft (v, e))) = RR s (Reft (v, e'))
+    where
+      e'   = elaborate x env' e
+      env' = insertSEnv v s env
+
+instance Elaborate BindEnv where
+  elaborate z env = mapBindEnv (\i (x, sr) -> (x, elaborate (z ++ msg i x sr) env sr))
+    where
+      msg i x sr  = unwords [" elabBE",  show i, show x, show sr]
+
+instance Elaborate (SimpC a) where
+  elaborate x env c = c {_crhs = elaborate x env (_crhs c) }
+
+-- instance Elaborate Qualifier where
+  -- elaborate env q = q { qParams = elaborate env (qParams q)
+                      -- , qBody   = elaborate [env ++ qParams] (qBody q)
+                      -- }
+
+elabExpr :: String -> SEnv Sort -> Expr -> Expr
+elabExpr msg γ e
+  = case runCM0 $ elab f e of
+      Left msg -> die $ err dummySpan (d msg)
+      Right s  -> fst s
+    where
+      f   = (`lookupSEnvWithDistance` γ')
+      γ'  = γ `mappend` Thy.theorySEnv
+      d m = vcat [ "elaborate" <+> text msg <+> "failed on:"
+                 , nest 4 (pprint e)
+                 , "with error"
+                 , nest 4 (text m)
+                 , "in environment"
+                 , nest 4 (pprint $ subEnv γ' e)
+                 ]
+
+elabApply :: Expr -> Expr
+elabApply = go
+  where
+    go e                  = case splitArgs e of
+                             (e', []) -> step e'
+                             (f , es) -> defuncEApp (go f) (mapFst go <$> es)
+    step (PAnd [])        = PTrue
+    step (POr [])         = PFalse
+    step (ENeg e)         = ENeg (go  e)
+    step (EBin o e1 e2)   = EBin o (go e1) (go e2)
+    step (EIte e1 e2 e3)  = EIte (go e1) (go e2) (go e3)
+    step (ECst e t)       = ECst (go e) t
+    step (PAnd ps)        = PAnd (go <$> ps)
+    step (POr ps)         = POr  (go <$> ps)
+    step (PNot p)         = PNot (go p)
+    step (PImp p q)       = PImp (go p) (go q)
+    step (PIff p q)       = PIff (go p) (go q)
+    step (PExist bs p)    = PExist bs (go p)
+    step (PAll   bs p)    = PAll   bs (go p)
+    step (PAtom r e1 e2)  = PAtom r (go e1) (go e2)
+    step e@(EApp {})      = go e
+    step (ELam b e)       = ELam b (go e)
+    step (PGrad k su e)   = PGrad k su (go e)
+    step e@(PKVar {})     = e
+    step e@(ESym {})      = e
+    step e@(ECon {})      = e
+    step e@(EVar {})      = e
+    -- ELam, ETApp, ETAbs, PAll, PExist
+    step e                = error $ "TODO elabApply: " ++ showpp e
+
+--------------------------------------------------------------------------------
+-- | Sort Inference ------------------------------------------------------------
+--------------------------------------------------------------------------------
+sortExpr :: SrcSpan -> SEnv Sort -> Expr -> Sort
+sortExpr l γ e = case runCM0 $ checkExpr f e of
+    Left msg -> die $ err l (d msg)
+    Right s  -> s
+  where
+    f   = (`lookupSEnvWithDistance` γ)
+    d m = vcat [ "sortExpr failed on expression:"
+               , nest 4 (pprint e)
+               , "with error:"
+               , nest 4 (text m)
+               , "in environment"
+               , nest 4 (pprint γ)
+               ]
+
+checkSortExpr :: SEnv Sort -> Expr -> Maybe Sort
+checkSortExpr γ e = case runCM0 $ checkExpr f e of
+    Left _   -> Nothing
+    Right s  -> Just s
+  where
+    f x  = case lookupSEnv x γ of
+            Just z  -> Found z
+            Nothing -> Alts []
+
+subEnv :: (Subable e) => SEnv a -> e -> SEnv a
+subEnv g e = intersectWithSEnv (\t _ -> t) g g'
+  where
+    g' = fromListSEnv $ (, ()) <$> syms e
+
+
+--------------------------------------------------------------------------------
+-- | Checking Refinements ------------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- | Types used throughout checker
+
+type StateM = Int
+
+newtype CheckM a = CM {runCM :: StateM -> (StateM, Either String a)}
+
+type Env      = Symbol -> SESearch Sort
+
+
+instance Monad CheckM where
+  return x     = CM $ \i -> (i, Right x)
+  (CM m) >>= f = CM $ \i -> case m i of
+                             (j, Left s)  -> (j, Left s)
+                             (j, Right x) -> runCM (f x) j
+
+
+instance MonadError String CheckM where
+  throwError s = CM $ \i -> (i, Left s)
+  (CM m) `catchError` f = CM $ \i -> case m i of
+                                      (j, Left s) -> runCM (f s) j
+                                      (j, Right x) -> (j, Right x)
+
+withError :: CheckM a -> String -> CheckM a
+act `withError` e' = act `catchError` (\e -> throwError (e ++ "\n  because\n" ++ e'))
+
+instance Functor CheckM where
+  fmap f (CM m) = CM $ \i -> case m i of {(j, Left s) -> (j, Left s); (j, Right x) -> (j, Right $ f x)}
+
+instance Applicative CheckM where
+  pure x     = CM $ \i -> (i, Right x)
+  (CM f) <*> (CM m) = CM $ \i -> case m i of
+                             (j, Left s)  -> (j, Left s)
+                             (_, Right x) -> case f i of
+                                 (k, Left s)  -> (k, Left s)
+                                 (k, Right g) -> (k, Right $ g x)
+
+initCM :: StateM
+initCM = 42
+
+runCM0 :: CheckM a -> Either String a
+runCM0 act = snd $ runCM act initCM
+
+class Freshable a where
+  fresh   :: CheckM a
+  refresh :: a -> CheckM a
+  refresh _ = fresh
+
+instance Freshable Int where
+  fresh = CM (\n -> (n+1, Right n))
+
+instance Freshable [Int] where
+  fresh   = mapM (const fresh) [0..]
+  refresh = mapM refresh
+
+--------------------------------------------------------------------------------
+-- | Checking Refinements ------------------------------------------------------
+--------------------------------------------------------------------------------
+checkSortedReft :: SEnv SortedReft -> [Symbol] -> SortedReft -> Maybe Doc
+checkSortedReft env xs sr = applyNonNull Nothing oops unknowns
+  where
+    oops                  = Just . (text "Unknown symbols:" <+>) . toFix
+    unknowns              = [ x | x <- syms sr, x `notElem` v : xs, not (x `memberSEnv` env)]
+    Reft (v,_)            = sr_reft sr
+
+checkSortedReftFull :: Checkable a => SEnv SortedReft -> a -> Maybe Doc
+checkSortedReftFull γ t
+  = case runCM0 $ check γ' t of
+      Left e  -> Just (text e)
+      Right _ -> Nothing
+    where
+      γ' = sr_sort <$> γ
+
+checkSortFull :: Checkable a => SEnv SortedReft -> Sort -> a -> Maybe Doc
+checkSortFull γ s t
+  = case runCM0 $ checkSort γ' s t of
+      Left e  -> Just (text e)
+      Right _ -> Nothing
+    where
+      γ' = sr_sort <$> γ
+
+checkSorted :: Checkable a => SEnv Sort -> a -> Maybe Doc
+checkSorted γ t
+  = case runCM0 $ check γ t of
+      Left e   -> Just (text e)
+      Right _  -> Nothing
+
+pruneUnsortedReft :: SEnv Sort -> SortedReft -> SortedReft
+pruneUnsortedReft γ (RR s (Reft (v, p))) = RR s (Reft (v, tx p))
+  where
+    tx   = pAnd . mapMaybe (checkPred' f) . conjuncts
+    f    = (`lookupSEnvWithDistance` γ')
+    γ'   = insertSEnv v s γ
+    -- wmsg t r = "WARNING: prune unsorted reft:\n" ++ showFix r ++ "\n" ++ t
+
+checkPred' :: Env -> Expr -> Maybe Expr
+checkPred' f p = res -- traceFix ("checkPred: p = " ++ showFix p) $ res
+  where
+    res        = case runCM0 $ checkPred f p of
+                   Left _err   -> {- trace (_wmsg _err p) -} Nothing
+                   Right _  -> Just p
+
+class Checkable a where
+  check     :: SEnv Sort -> a -> CheckM ()
+  checkSort :: SEnv Sort -> Sort -> a -> CheckM ()
+
+  checkSort γ _ = check γ
+
+instance Checkable Expr where
+  check γ e = void $ checkExpr f e
+   where f =  (`lookupSEnvWithDistance` γ)
+
+  checkSort γ s e = void $ checkExpr f (ECst e s)
+    where
+      f           =  (`lookupSEnvWithDistance` γ)
+
+instance Checkable SortedReft where
+  check γ (RR s (Reft (v, ra))) = check γ' ra
+   where
+     γ' = insertSEnv v s γ
+
+--------------------------------------------------------------------------------
+-- | Checking Expressions ------------------------------------------------------
+--------------------------------------------------------------------------------
+checkExpr                  :: Env -> Expr -> CheckM Sort
+checkExpr _ (ESym _)       = return strSort
+checkExpr _ (ECon (I _))   = return FInt
+checkExpr _ (ECon (R _))   = return FReal
+checkExpr _ (ECon (L _ s)) = return s
+checkExpr f (EVar x)       = checkSym f x
+checkExpr f (ENeg e)       = checkNeg f e
+checkExpr f (EBin o e1 e2) = checkOp f e1 o e2
+checkExpr f (EIte p e1 e2) = checkIte f p e1 e2
+checkExpr f (ECst e t)     = checkCst f t e
+checkExpr f (EApp g e)     = checkApp f Nothing g e
+checkExpr f (PNot p)       = checkPred f p >> return boolSort
+checkExpr f (PImp p p')    = mapM_ (checkPred f) [p, p'] >> return boolSort
+checkExpr f (PIff p p')    = mapM_ (checkPred f) [p, p'] >> return boolSort
+checkExpr f (PAnd ps)      = mapM_ (checkPred f) ps >> return boolSort
+checkExpr f (POr ps)       = mapM_ (checkPred f) ps >> return boolSort
+checkExpr f (PAtom r e e') = checkRel f r e e' >> return boolSort
+checkExpr _ (PKVar {})     = return boolSort
+checkExpr f (PGrad _ _ e)  = checkPred f e >> return boolSort
+
+checkExpr f (PAll  bs e )  = checkExpr (addEnv f bs) e
+checkExpr f (PExist bs e)  = checkExpr (addEnv f bs) e
+checkExpr f (ELam (x,t) e) = FFunc t <$> checkExpr (addEnv f [(x,t)]) e
+checkExpr _ (ETApp _ _)    = error "SortCheck.checkExpr: TODO: implement ETApp"
+checkExpr _ (ETAbs _ _)    = error "SortCheck.checkExpr: TODO: implement ETAbs"
+
+addEnv :: Eq a => (a -> SESearch b) -> [(a, b)] -> a -> SESearch b
+addEnv f bs x
+  = case L.lookup x bs of
+      Just s  -> Found s
+      Nothing -> f x
+
+--------------------------------------------------------------------------------
+-- | Elaborate expressions with types to make polymorphic instantiation explicit.
+--------------------------------------------------------------------------------
+elab :: Env -> Expr -> CheckM (Expr, Sort)
+--------------------------------------------------------------------------------
+elab f e@(EBin o e1 e2) = do
+  (e1', s1) <- elab f e1
+  (e2', s2) <- elab f e2
+  s         <- checkExpr f e
+  return (EBin o (ECst e1' s1) (ECst e2' s2), s)
+
+elab f (EApp e1@(EApp _ _) e2) = do
+  (e1', _, e2', s2, s) <- elabEApp f e1 e2
+  return (eAppC s e1' (ECst e2' s2), s)
+
+elab f (EApp e1 e2) = do
+  (e1', s1, e2', s2, s) <- elabEApp f e1 e2
+  return (eAppC s (ECst e1' s1) (ECst e2' s2), s)
+
+elab _ e@(ESym _) =
+  return (e, strSort)
+
+elab _ e@(ECon (I _)) =
+  return (e, FInt)
+
+elab _ e@(ECon (R _)) =
+  return (e, FReal)
+
+elab _ e@(ECon (L _ s)) =
+  return (e, s)
+
+elab _ e@(PKVar _ _) =
+  return (e, boolSort)
+
+elab f (PGrad k su e) = 
+  ((, boolSort) . PGrad k su . fst) <$> elab f e 
+
+elab f e@(EVar x) =
+  (e,) <$> checkSym f x
+
+elab f (ENeg e) = do
+  (e', s) <- elab f e
+  return (ENeg e', s)
+
+elab f (EIte p e1 e2) = do
+  (p', _)  <- elab f p
+  (e1', _) <- elab f e1
+  (e2', _) <- elab f e2
+  s <- checkIte f p e1 e2
+  return (EIte p' e1' e2', s)
+
+elab f (ECst e t) = do
+  (e', _) <- elab f e
+  return (ECst e' t, t)
+
+elab f (PNot p) = do
+  (e', _) <- elab f p
+  return (PNot e', boolSort)
+
+elab f (PImp p1 p2) = do
+  (p1', _) <- elab f p1
+  (p2', _) <- elab f p2
+  return (PImp p1' p2', boolSort)
+
+elab f (PIff p1 p2) = do
+  (p1', _) <- elab f p1
+  (p2', _) <- elab f p2
+  return (PIff p1' p2', boolSort)
+
+elab f (PAnd ps) = do
+  ps' <- mapM (elab f) ps
+  return (PAnd (fst <$> ps'), boolSort)
+
+elab f (POr ps) = do
+  ps' <- mapM (elab f) ps
+  return (POr (fst <$> ps'), boolSort)
+
+elab f e@(PAtom Eq e1 e2) = do
+  t1        <- checkExpr f e1
+  t2        <- checkExpr f e2
+  (t1',t2') <- unite f e  t1 t2 `withError` (errElabExpr e)
+  e1'       <- elabAs f t1' e1
+  e2'       <- elabAs f t2' e2
+  return (PAtom Eq (ECst e1' t1') (ECst e2' t2'), boolSort)
+
+elab f (PAtom r e1 e2)
+  | r == Ueq || r == Une = do
+  (e1', _) <- elab f e1
+  (e2', _) <- elab f e2
+  return (PAtom r e1' e2', boolSort)
+
+elab f (PAtom r e1 e2) = do
+  e1' <- uncurry Thy.toInt <$> elab f e1
+  e2' <- uncurry Thy.toInt <$> elab f e2
+  return (PAtom r e1' e2', boolSort)
+
+elab f (PExist bs e) = do
+  (e', s) <- elab (addEnv f bs) e
+  let bs' = elaborate "PExist Args" mempty bs
+  return (PExist bs' e', s)
+
+elab f (PAll bs e) = do
+  (e', s) <- elab (addEnv f bs) e
+  let bs' = elaborate "PAll Args" mempty bs
+  return (PAll bs' e', s)
+
+elab f (ELam (x,t) e) = do
+  (e', s) <- elab (addEnv f [(x,t)]) e
+  let t' = elaborate "ELam Arg" mempty t
+  return (ELam (x,t') (ECst e' s), FFunc t s)
+
+elab _ (ETApp _ _) =
+  error "SortCheck.elab: TODO: implement ETApp"
+elab _ (ETAbs _ _) =
+  error "SortCheck.elab: TODO: implement ETAbs"
+
+-- elabAs :: Env -> Sort -> Expr -> CheckM Expr
+-- elabAs f t e = tracepp msg <$> elabAs' f t e
+--  where
+--    msg  = "elabAs: t = " ++ show t ++ " e = " ++ show e
+
+elabAs :: Env -> Sort -> Expr -> CheckM Expr
+elabAs f t (EApp e1 e2) = elabAppAs f t e1 e2
+elabAs f _ e            = fst <$> elab f e
+
+elabAppAs :: Env -> Sort -> Expr -> Expr -> CheckM Expr
+elabAppAs f t g e = do
+  gT       <- generalize =<< checkExpr f g
+  eT       <- checkExpr f e
+  (iT, oT, isu) <- checkFunSort gT
+  let ge    = Just (EApp g e)
+  su       <- unifyMany f ge isu [oT, iT] [t, eT]
+  let tg    = apply su gT
+  g'       <- elabAs f tg g
+  let te    = apply su eT
+  e'       <- elabAs f te e
+  return    $ EApp (ECst g' tg) (ECst e' te)
+
+elabEApp  :: Env -> Expr -> Expr -> CheckM (Expr, Sort, Expr, Sort, Sort)
+elabEApp f e1 e2 = do
+  (e1', s1) <- elab f e1
+  (e2', s2) <- elab f e2
+  s         <- elabAppSort f e1 e2 s1 s2
+  return      (e1', s1, e2', s2, s)
+
+--------------------------------------------------------------------------------
+-- | defuncEApp monomorphizes function applications.
+--------------------------------------------------------------------------------
+defuncEApp :: Expr -> [(Expr, Sort)] -> Expr
+defuncEApp e es
+  | Thy.isSmt2App (stripCasts e) es
+  = eApps e (fst <$> es)
+  | otherwise
+  = L.foldl' makeApplication e es
+
+-- e1 e2 => App (App runFun e1) (toInt e2)
+makeApplication :: Expr -> (Expr, Sort) -> Expr
+makeApplication e1 (e2, s) = ECst (EApp (EApp (EVar f) e1) e2') s
+  where
+    f                      = makeFunSymbol (spec s)
+    e2'                    = Thy.toInt e2 (exprSort "makeApplication" e2)
+    -- s                      = fromMaybe (resultType e1 e2) sO
+    spec                 :: Sort -> Sort
+    spec (FAbs _ s)      = spec s
+    spec s               = s
+
+makeFunSymbol :: Sort -> Symbol
+makeFunSymbol s
+  | (FApp (FTC c) _) <- s
+  , Thy.isConName setConName c
+  = setApplyName 1
+  | (FApp (FApp (FTC c) _) _) <- s
+  , Thy.isConName mapConName c
+  = mapApplyName 1
+  | (FApp (FTC bv) (FTC s))   <- s
+  , Thy.isConName bitVecName bv
+  , Just _ <- Thy.sizeBv s
+  = bitVecApplyName 1
+  | FTC c <- s, c == boolFTyCon
+  = boolApplyName 1
+  | s == FReal
+  = realApplyName 1
+  | otherwise
+  = intApplyName 1
+
+splitArgs :: Expr -> (Expr, [(Expr, Sort)])
+splitArgs = go []
+  where
+    go acc (ECst (EApp e1 e) s) = go ((e, s) : acc) e1
+    go _   e@EApp{}             = errorstar $ "UNEXPECTED: splitArgs: EApp without output type: " ++ showpp e
+    -- go acc (ECst e _)           = go acc e
+    go acc e                    = (e, acc)
+
+--------------------------------------------------------------------------------
+-- | Expressions sort  ---------------------------------------------------------
+--------------------------------------------------------------------------------
+exprSort :: String -> Expr -> Sort
+exprSort msg = go
+  where
+    go (ECst _ s) = s
+    go (ELam (_, sx) e) = FFunc sx (go e)
+    go (EApp e ex)
+      | FFunc sx s <- genSort (go e)
+      = maybe s (`apply` s) $ unifySorts (go ex) sx
+    go e = errorstar ("\nexprSort [" ++ msg ++ "] on unexpected expressions " ++ show e)
+
+genSort :: Sort -> Sort
+genSort (FAbs _ t) = genSort t
+genSort t          = t
+
+unite :: Env -> Expr -> Sort -> Sort -> CheckM (Sort, Sort)
+unite f e t1 t2 = do
+  su <- unifys f (Just e) [t1] [t2]
+  return (apply su t1, apply su t2)
+
+
+-- | Helper for checking symbol occurrences
+checkSym :: Env -> Symbol -> CheckM Sort
+checkSym f x
+  = case f x of
+     Found s -> return s
+     Alts xs -> throwError $ errUnboundAlts x xs
+
+-- | Helper for checking if-then-else expressions
+checkIte :: Env -> Expr -> Expr -> Expr -> CheckM Sort
+checkIte f p e1 e2 = do
+  checkPred f p
+  t1 <- checkExpr f e1
+  t2 <- checkExpr f e2
+  ((`apply` t1) <$> unifys f e' [t1] [t2]) `withError` (errIte e1 e2 t1 t2)
+  where
+    e' = Just (EIte  p e1 e2)
+
+-- | Helper for checking cast expressions
+checkCst :: Env -> Sort -> Expr -> CheckM Sort
+checkCst f t (EApp g e)
+  = checkApp f (Just t) g e
+checkCst f t e
+  = do t' <- checkExpr f e
+       ((`apply` t) <$> unifys f (Just e) [t] [t']) `withError` (errCast e t' t)
+
+elabAppSort :: Env -> Expr -> Expr -> Sort -> Sort -> CheckM Sort
+elabAppSort f e1 e2 s1 s2 = do
+  s1'  <- generalize s1
+  let e = Just (EApp e1 e2)
+  case s1' of
+    FFunc sx s -> (`apply` s) <$> unifys f e [sx] [s2]
+    FVar i     -> do j <- refresh 0 
+                     k <- refresh 0 
+                     (`apply` (FVar k)) <$> unifyMany f e (updateVar i (FFunc (FVar j) (FVar j)) emptySubst) [FVar j] [s2]
+    _          -> errorstar ("elabAppSort for expr" ++ showpp (EApp e1 e2) ++ " with sorts" ++ showpp s1  ++ " and " ++ showpp s2 )
+
+checkApp :: Env -> Maybe Sort -> Expr -> Expr -> CheckM Sort
+checkApp f to g es
+  = snd <$> checkApp' f to g es
+
+checkExprAs :: Env -> Sort -> Expr -> CheckM Sort
+checkExprAs f t (EApp g e)
+  = checkApp f (Just t) g e
+checkExprAs f t e
+  = do t' <- checkExpr f e
+       θ  <- unifys f (Just e) [t'] [t]
+       return $ apply θ t
+
+-- | Helper for checking uninterpreted function applications
+-- | Checking function application should be curried,
+-- | consider checking
+-- | fromJust :: Maybe a -> a, f :: Maybe (b -> b), x: c |- fromJust f x
+
+checkApp' :: Env -> Maybe Sort -> Expr -> Expr -> CheckM (TVSubst, Sort)
+checkApp' f to g e = do
+  gt       <- checkExpr f g >>= generalize
+  et       <- checkExpr f e
+  (it, ot, isu) <- checkFunSort gt
+  let ge    = Just (EApp g e)
+  θ        <- unifyMany f ge isu [it] [et]
+  let t     = apply θ ot
+  case to of
+    Nothing    -> return (θ, t)
+    Just t'    -> do θ' <- unifyMany f ge θ [t] [t']
+                     let ti = apply θ' et
+                     _ <- checkExprAs f ti e
+                     return (θ', apply θ' t)
+
+{-
+checkApp' f to g' e
+  = do gt           <- checkExpr f g
+       gt'          <- generalize gt
+       (its, ot)    <- sortFunction (length es) gt'
+       ets          <- mapM (checkExpr f) es
+       θ            <- unifys f its ets
+       let t         = apply θ ot
+       case to of
+         Nothing    -> return (θ, t)
+         Just t'    -> do θ' <- unifyMany f θ [t] [t']
+                          let ts = apply θ' <$> ets
+                          _ <- zipWithM (checkExprAs f) ts es
+                          return (θ', apply θ' t)
+  where
+    (g, es) = splitEApp $ EApp g' e
+-}
+
+-- | Helper for checking binary (numeric) operations
+checkNeg :: Env -> Expr -> CheckM Sort
+checkNeg f e = do
+  t <- checkExpr f e
+  checkNumeric f t >> return t
+
+checkOp :: Env -> Expr -> Bop -> Expr -> CheckM Sort
+checkOp f e1 o e2
+  = do t1 <- checkExpr f e1
+       t2 <- checkExpr f e2
+       checkOpTy f (EBin o e1 e2) t1 t2
+
+
+checkOpTy :: Env -> Expr -> Sort -> Sort -> CheckM Sort
+checkOpTy _ _ FInt FInt
+  = return FInt
+
+checkOpTy _ _ FReal FReal
+  = return FReal
+-- Coercing int to real is somewhat suspicious, but z3 seems
+-- to be ok with it
+checkOpTy _ _ FInt  FReal
+  = return FReal
+checkOpTy _ _ FReal FInt
+  = return FReal
+
+checkOpTy f _ t t'
+  | t == t'
+  = checkNumeric f t >> return t
+
+checkOpTy _ e t t'
+  = throwError $ errOp e t t'
+
+checkFractional :: Env -> Sort -> CheckM ()
+checkFractional f s@(FObj l)
+  = do t <- checkSym f l
+       unless (t == FFrac) (throwError $ errNonFractional s)
+checkFractional _ s
+  = unless (isReal s) (throwError $ errNonFractional s)
+
+checkNumeric :: Env -> Sort -> CheckM ()
+checkNumeric f s@(FObj l)
+  = do t <- checkSym f l
+       unless (t == FNum || t == FFrac) (throwError $ errNonNumeric s)
+checkNumeric _ s
+  = unless (isNumeric s) (throwError $ errNonNumeric s)
+
+--------------------------------------------------------------------------------
+-- | Checking Predicates -------------------------------------------------------
+--------------------------------------------------------------------------------
+
+checkPred                  :: Env -> Expr -> CheckM ()
+checkPred f e = checkExpr f e >>= checkBoolSort e
+
+checkBoolSort :: Expr -> Sort -> CheckM ()
+checkBoolSort e s
+ | s == boolSort = return ()
+ | otherwise     = throwError $ errBoolSort e s
+
+
+-- | Checking Relations
+checkRel :: Env -> Brel -> Expr -> Expr -> CheckM ()
+checkRel f Eq e1 e2 = do
+  t1 <- checkExpr f e1
+  t2 <- checkExpr f e2
+  su <- (unifys f (Just e) [t1] [t2]) `withError` (errRel e t1 t2)
+  _  <- checkExprAs f (apply su t1) e1
+  _  <- checkExprAs f (apply su t2) e2
+  checkRelTy f e Eq t1 t2
+  where
+    e = PAtom Eq e1 e2
+
+checkRel f r  e1 e2 = do
+  t1 <- checkExpr f e1
+  t2 <- checkExpr f e2
+  checkRelTy f (PAtom r e1 e2) r t1 t2
+
+checkRelTy :: Env -> Expr -> Brel -> Sort -> Sort -> CheckM ()
+checkRelTy _ _ Ueq _ _             = return ()
+checkRelTy _ _ Une _ _             = return ()
+checkRelTy f _ _ s1@(FObj l) s2@(FObj l') | l /= l'
+  = (checkNumeric f s1 >> checkNumeric f s2) `withError` (errNonNumerics l l')
+checkRelTy _ _ _ FReal FReal = return ()
+checkRelTy _ _ _ FInt  FReal = return ()
+checkRelTy _ _ _ FReal FInt  = return ()
+checkRelTy f _ _ FInt  s2    = checkNumeric    f s2 `withError` (errNonNumeric s2)
+checkRelTy f _ _ s1    FInt  = checkNumeric    f s1 `withError` (errNonNumeric s1)
+checkRelTy f _ _ FReal s2    = checkFractional f s2 `withError` (errNonFractional s2)
+checkRelTy f _ _ s1    FReal = checkFractional f s1 `withError` (errNonFractional s1)
+
+-- checkRelTy _ e Eq t1 t2
+--   | t1 == boolSort || t2 == boolSort = throwError $ errRel e t1 t2
+-- checkRelTy _ e Ne t1 t2
+--   | t1 == boolSort || t2 == boolSort = throwError $ errRel e t1 t2
+
+checkRelTy f e Eq t1 t2            = void (unifys f (Just e) [t1] [t2] `withError` (errRel e t1 t2))
+checkRelTy f e Ne t1 t2            = void (unifys f (Just e) [t1] [t2] `withError` (errRel e t1 t2))
+
+checkRelTy _ e _  t1 t2            = unless (t1 == t2) (throwError $ errRel e t1 t2)
+
+--------------------------------------------------------------------------------
+-- | Sort Unification
+--------------------------------------------------------------------------------
+unify :: Env -> Maybe Expr -> Sort -> Sort -> Maybe TVSubst
+--------------------------------------------------------------------------------
+unify f e t1 t2
+  = case runCM0 $ unify1 f e emptySubst t1 t2 of
+      Left _   -> Nothing
+      Right su -> Just su
+
+--------------------------------------------------------------------------------
+unifySorts :: Sort -> Sort -> Maybe TVSubst
+--------------------------------------------------------------------------------
+unifySorts   = unifyFast False emptyEnv
+  where
+    emptyEnv = const $ die $ err dummySpan "SortChecl: lookup in Empty Env "
+
+--------------------------------------------------------------------------------
+-- | Fast Unification; `unifyFast True` is just equality
+--------------------------------------------------------------------------------
+unifyFast :: Bool -> Env -> Sort -> Sort -> Maybe TVSubst
+--------------------------------------------------------------------------------
+unifyFast False f = unify f Nothing
+unifyFast True  _ = uMono
+  where
+    uMono t1 t2
+     | t1 == t2   = Just emptySubst
+     | otherwise  = Nothing
+
+
+--------------------------------------------------------------------------------
+unifys :: Env -> Maybe Expr -> [Sort] -> [Sort] -> CheckM TVSubst
+--------------------------------------------------------------------------------
+unifys f e = unifyMany f e emptySubst
+
+unifyMany :: Env -> Maybe Expr -> TVSubst -> [Sort] -> [Sort] -> CheckM TVSubst
+unifyMany f e θ ts ts'
+  | length ts == length ts' = foldM (uncurry . unify1 f e) θ $ zip ts ts'
+  | otherwise               = throwError $ errUnifyMany ts ts'
+
+
+unify1 :: Env -> Maybe Expr -> TVSubst -> Sort -> Sort -> CheckM TVSubst
+unify1 f e θ (FVar i) t
+  = unifyVar f e θ i t
+unify1 f e θ t (FVar i)
+  = unifyVar f e θ i t
+unify1 f e θ (FApp t1 t2) (FApp t1' t2')
+  = unifyMany f e θ [t1, t2] [t1', t2']
+unify1 _ _ θ (FTC l1) (FTC l2)
+  | isListTC l1 && isListTC l2
+  = return θ
+unify1 f e θ t1@(FAbs _ _) t2 = do
+  t1'<- generalize t1
+  unifyMany f e θ [t1'] [t2]
+unify1 f e θ t1 t2@(FAbs _ _) = do
+  t2' <- generalize t2
+  unifyMany f e θ [t1] [t2']
+unify1 _ _ θ s1 s2
+  | isString s1, isString s2
+  = return θ
+
+unify1 _ _ θ FInt  FReal = return θ
+
+unify1 _ _ θ FReal FInt  = return θ
+
+unify1 f e θ t FInt = do
+  checkNumeric f t `withError` (errUnify e t FInt)
+  return θ
+
+unify1 f e θ FInt t = do
+  checkNumeric f t `withError` (errUnify e FInt t)
+  return θ
+
+unify1 f e θ (FFunc t1 t2) (FFunc t1' t2') = do
+  unifyMany f e θ [t1, t2] [t1', t2']
+
+unify1 _ e θ t1 t2
+  | t1 == t2
+  = return θ
+  | otherwise
+  = throwError $ errUnify e t1 t2
+
+subst :: (Int, Sort) -> Sort -> Sort
+subst (j,tj) t@(FVar i)
+  | i == j    = tj
+  | otherwise = t
+subst su (FApp t1 t2)  = FApp (subst su t1) (subst su t2)
+subst _  (FTC l)       = FTC l
+subst su (FFunc t1 t2) = FFunc (subst su t1) (subst su t2)
+subst (j,tj) (FAbs i t)
+  | i == j    = FAbs i t
+  | otherwise = FAbs i $ subst (j,tj) t
+subst _  s             = s
+
+
+generalize :: Sort -> CheckM Sort
+generalize (FAbs i t) = do
+  v      <- refresh 0
+  let sub = (i, FVar v)
+  subst sub <$> generalize t
+generalize t =
+  return t
+
+unifyVar :: Env -> Maybe Expr -> TVSubst -> Int -> Sort -> CheckM TVSubst
+unifyVar _ _ θ i t@(FVar j)
+  = case lookupVar i θ of
+      Just t'       -> if t == t' then return θ else return $ updateVar j t' θ
+      Nothing       -> return $ updateVar i t θ
+
+unifyVar f e θ i t
+  = case lookupVar i θ of
+      Just (FVar j) -> return $ updateVar i t $ updateVar j t θ
+      Just t'       -> if t == t' then return θ else unify1 f e θ t t'
+      Nothing       -> return $ updateVar i t θ
+
+--------------------------------------------------------------------------------
+-- | Applying a Type Substitution ----------------------------------------------
+--------------------------------------------------------------------------------
+apply :: TVSubst -> Sort -> Sort
+--------------------------------------------------------------------------------
+apply θ          = sortMap f
+  where
+    f t@(FVar i) = fromMaybe t (lookupVar i θ)
+    f t          = t
+
+--------------------------------------------------------------------------------
+sortMap :: (Sort -> Sort) -> Sort -> Sort
+--------------------------------------------------------------------------------
+sortMap f (FAbs i t)    = FAbs i (sortMap f t)
+sortMap f (FFunc t1 t2) = FFunc (sortMap f t1) (sortMap f t2)
+sortMap f (FApp t1 t2)  = FApp  (sortMap f t1) (sortMap f t2)
+sortMap f t             = f t
+
+--------------------------------------------------------------------------------
+-- | Deconstruct a function-sort -----------------------------------------------
+--------------------------------------------------------------------------------
+
+checkFunSort :: Sort -> CheckM (Sort, Sort, TVSubst)
+checkFunSort (FAbs _ t)    = checkFunSort t
+checkFunSort (FFunc t1 t2) = return (t1, t2, emptySubst)
+checkFunSort (FVar i)      = do j <- refresh 0 
+                                k <- refresh 0 
+                                return (FVar j, FVar k, updateVar i (FFunc (FVar j) (FVar k)) emptySubst)
+checkFunSort t             = throwError $ errNonFunction 1 t
+
+{-
+sortFunction :: Int -> Sort -> CheckM ([Sort], Sort)
+sortFunction i t
+  = case functionSort t of
+     Nothing          -> throwError $ errNonFunction i t
+     Just (_, ts, t') -> if length ts < i
+                          then throwError $ errNonFunction i t
+                          else let (its, ots) = splitAt i ts
+                               in return (its, foldl FFunc t' ots)
+-}
+
+--------------------------------------------------------------------------------
+-- | API for manipulating Sort Substitutions -----------------------------------
+--------------------------------------------------------------------------------
+
+newtype TVSubst = Th (M.HashMap Int Sort) deriving (Show)
+
+lookupVar :: Int -> TVSubst -> Maybe Sort
+lookupVar i (Th m)   = M.lookup i m
+
+updateVar :: Int -> Sort -> TVSubst -> TVSubst
+updateVar i t (Th m) = Th (M.insert i t m)
+
+emptySubst :: TVSubst
+emptySubst = Th M.empty
+
+--------------------------------------------------------------------------------
+-- | Error messages ------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+errElabExpr    :: Expr -> String
+errElabExpr e  = printf "Elaborate fails on %s" (showpp e)
+
+errUnify :: Maybe Expr -> Sort -> Sort -> String
+errUnify eo t1 t2 = printf "Cannot unify %s with %s %s"
+                      (showpp t1) (showpp t2) (unifyExpr eo)
+
+unifyExpr :: Maybe Expr -> String
+unifyExpr Nothing  = ""
+unifyExpr (Just e) = "in expression: " ++ showpp e
+
+errUnifyMany :: [Sort] -> [Sort] -> String
+errUnifyMany ts ts'  = printf "Cannot unify types with different cardinalities %s and %s"
+                         (showpp ts) (showpp ts')
+
+errRel :: Expr -> Sort -> Sort -> String
+errRel e t1 t2       = printf "Invalid Relation %s with operand types %s and %s"
+                         (showpp e) (showpp t1) (showpp t2)
+
+errOp :: Expr -> Sort -> Sort -> String
+errOp e t t'
+  | t == t'          = printf "Operands have non-numeric types %s in %s"
+                         (showpp t) (showpp e)
+  | otherwise        = printf "Operands have different types %s and %s in %s"
+                         (showpp t) (showpp t') (showpp e)
+
+errIte :: Expr -> Expr -> Sort -> Sort -> String
+errIte e1 e2 t1 t2   = printf "Mismatched branches in Ite: then %s : %s, else %s : %s"
+                         (showpp e1) (showpp t1) (showpp e2) (showpp t2)
+
+errCast :: Expr -> Sort -> Sort -> String
+errCast e t' t       = printf "Cannot cast %s of sort %s to incompatible sort %s"
+                         (showpp e) (showpp t') (showpp t)
+
+errUnboundAlts :: Symbol -> [Symbol] -> String
+errUnboundAlts x xs  = printf "Unbound Symbol %s\n Perhaps you meant: %s"
+                        (showpp x)
+                        (foldr1 (\w s -> w ++ ", " ++ s) (showpp <$> xs))
+
+errNonFunction :: Int -> Sort -> String
+errNonFunction i t   = printf "The sort %s is not a function with at least %s arguments\n" (showpp t) (showpp i)
+
+errNonNumeric :: Sort -> String
+errNonNumeric  l     = printf "The sort %s is not numeric" (showpp l)
+
+errNonNumerics :: Symbol -> Symbol -> String
+errNonNumerics l l'  = printf "FObj sort %s and %s are different and not numeric" (showpp l) (showpp l')
+
+errNonFractional :: Sort -> String
+errNonFractional  l  = printf "The sort %s is not fractional" (showpp l)
+
+errBoolSort :: Expr -> Sort -> String
+errBoolSort     e s  = printf "Expressions %s should have bool sort, but has %s" (showpp e) (showpp s)
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types.hs b/liquid-fixpoint/src/Language/Fixpoint/Types.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types.hs
@@ -0,0 +1,18 @@
+-- | This module re-exports the data types, operations and
+--   serialization functions for representing Fixpoint's
+--   implication (i.e. subtyping) and well-formedness
+--   constraints.
+
+module Language.Fixpoint.Types (module X) where
+
+import Language.Fixpoint.Types.PrettyPrint      as X
+import Language.Fixpoint.Types.Names            as X
+import Language.Fixpoint.Types.Errors           as X
+import Language.Fixpoint.Types.Spans            as X
+import Language.Fixpoint.Types.Sorts            as X
+import Language.Fixpoint.Types.Refinements      as X
+import Language.Fixpoint.Types.Substitutions    as X
+import Language.Fixpoint.Types.Environments     as X
+import Language.Fixpoint.Types.Constraints      as X
+import Language.Fixpoint.Types.Utils            as X
+import Language.Fixpoint.Types.Triggers         as X
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Config.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Config.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Config.hs
@@ -0,0 +1,200 @@
+{-# LANGUAGE DeriveDataTypeable        #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE UndecidableInstances      #-}
+{-# LANGUAGE DeriveGeneric             #-}
+
+module Language.Fixpoint.Types.Config (
+    Config  (..)
+  , defConfig
+  , withPragmas
+
+  , getOpts
+
+  -- * SMT Solver options
+  , SMTSolver (..)
+
+  -- * Eliminate options
+  , Eliminate (..)
+  , useElim
+
+  -- * parallel solving options
+  , defaultMinPartSize
+  , defaultMaxPartSize
+  , multicore
+
+  , queryFile
+) where
+
+import Data.Serialize                (Serialize (..))
+import Control.Monad
+import GHC.Generics
+import System.Console.CmdArgs
+import System.Console.CmdArgs.Explicit
+import System.Environment
+
+import Language.Fixpoint.Utils.Files
+
+
+--------------------------------------------------------------------------------
+withPragmas :: Config -> [String] -> IO Config
+--------------------------------------------------------------------------------
+withPragmas = foldM withPragma
+
+withPragma :: Config -> String -> IO Config
+withPragma c s = withArgs [s] $ cmdArgsRun
+          config { modeValue = (modeValue config) { cmdArgsValue = c } }
+
+--------------------------------------------------------------------------------
+-- | Configuration Options -----------------------------------------------------
+--------------------------------------------------------------------------------
+
+defaultMinPartSize :: Int
+defaultMinPartSize = 500
+
+defaultMaxPartSize :: Int
+defaultMaxPartSize = 700
+
+
+data Config
+  = Config {
+      srcFile     :: FilePath            -- ^ src file (*.hs, *.ts, *.c, or even *.fq or *.bfq)
+    , cores       :: Maybe Int           -- ^ number of cores used to solve constraints
+    , minPartSize :: Int                 -- ^ Minimum size of a partition
+    , maxPartSize :: Int                 -- ^ Maximum size of a partition. Overrides minPartSize
+    , solver      :: SMTSolver           -- ^ which SMT solver to use
+    , linear      :: Bool                -- ^ not interpret div and mul in SMT
+    , stringTheory :: Bool               -- ^ interpretation of string theory by SMT
+    , defunction  :: Bool                -- ^ defunctionalize (use 'apply' for all uninterpreted applications)
+    , allowHO     :: Bool                -- ^ allow higher order binders in the logic environment
+    , allowHOqs   :: Bool                -- ^ allow higher order qualifiers
+    , eliminate   :: Eliminate           -- ^ eliminate non-cut KVars
+    , elimBound   :: Maybe Int           -- ^ maximum length of KVar chain to eliminate
+    , elimStats   :: Bool                -- ^ print eliminate stats
+    , solverStats :: Bool                -- ^ print solver stats
+    , metadata    :: Bool                -- ^ print meta-data associated with constraints
+    , stats       :: Bool                -- ^ compute constraint statistics
+    , parts       :: Bool                -- ^ partition FInfo into separate fq files
+    , save        :: Bool                -- ^ save FInfo as .bfq and .fq file
+    , minimize    :: Bool                -- ^ min .fq by delta debug (unsat with min constraints)
+    , minimizeQs  :: Bool                -- ^ min .fq by delta debug (sat with min qualifiers)
+    , minimizeKs  :: Bool                -- ^ min .fq by delta debug (sat with min kvars)
+    , minimalSol  :: Bool                -- ^ shrink final solution by pruning redundant qualfiers from fixpoint
+    , gradual     :: Bool                -- ^ solve "gradual" constraints
+    , extensionality   :: Bool           -- ^ allow function extensionality
+    , alphaEquivalence :: Bool           -- ^ allow lambda alpha equivalence axioms
+    , betaEquivalence  :: Bool           -- ^ allow lambda beta equivalence axioms
+    , normalForm       :: Bool           -- ^ allow lambda normal-form equivalence axioms
+    , autoKuts         :: Bool           -- ^ ignore given kut variables
+    , nonLinCuts       :: Bool           -- ^ Treat non-linear vars as cuts
+    , noslice          :: Bool           -- ^ Disable non-concrete KVar slicing
+    , rewriteAxioms    :: Bool           -- ^ allow axiom instantiation via rewriting
+    , arithmeticAxioms :: Bool           -- ^ allow axiom instantiation on arithmetic expressions
+    } deriving (Eq,Data,Typeable,Show,Generic)
+
+instance Default Config where
+  def = defConfig
+
+---------------------------------------------------------------------------------------
+
+data SMTSolver = Z3 | Cvc4 | Mathsat
+                 deriving (Eq, Data, Typeable, Generic)
+
+instance Default SMTSolver where
+  def = Z3
+
+instance Show SMTSolver where
+  show Z3      = "z3"
+  show Cvc4    = "cvc4"
+  show Mathsat = "mathsat"
+
+---------------------------------------------------------------------------------------
+-- | Eliminate describes the number of KVars to eliminate:
+--   None = use PA/Quals for ALL k-vars, i.e. no eliminate
+--   Some = use PA/Quals for CUT k-vars, i.e. eliminate non-cuts
+--   All  = eliminate ALL k-vars, solve cut-vars to TRUE
+---------------------------------------------------------------------------------------
+data Eliminate
+  = None
+  | Some
+  | All
+  deriving (Eq, Data, Typeable, Generic)
+
+instance Serialize Eliminate
+
+instance Default Eliminate where
+  def = None
+
+instance Show Eliminate where
+  show None = "none"
+  show Some = "some"
+  show All  = "all"
+
+
+useElim :: Config -> Bool
+useElim cfg = eliminate cfg /= None
+
+---------------------------------------------------------------------------------------
+
+defConfig :: Config
+defConfig = Config {
+    srcFile          = "out"   &= args    &= typFile
+  , defunction       = False   &= help "Allow higher order binders into fixpoint environment"
+  , solver           = def     &= help "Name of SMT Solver"
+  , linear           = False   &= help "Use uninterpreted integer multiplication and division"
+  , stringTheory     = False   &= help "Interpretation of String Theory by SMT"
+  , allowHO          = False   &= help "Allow higher order binders into fixpoint environment"
+  , allowHOqs        = False   &= help "Allow higher order qualifiers"
+  , eliminate        = None    &= help "Eliminate KVars [none = quals for all-kvars, cuts = quals for cut-kvars, all = eliminate all-kvars (TRUE for cuts)]"
+  , elimBound        = Nothing &= name "elimBound"  &= help "(alpha) Maximum eliminate-chain depth"
+  , elimStats        = False   &= help "(alpha) Print eliminate stats"
+  , solverStats      = False   &= help "Print solver stats"
+  , save             = False   &= help "Save Query as .fq and .bfq files"
+  , metadata         = False   &= help "Print meta-data associated with constraints"
+  , stats            = False   &= help "Compute constraint statistics"
+  , parts            = False   &= help "Partition constraints into indepdendent .fq files"
+  , cores            = def     &= help "(numeric) Number of threads to use"
+  , minPartSize      = defaultMinPartSize &= help "(numeric) Minimum partition size when solving in parallel"
+  , maxPartSize      = defaultMaxPartSize &= help "(numeric) Maximum partiton size when solving in parallel."
+  , minimize         = False &= help "Delta debug to minimize fq file (unsat with min constraints)"
+  , minimizeQs       = False &= help "Delta debug to minimize fq file (sat with min qualifiers)"
+  , minimizeKs       = False &= help "Delta debug to minimize fq file (sat with max kvars replaced by True)"
+  , minimalSol       = False &= help "Shrink fixpoint by removing implied qualifiers"
+  , gradual          = False &= help "Solve gradual-refinement typing constraints"
+  , extensionality   = False &= help "Allow function extensionality axioms"
+  , alphaEquivalence = False &= help "Allow lambda alpha equivalence axioms"
+  , betaEquivalence  = False &= help "Allow lambda alpha equivalence axioms"
+  , normalForm       = False  &= help "Allow lambda normal-form equivalence axioms"
+  , autoKuts         = False &= help "Ignore given Kut vars, compute from scratch"
+  , nonLinCuts       = False &= help "Treat non-linear kvars as cuts"
+  , noslice          = False &= help "Disable non-concrete KVar slicing"
+  , rewriteAxioms    = False &= help "allow axiom instantiation via rewriting"
+  , arithmeticAxioms = False &= help "Disable non-concrete KVar slicing"
+  }
+  &= verbosity
+  &= program "fixpoint"
+  &= help    "Predicate Abstraction Based Horn-Clause Solver"
+  &= summary "fixpoint Copyright 2009-15 Regents of the University of California."
+  &= details [ "Predicate Abstraction Based Horn-Clause Solver"
+             , ""
+             , "To check a file foo.fq type:"
+             , "  fixpoint foo.fq"
+             ]
+
+config :: Mode (CmdArgs Config)
+config = cmdArgsMode defConfig
+
+getOpts :: IO Config
+getOpts = do md <- cmdArgs defConfig
+             putStrLn banner
+             return md
+
+banner :: String
+banner =  "\n\nLiquid-Fixpoint Copyright 2013-15 Regents of the University of California.\n"
+       ++ "All Rights Reserved.\n"
+
+multicore :: Config -> Bool
+multicore cfg = cores cfg /= Just 1
+
+queryFile :: Ext -> Config -> FilePath
+queryFile e = extFileName e . srcFile
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Constraints.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Constraints.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Constraints.hs
@@ -0,0 +1,715 @@
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveFunctor              #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE NoMonomorphismRestriction  #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE GADTs                      #-}
+{-# LANGUAGE PatternGuards              #-}
+
+-- | This module contains the top-level QUERY data types and elements,
+--   including (Horn) implication & well-formedness constraints and sets.
+
+module Language.Fixpoint.Types.Constraints (
+
+   -- * Top-level Queries
+    FInfo, SInfo, GInfo (..), FInfoWithOpts(..)
+  , convertFormat
+  , Solver
+
+   -- * Serializing
+  , toFixpoint
+  , writeFInfo
+  , saveQuery
+
+   -- * Constructing Queries
+  , fi
+
+  -- * Constraints
+  , WfC (..), isGWfc, updateWfCExpr
+  , SubC, SubcId
+  , mkSubC, subcId, sid, senv, slhs, srhs, stag, subC, wfC
+  , SimpC (..)
+  , Tag
+  , TaggedC, clhs, crhs
+  , strengthenLhs
+
+  -- * Accessing Constraints
+  , addIds
+  , sinfo
+  , shiftVV
+
+  -- * Qualifiers
+  , Qualifier (..)
+  , trueQual
+  , qualifier
+  , mkQual, remakeQual
+
+  -- * Results
+  , FixSolution
+  , GFixSolution, toGFixSol
+  , Result (..)
+
+  -- * Cut KVars
+  , Kuts (..)
+  , ksMember
+
+  -- * Higher Order Logic
+  , HOInfo (..)
+  , allowHO
+  , allowHOquals
+
+  -- * Axioms
+  , AxiomEnv (..)
+  , Equation (..)
+  , Rewrite  (..)
+  , getEqBody
+  ) where
+
+import qualified Data.Binary as B
+import           Data.Generics             (Data)
+import           Data.Typeable             (Typeable)
+import           GHC.Generics              (Generic)
+import qualified Data.List                 as L -- (sort, nub, delete)
+import           Data.Maybe                (catMaybes)
+import           Control.DeepSeq
+import           Control.Monad             (void)
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Config hiding (allowHO)
+import           Language.Fixpoint.Types.Triggers
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Types.Errors
+import           Language.Fixpoint.Types.Spans
+import           Language.Fixpoint.Types.Sorts
+import           Language.Fixpoint.Types.Refinements
+import           Language.Fixpoint.Types.Substitutions
+import           Language.Fixpoint.Types.Environments
+import qualified Language.Fixpoint.Utils.Files as Files
+
+import           Language.Fixpoint.Misc
+import           Text.PrettyPrint.HughesPJ
+import qualified Data.HashMap.Strict       as M
+import qualified Data.HashSet              as S
+
+--------------------------------------------------------------------------------
+-- | Constraints ---------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+{-@ type Tag = { v : [Int] | len v == 1 } @-}
+
+type Tag           = [Int]
+
+data WfC a  =  WfC  { wenv  :: !IBindEnv
+                    , wrft  :: (Symbol, Sort, KVar)
+                    , winfo :: !a
+                    }
+             | GWfC { wenv  :: !IBindEnv
+                    , wrft  :: !(Symbol, Sort, KVar)
+                    , winfo :: !a
+                    , wexpr :: !Expr
+                    }
+              deriving (Eq, Generic, Functor)
+
+
+updateWfCExpr :: (Expr -> Expr) -> WfC a -> WfC a
+updateWfCExpr _ w@(WfC {})  = w
+updateWfCExpr f w@(GWfC {}) = w{wexpr = f (wexpr w)}
+
+isGWfc :: WfC a -> Bool
+isGWfc (GWfC _ _ _ _) = True
+isGWfc (WfC _ _ _)    = False
+
+type SubcId = Integer
+
+data SubC a = SubC { _senv  :: !IBindEnv
+                   , slhs   :: !SortedReft
+                   , srhs   :: !SortedReft
+                   , _sid   :: !(Maybe SubcId)
+                   , _stag  :: !Tag
+                   , _sinfo :: !a
+                   }
+              deriving (Eq, Generic, Functor)
+
+data SimpC a = SimpC { _cenv  :: !IBindEnv
+                     , _crhs  :: !Expr
+                     , _cid   :: !(Maybe Integer)
+                     , _ctag  :: !Tag
+                     , _cinfo :: !a
+                     }
+              deriving (Generic, Functor)
+
+strengthenLhs :: Expr -> SubC a -> SubC a
+strengthenLhs e subc = subc {slhs = go (slhs subc)}
+  where
+    go (RR s (Reft(v, r))) = RR s (Reft (v, pAnd [r, e]))
+
+class TaggedC c a where
+  senv  :: c a -> IBindEnv
+  sid   :: c a -> Maybe Integer
+  stag  :: c a -> Tag
+  sinfo :: c a -> a
+  clhs  :: BindEnv -> c a -> [(Symbol, SortedReft)]
+  crhs  :: c a -> Expr
+
+instance TaggedC SimpC a where
+  senv      = _cenv
+  sid       = _cid
+  stag      = _ctag
+  sinfo     = _cinfo
+  crhs      = _crhs
+  clhs be c = envCs be (senv c)
+
+instance TaggedC SubC a where
+  senv      = _senv
+  sid       = _sid
+  stag      = _stag
+  sinfo     = _sinfo
+  crhs      = reftPred . sr_reft . srhs
+  clhs be c = sortedReftBind (slhs c) : envCs be (senv c)
+
+sortedReftBind :: SortedReft -> (Symbol, SortedReft)
+sortedReftBind sr = (x, sr)
+  where
+    Reft (x, _)   = sr_reft sr
+
+subcId :: (TaggedC c a) => c a -> SubcId
+subcId = mfromJust "subCId" . sid
+
+---------------------------------------------------------------------------
+-- | Solutions and Results
+---------------------------------------------------------------------------
+
+type GFixSolution = GFixSol Expr
+
+type FixSolution  = M.HashMap KVar Expr
+newtype GFixSol e = GSol (M.HashMap KVar (e, [e]))
+  deriving (Generic, Monoid, Functor)
+
+toGFixSol :: M.HashMap KVar (e, [e]) -> GFixSol e
+toGFixSol = GSol
+
+
+data Result a = Result { resStatus    :: !(FixResult a)
+                       , resSolution  :: !FixSolution
+                       , gresSolution :: !GFixSolution }
+                deriving (Generic, Show)
+
+instance Monoid (Result a) where
+  mempty        = Result mempty mempty mempty
+  mappend r1 r2 = Result stat soln gsoln
+    where
+      stat      = mappend (resStatus r1)    (resStatus r2)
+      soln      = mappend (resSolution r1)  (resSolution r2)
+      gsoln     = mappend (gresSolution r1) (gresSolution r2)
+
+instance (Ord a, Fixpoint a) => Fixpoint (FixResult (SubC a)) where
+  toFix Safe             = text "Safe"
+  -- toFix (UnknownError d) = text $ "Unknown Error: " ++ d
+  toFix (Crash xs msg)   = vcat $ [ text "Crash!" ] ++  pprSinfos "CRASH: " xs ++ [parens (text msg)]
+  toFix (Unsafe xs)      = vcat $ text "Unsafe:" : pprSinfos "WARNING: " xs
+
+pprSinfos :: (Ord a, Fixpoint a) => String -> [SubC a] -> [Doc]
+pprSinfos msg = map ((text msg <>) . toFix) . L.sort . fmap sinfo
+
+instance Fixpoint a => Show (WfC a) where
+  show = showFix
+
+instance Fixpoint a => Show (SubC a) where
+  show = showFix
+
+instance Fixpoint a => Show (SimpC a) where
+  show = showFix
+
+instance Fixpoint a => PPrint (SubC a) where
+  pprintTidy _ = toFix
+
+instance Fixpoint a => PPrint (SimpC a) where
+  pprintTidy _ = toFix
+
+instance Fixpoint a => PPrint (WfC a) where
+  pprintTidy _ = toFix
+
+instance Fixpoint a => Fixpoint (SubC a) where
+  toFix c     = hang (text "\n\nconstraint:") 2 bd
+     where bd =   toFix (senv c)
+              $+$ text "lhs" <+> toFix (slhs c)
+              $+$ text "rhs" <+> toFix (srhs c)
+              $+$ (pprId (sid c) <+> text "tag" <+> toFix (stag c))
+              $+$ toFixMeta (text "constraint" <+> pprId (sid c)) (toFix (sinfo c))
+
+instance Fixpoint a => Fixpoint (SimpC a) where
+  toFix c     = hang (text "\n\nsimpleConstraint:") 2 bd
+     where bd =   toFix (senv c)
+              $+$ text "rhs" <+> toFix (crhs c)
+              $+$ (pprId (sid c) <+> text "tag" <+> toFix (stag c))
+              $+$ toFixMeta (text "simpleConstraint" <+> pprId (sid c)) (toFix (sinfo c))
+
+instance Fixpoint a => Fixpoint (WfC a) where
+  toFix w     = hang (text "\n\nwf:") 2 bd
+    where bd  =   toFix (wenv w)
+              -- NOTE: this next line is printed this way for compatability with the OCAML solver
+              $+$ text "reft" <+> toFix (RR t (Reft (v, PKVar k mempty)))
+              $+$ toFixMeta (text "wf") (toFix (winfo w))
+              $+$ if (isGWfc w) then (toFixMeta (text "expr") (toFix (wexpr w))) else mempty
+          (v, t, k) = wrft w
+
+toFixMeta :: Doc -> Doc -> Doc
+toFixMeta k v = text "// META" <+> k <+> text ":" <+> v
+
+pprId :: Show a => Maybe a -> Doc
+pprId (Just i)  = "id" <+> tshow i
+pprId _         = ""
+
+instance PPrint GFixSolution where
+  pprintTidy k (GSol xs) = vcat $ punctuate "\n\n" (pprintTidyGradual k <$> M.toList xs)
+
+pprintTidyGradual :: Tidy -> (KVar, (Expr, [Expr])) -> Doc
+pprintTidyGradual _ (x, (e, es)) = ppLocOfKVar x <+> text ":=" <+> (ppNonTauto " && " e <> pprint es)
+
+ppLocOfKVar :: KVar -> Doc
+ppLocOfKVar = text. dropWhile (/='(') . symbolString .kv
+
+ppNonTauto :: Doc -> Expr -> Doc
+ppNonTauto d e
+  | isTautoPred e = mempty
+  | otherwise     = pprint e <> d
+
+instance Show   GFixSolution where
+  show = showpp
+
+----------------------------------------------------------------
+instance B.Binary Qualifier
+instance B.Binary Kuts
+instance B.Binary HOInfo
+instance B.Binary GFixSolution
+instance (B.Binary a) => B.Binary (SubC a)
+instance (B.Binary a) => B.Binary (WfC a)
+instance (B.Binary a) => B.Binary (SimpC a)
+instance (B.Binary (c a), B.Binary a) => B.Binary (GInfo c a)
+
+instance NFData Qualifier
+instance NFData Kuts
+instance NFData HOInfo
+instance NFData GFixSolution
+
+instance (NFData a) => NFData (SubC a)
+instance (NFData a) => NFData (WfC a)
+instance (NFData a) => NFData (SimpC a)
+instance (NFData (c a), NFData a) => NFData (GInfo c a)
+instance (NFData a) => NFData (Result a)
+
+---------------------------------------------------------------------------
+-- | "Smart Constructors" for Constraints ---------------------------------
+---------------------------------------------------------------------------
+
+wfC :: (Fixpoint a) => IBindEnv -> SortedReft -> a -> [WfC a]
+wfC be sr x = if all isEmptySubst (sus ++ gsus)
+                then [WfC be (v, sr_sort sr, k) x | k <- ks] ++ [GWfC be (v, sr_sort sr, k) x e | (k, e) <- gs ]
+                else errorstar msg
+  where
+    msg             = "wfKvar: malformed wfC " ++ show sr
+    Reft (v, ras)   = sr_reft sr
+    (ks, sus)       = unzip $ go ras
+    (gs, gsus)      = unzip $ go' ras
+
+    go (PKVar k su) = [(k, su)]
+    go (PAnd es)    = [(k, su) | PKVar k su <- es]
+    go _            = []
+
+    go' (PGrad k su e) = [((k, e), su)]
+    go' (PAnd es)      = concatMap go' es
+    go' _              = []
+
+mkSubC :: IBindEnv -> SortedReft -> SortedReft -> Maybe Integer -> Tag -> a -> SubC a
+mkSubC = SubC
+
+subC :: IBindEnv -> SortedReft -> SortedReft -> Maybe Integer -> Tag -> a -> [SubC a]
+subC γ sr1 sr2 i y z = [SubC γ sr1' (sr2' r2') i y z | r2' <- reftConjuncts r2]
+   where
+     RR t1 r1          = sr1
+     RR t2 r2          = sr2
+     sr1'              = RR t1 $ shiftVV r1  vv'
+     sr2' r2'          = RR t2 $ shiftVV r2' vv'
+     vv'               = mkVV i
+
+mkVV :: Maybe Integer -> Symbol
+mkVV (Just i)  = vv $ Just i
+mkVV Nothing   = vvCon
+
+shiftVV :: Reft -> Symbol -> Reft
+shiftVV r@(Reft (v, ras)) v'
+   | v == v'   = r
+   | otherwise = Reft (v', subst1 ras (v, EVar v'))
+
+addIds :: [SubC a] -> [(Integer, SubC a)]
+addIds = zipWith (\i c -> (i, shiftId i $ c {_sid = Just i})) [1..]
+  where -- Adding shiftId to have distinct VV for SMT conversion
+    shiftId i c = c { slhs = shiftSR i $ slhs c }
+                    { srhs = shiftSR i $ srhs c }
+    shiftSR i sr = sr { sr_reft = shiftR i $ sr_reft sr }
+    shiftR i r@(Reft (v, _)) = shiftVV r (intSymbol v i)
+
+--------------------------------------------------------------------------------
+-- | Qualifiers ----------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+data Qualifier = Q { qName   :: !Symbol          -- ^ Name
+                   , qParams :: [(Symbol, Sort)] -- ^ Parameters
+                   , qBody   :: !Expr            -- ^ Predicate
+                   , qPos    :: !SourcePos       -- ^ Source Location
+                   }
+               deriving (Eq, Show, Data, Typeable, Generic)
+
+trueQual :: Qualifier
+trueQual = Q (symbol ("QTrue" :: String)) [] mempty (dummyPos "trueQual")
+
+instance Loc Qualifier where
+  srcSpan q = SS l l
+    where
+      l     = qPos q
+
+instance Fixpoint Qualifier where
+  toFix = pprQual
+
+instance PPrint Qualifier where
+  pprintTidy k q = "qualif" <+> pprintTidy k (qName q) <+> "defined at" <+> pprintTidy k (qPos q)
+
+pprQual :: Qualifier -> Doc
+pprQual (Q n xts p l) = text "qualif" <+> text (symbolString n) <> parens args <> colon <+> parens (toFix p) <+> text "//" <+> toFix l
+  where
+    args              = intersperse comma (toFix <$> xts)
+
+qualifier :: SEnv Sort -> SourcePos -> SEnv Sort -> Symbol -> Sort -> Expr -> Qualifier
+qualifier lEnv l γ v so p   = Q "Auto" ((v, so) : xts) p l
+  where
+    xs  = L.delete v $ L.nub $ syms p
+    xts = catMaybes $ zipWith (envSort l lEnv γ) xs [0..]
+
+envSort :: SourcePos -> SEnv Sort -> SEnv Sort -> Symbol -> Integer -> Maybe (Symbol, Sort)
+envSort l lEnv tEnv x i
+  | Just t <- lookupSEnv x tEnv = Just (x, t)
+  | Just _ <- lookupSEnv x lEnv = Nothing
+  | otherwise                   = Just (x, ai)
+  where
+    ai  = {- trace msg $ -} fObj $ Loc l l $ tempSymbol "LHTV" i
+    -- msg = "unknown symbol in qualifier: " ++ show x
+
+remakeQual :: Qualifier -> Qualifier
+remakeQual q = {- traceShow msg $ -} mkQual (qName q) (qParams q) (qBody q) (qPos q)
+
+-- | constructing qualifiers
+mkQual :: Symbol -> [(Symbol, Sort)] -> Expr -> SourcePos -> Qualifier
+mkQual n xts p = Q n ((v, t) : yts) (subst su p)
+  where
+    (v, t):zts = gSorts xts
+    -- yts        = first mkParam <$> zts
+    yts        = zts
+    su         = mkSubst $ zipWith (\(z,_) (y,_) -> (z, eVar y)) zts yts
+
+gSorts :: [(a, Sort)] -> [(a, Sort)]
+gSorts xts     = [(x, substVars su t) | (x, t) <- xts]
+  where
+    su         = (`zip` [0..]) . sortNub . concatMap (sortVars . snd) $ xts
+
+substVars :: [(Symbol, Int)] -> Sort -> Sort
+substVars su = mapSort' tx
+  where
+    tx (FObj x)
+      | Just i <- lookup x su = FVar i
+    tx t                      = t
+
+sortVars :: Sort -> [Symbol]
+sortVars = foldSort' go []
+  where
+    go b (FObj x) = x : b
+    go b _        = b
+
+-- COPIED from Visitor due to cyclic deps
+mapSort' :: (Sort -> Sort) -> Sort -> Sort
+mapSort' f = step
+  where
+    step             = go . f
+    go (FFunc t1 t2) = FFunc (step t1) (step t2)
+    go (FApp t1 t2)  = FApp (step t1) (step t2)
+    go (FAbs i t)    = FAbs i (step t)
+    go t             = t
+
+-- COPIED from Visitor due to cyclic deps
+foldSort' :: (a -> Sort -> a) -> a -> Sort -> a
+foldSort' f = step
+  where
+    step b t           = go (f b t) t
+    go b (FFunc t1 t2) = L.foldl' step b [t1, t2]
+    go b (FApp t1 t2)  = L.foldl' step b [t1, t2]
+    go b (FAbs _ t)    = go b t
+    go b _             = b
+
+
+--------------------------------------------------------------------------------
+-- | Constraint Cut Sets -------------------------------------------------------
+--------------------------------------------------------------------------------
+
+newtype Kuts = KS { ksVars :: S.HashSet KVar }
+               deriving (Eq, Show, Generic)
+
+instance Fixpoint Kuts where
+  toFix (KS s) = vcat $ ((text "cut " <>) . toFix) <$> S.toList s
+
+ksMember :: KVar -> Kuts -> Bool
+ksMember k (KS s) = S.member k s
+
+instance Monoid Kuts where
+  mempty        = KS S.empty
+  mappend k1 k2 = KS $ S.union (ksVars k1) (ksVars k2)
+
+------------------------------------------------------------------------
+-- | Constructing Queries
+------------------------------------------------------------------------
+fi :: [SubC a]
+   -> [WfC a]
+   -> BindEnv
+   -> SEnv Sort
+   -> SEnv Sort
+   -> Kuts
+   -> [Qualifier]
+   -> M.HashMap BindId a
+   -> Bool
+   -> Bool
+   -> [Triggered Expr]
+   -> AxiomEnv
+   -> GInfo SubC a
+fi cs ws binds ls ds ks qs bi aHO aHOq es axe
+  = FI { cm       = M.fromList $ addIds cs
+       , ws       = M.fromListWith err [(k, w) | w <- ws, let (_, _, k) = wrft w]
+       , bs       = binds
+       , gLits    = ls
+       , dLits    = ds
+       , kuts     = ks
+       , quals    = qs
+       , bindInfo = bi
+       , hoInfo   = HOI aHO aHOq
+       , asserts  = es
+       , ae       = axe
+       }
+  where
+    --TODO handle duplicates gracefully instead (merge envs by intersect?)
+    err = errorstar "multiple WfCs with same kvar"
+
+------------------------------------------------------------------------
+-- | Top-level Queries
+------------------------------------------------------------------------
+
+data FInfoWithOpts a = FIO {fioFI :: FInfo a, fioOpts :: [String]}
+
+type FInfo a   = GInfo SubC a
+type SInfo a   = GInfo SimpC a
+
+data HOInfo = HOI { hoBinds :: Bool          -- ^ Allow higher order binds in the environemnt
+                  , hoQuals :: Bool          -- ^ Allow higher order quals
+                  }
+  deriving (Eq, Show, Generic)
+
+allowHO, allowHOquals :: GInfo c a -> Bool
+allowHO      = hoBinds . hoInfo
+allowHOquals = hoQuals . hoInfo
+
+data GInfo c a =
+  FI { cm       :: !(M.HashMap SubcId (c a)) -- ^ cst id |-> Horn Constraint
+     , ws       :: !(M.HashMap KVar (WfC a))  -- ^ Kvar  |-> WfC defining its scope/args
+     , bs       :: !BindEnv                   -- ^ Bind  |-> (Symbol, SortedReft)
+     , gLits    :: !(SEnv Sort)               -- ^ Global Constant symbols
+     , dLits    :: !(SEnv Sort)               -- ^ Distinct Constant symbols
+     , kuts     :: !Kuts                      -- ^ Set of KVars *not* to eliminate
+  --    , packs    :: !Packs                     -- ^ Pack-sets of related KVars
+     , quals    :: ![Qualifier]               -- ^ Abstract domain
+     , bindInfo :: !(M.HashMap BindId a)      -- ^ Metadata about binders
+     , hoInfo   :: !HOInfo                    -- ^ Higher Order info
+     , asserts  :: ![Triggered Expr]
+     , ae       :: AxiomEnv
+     }
+  deriving (Eq, Show, Functor, Generic)
+
+
+instance Monoid HOInfo where
+  mempty        = HOI False False
+  mappend i1 i2 = HOI { hoBinds = hoBinds i1 || hoBinds i2
+                      , hoQuals = hoQuals i1 || hoQuals i2
+                      }
+
+instance Monoid (GInfo c a) where
+  mempty        = FI M.empty mempty mempty mempty mempty mempty mempty mempty mempty mempty mempty
+  mappend i1 i2 = FI { cm       = mappend (cm i1)       (cm i2)
+                     , ws       = mappend (ws i1)       (ws i2)
+                     , bs       = mappend (bs i1)       (bs i2)
+                     , gLits    = mappend (gLits i1)    (gLits i2)
+                     , dLits    = mappend (dLits i1)    (dLits i2)
+                     , kuts     = mappend (kuts i1)     (kuts i2)
+                     -- , packs    = mappend (packs i1)    (packs i2)
+                     , quals    = mappend (quals i1)    (quals i2)
+                     , bindInfo = mappend (bindInfo i1) (bindInfo i2)
+                     , hoInfo   = mappend (hoInfo i1)   (hoInfo i2)
+                     , asserts  = mappend (asserts i1)  (asserts i2)
+                     , ae  = mappend (ae i1)  (ae i2)
+                     }
+
+instance PTable (SInfo a) where
+  ptable z = DocTable [ (text "# Sub Constraints", pprint $ length $ cm z)
+                      , (text "# WF  Constraints", pprint $ length $ ws z)
+                      ]
+
+--------------------------------------------------------------------------
+-- | Rendering Queries
+--------------------------------------------------------------------------
+toFixpoint :: (Fixpoint a, Fixpoint (c a)) => Config -> GInfo c a -> Doc
+--------------------------------------------------------------------------
+toFixpoint cfg x' =    cfgDoc   cfg
+                  $++$ qualsDoc x'
+                  $++$ kutsDoc  x'
+                --   $++$ packsDoc x'
+                  $++$ gConDoc   x'
+                  $++$ dConDoc   x'
+                  $++$ bindsDoc x'
+                  $++$ csDoc    x'
+                  $++$ wsDoc    x'
+                  $++$ binfoDoc x'
+                  $++$ text "\n"
+  where
+    cfgDoc cfg    = text ("// " ++ show cfg)
+    gConDoc       = sEnvDoc "constant"             . gLits
+    dConDoc       = sEnvDoc "distinct"             . dLits
+    csDoc         = vcat     . map toFix . M.elems . cm
+    wsDoc         = vcat     . map toFix . M.elems . ws
+    kutsDoc       = toFix    . kuts
+    -- packsDoc      = toFix    . packs
+    bindsDoc      = toFix    . bs
+    qualsDoc      = vcat     . map toFix . quals
+    metaDoc (i,d) = toFixMeta (text "bind" <+> toFix i) (toFix d)
+    mdata         = metadata cfg
+    binfoDoc
+      | mdata     = vcat     . map metaDoc . M.toList . bindInfo
+      | otherwise = \_ -> text "\n"
+
+($++$) :: Doc -> Doc -> Doc
+x $++$ y = x $+$ text "\n" $+$ y
+
+sEnvDoc :: Doc -> SEnv Sort -> Doc
+sEnvDoc d       = vcat . map kvD . toListSEnv
+  where
+    kvD (c, so) = d <+> toFix c <+> ":" <+> parens (toFix so)
+
+writeFInfo :: (Fixpoint a, Fixpoint (c a)) => Config -> GInfo c a -> FilePath -> IO ()
+writeFInfo cfg fq f = writeFile f (render $ toFixpoint cfg fq)
+
+--------------------------------------------------------------------------
+-- | Query Conversions: FInfo to SInfo
+---------------------------------------------------------------------------
+convertFormat :: (Fixpoint a) => FInfo a -> SInfo a
+---------------------------------------------------------------------------
+convertFormat fi = fi' { cm = subcToSimpc <$> cm fi' }
+  where
+    fi'          = M.foldlWithKey' blowOutVV fi $ cm fi
+
+subcToSimpc :: SubC a -> SimpC a
+subcToSimpc s = SimpC
+  { _cenv     = senv s
+  , _crhs     = reftPred $ sr_reft $ srhs s
+  , _cid      = sid s
+  , _ctag     = stag s
+  , _cinfo    = sinfo s
+  }
+
+blowOutVV :: FInfo a -> Integer -> SubC a -> FInfo a
+blowOutVV fi i subc = fi { bs = be', cm = cm' }
+  where
+    sr            = slhs subc
+    x             = reftBind $ sr_reft sr
+    (bindId, be') = insertBindEnv x sr $ bs fi
+    subc'         = subc { _senv = insertsIBindEnv [bindId] $ senv subc }
+    cm'           = M.insert i subc' $ cm fi
+
+
+---------------------------------------------------------------------------
+-- | Top level Solvers ----------------------------------------------------
+---------------------------------------------------------------------------
+type Solver a = Config -> FInfo a -> IO (Result (Integer, a))
+
+--------------------------------------------------------------------------------
+saveQuery :: Config -> FInfo a -> IO ()
+--------------------------------------------------------------------------------
+saveQuery cfg fi = {- when (save cfg) $ -} do
+  let fi'  = void fi
+  saveBinaryQuery cfg fi'
+  saveTextQuery cfg   fi'
+
+saveBinaryQuery :: Config -> FInfo () -> IO ()
+saveBinaryQuery cfg fi = do
+  let bfq  = queryFile Files.BinFq cfg
+  putStrLn $ "Saving Binary Query: " ++ bfq ++ "\n"
+  ensurePath bfq
+  B.encodeFile bfq fi
+
+saveTextQuery :: Config -> FInfo () -> IO ()
+saveTextQuery cfg fi = do
+  let fq   = queryFile Files.Fq cfg
+  putStrLn $ "Saving Text Query: "   ++ fq ++ "\n"
+  ensurePath fq
+  writeFile fq $ render (toFixpoint cfg fi)
+
+---------------------------------------------------------------------------
+-- | Axiom Instantiation Information --------------------------------------
+---------------------------------------------------------------------------
+data AxiomEnv = AEnv { aenvSyms    :: ![Symbol]
+                     , aenvEqs     :: ![Equation]
+                     , aenvSimpl   :: ![Rewrite]
+                     , aenvFuel    :: M.HashMap SubcId Int
+                     , aenvExpand  :: M.HashMap SubcId Bool
+                     }
+  deriving (Eq, Show, Generic)
+
+instance B.Binary AxiomEnv
+instance B.Binary Rewrite
+instance B.Binary Equation
+instance B.Binary SMTSolver
+instance B.Binary Eliminate
+instance NFData AxiomEnv
+instance NFData Rewrite
+instance NFData Equation
+instance NFData SMTSolver
+instance NFData Eliminate
+
+instance Monoid AxiomEnv where
+  mempty = AEnv [] [] [] (M.fromList []) (M.fromList [])
+  mappend a1 a2 = AEnv aenvSyms' aenvEqs' aenvSimpl' aenvFuel' aenvExpand'
+    where aenvSyms'    = mappend (aenvSyms a1) (aenvSyms a2)
+          aenvEqs'     = mappend (aenvEqs a1) (aenvEqs a2)
+          aenvSimpl'   = mappend (aenvSimpl a1) (aenvSimpl a2)
+          aenvFuel'    = mappend (aenvFuel a1) (aenvFuel a2)
+          aenvExpand'  = mappend (aenvExpand a1) (aenvExpand a2)
+
+data Equation = Equ { eqName :: Symbol
+                    , eqArgs :: [Symbol]
+                    , eqBody :: Expr
+                    }
+  deriving (Eq, Show, Generic)
+
+-- eg  SMeasure (f D [x1..xn] e)
+-- for f (D x1 .. xn) = e
+data Rewrite  = SMeasure  { smName  :: Symbol         -- eg. f
+                          , smDC    :: Symbol         -- eg. D
+                          , smArgs  :: [Symbol]       -- eg. xs
+                          , smBody  :: Expr           -- eg. e[xs]
+                          }
+  deriving (Eq, Show, Generic)
+
+getEqBody :: Equation -> Maybe Expr
+getEqBody (Equ  x xs (PAnd ((PAtom Eq fxs e):_)))
+  | (EVar f, es) <- splitEApp fxs
+  , f == x
+  , es == (EVar <$> xs)
+  = Just e
+getEqBody _
+  = Nothing
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Environments.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Environments.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Environments.hs
@@ -0,0 +1,317 @@
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveFoldable             #-}
+{-# LANGUAGE DeriveFunctor              #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE DeriveTraversable          #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE NoMonomorphismRestriction  #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE GADTs                      #-}
+
+module Language.Fixpoint.Types.Environments (
+
+  -- * Environments
+    SEnv, SESearch(..)
+  , emptySEnv, toListSEnv, fromListSEnv, fromMapSEnv
+  , mapSEnvWithKey, mapSEnv, mapMSEnv
+  , insertSEnv, deleteSEnv, memberSEnv, lookupSEnv, unionSEnv, unionSEnv'
+  , intersectWithSEnv
+  , differenceSEnv
+  , filterSEnv
+  , lookupSEnvWithDistance
+  , envCs
+
+  -- * Local Constraint Environments
+  , IBindEnv, BindId, BindMap
+  , emptyIBindEnv
+  , insertsIBindEnv
+  , deleteIBindEnv
+  , elemsIBindEnv
+  , memberIBindEnv
+  , unionIBindEnv
+  , diffIBindEnv
+  , intersectionIBindEnv
+  , nullIBindEnv
+  , filterIBindEnv
+
+  -- * Global Binder Environments
+  , BindEnv, beBinds
+  , emptyBindEnv
+  , insertBindEnv, lookupBindEnv
+  , filterBindEnv, mapBindEnv, mapWithKeyMBindEnv, adjustBindEnv
+  , bindEnvFromList, bindEnvToList, elemsBindEnv
+
+  -- * Information needed to lookup and update Solutions
+  , SolEnv (..)
+
+  -- * Groups of KVars (needed by eliminate)
+  , Packs (..)
+  , getPack
+  , makePack
+  ) where
+
+-- import qualified Data.Binary as B
+import qualified Data.Binary as B
+import qualified Data.List   as L
+import           Data.Generics             (Data)
+import           Data.Typeable             (Typeable)
+import           GHC.Generics              (Generic)
+import           Data.Hashable
+import qualified Data.HashMap.Strict       as M
+import qualified Data.HashSet              as S
+import           Data.Maybe
+import           Data.Function             (on)
+import           Text.PrettyPrint.HughesPJ
+import           Control.DeepSeq
+
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Types.Refinements
+import           Language.Fixpoint.Types.Substitutions ()
+import           Language.Fixpoint.Misc
+
+type BindId        = Int
+type BindMap a     = M.HashMap BindId a
+
+newtype IBindEnv   = FB (S.HashSet BindId) deriving (Eq, Data, Typeable, Generic)
+
+instance PPrint IBindEnv where
+  pprintTidy _ = pprint . L.sort . elemsIBindEnv
+
+newtype SEnv a     = SE { seBinds :: M.HashMap Symbol a }
+                     deriving (Eq, Data, Typeable, Generic, Foldable, Traversable)
+
+data SizedEnv a    = BE { _beSize  :: !Int
+                        , beBinds :: !(BindMap a)
+                        } deriving (Eq, Show, Functor, Foldable, Generic, Traversable)
+
+instance PPrint a => PPrint (SizedEnv a) where
+  pprintTidy k (BE _ m) = pprintTidy k m
+
+type BindEnv       = SizedEnv (Symbol, SortedReft)
+-- Invariant: All BindIds in the map are less than beSize
+
+data SolEnv        = SolEnv { soeBinds :: !BindEnv
+                            -- , soePacks :: !Packs
+                            } deriving (Eq, Show, Generic)
+
+instance PPrint a => PPrint (SEnv a) where
+  pprintTidy k = pprintKVs k . L.sortBy (compare `on` fst) . toListSEnv
+
+toListSEnv              ::  SEnv a -> [(Symbol, a)]
+toListSEnv (SE env)     = M.toList env
+
+fromListSEnv            ::  [(Symbol, a)] -> SEnv a
+fromListSEnv            = SE . M.fromList
+
+fromMapSEnv             ::  M.HashMap Symbol a -> SEnv a
+fromMapSEnv             = SE
+
+mapSEnv                 :: (a -> b) -> SEnv a -> SEnv b
+mapSEnv f (SE env)      = SE (fmap f env)
+
+mapMSEnv                :: (Monad m) => (a -> m b) -> SEnv a -> m (SEnv b)
+mapMSEnv f env          = fromListSEnv <$> mapM (secondM f) (toListSEnv env)
+
+mapSEnvWithKey          :: ((Symbol, a) -> (Symbol, b)) -> SEnv a -> SEnv b
+mapSEnvWithKey f        = fromListSEnv . fmap f . toListSEnv
+
+deleteSEnv :: Symbol -> SEnv a -> SEnv a
+deleteSEnv x (SE env)   = SE (M.delete x env)
+
+insertSEnv :: Symbol -> a -> SEnv a -> SEnv a
+insertSEnv x v (SE env) = SE (M.insert x v env)
+
+lookupSEnv :: Symbol -> SEnv a -> Maybe a
+lookupSEnv x (SE env)   = M.lookup x env
+
+emptySEnv :: SEnv a
+emptySEnv               = SE M.empty
+
+memberSEnv :: Symbol -> SEnv a -> Bool
+memberSEnv x (SE env)   = M.member x env
+
+intersectWithSEnv :: (v1 -> v2 -> a) -> SEnv v1 -> SEnv v2 -> SEnv a
+intersectWithSEnv f (SE m1) (SE m2) = SE (M.intersectionWith f m1 m2)
+
+differenceSEnv :: SEnv a -> SEnv w -> SEnv a
+differenceSEnv (SE m1) (SE m2) = SE (M.difference m1 m2)
+
+filterSEnv :: (a -> Bool) -> SEnv a -> SEnv a
+filterSEnv f (SE m)     = SE (M.filter f m)
+
+unionSEnv :: SEnv a -> M.HashMap Symbol a -> SEnv a
+unionSEnv (SE m1) m2    = SE (M.union m1 m2)
+
+unionSEnv' :: SEnv a -> SEnv a -> SEnv a
+unionSEnv' (SE m1) (SE m2)    = SE (M.union m1 m2)
+
+lookupSEnvWithDistance :: Symbol -> SEnv a -> SESearch a
+lookupSEnvWithDistance x (SE env)
+  = case M.lookup x env of
+     Just z  -> Found z
+     Nothing -> Alts $ symbol <$> alts
+  where
+    alts       = takeMin $ zip (editDistance x' <$> ss) ss
+    ss         = symbolString <$> fst <$> M.toList env
+    x'         = symbolString x
+    takeMin xs = [z | (d, z) <- xs, d == getMin xs]
+    getMin     = minimum . (fst <$>)
+
+
+data SESearch a = Found a | Alts [Symbol]
+
+-- | Functions for Indexed Bind Environment
+
+
+instance Monoid IBindEnv where
+  mempty                  = emptyIBindEnv
+  mappend (FB e1) (FB e2) = FB (e1 `mappend` e2)
+
+emptyIBindEnv :: IBindEnv
+emptyIBindEnv = FB S.empty
+
+deleteIBindEnv :: BindId -> IBindEnv -> IBindEnv
+deleteIBindEnv i (FB s) = FB (S.delete i s)
+
+memberIBindEnv :: BindId -> IBindEnv -> Bool
+memberIBindEnv i (FB s) = S.member i s
+
+insertsIBindEnv :: [BindId] -> IBindEnv -> IBindEnv
+insertsIBindEnv is (FB s) = FB (foldr S.insert s is)
+
+elemsIBindEnv :: IBindEnv -> [BindId]
+elemsIBindEnv (FB s) = S.toList s
+
+
+-- | Functions for Global Binder Environment
+insertBindEnv :: Symbol -> SortedReft -> BindEnv -> (BindId, BindEnv)
+insertBindEnv x r (BE n m) = (n, BE (n + 1) (M.insert n (x, r) m))
+
+emptyBindEnv :: BindEnv
+emptyBindEnv = BE 0 M.empty
+
+filterBindEnv   :: (BindId -> Symbol -> SortedReft -> Bool) -> BindEnv -> BindEnv
+filterBindEnv f (BE n be) = BE n (M.filterWithKey (\ n (x, r) -> f n x r) be)
+
+bindEnvFromList :: [(BindId, Symbol, SortedReft)] -> BindEnv
+bindEnvFromList [] = emptyBindEnv
+bindEnvFromList bs = BE (1 + maxId) be
+  where
+    maxId          = maximum $ fst3 <$> bs
+    be             = M.fromList [(n, (x, r)) | (n, x, r) <- bs]
+
+elemsBindEnv :: BindEnv -> [BindId]
+elemsBindEnv be = fst3 <$> bindEnvToList be
+
+bindEnvToList :: BindEnv -> [(BindId, Symbol, SortedReft)]
+bindEnvToList (BE _ be) = [(n, x, r) | (n, (x, r)) <- M.toList be]
+
+mapBindEnv :: (BindId -> (Symbol, SortedReft) -> (Symbol, SortedReft)) -> BindEnv -> BindEnv
+mapBindEnv f (BE n m) = BE n $ M.mapWithKey f m
+-- (\i z -> tracepp (msg i z) $ f z) m
+--  where
+--    msg i z = "beMap " ++ show i ++ " " ++ show z
+
+mapWithKeyMBindEnv :: (Monad m) => ((BindId, (Symbol, SortedReft)) -> m (BindId, (Symbol, SortedReft))) -> BindEnv -> m BindEnv
+mapWithKeyMBindEnv f (BE n m) = (BE n . M.fromList) <$> mapM f (M.toList m)
+
+lookupBindEnv :: BindId -> BindEnv -> (Symbol, SortedReft)
+lookupBindEnv k (BE _ m) = fromMaybe err (M.lookup k m)
+  where
+    err                  = errorstar $ "lookupBindEnv: cannot find binder" ++ show k
+
+filterIBindEnv :: (BindId -> Bool) -> IBindEnv -> IBindEnv
+filterIBindEnv f (FB m) = FB (S.filter f m)
+
+unionIBindEnv :: IBindEnv -> IBindEnv -> IBindEnv
+unionIBindEnv (FB m1) (FB m2) = FB $ m1 `S.union` m2
+
+intersectionIBindEnv :: IBindEnv -> IBindEnv -> IBindEnv
+intersectionIBindEnv (FB m1) (FB m2) = FB $ m1 `S.intersection` m2
+
+nullIBindEnv :: IBindEnv -> Bool
+nullIBindEnv (FB m) = S.null m
+
+diffIBindEnv :: IBindEnv -> IBindEnv -> IBindEnv
+diffIBindEnv (FB m1) (FB m2) = FB $ m1 `S.difference` m2
+
+adjustBindEnv :: ((Symbol, SortedReft) -> (Symbol, SortedReft)) -> BindId -> BindEnv -> BindEnv
+adjustBindEnv f i (BE n m) = BE n $ M.adjust f i m
+
+instance Functor SEnv where
+  fmap = mapSEnv
+
+instance Fixpoint BindEnv where
+  toFix (BE _ m) = vcat $ map toFixBind $ hashMapToAscList m
+    where
+      toFixBind (i, (x, r)) = "bind" <+> toFix i <+> toFix x <+> ":" <+> toFix r
+
+instance (Fixpoint a) => Fixpoint (SEnv a) where
+   toFix (SE m)   = toFix (hashMapToAscList m)
+
+instance Fixpoint (SEnv a) => Show (SEnv a) where
+  show = render . toFix
+
+instance Monoid (SEnv a) where
+  mempty        = SE M.empty
+  mappend s1 s2 = SE $ M.union (seBinds s1) (seBinds s2)
+
+instance Monoid BindEnv where
+  mempty = BE 0 M.empty
+  mappend (BE 0 _) b = b
+  mappend b (BE 0 _) = b
+  mappend _ _        = errorstar "mappend on non-trivial BindEnvs"
+
+envCs :: BindEnv -> IBindEnv -> [(Symbol, SortedReft)]
+envCs be env = [lookupBindEnv i be | i <- elemsIBindEnv env]
+
+instance Fixpoint (IBindEnv) where
+  toFix (FB ids) = text "env" <+> toFix ids
+
+--------------------------------------------------------------------------------
+
+instance NFData Packs
+instance NFData IBindEnv
+instance NFData BindEnv
+instance (NFData a) => NFData (SEnv a)
+
+instance B.Binary Packs
+instance B.Binary IBindEnv
+instance B.Binary BindEnv
+instance (B.Binary a) => B.Binary (SEnv a)
+instance (Hashable a, Eq a, B.Binary a) => B.Binary (S.HashSet a) where
+  put = B.put . S.toList
+  get = S.fromList <$> B.get
+
+--------------------------------------------------------------------------------
+-- | Constraint Pack Sets ------------------------------------------------------
+--------------------------------------------------------------------------------
+
+newtype Packs = Packs { packm :: M.HashMap KVar Int }
+               deriving (Eq, Show, Generic)
+
+instance Fixpoint Packs where
+  toFix (Packs m) = vcat $ (("pack" <+>) . toFix) <$> kIs
+    where
+      kIs = L.sortBy (compare `on` snd) . M.toList $ m
+
+instance PPrint Packs where
+  pprintTidy _ = toFix
+
+instance Monoid Packs where
+  mempty        = Packs mempty
+  mappend m1 m2 = Packs $ M.union (packm m1) (packm m2)
+
+getPack :: KVar -> Packs -> Maybe Int
+getPack k (Packs m) = M.lookup k m
+
+makePack :: [S.HashSet KVar] -> Packs
+makePack kvss = Packs (M.fromList kIs)
+  where
+    kIs       = [ (k, i) | (i, ks) <- kPacks, k <- ks ]
+    kPacks    = zip [0..] . coalesce . fmap S.toList $ kvss
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Errors.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Errors.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Errors.hs
@@ -0,0 +1,208 @@
+{-# LANGUAGE CPP                       #-}
+{-# LANGUAGE DeriveDataTypeable        #-}
+{-# LANGUAGE DeriveGeneric             #-}
+{-# LANGUAGE DeriveFoldable            #-}
+{-# LANGUAGE DeriveTraversable         #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE ScopedTypeVariables       #-}
+{-# LANGUAGE StandaloneDeriving        #-}
+{-# LANGUAGE OverloadedStrings         #-}
+
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Language.Fixpoint.Types.Errors (
+  -- * Concrete Location Type
+    SrcSpan (..)
+  , dummySpan
+  , sourcePosElts
+
+  -- * Result
+
+  , FixResult (..)
+  , colorResult
+  , resultDoc
+
+  -- * Abstract Error Type
+  , Error
+
+  -- * Constructor
+  , err
+
+  -- * Accessors
+  , errLoc
+  , errMsg
+
+  -- * Adding Insult to Injury
+  , catError
+  , catErrors
+
+  -- * Fatal Exit
+  , die
+  , exit
+
+  -- * Some popular errors
+  , errFreeVarInQual
+  , errFreeVarInConstraint
+  , errIllScopedKVar
+  ) where
+
+import           Control.Exception
+-- import qualified Control.Monad.Error           as E
+import           Data.Serialize                (Serialize (..))
+import           Data.Generics                 (Data)
+import           Data.Typeable
+import           Control.DeepSeq
+-- import           Data.Hashable
+import qualified Data.Binary                   as B
+import           GHC.Generics                  (Generic)
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Spans
+import           Language.Fixpoint.Misc
+import           Text.PrettyPrint.HughesPJ
+-- import           Text.Printf
+import           Data.Function (on)
+
+-- import           Debug.Trace
+
+#if MIN_VERSION_pretty(1,1,3)
+import qualified Text.PrettyPrint.Annotated.HughesPJ as Ann
+
+deriving instance Generic (Ann.AnnotDetails a)
+instance Serialize a => Serialize (Ann.AnnotDetails a)
+instance Serialize a => Serialize (Ann.Doc a)
+#endif
+
+instance Serialize Error1
+-- FIXME: orphans are bad...
+instance Serialize TextDetails
+
+instance Serialize Doc
+instance Serialize Error
+instance Serialize (FixResult Error)
+
+instance (B.Binary a) => B.Binary (FixResult a)
+
+--------------------------------------------------------------------------------
+-- | A BareBones Error Type ----------------------------------------------------
+--------------------------------------------------------------------------------
+
+newtype Error = Error [Error1]
+                deriving (Eq, Ord, Show, Typeable, Generic)
+
+data Error1 = Error1
+  { errLoc :: SrcSpan
+  , errMsg :: Doc
+  } deriving (Eq, Show, Typeable, Generic)
+
+instance Ord Error1 where
+  compare = compare `on` errLoc
+
+instance PPrint Error1 where
+  pprintTidy k (Error1 l msg) = (pprintTidy k l <> ": Error")
+                                $+$ nest 2 msg
+
+instance PPrint Error where
+  pprintTidy k (Error es) = vcat $ pprintTidy k <$> es
+
+instance Fixpoint Error1 where
+  toFix = pprint
+
+instance Exception Error
+instance Exception (FixResult Error)
+
+
+---------------------------------------------------------------------
+catError :: Error -> Error -> Error
+---------------------------------------------------------------------
+catError (Error e1) (Error e2) = Error (e1 ++ e2)
+
+---------------------------------------------------------------------
+catErrors :: ListNE Error -> Error
+---------------------------------------------------------------------
+catErrors = foldr1 catError
+
+---------------------------------------------------------------------
+err :: SrcSpan -> Doc -> Error
+---------------------------------------------------------------------
+err sp d = Error [Error1 sp d]
+
+---------------------------------------------------------------------
+die :: Error -> a
+---------------------------------------------------------------------
+die = throw
+
+---------------------------------------------------------------------
+exit :: a -> IO a -> IO a
+---------------------------------------------------------------------
+exit def act = catch act $ \(e :: Error) -> do
+  putDocLn $ vcat ["Unexpected Errors!", pprint e]
+  return def
+
+putDocLn :: Doc -> IO ()
+putDocLn = putStrLn . render
+---------------------------------------------------------------------
+-- | Result ---------------------------------------------------------
+---------------------------------------------------------------------
+
+data FixResult a = Crash [a] String
+                 | Safe
+                 | Unsafe ![a]
+                   deriving (Data, Typeable, Foldable, Traversable, Show, Generic)
+
+instance (NFData a) => NFData (FixResult a)
+
+instance Eq a => Eq (FixResult a) where
+  Crash xs _ == Crash ys _        = xs == ys
+  Unsafe xs == Unsafe ys          = xs == ys
+  Safe      == Safe               = True
+  _         == _                  = False
+
+instance Monoid (FixResult a) where
+  mempty                          = Safe
+  mappend Safe x                  = x
+  mappend x Safe                  = x
+  mappend _ c@(Crash _ _)         = c
+  mappend c@(Crash _ _) _         = c
+  mappend (Unsafe xs) (Unsafe ys) = Unsafe (xs ++ ys)
+
+instance Functor FixResult where
+  fmap f (Crash xs msg)   = Crash (f <$> xs) msg
+  fmap f (Unsafe xs)      = Unsafe (f <$> xs)
+  fmap _ Safe             = Safe
+
+resultDoc :: (Fixpoint a) => FixResult a -> Doc
+resultDoc Safe             = text "Safe"
+resultDoc (Crash xs msg)   = vcat $ text ("Crash!: " ++ msg) : ((("CRASH:" <+>) . toFix) <$> xs)
+resultDoc (Unsafe xs)      = vcat $ text "Unsafe:"           : ((("WARNING:" <+>) . toFix) <$> xs)
+
+colorResult :: FixResult a -> Moods
+colorResult (Safe)      = Happy
+colorResult (Unsafe _)  = Angry
+colorResult (_)         = Sad
+
+---------------------------------------------------------------------
+-- | Catalogue of Errors --------------------------------------------
+---------------------------------------------------------------------
+
+errFreeVarInQual :: (PPrint q, Loc q, PPrint x) => q -> x -> Error
+errFreeVarInQual q x = err sp $ vcat [ "Qualifier with free vars"
+                                     , pprint q
+                                     , pprint x ]
+  where
+    sp               = srcSpan q
+
+errFreeVarInConstraint :: (PPrint a) => (Integer, a) -> Error
+errFreeVarInConstraint (i, ss) = err dummySpan $
+  vcat [ "Constraint with free vars"
+       , pprint i
+       , pprint ss
+       , "Try using the --prune-unsorted flag"
+       ]
+
+errIllScopedKVar :: (PPrint k, PPrint bs) => (k, Integer, Integer, bs) -> Error
+errIllScopedKVar (k, inId, outId, xs) = err dummySpan $
+  vcat [ "Ill-scoped KVar" <+> pprint k
+       , "Missing common binders at def" <+> pprint inId <+> "and use" <+> pprint outId
+       , pprint xs
+       ]
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Names.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Names.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Names.hs
@@ -0,0 +1,588 @@
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TypeSynonymInstances       #-}
+{-# LANGUAGE TypeFamilies               #-}
+{-# LANGUAGE ViewPatterns               #-}
+{-# LANGUAGE BangPatterns               #-}
+{-# LANGUAGE PatternGuards              #-}
+
+
+-- | This module contains Haskell variables representing globally visible names.
+--   Rather than have strings floating around the system, all constant names
+--   should be defined here, and the (exported) variables should be used and
+--   manipulated elsewhere.
+
+module Language.Fixpoint.Types.Names (
+
+  -- * Symbols
+    Symbol
+  , Symbolic (..)
+  , LocSymbol
+  , LocText
+  , symbolicString
+
+  -- * Conversion to/from Text
+  , symbolSafeText
+  , symbolSafeString
+  , symbolText
+  , symbolString
+
+  -- Predicates
+  , isPrefixOfSym
+  , isSuffixOfSym
+  , isNonSymbol
+  , isLitSymbol
+  , isNontrivialVV
+  , isDummy
+
+  -- * Destructors
+  , stripPrefix
+  , consSym
+  , unconsSym
+  , dropSym
+  , headSym
+  , lengthSym
+
+  -- * Transforms
+  , nonSymbol
+  , vvCon
+  , tidySymbol
+
+  -- * Widely used prefixes
+  , anfPrefix
+  , tempPrefix
+  , vv
+  , symChars
+
+  -- * Creating Symbols
+  , dummySymbol
+  , intSymbol
+  , tempSymbol
+
+  -- * Wrapping Symbols
+  , litSymbol
+  , renameSymbol
+  , kArgSymbol
+  , existSymbol
+  , suffixSymbol
+
+  -- * Unwrapping Symbols
+  , unLitSymbol
+
+  -- * Hardwired global names
+  , dummyName
+  , preludeName
+  , boolConName
+  , funConName
+  , listConName
+  , listLConName
+  , tupConName
+  , setConName
+  , mapConName
+  -- , propConName
+  -- , hpropConName
+  , strConName
+  , nilName
+  , consName
+  , vvName
+  , size32Name
+  , size64Name
+  , bitVecName
+  , bvAndName
+  , bvOrName
+  , prims
+  , mulFuncName
+  , divFuncName
+
+  -- * Casting function names
+  , setToIntName, bitVecToIntName, mapToIntName, boolToIntName, realToIntName
+  , setApplyName, bitVecApplyName, mapApplyName, boolApplyName, realApplyName, intApplyName
+
+  , lambdaName
+  , intArgName
+
+) where
+
+import           Control.DeepSeq             (NFData (..))
+import           Control.Arrow               (second)
+import           Data.Char                   (ord)
+import           Data.Maybe                  (fromMaybe)
+import           Data.Generics               (Data)
+import           Data.Hashable               (Hashable (..))
+import qualified Data.HashSet                as S
+import           Data.Interned
+import           Data.Interned.Internal.Text
+import           Data.String                 (IsString(..))
+import qualified Data.Text                   as T
+import           Data.Binary                 (Binary (..))
+import           Data.Typeable               (Typeable)
+import           GHC.Generics                (Generic)
+
+import           Text.PrettyPrint.HughesPJ   (text)
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Spans
+
+---------------------------------------------------------------
+-- | Symbols --------------------------------------------------
+---------------------------------------------------------------
+
+deriving instance Data     InternedText
+deriving instance Typeable InternedText
+deriving instance Generic  InternedText
+
+{- type SafeText = {v: T.Text | IsSafe v} @-}
+type SafeText = T.Text
+
+-- | Invariant: a `SafeText` is made up of:
+--
+--     ['0'..'9'] ++ ['a'...'z'] ++ ['A'..'Z'] ++ '$'
+--
+--   If the original text has ANY other chars, it is represented as:
+--
+--     lq$i
+--
+--   where i is a unique integer (for each text)
+
+data Symbol
+  = S { _symbolId      :: !Id
+      , symbolRaw     :: !T.Text
+      , symbolEncoded :: !T.Text
+      } deriving (Data, Typeable, Generic)
+
+instance Eq Symbol where
+  S i _ _ == S j _ _ = i == j
+
+instance Ord Symbol where
+  compare (S i _ _) (S j _ _) = compare i j
+
+instance Interned Symbol where
+  type Uninterned Symbol = T.Text
+  newtype Description Symbol = DT T.Text deriving (Eq)
+  describe = DT
+  identify i t = S i t (encode t)
+  cache = sCache
+
+instance Uninternable Symbol where
+  unintern (S _ t _) = t
+
+instance Hashable (Description Symbol) where
+  hashWithSalt s (DT t) = hashWithSalt s t
+
+instance Hashable Symbol where
+  -- NOTE: hash based on original text rather than id
+  hashWithSalt s (S _ t _) = hashWithSalt s t
+
+instance NFData Symbol where
+  rnf (S {}) = ()
+
+instance Binary Symbol where
+  get = textSymbol <$> get
+  put = put . symbolText
+
+sCache :: Cache Symbol
+sCache = mkCache
+{-# NOINLINE sCache #-}
+
+instance IsString Symbol where
+  fromString = textSymbol . T.pack
+
+instance Show Symbol where
+  show = show . symbolRaw
+
+mappendSym :: Symbol -> Symbol -> Symbol
+mappendSym s1 s2 = textSymbol $ mappend s1' s2'
+    where
+      s1'        = symbolText s1
+      s2'        = symbolText s2
+
+instance PPrint Symbol where
+  pprintTidy _ = text . symbolString
+
+instance Fixpoint T.Text where
+  toFix = text . T.unpack
+
+-- RJ: Use `symbolSafeText` if you want it to machine-readable,
+--     but `symbolText`     if you want it to be human-readable.
+
+instance Fixpoint Symbol where
+  toFix = toFix . checkedText -- symbolSafeText
+
+checkedText :: Symbol -> T.Text
+checkedText x
+  | Just (c, t') <- T.uncons t
+  , okHd c && T.all okChr t'   = t
+  | otherwise                  = symbolSafeText x
+  where
+    t     = symbolText x
+    okHd  = (`S.member` alphaChars)
+    okChr = (`S.member` symChars)
+
+---------------------------------------------------------------------------
+-- | Located Symbols -----------------------------------------------------
+---------------------------------------------------------------------------
+
+type LocSymbol = Located Symbol
+type LocText   = Located T.Text
+
+isDummy :: (Symbolic a) => a -> Bool
+isDummy a = symbol a == symbol dummyName
+
+instance Symbolic a => Symbolic (Located a) where
+  symbol = symbol . val
+
+---------------------------------------------------------------------------
+-- | Decoding Symbols -----------------------------------------------------
+---------------------------------------------------------------------------
+
+symbolText :: Symbol -> T.Text
+symbolText = symbolRaw
+
+symbolString :: Symbol -> String
+symbolString = T.unpack . symbolText
+
+symbolSafeText :: Symbol -> SafeText
+symbolSafeText = symbolEncoded
+
+symbolSafeString :: Symbol -> String
+symbolSafeString = T.unpack . symbolSafeText
+
+---------------------------------------------------------------------------
+-- | Encoding Symbols -----------------------------------------------------
+---------------------------------------------------------------------------
+
+-- INVARIANT: All strings *must* be built from here
+
+textSymbol :: T.Text -> Symbol
+textSymbol = intern
+
+encode :: T.Text -> SafeText
+encode t
+  | isFixKey t     = T.append "key$" t
+  | otherwise      = encodeUnsafe t
+
+isFixKey :: T.Text -> Bool
+isFixKey x = S.member x keywords
+
+encodeUnsafe :: T.Text -> T.Text
+encodeUnsafe = joinChunks . splitChunks . prefixAlpha
+
+prefixAlpha :: T.Text -> T.Text
+prefixAlpha t
+  | isAlpha0 t = t
+  | otherwise  = T.append "fix$" t
+
+isAlpha0 :: T.Text -> Bool
+isAlpha0 t = case T.uncons t of
+               Just (c, _) -> S.member c alphaChars
+               Nothing     -> False
+
+joinChunks :: (T.Text, [(Char, SafeText)]) -> SafeText
+joinChunks (t, [] ) = t
+joinChunks (t, cts) = T.concat $ padNull t : (tx <$> cts)
+  where
+    tx (c, ct)      = mconcat ["$", c2t c, "$", ct]
+    c2t             = T.pack . show . ord
+
+padNull :: T.Text -> T.Text
+padNull t
+  | T.null t  = "z$"
+  | otherwise = t
+
+splitChunks :: T.Text -> (T.Text, [(Char, SafeText)])
+splitChunks t = (h, go tl)
+  where
+    (h, tl)   = T.break isUnsafeChar t
+    go !ut    = case T.uncons ut of
+                  Nothing       -> []
+                  Just (c, ut') -> let (ct, utl) = T.break isUnsafeChar ut'
+                                   in (c, ct) : go utl
+
+isUnsafeChar :: Char -> Bool
+isUnsafeChar = not . (`S.member` okSymChars)
+
+
+keywords :: S.HashSet T.Text
+keywords   = S.fromList [ "env"
+                        , "id"
+                        , "tag"
+                        , "qualif"
+                        , "constant"
+                        , "cut"
+                        , "bind"
+                        , "constraint"
+                        , "lhs"
+                        , "rhs"
+                        , "NaN"
+                        , "min"
+                        , "map"
+                        ]
+
+-- | RJ: We allow the extra 'unsafeChars' to allow parsing encoded symbols.
+--   e.g. the raw string "This#is%$inval!d" may get encoded as "enc%12"
+--   and serialized as such in the fq/bfq file. We want to allow the parser
+--   to then be able to read the above back in.
+
+alphaChars :: S.HashSet Char
+alphaChars = S.fromList $ ['a' .. 'z'] ++ ['A' .. 'Z']
+
+numChars :: S.HashSet Char
+numChars = S.fromList ['0' .. '9']
+
+safeChars :: S.HashSet Char
+safeChars = alphaChars `mappend`
+            numChars   `mappend`
+            S.fromList ['_', '.']
+
+symChars :: S.HashSet Char
+symChars =  safeChars `mappend`
+            S.fromList ['%', '#', '$', '\'']
+
+okSymChars :: S.HashSet Char
+okSymChars = safeChars
+
+isPrefixOfSym :: Symbol -> Symbol -> Bool
+isPrefixOfSym (symbolText -> p) (symbolText -> x) = p `T.isPrefixOf` x
+
+isSuffixOfSym :: Symbol -> Symbol -> Bool
+isSuffixOfSym (symbolText -> p) (symbolText -> x) = p `T.isSuffixOf` x
+
+
+headSym :: Symbol -> Char
+headSym (symbolText -> t) = T.head t
+
+consSym :: Char -> Symbol -> Symbol
+consSym c (symbolText -> s) = symbol $ T.cons c s
+
+unconsSym :: Symbol -> Maybe (Char, Symbol)
+unconsSym (symbolText -> s) = second symbol <$> T.uncons s
+
+-- singletonSym :: Char -> Symbol -- Yuck
+-- singletonSym = (`consSym` "")
+
+lengthSym :: Symbol -> Int
+lengthSym (symbolText -> t) = T.length t
+
+dropSym :: Int -> Symbol -> Symbol
+dropSym n (symbolText -> t) = symbol $ T.drop n t
+
+stripPrefix :: Symbol -> Symbol -> Maybe Symbol
+stripPrefix p x = symbol <$> T.stripPrefix (symbolText p) (symbolText x)
+
+
+--------------------------------------------------------------------------------
+-- | Use this **EXCLUSIVELY** when you want to add stuff in front of a Symbol
+--------------------------------------------------------------------------------
+suffixSymbol :: Symbol -> Symbol -> Symbol
+suffixSymbol  x y = x `mappendSym` symSepName `mappendSym` y
+
+vv                  :: Maybe Integer -> Symbol
+-- vv (Just i)         = symbol $ symbolSafeText vvName `T.snoc` symSepName `mappend` T.pack (show i)
+vv (Just i)         = intSymbol vvName i
+vv Nothing          = vvName
+
+isNontrivialVV      :: Symbol -> Bool
+isNontrivialVV      = not . (vv Nothing ==)
+
+vvCon, dummySymbol :: Symbol
+vvCon       = vvName `suffixSymbol` "F"
+dummySymbol = dummyName
+
+litSymbol :: Symbol -> Symbol
+litSymbol s = litPrefix `mappendSym` s
+
+isLitSymbol :: Symbol -> Bool
+isLitSymbol = isPrefixOfSym litPrefix
+
+unLitSymbol :: Symbol -> Maybe Symbol
+unLitSymbol = stripPrefix litPrefix
+
+intSymbol :: (Show a) => Symbol -> a -> Symbol
+intSymbol x i = x `suffixSymbol` (symbol $ show i)
+
+tempSymbol :: Symbol -> Integer -> Symbol
+tempSymbol prefix = intSymbol (tempPrefix `mappendSym` prefix)
+
+renameSymbol :: Symbol -> Int -> Symbol
+renameSymbol prefix = intSymbol (renamePrefix `mappendSym` prefix)
+
+kArgSymbol :: Symbol -> Symbol -> Symbol
+kArgSymbol x k = (kArgPrefix `mappendSym` x) `suffixSymbol` k
+
+existSymbol :: Symbol -> Integer -> Symbol
+existSymbol prefix = intSymbol (existPrefix `mappendSym` prefix)
+
+
+tempPrefix, anfPrefix, renamePrefix, litPrefix  :: Symbol
+tempPrefix   = "lq_tmp$"
+anfPrefix    = "lq_anf$"
+renamePrefix = "lq_rnm$"
+litPrefix    = "lit$"
+
+kArgPrefix, existPrefix :: Symbol
+kArgPrefix   = "lq_karg$"
+existPrefix  = "lq_ext$"
+
+-------------------------------------------------------------------------
+tidySymbol :: Symbol -> Symbol
+-------------------------------------------------------------------------
+tidySymbol = unSuffixSymbol . unSuffixSymbol . unPrefixSymbol kArgPrefix
+
+unPrefixSymbol :: Symbol -> Symbol -> Symbol
+unPrefixSymbol p s = fromMaybe s (stripPrefix p s)
+
+unSuffixSymbol :: Symbol -> Symbol
+unSuffixSymbol s@(symbolText -> t)
+  = maybe s symbol $ T.stripSuffix symSepName $ fst $ T.breakOnEnd symSepName t
+
+-- takeWhileSym :: (Char -> Bool) -> Symbol -> Symbol
+-- takeWhileSym p (symbolText -> t) = symbol $ T.takeWhile p t
+
+
+nonSymbol :: Symbol
+nonSymbol = ""
+
+isNonSymbol :: Symbol -> Bool
+isNonSymbol = (== nonSymbol)
+
+------------------------------------------------------------------------------
+-- | Values that can be viewed as Symbols
+------------------------------------------------------------------------------
+
+class Symbolic a where
+  symbol :: a -> Symbol
+
+symbolicString :: (Symbolic a) => a -> String
+symbolicString = symbolString . symbol
+
+instance Symbolic T.Text where
+  symbol = textSymbol
+
+instance Symbolic String where
+  symbol = symbol . T.pack
+
+instance Symbolic Symbol where
+  symbol = id
+
+----------------------------------------------------------------------------
+--------------- Global Name Definitions ------------------------------------
+----------------------------------------------------------------------------
+
+lambdaName :: Symbol
+lambdaName = "smt_lambda"
+
+intArgName :: Int -> Symbol
+intArgName = intSymbol "lam_int_arg"
+
+setToIntName, bitVecToIntName, mapToIntName, realToIntName :: Symbol
+setToIntName    = "set_to_int"
+bitVecToIntName = "bitvec_to_int"
+mapToIntName    = "map_to_int"
+realToIntName   = "real_to_int"
+
+boolToIntName :: (IsString a) => a
+boolToIntName   = "bool_to_int"
+
+setApplyName, bitVecApplyName, mapApplyName, boolApplyName, realApplyName, intApplyName :: Int -> Symbol
+setApplyName    = intSymbol "set_apply_"
+bitVecApplyName = intSymbol "bitvec_apply"
+mapApplyName    = intSymbol "map_apply_"
+boolApplyName   = intSymbol "bool_apply_"
+realApplyName   = intSymbol "real_apply_"
+intApplyName    = intSymbol "int_apply_"
+
+
+preludeName, dummyName, boolConName, funConName :: Symbol
+preludeName  = "Prelude"
+dummyName    = "LIQUID$dummy"
+boolConName  = "Bool"
+funConName   = "->"
+
+listConName, listLConName, tupConName, _propConName, _hpropConName, vvName, setConName, mapConName :: Symbol
+listConName  = "[]"
+listLConName = "List"
+tupConName   = "Tuple"
+setConName   = "Set_Set"
+mapConName   = "Map_t"
+vvName       = "VV"
+_propConName  = "Prop"
+_hpropConName = "HProp"
+
+strConName  :: (IsString a) => a
+strConName   = "Str"
+-- symSepName   :: Char
+-- symSepName   = '#' -- DO NOT EVER CHANGE THIS
+
+symSepName   :: (IsString a) => a
+symSepName   = "##"
+
+nilName, consName, size32Name, size64Name, bitVecName, bvOrName, bvAndName :: Symbol
+nilName      = "nil"
+consName     = "cons"
+size32Name   = "Size32"
+size64Name   = "Size64"
+bitVecName   = "BitVec"
+bvOrName     = "bvor"
+bvAndName    = "bvand"
+
+mulFuncName, divFuncName :: Symbol
+mulFuncName  = "Z3_OP_MUL"
+divFuncName  = "Z3_OP_DIV"
+
+prims :: [Symbol]
+prims = [ _propConName
+        , _hpropConName
+        , vvName
+        , "Pred"
+        , "List"
+        , "[]"
+        , setConName
+        , "Set_sng"
+        , "Set_cup"
+        , "Set_cap"
+        , "Set_dif"
+        , "Set_emp"
+        , "Set_empty"
+        , "Set_mem"
+        , "Set_sub"
+        , mapConName
+        , "Map_select"
+        , "Map_store"
+        , size32Name
+        , size64Name
+        , bitVecName
+        , bvOrName
+        , bvAndName
+        , "FAppTy"
+        , nilName
+        , consName
+        ]
+
+{-
+-------------------------------------------------------------------------------
+-- | Memoized Decoding
+-------------------------------------------------------------------------------
+
+{-# NOINLINE symbolMemo #-}
+symbolMemo :: IORef (M.HashMap Int T.Text)
+symbolMemo = unsafePerformIO (newIORef M.empty)
+
+{-# NOINLINE memoEncode #-}
+memoEncode :: T.Text -> Int
+memoEncode t = unsafePerformIO $
+                 atomicModifyIORef symbolMemo $ \m ->
+                    (M.insert i t m, i)
+  where
+    i        = internedTextId $ intern t
+
+{-# NOINLINE memoDecode #-}
+memoDecode :: Int -> T.Text
+memoDecode i = unsafePerformIO $
+                 safeLookup msg i <$> readIORef symbolMemo
+               where
+                 msg = "Symbol Decode Error: " ++ show i
+
+-}
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/PrettyPrint.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/PrettyPrint.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/PrettyPrint.hs
@@ -0,0 +1,174 @@
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE FlexibleContexts   #-}
+{-# LANGUAGE FlexibleInstances  #-}
+{-# LANGUAGE OverloadedStrings  #-}
+
+module Language.Fixpoint.Types.PrettyPrint where
+
+import           Debug.Trace               (trace)
+import           Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.Boxes as B
+import qualified Data.HashMap.Strict as M
+import qualified Data.HashSet        as S
+import qualified Data.List           as L
+import           Language.Fixpoint.Misc
+import           Data.Hashable
+import qualified Data.Text as T
+
+
+traceFix     ::  (Fixpoint a) => String -> a -> a
+traceFix s x = trace ("\nTrace: [" ++ s ++ "] : " ++ showFix x) x
+
+------------------------------------------------------------------
+class Fixpoint a where
+  toFix    :: a -> Doc
+  simplify :: a -> a
+  simplify =  id
+
+showFix :: (Fixpoint a) => a -> String
+showFix =  render . toFix
+
+instance (Ord a, Hashable a, Fixpoint a) => Fixpoint (S.HashSet a) where
+  toFix xs = brackets $ sep $ punctuate ";" (toFix <$> L.sort (S.toList xs))
+  simplify = S.fromList . map simplify . S.toList
+
+instance Fixpoint () where
+  toFix _ = "()"
+
+instance Fixpoint a => Fixpoint (Maybe a) where
+  toFix    = maybe "Nothing" (("Just" <+>) . toFix)
+  simplify = fmap simplify
+
+instance Fixpoint a => Fixpoint [a] where
+  toFix xs = brackets $ sep $ punctuate ";" (fmap toFix xs)
+  simplify = map simplify
+
+instance (Fixpoint a, Fixpoint b) => Fixpoint (a,b) where
+  toFix   (x,y)  = toFix x <+> ":" <+> toFix y
+  simplify (x,y) = (simplify x, simplify y)
+
+instance (Fixpoint a, Fixpoint b, Fixpoint c) => Fixpoint (a,b,c) where
+  toFix   (x,y,z)  = toFix x <+> ":" <+> toFix y <+> ":" <+> toFix  z
+  simplify (x,y,z) = (simplify x, simplify y,simplify z)
+
+instance Fixpoint Bool where
+  toFix True  = "True"
+  toFix False = "False"
+  simplify z  = z
+
+instance Fixpoint Int where
+  toFix = tshow
+
+instance Fixpoint Integer where
+  toFix = integer
+
+instance Fixpoint Double where
+  toFix = double
+
+------------------------------------------------------------------
+
+data Tidy = Lossy | Full deriving (Eq, Ord)
+
+-- | Implement either `pprintTidy` or `pprintPrec`
+class PPrint a where
+
+  pprintTidy :: Tidy -> a -> Doc
+  pprintTidy = pprintPrec 0
+
+  pprintPrec :: Int -> Tidy -> a -> Doc
+  pprintPrec _ = pprintTidy
+
+-- | Top-level pretty printer
+pprint :: (PPrint a) => a -> Doc
+pprint = pprintPrec 0 Full
+
+showpp :: (PPrint a) => a -> String
+showpp = render . pprint
+
+showTable :: (PPrint k, PPrint v) => Tidy -> [(k, v)] -> String
+showTable k = render . pprintKVs k
+
+tracepp :: (PPrint a) => String -> a -> a
+tracepp s x = trace ("\nTrace: [" ++ s ++ "] : " ++ showpp x) x
+
+notracepp :: (PPrint a) => String -> a -> a
+notracepp _ x = x
+
+instance PPrint Doc where
+  pprintTidy _ = id
+
+instance PPrint a => PPrint (Maybe a) where
+  pprintTidy k = maybe "Nothing" (("Just" <+>) . pprintTidy k)
+
+instance PPrint a => PPrint [a] where
+  pprintTidy k = brackets . sep . punctuate comma . map (pprintTidy k)
+
+instance PPrint a => PPrint (S.HashSet a) where
+  pprintTidy k = pprintTidy k . S.toList
+
+instance (PPrint a, PPrint b) => PPrint (M.HashMap a b) where
+  pprintTidy k = pprintKVs k . M.toList
+
+pprintKVs   :: (PPrint k, PPrint v) => Tidy -> [(k, v)] -> Doc
+pprintKVs t = vcat . punctuate "\n" . map pp1
+  where
+    pp1 (x,y) = pprintTidy t x <+> ":=" <+> pprintTidy t y
+
+instance (PPrint a, PPrint b, PPrint c) => PPrint (a, b, c) where
+  pprintTidy k (x, y, z)  = parens $ pprintTidy k x <> "," <+>
+                                     pprintTidy k y <> "," <+>
+                                     pprintTidy k z
+
+
+instance (PPrint a, PPrint b) => PPrint (a,b) where
+  pprintTidy k (x, y)  = pprintTidy k x <+> ":" <+> pprintTidy k y
+
+instance PPrint Bool where
+  pprintTidy _ = text . show
+
+instance PPrint Float where
+  pprintTidy _ = text . show
+
+instance PPrint () where
+  pprintTidy _ = text . show
+
+#if !(defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,0,1,1)))
+instance PPrint String where
+  pprintTidy _ = text
+#endif
+
+instance PPrint Int where
+  pprintTidy _ = tshow
+
+instance PPrint Integer where
+  pprintTidy _ = integer
+
+instance PPrint T.Text where
+  pprintTidy _ = text . T.unpack
+
+newtype DocTable = DocTable [(Doc, Doc)]
+
+instance Monoid DocTable where
+  mempty                              = DocTable []
+  mappend (DocTable t1) (DocTable t2) = DocTable (t1 ++ t2)
+
+class PTable a where
+  ptable :: a -> DocTable
+
+instance PPrint DocTable where
+  pprintTidy _ (DocTable kvs) = boxDoc $ B.hsep 1 B.left [ks', cs', vs']
+    where
+      (ks, vs)                = unzip kvs
+      n                       = length kvs
+      ks'                     = B.vcat B.left  $ docBox <$> ks
+      vs'                     = B.vcat B.right $ docBox <$> vs
+      cs'                     = B.vcat B.left  $ replicate n $ B.text ":"
+
+boxHSep :: Doc -> Doc -> Doc
+boxHSep d1 d2 = boxDoc $ B.hcat B.top [docBox d1, docBox d2]
+
+boxDoc :: B.Box -> Doc
+boxDoc = text . B.render
+
+docBox :: Doc -> B.Box
+docBox = B.text . render
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Refinements.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Refinements.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Refinements.hs
@@ -0,0 +1,810 @@
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveFoldable             #-}
+{-# LANGUAGE DeriveFunctor              #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE DeriveTraversable          #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE NoMonomorphismRestriction  #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE GADTs                      #-}
+{-# LANGUAGE PatternGuards              #-}
+{-# LANGUAGE PatternSynonyms            #-}
+
+-- | This module has the types for representing terms in the refinement logic.
+
+module Language.Fixpoint.Types.Refinements (
+
+  -- * Representing Terms
+    SymConst (..)
+  , Constant (..)
+  , Bop (..)
+  , Brel (..)
+  , Expr (..), Pred
+  , pattern PTrue, pattern PTop, pattern PFalse, pattern EBot
+  , pattern ETimes, pattern ERTimes, pattern EDiv, pattern ERDiv
+  , pattern EEq
+  , KVar (..)
+  , Subst (..)
+  , KVSub (..)
+  , Reft (..)
+  , SortedReft (..)
+
+  -- * Constructing Terms
+  , eVar, elit
+  , eProp
+  , pAnd, pOr, pIte
+  , (&.&), (|.|)
+  , pExist
+  , mkEApp
+  , mkProp
+  , intKvar
+  , vv_
+
+  -- * Generalizing Embedding with Typeclasses
+  , Expression (..)
+  , Predicate (..)
+  , Subable (..)
+  , Reftable (..)
+
+  -- * Constructors
+  , reft                    -- "smart
+  , trueSortedReft          -- trivial reft
+  , trueReft, falseReft     -- trivial reft
+  , exprReft                -- singleton: v == e
+  , notExprReft             -- singleton: v /= e
+  , uexprReft               -- singleton: v ~~ e
+  , symbolReft              -- singleton: v == x
+  , usymbolReft             -- singleton: v ~~ x
+  , propReft                -- singleton: v <=> p
+  , predReft                -- any pred : p
+  , reftPred
+  , reftBind
+
+  -- * Predicates
+  , isFunctionSortedReft, functionSort
+  , isNonTrivial
+  , isContraPred
+  , isTautoPred
+  , isSingletonReft
+  , isFalse
+
+  -- * Destructing
+  , flattenRefas
+  , conjuncts
+  , eApps
+  , eAppC
+  , splitEApp
+  , reftConjuncts
+
+  -- * Transforming
+  , mapPredReft
+  , pprintReft
+
+  , debruijnIndex
+
+  -- * Gradual Type Manipulation
+  , pGAnds, pGAnd
+  , isGradual
+
+  ) where
+
+import qualified Data.Binary as B
+import           Data.Generics             (Data)
+import           Data.Typeable             (Typeable)
+import           Data.Hashable
+import           GHC.Generics              (Generic)
+import           Data.List                 (foldl', partition) -- , sort, sortBy)
+import           Data.String
+import           Data.Text                 (Text)
+import qualified Data.Text                 as T
+import           Control.DeepSeq
+import           Data.Maybe                (isJust)
+-- import           Text.Printf               (printf)
+-- import           Language.Fixpoint.Types.Config
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Types.PrettyPrint
+-- import           Language.Fixpoint.Types.Errors
+import           Language.Fixpoint.Types.Spans
+import           Language.Fixpoint.Types.Sorts
+import           Language.Fixpoint.Misc
+-- import           Text.Parsec.Pos
+import           Text.PrettyPrint.HughesPJ
+-- import           Data.Array                hiding (indices)
+import qualified Data.HashMap.Strict       as M
+-- import qualified Data.HashSet              as S
+
+instance NFData KVar
+instance NFData Subst
+instance NFData Constant
+instance NFData SymConst
+instance NFData Brel
+instance NFData Bop
+instance NFData Expr
+instance NFData Reft
+instance NFData SortedReft
+
+instance (Hashable k, Eq k, B.Binary k, B.Binary v) => B.Binary (M.HashMap k v) where
+  put = B.put . M.toList
+  get = M.fromList <$> B.get
+
+instance B.Binary KVar
+instance B.Binary Subst
+instance B.Binary Constant
+instance B.Binary SymConst
+instance B.Binary Brel
+instance B.Binary Bop
+instance B.Binary Expr
+instance B.Binary Reft
+instance B.Binary SortedReft
+
+reftConjuncts :: Reft -> [Reft]
+reftConjuncts (Reft (v, ra)) = [Reft (v, ra') | ra' <- ras']
+  where
+    ras'                     = if null ps then ks else ((pAnd ps) : ks)
+    (ks, ps)                 = partition (\p -> isKvar p || isGradual p) $ refaConjuncts ra
+
+isKvar :: Expr -> Bool
+isKvar (PKVar _ _) = True
+isKvar _           = False
+
+isGradual :: Expr -> Bool
+isGradual (PGrad _ _ _) = True
+isGradual _             = False
+
+refaConjuncts :: Expr -> [Expr]
+refaConjuncts p = [p' | p' <- conjuncts p, not $ isTautoPred p']
+
+
+--------------------------------------------------------------------------------
+-- | Kvars ---------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+newtype KVar = KV { kv :: Symbol }
+               deriving (Eq, Ord, Data, Typeable, Generic, IsString)
+
+intKvar :: Integer -> KVar
+intKvar = KV . intSymbol "k_"
+
+instance Show KVar where
+  show (KV x) = "$" ++ show x
+
+instance Hashable KVar
+instance Hashable Brel
+instance Hashable Bop
+instance Hashable SymConst
+instance Hashable Constant
+
+--------------------------------------------------------------------------------
+-- | Substitutions -------------------------------------------------------------
+--------------------------------------------------------------------------------
+newtype Subst = Su (M.HashMap Symbol Expr)
+                deriving (Eq, Data, Typeable, Generic)
+
+instance Show Subst where
+  show = showFix
+
+instance Fixpoint Subst where
+  toFix (Su m) = case hashMapToAscList m of
+                   []  -> empty
+                   xys -> hcat $ map (\(x,y) -> brackets $ toFix x <> text ":=" <> toFix y) xys
+
+instance PPrint Subst where
+  pprintTidy _ = toFix
+
+data KVSub = KVS
+  { ksuVV    :: Symbol
+  , ksuSort  :: Sort
+  , ksuKVar  :: KVar
+  , ksuSubst :: Subst
+  } deriving (Eq, Data, Typeable, Generic, Show)
+
+instance PPrint KVSub where
+  pprintTidy k ksu = pprintTidy k (ksuVV ksu, ksuKVar ksu, ksuSubst ksu)
+
+--------------------------------------------------------------------------------
+-- | Expressions ---------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- | Uninterpreted constants that are embedded as  "constant symbol : Str"
+
+data SymConst = SL !Text
+              deriving (Eq, Ord, Show, Data, Typeable, Generic)
+
+data Constant = I !Integer
+              | R !Double
+              | L !Text !Sort
+              deriving (Eq, Ord, Show, Data, Typeable, Generic)
+
+data Brel = Eq | Ne | Gt | Ge | Lt | Le | Ueq | Une
+            deriving (Eq, Ord, Show, Data, Typeable, Generic)
+
+data Bop  = Plus | Minus | Times | Div | Mod | RTimes | RDiv
+            deriving (Eq, Ord, Show, Data, Typeable, Generic)
+              -- NOTE: For "Mod" 2nd expr should be a constant or a var *)
+
+data Expr = ESym !SymConst
+          | ECon !Constant
+          | EVar !Symbol
+          | EApp !Expr !Expr
+          | ENeg !Expr
+          | EBin !Bop !Expr !Expr
+          | EIte !Expr !Expr !Expr
+          | ECst !Expr !Sort
+          | ELam !(Symbol, Sort)   !Expr
+          | ETApp !Expr !Sort
+          | ETAbs !Expr !Symbol
+          | PAnd   ![Expr]
+          | POr    ![Expr]
+          | PNot   !Expr
+          | PImp   !Expr !Expr
+          | PIff   !Expr !Expr
+          | PAtom  !Brel  !Expr !Expr
+          | PKVar  !KVar !Subst
+          | PAll   ![(Symbol, Sort)] !Expr
+          | PExist ![(Symbol, Sort)] !Expr
+          | PGrad  !KVar !Subst !Expr
+          deriving (Eq, Show, Data, Typeable, Generic)
+
+type Pred = Expr
+
+pattern PTrue         = PAnd []
+pattern PTop          = PAnd []
+pattern PFalse        = POr  []
+pattern EBot          = POr  []
+pattern EEq e1 e2     = PAtom Eq    e1 e2
+pattern ETimes e1 e2  = EBin Times  e1 e2
+pattern ERTimes e1 e2 = EBin RTimes e1 e2
+pattern EDiv e1 e2    = EBin Div    e1 e2
+pattern ERDiv e1 e2   = EBin RDiv   e1 e2
+
+
+mkEApp :: LocSymbol -> [Expr] -> Expr
+mkEApp = eApps . EVar . val
+
+eApps :: Expr -> [Expr] -> Expr
+eApps f es  = foldl' EApp f es
+
+splitEApp :: Expr -> (Expr, [Expr])
+splitEApp = go []
+  where
+    go acc (EApp f e) = go (e:acc) f
+    go acc e          = (e, acc)
+
+eAppC :: Sort -> Expr -> Expr -> Expr
+eAppC s e1 e2 = ECst (EApp e1 e2) s
+
+
+
+debruijnIndex :: Expr -> Int
+debruijnIndex = go
+  where
+    go (ELam _ e)      = 1 + go e
+    go (ECst e _)      = go e
+    go (EApp e1 e2)    = go e1 + go e2
+    go (ESym _)        = 1
+    go (ECon _)        = 1
+    go (EVar _)        = 1
+    go (ENeg e)        = go e
+    go (EBin _ e1 e2)  = go e1 + go e2
+    go (EIte e e1 e2)  = go e + go e1 + go e2
+    go (ETAbs e _)     = go e
+    go (ETApp e _)     = go e
+    go (PAnd es)       = foldl (\n e -> n + go e) 0 es
+    go (POr es)        = foldl (\n e -> n + go e) 0 es
+    go (PNot e)        = go e
+    go (PImp e1 e2)    = go e1 + go e2
+    go (PIff e1 e2)    = go e1 + go e2
+    go (PAtom _ e1 e2) = go e1 + go e2
+    go (PAll _ e)      = go e
+    go (PExist _ e)    = go e
+    go (PKVar _ _)     = 1
+    go (PGrad _ _ e)   = go e
+
+
+-- | Parsed refinement of @Symbol@ as @Expr@
+--   e.g. in '{v: _ | e }' v is the @Symbol@ and e the @Expr@
+newtype Reft = Reft (Symbol, Expr)
+               deriving (Eq, Data, Typeable, Generic)
+
+data SortedReft = RR { sr_sort :: !Sort, sr_reft :: !Reft }
+                  deriving (Eq, Data, Typeable, Generic)
+
+elit :: Located Symbol -> Sort -> Expr
+elit l s = ECon $ L (symbolText $ val l) s
+
+instance Fixpoint Constant where
+  toFix (I i)   = toFix i
+  toFix (R i)   = toFix i
+  toFix (L s t) = parens $ text "lit" <+> text "\"" <> toFix s <> text "\"" <+> toFix t
+
+--------------------------------------------------------------------------------
+-- | String Constants ----------------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- | Replace all symbol-representations-of-string-literals with string-literal
+--   Used to transform parsed output from fixpoint back into fq.
+
+instance Symbolic SymConst where
+  symbol = encodeSymConst
+
+encodeSymConst        :: SymConst -> Symbol
+encodeSymConst (SL s) = litSymbol $ symbol s
+
+_decodeSymConst :: Symbol -> Maybe SymConst
+_decodeSymConst = fmap (SL . symbolText) . unLitSymbol
+
+instance Fixpoint SymConst where
+  toFix  = toFix . encodeSymConst
+
+instance Fixpoint KVar where
+  toFix (KV k) = text "$" <> toFix k
+
+instance Fixpoint Brel where
+  toFix Eq  = text "="
+  toFix Ne  = text "!="
+  toFix Ueq = text "~~"
+  toFix Une = text "!~"
+  toFix Gt  = text ">"
+  toFix Ge  = text ">="
+  toFix Lt  = text "<"
+  toFix Le  = text "<="
+
+instance Fixpoint Bop where
+  toFix Plus   = text "+"
+  toFix Minus  = text "-"
+  toFix RTimes = text "*."
+  toFix Times  = text "*"
+  toFix Div    = text "/"
+  toFix RDiv   = text "/."
+  toFix Mod    = text "mod"
+
+instance Fixpoint Expr where
+  toFix (ESym c)       = toFix $ encodeSymConst c
+  toFix (ECon c)       = toFix c
+  toFix (EVar s)       = toFix s
+  toFix e@(EApp _ _)   = parens $ hcat $ punctuate " " $ toFix <$> (f:es) where (f, es) = splitEApp e
+  toFix (ENeg e)       = parens $ text "-"  <+> parens (toFix e)
+  toFix (EBin o e1 e2) = parens $ toFix e1  <+> toFix o <+> toFix e2
+  toFix (EIte p e1 e2) = parens $ text "if" <+> toFix p <+> text "then" <+> toFix e1 <+> text "else" <+> toFix e2
+  toFix (ECst e so)    = parens $ toFix e   <+> text " : " <+> toFix so
+  -- toFix (EBot)         = text "_|_"
+  -- toFix PTop           = text "???"
+  toFix PTrue          = text "true"
+  toFix PFalse         = text "false"
+  toFix (PNot p)       = parens $ text "~" <+> parens (toFix p)
+  toFix (PImp p1 p2)   = parens $ toFix p1 <+> text "=>" <+> toFix p2
+  toFix (PIff p1 p2)   = parens $ toFix p1 <+> text "<=>" <+> toFix p2
+  toFix (PAnd ps)      = text "&&" <+> toFix ps
+  toFix (POr  ps)      = text "||" <+> toFix ps
+  toFix (PAtom r e1 e2)  = parens $ toFix e1 <+> toFix r <+> toFix e2
+  toFix (PKVar k su)     = toFix k <> toFix su
+  toFix (PAll xts p)     = "forall" <+> (toFix xts
+                                        $+$ ("." <+> toFix p))
+  toFix (PExist xts p)   = "exists" <+> (toFix xts
+                                        $+$ ("." <+> toFix p))
+  toFix (ETApp e s)      = text "tapp" <+> toFix e <+> toFix s
+  toFix (ETAbs e s)      = text "tabs" <+> toFix e <+> toFix s
+  toFix (PGrad _ _ e)    = toFix e <+> text "&&" <+> text "??" -- <+> toFix k <+> toFix su
+  toFix (ELam (x,s) e)   = text "lam" <+> toFix x <+> ":" <+> toFix s <+> "." <+> toFix e
+
+  simplify (PAnd [])     = PTrue
+  simplify (POr  [])     = PFalse
+  simplify (PAnd [p])    = simplify p
+  simplify (POr  [p])    = simplify p
+
+  simplify (PGrad k su e)
+    | isContraPred e      = PFalse
+    | otherwise           = PGrad k su (simplify e)
+
+  simplify (PAnd ps)
+    | any isContraPred ps = PFalse
+    | otherwise           = PAnd $ filter (not . isTautoPred) $ map simplify ps
+
+  simplify (POr  ps)
+    | any isTautoPred ps = PTrue
+    | otherwise          = POr  $ filter (not . isContraPred) $ map simplify ps
+
+  simplify p
+    | isContraPred p     = PFalse
+    | isTautoPred  p     = PTrue
+    | otherwise          = p
+
+isContraPred   :: Expr -> Bool
+isContraPred z = eqC z || (z `elem` contras)
+  where
+    contras    = [PFalse]
+
+    eqC (PAtom Eq (ECon x) (ECon y))
+               = x /= y
+    eqC (PAtom Ueq (ECon x) (ECon y))
+               = x /= y
+    eqC (PAtom Ne x y)
+               = x == y
+    eqC (PAtom Une x y)
+               = x == y
+    eqC _      = False
+
+isTautoPred   :: Expr -> Bool
+isTautoPred z  = z == PTop || z == PTrue || eqT z
+  where
+    eqT (PAnd [])
+               = True
+    eqT (PAtom Le x y)
+               = x == y
+    eqT (PAtom Ge x y)
+               = x == y
+    eqT (PAtom Eq x y)
+               = x == y
+    eqT (PAtom Ueq x y)
+               = x == y
+    eqT (PAtom Ne (ECon x) (ECon y))
+               = x /= y
+    eqT (PAtom Une (ECon x) (ECon y))
+               = x /= y
+    eqT _      = False
+
+isEq  :: Brel -> Bool
+isEq r          = r == Eq || r == Ueq
+
+instance PPrint Constant where
+  pprintTidy _ = toFix
+
+instance PPrint Brel where
+  pprintTidy _ Eq = "=="
+  pprintTidy _ Ne = "/="
+  pprintTidy _ r  = toFix r
+
+instance PPrint Bop where
+  pprintTidy _  = toFix
+
+instance PPrint Sort where
+  pprintTidy _ = toFix
+
+instance PPrint KVar where
+  pprintTidy _ (KV x) = text "$" <> pprint x
+
+instance PPrint SymConst where
+  pprintTidy _ (SL x) = doubleQuotes $ text $ T.unpack x
+
+-- | Wrap the enclosed 'Doc' in parentheses only if the condition holds.
+parensIf :: Bool -> Doc -> Doc
+parensIf True  = parens
+parensIf False = id
+
+-- NOTE: The following Expr and Pred printers use pprintPrec to print
+-- expressions with minimal parenthesization. The precedence rules are somewhat
+-- fragile, and it would be nice to have them directly tied to the parser, but
+-- the general idea is (from lowest to highest precedence):
+--
+-- 1 - if-then-else
+-- 2 - => and <=>
+-- 3 - && and ||
+-- 4 - ==, !=, <, <=, >, >=
+-- 5 - mod
+-- 6 - + and -
+-- 7 - * and /
+-- 8 - function application
+--
+-- Each printer `p` checks whether the precedence of the context is greater than
+-- its own precedence. If so, the printer wraps itself in parentheses. Then it
+-- sets the contextual precedence for recursive printer invocations to
+-- (prec p + 1).
+
+opPrec :: Bop -> Int
+opPrec Mod    = 5
+opPrec Plus   = 6
+opPrec Minus  = 6
+opPrec Times  = 7
+opPrec RTimes = 7
+opPrec Div    = 7
+opPrec RDiv   = 7
+
+instance PPrint Expr where
+  pprintPrec _ k (ESym c)        = pprintTidy k c
+  pprintPrec _ k (ECon c)        = pprintTidy k c
+  pprintPrec _ k (EVar s)        = pprintTidy k s
+  -- pprintPrec _ (EBot)          = text "_|_"
+  pprintPrec z k (ENeg e)        = parensIf (z > zn) $
+                                   "-" <> pprintPrec (zn + 1) k e
+    where zn = 2
+  pprintPrec z k (EApp f es)     = parensIf (z > za) $
+                                   pprintPrec za k f <+> pprintPrec (za+1) k es
+    where za = 8
+  pprintPrec z k (EBin o e1 e2)  = parensIf (z > zo) $
+                                   pprintPrec (zo+1) k e1 <+>
+                                   pprintTidy k o         <+>
+                                   pprintPrec (zo+1) k e2
+    where zo = opPrec o
+  pprintPrec z k (EIte p e1 e2)  = parensIf (z > zi) $
+                                   "if"   <+> pprintPrec (zi+1) k p  <+>
+                                   "then" <+> pprintPrec (zi+1) k e1 <+>
+                                   "else" <+> pprintPrec (zi+1) k e2
+    where zi = 1
+
+  -- pprintPrec _ k (ECst e so)     = parens $ pprint e <+> ":" <+> const (text "...") (pprintTidy k so)
+  pprintPrec z k (ECst e _)      = pprintPrec z k e
+  pprintPrec _ _ PTrue           = trueD
+  pprintPrec _ _ PFalse          = falseD
+  pprintPrec z k (PNot p)        = parensIf (z > zn) $
+                                   "not" <+> pprintPrec (zn+1) k p
+    where zn = 8
+  pprintPrec z k (PImp p1 p2)    = parensIf (z > zi) $
+                                   (pprintPrec (zi+1) k p1) <+>
+                                   "=>"                     <+>
+                                   (pprintPrec (zi+1) k p2)
+    where zi = 2
+  pprintPrec z k (PIff p1 p2)    = parensIf (z > zi) $
+                                   (pprintPrec (zi+1) k p1) <+>
+                                   "<=>"                    <+>
+                                   (pprintPrec (zi+1) k p2)
+    where zi = 2
+  pprintPrec z k (PAnd ps)       = parensIf (z > za) $
+                                   pprintBin (za + 1) k trueD andD ps
+    where za = 3
+  pprintPrec z k (POr  ps)       = parensIf (z > zo) $
+                                   pprintBin (zo + 1) k falseD orD ps
+    where zo = 3
+  pprintPrec z k (PAtom r e1 e2) = parensIf (z > za) $
+                                   pprintPrec (za+1) k e1 <+>
+                                   pprintTidy k r         <+>
+                                   pprintPrec (za+1) k e2
+    where za = 4
+  pprintPrec _ k (PAll xts p)    = pprintQuant k "forall" xts p
+  pprintPrec _ k (PExist xts p)  = pprintQuant k "exists" xts p
+  pprintPrec _ k (ELam (x,t) e)  = "lam" <+> toFix x <+> ":" <+> toFix t <+> text "." <+> pprintTidy k e
+  pprintPrec _ _ p@(PKVar {})    = toFix p
+  pprintPrec _ _ (ETApp e s)     = "ETApp" <+> toFix e <+> toFix s
+  pprintPrec _ _ (ETAbs e s)     = "ETAbs" <+> toFix e <+> toFix s
+  pprintPrec z k (PGrad _ _ e)   = pprintPrec z k e <+> "&&" <+> "??"
+
+pprintQuant :: Tidy -> Doc -> [(Symbol, Sort)] -> Expr -> Doc
+pprintQuant k d xts p = (d <+> toFix xts)
+                        $+$
+                        ("  ." <+> pprintTidy k p)
+
+trueD, falseD, andD, orD :: Doc
+trueD  = "true"
+falseD = "false"
+andD   = "&&"
+orD    = "||"
+
+pprintBin :: (PPrint a) => Int -> Tidy -> Doc -> Doc -> [a] -> Doc
+pprintBin _ _ b _ [] = b
+pprintBin z k _ o xs = vIntersperse o $ pprintPrec z k <$> xs
+
+vIntersperse :: Doc -> [Doc] -> Doc
+vIntersperse _ []     = empty
+vIntersperse _ [d]    = d
+vIntersperse s (d:ds) = vcat (d : ((s <+>) <$> ds))
+
+pprintReft :: Tidy -> Reft -> Doc
+pprintReft k (Reft (_,ra)) = pprintBin z k trueD andD flat
+  where
+    flat = flattenRefas [ra]
+    z    = if length flat > 1 then 3 else 0
+
+------------------------------------------------------------------------
+-- | Generalizing Symbol, Expression, Predicate into Classes -----------
+------------------------------------------------------------------------
+
+-- | Values that can be viewed as Constants
+
+-- | Values that can be viewed as Expressions
+
+class Expression a where
+  expr   :: a -> Expr
+
+-- | Values that can be viewed as Predicates
+
+class Predicate a where
+  prop   :: a -> Expr
+
+instance Expression SortedReft where
+  expr (RR _ r) = expr r
+
+instance Expression Reft where
+  expr (Reft(_, e)) = e
+
+instance Expression Expr where
+  expr = id
+
+-- | The symbol may be an encoding of a SymConst.
+
+instance Expression Symbol where
+  expr s = eVar s
+
+instance Expression Text where
+  expr = ESym . SL
+
+instance Expression Integer where
+  expr = ECon . I
+
+instance Expression Int where
+  expr = expr . toInteger
+
+instance Predicate Symbol where
+  prop = eProp
+
+instance Predicate Expr where
+  prop = id
+
+instance Predicate Bool where
+  prop True  = PTrue
+  prop False = PFalse
+
+instance Expression a => Expression (Located a) where
+  expr   = expr . val
+
+eVar ::  Symbolic a => a -> Expr
+eVar = EVar . symbol
+
+eProp ::  Symbolic a => a -> Expr
+eProp = mkProp . eVar
+
+isSingletonExpr :: Symbol -> Expr -> Maybe Expr
+isSingletonExpr v (PAtom r e1 e2)
+  | e1 == EVar v && isEq r = Just e2
+  | e2 == EVar v && isEq r = Just e1
+isSingletonExpr _ _        = Nothing
+
+pAnd, pOr     :: ListNE Pred -> Pred
+pAnd          = simplify . PAnd
+pOr           = simplify . POr
+
+(&.&) :: Pred -> Pred -> Pred
+(&.&) p q = pAnd [p, q]
+
+(|.|) :: Pred -> Pred -> Pred
+(|.|) p q = pOr [p, q]
+
+pIte :: Pred -> Expr -> Expr -> Expr
+pIte p1 p2 p3 = pAnd [p1 `PImp` p2, (PNot p1) `PImp` p3]
+
+pExist :: [(Symbol, Sort)] -> Pred -> Pred
+pExist []  p = p
+pExist xts p = PExist xts p
+
+mkProp :: Expr -> Pred
+mkProp = id -- EApp (EVar propConName)
+
+--------------------------------------------------------------------------------
+-- | Predicates ----------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+isSingletonReft :: Reft -> Maybe Expr
+isSingletonReft (Reft (v, ra)) = firstMaybe (isSingletonExpr v) $ conjuncts ra
+
+relReft :: (Expression a) => Brel -> a -> Reft
+relReft r e   = Reft (vv_, PAtom r (eVar vv_)  (expr e))
+
+exprReft, notExprReft, uexprReft ::  (Expression a) => a -> Reft
+exprReft      = relReft Eq
+notExprReft   = relReft Ne
+uexprReft     = relReft Ueq
+
+propReft      ::  (Predicate a) => a -> Reft
+propReft p    = Reft (vv_, PIff (eProp vv_) (prop p))
+
+predReft      :: (Predicate a) => a -> Reft
+predReft p    = Reft (vv_, prop p)
+
+reft :: Symbol -> Expr -> Reft
+reft v p = Reft (v, p)
+
+mapPredReft :: (Expr -> Expr) -> Reft -> Reft
+mapPredReft f (Reft (v, p)) = Reft (v, f p)
+
+---------------------------------------------------------------
+-- | Refinements ----------------------------------------------
+---------------------------------------------------------------
+
+isFunctionSortedReft :: SortedReft -> Bool
+isFunctionSortedReft = isJust . functionSort . sr_sort
+
+isNonTrivial :: Reftable r => r -> Bool
+isNonTrivial = not . isTauto
+
+reftPred :: Reft -> Expr
+reftPred (Reft (_, p)) = p
+
+reftBind :: Reft -> Symbol
+reftBind (Reft (x, _)) = x
+
+------------------------------------------------------------
+-- | Gradual Type Manipulation  ----------------------------
+------------------------------------------------------------
+pGAnds :: [Expr] -> Expr
+pGAnds = foldl pGAnd PTrue
+
+pGAnd :: Expr -> Expr -> Expr
+pGAnd (PGrad k su p) q = PGrad k su (pAnd [p, q])
+pGAnd p (PGrad k su q) = PGrad k su (pAnd [p, q])
+pGAnd p q              = pAnd [p,q]
+
+------------------------------------------------------------
+-- | Generally Useful Refinements --------------------------
+------------------------------------------------------------
+
+symbolReft    :: (Symbolic a) => a -> Reft
+symbolReft    = exprReft . eVar
+
+usymbolReft   :: (Symbolic a) => a -> Reft
+usymbolReft   = uexprReft . eVar
+
+vv_ :: Symbol
+vv_ = vv Nothing
+
+trueSortedReft :: Sort -> SortedReft
+trueSortedReft = (`RR` trueReft)
+
+trueReft, falseReft :: Reft
+trueReft  = Reft (vv_, PTrue)
+falseReft = Reft (vv_, PFalse)
+
+flattenRefas :: [Expr] -> [Expr]
+flattenRefas        = concatMap flatP
+  where
+    flatP (PAnd ps) = concatMap flatP ps
+    flatP p         = [p]
+
+conjuncts :: Expr -> [Expr]
+conjuncts (PAnd ps) = concatMap conjuncts ps
+conjuncts p
+  | isTautoPred p   = []
+  | otherwise       = [p]
+
+
+-------------------------------------------------------------------------
+-- | TODO: This doesn't seem to merit a TC ------------------------------
+-------------------------------------------------------------------------
+
+class Falseable a where
+  isFalse :: a -> Bool
+
+instance Falseable Expr where
+  isFalse (PFalse) = True
+  isFalse _        = False
+
+instance Falseable Reft where
+  isFalse (Reft (_, ra)) = isFalse ra
+
+-------------------------------------------------------------------------
+-- | Class Predicates for Valid Refinements -----------------------------
+-------------------------------------------------------------------------
+
+class Subable a where
+  syms   :: a -> [Symbol]
+  substa :: (Symbol -> Symbol) -> a -> a
+  -- substa f  = substf (EVar . f)
+
+  substf :: (Symbol -> Expr) -> a -> a
+  subst  :: Subst -> a -> a
+  subst1 :: a -> (Symbol, Expr) -> a
+  subst1 y (x, e) = subst (Su $ M.fromList [(x,e)]) y
+
+instance Subable a => Subable (Located a) where
+  syms (Loc _ _ x)   = syms x
+  substa f (Loc l l' x) = Loc l l' (substa f x)
+  substf f (Loc l l' x) = Loc l l' (substf f x)
+  subst su (Loc l l' x) = Loc l l' (subst su x)
+
+
+class (Monoid r, Subable r) => Reftable r where
+  isTauto :: r -> Bool
+  ppTy    :: r -> Doc -> Doc
+
+  top     :: r -> r
+  top _   =  mempty
+
+  bot     :: r -> r
+
+  meet    :: r -> r -> r
+  meet    = mappend
+
+  toReft  :: r -> Reft
+  ofReft  :: Reft -> r
+  params  :: r -> [Symbol]          -- ^ parameters for Reft, vv + others
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Solutions.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Solutions.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Solutions.hs
@@ -0,0 +1,387 @@
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE NoMonomorphismRestriction  #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE TypeOperators              #-}
+{-# LANGUAGE GADTs                      #-}
+{-# LANGUAGE PatternGuards              #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE TupleSections              #-}
+
+-- | This module contains the top-level SOLUTION data types,
+--   including various indices used for solving.
+
+module Language.Fixpoint.Types.Solutions (
+
+  -- * Solution tables
+    Solution, GSolution
+  , Sol (gMap, sEnv), updateGMap, updateGMapWithKey
+  , sScp
+  , CMap
+
+  -- * Solution elements
+  , Hyp, Cube (..), QBind, GBind
+  , EQual (..)
+
+  -- * Equal elements
+  , eQual
+  , trueEqual
+
+  -- * Gradual Solution elements   
+  , qbToGb, gbToQbs, gbEquals, equalsGb, emptyGMap   
+
+  -- * Solution Candidates (move to SolverMonad?)
+  , Cand
+
+  -- * Constructor
+  , fromList
+
+  -- * Update
+  , update
+
+  -- * Lookup
+  , lookupQBind
+  , lookup, glookup
+
+  -- * Manipulating QBind
+  , qb
+  , qbPreds
+  , qbFilter
+
+  , gbFilterM
+
+  -- * Conversion for client
+  , result, resultGradual
+
+  -- * "Fast" Solver (DEPRECATED as unsound)
+  , Index  (..)
+  , KIndex (..)
+  , BindPred (..)
+  , BIndex (..)
+  ) where
+
+import           Prelude hiding (lookup)
+import           GHC.Generics
+import           Control.DeepSeq
+import           Data.Maybe (fromMaybe)
+import           Data.Hashable
+import qualified Data.HashMap.Strict       as M
+import qualified Data.List as L
+import           Data.Generics             (Data)
+import           Data.Typeable             (Typeable)
+import           Control.Monad (filterM)
+-- import qualified Data.HashSet              as S
+import           Language.Fixpoint.Misc
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Types.Sorts
+import           Language.Fixpoint.Types.Refinements
+import           Language.Fixpoint.Types.Environments
+import           Language.Fixpoint.Types.Constraints
+import           Language.Fixpoint.Types.Substitutions
+import           Language.Fixpoint.SortCheck (elaborate)
+import           Text.PrettyPrint.HughesPJ
+
+--------------------------------------------------------------------------------
+-- | Update Solution -----------------------------------------------------------
+--------------------------------------------------------------------------------
+update :: Sol a QBind -> [KVar] -> [(KVar, EQual)] -> (Bool, Sol a QBind)
+--------------------------------------------------------------------------------
+update s ks kqs = {- tracepp msg -} (or bs, s')
+  where
+    kqss        = groupKs ks kqs
+    (bs, s')    = folds update1 s kqss
+    -- msg      = printf "ks = %s, s = %s" (showpp ks) (showpp s)
+
+folds   :: (a -> b -> (c, a)) -> a -> [b] -> ([c], a)
+folds f b = L.foldl' step ([], b)
+  where
+     step (cs, acc) x = (c:cs, x')
+       where
+         (c, x')      = f acc x
+
+groupKs :: [KVar] -> [(KVar, EQual)] -> [(KVar, QBind)]
+groupKs ks kqs = [ (k, QB eqs) | (k, eqs) <- M.toList $ groupBase m0 kqs ]
+  where
+    m0         = M.fromList $ (,[]) <$> ks
+
+update1 :: Sol a QBind -> (KVar, QBind) -> (Bool, Sol a QBind)
+update1 s (k, qs) = (change, updateK k qs s)
+  where
+    oldQs         = lookupQBind s k
+    change        = qbSize oldQs /= qbSize qs
+
+--------------------------------------------------------------------------------
+-- | The `Solution` data type --------------------------------------------------
+--------------------------------------------------------------------------------
+type Solution  = Sol () QBind
+type GSolution = Sol (((Symbol, Sort), Expr), GBind) QBind
+newtype QBind = QB [EQual]   deriving (Show, Data, Typeable, Generic, Eq)
+newtype GBind = GB [[EQual]] deriving (Show, Data, Typeable, Generic)
+
+emptyGMap :: GSolution -> GSolution 
+emptyGMap sol = mapGMap sol (\(x,_) -> (x, GB []))
+
+updateGMapWithKey :: [(KVar, QBind)] -> GSolution -> GSolution
+updateGMapWithKey kqs sol = sol {gMap =  foldl (\m (k, (QB eq)) -> M.adjust (\(x, GB eqs) -> (x, GB (if eq `elem` eqs then eqs else eq:eqs))) k m) (gMap sol) kqs } 
+
+qb :: [EQual] -> QBind
+qb = QB
+
+qbEQuals :: QBind -> [EQual]
+qbEQuals (QB xs) = xs
+
+qbToGb :: QBind -> GBind
+qbToGb (QB xs) = GB $ map (:[]) xs
+
+gbToQbs :: GBind -> [QBind]
+gbToQbs (GB [])  = [QB [trueEqual]] 
+gbToQbs (GB ess) = QB <$> ess
+
+gbEquals :: GBind -> [[EQual]]
+gbEquals (GB eqs) = eqs 
+
+equalsGb :: [[EQual]] -> GBind
+equalsGb = GB 
+
+gbFilterM :: Monad m => ([EQual] -> m Bool) -> GBind -> m GBind
+gbFilterM f (GB eqs) = GB <$> filterM f eqs 
+
+qbSize :: QBind -> Int
+qbSize = length . qbEQuals
+
+qbFilter :: (EQual -> Bool) -> QBind -> QBind
+qbFilter f (QB eqs) = QB (filter f eqs)
+
+instance NFData QBind
+instance NFData GBind
+
+instance PPrint QBind where
+  pprintTidy k = pprintTidy k . qbEQuals
+
+--------------------------------------------------------------------------------
+-- | A `Sol` contains the various indices needed to compute a solution,
+--   in particular, to compute `lhsPred` for any given constraint.
+--------------------------------------------------------------------------------
+data Sol b a = Sol
+  { sEnv  :: !(SEnv Sort)                -- ^ Environment used to elaborate solutions
+  , sMap  :: !(M.HashMap KVar a)         -- ^ Actual solution (for cut kvar)
+  , gMap  :: !(M.HashMap KVar b)         -- ^ Solution for gradual variables 
+  , sHyp  :: !(M.HashMap KVar Hyp)       -- ^ Defining cubes  (for non-cut kvar)
+  -- , sBot  :: !(M.HashMap KVar ())        -- ^ set of BOT (cut kvars)
+  , sScp  :: !(M.HashMap KVar IBindEnv)  -- ^ set of allowed binders for kvar
+  }
+
+updateGMap :: Sol b a -> M.HashMap KVar b -> Sol b a 
+updateGMap sol gmap = sol {gMap = gmap}
+
+
+mapGMap :: Sol b a -> (b -> b) -> Sol b a 
+mapGMap sol f = sol {gMap = M.map f (gMap sol)}
+
+
+instance Monoid (Sol a b) where
+  mempty        = Sol mempty mempty mempty mempty mempty
+  mappend s1 s2 = Sol { sEnv  = mappend (sEnv s1) (sEnv s2)
+                      , sMap  = mappend (sMap s1) (sMap s2)
+                      , gMap  = mappend (gMap s1) (gMap s2)
+                      , sHyp  = mappend (sHyp s1) (sHyp s2)
+    --                , sBot  = mappend (sBot s1) (sBot s2)
+                      , sScp  = mappend (sScp s1) (sScp s2)
+                      }
+
+instance Functor (Sol a) where
+  fmap f (Sol e s m1 m2 m3) = Sol e (f <$> s) m1 m2 m3 
+
+instance (PPrint a, PPrint b) => PPrint (Sol a b) where
+  pprintTidy k = pprintTidy k . sMap
+
+
+--------------------------------------------------------------------------------
+-- | A `Cube` is a single constraint defining a KVar ---------------------------
+--------------------------------------------------------------------------------
+type Hyp      = ListNE Cube
+
+data Cube = Cube
+  { cuBinds :: IBindEnv  -- ^ Binders       from defining Env
+  , cuSubst :: Subst     -- ^ Substitutions from cstrs    Rhs
+  , cuId    :: SubcId    -- ^ Id            of   defining Cstr
+  , cuTag   :: Tag       -- ^ Tag           of   defining Cstr (DEBUG)
+  }
+
+instance PPrint Cube where
+  pprintTidy _ c = "Cube" <+> pprint (cuId c)
+
+instance Show Cube where
+  show = showpp
+--------------------------------------------------------------------------------
+result :: Sol a QBind -> M.HashMap KVar Expr
+--------------------------------------------------------------------------------
+result s = sMap $ (pAnd . fmap eqPred . qbEQuals) <$> s
+
+
+--------------------------------------------------------------------------------
+resultGradual :: GSolution -> M.HashMap KVar (Expr, [Expr])
+--------------------------------------------------------------------------------
+resultGradual s = fmap go' (gMap s)
+  where 
+    go' ((_,e), GB eqss) 
+     = (e, [PAnd $ fmap eqPred eqs | eqs <- eqss])
+
+
+--------------------------------------------------------------------------------
+-- | Create a Solution ---------------------------------------------------------
+--------------------------------------------------------------------------------
+fromList :: SEnv Sort -> [(KVar, a)] -> [(KVar, b)] -> [(KVar, Hyp)] -> M.HashMap KVar IBindEnv -> Sol a b
+fromList env kGs kXs kYs = Sol env kXm kGm kYm -- kBm
+  where
+    kXm              = M.fromList   kXs
+    kYm              = M.fromList   kYs
+    kGm              = M.fromList   kGs
+ -- kBm              = const () <$> kXm
+
+--------------------------------------------------------------------------------
+qbPreds :: String -> Sol a QBind -> Subst -> QBind -> [(Pred, EQual)]
+--------------------------------------------------------------------------------
+qbPreds msg s su (QB eqs) = [ (elabPred eq, eq) | eq <- eqs ]
+  where
+    elabPred          = elaborate ("qbPreds:" ++ msg) env . subst su . eqPred
+    env               = sEnv s
+
+--------------------------------------------------------------------------------
+-- | Read / Write Solution at KVar ---------------------------------------------
+--------------------------------------------------------------------------------
+lookupQBind :: Sol a QBind -> KVar -> QBind
+--------------------------------------------------------------------------------
+lookupQBind s k = {- tracepp _msg $ -} fromMaybe (QB []) (lookupElab s k)
+  where
+    _msg        = "lookupQB: k = " ++ show k
+
+--------------------------------------------------------------------------------
+glookup :: GSolution -> KVar -> Either Hyp (Either QBind (((Symbol, Sort), Expr), GBind))
+--------------------------------------------------------------------------------
+glookup s k
+  | Just gbs <- M.lookup k (gMap s)
+  = Right (Right gbs)
+  | Just cs  <- M.lookup k (sHyp s) -- non-cut variable, return its cubes
+  = Left cs
+  | Just eqs <- lookupElab s k
+  = Right (Left eqs)                 -- TODO: don't initialize kvars that have a hyp solution
+  | otherwise
+  = errorstar $ "solLookup: Unknown kvar " ++ show k
+
+
+
+--------------------------------------------------------------------------------
+lookup :: Sol a QBind -> KVar -> Either Hyp QBind
+--------------------------------------------------------------------------------
+lookup s k
+  | Just cs  <- M.lookup k (sHyp s) -- non-cut variable, return its cubes
+  = Left cs
+  | Just eqs <- lookupElab s k
+  = Right eqs                 -- TODO: don't initialize kvars that have a hyp solution
+  | otherwise
+  = errorstar $ "solLookup: Unknown kvar " ++ show k
+
+lookupElab :: Sol b QBind -> KVar -> Maybe QBind
+lookupElab s k = M.lookup k (sMap s)
+
+--------------------------------------------------------------------------------
+updateK :: KVar -> a -> Sol b a -> Sol b a
+--------------------------------------------------------------------------------
+updateK k qs s = s { sMap = M.insert k qs (sMap s)
+--                 , sBot = M.delete k    (sBot s)
+                   }
+
+
+--------------------------------------------------------------------------------
+-- | A `Cand` is an association list indexed by predicates
+--------------------------------------------------------------------------------
+type Cand a   = [(Expr, a)]
+
+
+--------------------------------------------------------------------------------
+-- | Instantiated Qualifiers ---------------------------------------------------
+--------------------------------------------------------------------------------
+data EQual = EQL
+  { _eqQual :: !Qualifier
+  , eqPred  :: !Expr
+  , _eqArgs :: ![Expr]
+  } deriving (Eq, Show, Data, Typeable, Generic)
+
+trueEqual :: EQual
+trueEqual = EQL trueQual mempty [] 
+
+instance PPrint EQual where
+  pprintTidy k = pprintTidy k . eqPred
+
+instance NFData EQual
+
+{- EQL :: q:_ -> p:_ -> ListX F.Expr {q_params q} -> _ @-}
+eQual :: Qualifier -> [Symbol] -> EQual
+eQual q xs = {- tracepp "eQual" $ -} EQL q p es
+  where
+    p      = subst su $  qBody q
+    su     = mkSubst  $  safeZip "eQual" qxs es
+    es     = eVar    <$> xs
+    qxs    = fst     <$> qParams q
+
+--------------------------------------------------------------------------------
+-- | A KIndex uniquely identifies each *use* of a KVar in an (LHS) binder
+--------------------------------------------------------------------------------
+data KIndex = KIndex { kiBIndex :: !BindId
+                     , kiPos    :: !Int
+                     , kiKVar   :: !KVar
+                     }
+              deriving (Eq, Ord, Show, Generic)
+
+instance Hashable KIndex
+
+instance PPrint KIndex where
+  pprintTidy _ = tshow
+
+--------------------------------------------------------------------------------
+-- | A BIndex is created for each LHS Bind or RHS constraint
+--------------------------------------------------------------------------------
+data BIndex    = Root
+               | Bind !BindId
+               | Cstr !SubcId
+                 deriving (Eq, Ord, Show, Generic)
+
+instance Hashable BIndex
+
+instance PPrint BIndex where
+  pprintTidy _ = tshow
+
+--------------------------------------------------------------------------------
+-- | Each `Bind` corresponds to a conjunction of a `bpConc` and `bpKVars`
+--------------------------------------------------------------------------------
+data BindPred  = BP
+  { bpConc :: !Pred                  -- ^ Concrete predicate (PTrue o)
+  , bpKVar :: ![KIndex]              -- ^ KVar-Subst pairs
+  } deriving (Show)
+
+instance PPrint BindPred where
+  pprintTidy _ = tshow
+
+
+--------------------------------------------------------------------------------
+-- | A Index is a suitably indexed version of the cosntraints that lets us
+--   1. CREATE a monolithic "background formula" representing all constraints,
+--   2. ASSERT each lhs via bits for the subc-id and formulas for dependent cut KVars
+--------------------------------------------------------------------------------
+data Index = FastIdx
+  { bindExpr   :: !(BindId |-> BindPred) -- ^ BindPred for each BindId
+  , kvUse      :: !(KIndex |-> KVSub)    -- ^ Definition of each `KIndex`
+  , kvDef      :: !(KVar   |-> Hyp)      -- ^ Constraints defining each `KVar`
+  , envBinds   :: !(CMap IBindEnv)       -- ^ Binders of each Subc
+  , envTx      :: !(CMap [SubcId])       -- ^ Transitive closure oof all dependent binders
+  , envSorts   :: !(SEnv Sort)           -- ^ Sorts for all symbols
+  -- , bindPrev   :: !(BIndex |-> BIndex)   -- ^ "parent" (immediately dominating) binder
+  -- , kvDeps     :: !(CMap [KIndex])       -- ^ List of (Cut) KVars on which a SubC depends
+  }
+
+type CMap a  = M.HashMap SubcId a
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Sorts.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Sorts.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Sorts.hs
@@ -0,0 +1,345 @@
+{-# LANGUAGE TupleSections              #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE NoMonomorphismRestriction  #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE GADTs                      #-}
+
+-- | This module contains the data types, operations and
+--   serialization functions for representing Fixpoint's
+--   implication (i.e. subtyping) and well-formedness
+--   constraints in Haskell. The actual constraint
+--   solving is done by the `fixpoint.native` which
+--   is written in Ocaml.
+
+module Language.Fixpoint.Types.Sorts (
+
+  -- * Embedding to Fixpoint Types
+    Sort (..)
+  , Sub (..)
+  , FTycon, TCEmb
+  , sortFTycon
+  , intFTyCon, boolFTyCon, realFTyCon, numFTyCon, strFTyCon, setFTyCon  -- TODO: hide these
+
+  , intSort, realSort, boolSort, strSort, funcSort
+  , setSort, bitVecSort, mapSort
+  , listFTyCon
+  , isListTC
+  , isFirstOrder
+  , mappendFTC
+  , fTyconSymbol, symbolFTycon, fTyconSort, symbolNumInfoFTyCon
+  , fApp, fApp', fAppTC
+  , fObj
+
+  , sortSubst
+  , functionSort
+  , mkFFunc
+  , bkFFunc
+
+  , isNumeric, isReal, isString
+  ) where
+
+import qualified Data.Binary as B
+import           Data.Generics             (Data)
+import           Data.Typeable             (Typeable)
+import           GHC.Generics              (Generic)
+
+import           Data.Monoid               ()
+import           Data.Hashable
+import           Data.List                 (foldl')
+import           Control.DeepSeq
+import           Data.Maybe                (fromMaybe)
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Spans
+import           Language.Fixpoint.Misc
+import           Text.PrettyPrint.HughesPJ
+import qualified Data.HashMap.Strict       as M
+
+
+data FTycon   = TC LocSymbol TCInfo deriving (Ord, Show, Data, Typeable, Generic)
+type TCEmb a  = M.HashMap a FTycon
+
+
+instance Eq FTycon where
+  (TC s _) == (TC s' _) = val s == val s'
+
+data TCInfo = TCInfo { tc_isNum :: Bool, tc_isReal :: Bool, tc_isString :: Bool }
+  deriving (Eq, Ord, Show, Data, Typeable, Generic)
+
+mappendFTC :: FTycon -> FTycon -> FTycon
+mappendFTC (TC x i1) (TC _ i2) = TC x (mappend i1 i2)
+
+instance Monoid TCInfo where
+  mempty                                          = TCInfo defNumInfo defRealInfo defStrInfo
+  mappend (TCInfo i1 i2 i3)  (TCInfo i1' i2' i3') = TCInfo (i1 || i1') (i2 || i2') (i3 || i3')
+
+defTcInfo, numTcInfo, realTcInfo, strTcInfo :: TCInfo
+defTcInfo  = TCInfo defNumInfo defRealInfo defStrInfo
+numTcInfo  = TCInfo True       defRealInfo defStrInfo
+realTcInfo = TCInfo True       True        defStrInfo
+strTcInfo  = TCInfo defNumInfo defRealInfo True
+
+defNumInfo, defRealInfo, defStrInfo :: Bool
+defNumInfo  = False
+defRealInfo = False
+defStrInfo  = False
+
+charFTyCon, intFTyCon, boolFTyCon, realFTyCon, funcFTyCon, numFTyCon, strFTyCon, listFTyCon, setFTyCon :: FTycon
+intFTyCon  = TC (dummyLoc "int"      ) numTcInfo
+boolFTyCon = TC (dummyLoc "bool"     ) defTcInfo
+realFTyCon = TC (dummyLoc "real"     ) realTcInfo
+numFTyCon  = TC (dummyLoc "num"      ) numTcInfo
+funcFTyCon = TC (dummyLoc "function" ) defTcInfo
+strFTyCon  = TC (dummyLoc strConName ) strTcInfo
+listFTyCon = TC (dummyLoc listConName) defTcInfo
+charFTyCon = TC (dummyLoc "Char"     ) defTcInfo
+setFTyCon  = TC (dummyLoc setConName ) defTcInfo
+
+isListConName :: LocSymbol -> Bool
+isListConName x = c == listConName || c == listLConName --"List"
+  where
+    c           = val x
+
+isListTC :: FTycon -> Bool
+isListTC (TC z _) = isListConName z
+
+fTyconSymbol :: FTycon -> Located Symbol
+fTyconSymbol (TC s _) = s
+
+symbolNumInfoFTyCon :: LocSymbol -> Bool -> Bool -> FTycon
+symbolNumInfoFTyCon c isNum isReal
+  | isListConName c
+  = TC (fmap (const listConName) c) tcinfo
+  | otherwise
+  = TC c tcinfo
+  where
+    tcinfo = defTcInfo{tc_isNum = isNum, tc_isReal = isReal}
+
+
+
+symbolFTycon :: LocSymbol -> FTycon
+symbolFTycon c = symbolNumInfoFTyCon c defNumInfo defRealInfo
+
+fApp :: Sort -> [Sort] -> Sort
+fApp = foldl' FApp
+
+fAppTC :: FTycon -> [Sort] -> Sort
+fAppTC = fApp . fTyconSort
+
+fApp' :: Sort -> ListNE Sort
+fApp' = go []
+  where
+    go acc (FApp t1 t2) = go (t2 : acc) t1
+    go acc t            = t : acc
+
+fObj :: LocSymbol -> Sort
+fObj = fTyconSort . (`TC` defTcInfo)
+
+sortFTycon :: Sort -> Maybe FTycon
+sortFTycon FInt    = Just intFTyCon
+sortFTycon FReal   = Just realFTyCon
+sortFTycon FNum    = Just numFTyCon
+sortFTycon (FTC c) = Just c
+sortFTycon _       = Nothing
+
+
+functionSort :: Sort -> Maybe ([Int], [Sort], Sort)
+functionSort s
+  | null is && null ss
+  = Nothing
+  | otherwise
+  = Just (is, ss, r)
+  where
+    (is, ss, r) = go [] [] s
+    go vs ss (FAbs i t)    = go (i:vs) ss t
+    go vs ss (FFunc s1 s2) = go vs (s1:ss) s2
+    go vs ss t             = (reverse vs, reverse ss, t)
+
+----------------------------------------------------------------------
+------------------------------- Sorts --------------------------------
+----------------------------------------------------------------------
+
+data Sort = FInt
+          | FReal
+          | FNum                 -- ^ numeric kind for Num tyvars
+          | FFrac                -- ^ numeric kind for Fractional tyvars
+          | FObj  !Symbol        -- ^ uninterpreted type
+          | FVar  !Int           -- ^ fixpoint type variable
+          | FFunc !Sort !Sort    -- ^ function
+          | FAbs  !Int !Sort     -- ^ type-abstraction
+          | FTC   !FTycon
+          | FApp  !Sort !Sort    -- ^ constructed type
+              deriving (Eq, Ord, Show, Data, Typeable, Generic)
+
+
+isFirstOrder, isFunction :: Sort -> Bool
+
+isFirstOrder (FFunc sx s) = not (isFunction sx) && isFirstOrder s
+isFirstOrder (FAbs _ s)   = isFirstOrder s
+isFirstOrder (FApp s1 s2) = (not $ isFunction s1) && (not $ isFunction s2)
+isFirstOrder _            = True
+
+isFunction (FAbs _ s)  = isFunction s
+isFunction (FFunc _ _) = True
+isFunction _           = False
+
+isNumeric :: Sort -> Bool
+isNumeric FInt           = True
+isNumeric (FApp s _)     = isNumeric s
+isNumeric (FTC (TC _ i)) = tc_isNum i
+isNumeric (FAbs _ s)     = isNumeric s
+isNumeric _              = False
+
+isReal :: Sort -> Bool
+isReal FReal          = True
+isReal (FApp s _)     = isReal s
+isReal (FTC (TC _ i)) = tc_isReal i
+isReal (FAbs _ s)     = isReal s
+isReal _              = False
+
+
+isString :: Sort -> Bool
+isString (FApp l c)     = (isList l && isChar c) || isString l
+isString (FTC (TC c i)) = (val c == strConName || tc_isString i)
+isString (FAbs _ s)     = isString s
+isString _              = False
+
+isList :: Sort -> Bool
+isList (FTC c) = isListTC c
+isList _       = False
+
+isChar :: Sort -> Bool
+isChar (FTC c) = c == charFTyCon
+isChar _       = False
+
+{-@ FFunc :: Nat -> ListNE Sort -> Sort @-}
+
+mkFFunc :: Int -> [Sort] -> Sort
+mkFFunc i ss     = go [0..i-1] ss
+  where
+    go [] [s]    = s
+    go [] (s:ss) = FFunc s $ go [] ss
+    go (i:is) ss = FAbs i $ go is ss
+    go _ _       = error "cannot happen"
+
+   -- foldl (flip FAbs) (foldl1 (flip FFunc) ss) [0..i-1]
+
+bkFFunc :: Sort -> Maybe (Int, [Sort])
+bkFFunc t    = (maximum (0 : as),) <$> bkFun t'
+  where
+    (as, t') = bkAbs t
+
+bkAbs :: Sort -> ([Int], Sort)
+bkAbs (FAbs i t) = (i:is, t') where (is, t') = bkAbs t
+bkAbs t          = ([], t)
+
+bkFun :: Sort -> Maybe [Sort]
+bkFun z@(FFunc _ _)  = Just (go z)
+  where
+    go (FFunc t1 t2) = t1 : go t2
+    go t             = [t]
+bkFun _              = Nothing
+
+
+instance Hashable FTycon where
+  hashWithSalt i (TC s _) = hashWithSalt i s
+
+instance Hashable Sort
+
+newtype Sub = Sub [(Int, Sort)] deriving (Generic)
+
+instance Fixpoint Sort where
+  toFix = toFixSort
+
+toFixSort :: Sort -> Doc
+toFixSort (FVar i)     = text "@"   <> parens (toFix i)
+toFixSort FInt         = text "int"
+toFixSort FReal        = text "real"
+toFixSort FFrac        = text "frac"
+toFixSort (FObj x)     = toFix x
+toFixSort FNum         = text "num"
+toFixSort t@(FAbs _ _) = toFixAbsApp t
+toFixSort t@(FFunc _ _)= toFixAbsApp t
+toFixSort (FTC c)      = toFix c
+toFixSort t@(FApp _ _) = toFixFApp (fApp' t)
+
+toFixAbsApp :: Sort -> Doc
+toFixAbsApp t = text "func" <> parens (toFix n <> text ", " <> toFix ts)
+  where
+    Just (vs, ss, s) = functionSort t
+    n                = length vs
+    ts               = ss ++ [s]
+
+toFixFApp            :: ListNE Sort -> Doc
+toFixFApp [t]        = toFixSort t
+toFixFApp [FTC c, t]
+  | isListTC c       = brackets $ toFixSort t
+toFixFApp ts         = parens $ intersperse space (toFixSort <$> ts)
+
+instance Fixpoint FTycon where
+  toFix (TC s _)       = toFix s
+
+-------------------------------------------------------------------------
+-- | Exported Basic Sorts -----------------------------------------------
+-------------------------------------------------------------------------
+
+boolSort, intSort, realSort, strSort, funcSort :: Sort
+boolSort = fTyconSort boolFTyCon
+strSort  = fTyconSort strFTyCon
+intSort  = fTyconSort intFTyCon
+realSort = fTyconSort realFTyCon
+funcSort = fTyconSort funcFTyCon
+
+setSort :: Sort -> Sort
+setSort    = FApp (FTC setFTyCon)
+
+bitVecSort :: Sort
+bitVecSort = FApp (FTC $ symbolFTycon' bitVecName) (FTC $ symbolFTycon' size32Name)
+
+mapSort :: Sort -> Sort -> Sort
+mapSort = FApp . FApp (FTC (symbolFTycon' mapConName))
+
+symbolFTycon' :: Symbol -> FTycon
+symbolFTycon' = symbolFTycon . dummyLoc
+
+fTyconSort :: FTycon -> Sort
+fTyconSort c
+  | c == intFTyCon  = FInt
+  | c == realFTyCon = FReal
+  | c == numFTyCon  = FNum
+  | otherwise       = FTC c
+
+------------------------------------------------------------------------
+sortSubst                  :: M.HashMap Symbol Sort -> Sort -> Sort
+------------------------------------------------------------------------
+sortSubst θ t@(FObj x)    = fromMaybe t (M.lookup x θ)
+sortSubst θ (FFunc t1 t2) = FFunc (sortSubst θ t1) (sortSubst θ t2)
+sortSubst θ (FApp t1 t2)  = FApp  (sortSubst θ t1) (sortSubst θ t2)
+sortSubst θ (FAbs i t)    = FAbs i (sortSubst θ t)
+sortSubst _  t            = t
+
+
+instance B.Binary FTycon
+instance B.Binary TCInfo
+instance B.Binary Sort
+instance B.Binary Sub
+
+instance NFData FTycon
+instance NFData TCInfo
+instance NFData Sort
+instance NFData Sub
+
+
+instance Monoid Sort where
+  mempty            = FObj "any"
+  mappend t1 t2
+    | t1 == mempty  = t2
+    | t2 == mempty  = t1
+    | t1 == t2      = t1
+    | otherwise     = errorstar $ "mappend-sort: conflicting sorts t1 =" ++ show t1 ++ " t2 = " ++ show t2
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Spans.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Spans.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Spans.hs
@@ -0,0 +1,189 @@
+{-# LANGUAGE DeriveDataTypeable        #-}
+{-# LANGUAGE DeriveGeneric             #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE ScopedTypeVariables       #-}
+
+module Language.Fixpoint.Types.Spans (
+
+  -- * Concrete Location Type
+    SourcePos
+  , SrcSpan (..)
+
+  -- * Located Values
+  , Loc (..)
+  , Located (..)
+
+  -- * Constructing spans
+  , dummySpan
+  , locAt
+  , dummyLoc
+  , dummyPos
+  , atLoc
+
+  -- * Destructing spans
+  , sourcePosElts
+  ) where
+
+-- import           Control.Exception
+import           Control.DeepSeq
+-- import qualified Control.Monad.Error           as E
+import           Data.Serialize                (Serialize (..))
+import           Data.Generics                 (Data)
+import           Data.Hashable
+import           Data.Typeable
+import           Data.String
+import qualified Data.Binary                   as B
+import           GHC.Generics                  (Generic)
+import           Language.Fixpoint.Types.PrettyPrint
+-- import           Language.Fixpoint.Misc
+import           Text.Parsec.Pos
+import           Text.PrettyPrint.HughesPJ
+import           Text.Printf
+-- import           Debug.Trace
+
+-----------------------------------------------------------------------
+-- | Located Values ---------------------------------------------------
+-----------------------------------------------------------------------
+
+class Loc a where
+  srcSpan :: a -> SrcSpan
+
+-----------------------------------------------------------------------
+-- | Retrofitting instances to SourcePos ------------------------------
+-----------------------------------------------------------------------
+
+instance NFData SourcePos where
+  rnf = rnf . ofSourcePos
+
+instance B.Binary SourcePos where
+  put = B.put . ofSourcePos
+  get = toSourcePos <$> B.get
+
+instance Serialize SourcePos where
+  put = put . ofSourcePos
+  get = toSourcePos <$> get
+
+instance PPrint SourcePos where
+  pprintTidy _ = text . show
+
+instance Hashable SourcePos where
+  hashWithSalt i   = hashWithSalt i . sourcePosElts
+
+ofSourcePos :: SourcePos -> (SourceName, Line, Column)
+ofSourcePos p = (f, l, c)
+  where
+   f = sourceName   p
+   l = sourceLine   p
+   c = sourceColumn p
+
+toSourcePos :: (SourceName, Line, Column) -> SourcePos
+toSourcePos (f, l, c) = newPos f l c
+
+sourcePosElts :: SourcePos -> (SourceName, Line, Column)
+sourcePosElts s = (src, line, col)
+  where
+    src         = sourceName   s
+    line        = sourceLine   s
+    col         = sourceColumn s
+
+instance Fixpoint SourcePos where
+  toFix = text . show
+
+
+data Located a = Loc { loc  :: !SourcePos -- ^ Start Position
+                     , locE :: !SourcePos -- ^ End Position
+                     , val  :: !a
+                     } deriving (Data, Typeable, Generic)
+
+instance Loc (Located a) where
+  srcSpan (Loc l l' _) = SS l l'
+
+
+instance (NFData a) => NFData (Located a)
+
+instance Fixpoint a => Fixpoint (Located a) where
+  toFix = toFix . val
+
+instance Functor Located where
+  fmap f (Loc l l' x) =  Loc l l' (f x)
+
+
+instance Foldable Located where
+  foldMap f (Loc _ _ x) = f x
+
+instance Traversable Located where
+  traverse f (Loc l l' x) = Loc l l' <$> f x
+
+instance Show a => Show (Located a) where
+  show (Loc l l' x)
+    | l == l' && l == dummyPos "Fixpoint.Types.dummyLoc" = show x ++ " (dummyLoc)"
+    | otherwise  = show x ++ " defined from: " ++ show l ++ " to: " ++ show l'
+
+instance PPrint a => PPrint (Located a) where
+  pprintTidy k (Loc _ _ x) = pprintTidy k x
+
+instance Eq a => Eq (Located a) where
+  (Loc _ _ x) == (Loc _ _ y) = x == y
+
+instance Ord a => Ord (Located a) where
+  compare x y = compare (val x) (val y)
+
+instance (B.Binary a) => B.Binary (Located a)
+
+instance Hashable a => Hashable (Located a) where
+  hashWithSalt i = hashWithSalt i . val
+
+instance (IsString a) => IsString (Located a) where
+  fromString = dummyLoc . fromString
+
+
+-----------------------------------------------------------------------
+-- | A Reusable SrcSpan Type ------------------------------------------
+-----------------------------------------------------------------------
+
+data SrcSpan = SS { sp_start :: !SourcePos
+                  , sp_stop  :: !SourcePos}
+                 deriving (Eq, Ord, Show, Data, Typeable, Generic)
+
+instance Serialize SrcSpan
+
+instance PPrint SrcSpan where
+  pprintTidy _ = ppSrcSpan
+
+-- ppSrcSpan_short z = parens
+--                   $ text (printf "file %s: (%d, %d) - (%d, %d)" (takeFileName f) l c l' c')
+--   where
+--     (f,l ,c )     = sourcePosElts $ sp_start z
+--     (_,l',c')     = sourcePosElts $ sp_stop  z
+
+ppSrcSpan :: SrcSpan -> Doc
+ppSrcSpan z       = text (printf "%s:%d:%d-%d:%d" f l c l' c')
+                -- parens $ text (printf "file %s: (%d, %d) - (%d, %d)" (takeFileName f) l c l' c')
+  where
+    (f,l ,c )     = sourcePosElts $ sp_start z
+    (_,l',c')     = sourcePosElts $ sp_stop  z
+
+
+instance Hashable SrcSpan where
+  hashWithSalt i z = hashWithSalt i (sp_start z, sp_stop z)
+
+dummySpan :: SrcSpan
+dummySpan = SS l l
+  where l = initialPos ""
+
+atLoc :: Located a -> b -> Located b
+atLoc (Loc l l' _) = Loc l l'
+
+locAt :: String -> a -> Located a
+locAt s  = Loc l l
+  where
+    l    = dummyPos s
+
+dummyLoc :: a -> Located a
+dummyLoc = Loc l l
+  where
+    l    = dummyPos "Fixpoint.Types.dummyLoc"
+
+dummyPos   :: String -> SourcePos
+dummyPos s = newPos s 0 0
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Substitutions.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Substitutions.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Substitutions.hs
@@ -0,0 +1,283 @@
+-- | This module contains the various instances for Subable,
+--   which (should) depend on the visitors, and hence cannot
+--   be in the same place as the @Term@ definitions.
+module Language.Fixpoint.Types.Substitutions (
+    mkSubst
+  , isEmptySubst
+  , substExcept
+  , substfExcept
+  , subst1Except
+  , targetSubstSyms
+  , filterSubst
+  ) where
+
+import           Data.Maybe
+import qualified Data.HashMap.Strict       as M
+import qualified Data.HashSet              as S
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Types.Sorts
+import           Language.Fixpoint.Types.Refinements
+import           Language.Fixpoint.Misc
+import           Text.PrettyPrint.HughesPJ
+import           Text.Printf               (printf)
+
+instance Monoid Subst where
+  mempty  = emptySubst
+  mappend = catSubst
+
+filterSubst :: (Symbol -> Expr -> Bool) -> Subst -> Subst
+filterSubst f (Su m) = Su (M.filterWithKey f m)
+
+emptySubst :: Subst
+emptySubst = Su M.empty
+
+catSubst :: Subst -> Subst -> Subst
+catSubst (Su s1) θ2@(Su s2) = Su $ M.union s1' s2
+  where
+    s1'                     = subst θ2 <$> s1
+
+mkSubst :: [(Symbol, Expr)] -> Subst
+
+mkSubst = Su . M.fromList . reverse . filter notTrivial 
+  where
+    notTrivial (x, EVar y) = x /= y
+    notTrivial _           = True  
+
+isEmptySubst :: Subst -> Bool
+isEmptySubst (Su xes) = M.null xes
+
+targetSubstSyms :: Subst -> [Symbol]
+targetSubstSyms (Su ms) = syms $ M.elems ms
+
+instance Subable () where
+  syms _      = []
+  subst _ ()  = ()
+  substf _ () = ()
+  substa _ () = ()
+
+instance (Subable a, Subable b) => Subable (a,b) where
+  syms  (x, y)   = syms x ++ syms y
+  subst su (x,y) = (subst su x, subst su y)
+  substf f (x,y) = (substf f x, substf f y)
+  substa f (x,y) = (substa f x, substa f y)
+
+instance Subable a => Subable [a] where
+  syms   = concatMap syms
+  subst  = map . subst
+  substf = map . substf
+  substa = map . substa
+
+instance Subable a => Subable (M.HashMap k a) where
+  syms   = syms . M.elems
+  subst  = M.map . subst
+  substf = M.map . substf
+  substa = M.map . substa
+
+subst1Except :: (Subable a) => [Symbol] -> a -> (Symbol, Expr) -> a
+subst1Except xs z su@(x, _)
+  | x `elem` xs = z
+  | otherwise   = subst1 z su
+
+substfExcept :: (Symbol -> Expr) -> [Symbol] -> Symbol -> Expr
+substfExcept f xs y = if y `elem` xs then EVar y else f y
+
+substExcept  :: Subst -> [Symbol] -> Subst
+-- substExcept  (Su m) xs = Su (foldr M.delete m xs)
+substExcept (Su xes) xs = Su $ M.filterWithKey (const . not . (`elem` xs)) xes
+
+instance Subable Symbol where
+  substa f                 = f
+  substf f x               = subSymbol (Just (f x)) x
+  subst su x               = subSymbol (Just $ appSubst su x) x -- subSymbol (M.lookup x s) x
+  syms x                   = [x]
+
+appSubst :: Subst -> Symbol -> Expr
+appSubst (Su s) x = fromMaybe (EVar x) (M.lookup x s)
+
+subSymbol :: Maybe Expr -> Symbol -> Symbol
+subSymbol (Just (EVar y)) _ = y
+subSymbol Nothing         x = x
+subSymbol a               b = errorstar (printf "Cannot substitute symbol %s with expression %s" (showFix b) (showFix a))
+
+substfLam :: (Symbol -> Expr) -> (Symbol, Sort) -> Expr -> Expr
+substfLam f s@(x, _) e =  ELam s (substf (\y -> if y == x then EVar x else f y) e)
+
+instance Subable Expr where
+  syms                     = exprSymbols
+  substa f                 = substf (EVar . f)
+  substf f (EApp s e)      = EApp (substf f s) (substf f e)
+  substf f (ELam x e)      = substfLam f x e
+  substf f (ENeg e)        = ENeg (substf f e)
+  substf f (EBin op e1 e2) = EBin op (substf f e1) (substf f e2)
+  substf f (EIte p e1 e2)  = EIte (substf f p) (substf f e1) (substf f e2)
+  substf f (ECst e so)     = ECst (substf f e) so
+  substf f (EVar x)        = f x
+  substf f (PAnd ps)       = PAnd $ map (substf f) ps
+  substf f (POr  ps)       = POr  $ map (substf f) ps
+  substf f (PNot p)        = PNot $ substf f p
+  substf f (PImp p1 p2)    = PImp (substf f p1) (substf f p2)
+  substf f (PIff p1 p2)    = PIff (substf f p1) (substf f p2)
+  substf f (PAtom r e1 e2) = PAtom r (substf f e1) (substf f e2)
+  substf _ p@(PKVar _ _)   = p
+  substf _  (PAll _ _)     = errorstar "substf: FORALL"
+  substf f (PGrad k su e)  = PGrad k su (substf f e)
+  substf _  p              = p
+
+
+  subst su (EApp f e)      = EApp (subst su f) (subst su e)
+  subst su (ELam x e)      = ELam x (subst (removeSubst su (fst x)) e)
+  subst su (ENeg e)        = ENeg (subst su e)
+  subst su (EBin op e1 e2) = EBin op (subst su e1) (subst su e2)
+  subst su (EIte p e1 e2)  = EIte (subst su p) (subst su e1) (subst su e2)
+  subst su (ECst e so)     = ECst (subst su e) so
+  subst su (EVar x)        = appSubst su x
+  subst su (PAnd ps)       = PAnd $ map (subst su) ps
+  subst su (POr  ps)       = POr  $ map (subst su) ps
+  subst su (PNot p)        = PNot $ subst su p
+  subst su (PImp p1 p2)    = PImp (subst su p1) (subst su p2)
+  subst su (PIff p1 p2)    = PIff (subst su p1) (subst su p2)
+  subst su (PAtom r e1 e2) = PAtom r (subst su e1) (subst su e2)
+  subst su (PKVar k su')   = PKVar k $ su' `catSubst` su
+  subst su (PGrad k su' e) = PGrad k (su' `catSubst` su)  (subst su e)
+  subst su (PAll bs p)
+          | disjoint su bs = PAll bs $ subst su p --(substExcept su (fst <$> bs)) p
+          | otherwise      = errorstar "subst: PAll (without disjoint binds)"
+  subst su (PExist bs p)
+          | disjoint su bs = PExist bs $ subst su p --(substExcept su (fst <$> bs)) p
+          | otherwise      = errorstar ("subst: EXISTS (without disjoint binds)" ++ show (bs, su))
+  subst _  p               = p
+
+removeSubst :: Subst -> Symbol -> Subst
+removeSubst (Su su) x = Su $ M.delete x su
+
+disjoint :: Subst -> [(Symbol, Sort)] -> Bool
+disjoint (Su su) bs = S.null $ suSyms `S.intersection` bsSyms
+  where
+    suSyms = S.fromList $ syms (M.elems su) ++ syms (M.keys su)
+    bsSyms = S.fromList $ syms $ fst <$> bs
+
+instance Monoid Expr where
+  mempty      = PTrue
+  mappend p q = pAnd [p, q]
+  mconcat     = pAnd
+
+instance Monoid Reft where
+  mempty  = trueReft
+  mappend = meetReft
+
+meetReft :: Reft -> Reft -> Reft
+meetReft (Reft (v, ra)) (Reft (v', ra'))
+  | v == v'          = Reft (v , ra  `mappend` ra')
+  | v == dummySymbol = Reft (v', ra' `mappend` (ra `subst1`  (v , EVar v')))
+  | otherwise        = Reft (v , ra  `mappend` (ra' `subst1` (v', EVar v )))
+
+instance Monoid SortedReft where
+  mempty        = RR mempty mempty
+  mappend t1 t2 = RR (mappend (sr_sort t1) (sr_sort t2)) (mappend (sr_reft t1) (sr_reft t2))
+
+instance Subable Reft where
+  syms (Reft (v, ras))      = v : syms ras
+  substa f (Reft (v, ras))  = Reft (f v, substa f ras)
+  subst su (Reft (v, ras))  = Reft (v, subst (substExcept su [v]) ras)
+  substf f (Reft (v, ras))  = Reft (v, substf (substfExcept f [v]) ras)
+  subst1 (Reft (v, ras)) su = Reft (v, subst1Except [v] ras su)
+
+instance Subable SortedReft where
+  syms               = syms . sr_reft
+  subst su (RR so r) = RR so $ subst su r
+  substf f (RR so r) = RR so $ substf f r
+  substa f (RR so r) = RR so $ substa f r
+
+instance Reftable () where
+  isTauto _ = True
+  ppTy _  d = d
+  top  _    = ()
+  bot  _    = ()
+  meet _ _  = ()
+  toReft _  = mempty
+  ofReft _  = mempty
+  params _  = []
+
+instance Reftable Reft where
+  isTauto  = all isTautoPred . conjuncts . reftPred
+  ppTy     = pprReft
+  toReft   = id
+  ofReft   = id
+  params _ = []
+  bot    _        = falseReft
+  top (Reft(v,_)) = Reft (v, mempty)
+
+pprReft :: Reft -> Doc -> Doc
+pprReft (Reft (v, p)) d
+  | isTautoPred p
+  = d
+  | otherwise
+  = braces (toFix v <+> colon <+> d <+> text "|" <+> ppRas [p])
+
+instance Reftable SortedReft where
+  isTauto  = isTauto . toReft
+  ppTy     = ppTy . toReft
+  toReft   = sr_reft
+  ofReft   = errorstar "No instance of ofReft for SortedReft"
+  params _ = []
+  bot s    = s { sr_reft = falseReft }
+  top s    = s { sr_reft = trueReft }
+
+-- RJ: this depends on `isTauto` hence, here.
+instance PPrint Reft where
+  pprintTidy k r
+    | isTauto r        = text "true"
+    | otherwise        = pprintReft k r
+
+instance PPrint SortedReft where
+  pprintTidy k (RR so (Reft (v, ras)))
+    = braces
+    $ pprintTidy k v <+> text ":" <+> toFix so <+> text "|" <+> pprintTidy k ras
+
+instance Fixpoint Reft where
+  toFix = pprReftPred
+
+instance Fixpoint SortedReft where
+  toFix (RR so (Reft (v, ra)))
+    = braces
+    $ toFix v <+> text ":" <+> toFix so <+> text "|" <+> toFix (conjuncts ra)
+
+instance Show Reft where
+  show = showFix
+
+instance Show SortedReft where
+  show  = showFix
+
+pprReftPred :: Reft -> Doc
+pprReftPred (Reft (_, p))
+  | isTautoPred p
+  = text "true"
+  | otherwise
+  = ppRas [p]
+
+ppRas :: [Expr] -> Doc
+ppRas = cat . punctuate comma . map toFix . flattenRefas
+
+--------------------------------------------------------------------------------
+-- | TODO: Rewrite using visitor -----------------------------------------------
+--------------------------------------------------------------------------------
+exprSymbols :: Expr -> [Symbol]
+exprSymbols = go
+  where
+    go (EVar x)           = [x]
+    go (EApp f e)         = go f ++ go e
+    go (ELam (x,_) e)     = filter (/= x) (go e)
+    go (ENeg e)           = go e
+    go (EBin _ e1 e2)     = go e1 ++ go e2
+    go (EIte p e1 e2)     = exprSymbols p ++ go e1 ++ go e2
+    go (ECst e _)         = go e
+    go (PAnd ps)          = concatMap go ps
+    go (POr ps)           = concatMap go ps
+    go (PNot p)           = go p
+    go (PIff p1 p2)       = go p1 ++ go p2
+    go (PImp p1 p2)       = go p1 ++ go p2
+    go (PAtom _ e1 e2)    = exprSymbols e1 ++ exprSymbols e2
+    go (PKVar _ (Su su))  = {- CUTSOLVER k : -} syms (M.elems su)
+    go (PAll xts p)       = (fst <$> xts) ++ go p
+    go _                  = []
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Triggers.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Triggers.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Triggers.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveFunctor              #-}
+{-# LANGUAGE DeriveGeneric              #-}
+
+module Language.Fixpoint.Types.Triggers (
+
+    Triggered (..), Trigger(..),
+
+    noTrigger, defaultTrigger,
+
+    makeTriggers
+
+    ) where
+
+import qualified Data.Binary as B
+import           Control.DeepSeq
+import           GHC.Generics              (Generic)
+
+import Language.Fixpoint.Types.Refinements
+import Language.Fixpoint.Misc              (errorstar)
+
+
+data Triggered a = TR Trigger a
+  deriving (Eq, Show, Functor, Generic)
+
+data Trigger = NoTrigger | LeftHandSide
+  deriving (Eq, Show, Generic)
+
+
+noTrigger :: e -> Triggered e
+noTrigger = TR NoTrigger
+
+defaultTrigger :: e -> Triggered e
+defaultTrigger = TR LeftHandSide
+
+makeTriggers :: Triggered Expr -> [Expr]
+makeTriggers (TR LeftHandSide e) = [getLeftHandSide e]
+makeTriggers (TR NoTrigger    _) = errorstar "makeTriggers on NoTrigger"
+
+
+getLeftHandSide :: Expr -> Expr
+getLeftHandSide (ECst e _)
+  = getLeftHandSide e
+getLeftHandSide (PAll _ e)
+  = getLeftHandSide e
+getLeftHandSide (PExist _ e)
+  = getLeftHandSide e
+getLeftHandSide (PAtom eq lhs _)
+  | eq == Eq || eq == Ueq
+  = lhs
+getLeftHandSide (PIff lhs _)
+  = lhs
+getLeftHandSide _
+ = defaltPatter
+
+-- NV TODO find out a valid, default pattern that does not instantiate the axiom
+defaltPatter :: Expr
+defaltPatter = PFalse
+
+instance B.Binary Trigger
+instance NFData   Trigger
+
+instance (B.Binary a) => B.Binary (Triggered a)
+instance (NFData a)   => NFData   (Triggered a)
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Utils.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Utils.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Utils.hs
@@ -0,0 +1,57 @@
+-- | This module has various utility functions for accessing queries.
+--   TODO: move the "clients" in Visitors into this module.
+
+module Language.Fixpoint.Types.Utils (
+  -- * Domain of a kvar
+    kvarDomain
+
+  -- * Free variables in a refinement
+  , reftFreeVars
+
+  -- * Deconstruct a SortedReft
+  , sortedReftConcKVars
+  ) where
+
+import qualified Data.HashMap.Strict                  as M
+import qualified Data.HashSet                         as S
+
+import           Language.Fixpoint.Misc
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Types.Refinements
+import           Language.Fixpoint.Types.Environments
+import           Language.Fixpoint.Types.Constraints
+
+--------------------------------------------------------------------------------
+-- | Compute the domain of a kvar
+--------------------------------------------------------------------------------
+kvarDomain :: SInfo a -> KVar -> [Symbol]
+--------------------------------------------------------------------------------
+kvarDomain si k = domain (bs si) (getWfC si k)
+
+domain :: BindEnv -> WfC a -> [Symbol]
+domain be wfc = fst3 (wrft wfc) : map fst (envCs be $ wenv wfc)
+
+getWfC :: SInfo a -> KVar -> WfC a
+getWfC si k = ws si M.! k
+
+--------------------------------------------------------------------------------
+-- | Free variables of a refinement
+--------------------------------------------------------------------------------
+--TODO deduplicate (also in Solver/UniqifyBinds)
+reftFreeVars :: Reft -> S.HashSet Symbol
+reftFreeVars r@(Reft (v, _)) = S.delete v $ S.fromList $ syms r
+
+--------------------------------------------------------------------------------
+-- | Split a SortedReft into its concrete and KVar components
+--------------------------------------------------------------------------------
+sortedReftConcKVars :: Symbol -> SortedReft -> ([Pred], [KVSub], [KVSub])
+sortedReftConcKVars x sr = go [] [] [] ves
+  where
+    ves                  = [(v, p `subst1` (v, eVar x)) | Reft (v, p) <- rs ]
+    rs                   = reftConjuncts (sr_reft sr)
+    t                    = sr_sort sr
+
+    go ps ks gs ((v, PKVar k su  ):xs) = go ps (KVS v t k su:ks) gs xs 
+    go ps ks gs ((v, PGrad k su _):xs) = go ps ks (KVS v t k su:gs) xs 
+    go ps ks gs ((_, p):xs)            = go (p:ps) ks gs xs 
+    go ps ks gs []                     = (ps, ks, gs)
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Types/Visitor.hs b/liquid-fixpoint/src/Language/Fixpoint/Types/Visitor.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Types/Visitor.hs
@@ -0,0 +1,349 @@
+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+
+module Language.Fixpoint.Types.Visitor (
+  -- * Visitor
+     Visitor (..)
+  ,  Visitable (..)
+
+  -- * Extracting Symbolic Constants (String Literals)
+  ,  SymConsts (..)
+
+  -- * Default Visitor
+  , defaultVisitor
+
+  -- * Transformers
+  , trans
+
+  -- * Accumulators
+  , fold
+
+  -- * Clients
+  , stripCasts
+  , kvars, eapps
+  , size, lamSize
+  , envKVars
+  , envKVarsN
+  , rhsKVars
+  , mapKVars, mapKVars', mapKVarSubsts
+  , mapExpr, mapMExpr
+
+  -- * Predicates on Constraints
+  , isConcC , isKvarC
+
+  -- * Sorts
+  , foldSort, mapSort
+
+
+  ) where
+
+import           Control.Monad.Trans.State.Strict (State, modify, runState)
+import qualified Data.HashSet        as S
+import qualified Data.HashMap.Strict as M
+import qualified Data.List           as L
+import           Language.Fixpoint.Types hiding (mapSort)
+import           Language.Fixpoint.Misc (count, sortNub)
+
+data Visitor acc ctx = Visitor {
+ -- | Context @ctx@ is built in a "top-down" fashion; not "across" siblings
+    ctxExpr :: ctx -> Expr -> ctx
+
+  -- | Transforms can access current @ctx@
+  , txExpr  :: ctx -> Expr -> Expr
+
+  -- | Accumulations can access current @ctx@; @acc@ value is monoidal
+  , accExpr :: ctx -> Expr -> acc
+  }
+
+---------------------------------------------------------------------------------
+defaultVisitor :: Monoid acc => Visitor acc ctx
+---------------------------------------------------------------------------------
+defaultVisitor = Visitor
+  { ctxExpr    = const -- \c _ -> c
+  , txExpr     = \_ x -> x
+  , accExpr    = \_ _ -> mempty
+  }
+
+
+------------------------------------------------------------------------
+
+fold         :: (Visitable t, Monoid a) => Visitor a ctx -> ctx -> a -> t -> a
+fold v c a t = snd $ execVisitM v c a visit t
+
+trans        :: (Visitable t, Monoid a) => Visitor a ctx -> ctx -> a -> t -> t
+trans v c _ z = fst $ execVisitM v c mempty visit z
+
+execVisitM :: Visitor a ctx -> ctx -> a -> (Visitor a ctx -> ctx -> t -> State a t) -> t -> (t, a)
+execVisitM v c a f x = runState (f v c x) a
+
+type VisitM acc = State acc
+
+accum :: (Monoid a) => a -> VisitM a ()
+accum = modify . mappend
+
+(<$$>) ::  (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
+f <$$> x = traverse f x
+
+------------------------------------------------------------------------------
+class Visitable t where
+  visit :: (Monoid a) => Visitor a c -> c -> t -> VisitM a t
+
+instance Visitable Expr where
+  visit = visitExpr
+
+instance Visitable Reft where
+  visit v c (Reft (x, ra)) = (Reft . (x, )) <$> visit v c ra
+
+instance Visitable SortedReft where
+  visit v c (RR t r) = RR t <$> visit v c r
+
+instance Visitable (Symbol, SortedReft) where
+  visit v c (sym, sr) = (sym, ) <$> visit v c sr
+
+instance Visitable BindEnv where
+  visit v c = mapM (visit v c)
+
+---------------------------------------------------------------------------------
+-- WARNING: these instances were written for mapKVars over GInfos only;
+-- check that they behave as expected before using with other clients.
+instance Visitable (SimpC a) where
+  visit v c x = do
+    rhs' <- visit v c (_crhs x)
+    return x { _crhs = rhs' }
+
+instance Visitable (SubC a) where
+  visit v c x = do
+    lhs' <- visit v c (slhs x)
+    rhs' <- visit v c (srhs x)
+    return x { slhs = lhs', srhs = rhs' }
+
+instance (Visitable (c a)) => Visitable (GInfo c a) where
+  visit v c x = do
+    cm' <- mapM (visit v c) (cm x)
+    bs' <- visit v c (bs x)
+    return x { cm = cm', bs = bs' }
+
+
+
+---------------------------------------------------------------------------------
+visitExpr :: (Monoid a) => Visitor a ctx -> ctx -> Expr -> VisitM a Expr
+visitExpr v = vE
+  where
+    vE c e = do {-# SCC "visitExpr.vE.accum" #-} accum acc
+                {-# SCC "visitExpr.vE.step" #-} step c' e'
+      where c'  = ctxExpr v c e
+            e'  = txExpr v c' e
+            acc = accExpr v c' e
+    step _ e@(ESym _)      = return e
+    step _ e@(ECon _)      = return e
+    step _ e@(EVar _)      = return e
+    step c (EApp f e)      = EApp        <$> vE c f  <*> vE c e
+    step c (ENeg e)        = ENeg        <$> vE c e
+    step c (EBin o e1 e2)  = EBin o      <$> vE c e1 <*> vE c e2
+    step c (EIte p e1 e2)  = EIte        <$> vE c p  <*> vE c e1 <*> vE c e2
+    step c (ECst e t)      = (`ECst` t)  <$> vE c e
+    step c (PAnd  ps)      = PAnd        <$> (vE c <$$> ps)
+    step c (POr  ps)       = POr         <$> (vE c <$$> ps)
+    step c (PNot p)        = PNot        <$> vE c p
+    step c (PImp p1 p2)    = PImp        <$> vE c p1 <*> vE c p2
+    step c (PIff p1 p2)    = PIff        <$> vE c p1 <*> vE c p2
+    step c (PAtom r e1 e2) = PAtom r     <$> vE c e1 <*> vE c e2
+    step c (PAll xts p)    = PAll   xts  <$> vE c p
+    step c (ELam (x,t) e)  = ELam (x,t)  <$> vE c e
+    step c (PExist xts p)  = PExist xts  <$> vE c p
+    step c (ETApp e s)     = (`ETApp` s) <$> vE c e
+    step c (ETAbs e s)     = (`ETAbs` s) <$> vE c e
+    step _ p@(PKVar _ _)   = return p
+    step c (PGrad k su e)  = PGrad k su <$> vE c e 
+
+mapKVars :: Visitable t => (KVar -> Maybe Expr) -> t -> t
+mapKVars f = mapKVars' f'
+  where
+    f' (kv', _) = f kv'
+
+mapKVars' :: Visitable t => ((KVar, Subst) -> Maybe Expr) -> t -> t
+mapKVars' f            = trans kvVis () []
+  where
+    kvVis              = defaultVisitor { txExpr = txK }
+    txK _ (PKVar k su)
+      | Just p' <- f (k, su) = subst su p'
+    txK _ (PGrad k su _)
+      | Just p' <- f (k, su) = subst su p'
+    txK _ p            = p
+
+mapExpr :: (Expr -> Expr) -> Expr -> Expr
+mapExpr f = trans (defaultVisitor {txExpr = const f}) () []
+
+
+mapMExpr :: (Monad m) => (Expr -> m Expr) -> Expr -> m Expr
+mapMExpr f = go
+  where
+    go e@(ESym _)      = f e
+    go e@(ECon _)      = f e
+    go e@(EVar _)      = f e
+    go e@(PKVar _ _)   = f e
+    go (PGrad k su e)  = f =<< (PGrad k su  <$>  go e                     )
+    go (ENeg e)        = f =<< (ENeg        <$>  go e                     )
+    go (PNot p)        = f =<< (PNot        <$>  go p                     )
+    go (ECst e t)      = f =<< ((`ECst` t)  <$>  go e                     )
+    go (PAll xts p)    = f =<< (PAll   xts  <$>  go p                     )
+    go (ELam (x,t) e)  = f =<< (ELam (x,t)  <$>  go e                     )
+    go (PExist xts p)  = f =<< (PExist xts  <$>  go p                     )
+    go (ETApp e s)     = f =<< ((`ETApp` s) <$>  go e                     )
+    go (ETAbs e s)     = f =<< ((`ETAbs` s) <$>  go e                     )
+    go (EApp g e)      = f =<< (EApp        <$>  go g  <*> go e           )
+    go (EBin o e1 e2)  = f =<< (EBin o      <$>  go e1 <*> go e2          )
+    go (PImp p1 p2)    = f =<< (PImp        <$>  go p1 <*> go p2          )
+    go (PIff p1 p2)    = f =<< (PIff        <$>  go p1 <*> go p2          )
+    go (PAtom r e1 e2) = f =<< (PAtom r     <$>  go e1 <*> go e2          )
+    go (EIte p e1 e2)  = f =<< (EIte        <$>  go p  <*> go e1 <*> go e2)
+    go (PAnd  ps)      = f =<< (PAnd        <$> (go <$$> ps)              )
+    go (POr  ps)       = f =<< (POr         <$> (go <$$> ps)              )
+
+mapKVarSubsts :: Visitable t => (KVar -> Subst -> Subst) -> t -> t
+mapKVarSubsts f          = trans kvVis () []
+  where
+    kvVis                = defaultVisitor { txExpr = txK }
+    txK _ (PKVar k su)   = PKVar k (f k su)
+    txK _ (PGrad k su e) = PGrad k (f k su) e
+    txK _ p              = p
+  
+newtype MInt = MInt Integer
+
+instance Monoid MInt where
+  mempty                    = MInt 0
+  mappend (MInt m) (MInt n) = MInt (m + n)
+
+size :: Visitable t => t -> Integer
+size t    = n
+  where
+    MInt n = fold szV () mempty t
+    szV    = (defaultVisitor :: Visitor MInt t) { accExpr = \ _ _ -> MInt 1 }
+
+
+lamSize :: Visitable t => t -> Integer
+lamSize t    = n
+  where
+    MInt n = fold szV () mempty t
+    szV    = (defaultVisitor :: Visitor MInt t) { accExpr = accum }
+    accum _ (ELam _ _) = MInt 1
+    accum _ _          = MInt 0
+
+eapps :: Visitable t => t -> [Expr]
+eapps                 = fold eappVis () []
+  where
+    eappVis              = (defaultVisitor :: Visitor [KVar] t) { accExpr = eapp' }
+    eapp' _ e@(EApp _ _) = [e]
+    eapp' _ _            = []
+
+kvars :: Visitable t => t -> [KVar]
+kvars                 = fold kvVis () []
+  where
+    kvVis             = (defaultVisitor :: Visitor [KVar] t) { accExpr = kv' }
+    kv' _ (PKVar k _)   = [k]
+    kv' _ (PGrad k _ _) = [k]
+    kv' _ _             = []
+
+envKVars :: (TaggedC c a) => BindEnv -> c a -> [KVar]
+envKVars be c = squish [ kvs sr |  (_, sr) <- clhs be c]
+  where
+    squish    = S.toList  . S.fromList . concat
+    kvs       = kvars . sr_reft
+
+envKVarsN :: (TaggedC c a) => BindEnv -> c a -> [(KVar, Int)]
+envKVarsN be c = tally [ kvs sr |  (_, sr) <- clhs be c]
+  where
+    tally      = count . concat
+    kvs        = kvars . sr_reft
+
+rhsKVars :: (TaggedC c a) => c a -> [KVar]
+rhsKVars = kvars . crhs -- rhsCs
+
+isKvarC :: (TaggedC c a) => c a -> Bool
+isKvarC = all isKvar . conjuncts . crhs
+
+isConcC :: (TaggedC c a) => c a -> Bool
+isConcC = all isConc . conjuncts . crhs
+
+isKvar :: Expr -> Bool
+isKvar (PKVar {}) = True
+isKvar (PGrad {}) = True 
+isKvar _          = False
+
+isConc :: Expr -> Bool
+isConc = null . kvars
+
+stripCasts :: Expr -> Expr
+stripCasts = mapExpr go
+  where
+    go (ECst e _) = e
+    go e          = e
+
+---------------------------------------------------------------------------------
+-- | Visitors over @Sort@
+---------------------------------------------------------------------------------
+foldSort :: (a -> Sort -> a) -> a -> Sort -> a
+foldSort f = step
+  where
+    step b t           = go (f b t) t
+    go b (FFunc t1 t2) = L.foldl' step b [t1, t2]
+    go b (FApp t1 t2)  = L.foldl' step b [t1, t2]
+    go b (FAbs _ t)    = go b t
+    go b _             = b
+
+mapSort :: (Sort -> Sort) -> Sort -> Sort
+mapSort f = step
+  where
+    step             = go . f
+    go (FFunc t1 t2) = FFunc (step t1) (step t2)
+    go (FApp t1 t2)  = FApp (step t1) (step t2)
+    go (FAbs i t)    = FAbs i (step t)
+    go t             = t
+
+---------------------------------------------------------------
+-- | String Constants -----------------------------------------
+---------------------------------------------------------------
+
+-- symConstLits    :: FInfo a -> [(Symbol, Sort)]
+-- symConstLits fi = [(symbol c, strSort) | c <- symConsts fi]
+
+class SymConsts a where
+  symConsts :: a -> [SymConst]
+
+-- instance  SymConsts (FInfo a) where
+instance (SymConsts (c a)) => SymConsts (GInfo c a) where
+  symConsts fi = sortNub $ csLits ++ bsLits ++ qsLits
+    where
+      csLits   = concatMap symConsts $ M.elems  $  cm    fi
+      bsLits   = symConsts           $ bs                fi
+      qsLits   = concatMap symConsts $ qBody   <$> quals fi
+
+instance SymConsts BindEnv where
+  symConsts    = concatMap (symConsts . snd) . M.elems . beBinds
+
+instance SymConsts (SubC a) where
+  symConsts c  = symConsts (slhs c) ++
+                 symConsts (srhs c)
+
+instance SymConsts (SimpC a) where
+  symConsts c  = symConsts (crhs c)
+
+instance SymConsts SortedReft where
+  symConsts = symConsts . sr_reft
+
+instance SymConsts Reft where
+  symConsts (Reft (_, ra)) = getSymConsts ra
+
+
+instance SymConsts Expr where
+  symConsts = getSymConsts
+
+getSymConsts :: Visitable t => t -> [SymConst]
+getSymConsts         = fold scVis () []
+  where
+    scVis            = (defaultVisitor :: Visitor [SymConst] t)  { accExpr = sc }
+    sc _ (ESym c)    = [c]
+    sc _ _           = []
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Utils/Files.hs b/liquid-fixpoint/src/Language/Fixpoint/Utils/Files.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Utils/Files.hs
@@ -0,0 +1,210 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-- | This module contains Haskell variables representing globally visible
+-- names for files, paths, extensions.
+--
+-- Rather than have strings floating around the system, all constant names
+-- should be defined here, and the (exported) variables should be used and
+-- manipulated elsewhere.
+
+module Language.Fixpoint.Utils.Files (
+
+  -- * Hardwired file extension names
+    Ext (..)
+  , extFileName
+  , extFileNameR
+  , tempDirectory
+  , extModuleName
+  , withExt
+  , isExtFile
+  , isBinary
+
+  -- * Hardwired paths
+  , getFixpointPath
+  , getZ3LibPath
+
+  -- * Various generic utility functions for finding and removing files
+  , getFileInDirs
+  , copyFiles
+
+) where
+
+import qualified Control.Exception      as Ex
+import           Control.Monad
+import           Data.List              hiding (find)
+import           Data.Maybe             (fromMaybe)
+import           System.Directory
+import           System.FilePath
+import           Language.Fixpoint.Misc (errorstar)
+
+------------------------------------------------------------
+-- | Hardwired Paths and Files -----------------------------
+------------------------------------------------------------
+
+getFixpointPath :: IO FilePath
+getFixpointPath = fromMaybe msg . msum <$>
+                  sequence [ findExecutable "fixpoint.native"
+                           , findExecutable "fixpoint.native.exe"
+                             -- fallback for developing in-tree...
+                           , findFile ["external/fixpoint"] "fixpoint.native"
+                           ]
+  where
+    msg = errorstar "Cannot find fixpoint binary [fixpoint.native]"
+
+getZ3LibPath :: IO FilePath
+getZ3LibPath    = dropFileName <$> getFixpointPath
+
+
+--checkM f msg p
+--  = do ex <- f p
+--       if ex then return p else errorstar $ "Cannot find " ++ msg ++ " at :" ++ p
+
+
+ -----------------------------------------------------------------------------------
+
+data Ext = Cgi      -- ^ Constraint Generation Information
+         | Fq       -- ^ Input to constraint solving (fixpoint)
+         | Out      -- ^ Output from constraint solving (fixpoint)
+         | Html     -- ^ HTML file with inferred type annotations
+         | Annot    -- ^ Text file with inferred types
+         | Vim      -- ^ Vim annotation file
+         | Hs       -- ^ Haskell source
+         | HsBoot   -- ^ Haskell source
+         | LHs      -- ^ Literate Haskell source
+         | Js       -- ^ JavaScript source
+         | Ts       -- ^ Typescript source
+         | Spec     -- ^ Spec file (e.g. include/Prelude.spec)
+         | BinSpec  -- ^ Lifted-Spec file, containing automatically generated specifications 
+         | Hquals   -- ^ Qualifiers file (e.g. include/Prelude.hquals)
+         | Result   -- ^ Final result: SAFE/UNSAFE
+         | Cst      -- ^ HTML file with templates?
+         | Mkdn     -- ^ Markdown file (temporarily generated from .Lhs + annots)
+         | Json     -- ^ JSON file containing result (annots + errors)
+         | Saved    -- ^ Previous source (for incremental checking)
+         | Cache    -- ^ Previous output (for incremental checking)
+         | Dot      -- ^ Constraint Graph
+         | Part Int -- ^ Partition
+         | Auto Int -- ^ SMTLIB2 queries for automatically created proofs
+         | Pred
+         | PAss
+         | Dat
+         | BinFq    -- ^ Binary representation of .fq / FInfo
+         | Smt2     -- ^ SMTLIB2 query file
+         | Min      -- ^ filter constraints with delta debug
+         | MinQuals -- ^ filter qualifiers with delta debug
+         | MinKVars -- ^ filter kvars with delta debug
+         deriving (Eq, Ord, Show)
+
+extMap :: Ext -> FilePath
+extMap          = go
+  where
+    go Cgi      = ".cgi"
+    go Pred     = ".pred"
+    go PAss     = ".pass"
+    go Dat      = ".dat"
+    go Out      = ".fqout"
+    go Fq       = ".fq"
+    go Html     = ".html"
+    go Cst      = ".cst"
+    go Annot    = ".annot"
+    go Vim      = ".vim.annot"
+    go Hs       = ".hs"
+    go LHs      = ".lhs"
+    go HsBoot   = ".hs-boot"
+    go Js       = ".js"
+    go Ts       = ".ts"
+    go Mkdn     = ".markdown"
+    go Json     = ".json"
+    go Spec     = ".spec"
+    go BinSpec  = ".bspec"
+    go Hquals   = ".hquals"
+    go Result   = ".out"
+    go Saved    = ".bak"
+    go Cache    = ".err"
+    go Smt2     = ".smt2"
+    go (Auto n) = ".auto." ++ show n
+    go Dot      = ".dot"
+    go BinFq    = ".bfq"
+    go (Part n) = "." ++ show n
+    go Min      = ".minfq"
+    go MinQuals = ".minquals"
+    go MinKVars = ".minkvars"
+    -- go _      = errorstar $ "extMap: Unknown extension " ++ show e
+
+withExt         :: FilePath -> Ext -> FilePath
+withExt f ext   =  replaceExtension f (extMap ext)
+
+extFileName     :: Ext -> FilePath -> FilePath
+extFileName e f = path </> addExtension file ext
+  where
+    path        = tempDirectory f
+    file        = takeFileName  f
+    ext         = extMap e
+
+tempDirectory   :: FilePath -> FilePath
+tempDirectory f
+  | isTmp dir   = dir
+  | otherwise   = dir </> tmpDirName
+  where
+    dir         = takeDirectory f
+    isTmp       = (tmpDirName `isSuffixOf`)
+
+tmpDirName :: FilePath
+tmpDirName      = ".liquid"
+
+extFileNameR     :: Ext -> FilePath -> FilePath
+extFileNameR ext = (`addExtension` extMap ext)
+
+isExtFile ::  Ext -> FilePath -> Bool
+isExtFile ext = (extMap ext ==) . takeExtension
+
+extModuleName ::  String -> Ext -> FilePath
+extModuleName modName ext =
+  case explode modName of
+    [] -> errorstar $ "malformed module name: " ++ modName
+    ws -> extFileNameR ext $ foldr1 (</>) ws
+  where
+    explode = words . map (\c -> if c == '.' then ' ' else c)
+
+copyFiles :: [FilePath] -> FilePath -> IO ()
+copyFiles srcs tgt
+  = do Ex.catch (removeFile tgt) $ \(_ :: Ex.IOException) -> return ()
+       forM_ srcs (readFile >=> appendFile tgt)
+
+
+----------------------------------------------------------------------------------
+
+-- getHsTargets p = mapM canonicalizePath =<< files
+--   where
+--     files
+--       | hasTrailingPathSeparator p = getHsSourceFiles p
+--       | otherwise                  = return [p]
+
+-- getHsSourceFiles = find dirs hs
+--   where hs   = extension ==? ".hs" ||? extension ==? ".lhs"
+--         dirs = liftM (not . ("dist" `isSuffixOf`)) directory
+
+---------------------------------------------------------------------------
+
+
+getFileInDirs :: FilePath -> [FilePath] -> IO (Maybe FilePath)
+getFileInDirs name = findFirst (testM doesFileExist . (</> name))
+
+testM :: (Monad m) => (a -> m Bool) -> a -> m [a]
+testM f x = do b <- f x
+               return [ x | b ]
+
+findFirst ::  Monad m => (t -> m [a]) -> [t] -> m (Maybe a)
+findFirst _ []     = return Nothing
+findFirst f (x:xs) = do r <- f x
+                        case r of
+                          y:_ -> return (Just y)
+                          []  -> findFirst f xs
+
+-- findFileInDirs ::  FilePath -> [FilePath] -> IO FilePath
+-- findFileInDirs file dirs
+--   = liftM (fromMaybe err) (findFirst (find always (fileName ==? file)) dirs)
+--     where err = errorstar $ "findFileInDirs: cannot find " ++ file ++ " in " ++ show dirs
+
+isBinary :: FilePath -> Bool
+isBinary = isExtFile BinFq
diff --git a/liquid-fixpoint/src/Language/Fixpoint/Utils/Statistics.hs b/liquid-fixpoint/src/Language/Fixpoint/Utils/Statistics.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/src/Language/Fixpoint/Utils/Statistics.hs
@@ -0,0 +1,75 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | This module implements functions that print out
+--   statistics about the constraints.
+module Language.Fixpoint.Utils.Statistics (statistics) where
+
+import           Control.DeepSeq
+import           GHC.Generics
+import           Control.Arrow ((&&&))
+
+import           Language.Fixpoint.Misc                (donePhase, Moods(..), applyNonNull)
+import           Language.Fixpoint.Types.Config
+import           Language.Fixpoint.Types.PrettyPrint
+import           Language.Fixpoint.Graph (partition')
+import qualified Language.Fixpoint.Types        as F
+import qualified Data.HashMap.Strict            as M
+import           Data.List (sort,group)
+import           Text.PrettyPrint.HughesPJ
+
+statistics :: Config -> F.FInfo a -> IO (F.Result (Integer, a))
+statistics _ fi = do
+  let fis = partition' Nothing fi
+  putStrLn $ render $ pprint $ partitionStats fis
+  donePhase Loud "Statistics"
+  return mempty
+
+partitionStats :: [F.FInfo a] -> Maybe Stats
+partitionStats fis = info
+  where
+    css            = [M.keys $ F.cm fi | fi <- fis]
+    sizes          = fromIntegral . length <$> css
+    info           = applyNonNull Nothing (Just . mkStats) sizes
+
+-------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------
+
+data Stats = Stats { cSizes  :: [Float]
+                   , cFreq   :: [(Float, Int)]
+                   , cTotal  :: !Float
+                   , cMean   :: !Float
+                   , cMax    :: !Float
+                   , cSpeed  :: !Float
+                   } deriving (Show, Generic)
+
+instance NFData Stats
+
+instance PPrint Stats where
+  pprintTidy _ s =
+    vcat [ "STAT: max/total =" <+> pprint (cMax   s) <+> "/" <+> pprint (cTotal s)
+         , "STAT: freqs     =" <+> pprint (cFreq  s)
+         , "STAT: average   =" <+> pprint (cMean  s)
+         , "STAT: speed     =" <+> pprint (cSpeed s)
+         ]
+
+mkStats :: [Float] -> Stats
+mkStats ns  = Stats {
+    cSizes  = ns
+  , cFreq   = frequency ns
+  , cTotal  = total
+  , cMean   = avg
+  , cMax    = maxx
+  , cSpeed  = total / maxx
+  }
+  where
+    maxx    = maximum ns
+    total   = sum  ns
+    avg     = mean ns
+
+frequency :: (Ord a) => [a] -> [(a, Int)]
+frequency = map (head &&& length) . group . sort
+
+mean :: [Float] -> Float
+mean ns  = sum ns / fromIntegral (length ns)
diff --git a/liquid-fixpoint/stack.yaml b/liquid-fixpoint/stack.yaml
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/stack.yaml
@@ -0,0 +1,12 @@
+flags:
+ liquid-fixpoint:
+  devel: True
+packages:
+- '.'
+extra-deps:
+- dotgen-0.4.2
+- fgl-visualize-0.1.0.1
+- intern-0.9.1.4
+- located-base-0.1.1.0
+
+resolver: nightly-2016-05-21
diff --git a/liquid-fixpoint/tests/crash/num00.fq b/liquid-fixpoint/tests/crash/num00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/crash/num00.fq
@@ -0,0 +1,29 @@
+// This qualifier saves the day; solve constraints WITHOUT IT
+
+qualif Zog(v:a) : (0 <= v)
+qualif Bog(v:a) : (0 <= 1)
+
+
+bind 0 zog : {v : int | true}
+
+constraint:
+  env [0]
+  lhs {v : alpha | (v = 10)}
+  rhs {v : alpha | $k0}
+  id 1 tag []
+
+constraint:
+  env [0]
+  lhs {v : alpha | $k0}
+  rhs {v : alpha | $k0}
+  id 2 tag []
+
+constraint:
+  env [0]
+  lhs {v : alpha | $k0}
+  rhs {v : alpha | 0 <= v}
+  id 3 tag []
+
+wf:
+  env [0]
+  reft {v: alpha | $k0}
diff --git a/liquid-fixpoint/tests/crash/sort00.fq b/liquid-fixpoint/tests/crash/sort00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/crash/sort00.fq
@@ -0,0 +1,12 @@
+// for LH Issue 773
+
+constant foo : (func(0, [int; int]))
+
+bind 0 x     : {v: Str | true}
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | (foo x = 0)}
+  rhs {v : int | (3 = 1 + 2) }
+  id 1 tag []
+
diff --git a/liquid-fixpoint/tests/crash/sort01.fq b/liquid-fixpoint/tests/crash/sort01.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/crash/sort01.fq
@@ -0,0 +1,13 @@
+// for LH Issue 774
+
+constant foo : (func(0, [int; int]))
+
+bind 0 x     : {v: Str | true}
+bind 1 y     : {v: Str | true}
+
+constraint:
+  env [ 0; 1 ]
+  lhs {v : int | (foo x = foo y)}
+  rhs {v : int | (3 = 1 + 2) }
+  id 1 tag []
+
diff --git a/liquid-fixpoint/tests/cut/test00-tx.fq b/liquid-fixpoint/tests/cut/test00-tx.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/cut/test00-tx.fq
@@ -0,0 +1,12 @@
+
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+bind 0 a : {v:int | (v = 10 || v = 20) }
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 
diff --git a/liquid-fixpoint/tests/cut/test00.fq b/liquid-fixpoint/tests/cut/test00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/cut/test00.fq
@@ -0,0 +1,28 @@
+
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+bind 0 a : {v: int | $k0}
+
+constraint:
+  env [ ]
+  lhs {v : int | (v = 10)}
+  rhs {v : int | $k0}
+  id 1 
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 20}
+  rhs {v : int | $k0}
+  id 2 
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/cut/test00a-tx.fq b/liquid-fixpoint/tests/cut/test00a-tx.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/cut/test00a-tx.fq
@@ -0,0 +1,43 @@
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+constraint:
+  env [z : {v : int | true}]
+  lhs {v : int | (z=10) \/ (z=20)}
+  rhs {v : int | 10 <= z}
+  id 3 
+
+/*
+
+Rewriting constraints as:
+
+    id 1
+    x:int, v:int |- x=10 /\ v=x => k0
+    
+    id 2
+    y:int, v:int |- y=20 /\ v=y => k0
+
+Projecting out all variables NOT in the WF of k0
+
+    id 1
+    v:int |- (exists x:int. x=10 /\ v=x) => k0
+           
+    id 2
+    v:int |- (exists y:int. y=20 /\ v=y) => k0
+
+Take the \/ of all constraints on k0
+
+     k0 = (exists x:int. x=10 /\ v=x) \/ (exists y:int. y=20 /\ v=y)
+     
+     k0[z/v]
+       = (\x. x=10 /\ v=x) \/ (\y. y=20 /\ v=y)[z/v]
+         = (\x. x=10 /\ z=x) \/ (\y. y=20 /\ z=y)
+
+So you get:
+
+     env [2]
+        lhs {v : int | (\x. x=10 /\ z=x) \/ (\y. y=20 /\ z=y)}
+     rhs {v : int | 10 <= z}
+     id 3 
+
+*/
diff --git a/liquid-fixpoint/tests/cut/test00a.fq b/liquid-fixpoint/tests/cut/test00a.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/cut/test00a.fq
@@ -0,0 +1,29 @@
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+bind 0 x : {v : int | true}
+bind 1 y : {v : int | true}
+bind 2 z : {v : int | true}
+
+constraint:
+  env [0]
+  lhs {v : int | (x = 10)}
+  rhs {v : int | $k0[v:=x]}
+  id 1 
+
+constraint:
+  env [1]
+  lhs {v : int | y = 20}
+  rhs {v : int | $k0[v:=y]}
+  id 2 
+
+constraint:
+  env [2]
+  lhs {v : int | $k0[v:=z]}
+  rhs {v : int | 10 <= z}
+  id 3 
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
+
diff --git a/liquid-fixpoint/tests/cut/test1-tx.fq b/liquid-fixpoint/tests/cut/test1-tx.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/cut/test1-tx.fq
@@ -0,0 +1,43 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+constraint:
+  env [a : {v : int | (exists x:int. x=10 /\ v=x) 
+                   \/ (exists y:int. y=20 /\ v=y) }]
+  lhs {v : int | v = a  }
+  rhs {v : int | 10 <= v}
+  id 3 
+
+/*
+
+Rewriting constraints as:
+
+    id 1
+    x:int, v:int |- (v=10)[x/v] /\ (v=x) => k0
+    x:int, v:int |- (x=10) /\ (v=x) => k0
+
+    id 2
+    y:int, v:int |- (v=20)[y/v] /\ (v=y) => k0
+    y:int, v:int |- (y=20) /\ (v=y) => k0
+
+Projecting out all variables NOT in the WF of k0
+
+    id 1
+    v:int |- (exists x:int. x=10 /\ v=x) => k0
+
+    id 2
+    v:int |- (exists y:int. y=20 /\ v=y) => k0
+
+Take the \/ of all constraints on k0
+
+    k0 = (exists x:int. x=10 /\ v=x) \/ (exists y:int. y=20 /\ v=y)
+     
+So you get:
+
+    env [a : {v : int | (exists x:int. x=10 /\ v=x) \/ (exists y:int. y=20 /\ v=y) }]
+      lhs {v : int | v = a  }
+    rhs {v : int | 10 <= v}
+    id 3
+
+*/
diff --git a/liquid-fixpoint/tests/cut/test1.fq b/liquid-fixpoint/tests/cut/test1.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/cut/test1.fq
@@ -0,0 +1,29 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+bind 0 x : {v : int | v = 10}
+bind 1 y : {v : int | v = 20}
+bind 2 a : {v : int | $k0    }
+      
+constraint:
+  env [0]
+  lhs {v : int | v = x}
+  rhs {v : int | $k0   }
+  id 1 
+
+constraint:
+  env [1]
+  lhs {v : int | v = y}
+  rhs {v : int | $k0   }
+  id 2 
+
+constraint:
+  env [2]
+  lhs {v : int | v = a  }
+  rhs {v : int | 10 <= v}
+  id 3 
+
+wf:
+  env [ ]
+  reft {v : int | $k0}
diff --git a/liquid-fixpoint/tests/cut/test2-tx.fq b/liquid-fixpoint/tests/cut/test2-tx.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/cut/test2-tx.fq
@@ -0,0 +1,112 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a): (10 <= v)
+
+// But you may use this one
+qualif Pog(v:a): (0 <= v)
+
+
+
+
+/* 
+
+-- Version 1 (eliminate k1) --
+
+Rewriting constraints as:
+
+    id 0
+    v:int |- (v=0) => k1
+
+    id 3
+    v:int |- k0 => k1
+
+Projecting out all variables NOT in the WF of k1
+
+    N/A
+
+Take the \/ of all constraints on k1
+
+    k1 = (v=0) \/ k0
+
+So you get:
+
+  bind 0 x: {v: int | v = 10      }
+  bind 1 a: {v: int | (v=0) \/ k0 }
+  bind 2 y: {v: int | v = 20      }
+  bind 3 b: {v: int | (v=0) \/ k0 }
+  bind 4 c: {v: int | k0          }
+
+  constraint:
+    env [ 0; 1]
+      lhs {v : int | v = x + a}
+    rhs {v : int | k0}
+    id 1 
+
+  constraint:
+    env [2; 3]
+      lhs {v : int | v = y + b}
+    rhs {v : int | k0}
+    id 2 
+
+  constraint:
+    env [4]
+      lhs {v : int | v = c  }
+    rhs {v : int | 10 <= v}
+    id 4 
+
+  wf:
+    env [ ]
+    reft {v: int | k1}
+
+
+
+
+-- Version 2 (eliminate k0) --
+
+Rewriting constraints as:
+
+    id 1
+    x:int, a:int, v:int |- (v=10)[x/v] /\ k1[a/v] /\ (v=x+a) => k0
+    x:int, a:int, v:int |- (x=10) /\ k1[a/v] /\ (v=x+a) => k0
+
+    id 2
+    y:int, b:int, v:int |- (v=20)[y/v] /\ k1[b/v] /\ (v=y+b) => k0
+    y:int, b:int, v:int |- (y=20) /\ k1[b/v] /\ (v=y+b) => k0
+
+Projecting out all variables NOT in the WF of k0
+
+    id 1
+    v:int |- (exists x:int a:int. (x=10) /\ k1[a/v] /\ (v=x+a)) => k0
+    
+    id 2
+    v:int |- (exists y:int b:int. (y=20) /\ k1[b/v] /\ (v=y+b)) => k0
+
+Take the \/ of all constraints on k0
+
+    k0 = (exists x:int a:int. (x=10) /\ k1[a/v] /\ (v=x+a))
+      \/ (exists y:int b:int. (y=20) /\ k1[b/v] /\ (v=y+b))
+
+So you get:
+
+  bind 4 c: {v: int | (exists x:int a:int. (x=10) /\ k1[a/v] /\ (v=x+a))
+                   \/ (exists y:int b:int. (y=20) /\ k1[b/v] /\ (v=y+b))    }
+
+  constraint:
+    env [ ]
+      lhs {v : int | v = 0}
+    rhs {v : int | k1 }
+    id 0 
+
+
+  constraint:
+    env [ ]
+      lhs {v : int | (exists x:int a:int. (x=10) /\ k1[a/v] /\ (v=x+a))
+                \/ (exists y:int b:int. (y=20) /\ k1[b/v] /\ (v=y+b))}
+    rhs {v : int | k1}
+    id 3
+
+  constraint:
+    env [4]
+      lhs {v : int | v = c  }
+    rhs {v : int | 10 <= v}
+    id 4 
diff --git a/liquid-fixpoint/tests/cut/test2.fq b/liquid-fixpoint/tests/cut/test2.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/cut/test2.fq
@@ -0,0 +1,51 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a): (10 <= v)
+
+// But you may use this one
+qualif Pog(v:a): (0 <= v)
+
+bind 0 x: {v: int | v = 10}
+bind 1 a: {v: int | $k1    }
+bind 2 y: {v: int | v = 20}
+bind 3 b: {v: int | $k1    }
+bind 4 c: {v: int | $k0    }
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 0}
+  rhs {v : int | $k1 }
+  id 0 
+
+
+constraint:
+  env [ 0; 1]
+  lhs {v : int | v = x + a}
+  rhs {v : int | $k0}
+  id 1 
+
+constraint:
+  env [2; 3]
+  lhs {v : int | v = y + b}
+  rhs {v : int | $k0}
+  id 2 
+
+constraint:
+  env [ ]
+  lhs {v : int | $k0}
+  rhs {v : int | $k1}
+  id 3
+
+constraint:
+  env [4]
+  lhs {v : int | v = c  }
+  rhs {v : int | 10 <= v}
+  id 4 
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
+
+wf:
+  env [ ]
+  reft {v: int | $k1}
diff --git a/liquid-fixpoint/tests/elim/div00.fq b/liquid-fixpoint/tests/elim/div00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/div00.fq
@@ -0,0 +1,23 @@
+
+// --eliminate should be able to solve this WITHOUT the qualifier
+// qualif Zog(v:int) : (v /= 0)
+
+bind 0 n : {v: int | true }
+bind 1 m : {v: int | true }
+bind 2 z : {v: int | $k0[n := m] }
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 12 }
+  rhs {v : int | $k0    }
+  id 1 tag []
+
+constraint:
+  env [ 1; 2 ]
+  lhs {v : int | v  = z}
+  rhs {v : int | v /= 0}
+  id 2 tag []
+
+wf:
+  env [ 0 ]
+  reft {v: int | $k0 }
diff --git a/liquid-fixpoint/tests/elim/elim00.fq b/liquid-fixpoint/tests/elim/elim00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/elim00.fq
@@ -0,0 +1,1494 @@
+fixpoint "--defunct"
+
+// qualif Cmp(v : @(0), x : @(0)): ((v > x)) // "tests/todo/elim00.hs.fq" (line 1, column 8)
+// qualif Cmp(v : @(0), x : @(0)): ((v = x)) // "tests/todo/elim00.hs.fq" (line 2, column 8)
+
+
+constant Control.Exception.Base.irrefutPatError##09 : (func(1, [int;
+                                                                @(0)]))
+constant GHC.Base..##r2C : (func(3, [func(0, [@(0); @(1)]);
+                                     func(0, [@(2); @(0)]);
+                                     @(2);
+                                     @(1)]))
+constant runFun : (func(2, [(Arrow  @(0)  @(1)); @(0); @(1)]))
+constant GHC.Tuple.$40$$44$$44$$41$$35$$35$76 : (func(3, [@(0);
+                                                          @(1);
+                                                          @(2);
+                                                          (Tuple  @(0)  @(1)  @(2))]))
+constant GHC.Real.D$58$Integral$35$$35$rWH : (func(1, [func(0, [@(0);
+                                                                @(0);
+                                                                @(0)]);
+                                                       func(0, [@(0); @(0); @(0)]);
+                                                       func(0, [@(0); @(0); @(0)]);
+                                                       func(0, [@(0); @(0); @(0)]);
+                                                       func(0, [@(0); @(0); (Tuple  @(0)  @(0))]);
+                                                       func(0, [@(0); @(0); (Tuple  @(0)  @(0))]);
+                                                       func(0, [@(0); int]);
+                                                       (GHC.Real.Integral  @(0))]))
+constant addrLen : (func(0, [int; int]))
+constant papp5 : (func(10, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4));
+                            @(5);
+                            @(6);
+                            @(7);
+                            @(8);
+                            @(9);
+                            bool]))
+constant xsListSelector : (func(1, [[@(0)]; [@(0)]]))
+constant x_Tuple21 : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant x_Tuple65 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(4)]))
+constant Elim.foo##rlD : (func(0, [Elim.Foo; Elim.Foo]))
+constant x_Tuple55 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(4)]))
+constant GHC.Integer.Type.smallInteger##0Z : (func(0, [int; int]))
+constant x_Tuple33 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(2)]))
+constant x_Tuple77 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(6)]))
+constant GHC.Base.Just##r1e : (func(1, [@(0);
+                                        (GHC.Base.Maybe  @(0))]))
+constant Elim.xx##rlB : (func(0, [Elim.Foo; int]))
+constant papp3 : (func(6, [(Pred  @(0)  @(1)  @(2));
+                           @(3);
+                           @(4);
+                           @(5);
+                           bool]))
+constant GHC.Prim.$43$$35$$35$$35$98 : (func(0, [int; int; int]))
+constant x_Tuple63 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(2)]))
+constant x_Tuple41 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(0)]))
+constant GHC.Types.LT##6S : (GHC.Types.Ordering)
+constant GHC.Prim.$60$$35$$35$$35$9q : (func(0, [int; int; int]))
+constant papp4 : (func(8, [(Pred  @(0)  @(1)  @(2)  @(3));
+                           @(4);
+                           @(5);
+                           @(6);
+                           @(7);
+                           bool]))
+constant Elim.PP##rlx : (func(2, [@(0);
+                                  @(1);
+                                  (Elim.Pair  @(0)  @(1))]))
+constant x_Tuple64 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(3)]))
+constant GHC.Types.GT##6W : (GHC.Types.Ordering)
+constant GHC.Prim.$45$$35$$35$$35$99 : (func(0, [int; int; int]))
+constant GHC.Types.$58$$35$$35$64 : (func(1, [@(0);
+                                              [@(0)];
+                                              [@(0)]]))
+constant autolen : (func(1, [@(0); int]))
+constant GHC.Types.I###6c : (func(0, [int; int]))
+constant x_Tuple52 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(1)]))
+constant xx : (func(0, [Elim.Foo; int]))
+constant null : (func(1, [[@(0)]; bool]))
+constant GHC.Num.$43$$35$$35$rt : (func(1, [@(0); @(0); @(0)]))
+constant GHC.Tuple.$40$$44$$44$$44$$44$$41$$35$$35$7a : (func(5, [@(0);
+                                                                  @(1);
+                                                                  @(2);
+                                                                  @(3);
+                                                                  @(4);
+                                                                  (Tuple  @(0)  @(1)  @(2)  @(3)  @(4))]))
+constant papp2 : (func(4, [(Pred  @(0)  @(1)); @(2); @(3); bool]))
+constant x_Tuple62 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(1)]))
+constant GHC.Tuple.$40$$44$$41$$35$$35$74 : (func(2, [@(0);
+                                                      @(1);
+                                                      (Tuple  @(0)  @(1))]))
+constant Elim.yy##rlC : (func(0, [Elim.Foo; int]))
+constant fromJust : (func(1, [(GHC.Base.Maybe  @(0)); @(0)]))
+constant papp7 : (func(14, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                            @(7);
+                            @(8);
+                            @(9);
+                            @(10);
+                            @(11);
+                            @(12);
+                            @(13);
+                            bool]))
+constant x_Tuple53 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(2)]))
+constant x_Tuple71 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(0)]))
+constant GHC.Prim.$62$$35$$35$$35$9m : (func(0, [int; int; int]))
+constant x_Tuple74 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(3)]))
+constant Elim.Emp##rly : (func(2, [(Elim.Pair  @(0)  @(1))]))
+constant len : (func(2, [(@(0)  @(1)); int]))
+constant GHC.Tuple.$40$$44$$44$$44$$44$$44$$44$$41$$35$$35$7e : (func(7, [@(0);
+                                                                          @(1);
+                                                                          @(2);
+                                                                          @(3);
+                                                                          @(4);
+                                                                          @(5);
+                                                                          @(6);
+                                                                          (Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6))]))
+constant papp6 : (func(12, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                            @(6);
+                            @(7);
+                            @(8);
+                            @(9);
+                            @(10);
+                            @(11);
+                            bool]))
+constant x_Tuple22 : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant Data.Foldable.length##r1s : (func(2, [(@(0)  @(0)); int]))
+constant x_Tuple66 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(5)]))
+constant x_Tuple44 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(3)]))
+constant xListSelector : (func(1, [[@(0)]; @(0)]))
+constant strLen : (func(0, [int; int]))
+constant x_Tuple72 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(1)]))
+constant GHC.Tuple.$40$$44$$44$$44$$41$$35$$35$78 : (func(4, [@(0);
+                                                              @(1);
+                                                              @(2);
+                                                              @(3);
+                                                              (Tuple  @(0)  @(1)  @(2)  @(3))]))
+constant isJust : (func(1, [(GHC.Base.Maybe  @(0)); bool]))
+constant GHC.Prim.$61$$61$$35$$35$$35$9o : (func(0, [int;
+                                                     int;
+                                                     int]))
+constant Elim.Foo##rlA : (func(0, [int; int; Elim.Foo]))
+constant Prop : (func(0, [GHC.Types.Bool; bool]))
+constant x_Tuple31 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(0)]))
+constant x_Tuple75 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(4)]))
+constant papp1 : (func(2, [(Pred  @(0)); @(1); bool]))
+constant yy : (func(0, [Elim.Foo; int]))
+constant x_Tuple61 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(0)]))
+constant GHC.Prim.$62$$61$$35$$35$$35$9n : (func(0, [int;
+                                                     int;
+                                                     int]))
+constant lit$36$tests$47$pos$47$elim00.hs$58$14$58$5$45$30$124$PP$32$wink$32$cow : (Str)
+constant x_Tuple43 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(2)]))
+constant GHC.Types.EQ##6U : (GHC.Types.Ordering)
+constant x_Tuple51 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(0)]))
+constant GHC.Base.Nothing##r1d : (func(1, [(GHC.Base.Maybe  @(0))]))
+constant GHC.Num.$45$$35$$35$02B : (func(1, [@(0); @(0); @(0)]))
+constant GHC.Num.$42$$35$$35$ru : (func(1, [@(0); @(0); @(0)]))
+constant x_Tuple73 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(2)]))
+constant GHC.Types.$91$$93$$35$$35$6m : (func(1, [[@(0)]]))
+constant x_Tuple54 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(3)]))
+constant cmp : (func(0, [GHC.Types.Ordering; GHC.Types.Ordering]))
+constant x_Tuple32 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(1)]))
+constant x_Tuple76 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(5)]))
+constant GHC.Prim.$60$$61$$35$$35$$35$9r : (func(0, [int;
+                                                     int;
+                                                     int]))
+constant GHC.Real.D$58$Fractional$35$$35$rVU : (func(1, [func(0, [@(0);
+                                                                  @(0);
+                                                                  @(0)]);
+                                                         func(0, [@(0); @(0)]);
+                                                         func(0, [(GHC.Real.Ratio  int); @(0)]);
+                                                         (GHC.Real.Fractional  @(0))]))
+constant fst : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant snd : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant GHC.Tuple.$40$$44$$44$$44$$44$$44$$41$$35$$35$7c : (func(6, [@(0);
+                                                                      @(1);
+                                                                      @(2);
+                                                                      @(3);
+                                                                      @(4);
+                                                                      @(5);
+                                                                      (Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5))]))
+constant x_Tuple42 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(1)]))
+constant GHC.Prim.void###0l : (GHC.Prim.Void#)
+
+
+bind 0 GHC.Prim.void###0l : {VV##180 : GHC.Prim.Void# | []}
+bind 1 Elim.Emp##rly : {VV : func(2, [(Elim.Pair  @(0)  @(1))]) | []}
+bind 2 GHC.Types.EQ##6U : {VV##185 : GHC.Types.Ordering | [(VV##185 = GHC.Types.EQ##6U)]}
+bind 3 GHC.Types.LT##6S : {VV##186 : GHC.Types.Ordering | [(VV##186 = GHC.Types.LT##6S)]}
+bind 4 GHC.Types.GT##6W : {VV##187 : GHC.Types.Ordering | [(VV##187 = GHC.Types.GT##6W)]}
+bind 5 Elim.Emp##rly : {VV : func(2, [(Elim.Pair  @(0)  @(1))]) | []}
+bind 6 GHC.Types.$91$$93$$35$$35$6m : {VV : func(1, [[@(0)]]) | []}
+bind 7 GHC.Types.GT##6W : {VV##213 : GHC.Types.Ordering | [((cmp VV##213) = GHC.Types.GT##6W)]}
+bind 8 GHC.Types.LT##6S : {VV##214 : GHC.Types.Ordering | [((cmp VV##214) = GHC.Types.LT##6S)]}
+bind 9 GHC.Types.EQ##6U : {VV##215 : GHC.Types.Ordering | [((cmp VV##215) = GHC.Types.EQ##6U)]}
+bind 10 GHC.Base.Nothing##r1d : {VV : func(1, [(GHC.Base.Maybe  @(0))]) | []}
+bind 11 ds_dxd : {VV##222 : Elim.Foo | []}
+bind 12 lq_anf$##dxr : {lq_tmp$x##223 : Elim.Foo | [(lq_tmp$x##223 = ds_dxd)]}
+bind 13 lq_anf$##dxr : {lq_tmp$x##225 : Elim.Foo | [(lq_tmp$x##225 = ds_dxd)]}
+bind 14 xig##awy : {lq_tmp$x##233 : int | []}
+bind 15 yog##awz : {lq_tmp$x##234 : int | [(xig##awy < lq_tmp$x##234)]}
+bind 16 lq_anf$##dxr : {lq_tmp$x##225 : Elim.Foo | [(lq_tmp$x##225 = ds_dxd);
+                                                    ((yy lq_tmp$x##225) = yog##awz);
+                                                    ((xx lq_tmp$x##225) = xig##awy);
+                                                    (lq_tmp$x##225 = (Elim.Foo##rlA xig##awy yog##awz));
+                                                    ((yy lq_tmp$x##225) = yog##awz);
+                                                    ((xx lq_tmp$x##225) = xig##awy)]}
+bind 17 lq_anf$##dxs : {lq_tmp$x##242 : (Elim.Pair  int  int) | [(lq_tmp$x##242 = (Elim.PP##rlx xig##awy yog##awz))]}
+bind 18 lq_anf$##dxt : {lq_tmp$x##273 : (Elim.Pair  int  int) | [(lq_tmp$x##273 = lq_anf$##dxs)]}
+bind 19 lq_anf$##dxt : {lq_tmp$x##277 : (Elim.Pair  int  int) | [(lq_tmp$x##277 = lq_anf$##dxs)]}
+bind 20 wink##ax3 : {lq_tmp$x##275 : int | [$k_##248[lq_tmp$x##277:=lq_anf$##dxt][VV##247:=lq_tmp$x##275][lq_tmp$x##242:=lq_anf$##dxt][lq_tmp$x##271:=lq_tmp$x##275][lq_tmp$x##273:=lq_anf$##dxt][lq_tmp$x##245:=xig##awy][lq_tmp$x##246:=yog##awz][lq_tmp$x##250:=lq_tmp$x##275]]}
+bind 21 cow##ax4 : {lq_tmp$x##276 : int | [$k_##252[lq_tmp$x##277:=lq_anf$##dxt][lq_tmp$x##281:=wink##ax3][VV##251:=lq_tmp$x##276][lq_tmp$x##242:=lq_anf$##dxt][lq_tmp$x##254:=lq_tmp$x##276][lq_tmp$x##273:=lq_anf$##dxt][lq_tmp$x##245:=xig##awy][lq_tmp$x##246:=yog##awz][lq_tmp$x##272:=lq_tmp$x##276]]}
+bind 22 lq_anf$##dxt : {lq_tmp$x##277 : (Elim.Pair  int  int) | [(lq_tmp$x##277 = lq_anf$##dxs);
+                                                                 (lq_tmp$x##277 = (Elim.PP##rlx wink##ax3 cow##ax4));
+                                                                 (lq_tmp$x##277 = (Elim.PP##rlx wink##ax3 cow##ax4));
+                                                                 (lq_tmp$x##277 = (Elim.PP##rlx wink##ax3 cow##ax4))]}
+bind 23 lq_tmp$x##307 : {VV##308 : int | []}
+bind 24 lq_anf$##dxt : {lq_tmp$x##313 : (Elim.Pair  int  int) | [(lq_tmp$x##313 = lq_anf$##dxs)]}
+bind 25 lq_anf$##dxt : {lq_tmp$x##313 : (Elim.Pair  int  int) | [(lq_tmp$x##313 = lq_anf$##dxs);
+                                                                 (lq_tmp$x##313 = Elim.Emp##rly);
+                                                                 (lq_tmp$x##313 = Elim.Emp##rly);
+                                                                 (lq_tmp$x##313 = Elim.Emp##rly)]}
+bind 26 ds_dxg : {VV##318 : GHC.Prim.Void# | [$k_##319]}
+bind 27 lq_anf$##dxu : {lq_tmp$x##335 : int | [(lq_tmp$x##335 ~~ lit$36$tests$47$pos$47$elim00.hs$58$14$58$5$45$30$124$PP$32$wink$32$cow);
+                                               ((strLen lq_tmp$x##335) = 39)]}
+bind 28 ds_dxh : {VV##268 : (Tuple  int  int) | [$k_##269]}
+bind 29 lq_anf$##dxw : {lq_tmp$x##368 : (Tuple  int  int) | [(lq_tmp$x##368 = ds_dxh)]}
+bind 30 lq_anf$##dxw : {lq_tmp$x##374 : (Tuple  int  int) | [(lq_tmp$x##374 = ds_dxh)]}
+bind 31 wink##ax3 : {lq_tmp$x##370 : int | [$k_##259[lq_tmp$x##368:=lq_anf$##dxw][VV##268:=lq_anf$##dxw][lq_tmp$x##364:=lq_tmp$x##370][VV##258:=lq_tmp$x##370][lq_tmp$x##374:=lq_anf$##dxw]]}
+bind 32 cow##Xxd : {lq_tmp$x##371 : int | [$k_##262[lq_tmp$x##368:=lq_anf$##dxw][VV##268:=lq_anf$##dxw][VV##261:=lq_tmp$x##371][lq_tmp$x##365:=lq_tmp$x##371][lq_tmp$x##379:=wink##ax3][lq_tmp$x##374:=lq_anf$##dxw];
+                                           $k_##266[lq_tmp$x##368:=lq_anf$##dxw][lq_tmp$x##373:=lq_tmp$x##371][VV##265:=lq_tmp$x##371][lq_tmp$x##264:=wink##ax3][lq_tmp$x##367:=lq_tmp$x##371][VV##268:=lq_anf$##dxw][lq_tmp$x##372:=wink##ax3][lq_tmp$x##366:=wink##ax3][lq_tmp$x##379:=wink##ax3][lq_tmp$x##374:=lq_anf$##dxw]]}
+bind 33 lq_anf$##dxw : {lq_tmp$x##374 : (Tuple  int  int) | [(lq_tmp$x##374 = ds_dxh);
+                                                             ((snd lq_tmp$x##374) = cow##Xxd);
+                                                             ((fst lq_tmp$x##374) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##374) = cow##Xxd);
+                                                             ((x_Tuple21 lq_tmp$x##374) = wink##ax3);
+                                                             (lq_tmp$x##374 = (GHC.Tuple.$40$$44$$41$$35$$35$74 wink##ax3 cow##Xxd));
+                                                             ((snd lq_tmp$x##374) = cow##Xxd);
+                                                             ((fst lq_tmp$x##374) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##374) = cow##Xxd);
+                                                             ((x_Tuple21 lq_tmp$x##374) = wink##ax3)]}
+bind 34 wink##ax3 : {VV##361 : int | [$k_##362]}
+// bind 45 wink##ax3 : {lq_tmp$x##452 : int | [$k_##428[lq_tmp$x##425:=wink##ax3][lq_tmp$x##456:=lq_anf$##dxy][VV##427:=lq_tmp$x##452][lq_tmp$x##426:=cow##ax4][lq_tmp$x##450:=lq_anf$##dxy][lq_tmp$x##430:=lq_tmp$x##452][lq_tmp$x##446:=lq_tmp$x##452][lq_tmp$x##422:=lq_anf$##dxy]]}
+
+bind 35 lq_anf$##dxv : {lq_tmp$x##398 : (Tuple  int  int) | [(lq_tmp$x##398 = ds_dxh)]}
+bind 36 lq_anf$##dxv : {lq_tmp$x##404 : (Tuple  int  int) | [(lq_tmp$x##404 = ds_dxh)]}
+bind 37 wink##ax3 : {lq_tmp$x##400 : int | [$k_##259[VV##268:=lq_anf$##dxv][lq_tmp$x##394:=lq_tmp$x##400][VV##258:=lq_tmp$x##400][lq_tmp$x##398:=lq_anf$##dxv][lq_tmp$x##404:=lq_anf$##dxv]]}
+bind 38 cow##ax4 : {lq_tmp$x##401 : int | [$k_##262[VV##268:=lq_anf$##dxv][VV##261:=lq_tmp$x##401][lq_tmp$x##409:=wink##ax3][lq_tmp$x##398:=lq_anf$##dxv][lq_tmp$x##395:=lq_tmp$x##401][lq_tmp$x##404:=lq_anf$##dxv];
+                                           $k_##266[lq_tmp$x##396:=wink##ax3][VV##265:=lq_tmp$x##401][lq_tmp$x##264:=wink##ax3][VV##268:=lq_anf$##dxv][lq_tmp$x##397:=lq_tmp$x##401][lq_tmp$x##409:=wink##ax3][lq_tmp$x##403:=lq_tmp$x##401][lq_tmp$x##398:=lq_anf$##dxv][lq_tmp$x##402:=wink##ax3][lq_tmp$x##404:=lq_anf$##dxv]]}
+bind 39 lq_anf$##dxv : {lq_tmp$x##404 : (Tuple  int  int) | [(lq_tmp$x##404 = ds_dxh);
+                                                             ((snd lq_tmp$x##404) = cow##ax4);
+                                                             ((fst lq_tmp$x##404) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##404) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##404) = wink##ax3);
+                                                             (lq_tmp$x##404 = (GHC.Tuple.$40$$44$$41$$35$$35$74 wink##ax3 cow##ax4));
+                                                             ((snd lq_tmp$x##404) = cow##ax4);
+                                                             ((fst lq_tmp$x##404) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##404) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##404) = wink##ax3)]}
+bind 40 cow##ax4 : {VV##391 : int | [$k_##392]}
+bind 41 lq_tmp$x##438 : {VV##439 : int | []}
+bind 42 ds_dxi : {lq_tmp$x##422 : (Tuple  int  int) | [((snd lq_tmp$x##422) = cow##ax4);
+                                                       ((fst lq_tmp$x##422) = wink##ax3);
+                                                       ((x_Tuple22 lq_tmp$x##422) = cow##ax4);
+                                                       ((x_Tuple21 lq_tmp$x##422) = wink##ax3)]}
+bind 43 lq_anf$##dxy : {lq_tmp$x##450 : (Tuple  int  int) | [(lq_tmp$x##450 = ds_dxi)]}
+bind 44 lq_anf$##dxy : {lq_tmp$x##456 : (Tuple  int  int) | [(lq_tmp$x##456 = ds_dxi)]}
+bind 45 wink##ax3 : {lq_tmp$x##452 : int | [$k_##428[lq_tmp$x##425:=wink##ax3][lq_tmp$x##456:=lq_anf$##dxy][VV##427:=lq_tmp$x##452][lq_tmp$x##426:=cow##ax4][lq_tmp$x##450:=lq_anf$##dxy][lq_tmp$x##430:=lq_tmp$x##452][lq_tmp$x##446:=lq_tmp$x##452][lq_tmp$x##422:=lq_anf$##dxy]]}
+bind 46 cow##ax4 : {lq_tmp$x##453 : int | [$k_##432[lq_tmp$x##425:=wink##ax3][lq_tmp$x##456:=lq_anf$##dxy][lq_tmp$x##426:=cow##ax4][VV##431:=lq_tmp$x##453][lq_tmp$x##450:=lq_anf$##dxy][lq_tmp$x##447:=lq_tmp$x##453][lq_tmp$x##461:=wink##ax3][lq_tmp$x##422:=lq_anf$##dxy][lq_tmp$x##434:=lq_tmp$x##453];
+                                           $k_##436[lq_tmp$x##425:=wink##ax3][lq_tmp$x##456:=lq_anf$##dxy][lq_tmp$x##426:=cow##ax4][lq_tmp$x##455:=lq_tmp$x##453][lq_tmp$x##450:=lq_anf$##dxy][lq_tmp$x##461:=wink##ax3][lq_tmp$x##438:=wink##ax3][lq_tmp$x##421:=wink##ax3][lq_tmp$x##422:=lq_anf$##dxy][lq_tmp$x##434:=lq_tmp$x##453][lq_tmp$x##448:=wink##ax3][lq_tmp$x##449:=lq_tmp$x##453][VV##435:=lq_tmp$x##453][lq_tmp$x##454:=wink##ax3]]}
+bind 47 lq_anf$##dxy : {lq_tmp$x##456 : (Tuple  int  int) | [(lq_tmp$x##456 = ds_dxi);
+                                                             ((snd lq_tmp$x##456) = cow##ax4);
+                                                             ((fst lq_tmp$x##456) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##456) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##456) = wink##ax3);
+                                                             (lq_tmp$x##456 = (GHC.Tuple.$40$$44$$41$$35$$35$74 wink##ax3 cow##ax4));
+                                                             ((snd lq_tmp$x##456) = cow##ax4);
+                                                             ((fst lq_tmp$x##456) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##456) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##456) = wink##ax3)]}
+bind 48 wink##awA : {VV##443 : int | [$k_##444]}
+
+bind 49 lq_anf$##dxx : {lq_tmp$x##480 : (Tuple  int  int) | [(lq_tmp$x##480 = ds_dxi)]}
+bind 50 lq_anf$##dxx : {lq_tmp$x##486 : (Tuple  int  int) | [(lq_tmp$x##486 = ds_dxi)]}
+bind 51 wink##ax3 : {lq_tmp$x##482 : int | [$k_##428[lq_tmp$x##425:=wink##ax3][VV##427:=lq_tmp$x##482][lq_tmp$x##426:=cow##ax4][lq_tmp$x##476:=lq_tmp$x##482][lq_tmp$x##430:=lq_tmp$x##482][lq_tmp$x##480:=lq_anf$##dxx][lq_tmp$x##422:=lq_anf$##dxx][lq_tmp$x##486:=lq_anf$##dxx]]}
+bind 52 cow##ax4 : {lq_tmp$x##483 : int | [$k_##432[lq_tmp$x##425:=wink##ax3][lq_tmp$x##426:=cow##ax4][VV##431:=lq_tmp$x##483][lq_tmp$x##491:=wink##ax3][lq_tmp$x##480:=lq_anf$##dxx][lq_tmp$x##477:=lq_tmp$x##483][lq_tmp$x##422:=lq_anf$##dxx][lq_tmp$x##434:=lq_tmp$x##483][lq_tmp$x##486:=lq_anf$##dxx];
+                                           $k_##436[lq_tmp$x##425:=wink##ax3][lq_tmp$x##426:=cow##ax4][lq_tmp$x##491:=wink##ax3][lq_tmp$x##480:=lq_anf$##dxx][lq_tmp$x##479:=lq_tmp$x##483][lq_tmp$x##485:=lq_tmp$x##483][lq_tmp$x##438:=wink##ax3][lq_tmp$x##421:=wink##ax3][lq_tmp$x##422:=lq_anf$##dxx][lq_tmp$x##434:=lq_tmp$x##483][lq_tmp$x##484:=wink##ax3][lq_tmp$x##478:=wink##ax3][lq_tmp$x##486:=lq_anf$##dxx][VV##435:=lq_tmp$x##483]]}
+bind 53 lq_anf$##dxx : {lq_tmp$x##486 : (Tuple  int  int) | [(lq_tmp$x##486 = ds_dxi);
+                                                             ((snd lq_tmp$x##486) = cow##ax4);
+                                                             ((fst lq_tmp$x##486) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##486) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##486) = wink##ax3);
+                                                             (lq_tmp$x##486 = (GHC.Tuple.$40$$44$$41$$35$$35$74 wink##ax3 cow##ax4));
+                                                             ((snd lq_tmp$x##486) = cow##ax4);
+                                                             ((fst lq_tmp$x##486) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##486) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##486) = wink##ax3)]}
+bind 54 cow##awB : {VV##473 : int | [$k_##474]}
+bind 55 ds_dxo : {VV##514 : Elim.Foo | []}
+bind 56 lq_anf$##dxz : {lq_tmp$x##515 : Elim.Foo | [(lq_tmp$x##515 = ds_dxo)]}
+bind 57 lq_anf$##dxz : {lq_tmp$x##517 : Elim.Foo | [(lq_tmp$x##517 = ds_dxo)]}
+bind 58 ds_dxp : {lq_tmp$x##525 : int | []}
+bind 59 ds_dxq : {lq_tmp$x##526 : int | [(ds_dxp < lq_tmp$x##526)]}
+bind 60 lq_anf$##dxz : {lq_tmp$x##517 : Elim.Foo | [(lq_tmp$x##517 = ds_dxo);
+                                                    ((yy lq_tmp$x##517) = ds_dxq);
+                                                    ((xx lq_tmp$x##517) = ds_dxp);
+                                                    (lq_tmp$x##517 = (Elim.Foo##rlA ds_dxp ds_dxq));
+                                                    ((yy lq_tmp$x##517) = ds_dxq);
+                                                    ((xx lq_tmp$x##517) = ds_dxp)]}
+bind 61 ds_dxl : {VV##537 : Elim.Foo | []}
+bind 62 lq_anf$##dxA : {lq_tmp$x##538 : Elim.Foo | [(lq_tmp$x##538 = ds_dxl)]}
+bind 63 lq_anf$##dxA : {lq_tmp$x##540 : Elim.Foo | [(lq_tmp$x##540 = ds_dxl)]}
+bind 64 ds_dxm : {lq_tmp$x##548 : int | []}
+bind 65 ds_dxn : {lq_tmp$x##549 : int | [(ds_dxm < lq_tmp$x##549)]}
+bind 66 lq_anf$##dxA : {lq_tmp$x##540 : Elim.Foo | [(lq_tmp$x##540 = ds_dxl);
+                                                    ((yy lq_tmp$x##540) = ds_dxn);
+                                                    ((xx lq_tmp$x##540) = ds_dxm);
+                                                    (lq_tmp$x##540 = (Elim.Foo##rlA ds_dxm ds_dxn));
+                                                    ((yy lq_tmp$x##540) = ds_dxn);
+                                                    ((xx lq_tmp$x##540) = ds_dxm)]}
+bind 67 VV##559 : {VV##559 : int | [(VV##559 = ds_dxm)]}
+bind 68 VV##561 : {VV##561 : int | [(VV##561 = ds_dxq)]}
+bind 69 VV##563 : {VV##563 : Elim.Foo | [((yy VV##563) = cow##awB);
+                                         ((xx VV##563) = wink##awA)]}
+bind 70 VV##565 : {VV##565 : int | [(VV##565 = cow##awB)]}
+bind 71 VV##567 : {VV##567 : int | [(VV##567 = wink##awA)]}
+bind 72 VV##569 : {VV##569 : int | [(VV##569 = cow##ax4)]}
+bind 73 VV##571 : {VV##571 : int | [(VV##571 = wink##ax3)]}
+bind 74 VV##573 : {VV##573 : int | [(VV##573 = cow##ax4)]}
+bind 75 VV##575 : {VV##575 : int | [(VV##575 = wink##ax3)]}
+bind 76 VV##577 : {VV##577 : int | [(VV##577 = cow##ax4)]}
+bind 77 VV##579 : {VV##579 : int | [(VV##579 = wink##ax3)]}
+bind 78 VV##581 : {VV##581 : (Tuple  int  int) | [$k_##333[VV##332:=VV##581][ds_dxg:=GHC.Prim.void###0l]]}
+bind 79 VV##583 : {VV##583 : int | [$k_##323[VV##322:=VV##583][VV##332:=VV##581][ds_dxg:=GHC.Prim.void###0l]]}
+bind 80 VV##585 : {VV##585 : int | [$k_##326[VV##325:=VV##585][VV##332:=VV##581][ds_dxg:=GHC.Prim.void###0l]]}
+bind 81 lq_tmp$x##264 : {VV##587 : int | []}
+bind 82 VV##588 : {VV##588 : int | [$k_##330[VV##332:=VV##581][VV##329:=VV##588][ds_dxg:=GHC.Prim.void###0l][lq_tmp$x##328:=lq_tmp$x##264]]}
+bind 83 VV##590 : {VV##590 : GHC.Prim.Void# | [(VV##590 = GHC.Prim.void###0l)]}
+bind 84 VV##592 : {VV##592 : (Tuple  int  int) | [$k_##351[lq_tmp$x##339:=lq_anf$##dxu][lq_tmp$x##357:=VV##592][VV##350:=VV##592]]}
+bind 85 VV##594 : {VV##594 : int | [$k_##341[lq_tmp$x##353:=VV##594][lq_tmp$x##339:=lq_anf$##dxu][lq_tmp$x##357:=VV##592][VV##340:=VV##594][VV##350:=VV##592]]}
+bind 86 VV##596 : {VV##596 : int | [$k_##344[lq_tmp$x##339:=lq_anf$##dxu][lq_tmp$x##357:=VV##592][VV##343:=VV##596][lq_tmp$x##354:=VV##596][VV##350:=VV##592]]}
+bind 87 lq_tmp$x##328 : {VV##598 : int | []}
+bind 88 VV##599 : {VV##599 : int | [$k_##348[lq_tmp$x##355:=lq_tmp$x##328][lq_tmp$x##356:=VV##599][VV##347:=VV##599][lq_tmp$x##339:=lq_anf$##dxu][lq_tmp$x##346:=lq_tmp$x##328][lq_tmp$x##357:=VV##592][VV##350:=VV##592]]}
+bind 89 VV##601 : {VV##601 : int | [(VV##601 = lq_anf$##dxu)]}
+bind 90 VV##603 : {VV##603 : (Tuple  int  int) | [((snd VV##603) = cow##ax4);
+                                                  ((fst VV##603) = wink##ax3);
+                                                  ((x_Tuple22 VV##603) = cow##ax4);
+                                                  ((x_Tuple21 VV##603) = wink##ax3)]}
+bind 91 VV##605 : {VV##605 : int | [$k_##297[lq_tmp$x##295:=cow##ax4][lq_tmp$x##299:=VV##605][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][VV##296:=VV##605]]}
+bind 92 VV##607 : {VV##607 : int | [$k_##301[lq_tmp$x##295:=cow##ax4][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][VV##300:=VV##607][lq_tmp$x##303:=VV##607]]}
+bind 93 lq_tmp$x##264 : {VV##609 : int | []}
+bind 94 VV##610 : {VV##610 : int | [$k_##305[lq_tmp$x##295:=cow##ax4][lq_tmp$x##290:=lq_tmp$x##264][VV##304:=VV##610][lq_tmp$x##307:=lq_tmp$x##264][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][lq_tmp$x##303:=VV##610]]}
+bind 95 VV##612 : {VV##612 : int | [(VV##612 = cow##ax4)]}
+bind 96 VV##614 : {VV##614 : int | [(VV##614 = wink##ax3)]}
+bind 97 VV##616 : {VV##616 : int | [(VV##616 = yog##awz)]}
+bind 98 VV##618 : {VV##618 : int | [(VV##618 = xig##awy)]}
+bind 99 VV##473 : {VV##473 : int | [$k_##474]}
+bind 100 VV##443 : {VV##443 : int | [$k_##444]}
+bind 101 VV##435 : {VV##435 : int | [$k_##436]}
+bind 102 VV##431 : {VV##431 : int | [$k_##432]}
+bind 103 VV##427 : {VV##427 : int | [$k_##428]}
+bind 104 VV##391 : {VV##391 : int | [$k_##392]}
+bind 105 VV##361 : {VV##361 : int | [$k_##362]}
+bind 106 VV##318 : {VV##318 : GHC.Prim.Void# | [$k_##319]}
+bind 107 VV##350 : {VV##350 : (Tuple  int  int) | [$k_##351]}
+bind 108 VV##340 : {VV##340 : int | [$k_##341]}
+bind 109 VV##343 : {VV##343 : int | [$k_##344]}
+bind 110 lq_tmp$x##346 : {VV##631 : int | []}
+bind 111 VV##347 : {VV##347 : int | [$k_##348]}
+bind 112 VV##332 : {VV##332 : (Tuple  int  int) | [$k_##333]}
+bind 113 VV##322 : {VV##322 : int | [$k_##323]}
+bind 114 VV##325 : {VV##325 : int | [$k_##326]}
+bind 115 lq_tmp$x##328 : {VV##636 : int | []}
+bind 116 VV##329 : {VV##329 : int | [$k_##330]}
+bind 117 VV##304 : {VV##304 : int | [$k_##305]}
+bind 118 VV##300 : {VV##300 : int | [$k_##301]}
+bind 119 VV##296 : {VV##296 : int | [$k_##297]}
+bind 120 VV##268 : {VV##268 : (Tuple  int  int) | [$k_##269]}
+bind 121 VV##258 : {VV##258 : int | [$k_##259]}
+bind 122 VV##261 : {VV##261 : int | [$k_##262]}
+bind 123 lq_tmp$x##264 : {VV##644 : int | []}
+bind 124 VV##265 : {VV##265 : int | [$k_##266]}
+bind 125 VV##251 : {VV##251 : int | [$k_##252]}
+bind 126 VV##247 : {VV##247 : int | [$k_##248]}
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42;
+       48;
+       54 ]
+  lhs {VV##1 : int | [(VV##1 = cow##awB)]}
+  rhs {VV##1 : int | [(wink##awA < VV##1)]}
+  id 1 tag [1]
+  // META constraint id 1 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42;
+       48;
+       49;
+       50;
+       51;
+       52;
+       53]
+  lhs {VV##2 : int | [(VV##2 = cow##ax4)]}
+  rhs {VV##2 : int | [$k_##474[VV##569:=VV##2][VV##F##2:=VV##2][VV##F:=VV##2][VV##473:=VV##2]]}
+  id 2 tag [1]
+  // META constraint id 2 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  lhs {VV##18 : (Tuple  int  int) | [((snd VV##18) = cow##ax4);
+                                     ((fst VV##18) = wink##ax3);
+                                     ((x_Tuple22 VV##18) = cow##ax4);
+                                     ((x_Tuple21 VV##18) = wink##ax3)]}
+  rhs {VV##18 : (Tuple  int  int) | [$k_##269[VV##F##18:=VV##18][VV##268:=VV##18][VV##603:=VV##18][VV##F:=VV##18]]}
+  id 18 tag [1]
+  // META constraint id 18 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42;
+       43;
+       44;
+       45;
+       46;
+       47]
+  lhs {VV##3 : int | [(VV##3 = wink##ax3)]}
+  rhs {VV##3 : int | [$k_##444[VV##571:=VV##3][VV##F:=VV##3][VV##F##3:=VV##3][VV##443:=VV##3]]}
+  id 3 tag [1]
+  // META constraint id 3 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22;
+       90]
+  lhs {VV##19 : int | [$k_##297[lq_tmp$x##295:=cow##ax4][VV##605:=VV##19][lq_tmp$x##299:=VV##19][lq_tmp$x##291:=VV##603][VV##F##19:=VV##19][lq_tmp$x##294:=wink##ax3][VV##F:=VV##19][VV##296:=VV##19]]}
+  rhs {VV##19 : int | [$k_##259[VV##605:=VV##19][VV##268:=VV##603][VV##258:=VV##19][VV##F##19:=VV##19][VV##F:=VV##19]]}
+  id 19 tag [1]
+  // META constraint id 19 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  lhs {VV##4 : int | [(VV##4 = cow##ax4)]}
+  rhs {VV##4 : int | [$k_##432[lq_tmp$x##425:=wink##ax3][VV##431:=VV##4][VV##573:=VV##4][lq_tmp$x##434:=VV##4][VV##F:=VV##4][VV##F##4:=VV##4]]}
+  id 4 tag [1]
+  // META constraint id 4 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22;
+       90]
+  lhs {VV##20 : int | [$k_##301[lq_tmp$x##295:=cow##ax4][VV##607:=VV##20][VV##F##20:=VV##20][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][VV##300:=VV##20][lq_tmp$x##303:=VV##20][VV##F:=VV##20]]}
+  rhs {VV##20 : int | [$k_##262[VV##268:=VV##603][VV##607:=VV##20][VV##F##20:=VV##20][VV##261:=VV##20][VV##F:=VV##20]]}
+  id 20 tag [1]
+  // META constraint id 20 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  lhs {VV##5 : int | [(VV##5 = cow##ax4)]}
+  rhs {VV##5 : int | [$k_##436[lq_tmp$x##425:=wink##ax3][VV##F##5:=VV##5][VV##573:=VV##5][lq_tmp$x##438:=wink##ax3][lq_tmp$x##434:=VV##5][VV##F:=VV##5][VV##435:=VV##5]]}
+  id 5 tag [1]
+  // META constraint id 5 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22;
+       90;
+       93]
+  lhs {VV##21 : int | [$k_##305[lq_tmp$x##295:=cow##ax4][lq_tmp$x##290:=lq_tmp$x##264][VV##304:=VV##21][VV##610:=VV##21][lq_tmp$x##307:=lq_tmp$x##264][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][lq_tmp$x##303:=VV##21][VV##F##21:=VV##21][VV##F:=VV##21]]}
+  rhs {VV##21 : int | [$k_##266[VV##265:=VV##21][VV##610:=VV##21][VV##268:=VV##603][VV##F##21:=VV##21][VV##F:=VV##21]]}
+  id 21 tag [1]
+  // META constraint id 21 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  lhs {VV##6 : int | [(VV##6 = wink##ax3)]}
+  rhs {VV##6 : int | [$k_##428[VV##F##6:=VV##6][VV##427:=VV##6][lq_tmp$x##430:=VV##6][VV##F:=VV##6][VV##575:=VV##6]]}
+  id 6 tag [1]
+  // META constraint id 6 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  lhs {VV##22 : int | [(VV##22 = cow##ax4)]}
+  rhs {VV##22 : int | [$k_##301[VV##F##22:=VV##22][VV##612:=VV##22][lq_tmp$x##294:=wink##ax3][VV##300:=VV##22][lq_tmp$x##303:=VV##22][VV##F:=VV##22]]}
+  id 22 tag [1]
+  // META constraint id 22 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       35;
+       36;
+       37;
+       38;
+       39]
+  lhs {VV##7 : int | [(VV##7 = cow##ax4)]}
+  rhs {VV##7 : int | [$k_##392[VV##391:=VV##7][VV##F##7:=VV##7][VV##F:=VV##7][VV##577:=VV##7]]}
+  id 7 tag [1]
+  // META constraint id 7 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  lhs {VV##23 : int | [(VV##23 = cow##ax4)]}
+  rhs {VV##23 : int | [$k_##305[VV##304:=VV##23][lq_tmp$x##307:=wink##ax3][VV##612:=VV##23][lq_tmp$x##294:=wink##ax3][lq_tmp$x##303:=VV##23][VV##F:=VV##23][VV##F##23:=VV##23]]}
+  id 23 tag [1]
+  // META constraint id 23 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       29;
+       30;
+       31;
+       32;
+       33]
+  lhs {VV##8 : int | [(VV##8 = wink##ax3)]}
+  rhs {VV##8 : int | [$k_##362[VV##579:=VV##8][VV##F##8:=VV##8][VV##361:=VV##8][VV##F:=VV##8]]}
+  id 8 tag [1]
+  // META constraint id 8 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  lhs {VV##24 : int | [(VV##24 = wink##ax3)]}
+  rhs {VV##24 : int | [$k_##297[lq_tmp$x##299:=VV##24][VV##614:=VV##24][VV##F:=VV##24][VV##296:=VV##24][VV##F##24:=VV##24]]}
+  id 24 tag [1]
+  // META constraint id 24 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16]
+  lhs {VV##25 : int | [(VV##25 = yog##awz)]}
+  rhs {VV##25 : int | [$k_##252[VV##251:=VV##25][lq_tmp$x##254:=VV##25][lq_tmp$x##245:=xig##awy][VV##F:=VV##25][VV##616:=VV##25][VV##F##25:=VV##25]]}
+  id 25 tag [1]
+  // META constraint id 25 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16]
+  lhs {VV##26 : int | [(VV##26 = xig##awy)]}
+  rhs {VV##26 : int | [$k_##248[VV##618:=VV##26][VV##247:=VV##26][VV##F##26:=VV##26][VV##F:=VV##26][lq_tmp$x##250:=VV##26]]}
+  id 26 tag [1]
+  // META constraint id 26 : ()
+
+
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       115]
+  reft {VV##329 : int | [$k_##330]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25]
+  reft {VV##318 : GHC.Prim.Void# | [$k_##319]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       27;
+       107]
+  reft {VV##343 : int | [$k_##344]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  reft {VV##427 : int | [$k_##428]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16]
+  reft {VV##247 : int | [$k_##248]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       41]
+  reft {VV##435 : int | [$k_##436]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42]
+  reft {VV##443 : int | [$k_##444]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  reft {VV##296 : int | [$k_##297]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       27;
+       110]
+  reft {VV##347 : int | [$k_##348]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42;
+       48]
+  reft {VV##473 : int | [$k_##474]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       27]
+  reft {VV##350 : (Tuple  int  int) | [$k_##351]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34]
+  reft {VV##391 : int | [$k_##392]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26]
+  reft {VV##332 : (Tuple  int  int) | [$k_##333]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       120]
+  reft {VV##258 : int | [$k_##259]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       120]
+  reft {VV##261 : int | [$k_##262]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       27;
+       107]
+  reft {VV##340 : int | [$k_##341]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22;
+       23]
+  reft {VV##304 : int | [$k_##305]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       112]
+  reft {VV##325 : int | [$k_##326]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28]
+  reft {VV##361 : int | [$k_##362]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       123]
+  reft {VV##265 : int | [$k_##266]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       112]
+  reft {VV##322 : int | [$k_##323]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  reft {VV##300 : int | [$k_##301]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17]
+  reft {VV##268 : (Tuple  int  int) | [$k_##269]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  reft {VV##431 : int | [$k_##432]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16]
+  reft {VV##251 : int | [$k_##252]}
+  // META wf : ()
diff --git a/liquid-fixpoint/tests/elim/kvparam00.fq b/liquid-fixpoint/tests/elim/kvparam00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/kvparam00.fq
@@ -0,0 +1,20 @@
+bind 0 x : {v : int | []}
+
+bind 1 y : {v : int | []}
+
+constraint:
+  env [0; 1]
+  lhs {VV#F1 : int | []}
+  rhs {VV#F1 : int | [$k_0[v:=x]]}
+  id 1 tag [3]
+
+constraint:
+  env [0; 1]
+  lhs {VV#F2 : int | [$k_0[v:=y]]}
+  rhs {VV#F2 : int | [y = x]}
+  id 2 tag [4]
+
+wf:
+  env []
+  reft {v : int | [$k_0]}
+
diff --git a/liquid-fixpoint/tests/elim/len00.fq b/liquid-fixpoint/tests/elim/len00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/len00.fq
@@ -0,0 +1,23 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+//qualif ListZ(v : [@(0)]): (len v >= 0)
+
+constant len : (func(2, [(@(0)  @(1)); int]))
+
+bind 0 y : {v : [(Tuple int a)] | [len v >= 0]}
+
+constraint:
+  env [0]
+  lhs {v : [(Tuple int a)] | [v = y] }
+  rhs {v : [(Tuple int a)] | [$k0]   }
+  id 1 tag []
+
+constraint:
+  env []
+  lhs {v : [(Tuple int a)] | [$k0]             }
+  rhs {v : [(Tuple int a)] | [len v >= 0] }
+  id 2 tag []
+
+wf:
+  env [ ]
+  reft {v : [(Tuple int a)] | [$k0] }
diff --git a/liquid-fixpoint/tests/elim/test00-tx.fq b/liquid-fixpoint/tests/elim/test00-tx.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/test00-tx.fq
@@ -0,0 +1,12 @@
+
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+bind 0 a : {v:int | (v = 10 || v = 20) }
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 tag []
diff --git a/liquid-fixpoint/tests/elim/test00.fq b/liquid-fixpoint/tests/elim/test00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/test00.fq
@@ -0,0 +1,26 @@
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+bind 0 a : {v: int | $k0}
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 10}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 20}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/elim/test00a.fq b/liquid-fixpoint/tests/elim/test00a.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/test00a.fq
@@ -0,0 +1,28 @@
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+bind 0 x : {v : int | true}
+bind 1 y : {v : int | true}
+bind 2 z : {v : int | true}
+
+constraint:
+  env [0]
+  lhs {v : int | (x = 10)}
+  rhs {v : int | $k0[v:=x]}
+  id 1 tag []
+
+constraint:
+  env [1]
+  lhs {v : int | y = 20}
+  rhs {v : int | $k0[v:=y]}
+  id 2 tag []
+
+constraint:
+  env [2]
+  lhs {v : int | $k0[v:=z]}
+  rhs {v : int | 10 <= z}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/elim/test1.fq b/liquid-fixpoint/tests/elim/test1.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/test1.fq
@@ -0,0 +1,29 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a) : (10 <= v)
+
+bind 0 x : {v : int | v = 10}
+bind 1 y : {v : int | v = 20}
+bind 2 a : {v : int | $k0    }
+      
+constraint:
+  env [0]
+  lhs {v : int | v = x}
+  rhs {v : int | $k0   }
+  id 1 tag []
+
+constraint:
+  env [1]
+  lhs {v : int | v = y}
+  rhs {v : int | $k0   }
+  id 2 tag []
+
+constraint:
+  env [2]
+  lhs {v : int | v = a  }
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v : int | $k0}
diff --git a/liquid-fixpoint/tests/elim/test2.fq b/liquid-fixpoint/tests/elim/test2.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/test2.fq
@@ -0,0 +1,53 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+// qualif Zog(v:a): (10 <= v)
+
+// But you may use this one
+qualif Pog(v:a): (0 <= v)
+
+bind 0 x: {v: int | v = 10}
+bind 1 a: {v: int | $k1    }
+bind 2 y: {v: int | v = 20}
+bind 3 b: {v: int | $k1    }
+bind 4 c: {v: int | $k0    }
+
+cut $k1
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 0}
+  rhs {v : int | $k1 }
+  id 0 tag []
+
+
+constraint:
+  env [0; 1]
+  lhs {v : int | v = x + a}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [2; 3]
+  lhs {v : int | v = y + b}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | $k0}
+  rhs {v : int | $k1}
+  id 3 tag []
+
+constraint:
+  env [4]
+  lhs {v : int | v = c  }
+  rhs {v : int | 10 <= v}
+  id 4 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
+
+wf:
+  env [ ]
+  reft {v: int | $k1}
diff --git a/liquid-fixpoint/tests/elim/tuple00.fq b/liquid-fixpoint/tests/elim/tuple00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/tuple00.fq
@@ -0,0 +1,114 @@
+
+bind 0 cat   : {v: int | v = 100 }
+bind 1 dog   : {v: int | v = 200 }
+bind 2 frog  : {v: int | v = 400 }
+bind 3 mouse : {v: int | v = 500 }
+bind 4 hippo : {v: int | v = 600 }
+bind 5 goose : {v: int | v = 700 }
+bind 6 crow  : {v: int | v = 800 }
+bind 7 pig   : {v: int | v = 900 }
+
+bind 20 x_1_1 : {v: int | $k_1_1 }
+bind 21 x_1_2 : {v: int | $k_1_2 }
+bind 22 x_2_1 : {v: int | $k_2_1 }
+bind 23 x_2_2 : {v: int | $k_2_2 }
+bind 24 x_3_1 : {v: int | $k_3_1 }
+bind 25 x_3_2 : {v: int | $k_3_2 }
+
+pack $k_1_1 : 1
+pack $k_1_2 : 1
+pack $k_2_1 : 2
+pack $k_2_2 : 2
+pack $k_3_1 : 3
+pack $k_3_2 : 3
+pack $k_4_1 : 4
+pack $k_4_2 : 4
+
+
+
+constraint:
+  env [ 0; 1; 2; 3; 4; 5; 6; 7 ]
+  lhs {v : int | v = 1}
+  rhs {v : int | $k_1_1}
+  id 1 tag []
+
+constraint:
+  env [ 0; 1; 2; 3; 4; 5; 6; 7 ]
+  lhs {v : int | v = 2}
+  rhs {v : int | $k_1_2}
+  id 2 tag []
+
+constraint:
+  env [ 20; 21 ]
+  lhs {v : int | v = x_1_1 }
+  rhs {v : int | $k_2_1    }
+  id 3 tag []
+
+constraint:
+  env [ 20; 21 ]
+  lhs {v : int | v = x_1_2 }
+  rhs {v : int | $k_2_2    }
+  id 4 tag []
+
+constraint:
+  env [ 22; 23 ]
+  lhs {v : int | v = x_2_1 }
+  rhs {v : int | $k_3_1    }
+  id 5 tag []
+
+constraint:
+  env [ 22; 23 ]
+  lhs {v : int | v = x_2_2 }
+  rhs {v : int | $k_3_2    }
+  id 6 tag []
+
+constraint:
+  env [ 24; 25 ]
+  lhs {v : int | v = x_3_1 }
+  rhs {v : int | $k_4_1    }
+  id 7 tag []
+
+constraint:
+  env [ 24; 25 ]
+  lhs {v : int | v = x_3_2 }
+  rhs {v : int | $k_4_2    }
+  id 8 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | $k_4_1 }
+  rhs {v : int | v = 1  }
+  id 9 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k_1_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_1_2}
+
+wf:
+  env [ ]
+  reft {v: int | $k_2_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_2_2}
+
+wf:
+  env [ ]
+  reft {v: int | $k_3_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_3_2}
+
+
+wf:
+  env [ ]
+  reft {v: int | $k_4_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_4_2}
diff --git a/liquid-fixpoint/tests/elim/tuple01.fq b/liquid-fixpoint/tests/elim/tuple01.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/elim/tuple01.fq
@@ -0,0 +1,137 @@
+// This test illustrates how you can get an exponential VC from nested tuples
+
+bind 0 cat   : {v: int | v = 100 }
+bind 1 dog   : {v: int | v = 200 }
+bind 2 frog  : {v: int | v = 400 }
+bind 3 mouse : {v: int | v = 500 }
+bind 4 hippo : {v: int | v = 600 }
+bind 5 goose : {v: int | v = 700 }
+bind 6 crow  : {v: int | v = 800 }
+bind 7 pig   : {v: int | v = 900 }
+
+bind 20 x_1_1 : {v: int | $k_1_1 }
+bind 21 x_1_2 : {v: int | $k_1_2 }
+bind 22 x_2_1 : {v: int | $k_2_1 }
+bind 23 x_2_2 : {v: int | $k_2_2 }
+bind 24 x_3_1 : {v: int | $k_3_1 }
+bind 25 x_3_2 : {v: int | $k_3_2 }
+bind 26 x_4_1 : {v: int | $k_4_1 }
+bind 27 x_4_2 : {v: int | $k_4_2 }
+
+// pack $k_1_1 : 1
+// pack $k_1_2 : 1
+// pack $k_2_1 : 2
+// pack $k_2_2 : 2
+// pack $k_3_1 : 3
+// pack $k_3_2 : 3
+// pack $k_4_1 : 4
+// pack $k_4_2 : 4
+// pack $k_5_1 : 5
+// pack $k_5_2 : 5
+
+constraint:
+  env [ 0; 1; 2; 3; 4; 5; 6; 7 ]
+  lhs {v : int | v = 1}
+  rhs {v : int | $k_1_1}
+  id 1 tag []
+
+constraint:
+  env [ 0; 1; 2; 3; 4; 5; 6; 7 ]
+  lhs {v : int | v = 2}
+  rhs {v : int | $k_1_2}
+  id 2 tag []
+
+constraint:
+  env [ 20; 21 ]
+  lhs {v : int | v = x_1_1 }
+  rhs {v : int | $k_2_1    }
+  id 3 tag []
+
+constraint:
+  env [ 20; 21 ]
+  lhs {v : int | v = x_1_2 }
+  rhs {v : int | $k_2_2    }
+  id 4 tag []
+
+constraint:
+  env [ 22; 23 ]
+  lhs {v : int | v = x_2_1 }
+  rhs {v : int | $k_3_1    }
+  id 5 tag []
+
+constraint:
+  env [ 22; 23 ]
+  lhs {v : int | v = x_2_2 }
+  rhs {v : int | $k_3_2    }
+  id 6 tag []
+
+constraint:
+  env [ 24; 25 ]
+  lhs {v : int | v = x_3_1 }
+  rhs {v : int | $k_4_1    }
+  id 7 tag []
+
+constraint:
+  env [ 24; 25 ]
+  lhs {v : int | v = x_3_2 }
+  rhs {v : int | $k_4_2    }
+  id 8 tag []
+
+constraint:
+  env [ 26; 27 ]
+  lhs {v : int | v = x_4_1 }
+  rhs {v : int | $k_5_1    }
+  id 9 tag []
+
+constraint:
+  env [ 26; 27 ]
+  lhs {v : int | v = x_4_2 }
+  rhs {v : int | $k_5_2    }
+  id 10 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | $k_5_1 }
+  rhs {v : int | v = 1  }
+  id 11 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k_1_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_1_2}
+
+wf:
+  env [ ]
+  reft {v: int | $k_2_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_2_2}
+
+wf:
+  env [ ]
+  reft {v: int | $k_3_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_3_2}
+
+
+wf:
+  env [ ]
+  reft {v: int | $k_4_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_4_2}
+
+wf:
+  env [ ]
+  reft {v: int | $k_5_1}
+
+wf:
+  env [ ]
+  reft {v: int | $k_5_2}
diff --git a/liquid-fixpoint/tests/minimize/two-cores.fq b/liquid-fixpoint/tests/minimize/two-cores.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/minimize/two-cores.fq
@@ -0,0 +1,30 @@
+qualif Cmp(v:a): (v = 10)
+qualif Cmp(v:a): (v = 12)
+
+constraint:
+  env []
+  lhs {v : int | [v = 10]}
+  rhs {v : int | [$k_0]}
+  id 1 tag [3]
+
+constraint:
+  env []
+  lhs {v : int | [$k_0]}
+  rhs {v : int | [v != 10]}
+  id 4 tag [4]
+
+constraint:
+  env []
+  lhs {v : int | [v = 12]}
+  rhs {v : int | [$k_0]}
+  id 2 tag [5]
+
+constraint:
+  env []
+  lhs {v : int | [$k_0]}
+  rhs {v : int | [v != 12]}
+  id 3 tag [6]
+
+wf:
+  env []
+  reft {v : int | [$k_0]}
diff --git a/liquid-fixpoint/tests/neg/NonLinear.fq b/liquid-fixpoint/tests/neg/NonLinear.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/NonLinear.fq
@@ -0,0 +1,28 @@
+
+bind 1 pig      : {v: int | []}
+bind 2 pigOut   : {v: int | [v = pig + 1]}
+
+bind 3 argAlice : {v: int | v = 10}
+bind 4 alice    : {v: int | [$k0[vk01 := argAlice][vk02 := v]] }
+
+bind 5 argBob   : {v: int | v = 20}
+bind 6 bob      : {v: int | [$k0[vk01 := argBob][vk02 := v]] }
+
+bind 10 vk01   : {v: int | []}
+
+constraint:
+  env [1; 2] 
+  lhs {v1 : int | [v1 = pigOut]} 
+  rhs {v1 : int | [$k0[vk01 := pig][vk02 := v1]]}
+  id 1 tag [2]
+
+constraint:
+  env [3; 4; 5; 6] 
+  lhs {v2 : int | []} 
+  rhs {v2 : int | [false]}
+  id 2 tag [2]
+
+wf:
+  env [10]
+  reft {vk02: int | [$k0]}
+
diff --git a/liquid-fixpoint/tests/neg/NonLinear.hs.fq b/liquid-fixpoint/tests/neg/NonLinear.hs.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/NonLinear.hs.fq
@@ -0,0 +1,91 @@
+
+bind 0 GHC.Num.$fNumInt##rlL : {VV##27 : (GHC.Num.Num  int) | []}
+bind 1 GHC.Types.EQ##6U : {VV##28 : GHC.Types.Ordering | [(VV##28 = GHC.Types.EQ##6U)]}
+bind 2 GHC.Types.LT##6S : {VV##29 : GHC.Types.Ordering | [(VV##29 = GHC.Types.LT##6S)]}
+bind 3 GHC.Types.GT##6W : {VV##30 : GHC.Types.Ordering | [(VV##30 = GHC.Types.GT##6W)]}
+bind 4 pig##amI : {VV##33 : int | []}
+bind 5 lq_anf$##dvQ : {lq_tmp$x##41 : int | [(lq_tmp$x##41 = (1  :  int))]}
+bind 6 zink##alG : {zink##0 : int | [(zink##0 = 5)]}
+bind 7 zonk##alH : {zonk##1 : int | [(zonk##1 = 67)]}
+bind 8 bob##alJ : {lq_tmp$x##65 : int | [$k_##38[VV##37:=lq_tmp$x##65][lq_tmp$x##67:=zonk##alH][pig##amI:=zonk##alH]]}
+bind 9 alice##alI : {lq_tmp$x##71 : int | [$k_##38[VV##37:=lq_tmp$x##71][pig##amI:=zink##alG][lq_tmp$x##73:=zink##alG]]}
+bind 10 VV##96 : {VV##96 : int | []}
+bind 11 zink##alG : {zink##0 : int | []}
+bind 12 VV##99 : {VV##99 : int | []}
+bind 13 lq_tmp$x##92 : {zonk##1 : int | []}
+bind 14 VV##102 : {VV##102 : int | []}
+bind 15 VV##104 : {VV##104 : int | []}
+bind 16 zonk##alH : {zonk##1 : int | []}
+bind 17 VV##107 : {VV##107 : int | []}
+bind 18 VV##109 : {VV##109 : int | [(VV##109 = (alice##alI + bob##alJ))]}
+bind 19 VV##111 : {VV##111 : int | [$k_##38[VV##37:=VV##111][lq_tmp$x##88:=VV##111][lq_tmp$x##67:=zonk##alH][lq_tmp$x##65:=VV##111][pig##amI:=zonk##alH];
+                                    (VV##111 = bob##alJ)]}
+bind 20 VV##113 : {VV##113 : int | [$k_##38[VV##37:=VV##113][lq_tmp$x##87:=VV##113][lq_tmp$x##71:=VV##113][pig##amI:=zink##alG][lq_tmp$x##73:=zink##alG];
+                                    (VV##113 = alice##alI)]}
+bind 21 VV##115 : {VV##115 : int | [(VV##115 = 5);
+                                    (VV##115 = zink##alG)]}
+bind 22 VV##117 : {VV##117 : int | [(VV##117 = 67);
+                                    (VV##117 = zonk##alH)]}
+bind 23 VV##119 : {VV##119 : int | [(VV##119 = (pig##amI + lq_anf$##dvQ))]}
+bind 24 VV##121 : {VV##121 : int | [(VV##121 = (1  :  int));
+                                    (VV##121 = lq_anf$##dvQ)]}
+bind 25 VV##123 : {VV##123 : int | [$k_##34[lq_tmp$x##57:=VV##123][VV##33:=VV##123];
+                                    (VV##123 = pig##amI)]}
+bind 26 VV##125 : {VV##125 : int | [(VV##125 = 1)]}
+bind 27 VV##33 : {VV##33 : int | [$k_##34]}
+bind 28 VV##37 : {VV##37 : int | [$k_##38]}
+
+
+
+
+constraint:
+  env [0; 1; 2; 3; 6; 7; 8; 9]
+  lhs {VV##F##1 : int | [(VV##F##1 = (alice##alI + bob##alJ))]}
+  rhs {VV##F##1 : int | [(VV##F##1 = 0)]}
+  id 1 tag [2]
+  // META constraint id 1 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 6; 7]
+  lhs {VV##F##2 : int | [(VV##F##2 = 5); (VV##F##2 = zink##alG)]}
+  rhs {VV##F##2 : int | [$k_##34[VV##115:=VV##F##2][lq_tmp$x##70:=VV##F##2][VV##F:=VV##F##2][VV##33:=VV##F##2]]}
+  id 2 tag [2]
+  // META constraint id 2 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 6; 7]
+  lhs {VV##F##3 : int | [(VV##F##3 = 67); (VV##F##3 = zonk##alH)]}
+  rhs {VV##F##3 : int | [$k_##34[lq_tmp$x##64:=VV##F##3][VV##117:=VV##F##3][VV##F:=VV##F##3][VV##33:=VV##F##3]]}
+  id 3 tag [2]
+  // META constraint id 3 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5]
+  lhs {VV##F##4 : int | [(VV##F##4 = (pig##amI + lq_anf$##dvQ))]}
+  rhs {VV##F##4 : int | [$k_##38[VV##37:=VV##F##4][VV##119:=VV##F##4][VV##F:=VV##F##4]]}
+  id 4 tag [1]
+  // META constraint id 4 : ()
+
+
+
+
+wf:
+  env [0; 1; 2; 3; 4]
+  reft {VV##37 : int | [$k_##38]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3]
+  reft {VV##33 : int | [$k_##34]}
+  // META wf : ()
+
+
+
+
+
+
+
diff --git a/liquid-fixpoint/tests/neg/conj-rhs.fq b/liquid-fixpoint/tests/neg/conj-rhs.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/conj-rhs.fq
@@ -0,0 +1,6 @@
+constraint:
+  env []
+  lhs {v:int | true }
+  rhs {v:int | (0 = 1) && (1 = 0) }
+  id 1
+  tag [1]
diff --git a/liquid-fixpoint/tests/neg/elim-dep-00.fq b/liquid-fixpoint/tests/neg/elim-dep-00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/elim-dep-00.fq
@@ -0,0 +1,43 @@
+
+qualif False(v:int) : (0 = 1)
+qualif Zero(v:int) : (0 = v)
+qualif One(v:int) : (1 = v)
+
+bind 1 x : {v:int | $k2 }
+
+// cut $k1 -- eliminating $k1 causes UNSOUNDNESS
+
+cut $k2
+
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 0 }
+  rhs {v : int | $k1   }
+  id 1 tag []
+
+constraint:
+  env [ 1 ]
+  lhs {v : int | v = x + 1 }
+  rhs {v : int | $k1       }
+  id 2 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | $k1}
+  rhs {v : int | $k2}
+  id 3 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | $k2  }
+  rhs {v : int | 0 = v}
+  id 4 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k1}
+
+wf:
+  env [ ]
+  reft {v: int | $k2}
diff --git a/liquid-fixpoint/tests/neg/float-literal.fq b/liquid-fixpoint/tests/neg/float-literal.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/float-literal.fq
@@ -0,0 +1,6 @@
+
+constraint:
+  env []
+  lhs {VV#F2 : a_aZU | []}
+  rhs {VV#F2 : a_aZU | [(VV#F2 >= 1.0)]}
+  id 2 tag [2]
diff --git a/liquid-fixpoint/tests/neg/float.fq b/liquid-fixpoint/tests/neg/float.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/float.fq
@@ -0,0 +1,11 @@
+// adapted from LH test Propability.hs
+
+bind 50 x : {v1 : real | [(v1 = 0.2)]}
+bind 56 y : {v2 : real | [(v2 = 0.9 + x)]}
+
+constraint:
+  env [50;
+       56]
+  lhs {VV#F3 : real | []}
+  rhs {VV#F3 : real | [(y = 1.0)]}
+  id 3 tag [1]
diff --git a/liquid-fixpoint/tests/neg/literals.fq b/liquid-fixpoint/tests/neg/literals.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/literals.fq
@@ -0,0 +1,10 @@
+//adapted from LH test Strings.hs
+
+constant lit#bar : (Str)
+constant lit#foo : (Str)
+
+constraint:
+  env []
+  lhs {VV#F1 : int | []}
+  rhs {VV#F1 : int | [(lit#bar = lit#foo)]}
+  id 1 tag [6]
diff --git a/liquid-fixpoint/tests/neg/pack00.fq b/liquid-fixpoint/tests/neg/pack00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/pack00.fq
@@ -0,0 +1,37 @@
+
+bind 1 pig      : {v: int | []}
+
+bind 3 argAlice : {v: int | v = 10}
+bind 4 alice    : {v: int | [$k0[vk01 := argAlice][vk02 := v]] }
+
+bind 5 argBob   : {v: int | v = 20}
+bind 6 bob      : {v: int | [$k1[vk11 := argBob][vk12 := v]] }
+
+bind 10 vk01   : {v: int | []}
+bind 11 vk11   : {v: int | []}
+
+constraint:
+  env [1]
+  lhs {v1 : int | [v1 = pig + 1]}
+  rhs {v1 : int | [$k0[vk01 := pig][vk02 := v1]]}
+  id 1 tag [2]
+
+constraint:
+  env [1]
+  lhs {v2 : int | [v2 = pig + 1]}
+  rhs {v2 : int | [$k1[vk11 := pig][vk12 := v2]]}
+  id 2 tag [2]
+
+constraint:
+  env [3; 4; 5; 6]
+  lhs {v3 : int | [v3 = alice + bob]}
+  rhs {v3 : int | [v3 = 0]}
+  id 3 tag [2]
+
+wf:
+  env [10]
+  reft {vk02: int | [$k0]}
+
+wf:
+  env [11]
+  reft {vk12: int | [$k1]}
diff --git a/liquid-fixpoint/tests/neg/pack01.fq b/liquid-fixpoint/tests/neg/pack01.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/pack01.fq
@@ -0,0 +1,45 @@
+
+
+bind 1 pig      : {v: int | []}
+
+bind 3 argAlice : {v: int | v = 10}
+bind 4 alice    : {v: int | [$k0[vk01 := argAlice][vk02 := v]] }
+
+bind 5 argBob   : {v: int | v = 20}
+bind 6 bob      : {v: int | [$k1[vk11 := argBob][vk12 := v]] }
+
+bind 10 vk01   : {v: int | []}
+bind 11 vk11   : {v: int | []}
+
+// This is a version of the UNSAFE pack00.fq + the pack annotations,
+// which shouldn't magically make it safe.
+
+pack $k0 : 1
+pack $k1 : 1
+
+
+constraint:
+  env [1]
+  lhs {v1 : int | [v1 = pig + 1]}
+  rhs {v1 : int | [$k0[vk01 := pig][vk02 := v1]]}
+  id 1 tag [2]
+
+constraint:
+  env [1]
+  lhs {v2 : int | [v2 = pig + 1]}
+  rhs {v2 : int | [$k1[vk11 := pig][vk12 := v2]]}
+  id 2 tag [2]
+
+constraint:
+  env [3; 4; 5; 6]
+  lhs {v3 : int | [v3 = alice + bob]}
+  rhs {v3 : int | [v3 = 0]}
+  id 3 tag [2]
+
+wf:
+  env [10]
+  reft {vk02: int | [$k0]}
+
+wf:
+  env [11]
+  reft {vk12: int | [$k1]}
diff --git a/liquid-fixpoint/tests/neg/poly0.fq b/liquid-fixpoint/tests/neg/poly0.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/poly0.fq
@@ -0,0 +1,15 @@
+fixpoint "--defunct"
+
+// This definition works fine ...
+// constant offset : (func(0, [int ; int ; (BitVec Size32) ]))
+
+// But this crashes as 'offset 0' is embedded as int not bv...
+constant offset : (func(1, [int; int; @(0)]))
+
+bind 0 x  : {VV : (BitVec  Size32) | [ VV = offset 0 0 ]}
+
+constraint:
+  env [0]
+  lhs {VV : (BitVec Size32) | [ VV = x ] }
+  rhs {VV : (BitVec Size32) | [ VV != x ] }
+  id 1 tag [1]
diff --git a/liquid-fixpoint/tests/neg/poly1.fq b/liquid-fixpoint/tests/neg/poly1.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/poly1.fq
@@ -0,0 +1,17 @@
+fixpoint "--defunct"
+
+// This definition works fine ...
+// constant offset : (func(2, [int ; (BitVec Size32) ]))
+
+// But this crashes as 'offset 0' is embedded as int not bv...
+constant offset : (func(2, [int; @(0)]))
+
+bind 0 x  : {VV : (BitVec  Size32) | [ VV = offset 0 ]}
+
+constraint: 
+  env [0]
+  lhs {VV : (BitVec Size32) | [ VV = x ] }
+  rhs {VV : (BitVec Size32) | [ VV != x ] }
+  id 1 tag [1]
+
+
diff --git a/liquid-fixpoint/tests/neg/poly2.fq b/liquid-fixpoint/tests/neg/poly2.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/poly2.fq
@@ -0,0 +1,15 @@
+fixpoint "--defunct"
+
+// This definition works fine ...
+// constant offset : (func(0, [int ; int ; (BitVec Size32) ]))
+
+// But this crashes as 'offset 0' is embedded as int not bv...
+constant offset : (func(2, [@(0); int; int; @(0); @(1)]))
+
+bind 0 x  : {VV : (BitVec  Size32) | [ VV = offset 0 0 0 0 ]}
+
+constraint:
+  env [0]
+  lhs {VV : (BitVec Size32) | [ VV = x ] }
+  rhs {VV : (BitVec Size32) | [ VV != x ] }
+  id 1 tag [1]
diff --git a/liquid-fixpoint/tests/neg/test00.fq b/liquid-fixpoint/tests/neg/test00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/test00.fq
@@ -0,0 +1,28 @@
+
+qualif Zog(v:a) : (10 <= v)
+qualif Bog(v:a, x:a) : (x <= v)
+
+bind 0 a : {v: int | $k0}
+
+constraint:
+  env [ ]
+  lhs {v : int | (v = 9)}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 20}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ 0
+      ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/neg/test00.hs.fq b/liquid-fixpoint/tests/neg/test00.hs.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/test00.hs.fq
@@ -0,0 +1,286 @@
+qualif Fst(v : @(1), y : @(0)): (v = fst([y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 29, column 8)
+qualif Snd(v : @(1), y : @(0)): (v = snd([y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 30, column 8)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) > 0)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 13, column 8)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) = 0)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 14, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) = 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 16, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) >= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 17, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) > 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 18, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) = len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 20, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) >= len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 21, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) > len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 22, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) <= len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 23, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) < len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 24, column 8)
+qualif EqLen(v : int, xs : [@(0)]): (v = len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 26, column 8)
+qualif LenEq(v : [@(0)], x : int): (x = len([v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 27, column 8)
+qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x + 1)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 28, column 8)
+qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x - 1)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 29, column 8)
+qualif LenAcc(v : int, xs : [@(0)], n : int): (v = (len([xs]) + n)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 30, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 3, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 4, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 5, column 8)
+qualif Bot(v : bool): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 6, column 8)
+qualif Bot(v : int): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 7, column 8)
+qualif CmpZ(v : @(0)): (v < 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 9, column 8)
+qualif CmpZ(v : @(0)): (v <= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 10, column 8)
+qualif CmpZ(v : @(0)): (v > 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 11, column 8)
+qualif CmpZ(v : @(0)): (v >= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 12, column 8)
+qualif CmpZ(v : @(0)): (v = 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 13, column 8)
+qualif CmpZ(v : @(0)): (v != 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 14, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v < x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 16, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v <= x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 17, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v > x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 18, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v >= x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 19, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v = x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 20, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v != x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 21, column 8)
+qualif One(v : int): (v = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 28, column 8)
+qualif True(v : bool): (? v) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 29, column 8)
+qualif False(v : bool): (~ ((? v))) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 30, column 8)
+qualif True1(v : GHC.Types.Bool): (? Prop([v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 31, column 8)
+qualif False1(v : GHC.Types.Bool): (~ ((? Prop([v])))) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 32, column 8)
+qualif Papp(v : @(0), p : (Pred  @(0))): (? papp1([p;
+                                                   v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 35, column 8)
+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): (? papp2([p;
+                                                                    v;
+                                                                    x])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 38, column 8)
+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): (? papp3([p;
+                                                                                    v;
+                                                                                    x;
+                                                                                    y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 41, column 8)
+
+
+
+
+constant runFun : (func(2, [(Arrow  @(0)  @(1)); @(0); @(1)]))
+constant addrLen : (func(0, [int; int]))
+constant xsListSelector : (func(1, [[@(0)]; [@(0)]]))
+constant x_Tuple21 : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant x_Tuple65 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(4)]))
+constant GHC.Types.False$35$68 : (GHC.Types.Bool)
+constant x_Tuple55 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(4)]))
+constant x_Tuple33 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(2)]))
+constant x_Tuple77 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(6)]))
+constant papp3 : (func(6, [(Pred  @(0)  @(1)  @(2));
+                           @(3);
+                           @(4);
+                           @(5);
+                           bool]))
+constant x_Tuple63 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(2)]))
+constant x_Tuple41 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(0)]))
+constant papp4 : (func(8, [(Pred  @(0)  @(1)  @(2)  @(6));
+                           @(3);
+                           @(4);
+                           @(5);
+                           @(7);
+                           bool]))
+constant x_Tuple64 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(3)]))
+constant autolen : (func(1, [@(0); int]))
+constant x_Tuple52 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(1)]))
+constant null : (func(1, [[@(0)]; bool]))
+constant papp2 : (func(4, [(Pred  @(0)  @(1)); @(2); @(3); bool]))
+constant x_Tuple62 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(1)]))
+constant fromJust : (func(1, [(GHC.Base.Maybe  @(0)); @(0)]))
+constant x_Tuple53 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(2)]))
+constant x_Tuple71 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(0)]))
+constant x_Tuple74 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(3)]))
+constant len : (func(2, [(@(0)  @(1)); int]))
+constant x_Tuple22 : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant x_Tuple66 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(5)]))
+constant x_Tuple44 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(3)]))
+constant xListSelector : (func(1, [[@(0)]; @(0)]))
+constant strLen : (func(0, [int; int]))
+constant x_Tuple72 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(1)]))
+constant isJust : (func(1, [(GHC.Base.Maybe  @(0)); bool]))
+constant Prop : (func(0, [GHC.Types.Bool; bool]))
+constant x_Tuple31 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(0)]))
+constant x_Tuple75 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(4)]))
+constant papp1 : (func(1, [(Pred  @(0)); @(0); bool]))
+constant x_Tuple61 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(0)]))
+constant x_Tuple43 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(2)]))
+constant x_Tuple51 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(0)]))
+constant GHC.Types.I$35$$35$6c : (func(0, [int; int]))
+constant x_Tuple73 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(2)]))
+constant x_Tuple54 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(3)]))
+constant x_Tuple32 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(1)]))
+constant cmp : (func(0, [GHC.Types.Ordering; GHC.Types.Ordering]))
+constant x_Tuple76 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(5)]))
+constant fst : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant snd : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant x_Tuple42 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(1)]))
+constant GHC.Types.True$35$6u : (GHC.Types.Bool)
+
+
+bind 0 GHC.Types.False$35$68 : {VV$35$159 : GHC.Types.Bool | []}
+bind 1 GHC.Types.True$35$6u : {VV$35$161 : GHC.Types.Bool | []}
+bind 2 GHC.Classes.$36$fOrdInt$35$rni : {VV$35$166 : (GHC.Classes.Ord  int) | []}
+bind 3 GHC.Types.EQ$35$6U : {VV$35$167 : GHC.Types.Ordering | [(VV$35$167 = GHC.Types.EQ$35$6U)]}
+bind 4 GHC.Types.LT$35$6S : {VV$35$168 : GHC.Types.Ordering | [(VV$35$168 = GHC.Types.LT$35$6S)]}
+bind 5 GHC.Types.GT$35$6W : {VV$35$169 : GHC.Types.Ordering | [(VV$35$169 = GHC.Types.GT$35$6W)]}
+bind 6 GHC.Types.True$35$6u : {v$35$4 : GHC.Types.Bool | [(? Prop([v$35$4]))]}
+bind 7 GHC.Types.False$35$68 : {v$35$5 : GHC.Types.Bool | [(~ ((? Prop([v$35$5]))))]}
+bind 8 GHC.Types.False$35$68 : {v$35$5 : GHC.Types.Bool | [(~ ((? Prop([v$35$5]))))]}
+bind 9 GHC.Types.$91$$93$$35$6m : {VV : func(1, [[@(0)]]) | []}
+bind 10 GHC.Types.True$35$6u : {v$35$4 : GHC.Types.Bool | [(? Prop([v$35$4]))]}
+bind 11 GHC.Types.GT$35$6W : {VV$35$214 : GHC.Types.Ordering | [(cmp([VV$35$214]) = GHC.Types.GT$35$6W)]}
+bind 12 GHC.Types.LT$35$6S : {VV$35$215 : GHC.Types.Ordering | [(cmp([VV$35$215]) = GHC.Types.LT$35$6S)]}
+bind 13 GHC.Types.EQ$35$6U : {VV$35$216 : GHC.Types.Ordering | [(cmp([VV$35$216]) = GHC.Types.EQ$35$6U)]}
+bind 14 GHC.Base.Nothing$35$r1d : {VV : func(1, [(GHC.Base.Maybe  @(0))]) | []}
+bind 15 z$35$a10N : {VV$35$221 : int | [$k_$35$222]}
+bind 16 lq_anf$36$_d116 : {lq_tmp$36$x$35$229 : int | [(lq_tmp$36$x$35$229 = (100  :  int))]}
+bind 17 lq_anf$36$_d117 : {lq_tmp$36$x$35$236 : GHC.Types.Bool | [((? Prop([lq_tmp$36$x$35$236])) <=> (z$35$a10N >= lq_anf$36$_d116))]}
+bind 18 lq_anf$36$_d118 : {lq_tmp$36$x$35$254 : int | [(lq_tmp$36$x$35$254 = (0  :  int))]}
+bind 19 Test0.x$35$rYP : {VV$35$250 : int | [$k_$35$251]}
+bind 20 lq_anf$36$_d119 : {lq_tmp$36$x$35$269 : int | [(lq_tmp$36$x$35$269 = (0  :  int))]}
+bind 21 lq_anf$36$_d11a : {lq_tmp$36$x$35$275 : GHC.Types.Bool | [((? Prop([lq_tmp$36$x$35$275])) <=> (Test0.x$35$rYP > lq_anf$36$_d119))]}
+bind 22 lq_anf$36$_d11b : {lq_tmp$36$x$35$291 : GHC.Types.Bool | [(lq_tmp$36$x$35$291 = lq_anf$36$_d11a)]}
+bind 23 lq_anf$36$_d11b : {lq_tmp$36$x$35$293 : GHC.Types.Bool | [(lq_tmp$36$x$35$293 = lq_anf$36$_d11a)]}
+bind 24 lq_anf$36$_d11b : {lq_tmp$36$x$35$293 : GHC.Types.Bool | [(lq_tmp$36$x$35$293 = lq_anf$36$_d11a);
+                                                                  (~ ((? Prop([lq_tmp$36$x$35$293]))));
+                                                                  (~ ((? Prop([lq_tmp$36$x$35$293]))));
+                                                                  (~ ((? Prop([lq_tmp$36$x$35$293]))))]}
+bind 25 lq_anf$36$_d11b : {lq_tmp$36$x$35$299 : GHC.Types.Bool | [(lq_tmp$36$x$35$299 = lq_anf$36$_d11a)]}
+bind 26 lq_anf$36$_d11b : {lq_tmp$36$x$35$299 : GHC.Types.Bool | [(lq_tmp$36$x$35$299 = lq_anf$36$_d11a);
+                                                                  (? Prop([lq_tmp$36$x$35$299]));
+                                                                  (? Prop([lq_tmp$36$x$35$299]));
+                                                                  (? Prop([lq_tmp$36$x$35$299]))]}
+bind 27 Test0.prop_abs$35$r10h : {VV$35$265 : GHC.Types.Bool | [$k_$35$266]}
+bind 28 VV$35$310 : {VV$35$310 : GHC.Types.Bool | [$k_$35$226[lq_tmp$36$x$35$307:=Test0.x$35$rYP][lq_tmp$36$x$35$305:=VV$35$310][VV$35$225:=VV$35$310][z$35$a10N:=Test0.x$35$rYP]]}
+bind 29 VV$35$310 : {VV$35$310 : GHC.Types.Bool | [$k_$35$226[lq_tmp$36$x$35$307:=Test0.x$35$rYP][lq_tmp$36$x$35$305:=VV$35$310][VV$35$225:=VV$35$310][z$35$a10N:=Test0.x$35$rYP]]}
+bind 30 VV$35$313 : {VV$35$313 : int | [(VV$35$313 = Test0.x$35$rYP)]}
+bind 31 VV$35$313 : {VV$35$313 : int | [(VV$35$313 = Test0.x$35$rYP)]}
+bind 32 VV$35$316 : {VV$35$316 : GHC.Types.Bool | [(VV$35$316 = GHC.Types.False$35$68)]}
+bind 33 VV$35$316 : {VV$35$316 : GHC.Types.Bool | [(VV$35$316 = GHC.Types.False$35$68)]}
+bind 34 VV$35$319 : {VV$35$319 : int | [(VV$35$319 = lq_anf$36$_d119)]}
+bind 35 VV$35$319 : {VV$35$319 : int | [(VV$35$319 = lq_anf$36$_d119)]}
+bind 36 VV$35$322 : {VV$35$322 : int | [(VV$35$322 = Test0.x$35$rYP)]}
+bind 37 VV$35$322 : {VV$35$322 : int | [(VV$35$322 = Test0.x$35$rYP)]}
+bind 38 VV$35$325 : {VV$35$325 : int | [(VV$35$325 = 0)]}
+bind 39 VV$35$325 : {VV$35$325 : int | [(VV$35$325 = 0)]}
+bind 40 VV$35$328 : {VV$35$328 : int | []}
+bind 41 VV$35$328 : {VV$35$328 : int | []}
+bind 42 VV$35$331 : {VV$35$331 : int | [(VV$35$331 = lq_anf$36$_d118)]}
+bind 43 VV$35$331 : {VV$35$331 : int | [(VV$35$331 = lq_anf$36$_d118)]}
+bind 44 VV$35$334 : {VV$35$334 : int | [(VV$35$334 = 0)]}
+bind 45 VV$35$334 : {VV$35$334 : int | [(VV$35$334 = 0)]}
+bind 46 VV$35$337 : {VV$35$337 : GHC.Types.Bool | [(? Prop([VV$35$337]))]}
+bind 47 VV$35$337 : {VV$35$337 : GHC.Types.Bool | [(? Prop([VV$35$337]))]}
+bind 48 VV$35$340 : {VV$35$340 : GHC.Types.Bool | [(VV$35$340 = lq_anf$36$_d117)]}
+bind 49 VV$35$340 : {VV$35$340 : GHC.Types.Bool | [(VV$35$340 = lq_anf$36$_d117)]}
+bind 50 VV$35$343 : {VV$35$343 : int | [(VV$35$343 = lq_anf$36$_d116)]}
+bind 51 VV$35$343 : {VV$35$343 : int | [(VV$35$343 = lq_anf$36$_d116)]}
+bind 52 VV$35$346 : {VV$35$346 : int | [(VV$35$346 = z$35$a10N)]}
+bind 53 VV$35$346 : {VV$35$346 : int | [(VV$35$346 = z$35$a10N)]}
+bind 54 VV$35$349 : {VV$35$349 : int | [(VV$35$349 = 100)]}
+bind 55 VV$35$349 : {VV$35$349 : int | [(VV$35$349 = 100)]}
+bind 56 VV$35$282 : {VV$35$282 : int | [$k_$35$283]}
+bind 57 VV$35$265 : {VV$35$265 : GHC.Types.Bool | [$k_$35$266]}
+bind 58 VV$35$250 : {VV$35$250 : int | [$k_$35$251]}
+bind 59 VV$35$221 : {VV$35$221 : int | [$k_$35$222]}
+bind 60 VV$35$225 : {VV$35$225 : GHC.Types.Bool | [$k_$35$226]}
+
+
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       19;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       8;
+       9;
+       25;
+       10;
+       26;
+       11;
+       12;
+       13;
+       14;
+       30]
+  lhs {VV$35$F2 : int | [(VV$35$F2 = Test0.x$35$rYP)]}
+  rhs {VV$35$F2 : int | [$k_$35$222[VV$35$221:=VV$35$F2][lq_tmp$36$x$35$304:=VV$35$F2][VV$35$313:=VV$35$F2][VV$35$F:=VV$35$F2]]}
+  id 2 tag [3]
+  // META constraint id 2 : tests/neg/test00.hs:8:30
+
+
+constraint:
+  env [0; 1; 2; 18; 3; 4; 5; 6; 7; 8; 40; 9; 10; 11; 12; 13; 14]
+  lhs {VV$35$F6 : int | []}
+  rhs {VV$35$F6 : int | [$k_$35$251[VV$35$328:=VV$35$F6][VV$35$250:=VV$35$F6][VV$35$F:=VV$35$F6]]}
+  id 6 tag [2]
+  // META constraint id 6 : tests/neg/test00.hs:6:1-12
+
+
+constraint:
+  env [0;
+       16;
+       48;
+       1;
+       17;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15]
+  lhs {VV$35$F8 : GHC.Types.Bool | [(VV$35$F8 = lq_anf$36$_d117)]}
+  rhs {VV$35$F8 : GHC.Types.Bool | [(? Prop([VV$35$F8]))]}
+  id 8 tag [1]
+  // META constraint id 8 : tests/neg/test00.hs:11:23-35
+
+
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14]
+  reft {VV$35$221 : int | [$k_$35$222]}
+  // META wf : <no location info>
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14]
+  reft {VV$35$250 : int | [$k_$35$251]}
+  // META wf : <no location info>
+
+
+
+
+
+
+
diff --git a/liquid-fixpoint/tests/neg/test00a.fq b/liquid-fixpoint/tests/neg/test00a.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/test00a.fq
@@ -0,0 +1,29 @@
+// This qualifier saves the day; solve constraints WITHOUT IT
+
+qualif Zog(v:a) : (10 <= v)
+
+bind 0 x : {v : int | true}
+bind 1 y : {v : int | true}
+bind 2 z : {v : int | true}
+
+constraint:
+  env [0]
+  lhs {v : int | (x = 9)}
+  rhs {v : int | $k0[v:=x]}
+  id 1 tag []
+
+constraint:
+  env [1]
+  lhs {v : int | y = 20}
+  rhs {v : int | $k0[v:=y]}
+  id 2 tag []
+
+constraint:
+  env [2]
+  lhs {v : int | $k0[v:=z]}
+  rhs {v : int | 10 <= z}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/neg/test1.fq b/liquid-fixpoint/tests/neg/test1.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/test1.fq
@@ -0,0 +1,29 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+qualif Zog(v:a) : (10 <= v)
+
+bind 0 x : {v : int | v = 9}
+bind 1 y : {v : int | v = 20}
+bind 2 a : {v : int | $k0    }
+      
+constraint:
+  env [0]
+  lhs {v : int | v = x}
+  rhs {v : int | $k0   }
+  id 1 tag []
+
+constraint:
+  env [1]
+  lhs {v : int | v = y}
+  rhs {v : int | $k0   }
+  id 2 tag []
+
+constraint:
+  env [2]
+  lhs {v : int | v = a  }
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v : int | $k0}
diff --git a/liquid-fixpoint/tests/neg/test2.fq b/liquid-fixpoint/tests/neg/test2.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/test2.fq
@@ -0,0 +1,51 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+qualif Zog(v:a): (10 <= v)
+
+// But you may use this one
+qualif Pog(v:a): (0 <= v)
+
+bind 0 x: {v: int | v = 9 }
+bind 1 a: {v: int | $k1    }
+bind 2 y: {v: int | v = 20}
+bind 3 b: {v: int | $k1    }
+bind 4 c: {v: int | $k0    }
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 0}
+  rhs {v : int | $k1 }
+  id 0 tag []
+
+
+constraint:
+  env [ 0; 1]
+  lhs {v : int | v = x + a}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [2; 3]
+  lhs {v : int | v = y + b}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | $k0}
+  rhs {v : int | $k1}
+  id 3 tag []
+
+constraint:
+  env [4]
+  lhs {v : int | v = c  }
+  rhs {v : int | 10 <= v}
+  id 4 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
+
+wf:
+  env [ ]
+  reft {v: int | $k1}
diff --git a/liquid-fixpoint/tests/neg/test3.fq b/liquid-fixpoint/tests/neg/test3.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/neg/test3.fq
@@ -0,0 +1,22 @@
+
+qualif Zog(v:a, z:b) : (v = z)
+
+bind 0 x : {v : int | true}
+bind 1 q : {v : int | true}
+bind 2 y : {v : int | v = 42}
+
+constraint:
+  env [1]
+  lhs {v : int | v = q}
+  rhs {v : int | $k0[x:=q] }
+  id 1 tag []
+
+constraint:
+  env [2]
+  lhs {v : int | $k0[x:=y]}
+  rhs {v : int | v = 10}
+  id 2 tag []
+
+wf:
+  env [0]
+  reft {v : int | $k0}
diff --git a/liquid-fixpoint/tests/pos/LogicCurry1.hs.fq b/liquid-fixpoint/tests/pos/LogicCurry1.hs.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/LogicCurry1.hs.fq
@@ -0,0 +1,245 @@
+fixpoint "--allowho"
+
+qualif Fst(v : @(1), y : @(0)): ((v = (fst y))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.spec" (line 28, column 8)
+qualif Snd(v : @(1), y : @(0)): ((v = (snd y))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.spec" (line 29, column 8)
+qualif Auto(v##1 : int, n : int, x : int): ((v##1 = (ack n x))) // "/Users/rjhala/research/stack/liquidhaskell/tests/pos/LogicCurry1.hs" (line 10, column 1)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((v <=> ((len xs) > 0))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 13, column 8)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((v <=> ((len xs) = 0))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 14, column 8)
+qualif ListZ(v : [@(0)]): (((len v) = 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 16, column 8)
+qualif ListZ(v : [@(0)]): (((len v) >= 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 17, column 8)
+qualif ListZ(v : [@(0)]): (((len v) > 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 18, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) = (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 20, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) >= (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 21, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) > (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 22, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) <= (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 23, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) < (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 24, column 8)
+qualif EqLen(v : int, xs : [@(0)]): ((v = (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 26, column 8)
+qualif LenEq(v : [@(0)], x : int): ((x = (len v))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 27, column 8)
+qualif LenDiff(v : [@(0)], x : int): (((len v) = (x + 1))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 28, column 8)
+qualif LenDiff(v : [@(0)], x : int): (((len v) = (x - 1))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 29, column 8)
+qualif LenAcc(v : int, xs : [@(0)], n : int): ((v = ((len xs) + n))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 30, column 8)
+qualif Bot(v : @(0)): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 3, column 8)
+qualif Bot(v : @(0)): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 4, column 8)
+qualif Bot(v : @(0)): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 5, column 8)
+qualif Bot(v : bool): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 6, column 8)
+qualif Bot(v : int): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 7, column 8)
+qualif CmpZ(v : @(0)): ((v < 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 9, column 8)
+qualif CmpZ(v : @(0)): ((v <= 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 10, column 8)
+qualif CmpZ(v : @(0)): ((v > 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 11, column 8)
+qualif CmpZ(v : @(0)): ((v >= 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 12, column 8)
+qualif CmpZ(v : @(0)): ((v = 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 13, column 8)
+qualif CmpZ(v : @(0)): ((v != 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 14, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v < x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 16, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v <= x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 17, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v > x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 18, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v >= x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 19, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v = x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 20, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v != x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 21, column 8)
+qualif One(v : int): ((v = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 28, column 8)
+qualif True1(v : GHC.Types.Bool): (v) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 29, column 8)
+qualif False1(v : GHC.Types.Bool): ((~ (v))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 30, column 8)
+qualif Papp(v : @(0), p : (Pred  @(0))): ((papp1 p v)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 34, column 8)
+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): ((papp2 p v x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 37, column 8)
+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): ((papp3 p v x y)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 39, column 8)
+
+
+
+
+constant runFun : (func(2, [(Arrow  @(0)  @(1)); @(0); @(1)]))
+constant addrLen : (func(0, [Str; int]))
+constant papp5 : (func(10, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4));
+                            @(5);
+                            @(6);
+                            @(7);
+                            @(8);
+                            @(9);
+                            bool]))
+constant x_Tuple21 : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant GHC.Types.False##68 : (bool)
+constant x_Tuple65 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(4)]))
+constant x_Tuple55 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(4)]))
+constant x_Tuple33 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(2)]))
+constant x_Tuple77 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(6)]))
+constant papp3 : (func(6, [(Pred  @(0)  @(1)  @(2));
+                           @(3);
+                           @(4);
+                           @(5);
+                           bool]))
+constant GHC.Types.True##6u : (bool)
+constant x_Tuple63 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(2)]))
+constant x_Tuple41 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(0)]))
+constant GHC.Types.LT##6S : (GHC.Types.Ordering)
+constant papp4 : (func(8, [(Pred  @(0)  @(1)  @(2)  @(3));
+                           @(4);
+                           @(5);
+                           @(6);
+                           @(7);
+                           bool]))
+constant x_Tuple64 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(3)]))
+constant GHC.Types.GT##6W : (GHC.Types.Ordering)
+constant autolen : (func(1, [@(0); int]))
+constant x_Tuple52 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(1)]))
+constant head : (func(1, [[@(0)]; @(0)]))
+constant null : (func(1, [[@(0)]; bool]))
+constant papp2 : (func(4, [(Pred  @(0)  @(1)); @(2); @(3); bool]))
+constant x_Tuple62 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(1)]))
+constant fromJust : (func(1, [(GHC.Base.Maybe  @(0)); @(0)]))
+constant papp7 : (func(14, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                            @(7);
+                            @(8);
+                            @(9);
+                            @(10);
+                            @(11);
+                            @(12);
+                            @(13);
+                            bool]))
+constant x_Tuple53 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(2)]))
+constant x_Tuple71 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(0)]))
+constant ack : (func(0, [int; int; int]))
+constant x_Tuple74 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(3)]))
+constant len : (func(2, [(@(0)  @(1)); int]))
+constant papp6 : (func(12, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                            @(6);
+                            @(7);
+                            @(8);
+                            @(9);
+                            @(10);
+                            @(11);
+                            bool]))
+constant x_Tuple22 : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant x_Tuple66 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(5)]))
+constant x_Tuple44 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(3)]))
+constant GHC.Err.undefined##02v : (func(1, [@(0)]))
+constant strLen : (func(0, [[Char]; int]))
+constant x_Tuple72 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(1)]))
+constant isJust : (func(1, [(GHC.Base.Maybe  @(0)); bool]))
+constant x_Tuple31 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(0)]))
+constant x_Tuple75 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(4)]))
+constant papp1 : (func(2, [(Pred  @(0)); @(1); bool]))
+constant x_Tuple61 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(0)]))
+constant x_Tuple43 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(2)]))
+constant tail : (func(1, [[@(0)]; [@(0)]]))
+constant GHC.Types.EQ##6U : (GHC.Types.Ordering)
+constant x_Tuple51 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(0)]))
+constant x_Tuple73 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(2)]))
+constant Main.ack##rjG : (func(0, [int; int; int]))
+constant x_Tuple54 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(3)]))
+constant cmp : (func(0, [GHC.Types.Ordering; GHC.Types.Ordering]))
+constant x_Tuple32 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(1)]))
+constant x_Tuple76 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(5)]))
+constant snd : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant fst : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant x_Tuple42 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(1)]))
+
+
+distinct GHC.Types.False##68 : (bool)
+distinct GHC.Types.True##6u : (bool)
+distinct GHC.Types.LT##6S : (GHC.Types.Ordering)
+distinct GHC.Types.GT##6W : (GHC.Types.Ordering)
+distinct GHC.Types.EQ##6U : (GHC.Types.Ordering)
+
+
+bind 0 GHC.Err.undefined##02v : {VV : func(1, [@(0)]) | []}
+bind 1 GHC.Types.True##6u : {VV##9 : bool | [(VV##9 = GHC.Types.True##6u)]}
+bind 2 GHC.Types.False##68 : {VV##10 : bool | [(VV##10 = GHC.Types.False##68)]}
+bind 3 GHC.Types.EQ##6U : {VV##11 : GHC.Types.Ordering | [(VV##11 = GHC.Types.EQ##6U)]}
+bind 4 GHC.Types.LT##6S : {VV##12 : GHC.Types.Ordering | [(VV##12 = GHC.Types.LT##6S)]}
+bind 5 GHC.Types.GT##6W : {VV##13 : GHC.Types.Ordering | [(VV##13 = GHC.Types.GT##6W)]}
+bind 6 Main.ack##rjG : {VV : func(0, [int; int; int]) | []}
+bind 7 Main.ack##rjG : {VV : func(0, [int; int; int]) | []}
+bind 8 m##alH : {VV##41 : int | []}
+bind 9 Main.bar##rlx : {VV : func(0, [int; int; int]) | []}
+bind 10 VV##55 : {VV##55 : int | []}
+bind 11 m##alH : {VV##57 : int | []}
+bind 12 VV##58 : {VV##58 : int | []}
+bind 13 lq_tmp$x##51 : {v : int | []}
+bind 14 VV##61 : {VV##61 : int | []}
+bind 15 VV##63 : {VV##63 : int | []}
+bind 16 lq_tmp$x##40 : {v : int | []}
+bind 17 VV##66 : {VV##66 : int | [(VV##66 = (ack m##alH lq_tmp$x##40))]}
+bind 18 VV##68 : {VV##68 : int | [(VV##68 = m##alH)]}
+bind 19 VV##70 : {VV##70 : int | []}
+bind 20 lq_tmp$x##17 : {VV##72 : int | []}
+bind 21 VV##73 : {VV##73 : int | []}
+bind 22 lq_tmp$x##19 : {VV##75 : int | []}
+bind 23 VV##76 : {VV##76 : int | [$k_##31[lq_tmp$x##22:=lq_tmp$x##17][VV##30:=VV##76][lq_tmp$x##26:=lq_tmp$x##19][lq_tmp$x##35:=VV##76]]}
+bind 24 VV##23 : {VV##23 : int | [$k_##24]}
+bind 25 lq_tmp$x##22 : {VV##23 : int | [$k_##24]}
+bind 26 VV##27 : {VV##27 : int | [$k_##28]}
+bind 27 lq_tmp$x##26 : {VV##27 : int | [$k_##28]}
+bind 28 VV##30 : {VV##30 : int | [$k_##31]}
+
+
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8]
+  lhs {VV##F##1 : func(0, [int; int]) | [(VV##F##1 = (ack m##alH))]}
+  rhs {VV##F##1 : func(0, [int; int]) | [(VV##F##1 = (ack m##alH))]}
+  id 1 tag [2]
+  // META constraint id 1 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6]
+  lhs {VV##F##2 : int | []}
+  rhs {VV##F##2 : int | [$k_##24[VV##70:=VV##F##2][VV##23:=VV##F##2][VV##F:=VV##F##2][lq_tmp$x##33:=VV##F##2]]}
+  id 2 tag [1]
+  // META constraint id 2 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6; 20]
+  lhs {VV##F##3 : int | []}
+  rhs {VV##F##3 : int | [$k_##28[lq_tmp$x##22:=lq_tmp$x##17][lq_tmp$x##34:=VV##F##3][VV##27:=VV##F##3][VV##73:=VV##F##3][VV##F:=VV##F##3]]}
+  id 3 tag [1]
+  // META constraint id 3 : ()
+
+
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 25]
+  reft {VV##27 : int | [$k_##28]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 25; 27]
+  reft {VV##30 : int | [$k_##31]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6]
+  reft {VV##23 : int | [$k_##24]}
+  // META wf : ()
+
+
+
+
+
+
+
diff --git a/liquid-fixpoint/tests/pos/NonLinear-pack.fq b/liquid-fixpoint/tests/pos/NonLinear-pack.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/NonLinear-pack.fq
@@ -0,0 +1,40 @@
+
+bind 1 pig      : {v: int | []}
+
+bind 3 argAlice : {v: int | v = 10}
+bind 4 alice    : {v: int | [$k0[vk01 := argAlice][vk02 := v]] }
+
+bind 5 argBob   : {v: int | v = 20}
+bind 6 bob      : {v: int | [$k1[vk11 := argBob][vk12 := v]] }
+
+bind 10 vk01   : {v: int | []}
+bind 11 vk11   : {v: int | []}
+
+pack $k0 : 1
+pack $k1 : 1
+
+constraint:
+  env [1]
+  lhs {v1 : int | [v1 = pig + 1]}
+  rhs {v1 : int | [$k0[vk01 := pig][vk02 := v1]]}
+  id 1 tag [2]
+
+constraint:
+  env [1]
+  lhs {v2 : int | [v2 = pig + 1]}
+  rhs {v2 : int | [$k1[vk11 := pig][vk12 := v2]]}
+  id 2 tag [2]
+
+constraint:
+  env [3; 4; 5; 6]
+  lhs {v3 : int | [v3 = alice + bob]}
+  rhs {v3 : int | [v3 = 32]}
+  id 3 tag [2]
+
+wf:
+  env [10]
+  reft {vk02: int | [$k0]}
+
+wf:
+  env [11]
+  reft {vk12: int | [$k1]}
diff --git a/liquid-fixpoint/tests/pos/bad-subst00.fq b/liquid-fixpoint/tests/pos/bad-subst00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/bad-subst00.fq
@@ -0,0 +1,26 @@
+qualif Zog(v:a) : (10 <= v)
+qualif Bog(v:a, x:a) : (x <= v)
+
+bind 0 a : {v: int | $k0[zogbert := pikachu] }
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 10}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 20}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/pos/bad-subst01.fq b/liquid-fixpoint/tests/pos/bad-subst01.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/bad-subst01.fq
@@ -0,0 +1,34 @@
+// fixpoint "--eliminate=some"
+
+
+qualif Zog(v:a) : (10 <= v)
+qualif Bog(v:a, x:a) : (x <= v)
+
+bind 0 a : {v: int | $k0 }
+
+// this is a junk binder that adds a bogus [param := zogbert] substitution
+// at each USE of k0 causing eliminate to crash.
+
+bind 10 zogbert : {v : int | [] }
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 10}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 20}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ 10 ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/pos/bad-subst02.fq b/liquid-fixpoint/tests/pos/bad-subst02.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/bad-subst02.fq
@@ -0,0 +1,22 @@
+fixpoint "--eliminate=none"
+
+qualif Eq(v:a, x:a): (v = x)
+
+bind 0 x0 : {v: a0 | true }
+bind 1 x1 : {v: a1 | true }
+
+constraint:
+  env [ 1 ]
+  lhs {v : a1 | v = x1 }
+  rhs {v : a1 | $k0[v0 := v][x0 := x1] }
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : a2 | $k0[v0 := v][x0 := x2] }
+  rhs {v : a2 | 2 < 3 + 4 }
+  id 2 tag []
+
+wf:
+  env [ 0 ]
+  reft {v0 : a0 | $k0 }
diff --git a/liquid-fixpoint/tests/pos/bool00.fq b/liquid-fixpoint/tests/pos/bool00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/bool00.fq
@@ -0,0 +1,28 @@
+qualif Zog(v:a) : (10 <= v)
+qualif Bog(v:a, x:a) : (x <= v)
+
+bind 0 a  : {v: int  | $k0}
+bind 1 tt : {v: bool | v}
+
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 10}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 20}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/pos/bool03.fq b/liquid-fixpoint/tests/pos/bool03.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/bool03.fq
@@ -0,0 +1,28 @@
+
+//qualif LE(v:a, x:a): (bool_to_int x <= bool_to_int v)
+
+qualif LE(v:a, x:a): (x <= v)
+
+constant lit$36$not$45$the$45$hippopotamus : (Str)
+constant lit#cat : (Str)
+constant lit#dog : (Str)
+
+bind 1 bx : {v: bool | true }
+
+bind 2 zx : {v: bool | lit#cat /= lit#dog }
+
+constraint:
+  env [ 1 ]
+  lhs {v : bool | bx <= v }
+  rhs {v : bool | $k1     }
+  id 1 tag []
+
+constraint:
+  env [ 1; 2 ]
+  lhs {v : bool | $k1 }
+  rhs {v : bool | bx <= v }
+  id 2 tag []
+
+wf:
+  env [1]
+  reft {v : bool | $k1 }
diff --git a/liquid-fixpoint/tests/pos/bool04.fq b/liquid-fixpoint/tests/pos/bool04.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/bool04.fq
@@ -0,0 +1,20 @@
+fixpoint "--eliminate=some"
+
+bind 1 bx : {v: int  | true }
+bind 2 by : {v: bool | true }
+
+constraint:
+  env [ 2 ]
+  lhs {v : int | true }
+  rhs {v : int | $k1[bx := by] }
+  id 1 tag []
+
+constraint:
+  env [ 1 ]
+  lhs {v : int | $k1    }
+  rhs {v : int | v <= v + 1 }
+  id 2 tag []
+
+wf:
+  env [1]
+  reft {v : int | $k1 }
diff --git a/liquid-fixpoint/tests/pos/conj-rhs.fq b/liquid-fixpoint/tests/pos/conj-rhs.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/conj-rhs.fq
@@ -0,0 +1,6 @@
+constraint:
+  env []
+  lhs {v:int | true }
+  rhs {v:int | (0 < 1) && (1 > 0) }
+  id 1
+  tag [1]
diff --git a/liquid-fixpoint/tests/pos/cut-keyword.fq b/liquid-fixpoint/tests/pos/cut-keyword.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/cut-keyword.fq
@@ -0,0 +1,3 @@
+
+cut $k__151
+constant Prop : (func(0, [GHC.Types.Bool; bool]))
diff --git a/liquid-fixpoint/tests/pos/elim00.fq b/liquid-fixpoint/tests/pos/elim00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/elim00.fq
@@ -0,0 +1,1495 @@
+fixpoint "--defunct"
+
+// trick is to do it without these
+qualif Cmp(v : @(0), x : @(0)): ((v > x)) // "tests/todo/elim00.hs.fq" (line 1, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v = x)) // "tests/todo/elim00.hs.fq" (line 2, column 8)
+
+
+constant Control.Exception.Base.irrefutPatError##09 : (func(1, [int;
+                                                                @(0)]))
+constant GHC.Base..##r2C : (func(3, [func(0, [@(0); @(1)]);
+                                     func(0, [@(2); @(0)]);
+                                     @(2);
+                                     @(1)]))
+constant runFun : (func(2, [(Arrow  @(0)  @(1)); @(0); @(1)]))
+constant GHC.Tuple.$40$$44$$44$$41$$35$$35$76 : (func(3, [@(0);
+                                                          @(1);
+                                                          @(2);
+                                                          (Tuple  @(0)  @(1)  @(2))]))
+constant GHC.Real.D$58$Integral$35$$35$rWH : (func(1, [func(0, [@(0);
+                                                                @(0);
+                                                                @(0)]);
+                                                       func(0, [@(0); @(0); @(0)]);
+                                                       func(0, [@(0); @(0); @(0)]);
+                                                       func(0, [@(0); @(0); @(0)]);
+                                                       func(0, [@(0); @(0); (Tuple  @(0)  @(0))]);
+                                                       func(0, [@(0); @(0); (Tuple  @(0)  @(0))]);
+                                                       func(0, [@(0); int]);
+                                                       (GHC.Real.Integral  @(0))]))
+constant addrLen : (func(0, [int; int]))
+constant papp5 : (func(10, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4));
+                            @(5);
+                            @(6);
+                            @(7);
+                            @(8);
+                            @(9);
+                            bool]))
+constant xsListSelector : (func(1, [[@(0)]; [@(0)]]))
+constant x_Tuple21 : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant x_Tuple65 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(4)]))
+constant Elim.foo##rlD : (func(0, [Elim.Foo; Elim.Foo]))
+constant x_Tuple55 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(4)]))
+constant GHC.Integer.Type.smallInteger##0Z : (func(0, [int; int]))
+constant x_Tuple33 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(2)]))
+constant x_Tuple77 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(6)]))
+constant GHC.Base.Just##r1e : (func(1, [@(0);
+                                        (GHC.Base.Maybe  @(0))]))
+constant Elim.xx##rlB : (func(0, [Elim.Foo; int]))
+constant papp3 : (func(6, [(Pred  @(0)  @(1)  @(2));
+                           @(3);
+                           @(4);
+                           @(5);
+                           bool]))
+constant GHC.Prim.$43$$35$$35$$35$98 : (func(0, [int; int; int]))
+constant x_Tuple63 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(2)]))
+constant x_Tuple41 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(0)]))
+constant GHC.Types.LT##6S : (GHC.Types.Ordering)
+constant GHC.Prim.$60$$35$$35$$35$9q : (func(0, [int; int; int]))
+constant papp4 : (func(8, [(Pred  @(0)  @(1)  @(2)  @(3));
+                           @(4);
+                           @(5);
+                           @(6);
+                           @(7);
+                           bool]))
+constant Elim.PP##rlx : (func(2, [@(0);
+                                  @(1);
+                                  (Elim.Pair  @(0)  @(1))]))
+constant x_Tuple64 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(3)]))
+constant GHC.Types.GT##6W : (GHC.Types.Ordering)
+constant GHC.Prim.$45$$35$$35$$35$99 : (func(0, [int; int; int]))
+constant GHC.Types.$58$$35$$35$64 : (func(1, [@(0);
+                                              [@(0)];
+                                              [@(0)]]))
+constant autolen : (func(1, [@(0); int]))
+constant GHC.Types.I###6c : (func(0, [int; int]))
+constant x_Tuple52 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(1)]))
+constant xx : (func(0, [Elim.Foo; int]))
+constant null : (func(1, [[@(0)]; bool]))
+constant GHC.Num.$43$$35$$35$rt : (func(1, [@(0); @(0); @(0)]))
+constant GHC.Tuple.$40$$44$$44$$44$$44$$41$$35$$35$7a : (func(5, [@(0);
+                                                                  @(1);
+                                                                  @(2);
+                                                                  @(3);
+                                                                  @(4);
+                                                                  (Tuple  @(0)  @(1)  @(2)  @(3)  @(4))]))
+constant papp2 : (func(4, [(Pred  @(0)  @(1)); @(2); @(3); bool]))
+constant x_Tuple62 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(1)]))
+constant GHC.Tuple.$40$$44$$41$$35$$35$74 : (func(2, [@(0);
+                                                      @(1);
+                                                      (Tuple  @(0)  @(1))]))
+constant Elim.yy##rlC : (func(0, [Elim.Foo; int]))
+constant fromJust : (func(1, [(GHC.Base.Maybe  @(0)); @(0)]))
+constant papp7 : (func(14, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                            @(7);
+                            @(8);
+                            @(9);
+                            @(10);
+                            @(11);
+                            @(12);
+                            @(13);
+                            bool]))
+constant x_Tuple53 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(2)]))
+constant x_Tuple71 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(0)]))
+constant GHC.Prim.$62$$35$$35$$35$9m : (func(0, [int; int; int]))
+constant x_Tuple74 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(3)]))
+constant Elim.Emp##rly : (func(2, [(Elim.Pair  @(0)  @(1))]))
+constant len : (func(2, [(@(0)  @(1)); int]))
+constant GHC.Tuple.$40$$44$$44$$44$$44$$44$$44$$41$$35$$35$7e : (func(7, [@(0);
+                                                                          @(1);
+                                                                          @(2);
+                                                                          @(3);
+                                                                          @(4);
+                                                                          @(5);
+                                                                          @(6);
+                                                                          (Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6))]))
+constant papp6 : (func(12, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                            @(6);
+                            @(7);
+                            @(8);
+                            @(9);
+                            @(10);
+                            @(11);
+                            bool]))
+constant x_Tuple22 : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant Data.Foldable.length##r1s : (func(2, [(@(0)  @(0)); int]))
+constant x_Tuple66 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(5)]))
+constant x_Tuple44 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(3)]))
+constant xListSelector : (func(1, [[@(0)]; @(0)]))
+constant strLen : (func(0, [int; int]))
+constant x_Tuple72 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(1)]))
+constant GHC.Tuple.$40$$44$$44$$44$$41$$35$$35$78 : (func(4, [@(0);
+                                                              @(1);
+                                                              @(2);
+                                                              @(3);
+                                                              (Tuple  @(0)  @(1)  @(2)  @(3))]))
+constant isJust : (func(1, [(GHC.Base.Maybe  @(0)); bool]))
+constant GHC.Prim.$61$$61$$35$$35$$35$9o : (func(0, [int;
+                                                     int;
+                                                     int]))
+constant Elim.Foo##rlA : (func(0, [int; int; Elim.Foo]))
+constant Prop : (func(0, [GHC.Types.Bool; bool]))
+constant x_Tuple31 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(0)]))
+constant x_Tuple75 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(4)]))
+constant papp1 : (func(2, [(Pred  @(0)); @(1); bool]))
+constant yy : (func(0, [Elim.Foo; int]))
+constant x_Tuple61 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(0)]))
+constant GHC.Prim.$62$$61$$35$$35$$35$9n : (func(0, [int;
+                                                     int;
+                                                     int]))
+constant lit$36$tests$47$pos$47$elim00.hs$58$14$58$5$45$30$124$PP$32$wink$32$cow : (Str)
+constant x_Tuple43 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(2)]))
+constant GHC.Types.EQ##6U : (GHC.Types.Ordering)
+constant x_Tuple51 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(0)]))
+constant GHC.Base.Nothing##r1d : (func(1, [(GHC.Base.Maybe  @(0))]))
+constant GHC.Num.$45$$35$$35$02B : (func(1, [@(0); @(0); @(0)]))
+constant GHC.Num.$42$$35$$35$ru : (func(1, [@(0); @(0); @(0)]))
+constant x_Tuple73 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(2)]))
+constant GHC.Types.$91$$93$$35$$35$6m : (func(1, [[@(0)]]))
+constant x_Tuple54 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(3)]))
+constant cmp : (func(0, [GHC.Types.Ordering; GHC.Types.Ordering]))
+constant x_Tuple32 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(1)]))
+constant x_Tuple76 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(5)]))
+constant GHC.Prim.$60$$61$$35$$35$$35$9r : (func(0, [int;
+                                                     int;
+                                                     int]))
+constant GHC.Real.D$58$Fractional$35$$35$rVU : (func(1, [func(0, [@(0);
+                                                                  @(0);
+                                                                  @(0)]);
+                                                         func(0, [@(0); @(0)]);
+                                                         func(0, [(GHC.Real.Ratio  int); @(0)]);
+                                                         (GHC.Real.Fractional  @(0))]))
+constant fst : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant snd : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant GHC.Tuple.$40$$44$$44$$44$$44$$44$$41$$35$$35$7c : (func(6, [@(0);
+                                                                      @(1);
+                                                                      @(2);
+                                                                      @(3);
+                                                                      @(4);
+                                                                      @(5);
+                                                                      (Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5))]))
+constant x_Tuple42 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(1)]))
+constant GHC.Prim.void###0l : (GHC.Prim.Void#)
+
+
+bind 0 GHC.Prim.void###0l : {VV##180 : GHC.Prim.Void# | []}
+bind 1 Elim.Emp##rly : {VV : func(2, [(Elim.Pair  @(0)  @(1))]) | []}
+bind 2 GHC.Types.EQ##6U : {VV##185 : GHC.Types.Ordering | [(VV##185 = GHC.Types.EQ##6U)]}
+bind 3 GHC.Types.LT##6S : {VV##186 : GHC.Types.Ordering | [(VV##186 = GHC.Types.LT##6S)]}
+bind 4 GHC.Types.GT##6W : {VV##187 : GHC.Types.Ordering | [(VV##187 = GHC.Types.GT##6W)]}
+bind 5 Elim.Emp##rly : {VV : func(2, [(Elim.Pair  @(0)  @(1))]) | []}
+bind 6 GHC.Types.$91$$93$$35$$35$6m : {VV : func(1, [[@(0)]]) | []}
+bind 7 GHC.Types.GT##6W : {VV##213 : GHC.Types.Ordering | [((cmp VV##213) = GHC.Types.GT##6W)]}
+bind 8 GHC.Types.LT##6S : {VV##214 : GHC.Types.Ordering | [((cmp VV##214) = GHC.Types.LT##6S)]}
+bind 9 GHC.Types.EQ##6U : {VV##215 : GHC.Types.Ordering | [((cmp VV##215) = GHC.Types.EQ##6U)]}
+bind 10 GHC.Base.Nothing##r1d : {VV : func(1, [(GHC.Base.Maybe  @(0))]) | []}
+bind 11 ds_dxd : {VV##222 : Elim.Foo | []}
+bind 12 lq_anf$##dxr : {lq_tmp$x##223 : Elim.Foo | [(lq_tmp$x##223 = ds_dxd)]}
+bind 13 lq_anf$##dxr : {lq_tmp$x##225 : Elim.Foo | [(lq_tmp$x##225 = ds_dxd)]}
+bind 14 xig##awy : {lq_tmp$x##233 : int | []}
+bind 15 yog##awz : {lq_tmp$x##234 : int | [(xig##awy < lq_tmp$x##234)]}
+bind 16 lq_anf$##dxr : {lq_tmp$x##225 : Elim.Foo | [(lq_tmp$x##225 = ds_dxd);
+                                                    ((yy lq_tmp$x##225) = yog##awz);
+                                                    ((xx lq_tmp$x##225) = xig##awy);
+                                                    (lq_tmp$x##225 = (Elim.Foo##rlA xig##awy yog##awz));
+                                                    ((yy lq_tmp$x##225) = yog##awz);
+                                                    ((xx lq_tmp$x##225) = xig##awy)]}
+bind 17 lq_anf$##dxs : {lq_tmp$x##242 : (Elim.Pair  int  int) | [(lq_tmp$x##242 = (Elim.PP##rlx xig##awy yog##awz))]}
+bind 18 lq_anf$##dxt : {lq_tmp$x##273 : (Elim.Pair  int  int) | [(lq_tmp$x##273 = lq_anf$##dxs)]}
+bind 19 lq_anf$##dxt : {lq_tmp$x##277 : (Elim.Pair  int  int) | [(lq_tmp$x##277 = lq_anf$##dxs)]}
+bind 20 wink##ax3 : {lq_tmp$x##275 : int | [$k_##248[lq_tmp$x##277:=lq_anf$##dxt][VV##247:=lq_tmp$x##275][lq_tmp$x##242:=lq_anf$##dxt][lq_tmp$x##271:=lq_tmp$x##275][lq_tmp$x##273:=lq_anf$##dxt][lq_tmp$x##245:=xig##awy][lq_tmp$x##246:=yog##awz][lq_tmp$x##250:=lq_tmp$x##275]]}
+bind 21 cow##ax4 : {lq_tmp$x##276 : int | [$k_##252[lq_tmp$x##277:=lq_anf$##dxt][lq_tmp$x##281:=wink##ax3][VV##251:=lq_tmp$x##276][lq_tmp$x##242:=lq_anf$##dxt][lq_tmp$x##254:=lq_tmp$x##276][lq_tmp$x##273:=lq_anf$##dxt][lq_tmp$x##245:=xig##awy][lq_tmp$x##246:=yog##awz][lq_tmp$x##272:=lq_tmp$x##276]]}
+bind 22 lq_anf$##dxt : {lq_tmp$x##277 : (Elim.Pair  int  int) | [(lq_tmp$x##277 = lq_anf$##dxs);
+                                                                 (lq_tmp$x##277 = (Elim.PP##rlx wink##ax3 cow##ax4));
+                                                                 (lq_tmp$x##277 = (Elim.PP##rlx wink##ax3 cow##ax4));
+                                                                 (lq_tmp$x##277 = (Elim.PP##rlx wink##ax3 cow##ax4))]}
+bind 23 lq_tmp$x##307 : {VV##308 : int | []}
+bind 24 lq_anf$##dxt : {lq_tmp$x##313 : (Elim.Pair  int  int) | [(lq_tmp$x##313 = lq_anf$##dxs)]}
+bind 25 lq_anf$##dxt : {lq_tmp$x##313 : (Elim.Pair  int  int) | [(lq_tmp$x##313 = lq_anf$##dxs);
+                                                                 (lq_tmp$x##313 = Elim.Emp##rly);
+                                                                 (lq_tmp$x##313 = Elim.Emp##rly);
+                                                                 (lq_tmp$x##313 = Elim.Emp##rly)]}
+bind 26 ds_dxg : {VV##318 : GHC.Prim.Void# | [$k_##319]}
+bind 27 lq_anf$##dxu : {lq_tmp$x##335 : int | [(lq_tmp$x##335 ~~ lit$36$tests$47$pos$47$elim00.hs$58$14$58$5$45$30$124$PP$32$wink$32$cow);
+                                               ((strLen lq_tmp$x##335) = 39)]}
+bind 28 ds_dxh : {VV##268 : (Tuple  int  int) | [$k_##269]}
+bind 29 lq_anf$##dxw : {lq_tmp$x##368 : (Tuple  int  int) | [(lq_tmp$x##368 = ds_dxh)]}
+bind 30 lq_anf$##dxw : {lq_tmp$x##374 : (Tuple  int  int) | [(lq_tmp$x##374 = ds_dxh)]}
+bind 31 wink##ax3 : {lq_tmp$x##370 : int | [$k_##259[lq_tmp$x##368:=lq_anf$##dxw][VV##268:=lq_anf$##dxw][lq_tmp$x##364:=lq_tmp$x##370][VV##258:=lq_tmp$x##370][lq_tmp$x##374:=lq_anf$##dxw]]}
+bind 32 cow##Xxd : {lq_tmp$x##371 : int | [$k_##262[lq_tmp$x##368:=lq_anf$##dxw][VV##268:=lq_anf$##dxw][VV##261:=lq_tmp$x##371][lq_tmp$x##365:=lq_tmp$x##371][lq_tmp$x##379:=wink##ax3][lq_tmp$x##374:=lq_anf$##dxw];
+                                           $k_##266[lq_tmp$x##368:=lq_anf$##dxw][lq_tmp$x##373:=lq_tmp$x##371][VV##265:=lq_tmp$x##371][lq_tmp$x##264:=wink##ax3][lq_tmp$x##367:=lq_tmp$x##371][VV##268:=lq_anf$##dxw][lq_tmp$x##372:=wink##ax3][lq_tmp$x##366:=wink##ax3][lq_tmp$x##379:=wink##ax3][lq_tmp$x##374:=lq_anf$##dxw]]}
+bind 33 lq_anf$##dxw : {lq_tmp$x##374 : (Tuple  int  int) | [(lq_tmp$x##374 = ds_dxh);
+                                                             ((snd lq_tmp$x##374) = cow##Xxd);
+                                                             ((fst lq_tmp$x##374) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##374) = cow##Xxd);
+                                                             ((x_Tuple21 lq_tmp$x##374) = wink##ax3);
+                                                             (lq_tmp$x##374 = (GHC.Tuple.$40$$44$$41$$35$$35$74 wink##ax3 cow##Xxd));
+                                                             ((snd lq_tmp$x##374) = cow##Xxd);
+                                                             ((fst lq_tmp$x##374) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##374) = cow##Xxd);
+                                                             ((x_Tuple21 lq_tmp$x##374) = wink##ax3)]}
+bind 34 wink##ax3 : {VV##361 : int | [$k_##362]}
+// bind 45 wink##ax3 : {lq_tmp$x##452 : int | [$k_##428[lq_tmp$x##425:=wink##ax3][lq_tmp$x##456:=lq_anf$##dxy][VV##427:=lq_tmp$x##452][lq_tmp$x##426:=cow##ax4][lq_tmp$x##450:=lq_anf$##dxy][lq_tmp$x##430:=lq_tmp$x##452][lq_tmp$x##446:=lq_tmp$x##452][lq_tmp$x##422:=lq_anf$##dxy]]}
+
+bind 35 lq_anf$##dxv : {lq_tmp$x##398 : (Tuple  int  int) | [(lq_tmp$x##398 = ds_dxh)]}
+bind 36 lq_anf$##dxv : {lq_tmp$x##404 : (Tuple  int  int) | [(lq_tmp$x##404 = ds_dxh)]}
+bind 37 wink##ax3 : {lq_tmp$x##400 : int | [$k_##259[VV##268:=lq_anf$##dxv][lq_tmp$x##394:=lq_tmp$x##400][VV##258:=lq_tmp$x##400][lq_tmp$x##398:=lq_anf$##dxv][lq_tmp$x##404:=lq_anf$##dxv]]}
+bind 38 cow##ax4 : {lq_tmp$x##401 : int | [$k_##262[VV##268:=lq_anf$##dxv][VV##261:=lq_tmp$x##401][lq_tmp$x##409:=wink##ax3][lq_tmp$x##398:=lq_anf$##dxv][lq_tmp$x##395:=lq_tmp$x##401][lq_tmp$x##404:=lq_anf$##dxv];
+                                           $k_##266[lq_tmp$x##396:=wink##ax3][VV##265:=lq_tmp$x##401][lq_tmp$x##264:=wink##ax3][VV##268:=lq_anf$##dxv][lq_tmp$x##397:=lq_tmp$x##401][lq_tmp$x##409:=wink##ax3][lq_tmp$x##403:=lq_tmp$x##401][lq_tmp$x##398:=lq_anf$##dxv][lq_tmp$x##402:=wink##ax3][lq_tmp$x##404:=lq_anf$##dxv]]}
+bind 39 lq_anf$##dxv : {lq_tmp$x##404 : (Tuple  int  int) | [(lq_tmp$x##404 = ds_dxh);
+                                                             ((snd lq_tmp$x##404) = cow##ax4);
+                                                             ((fst lq_tmp$x##404) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##404) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##404) = wink##ax3);
+                                                             (lq_tmp$x##404 = (GHC.Tuple.$40$$44$$41$$35$$35$74 wink##ax3 cow##ax4));
+                                                             ((snd lq_tmp$x##404) = cow##ax4);
+                                                             ((fst lq_tmp$x##404) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##404) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##404) = wink##ax3)]}
+bind 40 cow##ax4 : {VV##391 : int | [$k_##392]}
+bind 41 lq_tmp$x##438 : {VV##439 : int | []}
+bind 42 ds_dxi : {lq_tmp$x##422 : (Tuple  int  int) | [((snd lq_tmp$x##422) = cow##ax4);
+                                                       ((fst lq_tmp$x##422) = wink##ax3);
+                                                       ((x_Tuple22 lq_tmp$x##422) = cow##ax4);
+                                                       ((x_Tuple21 lq_tmp$x##422) = wink##ax3)]}
+bind 43 lq_anf$##dxy : {lq_tmp$x##450 : (Tuple  int  int) | [(lq_tmp$x##450 = ds_dxi)]}
+bind 44 lq_anf$##dxy : {lq_tmp$x##456 : (Tuple  int  int) | [(lq_tmp$x##456 = ds_dxi)]}
+bind 45 wink##ax3 : {lq_tmp$x##452 : int | [$k_##428[lq_tmp$x##425:=wink##ax3][lq_tmp$x##456:=lq_anf$##dxy][VV##427:=lq_tmp$x##452][lq_tmp$x##426:=cow##ax4][lq_tmp$x##450:=lq_anf$##dxy][lq_tmp$x##430:=lq_tmp$x##452][lq_tmp$x##446:=lq_tmp$x##452][lq_tmp$x##422:=lq_anf$##dxy]]}
+bind 46 cow##ax4 : {lq_tmp$x##453 : int | [$k_##432[lq_tmp$x##425:=wink##ax3][lq_tmp$x##456:=lq_anf$##dxy][lq_tmp$x##426:=cow##ax4][VV##431:=lq_tmp$x##453][lq_tmp$x##450:=lq_anf$##dxy][lq_tmp$x##447:=lq_tmp$x##453][lq_tmp$x##461:=wink##ax3][lq_tmp$x##422:=lq_anf$##dxy][lq_tmp$x##434:=lq_tmp$x##453];
+                                           $k_##436[lq_tmp$x##425:=wink##ax3][lq_tmp$x##456:=lq_anf$##dxy][lq_tmp$x##426:=cow##ax4][lq_tmp$x##455:=lq_tmp$x##453][lq_tmp$x##450:=lq_anf$##dxy][lq_tmp$x##461:=wink##ax3][lq_tmp$x##438:=wink##ax3][lq_tmp$x##421:=wink##ax3][lq_tmp$x##422:=lq_anf$##dxy][lq_tmp$x##434:=lq_tmp$x##453][lq_tmp$x##448:=wink##ax3][lq_tmp$x##449:=lq_tmp$x##453][VV##435:=lq_tmp$x##453][lq_tmp$x##454:=wink##ax3]]}
+bind 47 lq_anf$##dxy : {lq_tmp$x##456 : (Tuple  int  int) | [(lq_tmp$x##456 = ds_dxi);
+                                                             ((snd lq_tmp$x##456) = cow##ax4);
+                                                             ((fst lq_tmp$x##456) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##456) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##456) = wink##ax3);
+                                                             (lq_tmp$x##456 = (GHC.Tuple.$40$$44$$41$$35$$35$74 wink##ax3 cow##ax4));
+                                                             ((snd lq_tmp$x##456) = cow##ax4);
+                                                             ((fst lq_tmp$x##456) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##456) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##456) = wink##ax3)]}
+bind 48 wink##awA : {VV##443 : int | [$k_##444]}
+
+bind 49 lq_anf$##dxx : {lq_tmp$x##480 : (Tuple  int  int) | [(lq_tmp$x##480 = ds_dxi)]}
+bind 50 lq_anf$##dxx : {lq_tmp$x##486 : (Tuple  int  int) | [(lq_tmp$x##486 = ds_dxi)]}
+bind 51 wink##ax3 : {lq_tmp$x##482 : int | [$k_##428[lq_tmp$x##425:=wink##ax3][VV##427:=lq_tmp$x##482][lq_tmp$x##426:=cow##ax4][lq_tmp$x##476:=lq_tmp$x##482][lq_tmp$x##430:=lq_tmp$x##482][lq_tmp$x##480:=lq_anf$##dxx][lq_tmp$x##422:=lq_anf$##dxx][lq_tmp$x##486:=lq_anf$##dxx]]}
+bind 52 cow##ax4 : {lq_tmp$x##483 : int | [$k_##432[lq_tmp$x##425:=wink##ax3][lq_tmp$x##426:=cow##ax4][VV##431:=lq_tmp$x##483][lq_tmp$x##491:=wink##ax3][lq_tmp$x##480:=lq_anf$##dxx][lq_tmp$x##477:=lq_tmp$x##483][lq_tmp$x##422:=lq_anf$##dxx][lq_tmp$x##434:=lq_tmp$x##483][lq_tmp$x##486:=lq_anf$##dxx];
+                                           $k_##436[lq_tmp$x##425:=wink##ax3][lq_tmp$x##426:=cow##ax4][lq_tmp$x##491:=wink##ax3][lq_tmp$x##480:=lq_anf$##dxx][lq_tmp$x##479:=lq_tmp$x##483][lq_tmp$x##485:=lq_tmp$x##483][lq_tmp$x##438:=wink##ax3][lq_tmp$x##421:=wink##ax3][lq_tmp$x##422:=lq_anf$##dxx][lq_tmp$x##434:=lq_tmp$x##483][lq_tmp$x##484:=wink##ax3][lq_tmp$x##478:=wink##ax3][lq_tmp$x##486:=lq_anf$##dxx][VV##435:=lq_tmp$x##483]]}
+bind 53 lq_anf$##dxx : {lq_tmp$x##486 : (Tuple  int  int) | [(lq_tmp$x##486 = ds_dxi);
+                                                             ((snd lq_tmp$x##486) = cow##ax4);
+                                                             ((fst lq_tmp$x##486) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##486) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##486) = wink##ax3);
+                                                             (lq_tmp$x##486 = (GHC.Tuple.$40$$44$$41$$35$$35$74 wink##ax3 cow##ax4));
+                                                             ((snd lq_tmp$x##486) = cow##ax4);
+                                                             ((fst lq_tmp$x##486) = wink##ax3);
+                                                             ((x_Tuple22 lq_tmp$x##486) = cow##ax4);
+                                                             ((x_Tuple21 lq_tmp$x##486) = wink##ax3)]}
+bind 54 cow##awB : {VV##473 : int | [$k_##474]}
+bind 55 ds_dxo : {VV##514 : Elim.Foo | []}
+bind 56 lq_anf$##dxz : {lq_tmp$x##515 : Elim.Foo | [(lq_tmp$x##515 = ds_dxo)]}
+bind 57 lq_anf$##dxz : {lq_tmp$x##517 : Elim.Foo | [(lq_tmp$x##517 = ds_dxo)]}
+bind 58 ds_dxp : {lq_tmp$x##525 : int | []}
+bind 59 ds_dxq : {lq_tmp$x##526 : int | [(ds_dxp < lq_tmp$x##526)]}
+bind 60 lq_anf$##dxz : {lq_tmp$x##517 : Elim.Foo | [(lq_tmp$x##517 = ds_dxo);
+                                                    ((yy lq_tmp$x##517) = ds_dxq);
+                                                    ((xx lq_tmp$x##517) = ds_dxp);
+                                                    (lq_tmp$x##517 = (Elim.Foo##rlA ds_dxp ds_dxq));
+                                                    ((yy lq_tmp$x##517) = ds_dxq);
+                                                    ((xx lq_tmp$x##517) = ds_dxp)]}
+bind 61 ds_dxl : {VV##537 : Elim.Foo | []}
+bind 62 lq_anf$##dxA : {lq_tmp$x##538 : Elim.Foo | [(lq_tmp$x##538 = ds_dxl)]}
+bind 63 lq_anf$##dxA : {lq_tmp$x##540 : Elim.Foo | [(lq_tmp$x##540 = ds_dxl)]}
+bind 64 ds_dxm : {lq_tmp$x##548 : int | []}
+bind 65 ds_dxn : {lq_tmp$x##549 : int | [(ds_dxm < lq_tmp$x##549)]}
+bind 66 lq_anf$##dxA : {lq_tmp$x##540 : Elim.Foo | [(lq_tmp$x##540 = ds_dxl);
+                                                    ((yy lq_tmp$x##540) = ds_dxn);
+                                                    ((xx lq_tmp$x##540) = ds_dxm);
+                                                    (lq_tmp$x##540 = (Elim.Foo##rlA ds_dxm ds_dxn));
+                                                    ((yy lq_tmp$x##540) = ds_dxn);
+                                                    ((xx lq_tmp$x##540) = ds_dxm)]}
+bind 67 VV##559 : {VV##559 : int | [(VV##559 = ds_dxm)]}
+bind 68 VV##561 : {VV##561 : int | [(VV##561 = ds_dxq)]}
+bind 69 VV##563 : {VV##563 : Elim.Foo | [((yy VV##563) = cow##awB);
+                                         ((xx VV##563) = wink##awA)]}
+bind 70 VV##565 : {VV##565 : int | [(VV##565 = cow##awB)]}
+bind 71 VV##567 : {VV##567 : int | [(VV##567 = wink##awA)]}
+bind 72 VV##569 : {VV##569 : int | [(VV##569 = cow##ax4)]}
+bind 73 VV##571 : {VV##571 : int | [(VV##571 = wink##ax3)]}
+bind 74 VV##573 : {VV##573 : int | [(VV##573 = cow##ax4)]}
+bind 75 VV##575 : {VV##575 : int | [(VV##575 = wink##ax3)]}
+bind 76 VV##577 : {VV##577 : int | [(VV##577 = cow##ax4)]}
+bind 77 VV##579 : {VV##579 : int | [(VV##579 = wink##ax3)]}
+bind 78 VV##581 : {VV##581 : (Tuple  int  int) | [$k_##333[VV##332:=VV##581][ds_dxg:=GHC.Prim.void###0l]]}
+bind 79 VV##583 : {VV##583 : int | [$k_##323[VV##322:=VV##583][VV##332:=VV##581][ds_dxg:=GHC.Prim.void###0l]]}
+bind 80 VV##585 : {VV##585 : int | [$k_##326[VV##325:=VV##585][VV##332:=VV##581][ds_dxg:=GHC.Prim.void###0l]]}
+bind 81 lq_tmp$x##264 : {VV##587 : int | []}
+bind 82 VV##588 : {VV##588 : int | [$k_##330[VV##332:=VV##581][VV##329:=VV##588][ds_dxg:=GHC.Prim.void###0l][lq_tmp$x##328:=lq_tmp$x##264]]}
+bind 83 VV##590 : {VV##590 : GHC.Prim.Void# | [(VV##590 = GHC.Prim.void###0l)]}
+bind 84 VV##592 : {VV##592 : (Tuple  int  int) | [$k_##351[lq_tmp$x##339:=lq_anf$##dxu][lq_tmp$x##357:=VV##592][VV##350:=VV##592]]}
+bind 85 VV##594 : {VV##594 : int | [$k_##341[lq_tmp$x##353:=VV##594][lq_tmp$x##339:=lq_anf$##dxu][lq_tmp$x##357:=VV##592][VV##340:=VV##594][VV##350:=VV##592]]}
+bind 86 VV##596 : {VV##596 : int | [$k_##344[lq_tmp$x##339:=lq_anf$##dxu][lq_tmp$x##357:=VV##592][VV##343:=VV##596][lq_tmp$x##354:=VV##596][VV##350:=VV##592]]}
+bind 87 lq_tmp$x##328 : {VV##598 : int | []}
+bind 88 VV##599 : {VV##599 : int | [$k_##348[lq_tmp$x##355:=lq_tmp$x##328][lq_tmp$x##356:=VV##599][VV##347:=VV##599][lq_tmp$x##339:=lq_anf$##dxu][lq_tmp$x##346:=lq_tmp$x##328][lq_tmp$x##357:=VV##592][VV##350:=VV##592]]}
+bind 89 VV##601 : {VV##601 : int | [(VV##601 = lq_anf$##dxu)]}
+bind 90 VV##603 : {VV##603 : (Tuple  int  int) | [((snd VV##603) = cow##ax4);
+                                                  ((fst VV##603) = wink##ax3);
+                                                  ((x_Tuple22 VV##603) = cow##ax4);
+                                                  ((x_Tuple21 VV##603) = wink##ax3)]}
+bind 91 VV##605 : {VV##605 : int | [$k_##297[lq_tmp$x##295:=cow##ax4][lq_tmp$x##299:=VV##605][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][VV##296:=VV##605]]}
+bind 92 VV##607 : {VV##607 : int | [$k_##301[lq_tmp$x##295:=cow##ax4][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][VV##300:=VV##607][lq_tmp$x##303:=VV##607]]}
+bind 93 lq_tmp$x##264 : {VV##609 : int | []}
+bind 94 VV##610 : {VV##610 : int | [$k_##305[lq_tmp$x##295:=cow##ax4][lq_tmp$x##290:=lq_tmp$x##264][VV##304:=VV##610][lq_tmp$x##307:=lq_tmp$x##264][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][lq_tmp$x##303:=VV##610]]}
+bind 95 VV##612 : {VV##612 : int | [(VV##612 = cow##ax4)]}
+bind 96 VV##614 : {VV##614 : int | [(VV##614 = wink##ax3)]}
+bind 97 VV##616 : {VV##616 : int | [(VV##616 = yog##awz)]}
+bind 98 VV##618 : {VV##618 : int | [(VV##618 = xig##awy)]}
+bind 99 VV##473 : {VV##473 : int | [$k_##474]}
+bind 100 VV##443 : {VV##443 : int | [$k_##444]}
+bind 101 VV##435 : {VV##435 : int | [$k_##436]}
+bind 102 VV##431 : {VV##431 : int | [$k_##432]}
+bind 103 VV##427 : {VV##427 : int | [$k_##428]}
+bind 104 VV##391 : {VV##391 : int | [$k_##392]}
+bind 105 VV##361 : {VV##361 : int | [$k_##362]}
+bind 106 VV##318 : {VV##318 : GHC.Prim.Void# | [$k_##319]}
+bind 107 VV##350 : {VV##350 : (Tuple  int  int) | [$k_##351]}
+bind 108 VV##340 : {VV##340 : int | [$k_##341]}
+bind 109 VV##343 : {VV##343 : int | [$k_##344]}
+bind 110 lq_tmp$x##346 : {VV##631 : int | []}
+bind 111 VV##347 : {VV##347 : int | [$k_##348]}
+bind 112 VV##332 : {VV##332 : (Tuple  int  int) | [$k_##333]}
+bind 113 VV##322 : {VV##322 : int | [$k_##323]}
+bind 114 VV##325 : {VV##325 : int | [$k_##326]}
+bind 115 lq_tmp$x##328 : {VV##636 : int | []}
+bind 116 VV##329 : {VV##329 : int | [$k_##330]}
+bind 117 VV##304 : {VV##304 : int | [$k_##305]}
+bind 118 VV##300 : {VV##300 : int | [$k_##301]}
+bind 119 VV##296 : {VV##296 : int | [$k_##297]}
+bind 120 VV##268 : {VV##268 : (Tuple  int  int) | [$k_##269]}
+bind 121 VV##258 : {VV##258 : int | [$k_##259]}
+bind 122 VV##261 : {VV##261 : int | [$k_##262]}
+bind 123 lq_tmp$x##264 : {VV##644 : int | []}
+bind 124 VV##265 : {VV##265 : int | [$k_##266]}
+bind 125 VV##251 : {VV##251 : int | [$k_##252]}
+bind 126 VV##247 : {VV##247 : int | [$k_##248]}
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42;
+       48;
+       54 ]
+  lhs {VV##1 : int | [(VV##1 = cow##awB)]}
+  rhs {VV##1 : int | [(wink##awA < VV##1)]}
+  id 1 tag [1]
+  // META constraint id 1 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42;
+       48;
+       49;
+       50;
+       51;
+       52;
+       53]
+  lhs {VV##2 : int | [(VV##2 = cow##ax4)]}
+  rhs {VV##2 : int | [$k_##474[VV##569:=VV##2][VV##F##2:=VV##2][VV##F:=VV##2][VV##473:=VV##2]]}
+  id 2 tag [1]
+  // META constraint id 2 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  lhs {VV##18 : (Tuple  int  int) | [((snd VV##18) = cow##ax4);
+                                     ((fst VV##18) = wink##ax3);
+                                     ((x_Tuple22 VV##18) = cow##ax4);
+                                     ((x_Tuple21 VV##18) = wink##ax3)]}
+  rhs {VV##18 : (Tuple  int  int) | [$k_##269[VV##F##18:=VV##18][VV##268:=VV##18][VV##603:=VV##18][VV##F:=VV##18]]}
+  id 18 tag [1]
+  // META constraint id 18 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42;
+       43;
+       44;
+       45;
+       46;
+       47]
+  lhs {VV##3 : int | [(VV##3 = wink##ax3)]}
+  rhs {VV##3 : int | [$k_##444[VV##571:=VV##3][VV##F:=VV##3][VV##F##3:=VV##3][VV##443:=VV##3]]}
+  id 3 tag [1]
+  // META constraint id 3 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22;
+       90]
+  lhs {VV##19 : int | [$k_##297[lq_tmp$x##295:=cow##ax4][VV##605:=VV##19][lq_tmp$x##299:=VV##19][lq_tmp$x##291:=VV##603][VV##F##19:=VV##19][lq_tmp$x##294:=wink##ax3][VV##F:=VV##19][VV##296:=VV##19]]}
+  rhs {VV##19 : int | [$k_##259[VV##605:=VV##19][VV##268:=VV##603][VV##258:=VV##19][VV##F##19:=VV##19][VV##F:=VV##19]]}
+  id 19 tag [1]
+  // META constraint id 19 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  lhs {VV##4 : int | [(VV##4 = cow##ax4)]}
+  rhs {VV##4 : int | [$k_##432[lq_tmp$x##425:=wink##ax3][VV##431:=VV##4][VV##573:=VV##4][lq_tmp$x##434:=VV##4][VV##F:=VV##4][VV##F##4:=VV##4]]}
+  id 4 tag [1]
+  // META constraint id 4 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22;
+       90]
+  lhs {VV##20 : int | [$k_##301[lq_tmp$x##295:=cow##ax4][VV##607:=VV##20][VV##F##20:=VV##20][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][VV##300:=VV##20][lq_tmp$x##303:=VV##20][VV##F:=VV##20]]}
+  rhs {VV##20 : int | [$k_##262[VV##268:=VV##603][VV##607:=VV##20][VV##F##20:=VV##20][VV##261:=VV##20][VV##F:=VV##20]]}
+  id 20 tag [1]
+  // META constraint id 20 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  lhs {VV##5 : int | [(VV##5 = cow##ax4)]}
+  rhs {VV##5 : int | [$k_##436[lq_tmp$x##425:=wink##ax3][VV##F##5:=VV##5][VV##573:=VV##5][lq_tmp$x##438:=wink##ax3][lq_tmp$x##434:=VV##5][VV##F:=VV##5][VV##435:=VV##5]]}
+  id 5 tag [1]
+  // META constraint id 5 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22;
+       90;
+       93]
+  lhs {VV##21 : int | [$k_##305[lq_tmp$x##295:=cow##ax4][lq_tmp$x##290:=lq_tmp$x##264][VV##304:=VV##21][VV##610:=VV##21][lq_tmp$x##307:=lq_tmp$x##264][lq_tmp$x##291:=VV##603][lq_tmp$x##294:=wink##ax3][lq_tmp$x##303:=VV##21][VV##F##21:=VV##21][VV##F:=VV##21]]}
+  rhs {VV##21 : int | [$k_##266[VV##265:=VV##21][VV##610:=VV##21][VV##268:=VV##603][VV##F##21:=VV##21][VV##F:=VV##21]]}
+  id 21 tag [1]
+  // META constraint id 21 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  lhs {VV##6 : int | [(VV##6 = wink##ax3)]}
+  rhs {VV##6 : int | [$k_##428[VV##F##6:=VV##6][VV##427:=VV##6][lq_tmp$x##430:=VV##6][VV##F:=VV##6][VV##575:=VV##6]]}
+  id 6 tag [1]
+  // META constraint id 6 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  lhs {VV##22 : int | [(VV##22 = cow##ax4)]}
+  rhs {VV##22 : int | [$k_##301[VV##F##22:=VV##22][VV##612:=VV##22][lq_tmp$x##294:=wink##ax3][VV##300:=VV##22][lq_tmp$x##303:=VV##22][VV##F:=VV##22]]}
+  id 22 tag [1]
+  // META constraint id 22 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       35;
+       36;
+       37;
+       38;
+       39]
+  lhs {VV##7 : int | [(VV##7 = cow##ax4)]}
+  rhs {VV##7 : int | [$k_##392[VV##391:=VV##7][VV##F##7:=VV##7][VV##F:=VV##7][VV##577:=VV##7]]}
+  id 7 tag [1]
+  // META constraint id 7 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  lhs {VV##23 : int | [(VV##23 = cow##ax4)]}
+  rhs {VV##23 : int | [$k_##305[VV##304:=VV##23][lq_tmp$x##307:=wink##ax3][VV##612:=VV##23][lq_tmp$x##294:=wink##ax3][lq_tmp$x##303:=VV##23][VV##F:=VV##23][VV##F##23:=VV##23]]}
+  id 23 tag [1]
+  // META constraint id 23 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       29;
+       30;
+       31;
+       32;
+       33]
+  lhs {VV##8 : int | [(VV##8 = wink##ax3)]}
+  rhs {VV##8 : int | [$k_##362[VV##579:=VV##8][VV##F##8:=VV##8][VV##361:=VV##8][VV##F:=VV##8]]}
+  id 8 tag [1]
+  // META constraint id 8 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  lhs {VV##24 : int | [(VV##24 = wink##ax3)]}
+  rhs {VV##24 : int | [$k_##297[lq_tmp$x##299:=VV##24][VV##614:=VV##24][VV##F:=VV##24][VV##296:=VV##24][VV##F##24:=VV##24]]}
+  id 24 tag [1]
+  // META constraint id 24 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16]
+  lhs {VV##25 : int | [(VV##25 = yog##awz)]}
+  rhs {VV##25 : int | [$k_##252[VV##251:=VV##25][lq_tmp$x##254:=VV##25][lq_tmp$x##245:=xig##awy][VV##F:=VV##25][VV##616:=VV##25][VV##F##25:=VV##25]]}
+  id 25 tag [1]
+  // META constraint id 25 : ()
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16]
+  lhs {VV##26 : int | [(VV##26 = xig##awy)]}
+  rhs {VV##26 : int | [$k_##248[VV##618:=VV##26][VV##247:=VV##26][VV##F##26:=VV##26][VV##F:=VV##26][lq_tmp$x##250:=VV##26]]}
+  id 26 tag [1]
+  // META constraint id 26 : ()
+
+
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       115]
+  reft {VV##329 : int | [$k_##330]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25]
+  reft {VV##318 : GHC.Prim.Void# | [$k_##319]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       27;
+       107]
+  reft {VV##343 : int | [$k_##344]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  reft {VV##427 : int | [$k_##428]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16]
+  reft {VV##247 : int | [$k_##248]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       41]
+  reft {VV##435 : int | [$k_##436]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42]
+  reft {VV##443 : int | [$k_##444]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  reft {VV##296 : int | [$k_##297]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       27;
+       110]
+  reft {VV##347 : int | [$k_##348]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40;
+       42;
+       48]
+  reft {VV##473 : int | [$k_##474]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       27]
+  reft {VV##350 : (Tuple  int  int) | [$k_##351]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34]
+  reft {VV##391 : int | [$k_##392]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26]
+  reft {VV##332 : (Tuple  int  int) | [$k_##333]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       120]
+  reft {VV##258 : int | [$k_##259]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       120]
+  reft {VV##261 : int | [$k_##262]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       27;
+       107]
+  reft {VV##340 : int | [$k_##341]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22;
+       23]
+  reft {VV##304 : int | [$k_##305]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       112]
+  reft {VV##325 : int | [$k_##326]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28]
+  reft {VV##361 : int | [$k_##362]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       123]
+  reft {VV##265 : int | [$k_##266]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       24;
+       25;
+       26;
+       112]
+  reft {VV##322 : int | [$k_##323]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       18;
+       19;
+       20;
+       21;
+       22]
+  reft {VV##300 : int | [$k_##301]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17]
+  reft {VV##268 : (Tuple  int  int) | [$k_##269]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15;
+       16;
+       17;
+       28;
+       34;
+       40]
+  reft {VV##431 : int | [$k_##432]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16]
+  reft {VV##251 : int | [$k_##252]}
+  // META wf : ()
diff --git a/liquid-fixpoint/tests/pos/float.fq b/liquid-fixpoint/tests/pos/float.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/float.fq
@@ -0,0 +1,11 @@
+// adapted from LH test Propability.hs
+
+bind 50 x : {v1 : real | [(v1 = 0.2)]}
+bind 56 y : {v2 : real | [(v2 = 0.8 + x)]}
+
+constraint:
+  env [50;
+       56]
+  lhs {VV#F3 : int | []}
+  rhs {VV#F3 : int | [(y = 1.0)]}
+  id 3 tag [1]
diff --git a/liquid-fixpoint/tests/pos/func-arg.fq b/liquid-fixpoint/tests/pos/func-arg.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/func-arg.fq
@@ -0,0 +1,1 @@
+bind 0 foo : {VV : func(0, [func(0, [int])]) | []}
diff --git a/liquid-fixpoint/tests/pos/func00.fq b/liquid-fixpoint/tests/pos/func00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/func00.fq
@@ -0,0 +1,9 @@
+
+bind 0 f : {v: func(0, [int; int]) | []}
+
+constraint:
+  env [ ]
+  lhs {v : int | [f = f]}
+  rhs {v : int | [0 < 7]}
+  id 1 tag []
+
diff --git a/liquid-fixpoint/tests/pos/hex.ts.fq b/liquid-fixpoint/tests/pos/hex.ts.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/hex.ts.fq
@@ -0,0 +1,342 @@
+qualif Bot(v : a): (0 = 1) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Bot(v : obj): (0 = 1) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Bot(v : Boolean): (0 = 1) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Bot(v : int): (0 = 1) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif CmpZ(v : int): (v < 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif CmpZ(v : int): (v <= 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif CmpZ(v : int): (v > 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif CmpZ(v : int): (v >= 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif CmpZ(v : int): (v = 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif CmpZ(v : int): (v != 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Cmp(v : int, x : int): (v < x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Cmp(v : int, x : int): (v <= x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Cmp(v : int, x : int): (v > x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Cmp(v : int, x : int): (v >= x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Cmp(v : a, x : a): (v ~~ x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Cmp(v : a, x : a): (v != x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif True1(v : Boolean): (? Prop([v])) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif False1(v : Boolean): (~ ((? Prop([v])))) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Tag(v : a, x : Str): (ttag([v]) = x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+qualif Len(v : b, w : a): (v < len([w])) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)
+
+
+
+
+constant lit$36$Array : (Str)
+constant lit$36$PI : (Str)
+constant lit$36$documentElement : (Str)
+constant extends_class : (func(1, [@(0); Str; bool]))
+constant numeric_min_value : (int)
+constant numeric_positive_infinity : (int)
+constant lit$36$Document : (Str)
+constant lit$36$Console : (Str)
+constant lit$36$LOG10E : (Str)
+constant lit$36$MAX_VALUE : (Str)
+constant lit$36$Error : (Str)
+constant numeric_nan : (int)
+constant lit$36$Math : (Str)
+constant lit$36$LN2 : (Str)
+constant offset : (func(2, [@(0); Str; @(1)]))
+constant hasDirectProperty : (func(1, [Str; @(0); bool]))
+constant lit$36$Object : (Str)
+constant lit$36$StringConstructor : (Str)
+constant lit$36$object : (Str)
+constant lit$36$NEGATIVE_INFINITY : (Str)
+constant lit$36$BUBBLING_PHASE : (Str)
+constant ttag : (func(1, [@(0); Str]))
+constant lit$36$AT_TARGET : (Str)
+constant lit$36$LN10 : (Str)
+constant lit$36$Event : (Str)
+constant numeric_max_value : (int)
+constant lit$36$CAPTURING_PHASE : (Str)
+constant lit$36$NaN : (Str)
+constant lit$36$undefined : (Str)
+constant lit$36$Function : (Str)
+constant len : (func(2, [(Array  @(0)  @(1)); int]))
+constant extends_interface : (func(1, [@(0); Str; bool]))
+constant numeric_negative_infinity : (int)
+constant lit$36$SQRT1_2 : (Str)
+constant Prop : (func(1, [@(0); bool]))
+constant hasProperty : (func(1, [Str; @(0); bool]))
+constant lit$36$String : (Str)
+constant lit$36$E : (Str)
+constant lit$36$POSITIVE_INFINITY : (Str)
+constant lit$36$MIN_VALUE : (Str)
+constant lit$36$prototype : (Str)
+constant lit$36$SQRT2 : (Str)
+constant lit$36$LOG2E : (Str)
+constant lit$36$Number : (Str)
+constant lit$36$HTMLElement : (Str)
+constant lit$36$number : (Str)
+constant enumProp : (func(1, [Str; @(0); bool]))
+constant lit$36$boolean : (Str)
+constant lit$36$Window : (Str)
+
+
+bind 0 undefined : {v : Undefined | [(ttag([v]) = lit$36$undefined);
+                                     (~ ((? Prop([v]))))]}
+bind 1 Object : {VV$35$285 : Object | [(? Prop([VV$35$285]));
+                                       (ttag([VV$35$285]) = lit$36$object)]}
+bind 2 Object.prototype : {VV : (Object  Immutable) | [(? extends_interface([VV;
+                                                                             lit$36$Object]));
+                                                       (? Prop([VV]));
+                                                       (ttag([VV]) = lit$36$object);
+                                                       (VV ~~ offset([Object; lit$36$prototype]))]}
+bind 3 NaN : {v : int | [(ttag([v]) = lit$36$number);
+                         ((? Prop([v])) <=> (v != 0));
+                         (v = numeric_nan)]}
+bind 4 Number : {VV$35$325 : Object | [(? Prop([VV$35$325]));
+                                       (ttag([VV$35$325]) = lit$36$object)]}
+bind 5 Number.POSITIVE_INFINITY : {v : int | [(ttag([v]) = lit$36$number);
+                                              ((? Prop([v])) <=> (v != 0));
+                                              (v ~~ offset([Number; lit$36$POSITIVE_INFINITY]))]}
+bind 6 Number.MIN_VALUE : {v : int | [(ttag([v]) = lit$36$number);
+                                      ((? Prop([v])) <=> (v != 0));
+                                      (v ~~ offset([Number; lit$36$MIN_VALUE]))]}
+bind 7 Number.prototype : {VV : (Number  Immutable) | [(? extends_interface([VV;
+                                                                             lit$36$Number]));
+                                                       (? Prop([VV]));
+                                                       (ttag([VV]) = lit$36$object);
+                                                       (VV ~~ offset([Number; lit$36$prototype]))]}
+bind 8 Number.NaN : {v : int | [(ttag([v]) = lit$36$number);
+                                ((? Prop([v])) <=> (v != 0));
+                                (v ~~ offset([Number; lit$36$NaN]))]}
+bind 9 Number.NEGATIVE_INFINITY : {v : int | [(ttag([v]) = lit$36$number);
+                                              ((? Prop([v])) <=> (v != 0));
+                                              (v ~~ offset([Number; lit$36$NEGATIVE_INFINITY]))]}
+bind 10 Number.MAX_VALUE : {v : int | [(ttag([v]) = lit$36$number);
+                                       ((? Prop([v])) <=> (v != 0));
+                                       (v ~~ offset([Number; lit$36$MAX_VALUE]))]}
+bind 11 Math : {VV$35$387 : (Math  Immutable) | [(? extends_interface([VV$35$387;
+                                                                       lit$36$Math]));
+                                                 (? Prop([VV$35$387]));
+                                                 (ttag([VV$35$387]) = lit$36$object)]}
+bind 12 Math.SQRT2 : {v : int | [(ttag([v]) = lit$36$number);
+                                 ((? Prop([v])) <=> (v != 0));
+                                 (v ~~ offset([Math; lit$36$SQRT2]))]}
+bind 13 Math.LN2 : {v : int | [(ttag([v]) = lit$36$number);
+                               ((? Prop([v])) <=> (v != 0));
+                               (v ~~ offset([Math; lit$36$LN2]))]}
+bind 14 Math.PI : {v : int | [(ttag([v]) = lit$36$number);
+                              ((? Prop([v])) <=> (v != 0));
+                              (v ~~ offset([Math; lit$36$PI]))]}
+bind 15 Math.LOG10E : {v : int | [(ttag([v]) = lit$36$number);
+                                  ((? Prop([v])) <=> (v != 0));
+                                  (v ~~ offset([Math; lit$36$LOG10E]))]}
+bind 16 Math.LOG2E : {v : int | [(ttag([v]) = lit$36$number);
+                                 ((? Prop([v])) <=> (v != 0));
+                                 (v ~~ offset([Math; lit$36$LOG2E]))]}
+bind 17 Math.E : {v : int | [(ttag([v]) = lit$36$number);
+                             ((? Prop([v])) <=> (v != 0));
+                             (v ~~ offset([Math; lit$36$E]))]}
+bind 18 Math.SQRT1_2 : {v : int | [(ttag([v]) = lit$36$number);
+                                   ((? Prop([v])) <=> (v != 0));
+                                   (v ~~ offset([Math; lit$36$SQRT1_2]))]}
+bind 19 Math.LN10 : {v : int | [(ttag([v]) = lit$36$number);
+                                ((? Prop([v])) <=> (v != 0));
+                                (v ~~ offset([Math; lit$36$LN10]))]}
+bind 20 String : {VV$35$469 : (StringConstructor  Immutable) | [(? extends_interface([VV$35$469;
+                                                                                      lit$36$StringConstructor]));
+                                                                (? Prop([VV$35$469]));
+                                                                (ttag([VV$35$469]) = lit$36$object)]}
+bind 21 String.prototype : {VV : (String  Immutable) | [(? extends_interface([VV;
+                                                                              lit$36$String]));
+                                                        (? Prop([VV]));
+                                                        (ttag([VV]) = lit$36$object);
+                                                        (VV ~~ offset([String; lit$36$prototype]))]}
+bind 22 Array : {VV$35$727 : Object | [(? Prop([VV$35$727]));
+                                       (ttag([VV$35$727]) = lit$36$object)]}
+bind 23 Array.prototype : {VV : (Array  Mutable  Top) | [(? extends_interface([VV;
+                                                                               lit$36$Array]));
+                                                         (? Prop([VV]));
+                                                         (ttag([VV]) = lit$36$object);
+                                                         (VV ~~ offset([Array; lit$36$prototype]))]}
+bind 24 Function : {VV$35$762 : Object | [(? Prop([VV$35$762]));
+                                          (ttag([VV$35$762]) = lit$36$object)]}
+bind 25 Function.prototype : {VV : (Function  Immutable) | [(? extends_interface([VV;
+                                                                                  lit$36$Function]));
+                                                            (? Prop([VV]));
+                                                            (ttag([VV]) = lit$36$object);
+                                                            (VV ~~ offset([Function;
+                                                                           lit$36$prototype]))]}
+bind 26 Console : {VV$35$891 : Object | [(? Prop([VV$35$891]));
+                                         (ttag([VV$35$891]) = lit$36$object)]}
+bind 27 Console.prototype : {VV : (Console  Immutable) | [(? extends_interface([VV;
+                                                                                lit$36$Console]));
+                                                          (? Prop([VV]));
+                                                          (ttag([VV]) = lit$36$object);
+                                                          (VV ~~ offset([Console;
+                                                                         lit$36$prototype]))]}
+bind 28 console : {VV$35$893 : (Console  Immutable) | [(? extends_interface([VV$35$893;
+                                                                             lit$36$Console]));
+                                                       (? Prop([VV$35$893]));
+                                                       (ttag([VV$35$893]) = lit$36$object)]}
+bind 29 Error : {VV$35$983 : Object | [(? Prop([VV$35$983]));
+                                       (ttag([VV$35$983]) = lit$36$object)]}
+bind 30 Error.prototype : {VV : (Error  Immutable) | [(? extends_interface([VV;
+                                                                            lit$36$Error]));
+                                                      (? Prop([VV]));
+                                                      (ttag([VV]) = lit$36$object);
+                                                      (VV ~~ offset([Error; lit$36$prototype]))]}
+bind 31 Event : {VV$35$1025 : Object | [(? Prop([VV$35$1025]));
+                                        (ttag([VV$35$1025]) = lit$36$object)]}
+bind 32 Event.CAPTURING_PHASE : {v : int | [(ttag([v]) = lit$36$number);
+                                            ((? Prop([v])) <=> (v != 0));
+                                            (v ~~ offset([Event; lit$36$CAPTURING_PHASE]))]}
+bind 33 Event.AT_TARGET : {v : int | [(ttag([v]) = lit$36$number);
+                                      ((? Prop([v])) <=> (v != 0));
+                                      (v ~~ offset([Event; lit$36$AT_TARGET]))]}
+bind 34 Event.prototype : {VV : (Event  Immutable) | [(? extends_interface([VV;
+                                                                            lit$36$Event]));
+                                                      (? Prop([VV]));
+                                                      (ttag([VV]) = lit$36$object);
+                                                      (VV ~~ offset([Event; lit$36$prototype]))]}
+bind 35 Event.BUBBLING_PHASE : {v : int | [(ttag([v]) = lit$36$number);
+                                           ((? Prop([v])) <=> (v != 0));
+                                           (v ~~ offset([Event; lit$36$BUBBLING_PHASE]))]}
+bind 36 document : {VV$35$1027 : (Document  Immutable) | [(? extends_interface([VV$35$1027;
+                                                                                lit$36$Document]));
+                                                          (? Prop([VV$35$1027]));
+                                                          (ttag([VV$35$1027]) = lit$36$object)]}
+bind 37 document.documentElement : {VV : (HTMLElement  Immutable) | [(? extends_interface([VV;
+                                                                                           lit$36$HTMLElement]));
+                                                                     (? Prop([VV]));
+                                                                     (ttag([VV]) = lit$36$object);
+                                                                     (VV ~~ offset([document;
+                                                                                    lit$36$documentElement]))]}
+bind 38 window : {VV$35$1031 : (Window  Immutable) | [(? extends_interface([VV$35$1031;
+                                                                            lit$36$Window]));
+                                                      (? Prop([VV$35$1031]));
+                                                      (ttag([VV$35$1031]) = lit$36$object)]}
+bind 39 lq_tmp_nano_1 : {VV : (BitVec  Size32) | [(VV = (lit "#x00000008" (BitVec  Size32)))]}
+bind 40 a_SSA_0 : {VV : (BitVec  Size32) | [(VV ~~ lq_tmp_nano_1);
+                                            (VV = (lit "#x00000008" (BitVec  Size32)))]}
+bind 41 lq_tmp_nano_2 : {VV : (BitVec  Size32) | [(VV = (lit "#x00000008" (BitVec  Size32)))]}
+bind 42 b_SSA_1 : {VV : (BitVec  Size32) | [(VV ~~ lq_tmp_nano_2);
+                                            (VV = (lit "#x00000008" (BitVec  Size32)))]}
+bind 43 lq_tmp_nano_3 : {v : (BitVec  Size32) | [(v = bvor([a_SSA_0;
+                                                            a_SSA_0]))]}
+bind 44 lq_tmp_nano_6 : {v : Boolean | [(ttag([v]) = lit$36$boolean);
+                                        ((? Prop([v])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]}
+bind 45 lq_tmp_nano_9 : {VV$35$4 : Void | []}
+
+
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       39;
+       8;
+       24;
+       40;
+       9;
+       25;
+       41;
+       10;
+       26;
+       42;
+       11;
+       27;
+       43;
+       12;
+       28;
+       44;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV$35$F1 : Boolean | [(ttag([VV$35$F1]) = lit$36$boolean);
+                             (VV$35$F1 ~~ lq_tmp_nano_6);
+                             (ttag([VV$35$F1]) = lit$36$boolean);
+                             ((? Prop([VV$35$F1])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]}
+  rhs {VV$35$F1 : Boolean | [(? Prop([VV$35$F1]))]}
+  id 1 tag [1]
+  // META constraint id 1 : /Users/rjhala/research/stack/liquid/refscript/tests/pos/simple/hex.ts:7:1-7:22
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       39;
+       8;
+       24;
+       40;
+       9;
+       25;
+       41;
+       10;
+       26;
+       42;
+       11;
+       27;
+       43;
+       12;
+       28;
+       44;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV$35$F2 : Boolean | [(ttag([VV$35$F2]) = lit$36$boolean);
+                             (VV$35$F2 ~~ lq_tmp_nano_6);
+                             (ttag([VV$35$F2]) = lit$36$boolean);
+                             ((? Prop([VV$35$F2])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]}
+  rhs {VV$35$F2 : Boolean | [(? Prop([VV$35$F2]))]}
+  id 2 tag [1]
+  // META constraint id 2 : /Users/rjhala/research/stack/liquid/refscript/tests/pos/simple/hex.ts:7:1-7:22
+
+
+
+
+
+
+
+
+
diff --git a/liquid-fixpoint/tests/pos/ho00.fq b/liquid-fixpoint/tests/pos/ho00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/ho00.fq
@@ -0,0 +1,21 @@
+fixpoint "--allowho"
+fixpoint "--eliminate=all"
+
+bind 1 foo : {v : func(0, [Tuple; (MapReduce.List a)]) | []}
+
+constraint:
+  env [ 1 ]
+  lhs {v : int | v = 12 }
+  rhs {v : int | $k0    }
+  id 1 tag [6]
+
+constraint:
+  env [ ]
+  lhs {v : int | $k0    }
+  rhs {v : int | 10 < v }
+  id 2 tag [6]
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
+
diff --git a/liquid-fixpoint/tests/pos/kvar-param-poly-00.fq b/liquid-fixpoint/tests/pos/kvar-param-poly-00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/kvar-param-poly-00.fq
@@ -0,0 +1,26 @@
+
+// a kvar's params can be instantiated / substituted with values of a different
+// type. Here, K0(v:alpha, x:alpha) but is instantiated with int.
+
+qualif Bog(v:a, x:a) : (x = v)
+
+bind 1 x : {v: alpha | true}
+
+bind 2 a : {v: int | v = 10 }
+bind 3 b : {v: int | $k0[x:= a]}
+
+constraint:
+  env [ 1 ]
+  lhs {v : alpha  | v = x }
+  rhs {v : alpha  | $k0   } 
+  id 1 tag []
+
+constraint:
+  env [ 2; 3 ]
+  lhs {v : int | v = b  }
+  rhs {v : int | v = 10 }
+  id 2 tag []
+
+wf:
+  env [ 1 ]
+  reft {v: alpha | $k0}
diff --git a/liquid-fixpoint/tests/pos/len00-rename.fq b/liquid-fixpoint/tests/pos/len00-rename.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/len00-rename.fq
@@ -0,0 +1,24 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+
+qualif ListZ(v : [@(0)]): (len v >= 0)
+
+constant len : (func(2, [(@(0)  @(1)); int]))
+
+bind 0 y : {v : [(Tuple int a)] | [len v >= 0]}
+
+constraint:
+  env [0]
+  lhs {v1 : [(Tuple int a)] | [v1 = y] }
+  rhs {v1 : [(Tuple int a)] | [$k0[v0 := v1]]   }
+  id 1 tag []
+
+constraint:
+  env []
+  lhs {v2 : [(Tuple int a)] | [$k0[v0 := v2]]             }
+  rhs {v2 : [(Tuple int a)] | [len v2 >= 0] }
+  id 2 tag []
+
+wf:
+  env [ ]
+  reft {v0 : [(Tuple int a)] | [$k0] }
diff --git a/liquid-fixpoint/tests/pos/len00.fq b/liquid-fixpoint/tests/pos/len00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/len00.fq
@@ -0,0 +1,24 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+
+qualif ListZ(v : [@(0)]): (len v >= 0)
+
+constant len : (func(2, [(@(0)  @(1)); int]))
+
+bind 0 yoink : {v : [(Tuple int a)] | [len v >= 0]}
+
+constraint:
+  env [0]
+  lhs {v : [(Tuple int a)] | [v = yoink] }
+  rhs {v : [(Tuple int a)] | [$k0]   }
+  id 1 tag []
+
+constraint:
+  env []
+  lhs {v : [(Tuple int a)] | [$k0]             }
+  rhs {v : [(Tuple int a)] | [len v >= 0] }
+  id 2 tag []
+
+wf:
+  env [ ]
+  reft {v : [(Tuple int a)] | [$k0] }
diff --git a/liquid-fixpoint/tests/pos/listqual.hs.fq b/liquid-fixpoint/tests/pos/listqual.hs.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/listqual.hs.fq
@@ -0,0 +1,577 @@
+qualif Append(v : [@(0)], xs : [@(0)], ys : [@(0)]): (len([v]) = (len([xs]) + len([ys]))) // "tests/pos/listqual.hs" (line 3, column 12)
+qualif Fst(v : @(1), y : @(0)): (v = fst([y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 29, column 8)
+qualif Snd(v : @(1), y : @(0)): (v = snd([y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 30, column 8)
+qualif Auto(v : [int]): (len([v]) = 2) // "tests/pos/listqual.hs" (line 10, column 1)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) > 0)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 13, column 8)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) = 0)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 14, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) = 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 16, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) >= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 17, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) > 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 18, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) = len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 20, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) >= len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 21, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) > len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 22, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) <= len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 23, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) < len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 24, column 8)
+qualif EqLen(v : int, xs : [@(0)]): (v = len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 26, column 8)
+qualif LenEq(v : [@(0)], x : int): (x = len([v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 27, column 8)
+qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x + 1)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 28, column 8)
+qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x - 1)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 29, column 8)
+qualif LenAcc(v : int, xs : [@(0)], n : int): (v = (len([xs]) + n)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 30, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 3, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 4, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 5, column 8)
+qualif Bot(v : bool): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 6, column 8)
+qualif Bot(v : int): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 7, column 8)
+qualif CmpZ(v : @(0)): (v < 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 9, column 8)
+qualif CmpZ(v : @(0)): (v <= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 10, column 8)
+qualif CmpZ(v : @(0)): (v > 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 11, column 8)
+qualif CmpZ(v : @(0)): (v >= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 12, column 8)
+qualif CmpZ(v : @(0)): (v = 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 13, column 8)
+qualif CmpZ(v : @(0)): (v != 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 14, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v < x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 16, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v <= x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 17, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v > x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 18, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v >= x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 19, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v = x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 20, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v != x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 21, column 8)
+qualif One(v : int): (v = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 28, column 8)
+qualif True(v : bool): (? v) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 29, column 8)
+qualif False(v : bool): (~ ((? v))) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 30, column 8)
+qualif True1(v : GHC.Types.Bool): (? Prop([v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 31, column 8)
+qualif False1(v : GHC.Types.Bool): (~ ((? Prop([v])))) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 32, column 8)
+qualif Papp(v : @(0), p : (Pred  @(0))): (? papp1([p;
+                                                   v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 35, column 8)
+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): (? papp2([p;
+                                                                    v;
+                                                                    x])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 38, column 8)
+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): (? papp3([p;
+                                                                                    v;
+                                                                                    x;
+                                                                                    y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 41, column 8)
+
+
+cut $k__185
+cut $k__172
+cut $k__178
+cut $k__175
+cut $k__182
+cut $k__162
+cut $k__168
+cut $k__158
+cut $k__165
+
+
+constant runFun : (func(2, [(Arrow  @(0)  @(1)); @(0); @(1)]))
+constant addrLen : (func(0, [int; int]))
+constant xsListSelector : (func(1, [[@(0)]; [@(0)]]))
+constant x_Tuple21 : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant x_Tuple65 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(4)]))
+constant x_Tuple55 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(4)]))
+constant x_Tuple33 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(2)]))
+constant x_Tuple77 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(6)]))
+constant papp3 : (func(6, [(Pred  @(0)  @(1)  @(2));
+                           @(3);
+                           @(4);
+                           @(5);
+                           bool]))
+constant x_Tuple63 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(2)]))
+constant x_Tuple41 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(0)]))
+constant papp4 : (func(8, [(Pred  @(0)  @(1)  @(2)  @(6));
+                           @(3);
+                           @(4);
+                           @(5);
+                           @(7);
+                           bool]))
+constant x_Tuple64 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(3)]))
+constant autolen : (func(1, [@(0); int]))
+constant x_Tuple52 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(1)]))
+constant null : (func(1, [[@(0)]; bool]))
+constant papp2 : (func(4, [(Pred  @(0)  @(1)); @(2); @(3); bool]))
+constant x_Tuple62 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(1)]))
+constant fromJust : (func(1, [(GHC.Base.Maybe  @(0)); @(0)]))
+constant GHC.Types.$91$$93$$35$6m : (func(1, [[@(0)]]))
+constant x_Tuple53 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(2)]))
+constant x_Tuple71 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(0)]))
+constant GHC.Types.$58$$35$64 : (func(1, [@(0); [@(0)]; [@(0)]]))
+constant x_Tuple74 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(3)]))
+constant len : (func(2, [(@(0)  @(1)); int]))
+constant x_Tuple22 : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant x_Tuple66 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(5)]))
+constant x_Tuple44 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(3)]))
+constant xListSelector : (func(1, [[@(0)]; @(0)]))
+constant strLen : (func(0, [int; int]))
+constant x_Tuple72 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(1)]))
+constant isJust : (func(1, [(GHC.Base.Maybe  @(0)); bool]))
+constant Prop : (func(0, [GHC.Types.Bool; bool]))
+constant x_Tuple31 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(0)]))
+constant x_Tuple75 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(4)]))
+constant papp1 : (func(1, [(Pred  @(0)); @(0); bool]))
+constant x_Tuple61 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(0)]))
+constant x_Tuple43 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(2)]))
+constant x_Tuple51 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(0)]))
+constant GHC.Types.I$35$$35$6c : (func(0, [int; int]))
+constant x_Tuple73 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(2)]))
+constant x_Tuple54 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(3)]))
+constant x_Tuple32 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(1)]))
+constant cmp : (func(0, [GHC.Types.Ordering; GHC.Types.Ordering]))
+constant x_Tuple76 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(5)]))
+constant fst : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant snd : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant x_Tuple42 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(1)]))
+
+
+bind 0 GHC.Types.$91$$93$$35$6m : {VV : func(1, [[@(0)]]) | []}
+bind 1 GHC.Types.EQ$35$6U : {VV$35$125 : GHC.Types.Ordering | [(VV$35$125 = GHC.Types.EQ$35$6U)]}
+bind 2 GHC.Types.LT$35$6S : {VV$35$126 : GHC.Types.Ordering | [(VV$35$126 = GHC.Types.LT$35$6S)]}
+bind 3 GHC.Types.GT$35$6W : {VV$35$127 : GHC.Types.Ordering | [(VV$35$127 = GHC.Types.GT$35$6W)]}
+bind 4 GHC.Types.$91$$93$$35$6m : {VV : func(1, [[@(0)]]) | []}
+bind 5 GHC.Types.GT$35$6W : {VV$35$150 : GHC.Types.Ordering | [(cmp([VV$35$150]) = GHC.Types.GT$35$6W)]}
+bind 6 GHC.Types.LT$35$6S : {VV$35$151 : GHC.Types.Ordering | [(cmp([VV$35$151]) = GHC.Types.LT$35$6S)]}
+bind 7 GHC.Types.EQ$35$6U : {VV$35$152 : GHC.Types.Ordering | [(cmp([VV$35$152]) = GHC.Types.EQ$35$6U)]}
+bind 8 GHC.Base.Nothing$35$r1d : {VV : func(1, [(GHC.Base.Maybe  @(0))]) | []}
+bind 9 ds_dwT : {VV$35$164 : [a_awA] | [$k__165;
+                                        (len([VV$35$164]) >= 0)]}
+bind 10 ys$35$awn : {VV$35$174 : [a_awA] | [$k__175[lq_tmp_x_187:=ds_dwT][lq_tmp_x_189:=ds_dwT][ds_dwT:=ds_dwT];
+                                            (len([VV$35$174]) >= 0)]}
+bind 11 lq_anf__dwU : {lq_tmp_x_195 : [a_awA] | [(lq_tmp_x_195 = ds_dwT);
+                                                 (len([lq_tmp_x_195]) >= 0)]}
+bind 12 lq_anf__dwU : {lq_tmp_x_198 : [a_awA] | [(lq_tmp_x_198 = ds_dwT);
+                                                 (len([lq_tmp_x_198]) >= 0);
+                                                 (len([lq_tmp_x_198]) >= 0)]}
+bind 13 lq_anf__dwU : {lq_tmp_x_198 : [a_awA] | [(lq_tmp_x_198 = ds_dwT);
+                                                 (len([lq_tmp_x_198]) >= 0);
+                                                 (len([lq_tmp_x_198]) = 0);
+                                                 ((? null([lq_tmp_x_198])) <=> true);
+                                                 (lq_tmp_x_198 = GHC.Types.$91$$93$$35$6m([]));
+                                                 (len([lq_tmp_x_198]) = 0);
+                                                 ((? null([lq_tmp_x_198])) <=> true);
+                                                 (len([lq_tmp_x_198]) >= 0)]}
+bind 14 lq_anf__dwU : {lq_tmp_x_208 : [a_awA] | [(lq_tmp_x_208 = ds_dwT);
+                                                 (len([lq_tmp_x_208]) >= 0);
+                                                 (len([lq_tmp_x_208]) >= 0)]}
+bind 15 x$35$awo : {VV : a_awA | [$k__158[VV$35$164:=lq_anf__dwU][lq_tmp_x_208:=lq_anf__dwU][lq_tmp_x_195:=lq_anf__dwU][VV$35$157:=VV]]}
+bind 16 xs$35$awp : {lq_tmp_x_218 : [a_awA] | [(len([lq_tmp_x_218]) >= 0)]}
+bind 17 lq_anf__dwU : {lq_tmp_x_208 : [a_awA] | [(lq_tmp_x_208 = ds_dwT);
+                                                 (len([lq_tmp_x_208]) >= 0);
+                                                 (len([lq_tmp_x_208]) = (1 + len([xs$35$awp])));
+                                                 ((? null([lq_tmp_x_208])) <=> false);
+                                                 (xsListSelector([lq_tmp_x_208]) = xs$35$awp);
+                                                 (xListSelector([lq_tmp_x_208]) = x$35$awo);
+                                                 (lq_tmp_x_208 = GHC.Types.$58$$35$64([x$35$awo;
+                                                                                       xs$35$awp]));
+                                                 (len([lq_tmp_x_208]) = (1 + len([xs$35$awp])));
+                                                 ((? null([lq_tmp_x_208])) <=> false);
+                                                 (xsListSelector([lq_tmp_x_208]) = xs$35$awp);
+                                                 (xListSelector([lq_tmp_x_208]) = x$35$awo);
+                                                 (len([lq_tmp_x_208]) >= 0)]}
+bind 18 lq_anf__dwV : {VV$35$184 : [a_awA] | [$k__185[lq_tmp_x_187:=xs$35$awp][lq_tmp_x_189:=xs$35$awp][ds_dwT:=xs$35$awp][lq_tmp_x_188:=ys$35$awn][ys$35$awn:=ys$35$awn][lq_tmp_x_190:=ys$35$awn];
+                                              (len([VV$35$184]) >= 0)]}
+bind 19 lq_tmp_x_259 : {VV : a_awA | []}
+bind 20 lq_anf__dwW : {lq_tmp_x_264 : int | [(lq_tmp_x_264 = (1  :  int))]}
+bind 21 lq_tmp_x_278 : {VV$35$279 : int | []}
+bind 22 lq_anf__dwX : {lq_tmp_x_270 : [int] | [(len([lq_tmp_x_270]) = 0);
+                                               ((? null([lq_tmp_x_270])) <=> true);
+                                               (len([lq_tmp_x_270]) >= 0)]}
+bind 23 lq_tmp_x_296 : {VV$35$297 : int | []}
+bind 24 lq_anf__dwY : {lq_tmp_x_284 : [int] | [(len([lq_tmp_x_284]) = (1 + len([lq_anf__dwX])));
+                                               ((? null([lq_tmp_x_284])) <=> false);
+                                               (xsListSelector([lq_tmp_x_284]) = lq_anf__dwX);
+                                               (xListSelector([lq_tmp_x_284]) = lq_anf__dwW);
+                                               (len([lq_tmp_x_284]) >= 0)]}
+bind 25 lq_anf__dwZ : {lq_tmp_x_305 : int | [(lq_tmp_x_305 = (2  :  int))]}
+bind 26 lq_tmp_x_319 : {VV$35$320 : int | []}
+bind 27 lq_anf__dx0 : {lq_tmp_x_311 : [int] | [(len([lq_tmp_x_311]) = 0);
+                                               ((? null([lq_tmp_x_311])) <=> true);
+                                               (len([lq_tmp_x_311]) >= 0)]}
+bind 28 lq_tmp_x_337 : {VV$35$338 : int | []}
+bind 29 lq_anf__dx1 : {lq_tmp_x_325 : [int] | [(len([lq_tmp_x_325]) = (1 + len([lq_anf__dx0])));
+                                               ((? null([lq_tmp_x_325])) <=> false);
+                                               (xsListSelector([lq_tmp_x_325]) = lq_anf__dx0);
+                                               (xListSelector([lq_tmp_x_325]) = lq_anf__dwZ);
+                                               (len([lq_tmp_x_325]) >= 0)]}
+bind 30 ListQual.boo$35$rlx : {v : [int] | [(len([v]) = 2);
+                                            (len([v]) >= 0)]}
+bind 31 VV$35$368 : {VV$35$368 : [int] | [$k__185[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_187:=lq_anf__dwY][lq_tmp_x_189:=lq_anf__dwY][lq_tmp_x_353:=lq_anf__dwY][ds_dwT:=lq_anf__dwY][lq_tmp_x_350:=VV$35$368][lq_tmp_x_188:=lq_anf__dx1][ys$35$awn:=lq_anf__dx1][VV$35$184:=VV$35$368][lq_tmp_x_190:=lq_anf__dx1];
+                                          (len([VV$35$368]) >= 0)]}
+bind 32 VV$35$368 : {VV$35$368 : [int] | [$k__185[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_187:=lq_anf__dwY][lq_tmp_x_189:=lq_anf__dwY][lq_tmp_x_353:=lq_anf__dwY][ds_dwT:=lq_anf__dwY][lq_tmp_x_350:=VV$35$368][lq_tmp_x_188:=lq_anf__dx1][ys$35$awn:=lq_anf__dx1][VV$35$184:=VV$35$368][lq_tmp_x_190:=lq_anf__dx1];
+                                          (len([VV$35$368]) >= 0)]}
+bind 33 VV$35$371 : {VV$35$371 : int | [$k__356[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_353:=lq_anf__dwY][VV$35$355:=VV$35$371][lq_tmp_x_350:=VV$35$368][lq_tmp_x_358:=VV$35$371];
+                                        $k__178[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_187:=lq_anf__dwY][lq_tmp_x_189:=lq_anf__dwY][lq_tmp_x_353:=lq_anf__dwY][ds_dwT:=lq_anf__dwY][VV$35$177:=VV$35$371][lq_tmp_x_350:=VV$35$368][lq_tmp_x_188:=lq_anf__dx1][ys$35$awn:=lq_anf__dx1][lq_tmp_x_358:=VV$35$371][VV$35$184:=VV$35$368][lq_tmp_x_190:=lq_anf__dx1]]}
+bind 34 VV$35$371 : {VV$35$371 : int | [$k__356[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_353:=lq_anf__dwY][VV$35$355:=VV$35$371][lq_tmp_x_350:=VV$35$368][lq_tmp_x_358:=VV$35$371];
+                                        $k__178[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_187:=lq_anf__dwY][lq_tmp_x_189:=lq_anf__dwY][lq_tmp_x_353:=lq_anf__dwY][ds_dwT:=lq_anf__dwY][VV$35$177:=VV$35$371][lq_tmp_x_350:=VV$35$368][lq_tmp_x_188:=lq_anf__dx1][ys$35$awn:=lq_anf__dx1][lq_tmp_x_358:=VV$35$371][VV$35$184:=VV$35$368][lq_tmp_x_190:=lq_anf__dx1]]}
+bind 35 fldList : {VV$35$374 : int | []}
+bind 36 VV$35$375 : {VV$35$375 : int | [$k__182[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_187:=lq_anf__dwY][lq_tmp_x_189:=lq_anf__dwY][lq_tmp_x_353:=lq_anf__dwY][ds_dwT:=lq_anf__dwY][VV$35$181:=VV$35$375][lq_tmp_x_350:=VV$35$368][lq_tmp_x_188:=lq_anf__dx1][ys$35$awn:=lq_anf__dx1][lq_tmp_x_180:=fldList][lq_tmp_x_349:=fldList][lq_tmp_x_358:=VV$35$375][VV$35$184:=VV$35$368][lq_tmp_x_190:=lq_anf__dx1]]}
+bind 37 VV$35$375 : {VV$35$375 : int | [$k__182[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_187:=lq_anf__dwY][lq_tmp_x_189:=lq_anf__dwY][lq_tmp_x_353:=lq_anf__dwY][ds_dwT:=lq_anf__dwY][VV$35$181:=VV$35$375][lq_tmp_x_350:=VV$35$368][lq_tmp_x_188:=lq_anf__dx1][ys$35$awn:=lq_anf__dx1][lq_tmp_x_180:=fldList][lq_tmp_x_349:=fldList][lq_tmp_x_358:=VV$35$375][VV$35$184:=VV$35$368][lq_tmp_x_190:=lq_anf__dx1]]}
+bind 38 VV$35$378 : {VV$35$378 : [int] | [(VV$35$378 = lq_anf__dx1);
+                                          (len([VV$35$378]) >= 0)]}
+bind 39 VV$35$378 : {VV$35$378 : [int] | [(VV$35$378 = lq_anf__dx1);
+                                          (len([VV$35$378]) >= 0)]}
+bind 40 VV$35$381 : {VV$35$381 : int | [$k__331[lq_tmp_x_329:=lq_anf__dx0][lq_tmp_x_363:=VV$35$381][VV$35$330:=VV$35$381][lq_tmp_x_366:=VV$35$378][lq_tmp_x_328:=lq_anf__dwZ][lq_tmp_x_333:=VV$35$381][lq_tmp_x_325:=VV$35$378]]}
+bind 41 VV$35$381 : {VV$35$381 : int | [$k__331[lq_tmp_x_329:=lq_anf__dx0][lq_tmp_x_363:=VV$35$381][VV$35$330:=VV$35$381][lq_tmp_x_366:=VV$35$378][lq_tmp_x_328:=lq_anf__dwZ][lq_tmp_x_333:=VV$35$381][lq_tmp_x_325:=VV$35$378]]}
+bind 42 lq_tmp_x_347 : {VV$35$384 : int | []}
+bind 43 VV$35$385 : {VV$35$385 : int | [$k__335[lq_tmp_x_365:=VV$35$385][lq_tmp_x_329:=lq_anf__dx0][lq_tmp_x_324:=lq_tmp_x_347][lq_tmp_x_364:=lq_tmp_x_347][lq_tmp_x_366:=VV$35$378][lq_tmp_x_328:=lq_anf__dwZ][lq_tmp_x_333:=VV$35$385][lq_tmp_x_337:=lq_tmp_x_347][lq_tmp_x_325:=VV$35$378][VV$35$334:=VV$35$385]]}
+bind 44 VV$35$385 : {VV$35$385 : int | [$k__335[lq_tmp_x_365:=VV$35$385][lq_tmp_x_329:=lq_anf__dx0][lq_tmp_x_324:=lq_tmp_x_347][lq_tmp_x_364:=lq_tmp_x_347][lq_tmp_x_366:=VV$35$378][lq_tmp_x_328:=lq_anf__dwZ][lq_tmp_x_333:=VV$35$385][lq_tmp_x_337:=lq_tmp_x_347][lq_tmp_x_325:=VV$35$378][VV$35$334:=VV$35$385]]}
+bind 45 VV$35$388 : {VV$35$388 : [int] | [(VV$35$388 = lq_anf__dwY);
+                                          (len([VV$35$388]) >= 0)]}
+bind 46 VV$35$388 : {VV$35$388 : [int] | [(VV$35$388 = lq_anf__dwY);
+                                          (len([VV$35$388]) >= 0)]}
+bind 47 VV$35$391 : {VV$35$391 : int | [$k__290[VV$35$289:=VV$35$391][lq_tmp_x_288:=lq_anf__dwX][lq_tmp_x_292:=VV$35$391][lq_tmp_x_362:=VV$35$388][lq_tmp_x_359:=VV$35$391][lq_tmp_x_284:=VV$35$388][lq_tmp_x_287:=lq_anf__dwW]]}
+bind 48 VV$35$391 : {VV$35$391 : int | [$k__290[VV$35$289:=VV$35$391][lq_tmp_x_288:=lq_anf__dwX][lq_tmp_x_292:=VV$35$391][lq_tmp_x_362:=VV$35$388][lq_tmp_x_359:=VV$35$391][lq_tmp_x_284:=VV$35$388][lq_tmp_x_287:=lq_anf__dwW]]}
+bind 49 lq_tmp_x_345 : {VV$35$394 : int | []}
+bind 50 VV$35$395 : {VV$35$395 : int | [$k__294[lq_tmp_x_361:=VV$35$395][lq_tmp_x_288:=lq_anf__dwX][lq_tmp_x_360:=lq_tmp_x_345][VV$35$293:=VV$35$395][lq_tmp_x_292:=VV$35$395][lq_tmp_x_362:=VV$35$388][lq_tmp_x_296:=lq_tmp_x_345][lq_tmp_x_283:=lq_tmp_x_345][lq_tmp_x_284:=VV$35$388][lq_tmp_x_287:=lq_anf__dwW]]}
+bind 51 VV$35$395 : {VV$35$395 : int | [$k__294[lq_tmp_x_361:=VV$35$395][lq_tmp_x_288:=lq_anf__dwX][lq_tmp_x_360:=lq_tmp_x_345][VV$35$293:=VV$35$395][lq_tmp_x_292:=VV$35$395][lq_tmp_x_362:=VV$35$388][lq_tmp_x_296:=lq_tmp_x_345][lq_tmp_x_283:=lq_tmp_x_345][lq_tmp_x_284:=VV$35$388][lq_tmp_x_287:=lq_anf__dwW]]}
+bind 52 VV$35$398 : {VV$35$398 : [int] | [(VV$35$398 = lq_anf__dx0);
+                                          (len([VV$35$398]) >= 0)]}
+bind 53 VV$35$398 : {VV$35$398 : [int] | [(VV$35$398 = lq_anf__dx0);
+                                          (len([VV$35$398]) >= 0)]}
+bind 54 VV$35$401 : {VV$35$401 : int | [$k__313[lq_tmp_x_340:=VV$35$401][lq_tmp_x_343:=VV$35$398][VV$35$312:=VV$35$401][lq_tmp_x_311:=VV$35$398][lq_tmp_x_315:=VV$35$401]]}
+bind 55 VV$35$401 : {VV$35$401 : int | [$k__313[lq_tmp_x_340:=VV$35$401][lq_tmp_x_343:=VV$35$398][VV$35$312:=VV$35$401][lq_tmp_x_311:=VV$35$398][lq_tmp_x_315:=VV$35$401]]}
+bind 56 lq_tmp_x_322 : {VV$35$404 : int | []}
+bind 57 VV$35$405 : {VV$35$405 : int | [$k__317[lq_tmp_x_342:=VV$35$405][lq_tmp_x_343:=VV$35$398][lq_tmp_x_341:=lq_tmp_x_322][VV$35$316:=VV$35$405][lq_tmp_x_319:=lq_tmp_x_322][lq_tmp_x_311:=VV$35$398][lq_tmp_x_310:=lq_tmp_x_322][lq_tmp_x_315:=VV$35$405]]}
+bind 58 VV$35$405 : {VV$35$405 : int | [$k__317[lq_tmp_x_342:=VV$35$405][lq_tmp_x_343:=VV$35$398][lq_tmp_x_341:=lq_tmp_x_322][VV$35$316:=VV$35$405][lq_tmp_x_319:=lq_tmp_x_322][lq_tmp_x_311:=VV$35$398][lq_tmp_x_310:=lq_tmp_x_322][lq_tmp_x_315:=VV$35$405]]}
+bind 59 VV$35$408 : {VV$35$408 : int | [(VV$35$408 = lq_anf__dwZ)]}
+bind 60 VV$35$408 : {VV$35$408 : int | [(VV$35$408 = lq_anf__dwZ)]}
+bind 61 VV$35$411 : {VV$35$411 : int | [(VV$35$411 = 2)]}
+bind 62 VV$35$411 : {VV$35$411 : int | [(VV$35$411 = 2)]}
+bind 63 VV$35$414 : {VV$35$414 : [int] | [(VV$35$414 = lq_anf__dwX);
+                                          (len([VV$35$414]) >= 0)]}
+bind 64 VV$35$414 : {VV$35$414 : [int] | [(VV$35$414 = lq_anf__dwX);
+                                          (len([VV$35$414]) >= 0)]}
+bind 65 VV$35$417 : {VV$35$417 : int | [$k__272[lq_tmp_x_274:=VV$35$417][VV$35$271:=VV$35$417][lq_tmp_x_302:=VV$35$414][lq_tmp_x_299:=VV$35$417][lq_tmp_x_270:=VV$35$414]]}
+bind 66 VV$35$417 : {VV$35$417 : int | [$k__272[lq_tmp_x_274:=VV$35$417][VV$35$271:=VV$35$417][lq_tmp_x_302:=VV$35$414][lq_tmp_x_299:=VV$35$417][lq_tmp_x_270:=VV$35$414]]}
+bind 67 lq_tmp_x_281 : {VV$35$420 : int | []}
+bind 68 VV$35$421 : {VV$35$421 : int | [$k__276[lq_tmp_x_269:=lq_tmp_x_281][VV$35$275:=VV$35$421][lq_tmp_x_274:=VV$35$421][lq_tmp_x_301:=VV$35$421][lq_tmp_x_302:=VV$35$414][lq_tmp_x_300:=lq_tmp_x_281][lq_tmp_x_278:=lq_tmp_x_281][lq_tmp_x_270:=VV$35$414]]}
+bind 69 VV$35$421 : {VV$35$421 : int | [$k__276[lq_tmp_x_269:=lq_tmp_x_281][VV$35$275:=VV$35$421][lq_tmp_x_274:=VV$35$421][lq_tmp_x_301:=VV$35$421][lq_tmp_x_302:=VV$35$414][lq_tmp_x_300:=lq_tmp_x_281][lq_tmp_x_278:=lq_tmp_x_281][lq_tmp_x_270:=VV$35$414]]}
+bind 70 VV$35$424 : {VV$35$424 : int | [(VV$35$424 = lq_anf__dwW)]}
+bind 71 VV$35$424 : {VV$35$424 : int | [(VV$35$424 = lq_anf__dwW)]}
+bind 72 VV$35$427 : {VV$35$427 : int | [(VV$35$427 = 1)]}
+bind 73 VV$35$427 : {VV$35$427 : int | [(VV$35$427 = 1)]}
+bind 74 VV$35$430 : {VV$35$430 : [a_awA] | [(len([VV$35$430]) = (1 + len([lq_anf__dwV])));
+                                            ((? null([VV$35$430])) <=> false);
+                                            (xsListSelector([VV$35$430]) = lq_anf__dwV);
+                                            (xListSelector([VV$35$430]) = x$35$awo);
+                                            (len([VV$35$430]) >= 0)]}
+bind 75 VV$35$430 : {VV$35$430 : [a_awA] | [(len([VV$35$430]) = (1 + len([lq_anf__dwV])));
+                                            ((? null([VV$35$430])) <=> false);
+                                            (xsListSelector([VV$35$430]) = lq_anf__dwV);
+                                            (xListSelector([VV$35$430]) = x$35$awo);
+                                            (len([VV$35$430]) >= 0)]}
+bind 76 VV$35$253 : {VV$35$253 : a_awA | [$k__254[lq_tmp_x_252:=lq_anf__dwV][lq_tmp_x_248:=VV$35$430][lq_tmp_x_251:=x$35$awo]]}
+bind 77 lq_tmp_x_180 : {VV : a_awA | []}
+bind 78 VV$35$253 : {VV$35$253 : a_awA | [$k__257[lq_tmp_x_252:=lq_anf__dwV][VV$35$256:=VV$35$253][lq_tmp_x_248:=VV$35$430][lq_tmp_x_259:=lq_tmp_x_180][lq_tmp_x_247:=lq_tmp_x_180][lq_tmp_x_251:=x$35$awo]]}
+bind 79 VV$35$436 : {VV$35$436 : [a_awA] | [(VV$35$436 = lq_anf__dwV);
+                                            (len([VV$35$436]) >= 0)]}
+bind 80 VV$35$436 : {VV$35$436 : [a_awA] | [(VV$35$436 = lq_anf__dwV);
+                                            (len([VV$35$436]) >= 0)]}
+bind 81 VV$35$237 : {VV$35$237 : a_awA | [$k__238[lq_tmp_x_262:=VV$35$436][lq_tmp_x_189:=xs$35$awp][VV$35$184:=VV$35$436][lq_tmp_x_190:=ys$35$awn];
+                                          $k__178[lq_tmp_x_262:=VV$35$436][lq_tmp_x_187:=xs$35$awp][lq_tmp_x_189:=xs$35$awp][ds_dwT:=xs$35$awp][VV$35$177:=VV$35$237][lq_tmp_x_188:=ys$35$awn][ys$35$awn:=ys$35$awn][VV$35$184:=VV$35$436][lq_tmp_x_190:=ys$35$awn]]}
+bind 82 lq_tmp_x_245 : {VV : a_awA | []}
+bind 83 VV$35$237 : {VV$35$237 : a_awA | [$k__182[lq_tmp_x_262:=VV$35$436][lq_tmp_x_187:=xs$35$awp][lq_tmp_x_189:=xs$35$awp][ds_dwT:=xs$35$awp][VV$35$181:=VV$35$237][lq_tmp_x_261:=lq_tmp_x_245][lq_tmp_x_188:=ys$35$awn][ys$35$awn:=ys$35$awn][lq_tmp_x_180:=lq_tmp_x_245][VV$35$184:=VV$35$436][lq_tmp_x_190:=ys$35$awn]]}
+bind 84 VV : {VV : a_awA | [(VV = x$35$awo)]}
+bind 85 VV$35$443 : {VV$35$443 : [a_awA] | [(VV$35$443 = ys$35$awn);
+                                            (len([VV$35$443]) >= 0)]}
+bind 86 VV$35$443 : {VV$35$443 : [a_awA] | [(VV$35$443 = ys$35$awn);
+                                            (len([VV$35$443]) >= 0)]}
+bind 87 VV : {VV : a_awA | [$k__168[lq_tmp_x_187:=ds_dwT][VV$35$167:=VV][lq_tmp_x_189:=ds_dwT][ds_dwT:=ds_dwT][lq_tmp_x_243:=VV$35$443][VV$35$174:=VV$35$443]]}
+bind 88 lq_tmp_x_170 : {VV : a_awA | []}
+bind 89 VV : {VV : a_awA | [$k__172[lq_tmp_x_187:=ds_dwT][lq_tmp_x_189:=ds_dwT][lq_tmp_x_242:=lq_tmp_x_170][ds_dwT:=ds_dwT][lq_tmp_x_243:=VV$35$443][lq_tmp_x_170:=lq_tmp_x_170][VV$35$174:=VV$35$443][VV$35$171:=VV]]}
+bind 90 VV$35$449 : {VV$35$449 : [a_awA] | [(VV$35$449 = xs$35$awp);
+                                            (len([VV$35$449]) >= 0)]}
+bind 91 VV$35$449 : {VV$35$449 : [a_awA] | [(VV$35$449 = xs$35$awp);
+                                            (len([VV$35$449]) >= 0)]}
+bind 92 VV : {VV : a_awA | [$k__158[lq_tmp_x_215:=x$35$awo][lq_tmp_x_218:=VV$35$449][VV$35$164:=lq_anf__dwU][lq_tmp_x_208:=lq_anf__dwU][lq_tmp_x_241:=VV$35$449][lq_tmp_x_195:=lq_anf__dwU][VV$35$157:=VV];
+                            $k__162[lq_tmp_x_215:=x$35$awo][lq_tmp_x_218:=VV$35$449][VV$35$164:=lq_anf__dwU][lq_tmp_x_207:=x$35$awo][lq_tmp_x_208:=lq_anf__dwU][VV$35$161:=VV][lq_tmp_x_160:=x$35$awo][lq_tmp_x_241:=VV$35$449][lq_tmp_x_195:=lq_anf__dwU][lq_tmp_x_194:=x$35$awo]]}
+bind 93 lq_tmp_x_160 : {VV : a_awA | []}
+bind 94 VV : {VV : a_awA | [$k__162[lq_tmp_x_215:=x$35$awo][lq_tmp_x_218:=VV$35$449][VV$35$164:=lq_anf__dwU][lq_tmp_x_207:=lq_tmp_x_160][lq_tmp_x_208:=lq_anf__dwU][VV$35$161:=VV][lq_tmp_x_160:=lq_tmp_x_160][lq_tmp_x_241:=VV$35$449][lq_tmp_x_217:=lq_tmp_x_160][lq_tmp_x_195:=lq_anf__dwU][lq_tmp_x_240:=lq_tmp_x_160][lq_tmp_x_194:=lq_tmp_x_160]]}
+bind 95 VV$35$455 : {VV$35$455 : [a_awA] | [(VV$35$455 = ys$35$awn);
+                                            (len([VV$35$455]) >= 0)]}
+bind 96 VV$35$455 : {VV$35$455 : [a_awA] | [(VV$35$455 = ys$35$awn);
+                                            (len([VV$35$455]) >= 0)]}
+bind 97 VV : {VV : a_awA | [$k__168[lq_tmp_x_187:=ds_dwT][VV$35$167:=VV][lq_tmp_x_189:=ds_dwT][lq_tmp_x_206:=VV$35$455][ds_dwT:=ds_dwT][VV$35$174:=VV$35$455]]}
+bind 98 lq_tmp_x_180 : {VV : a_awA | []}
+bind 99 VV : {VV : a_awA | [$k__172[lq_tmp_x_187:=ds_dwT][lq_tmp_x_189:=ds_dwT][lq_tmp_x_206:=VV$35$455][ds_dwT:=ds_dwT][lq_tmp_x_205:=lq_tmp_x_180][lq_tmp_x_170:=lq_tmp_x_180][VV$35$174:=VV$35$455][VV$35$171:=VV]]}
+bind 100 VV$35$355 : {VV$35$355 : int | [$k__356]}
+bind 101 VV$35$334 : {VV$35$334 : int | [$k__335]}
+bind 102 VV$35$330 : {VV$35$330 : int | [$k__331]}
+bind 103 VV$35$316 : {VV$35$316 : int | [$k__317]}
+bind 104 VV$35$312 : {VV$35$312 : int | [$k__313]}
+bind 105 VV$35$293 : {VV$35$293 : int | [$k__294]}
+bind 106 VV$35$289 : {VV$35$289 : int | [$k__290]}
+bind 107 VV$35$275 : {VV$35$275 : int | [$k__276]}
+bind 108 VV$35$271 : {VV$35$271 : int | [$k__272]}
+bind 109 VV$35$164 : {VV$35$164 : [a_awA] | [$k__165;
+                                             (len([VV$35$164]) >= 0)]}
+bind 110 lq_tmp_x_160 : {VV : a_awA | []}
+bind 111 ds_dwT : {VV$35$164 : [a_awA] | [$k__165;
+                                          (len([VV$35$164]) >= 0)]}
+bind 112 VV$35$174 : {VV$35$174 : [a_awA] | [$k__175;
+                                             (len([VV$35$174]) >= 0)]}
+bind 113 lq_tmp_x_170 : {VV : a_awA | []}
+bind 114 ys$35$awn : {VV$35$174 : [a_awA] | [$k__175;
+                                             (len([VV$35$174]) >= 0)]}
+bind 115 VV$35$184 : {VV$35$184 : [a_awA] | [$k__185;
+                                             (len([VV$35$184]) >= 0)]}
+bind 116 lq_tmp_x_180 : {VV : a_awA | []}
+
+
+
+
+constraint:
+  env [0; 64; 1; 2; 3; 67; 4; 20; 68; 5; 6; 22; 7; 8]
+  lhs {VV$35$F16 : int | [$k__276[VV$35$421:=VV$35$F16][lq_tmp_x_269:=lq_tmp_x_281][VV$35$275:=VV$35$F16][lq_tmp_x_274:=VV$35$F16][lq_tmp_x_301:=VV$35$F16][VV$35$F:=VV$35$F16][lq_tmp_x_302:=VV$35$414][lq_tmp_x_300:=lq_tmp_x_281][lq_tmp_x_278:=lq_tmp_x_281][lq_tmp_x_270:=VV$35$414]]}
+  rhs {VV$35$F16 : int | [$k__294[VV$35$421:=VV$35$F16][lq_tmp_x_282:=VV$35$414][VV$35$F:=VV$35$F16][VV$35$293:=VV$35$F16][lq_tmp_x_292:=VV$35$F16][lq_tmp_x_296:=lq_tmp_x_281][lq_tmp_x_287:=lq_anf__dwW]]}
+  id 16 tag [2]
+  // META constraint id 16 : tests/pos/listqual.hs:10:1-3
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 20; 5; 6; 22; 7; 8; 24; 25; 27; 29; 31]
+  lhs {VV$35$F1 : [int] | [$k__185[lq_tmp_x_354:=lq_anf__dx1][lq_tmp_x_187:=lq_anf__dwY][lq_tmp_x_189:=lq_anf__dwY][lq_tmp_x_353:=lq_anf__dwY][ds_dwT:=lq_anf__dwY][VV$35$F:=VV$35$F1][lq_tmp_x_350:=VV$35$F1][VV$35$368:=VV$35$F1][lq_tmp_x_188:=lq_anf__dx1][ys$35$awn:=lq_anf__dx1][VV$35$184:=VV$35$F1][lq_tmp_x_190:=lq_anf__dx1];
+                           (len([VV$35$F1]) >= 0)]}
+  rhs {VV$35$F1 : [int] | [(len([VV$35$F1]) = 2)]}
+  id 1 tag [2]
+  // META constraint id 1 : tests/pos/listqual.hs:10:1-20
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 20; 5; 6; 22; 70; 7; 8]
+  lhs {VV$35$F17 : int | [(VV$35$F17 = lq_anf__dwW)]}
+  rhs {VV$35$F17 : int | [$k__290[VV$35$424:=VV$35$F17][VV$35$289:=VV$35$F17][VV$35$F:=VV$35$F17][lq_tmp_x_292:=VV$35$F17]]}
+  id 17 tag [2]
+  // META constraint id 17 : tests/pos/listqual.hs:10:15
+
+
+constraint:
+  env [0; 16; 1; 17; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 91; 92; 14; 15]
+  lhs {VV$35$F33 : a_awA | [$k__158[lq_tmp_x_215:=x$35$awo][VV:=VV$35$F33][lq_tmp_x_218:=VV$35$449][VV$35$164:=lq_anf__dwU][lq_tmp_x_208:=lq_anf__dwU][lq_tmp_x_241:=VV$35$449][VV$35$F:=VV$35$F33][lq_tmp_x_195:=lq_anf__dwU][VV$35$157:=VV$35$F33];
+                            $k__162[lq_tmp_x_215:=x$35$awo][VV:=VV$35$F33][lq_tmp_x_218:=VV$35$449][VV$35$164:=lq_anf__dwU][lq_tmp_x_207:=x$35$awo][lq_tmp_x_208:=lq_anf__dwU][VV$35$161:=VV$35$F33][lq_tmp_x_160:=x$35$awo][lq_tmp_x_241:=VV$35$449][VV$35$F:=VV$35$F33][lq_tmp_x_195:=lq_anf__dwU][lq_tmp_x_194:=x$35$awo]]}
+  rhs {VV$35$F33 : a_awA | [$k__158[VV$35$164:=VV$35$449][VV$35$F:=VV$35$F33][VV$35$237:=VV$35$F33][VV$35$157:=VV$35$F33]]}
+  id 33 tag [1]
+  // META constraint id 33 : tests/pos/listqual.hs:6:31-32
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 20; 5; 6; 22; 38; 7; 8; 24; 25; 27; 29]
+  lhs {VV$35$F2 : [int] | [(VV$35$F2 = lq_anf__dx1);
+                           (len([VV$35$F2]) >= 0)]}
+  rhs {VV$35$F2 : [int] | [$k__175[lq_tmp_x_187:=lq_anf__dwY][lq_tmp_x_189:=lq_anf__dwY][lq_tmp_x_353:=lq_anf__dwY][ds_dwT:=lq_anf__dwY][VV$35$F:=VV$35$F2][lq_tmp_x_348:=VV$35$F2][VV$35$174:=VV$35$F2][VV$35$378:=VV$35$F2]]}
+  id 2 tag [2]
+  // META constraint id 2 : tests/pos/listqual.hs:10:18-20
+
+
+constraint:
+  env [0; 16; 1; 17; 2; 18; 3; 4; 5; 6; 7; 8; 9; 10; 74; 11; 14; 15]
+  lhs {VV$35$F18 : [a_awA] | [(len([VV$35$F18]) = (1 + len([lq_anf__dwV])));
+                              ((? null([VV$35$F18])) <=> false);
+                              (xsListSelector([VV$35$F18]) = lq_anf__dwV);
+                              (xListSelector([VV$35$F18]) = x$35$awo);
+                              (len([VV$35$F18]) >= 0)]}
+  rhs {VV$35$F18 : [a_awA] | [$k__185[lq_tmp_x_187:=ds_dwT][lq_tmp_x_189:=ds_dwT][VV$35$430:=VV$35$F18][ds_dwT:=ds_dwT][VV$35$F:=VV$35$F18][lq_tmp_x_188:=ys$35$awn][ys$35$awn:=ys$35$awn][VV$35$184:=VV$35$F18][lq_tmp_x_190:=ys$35$awn]]}
+  id 18 tag [1]
+  // META constraint id 18 : tests/pos/listqual.hs:6:20-35
+
+
+constraint:
+  env [0;
+       16;
+       1;
+       17;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       93;
+       14;
+       94;
+       15]
+  lhs {VV$35$F34 : a_awA | [$k__162[lq_tmp_x_215:=x$35$awo][VV:=VV$35$F34][lq_tmp_x_218:=VV$35$449][VV$35$164:=lq_anf__dwU][lq_tmp_x_207:=lq_tmp_x_160][lq_tmp_x_208:=lq_anf__dwU][VV$35$161:=VV$35$F34][lq_tmp_x_160:=lq_tmp_x_160][lq_tmp_x_241:=VV$35$449][VV$35$F:=VV$35$F34][lq_tmp_x_217:=lq_tmp_x_160][lq_tmp_x_195:=lq_anf__dwU][lq_tmp_x_240:=lq_tmp_x_160][lq_tmp_x_194:=lq_tmp_x_160]]}
+  rhs {VV$35$F34 : a_awA | [$k__162[VV$35$164:=VV$35$449][VV$35$161:=VV$35$F34][VV$35$F:=VV$35$F34][VV$35$237:=VV$35$F34]]}
+  id 34 tag [1]
+  // META constraint id 34 : tests/pos/listqual.hs:6:31-32
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 95]
+  lhs {VV$35$F35 : [a_awA] | [(VV$35$F35 = ys$35$awn);
+                              (len([VV$35$F35]) >= 0)]}
+  rhs {VV$35$F35 : [a_awA] | [$k__185[lq_tmp_x_187:=ds_dwT][lq_tmp_x_189:=ds_dwT][ds_dwT:=ds_dwT][VV$35$F:=VV$35$F35][VV$35$455:=VV$35$F35][lq_tmp_x_188:=ys$35$awn][ys$35$awn:=ys$35$awn][VV$35$184:=VV$35$F35][lq_tmp_x_190:=ys$35$awn]]}
+  id 35 tag [1]
+  // META constraint id 35 : tests/pos/listqual.hs:5:20-21
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 20; 5; 6; 22; 7; 8; 24; 25; 27; 29; 45]
+  lhs {VV$35$F6 : [int] | [(VV$35$F6 = lq_anf__dwY);
+                           (len([VV$35$F6]) >= 0)]}
+  rhs {VV$35$F6 : [int] | [$k__165[VV$35$164:=VV$35$F6][VV$35$F:=VV$35$F6][lq_tmp_x_346:=VV$35$F6][VV$35$388:=VV$35$F6]]}
+  id 6 tag [2]
+  // META constraint id 6 : tests/pos/listqual.hs:10:14-16
+
+
+constraint:
+  env [0; 1; 2; 3; 4; 20; 5; 6; 22; 7; 8; 24; 25; 27; 29; 46; 47]
+  lhs {VV$35$F8 : int | [$k__290[VV$35$289:=VV$35$F8][lq_tmp_x_288:=lq_anf__dwX][VV$35$F:=VV$35$F8][lq_tmp_x_292:=VV$35$F8][lq_tmp_x_362:=VV$35$388][lq_tmp_x_359:=VV$35$F8][lq_tmp_x_284:=VV$35$388][VV$35$391:=VV$35$F8][lq_tmp_x_287:=lq_anf__dwW]]}
+  rhs {VV$35$F8 : int | [$k__158[VV$35$164:=VV$35$388][VV$35$F:=VV$35$F8][lq_tmp_x_346:=VV$35$388][VV$35$157:=VV$35$F8][lq_tmp_x_358:=VV$35$F8][VV$35$391:=VV$35$F8]]}
+  id 8 tag [2]
+  // META constraint id 8 : tests/pos/listqual.hs:10:14-16
+
+
+constraint:
+  env [0; 1; 49; 2; 50; 3; 4; 20; 5; 6; 22; 7; 8; 24; 25; 27; 29; 46]
+  lhs {VV$35$F9 : int | [$k__294[lq_tmp_x_361:=VV$35$F9][lq_tmp_x_288:=lq_anf__dwX][VV$35$F:=VV$35$F9][lq_tmp_x_360:=lq_tmp_x_345][VV$35$293:=VV$35$F9][lq_tmp_x_292:=VV$35$F9][VV$35$395:=VV$35$F9][lq_tmp_x_362:=VV$35$388][lq_tmp_x_296:=lq_tmp_x_345][lq_tmp_x_283:=lq_tmp_x_345][lq_tmp_x_284:=VV$35$388][lq_tmp_x_287:=lq_anf__dwW]]}
+  rhs {VV$35$F9 : int | [$k__162[VV$35$164:=VV$35$388][VV$35$161:=VV$35$F9][lq_tmp_x_160:=lq_tmp_x_345][VV$35$F:=VV$35$F9][lq_tmp_x_346:=VV$35$388][VV$35$395:=VV$35$F9][lq_tmp_x_358:=VV$35$F9]]}
+  id 9 tag [2]
+  // META constraint id 9 : tests/pos/listqual.hs:10:14-16
+
+
+constraint:
+  env [0; 16; 1; 17; 2; 3; 4; 5; 85; 6; 7; 8; 9; 10; 11; 14; 15]
+  lhs {VV$35$F25 : [a_awA] | [(VV$35$F25 = ys$35$awn);
+                              (len([VV$35$F25]) >= 0)]}
+  rhs {VV$35$F25 : [a_awA] | [$k__175[lq_tmp_x_187:=xs$35$awp][lq_tmp_x_189:=xs$35$awp][ds_dwT:=xs$35$awp][VV$35$F:=VV$35$F25][VV$35$174:=VV$35$F25][VV$35$443:=VV$35$F25]]}
+  id 25 tag [1]
+  // META constraint id 25 : tests/pos/listqual.hs:6:34-35
+
+
+constraint:
+  env [0; 16; 1; 17; 2; 3; 4; 5; 6; 7; 8; 9; 10; 90; 11; 14; 15]
+  lhs {VV$35$F29 : [a_awA] | [(VV$35$F29 = xs$35$awp);
+                              (len([VV$35$F29]) >= 0)]}
+  rhs {VV$35$F29 : [a_awA] | [$k__165[VV$35$164:=VV$35$F29][VV$35$F:=VV$35$F29][VV$35$449:=VV$35$F29]]}
+  id 29 tag [1]
+  // META constraint id 29 : tests/pos/listqual.hs:6:31-32
+
+
+constraint:
+  env [0; 64; 1; 65; 2; 3; 4; 20; 5; 6; 22; 7; 8]
+  lhs {VV$35$F14 : int | [$k__272[lq_tmp_x_274:=VV$35$F14][VV$35$271:=VV$35$F14][VV$35$F:=VV$35$F14][lq_tmp_x_302:=VV$35$414][VV$35$417:=VV$35$F14][lq_tmp_x_299:=VV$35$F14][lq_tmp_x_270:=VV$35$414]]}
+  rhs {VV$35$F14 : int | [$k__290[lq_tmp_x_282:=VV$35$414][VV$35$289:=VV$35$F14][VV$35$F:=VV$35$F14][VV$35$417:=VV$35$F14][lq_tmp_x_292:=VV$35$F14][lq_tmp_x_287:=lq_anf__dwW]]}
+  id 14 tag [2]
+  // META constraint id 14 : tests/pos/listqual.hs:10:1-3
+
+
+constraint:
+  env [0; 16; 1; 17; 2; 3; 4; 5; 6; 7; 8; 9; 10; 90; 11; 14; 15]
+  lhs {VV$35$F30 : [a_awA] | [(VV$35$F30 = xs$35$awp);
+                              (len([VV$35$F30]) >= 0)]}
+  rhs {VV$35$F30 : [a_awA] | [(len([VV$35$F30]) < len([ds_dwT]))]}
+  id 30 tag [1]
+  // META constraint id 30 : tests/pos/listqual.hs:6:31-32
+
+
+constraint:
+  env [0; 64; 1; 65; 2; 3; 4; 20; 5; 6; 22; 7; 8]
+  lhs {VV$35$F15 : int | [$k__272[lq_tmp_x_274:=VV$35$F15][VV$35$271:=VV$35$F15][VV$35$F:=VV$35$F15][lq_tmp_x_302:=VV$35$414][VV$35$417:=VV$35$F15][lq_tmp_x_299:=VV$35$F15][lq_tmp_x_270:=VV$35$414]]}
+  rhs {VV$35$F15 : int | [$k__294[lq_tmp_x_282:=VV$35$414][VV$35$F:=VV$35$F15][VV$35$417:=VV$35$F15][VV$35$293:=VV$35$F15][lq_tmp_x_292:=VV$35$F15][lq_tmp_x_296:=lq_anf__dwW][lq_tmp_x_287:=lq_anf__dwW]]}
+  id 15 tag [2]
+  // META constraint id 15 : tests/pos/listqual.hs:10:1-3
+
+
+constraint:
+  env [0; 16; 1; 17; 2; 3; 4; 5; 6; 7; 8; 9; 10; 90; 11; 14; 15]
+  lhs {VV$35$F31 : [a_awA] | [(VV$35$F31 = xs$35$awp);
+                              (len([VV$35$F31]) >= 0)]}
+  rhs {VV$35$F31 : [a_awA] | [(len([VV$35$F31]) >= 0)]}
+  id 31 tag [1]
+  // META constraint id 31 : tests/pos/listqual.hs:6:31-32
+
+
+
+
+wf:
+  env [0; 1; 2; 3; 4; 20; 5; 6; 22; 7; 23; 8]
+  reft {VV$35$293 : int | [$k__294]}
+  
+  // META wf  : tests/pos/listqual.hs:10:1-3
+
+
+wf:
+  env [0; 1; 2; 3; 4; 20; 5; 6; 22; 7; 8]
+  reft {VV$35$289 : int | [$k__290]}
+  
+  // META wf  : tests/pos/listqual.hs:10:1-3
+
+
+wf:
+  env [0; 1; 2; 3; 4; 20; 5; 21; 6; 7; 8]
+  reft {VV$35$275 : int | [$k__276]}
+  
+  // META wf  : tests/pos/listqual.hs:10:1-3
+
+
+wf:
+  env [0; 1; 2; 3; 4; 20; 5; 6; 7; 8]
+  reft {VV$35$271 : int | [$k__272]}
+  
+  // META wf  : tests/pos/listqual.hs:10:1-3
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8]
+  reft {VV$35$164 : [a_awA] | [$k__165]}
+  
+  // META wf  : <no location info>
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 109]
+  reft {VV$35$157 : a_awA | [$k__158]}
+  
+  // META wf  : <no location info>
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 110]
+  reft {VV$35$161 : a_awA | [$k__162]}
+  
+  // META wf  : <no location info>
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 111]
+  reft {VV$35$174 : [a_awA] | [$k__175]}
+  
+  // META wf  : <no location info>
+
+
+wf:
+  env [0; 1; 2; 114; 3; 4; 5; 6; 7; 8; 111]
+  reft {VV$35$184 : [a_awA] | [$k__185]}
+  
+  // META wf  : <no location info>
+
+
+
+
+
+
+
diff --git a/liquid-fixpoint/tests/pos/literals.fq b/liquid-fixpoint/tests/pos/literals.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/literals.fq
@@ -0,0 +1,13 @@
+//adapted from LH test Strings.hs
+
+constant lit#bar : (Str)
+constant lit#foo : (Str)
+
+distinct lit#bar : (Str)
+distinct lit#foo : (Str)
+
+constraint:
+  env []
+  lhs {VV#F1 : int | []}
+  rhs {VV#F1 : int | [(lit#bar != lit#foo)]}
+  id 1 tag [6]
diff --git a/liquid-fixpoint/tests/pos/literals01.fq b/liquid-fixpoint/tests/pos/literals01.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/literals01.fq
@@ -0,0 +1,9 @@
+
+constant lit$cat : (Str)
+distinct lit$cat : (Str)
+
+constraint:
+  env []
+  lhs {v : Str | v = lit$cat }
+  rhs {v : Str | strLen v = 3 }
+  id 1 tag [6]
diff --git a/liquid-fixpoint/tests/pos/literals02.fq b/liquid-fixpoint/tests/pos/literals02.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/literals02.fq
@@ -0,0 +1,28 @@
+constant strLen : (func(0, [[Char]; int]))
+constant len : (func(2, [(@(0)  @(1)); int]))
+
+constant lit$cat : (Str)
+
+distinct lit$cat : (Str)
+
+
+bind 0 Data.Foldable.$36$fFoldable$91$$93$$35$$35$rlx : {VV##27 : (Data.Foldable.Foldable  fix$36$$91$$93$) | []}
+bind 1 GHC.Types.True##6u : {VV##28 : bool | [(VV##28 = GHC.Types.True##6u)]}
+bind 2 GHC.Types.False##68 : {VV##29 : bool | [(VV##29 = GHC.Types.False##68)]}
+bind 3 GHC.Types.EQ##6U : {VV##30 : GHC.Types.Ordering | [(VV##30 = GHC.Types.EQ##6U)]}
+bind 4 GHC.Types.LT##6S : {VV##31 : GHC.Types.Ordering | [(VV##31 = GHC.Types.LT##6S)]}
+bind 5 GHC.Types.GT##6W : {VV##32 : GHC.Types.Ordering | [(VV##32 = GHC.Types.GT##6W)]}
+bind 6 lq_anf$##1677724177##dFz : {lq_tmp$x##35 : Str | [(lq_tmp$x##35 = lit$cat)]}
+bind 7 lq_anf$##1677724178##dFA : {lq_tmp$x##41 : [Char] | [(lq_tmp$x##41 ~~ lq_anf$##1677724177##dFz);
+                                                            ((len lq_tmp$x##41) = (strLen lq_anf$##1677724177##dFz));
+                                                            ((len lq_tmp$x##41) >= 0)]}
+
+constraint:
+  env [0; 1; 2; 3; 4; 5; 6; 7]
+  lhs {VV##F##1 : int | [(VV##F##1 >= 0);
+                         (VV##F##1 = (len lq_anf$##1677724178##dFA))]}
+  rhs {VV##F##1 : int | [(VV##F##1 = 3)]}
+  id 1 tag [1]
+  // META constraint id 1 : ()
+
+
diff --git a/liquid-fixpoint/tests/pos/literals03.fq b/liquid-fixpoint/tests/pos/literals03.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/literals03.fq
@@ -0,0 +1,16 @@
+constant lit$year     : (Str)
+constant lit$title    : (Str)
+constant lit$star     : (Str)
+constant lit$director : (Str)
+
+constant listElts : (func(0, [LLChar; (Set_Set Str)]))
+constant Set_sng : (func(1, [@(0); (Set_Set  @(0))]))
+
+bind 1 a  : {a : Str | a == "director" }
+bind 2 things : {v : LLChar | (listElts v == (Set_cup (Set_sng lit$year) (Set_cup (Set_sng lit$star) (Set_cup (Set_sng lit$director) (Set_sng lit$title)))))}
+
+constraint:
+  env [ 1; 2 ]
+  lhs {v : int | true }
+  rhs {v : int | Set_mem a (listElts things)} 
+  id 1 tag []
diff --git a/liquid-fixpoint/tests/pos/literals04.fq b/liquid-fixpoint/tests/pos/literals04.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/literals04.fq
@@ -0,0 +1,16 @@
+constant lit$year     : (Str)
+constant lit$title    : (Str)
+constant lit$star     : (Str)
+constant lit$director : (Str)
+
+constant listElts : (func(0, [LLChar; (Set_Set Str)]))
+constant Set_sng : (func(1, [@(0); (Set_Set  @(0))]))
+
+bind 1 a  : {a : Str | a == "director" }
+bind 2 things : {v : LLChar | (listElts v ~~ (Set_cup (Set_sng lit$year) (Set_cup (Set_sng lit$star) (Set_cup (Set_sng lit$director) (Set_sng lit$title)))))}
+
+constraint:
+  env [ 1; 2 ]
+  lhs {v : int | true }
+  rhs {v : int | Set_mem a (listElts things)} 
+  id 1 tag []
diff --git a/liquid-fixpoint/tests/pos/literals05.fq b/liquid-fixpoint/tests/pos/literals05.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/literals05.fq
@@ -0,0 +1,14 @@
+constant listElts : (func(0, [LLChar; (Set_Set Str)]))
+constant Set_sng : (func(1, [@(0); (Set_Set  @(0))]))
+
+bind 1 a  : {a : Str | a == "director" }
+bind 2 things : {v : LLChar | (listElts v == (Set_cup (Set_sng "year") 
+                                               (Set_cup (Set_sng "star") 
+                                                 (Set_cup (Set_sng "director") 
+                                                   (Set_sng "title"))))) }
+
+constraint:
+  env [ 1; 2 ]
+  lhs {v : int | true }
+  rhs {v : int | Set_mem a (listElts things)} 
+  id 1 tag []
diff --git a/liquid-fixpoint/tests/pos/meas00.fq b/liquid-fixpoint/tests/pos/meas00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/meas00.fq
@@ -0,0 +1,21 @@
+qualif Sz(v: Tree): (0 < thinginess v)
+qualif Sz(v: Tree): (1 < 0)
+
+constant thinginess : func(0, [Tree; int])
+
+constraint:
+  env [ ]
+  lhs {v : Tree | 666 < thinginess v }
+  rhs {v : Tree | $k1  }
+  id 1 tag []
+
+
+constraint:
+  env [ ]
+  lhs {v : Tree | $k1  }
+  rhs {v : Tree | 0 < thinginess v }
+  id 2 tag []
+
+wf: 
+  env [ ]
+  reft { v: Tree | $k1 }
diff --git a/liquid-fixpoint/tests/pos/meas02.fq b/liquid-fixpoint/tests/pos/meas02.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/meas02.fq
@@ -0,0 +1,25 @@
+
+qualif SumZ(v:[real]): (sumD v = 0.0)
+
+qualif SumZ(v:[real]): (((sumD v) / (sumD v)) = 1.0)
+
+constant sumD : (func(0, [[real]; real]))
+
+bind 0 zero    : {VV : real     | VV = 0.0 }
+bind 1 pumpkin : {VV : [real] | sumD VV = 0.0 }
+
+constraint:
+  env [ 0; 1 ]
+  lhs {v : [real] | v = pumpkin }
+  rhs {v : [real] | $k1 }
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : [real] | $k1 }
+  rhs {v : [real] | sumD v = 0.0 }
+  id 2 tag []
+
+wf:
+  env []
+  reft {v : [real] | $k1 }
diff --git a/liquid-fixpoint/tests/pos/min00.fq b/liquid-fixpoint/tests/pos/min00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/min00.fq
@@ -0,0 +1,22 @@
+
+qualif Zog(v:a) : (10 <= v)
+qualif Zog(v:a) : (9 <= v)
+qualif Zog(v:a) : (8 <= v)
+qualif Zog(v:a) : (99 <= v)
+
+constraint:
+  env []
+  lhs {v : int | (v = 100)}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env []
+  lhs {v : int | $k0}
+  rhs {v : int | (15 <= v) }
+  id 1 tag []
+
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/pos/multi-sorts.fq b/liquid-fixpoint/tests/pos/multi-sorts.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/multi-sorts.fq
@@ -0,0 +1,10 @@
+
+bind 0 x  : {VV : Tree | [] }
+bind 1 x  : {VV : List | [] }
+bind 2 x  : {VV : real | [] }
+
+constraint:
+  env [0]
+  lhs {VV : Tree | [ VV = x ] }
+  rhs {VV : Tree | [ VV = x ] }
+  id 1 tag [1]
diff --git a/liquid-fixpoint/tests/pos/multiple-func-sorts.fq b/liquid-fixpoint/tests/pos/multiple-func-sorts.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/multiple-func-sorts.fq
@@ -0,0 +1,4 @@
+// adapted from LH test vector2.hs
+
+constant foo :     func(1, [@(0); @(0)])
+bind 6 foo : {VV : func(1, [@(0); @(0)]) | []}
diff --git a/liquid-fixpoint/tests/pos/num00.fq b/liquid-fixpoint/tests/pos/num00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/num00.fq
@@ -0,0 +1,22 @@
+// This qualifier saves the day; solve constraints WITHOUT IT
+
+qualif Zog(v:a) : (0 <= v)
+
+bind 0 alpha : {v : num | true}
+
+constraint:
+  env [0]
+  lhs {v : alpha | (v = 10)}
+  rhs {v : alpha | $k0}
+  id 1 tag []
+
+constraint:
+  env [0]
+  lhs {v : alpha | $k0}
+  rhs {v : alpha | 0 <= v}
+  id 2 tag []
+
+wf:
+  env [0]
+  reft {v: alpha | $k0}
+
diff --git a/liquid-fixpoint/tests/pos/numoverload00.fq b/liquid-fixpoint/tests/pos/numoverload00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/numoverload00.fq
@@ -0,0 +1,23 @@
+
+qualif Foo(v:real, xiggety:real): (v = xiggety * xiggety)
+qualif Bar(v:real): (v = 0.0)
+
+bind 0 zero  : {VV : real | VV = 0.0 }
+bind 1 one   : {VV : real | VV = (1.0 / 1.0) }
+bind 2 thing : {VV : real | VV = zero }
+
+constraint:
+  env [ 0; 1; 2 ]
+  lhs {v : real | v = thing }
+  rhs {v : real | $k1 }
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : real | $k1 }
+  rhs {v : real | v = 0.0 }
+  id 2 tag []
+
+wf:
+  env []
+  reft {v : real | $k1 }
diff --git a/liquid-fixpoint/tests/pos/overwrite-names.fq b/liquid-fixpoint/tests/pos/overwrite-names.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/overwrite-names.fq
@@ -0,0 +1,8 @@
+constant Set_mem : (func(1, [@(0); FAppTy Set_Set  @(0); bool]))
+
+constraint:
+  env []
+  lhs {VV#F1 : int | [(VV#F1 > 10)]}
+  rhs {VV#F1 : int | [(VV#F1 > 10)]}
+  id 1 tag [1]
+ 
diff --git a/liquid-fixpoint/tests/pos/poly0.fq b/liquid-fixpoint/tests/pos/poly0.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/poly0.fq
@@ -0,0 +1,15 @@
+fixpoint "--defunct"
+
+// This definition works fine ...
+// constant offset : (func(0, [int ; int ; (BitVec Size32) ]))
+
+// But this crashes as 'offset 0' is embedded as int not bv...
+constant offset : (func(1, [int; int; @(0)]))
+
+bind 0 x  : {VV : (BitVec  Size32) | [ VV = offset 0 0 ]}
+
+constraint:
+  env [0]
+  lhs {VV : (BitVec Size32) | [ VV = x ] }
+  rhs {VV : (BitVec Size32) | [ VV = x ] }
+  id 1 tag [1]
diff --git a/liquid-fixpoint/tests/pos/poly1.fq b/liquid-fixpoint/tests/pos/poly1.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/poly1.fq
@@ -0,0 +1,17 @@
+fixpoint "--defunct"
+
+// This definition works fine ...
+// constant offset : (func(2, [int ; (BitVec Size32) ]))
+
+// But this crashes as 'offset 0' is embedded as int not bv...
+constant offset : (func(2, [int; @(0)]))
+
+bind 0 x  : {VV : (BitVec  Size32) | [ VV = offset 0 ]}
+
+constraint: 
+  env [0]
+  lhs {VV : (BitVec Size32) | [ VV = x ] }
+  rhs {VV : (BitVec Size32) | [ VV = x ] }
+  id 1 tag [1]
+
+
diff --git a/liquid-fixpoint/tests/pos/poly2.fq b/liquid-fixpoint/tests/pos/poly2.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/poly2.fq
@@ -0,0 +1,15 @@
+fixpoint "--defunct"
+
+// This definition works fine ...
+// constant offset : (func(0, [int ; int ; (BitVec Size32) ]))
+
+// But this crashes as 'offset 0' is embedded as int not bv...
+constant offset : (func(2, [@(0); int; int; @(0); @(1)]))
+
+bind 0 x  : {VV : (BitVec  Size32) | [ VV = offset 0 0 0 0 ]}
+
+constraint:
+  env [0]
+  lhs {VV : (BitVec Size32) | [ VV = x ] }
+  rhs {VV : (BitVec Size32) | [ VV = x ] }
+  id 1 tag [1]
diff --git a/liquid-fixpoint/tests/pos/qualif-inst.fq b/liquid-fixpoint/tests/pos/qualif-inst.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/qualif-inst.fq
@@ -0,0 +1,17 @@
+// adapted from LH test eqelems.hs
+
+qualif Cmp(v : @(0), fix##126#X : @(0)): (v >= fix##126#X)
+
+constant elems : (func(1, [(Goo.T  @(0)); (Set_Set  @(0))]))
+
+bind 48 lq_anf__d14V : {lq_tmp_x_197 : (Set_Set  a_a14x) | []}
+
+constraint:
+  env []
+  lhs {VV#F4 : (Set_Set  a_a14x) | []}
+  rhs {VV#F4 : (Set_Set  a_a14x) | [$k__226[VV#225:=VV#F4]]}
+  id 4 tag [2]
+
+wf:
+  env [48]
+  reft {VV#225 : (Set_Set  a_a14x) | [$k__226]}
diff --git a/liquid-fixpoint/tests/pos/sets.fq b/liquid-fixpoint/tests/pos/sets.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/sets.fq
@@ -0,0 +1,7 @@
+// constant Set_empty : (func(1, [int; Set_Set @(0)]))
+
+constraint:
+  env []
+  lhs {v : Set_Set a_aTp | [(? Set_emp([v]))]}
+  rhs {v : Set_Set a_aTp | [(v = Set_empty([0]))]}
+  id 3 tag [2]
diff --git a/liquid-fixpoint/tests/pos/test00-par.fq b/liquid-fixpoint/tests/pos/test00-par.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test00-par.fq
@@ -0,0 +1,37 @@
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 10]}
+  rhs {v : int | [v > 0]}
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 20]}
+  rhs {v : int | [v > 0]}
+  id 2 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 20]}
+  rhs {v : int | [v > 0]}
+  id 3 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 10]}
+  rhs {v : int | [v > 0]}
+  id 4 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 20]}
+  rhs {v : int | [v > 0]}
+  id 5 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 20]}
+  rhs {v : int | [v > 0]}
+  id 6 tag []
+
diff --git a/liquid-fixpoint/tests/pos/test00.fq b/liquid-fixpoint/tests/pos/test00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test00.fq
@@ -0,0 +1,28 @@
+qualif Zog(v:a) : (10 <= v)
+qualif Bog(v:a, x:a) : (x <= v)
+
+bind 0 a : {va: int | $k0[v := va][thing := thang] }
+bind 1 thing : {v: int | true }
+bind 2 thang : {v: int | true }
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 10}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 20}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | v = a}
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ 2 ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/pos/test00.hs.fq b/liquid-fixpoint/tests/pos/test00.hs.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test00.hs.fq
@@ -0,0 +1,1021 @@
+
+qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (Prop(v) <=> len([xs]) > 0)
+qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (Prop(v) <=> len([xs]) = 0)
+qualif ListZ(v: [a])          : len([v]) =  0 
+qualif ListZ(v: [a])          : len([v]) >= 0 
+qualif ListZ(v: [a])          : len([v]) >  0 
+qualif CmpLen(v:[a], xs:[b])  : len([v]) =  len([xs]) 
+qualif CmpLen(v:[a], xs:[b])  : len([v]) >= len([xs]) 
+qualif CmpLen(v:[a], xs:[b])  : len([v]) >  len([xs]) 
+qualif CmpLen(v:[a], xs:[b])  : len([v]) <= len([xs]) 
+qualif CmpLen(v:[a], xs:[b])  : len([v]) <  len([xs]) 
+qualif EqLen(v:int, xs: [a]): v = len([xs]) 
+qualif LenEq(v:[a], x: int) :  x = len([v]) 
+qualif LenDiff(v:[a], x:int): len([v]) = x + 1
+qualif LenDiff(v:[a], x:int): len([v]) = x - 1
+qualif LenAcc(v:int, xs:[a], n: int): (v = len([xs]) + n)
+
+qualif Bot(v:obj): 0 = 1 
+qualif Bot(v:a): 0 = 1 
+qualif Bot(v:bool): 0 = 1 
+qualif Bot(v:int): 0 = 1 
+qualif CmpZ(v:a): (v <  0)
+qualif CmpZ(v:a): (v <= 0)
+qualif CmpZ(v:a): (v >  0)
+qualif CmpZ(v:a): (v >= 0)
+qualif CmpZ(v:a): (v  = 0)
+qualif CmpZ(v:a): (v != 0)
+
+qualif Cmp(v:a, x:a): (v <  x)
+qualif Cmp(v:a, x:a): (v <= x)
+qualif Cmp(v:a, x:a): (v >  x)
+qualif Cmp(v:a, x:a): (v >= x)
+qualif Cmp(v:a, x:a): (v  = x)
+qualif Cmp(v:a, x:a): (v != x)
+
+qualif One(v:int)     : v = 1
+qualif True(v:bool)   : (? v) 
+qualif False(v:bool)  : ~ (? v) 
+qualif True1(v:GHC.Types.Bool): (Prop(v))
+qualif False1(v:GHC.Types.Bool): (~ Prop(v))
+qualif Papp(v:a, p:Pred a) : (papp1(p, v))
+
+constant papp1 : func(1, [Pred @(0); @(0); bool])
+
+qualif Papp2(v:a,x:b,p:Pred a b) : papp2(p, v, x)
+constant papp2 : func(4, [Pred @(0) @(1); @(2); @(3); bool])
+
+qualif Papp3(v:a,x:b, y:c, p:Pred a b c) : papp3(p, v, x, y)
+constant papp3 : func(6, [Pred @(0) @(1) @(2); @(3); @(4); @(5); bool])
+
+qualif Papp4(v:a,x:b, y:c, z:d, p:Pred a b c d) : papp4(p, v, x, y, z)
+constant papp4 : func(8, [Pred @(0) @(1) @(2) @(6); @(3); @(4); @(5); @(7); bool])
+
+
+
+constant Prop : func(0, [GHC.Types.Bool; bool])
+qualif Fst(v : @(1), fix##126#Y : @(0)): (v = fst([fix##126#Y])) // "/Users/rjhala/research/liquid/liquidhaskell/.cabal-sandbox/share/x86_64-osx-ghc-7.8.3/liquidhaskell-0.3.1.0/include/GHC/Base.spec" (line 26, column 8)
+qualif Snd(v : @(1), fix##126#Y : @(0)): (v = snd([fix##126#Y])) // "/Users/rjhala/research/liquid/liquidhaskell/.cabal-sandbox/share/x86_64-osx-ghc-7.8.3/liquidhaskell-0.3.1.0/include/GHC/Base.spec" (line 27, column 8)
+
+constant Prop : func(0, [GHC.Types.Bool; bool])
+constant x_Tuple54 : func(5, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4);
+                              @(3)])
+constant x_Tuple44 : func(4, [FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3);
+                              @(3)])
+constant xListSelector : func(1, [[@(0)]; @(0)])
+constant x_Tuple41 : func(4, [FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3);
+                              @(0)])
+constant x_Tuple76 : func(7, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5))  @(6);
+                              @(5)])
+constant addrLen : func(0, [int; int])
+constant x_Tuple65 : func(6, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5);
+                              @(4)])
+constant x_Tuple52 : func(5, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4);
+                              @(1)])
+constant GHC.Types.False#68 : (GHC.Types.Bool)
+constant x_Tuple64 : func(6, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5);
+                              @(3)])
+constant x_Tuple33 : func(3, [FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2);
+                              @(2)])
+constant fst : func(2, [FAppTy (FAppTy fix##40##41#  @(0))  @(1);
+                        @(0)])
+constant x_Tuple31 : func(3, [FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2);
+                              @(0)])
+constant x_Tuple43 : func(4, [FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3);
+                              @(2)])
+constant x_Tuple71 : func(7, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5))  @(6);
+                              @(0)])
+constant x_Tuple32 : func(3, [FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2);
+                              @(1)])
+constant x_Tuple72 : func(7, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5))  @(6);
+                              @(1)])
+constant x_Tuple63 : func(6, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5);
+                              @(2)])
+constant x_Tuple75 : func(7, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5))  @(6);
+                              @(4)])
+constant x_Tuple51 : func(5, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4);
+                              @(0)])
+constant len : func(1, [[@(0)]; int])
+constant xsListSelector : func(1, [[@(0)]; [@(0)]])
+constant null : func(1, [[@(0)]; bool])
+constant x_Tuple53 : func(5, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4);
+                              @(2)])
+constant x_Tuple22 : func(2, [FAppTy (FAppTy fix##40##41#  @(0))  @(1);
+                              @(1)])
+constant fromJust : func(1, [FAppTy Data.Maybe.Maybe  @(0); @(0)])
+constant snd : func(2, [FAppTy (FAppTy fix##40##41#  @(0))  @(1);
+                        @(1)])
+constant x_Tuple73 : func(7, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5))  @(6);
+                              @(2)])
+constant x_Tuple62 : func(6, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5);
+                              @(1)])
+constant x_Tuple55 : func(5, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4);
+                              @(4)])
+constant x_Tuple74 : func(7, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5))  @(6);
+                              @(3)])
+constant cmp : func(0, [GHC.Types.Ordering; GHC.Types.Ordering])
+constant x_Tuple42 : func(4, [FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3);
+                              @(1)])
+constant x_Tuple21 : func(2, [FAppTy (FAppTy fix##40##41#  @(0))  @(1);
+                              @(0)])
+constant x_Tuple61 : func(6, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5);
+                              @(0)])
+constant isJust : func(1, [FAppTy Data.Maybe.Maybe  @(0); bool])
+constant x_Tuple66 : func(6, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5);
+                              @(5)])
+constant GHC.Types.True#6u : (GHC.Types.Bool)
+constant x_Tuple77 : func(7, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4))  @(5))  @(6);
+                              @(6)])
+bind 0 GHC.Types.False#68 : {VV#171 : GHC.Types.Bool | []}
+bind 1 GHC.Types.I##6c : {VV : func(0, [int; int]) | []}
+bind 2 GHC.Types.True#6u : {VV#173 : GHC.Types.Bool | []}
+bind 3 fix#GHC.Classes.#36#fOrdInt#35#rhx : {VV#175 : FAppTy GHC.Classes.Ord  int | []}
+bind 4 fix#GHC.Num.#36#fNumInt#35#rhy : {VV#176 : FAppTy GHC.Num.Num  int | []}
+bind 5 Language.Haskell.Liquid.Prelude.liquidAssertB#rpD : {VV : func(0, [GHC.Types.Bool;
+                                                                          GHC.Types.Bool]) | []}
+bind 6 Language.Haskell.Liquid.Prelude.choose#rpK : {VV : func(0, [int;
+                                                                   int]) | []}
+bind 7 GHC.Types.EQ#6U : {VV#179 : GHC.Types.Ordering | []}
+bind 8 GHC.Types.LT#6S : {VV#180 : GHC.Types.Ordering | []}
+bind 9 GHC.Types.GT#6W : {VV#181 : GHC.Types.Ordering | []}
+bind 10 GHC.Types.True#6u : {v : GHC.Types.Bool | [(? Prop([v]))]}
+bind 11 GHC.Types.False#68 : {v : GHC.Types.Bool | [(~ ((? Prop([v]))))]}
+bind 12 Language.Haskell.Liquid.Prelude.plus#rou : {VV : func(0, [int;
+                                                                  int;
+                                                                  int]) | []}
+bind 13 Language.Haskell.Liquid.Prelude.minus#rpv : {VV : func(0, [int;
+                                                                   int;
+                                                                   int]) | []}
+bind 14 Language.Haskell.Liquid.Prelude.times#rpw : {VV : func(0, [int;
+                                                                   int;
+                                                                   int]) | []}
+bind 15 Language.Haskell.Liquid.Prelude.eq#rpx : {VV : func(0, [int;
+                                                                int;
+                                                                GHC.Types.Bool]) | []}
+bind 16 Language.Haskell.Liquid.Prelude.neq#rpy : {VV : func(0, [int;
+                                                                 int;
+                                                                 GHC.Types.Bool]) | []}
+bind 17 Language.Haskell.Liquid.Prelude.leq#rpz : {VV : func(0, [int;
+                                                                 int;
+                                                                 GHC.Types.Bool]) | []}
+bind 18 Language.Haskell.Liquid.Prelude.geq#rpA : {VV : func(0, [int;
+                                                                 int;
+                                                                 GHC.Types.Bool]) | []}
+bind 19 Language.Haskell.Liquid.Prelude.lt#rpB : {VV : func(0, [int;
+                                                                int;
+                                                                GHC.Types.Bool]) | []}
+bind 20 Language.Haskell.Liquid.Prelude.gt#rpC : {VV : func(0, [int;
+                                                                int;
+                                                                GHC.Types.Bool]) | []}
+bind 21 Language.Haskell.Liquid.Prelude.liquidAssertB#rpD : {VV : func(0, [GHC.Types.Bool;
+                                                                           GHC.Types.Bool]) | []}
+bind 22 Language.Haskell.Liquid.Prelude.isEven#rpL : {VV : func(0, [int;
+                                                                    GHC.Types.Bool]) | []}
+bind 23 Language.Haskell.Liquid.Prelude.isOdd#rpM : {VV : func(0, [int;
+                                                                   GHC.Types.Bool]) | []}
+bind 24 GHC.Integer.Type.smallInteger#0Z : {VV : func(0, [int;
+                                                          int]) | []}
+bind 25 GHC.Types.I##6c : {VV : func(0, [int; int]) | []}
+bind 26 fix#GHC.Prim.#43##35##35#98 : {VV : func(0, [int;
+                                                     int;
+                                                     int]) | []}
+bind 27 fix#GHC.Prim.#45##35##35#99 : {VV : func(0, [int;
+                                                     int;
+                                                     int]) | []}
+bind 28 fix#GHC.Prim.#61##61##35##35#9o : {VV : func(0, [int;
+                                                         int;
+                                                         int]) | []}
+bind 29 fix#GHC.Prim.#62##61##35##35#9n : {VV : func(0, [int;
+                                                         int;
+                                                         int]) | []}
+bind 30 fix#GHC.Prim.#60##61##35##35#9r : {VV : func(0, [int;
+                                                         int;
+                                                         int]) | []}
+bind 31 fix#GHC.Prim.#60##35##35#9q : {VV : func(0, [int;
+                                                     int;
+                                                     int]) | []}
+bind 32 fix#GHC.Prim.#62##35##35#9m : {VV : func(0, [int;
+                                                     int;
+                                                     int]) | []}
+bind 33 GHC.Types.EQ#6U : {VV#220 : GHC.Types.Ordering | [(cmp([VV#220]) = GHC.Types.EQ#6U)]}
+bind 34 GHC.Types.LT#6S : {VV#222 : GHC.Types.Ordering | [(cmp([VV#222]) = GHC.Types.LT#6S)]}
+bind 35 GHC.Types.GT#6W : {VV#223 : GHC.Types.Ordering | [(cmp([VV#223]) = GHC.Types.GT#6W)]}
+bind 36 fix##36#dOrd_a165 : {VV#232 : FAppTy GHC.Classes.Ord  a_a164 | []}
+bind 37 fix##36#dNum_a166 : {VV#233 : FAppTy GHC.Num.Num  a_a164 | []}
+bind 38 a_a164 : {VV : num | []}
+bind 39 gooberding#a15N : {VV#234 : a_a164 | [$k_235]}
+bind 40 lq_anf__d16w : {lq_tmp_x241 : int | [(lq_tmp_x241 = 0)]}
+bind 41 lq_anf__d16x : {VV : a_a164 | [(VV = lq_anf__d16w)]}
+bind 42 lq_anf__d16y : {lq_tmp_x254 : GHC.Types.Bool | [((? Prop([lq_tmp_x254])) <=> (gooberding#a15N >= lq_anf__d16x))]}
+bind 43 lq_anf__d16z : {lq_tmp_x276 : int | [(lq_tmp_x276 = (0  :  int))]}
+bind 44 Test0.x#r12i : {VV#272 : int | [$k_273]}
+bind 45 lq_anf__d16A : {lq_tmp_x291 : int | [(lq_tmp_x291 = (0  :  int))]}
+bind 46 lq_anf__d16B : {lq_tmp_x297 : GHC.Types.Bool | [((? Prop([lq_tmp_x297])) <=> (Test0.x#r12i > lq_anf__d16A))]}
+bind 47 lq_anf__d16C : {lq_tmp_x313 : GHC.Types.Bool | [((? Prop([lq_tmp_x313])) <=> (Test0.x#r12i > lq_anf__d16A));
+                                                        (lq_tmp_x313 = lq_anf__d16B)]}
+bind 48 lq_anf__d16C : {lq_tmp_x315 : GHC.Types.Bool | [((? Prop([lq_tmp_x315])) <=> (Test0.x#r12i > lq_anf__d16A));
+                                                        (lq_tmp_x315 = lq_anf__d16B)]}
+bind 49 lq_anf__d16C : {lq_tmp_x315 : GHC.Types.Bool | [((? Prop([lq_tmp_x315])) <=> (Test0.x#r12i > lq_anf__d16A));
+                                                        (lq_tmp_x315 = lq_anf__d16B);
+                                                        (~ ((? Prop([lq_tmp_x315]))));
+                                                        (~ ((? Prop([lq_tmp_x315]))))]}
+bind 50 lq_anf__d16C : {lq_tmp_x321 : GHC.Types.Bool | [((? Prop([lq_tmp_x321])) <=> (Test0.x#r12i > lq_anf__d16A));
+                                                        (lq_tmp_x321 = lq_anf__d16B)]}
+bind 51 lq_anf__d16C : {lq_tmp_x321 : GHC.Types.Bool | [((? Prop([lq_tmp_x321])) <=> (Test0.x#r12i > lq_anf__d16A));
+                                                        (lq_tmp_x321 = lq_anf__d16B);
+                                                        (? Prop([lq_tmp_x321]));
+                                                        (? Prop([lq_tmp_x321]))]}
+bind 52 Test0.prop_abs#r12j : {VV#287 : GHC.Types.Bool | [$k_288]}
+bind 53 VV#343 : {VV#343 : GHC.Types.Bool | [$k_239[VV#238:=VV#343][fix##36#dOrd_a165:=fix#GHC.Classes.#36#fOrdInt#35#rhx][fix##36#dNum_a166:=fix#GHC.Num.#36#fNumInt#35#rhy][gooberding#a15N:=Test0.x#r12i][lq_tmp_x332:=fix#GHC.Classes.#36#fOrdInt#35#rhx][lq_tmp_x333:=fix#GHC.Num.#36#fNumInt#35#rhy][lq_tmp_x334:=Test0.x#r12i][lq_tmp_x328:=VV#343]]}
+bind 54 VV#343 : {VV#343 : GHC.Types.Bool | [$k_239[VV#238:=VV#343][fix##36#dOrd_a165:=fix#GHC.Classes.#36#fOrdInt#35#rhx][fix##36#dNum_a166:=fix#GHC.Num.#36#fNumInt#35#rhy][gooberding#a15N:=Test0.x#r12i][lq_tmp_x332:=fix#GHC.Classes.#36#fOrdInt#35#rhx][lq_tmp_x333:=fix#GHC.Num.#36#fNumInt#35#rhy][lq_tmp_x334:=Test0.x#r12i][lq_tmp_x328:=VV#343]]}
+bind 55 VV#346 : {VV#346 : int | [$k_273[VV#272:=VV#346][lq_tmp_x341:=VV#346];
+                                  (VV#346 = Test0.x#r12i)]}
+bind 56 VV#346 : {VV#346 : int | [$k_273[VV#272:=VV#346][lq_tmp_x341:=VV#346];
+                                  (VV#346 = Test0.x#r12i)]}
+bind 57 VV#349 : {VV#349 : GHC.Types.Bool | [(~ ((? Prop([VV#349]))));
+                                             (VV#349 = GHC.Types.False#68)]}
+bind 58 VV#349 : {VV#349 : GHC.Types.Bool | [(~ ((? Prop([VV#349]))));
+                                             (VV#349 = GHC.Types.False#68)]}
+bind 59 VV#352 : {VV#352 : int | [(VV#352 = (0  :  int));
+                                  (VV#352 = lq_anf__d16A)]}
+bind 60 VV#352 : {VV#352 : int | [(VV#352 = (0  :  int));
+                                  (VV#352 = lq_anf__d16A)]}
+bind 61 VV#355 : {VV#355 : int | [$k_273[VV#272:=VV#355][lq_tmp_x310:=VV#355];
+                                  (VV#355 = Test0.x#r12i)]}
+bind 62 VV#355 : {VV#355 : int | [$k_273[VV#272:=VV#355][lq_tmp_x310:=VV#355];
+                                  (VV#355 = Test0.x#r12i)]}
+bind 63 VV#358 : {VV#358 : int | [(VV#358 = 0)]}
+bind 64 VV#358 : {VV#358 : int | [(VV#358 = 0)]}
+bind 65 VV#361 : {VV#361 : int | []}
+bind 66 VV#361 : {VV#361 : int | []}
+bind 67 VV#364 : {VV#364 : int | [(VV#364 = (0  :  int));
+                                  (VV#364 = lq_anf__d16z)]}
+bind 68 VV#364 : {VV#364 : int | [(VV#364 = (0  :  int));
+                                  (VV#364 = lq_anf__d16z)]}
+bind 69 VV#367 : {VV#367 : int | [(VV#367 = 0)]}
+bind 70 VV#367 : {VV#367 : int | [(VV#367 = 0)]}
+bind 71 VV#370 : {VV#370 : GHC.Types.Bool | [(? Prop([VV#370]))]}
+bind 72 VV#370 : {VV#370 : GHC.Types.Bool | [(? Prop([VV#370]))]}
+bind 73 VV#373 : {VV#373 : GHC.Types.Bool | [((? Prop([VV#373])) <=> (gooberding#a15N >= lq_anf__d16x));
+                                             (VV#373 = lq_anf__d16y)]}
+bind 74 VV#373 : {VV#373 : GHC.Types.Bool | [((? Prop([VV#373])) <=> (gooberding#a15N >= lq_anf__d16x));
+                                             (VV#373 = lq_anf__d16y)]}
+bind 75 VV : {VV : a_a164 | [(VV = lq_anf__d16w);
+                             (VV = lq_anf__d16x)]}
+bind 76 VV#234 : {VV#234 : a_a164 | [$k_235;
+                                     (VV#234 = gooberding#a15N)]}
+bind 77 VV#378 : {VV#378 : int | [(VV#378 = 0);
+                                  (VV#378 = lq_anf__d16w)]}
+bind 78 VV#378 : {VV#378 : int | [(VV#378 = 0);
+                                  (VV#378 = lq_anf__d16w)]}
+bind 79 VV#304 : {VV#304 : int | [$k_305]}
+bind 80 VV#287 : {VV#287 : GHC.Types.Bool | [$k_288]}
+bind 81 VV#272 : {VV#272 : int | [$k_273]}
+bind 82 VV#238 : {VV#238 : GHC.Types.Bool | [$k_239]}
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       50;
+       3;
+       19;
+       35;
+       51;
+       4;
+       20;
+       5;
+       21;
+       53;
+       6;
+       22;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       44;
+       13;
+       29;
+       45;
+       14;
+       30;
+       46;
+       15;
+       31;
+       47]
+  lhs {VV#F1 : GHC.Types.Bool | [$k_239[VV#238:=VV#F1][fix##36#dOrd_a165:=fix#GHC.Classes.#36#fOrdInt#35#rhx][fix##36#dNum_a166:=fix#GHC.Num.#36#fNumInt#35#rhy][gooberding#a15N:=Test0.x#r12i][lq_tmp_x332:=fix#GHC.Classes.#36#fOrdInt#35#rhx][lq_tmp_x333:=fix#GHC.Num.#36#fNumInt#35#rhy][lq_tmp_x334:=Test0.x#r12i][lq_tmp_x328:=VV#F1][VV#343:=VV#F1][VV#F:=VV#F1]]}
+  rhs {VV#F1 : GHC.Types.Bool | [$k_288[VV#287:=VV#F1][VV#343:=VV#F1][VV#F:=VV#F1]]}
+  id 1 tag [3]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       50;
+       3;
+       19;
+       35;
+       51;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       23;
+       55;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       44;
+       13;
+       29;
+       45;
+       14;
+       30;
+       46;
+       15;
+       31;
+       47]
+  lhs {VV#F2 : int | [$k_273[VV#272:=VV#F2][lq_tmp_x341:=VV#F2][VV#346:=VV#F2][VV#F:=VV#F2];
+                      (VV#F2 = Test0.x#r12i)]}
+  rhs {VV#F2 : int | [$k_235[fix##36#dOrd_a165:=fix#GHC.Classes.#36#fOrdInt#35#rhx][fix##36#dNum_a166:=fix#GHC.Num.#36#fNumInt#35#rhy][VV#234:=VV#F2][lq_tmp_x332:=fix#GHC.Classes.#36#fOrdInt#35#rhx][lq_tmp_x333:=fix#GHC.Num.#36#fNumInt#35#rhy][lq_tmp_x336:=VV#F2][VV#346:=VV#F2][VV#F:=VV#F2]]}
+  id 2 tag [3]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       48;
+       1;
+       17;
+       33;
+       49;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       57;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       44;
+       13;
+       29;
+       45;
+       14;
+       30;
+       46;
+       15;
+       31;
+       47]
+  lhs {VV#F3 : GHC.Types.Bool | [(~ ((? Prop([VV#F3]))));
+                                 (VV#F3 = GHC.Types.False#68)]}
+  rhs {VV#F3 : GHC.Types.Bool | [$k_288[VV#287:=VV#F3][VV#349:=VV#F3][VV#F:=VV#F3]]}
+  id 3 tag [3]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       59;
+       12;
+       28;
+       44;
+       13;
+       29;
+       45;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV#F4 : int | [(VV#F4 = (0  :  int)); (VV#F4 = lq_anf__d16A)]}
+  rhs {VV#F4 : int | [$k_305[VV#304:=VV#F4][lq_tmp_x301:=fix#GHC.Classes.#36#fOrdInt#35#rhx][lq_tmp_x302:=Test0.x#r12i][lq_tmp_x307:=VV#F4][VV#352:=VV#F4][VV#F:=VV#F4]]}
+  id 4 tag [3]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       44;
+       13;
+       29;
+       45;
+       61;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV#F5 : int | [$k_273[VV#272:=VV#F5][lq_tmp_x310:=VV#F5][VV#355:=VV#F5][VV#F:=VV#F5];
+                      (VV#F5 = Test0.x#r12i)]}
+  rhs {VV#F5 : int | [$k_305[VV#304:=VV#F5][lq_tmp_x301:=fix#GHC.Classes.#36#fOrdInt#35#rhx][lq_tmp_x307:=VV#F5][VV#355:=VV#F5][VV#F:=VV#F5]]}
+  id 5 tag [3]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       65;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       43;
+       12;
+       28;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV#F6 : int | []}
+  rhs {VV#F6 : int | [$k_273[VV#272:=VV#F6][VV#361:=VV#F6][VV#F:=VV#F6]]}
+  id 6 tag [2]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       39;
+       71;
+       8;
+       24;
+       40;
+       9;
+       25;
+       41;
+       10;
+       26;
+       42;
+       11;
+       27;
+       12;
+       28;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV#F7 : GHC.Types.Bool | [(? Prop([VV#F7]))]}
+  rhs {VV#F7 : GHC.Types.Bool | [$k_239[VV#238:=VV#F7][VV#370:=VV#F7][VV#F:=VV#F7]]}
+  id 7 tag [1]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       39;
+       8;
+       24;
+       40;
+       9;
+       25;
+       41;
+       73;
+       10;
+       26;
+       42;
+       11;
+       27;
+       12;
+       28;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV#F8 : GHC.Types.Bool | [((? Prop([VV#F8])) <=> (gooberding#a15N >= lq_anf__d16x));
+                                 (VV#F8 = lq_anf__d16y)]}
+  rhs {VV#F8 : GHC.Types.Bool | [(? Prop([VV#F8]))]}
+  id 8 tag [1]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       39;
+       8;
+       24;
+       40;
+       9;
+       25;
+       41;
+       10;
+       26;
+       11;
+       27;
+       75;
+       12;
+       28;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV#F9 : a_a164 | [(VV#F9 = lq_anf__d16w);
+                         (VV#F9 = lq_anf__d16x)]}
+  rhs {VV#F9 : a_a164 | [$k_262[lq_tmp_x258:=fix##36#dOrd_a165][lq_tmp_x259:=gooberding#a15N][VV#261:=VV#F9][VV#F:=VV#F9]]}
+  id 9 tag [1]
+
+
+constraint:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       39;
+       8;
+       24;
+       40;
+       9;
+       25;
+       41;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       76;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV#F10 : a_a164 | [$k_235[VV#234:=VV#F10][VV#F:=VV#F10];
+                          (VV#F10 = gooberding#a15N)]}
+  rhs {VV#F10 : a_a164 | [$k_262[lq_tmp_x258:=fix##36#dOrd_a165][VV#261:=VV#F10][VV#F:=VV#F10]]}
+  id 10 tag [1]
+
+
+wf:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       44;
+       13;
+       29;
+       45;
+       14;
+       30;
+       15;
+       31]
+  reft {VV#304 : int | [$k_305]}
+  
+
+
+wf:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       44;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  reft {VV#287 : GHC.Types.Bool | [$k_288]}
+  
+
+
+wf:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  reft {VV#272 : int | [$k_273]}
+  
+
+
+wf:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  reft {VV#234 : a_a164 | [$k_235]}
+  
+
+
+wf:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       39;
+       8;
+       24;
+       40;
+       9;
+       25;
+       41;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  reft {VV#261 : a_a164 | [$k_262]}
+  
+
+
+wf:
+  env [0;
+       16;
+       32;
+       1;
+       17;
+       33;
+       2;
+       18;
+       34;
+       3;
+       19;
+       35;
+       4;
+       20;
+       36;
+       5;
+       21;
+       37;
+       6;
+       22;
+       38;
+       7;
+       23;
+       39;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       28;
+       13;
+       29;
+       14;
+       30;
+       15;
+       31]
+  reft {VV#238 : GHC.Types.Bool | [$k_239]}
+  
diff --git a/liquid-fixpoint/tests/pos/test000.hs.fq b/liquid-fixpoint/tests/pos/test000.hs.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test000.hs.fq
@@ -0,0 +1,489 @@
+qualif Fst(v : @(1), y : @(0)): (v = fst([y])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.spec" (line 29, column 8)
+qualif Snd(v : @(1), y : @(0)): (v = snd([y])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.spec" (line 30, column 8)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) > 0)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 13, column 8)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) = 0)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 14, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) = 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 16, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) >= 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 17, column 8)
+qualif ListZ(v : [@(0)]): (len([v]) > 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 18, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) = len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 20, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) >= len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 21, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) > len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 22, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) <= len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 23, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) < len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 24, column 8)
+qualif EqLen(v : int, xs : [@(0)]): (v = len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 26, column 8)
+qualif LenEq(v : [@(0)], x : int): (x = len([v])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 27, column 8)
+qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x + 1)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 28, column 8)
+qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x - 1)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 29, column 8)
+qualif LenAcc(v : int, xs : [@(0)], n : int): (v = (len([xs]) + n)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 30, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 3, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 4, column 8)
+qualif Bot(v : @(0)): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 5, column 8)
+qualif Bot(v : bool): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 6, column 8)
+qualif Bot(v : int): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 7, column 8)
+qualif CmpZ(v : @(0)): (v < 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 9, column 8)
+qualif CmpZ(v : @(0)): (v <= 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 10, column 8)
+qualif CmpZ(v : @(0)): (v > 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 11, column 8)
+qualif CmpZ(v : @(0)): (v >= 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 12, column 8)
+qualif CmpZ(v : @(0)): (v = 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 13, column 8)
+qualif CmpZ(v : @(0)): (v != 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 14, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v < x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 16, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v <= x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 17, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v > x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 18, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v >= x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 19, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v = x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 20, column 8)
+qualif Cmp(v : @(0), x : @(0)): (v != x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 21, column 8)
+qualif One(v : int): (v = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 28, column 8)
+qualif True(v : bool): (? v) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 29, column 8)
+qualif False(v : bool): (~ ((? v))) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 30, column 8)
+qualif True1(v : GHC.Types.Bool): (? Prop([v])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 31, column 8)
+qualif False1(v : GHC.Types.Bool): (~ ((? Prop([v])))) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 32, column 8)
+qualif Papp(v : @(0), p : (Pred  @(0))): (? papp1([p;
+                                                   v])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 35, column 8)
+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): (? papp2([p;
+                                                                    v;
+                                                                    x])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 38, column 8)
+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): (? papp3([p;
+                                                                                    v;
+                                                                                    x;
+                                                                                    y])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 41, column 8)
+
+
+
+
+constant runFun : (func(2, [(Arrow  @(0)  @(1)); @(0); @(1)]))
+constant addrLen : (func(0, [int; int]))
+constant xsListSelector : (func(1, [[@(0)]; [@(0)]]))
+constant x_Tuple21 : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant x_Tuple65 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(4)]))
+constant GHC.Types.False$35$68 : (GHC.Types.Bool)
+constant x_Tuple55 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(4)]))
+constant x_Tuple33 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(2)]))
+constant x_Tuple77 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(6)]))
+constant papp3 : (func(6, [(Pred  @(0)  @(1)  @(2));
+                           @(3);
+                           @(4);
+                           @(5);
+                           bool]))
+constant x_Tuple63 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(2)]))
+constant x_Tuple41 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(0)]))
+constant papp4 : (func(8, [(Pred  @(0)  @(1)  @(2)  @(6));
+                           @(3);
+                           @(4);
+                           @(5);
+                           @(7);
+                           bool]))
+constant x_Tuple64 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(3)]))
+constant autolen : (func(1, [@(0); int]))
+constant x_Tuple52 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(1)]))
+constant null : (func(1, [[@(0)]; bool]))
+constant papp2 : (func(4, [(Pred  @(0)  @(1)); @(2); @(3); bool]))
+constant x_Tuple62 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(1)]))
+constant fromJust : (func(1, [(GHC.Base.Maybe  @(0)); @(0)]))
+constant x_Tuple53 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(2)]))
+constant x_Tuple71 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(0)]))
+constant x_Tuple74 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(3)]))
+constant len : (func(2, [(@(0)  @(1)); int]))
+constant x_Tuple22 : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant x_Tuple66 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(5)]))
+constant x_Tuple44 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(3)]))
+constant xListSelector : (func(1, [[@(0)]; @(0)]))
+constant strLen : (func(0, [int; int]))
+constant x_Tuple72 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(1)]))
+constant isJust : (func(1, [(GHC.Base.Maybe  @(0)); bool]))
+constant Prop : (func(0, [GHC.Types.Bool; bool]))
+constant x_Tuple31 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(0)]))
+constant x_Tuple75 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(4)]))
+constant papp1 : (func(1, [(Pred  @(0)); @(0); bool]))
+constant x_Tuple61 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(0)]))
+constant x_Tuple43 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(2)]))
+constant x_Tuple51 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(0)]))
+constant GHC.Types.I$35$$35$6c : (func(0, [int; int]))
+constant x_Tuple73 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(2)]))
+constant x_Tuple54 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(3)]))
+constant cmp : (func(0, [GHC.Types.Ordering; GHC.Types.Ordering]))
+constant x_Tuple32 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(1)]))
+constant x_Tuple76 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(5)]))
+constant fst : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant snd : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant x_Tuple42 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(1)]))
+constant GHC.Types.True$35$6u : (GHC.Types.Bool)
+
+
+bind 0 GHC.Types.False$35$68 : {VV$35$170 : GHC.Types.Bool | []}
+bind 1 GHC.Types.True$35$6u : {VV$35$172 : GHC.Types.Bool | []}
+bind 2 GHC.Num.$36$fNumInt$35$rma : {VV$35$178 : (GHC.Num.Num  int) | []}
+bind 3 GHC.Classes.$36$fOrdInt$35$rni : {VV$35$179 : (GHC.Classes.Ord  int) | []}
+bind 4 GHC.Types.EQ$35$6U : {VV$35$180 : GHC.Types.Ordering | [(VV$35$180 = GHC.Types.EQ$35$6U)]}
+bind 5 GHC.Types.LT$35$6S : {VV$35$181 : GHC.Types.Ordering | [(VV$35$181 = GHC.Types.LT$35$6S)]}
+bind 6 GHC.Types.GT$35$6W : {VV$35$182 : GHC.Types.Ordering | [(VV$35$182 = GHC.Types.GT$35$6W)]}
+bind 7 GHC.Types.True$35$6u : {v_4 : GHC.Types.Bool | [(? Prop([v_4]))]}
+bind 8 GHC.Types.False$35$68 : {v_5 : GHC.Types.Bool | [(~ ((? Prop([v_5]))))]}
+bind 9 GHC.Types.False$35$68 : {v_5 : GHC.Types.Bool | [(~ ((? Prop([v_5]))))]}
+bind 10 GHC.Types.$91$$93$$35$6m : {VV : func(1, [[@(0)]]) | []}
+bind 11 GHC.Types.True$35$6u : {v_4 : GHC.Types.Bool | [(? Prop([v_4]))]}
+bind 12 GHC.Types.GT$35$6W : {VV$35$227 : GHC.Types.Ordering | [(cmp([VV$35$227]) = GHC.Types.GT$35$6W)]}
+bind 13 GHC.Types.LT$35$6S : {VV$35$228 : GHC.Types.Ordering | [(cmp([VV$35$228]) = GHC.Types.LT$35$6S)]}
+bind 14 GHC.Types.EQ$35$6U : {VV$35$229 : GHC.Types.Ordering | [(cmp([VV$35$229]) = GHC.Types.EQ$35$6U)]}
+bind 15 GHC.Base.Nothing$35$r1d : {VV : func(1, [(GHC.Base.Maybe  @(0))]) | []}
+bind 16 lq_anf__d12p : {lq_tmp_x_238 : int | [(lq_tmp_x_238 = (0  :  int))]}
+bind 17 lq_anf__d12q : {lq_tmp_x_244 : int | []}
+bind 18 lq_anf__d12r : {lq_tmp_x_250 : int | [(lq_tmp_x_250 = (10  :  int))]}
+bind 19 Test0.toss$35$rYP : {VV$35$234 : GHC.Types.Bool | [$k__235]}
+bind 20 lq_anf__d12s : {lq_tmp_x_275 : GHC.Types.Bool | [(lq_tmp_x_275 = Test0.toss$35$rYP)]}
+bind 21 lq_anf__d12s : {lq_tmp_x_277 : GHC.Types.Bool | [(lq_tmp_x_277 = Test0.toss$35$rYP)]}
+bind 22 lq_anf__d12s : {lq_tmp_x_277 : GHC.Types.Bool | [(lq_tmp_x_277 = Test0.toss$35$rYP);
+                                                         (~ ((? Prop([lq_tmp_x_277]))));
+                                                         (~ ((? Prop([lq_tmp_x_277]))));
+                                                         (~ ((? Prop([lq_tmp_x_277]))))]}
+bind 23 lq_anf__d12s : {lq_tmp_x_283 : GHC.Types.Bool | [(lq_tmp_x_283 = Test0.toss$35$rYP)]}
+bind 24 lq_anf__d12s : {lq_tmp_x_283 : GHC.Types.Bool | [(lq_tmp_x_283 = Test0.toss$35$rYP);
+                                                         (? Prop([lq_tmp_x_283]));
+                                                         (? Prop([lq_tmp_x_283]));
+                                                         (? Prop([lq_tmp_x_283]))]}
+bind 25 lq_anf__d12t : {lq_tmp_x_288 : GHC.Types.Bool | [(lq_tmp_x_288 = lq_anf__d12s)]}
+bind 26 lq_anf__d12t : {lq_tmp_x_290 : GHC.Types.Bool | [(lq_tmp_x_290 = lq_anf__d12s)]}
+bind 27 lq_anf__d12t : {lq_tmp_x_290 : GHC.Types.Bool | [(lq_tmp_x_290 = lq_anf__d12s);
+                                                         (~ ((? Prop([lq_tmp_x_290]))));
+                                                         (~ ((? Prop([lq_tmp_x_290]))));
+                                                         (~ ((? Prop([lq_tmp_x_290]))))]}
+bind 28 lq_anf__d12t : {lq_tmp_x_296 : GHC.Types.Bool | [(lq_tmp_x_296 = lq_anf__d12s)]}
+bind 29 lq_anf__d12t : {lq_tmp_x_296 : GHC.Types.Bool | [(lq_tmp_x_296 = lq_anf__d12s);
+                                                         (? Prop([lq_tmp_x_296]));
+                                                         (? Prop([lq_tmp_x_296]));
+                                                         (? Prop([lq_tmp_x_296]))]}
+bind 30 Test0.prop_abs$35$r10h : {VV$35$272 : GHC.Types.Bool | [$k__273]}
+bind 31 x$35$a11A : {VV$35$307 : int | [$k__308]}
+bind 32 lq_anf__d12u : {lq_tmp_x_315 : int | [(lq_tmp_x_315 = (0  :  int))]}
+bind 33 lq_anf__d12v : {lq_tmp_x_321 : GHC.Types.Bool | [((? Prop([lq_tmp_x_321])) <=> (x$35$a11A > lq_anf__d12u))]}
+bind 34 lq_anf__d12w : {lq_tmp_x_345 : int | [$k__343[lq_tmp_x_340:=lq_anf__d12v][VV$35$342:=lq_tmp_x_345][lq_tmp_x_341:=x$35$a11A]]}
+bind 35 lq_anf__d12x : {lq_tmp_x_350 : int | [(lq_tmp_x_350 = (1  :  int))]}
+bind 36 lq_anf__d12y : {lq_tmp_x_373 : int | [(lq_tmp_x_373 = (12  :  int))]}
+bind 37 Test0.goo$35$r10j : {VV$35$369 : int | [$k__370]}
+bind 38 zzz$35$a11B : {VV$35$384 : int | [$k__385]}
+bind 39 lq_anf__d12z : {lq_tmp_x_392 : int | [(lq_tmp_x_392 = (1  :  int))]}
+bind 40 lq_anf__d12A : {lq_tmp_x_415 : int | [(lq_tmp_x_415 = (29  :  int))]}
+bind 41 Test0.zoo$35$r10l : {VV$35$411 : int | [$k__412]}
+bind 42 VV$35$426 : {VV$35$426 : int | [$k__389[lq_tmp_x_423:=lq_anf__d12A][lq_tmp_x_421:=VV$35$426][zzz$35$a11B:=lq_anf__d12A][VV$35$388:=VV$35$426]]}
+bind 43 VV$35$426 : {VV$35$426 : int | [$k__389[lq_tmp_x_423:=lq_anf__d12A][lq_tmp_x_421:=VV$35$426][zzz$35$a11B:=lq_anf__d12A][VV$35$388:=VV$35$426]]}
+bind 44 VV$35$429 : {VV$35$429 : int | [(VV$35$429 = lq_anf__d12A)]}
+bind 45 VV$35$429 : {VV$35$429 : int | [(VV$35$429 = lq_anf__d12A)]}
+bind 46 VV$35$432 : {VV$35$432 : int | [(VV$35$432 = 29)]}
+bind 47 VV$35$432 : {VV$35$432 : int | [(VV$35$432 = 29)]}
+bind 48 VV$35$435 : {VV$35$435 : int | [(VV$35$435 = (zzz$35$a11B + lq_anf__d12z))]}
+bind 49 VV$35$435 : {VV$35$435 : int | [(VV$35$435 = (zzz$35$a11B + lq_anf__d12z))]}
+bind 50 VV$35$438 : {VV$35$438 : int | [(VV$35$438 = lq_anf__d12z)]}
+bind 51 VV$35$438 : {VV$35$438 : int | [(VV$35$438 = lq_anf__d12z)]}
+bind 52 VV$35$441 : {VV$35$441 : int | [(VV$35$441 = zzz$35$a11B)]}
+bind 53 VV$35$441 : {VV$35$441 : int | [(VV$35$441 = zzz$35$a11B)]}
+bind 54 VV$35$444 : {VV$35$444 : int | [(VV$35$444 = 1)]}
+bind 55 VV$35$444 : {VV$35$444 : int | [(VV$35$444 = 1)]}
+bind 56 VV$35$447 : {VV$35$447 : int | [$k__312[VV$35$311:=VV$35$447][lq_tmp_x_381:=lq_anf__d12y][x$35$a11A:=lq_anf__d12y][lq_tmp_x_379:=VV$35$447]]}
+bind 57 VV$35$447 : {VV$35$447 : int | [$k__312[VV$35$311:=VV$35$447][lq_tmp_x_381:=lq_anf__d12y][x$35$a11A:=lq_anf__d12y][lq_tmp_x_379:=VV$35$447]]}
+bind 58 VV$35$450 : {VV$35$450 : int | [(VV$35$450 = lq_anf__d12y)]}
+bind 59 VV$35$450 : {VV$35$450 : int | [(VV$35$450 = lq_anf__d12y)]}
+bind 60 VV$35$453 : {VV$35$453 : int | [(VV$35$453 = 12)]}
+bind 61 VV$35$453 : {VV$35$453 : int | [(VV$35$453 = 12)]}
+bind 62 VV$35$456 : {VV$35$456 : int | [(VV$35$456 = (lq_anf__d12w + lq_anf__d12x))]}
+bind 63 VV$35$456 : {VV$35$456 : int | [(VV$35$456 = (lq_anf__d12w + lq_anf__d12x))]}
+bind 64 VV$35$459 : {VV$35$459 : int | [(VV$35$459 = lq_anf__d12x)]}
+bind 65 VV$35$459 : {VV$35$459 : int | [(VV$35$459 = lq_anf__d12x)]}
+bind 66 VV$35$462 : {VV$35$462 : int | [(VV$35$462 = lq_anf__d12w)]}
+bind 67 VV$35$462 : {VV$35$462 : int | [(VV$35$462 = lq_anf__d12w)]}
+bind 68 VV$35$465 : {VV$35$465 : int | [(VV$35$465 = 1)]}
+bind 69 VV$35$465 : {VV$35$465 : int | [(VV$35$465 = 1)]}
+bind 70 VV$35$468 : {VV$35$468 : int | [(VV$35$468 = x$35$a11A)]}
+bind 71 VV$35$468 : {VV$35$468 : int | [(VV$35$468 = x$35$a11A)]}
+bind 72 VV$35$471 : {VV$35$471 : GHC.Types.Bool | [(VV$35$471 = lq_anf__d12v)]}
+bind 73 VV$35$471 : {VV$35$471 : GHC.Types.Bool | [(VV$35$471 = lq_anf__d12v)]}
+bind 74 VV$35$474 : {VV$35$474 : int | [(VV$35$474 = lq_anf__d12u)]}
+bind 75 VV$35$474 : {VV$35$474 : int | [(VV$35$474 = lq_anf__d12u)]}
+bind 76 VV$35$477 : {VV$35$477 : int | [(VV$35$477 = x$35$a11A)]}
+bind 77 VV$35$477 : {VV$35$477 : int | [(VV$35$477 = x$35$a11A)]}
+bind 78 VV$35$480 : {VV$35$480 : int | [(VV$35$480 = 0)]}
+bind 79 VV$35$480 : {VV$35$480 : int | [(VV$35$480 = 0)]}
+bind 80 VV$35$483 : {VV$35$483 : GHC.Types.Bool | [(? Prop([VV$35$483]))]}
+bind 81 VV$35$483 : {VV$35$483 : GHC.Types.Bool | [(? Prop([VV$35$483]))]}
+bind 82 VV$35$486 : {VV$35$486 : GHC.Types.Bool | [(VV$35$486 = lq_anf__d12t)]}
+bind 83 VV$35$486 : {VV$35$486 : GHC.Types.Bool | [(VV$35$486 = lq_anf__d12t)]}
+bind 84 VV$35$489 : {VV$35$489 : GHC.Types.Bool | [(VV$35$489 = GHC.Types.False$35$68)]}
+bind 85 VV$35$489 : {VV$35$489 : GHC.Types.Bool | [(VV$35$489 = GHC.Types.False$35$68)]}
+bind 86 VV$35$492 : {VV$35$492 : GHC.Types.Bool | [(VV$35$492 = GHC.Types.False$35$68)]}
+bind 87 VV$35$492 : {VV$35$492 : GHC.Types.Bool | [(VV$35$492 = GHC.Types.False$35$68)]}
+bind 88 VV$35$495 : {VV$35$495 : GHC.Types.Bool | [((? Prop([VV$35$495])) <=> (lq_anf__d12q > lq_anf__d12r))]}
+bind 89 VV$35$495 : {VV$35$495 : GHC.Types.Bool | [((? Prop([VV$35$495])) <=> (lq_anf__d12q > lq_anf__d12r))]}
+bind 90 VV$35$498 : {VV$35$498 : int | [(VV$35$498 = lq_anf__d12r)]}
+bind 91 VV$35$498 : {VV$35$498 : int | [(VV$35$498 = lq_anf__d12r)]}
+bind 92 VV$35$501 : {VV$35$501 : int | [(VV$35$501 = lq_anf__d12q)]}
+bind 93 VV$35$501 : {VV$35$501 : int | [(VV$35$501 = lq_anf__d12q)]}
+bind 94 VV$35$504 : {VV$35$504 : int | [(VV$35$504 = 10)]}
+bind 95 VV$35$504 : {VV$35$504 : int | [(VV$35$504 = 10)]}
+bind 96 VV$35$507 : {VV$35$507 : int | [(VV$35$507 = lq_anf__d12p)]}
+bind 97 VV$35$507 : {VV$35$507 : int | [(VV$35$507 = lq_anf__d12p)]}
+bind 98 VV$35$510 : {VV$35$510 : int | [(VV$35$510 = 0)]}
+bind 99 VV$35$510 : {VV$35$510 : int | [(VV$35$510 = 0)]}
+bind 100 VV$35$411 : {VV$35$411 : int | [$k__412]}
+bind 101 VV$35$384 : {VV$35$384 : int | [$k__385]}
+bind 102 VV$35$388 : {VV$35$388 : int | [$k__389]}
+bind 103 VV$35$369 : {VV$35$369 : int | [$k__370]}
+bind 104 VV$35$307 : {VV$35$307 : int | [$k__308]}
+bind 105 VV$35$342 : {VV$35$342 : int | [$k__343]}
+bind 106 VV$35$328 : {VV$35$328 : int | [$k__329]}
+bind 107 VV$35$311 : {VV$35$311 : int | [$k__312]}
+bind 108 VV$35$272 : {VV$35$272 : GHC.Types.Bool | [$k__273]}
+bind 109 VV$35$263 : {VV$35$263 : int | [$k__264]}
+bind 110 VV$35$234 : {VV$35$234 : GHC.Types.Bool | [$k__235]}
+
+
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       19;
+       4;
+       36;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       58;
+       11;
+       12;
+       13;
+       14;
+       30;
+       15]
+  lhs {VV$35$F5 : int | [(VV$35$F5 = lq_anf__d12y)]}
+  rhs {VV$35$F5 : int | [$k__308[VV$35$307:=VV$35$F5][VV$35$F:=VV$35$F5][VV$35$450:=VV$35$F5][lq_tmp_x_378:=VV$35$F5]]}
+  id 5 tag [4]
+  // META constraint id 5 : tests/pos/test000.hs:16:11-12
+
+
+constraint:
+  env [0;
+       32;
+       1;
+       33;
+       2;
+       3;
+       19;
+       4;
+       5;
+       6;
+       7;
+       8;
+       72;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       30;
+       15;
+       31]
+  lhs {VV$35$F8 : GHC.Types.Bool | [(VV$35$F8 = lq_anf__d12v)]}
+  rhs {VV$35$F8 : GHC.Types.Bool | [(? Prop([VV$35$F8]))]}
+  id 8 tag [3]
+  // META constraint id 8 : tests/pos/test000.hs:14:23-29
+
+
+constraint:
+  env [0;
+       80;
+       1;
+       2;
+       3;
+       19;
+       4;
+       20;
+       5;
+       6;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       11;
+       12;
+       28;
+       13;
+       29;
+       14;
+       15]
+  lhs {VV$35$F11 : GHC.Types.Bool | [(? Prop([VV$35$F11]))]}
+  rhs {VV$35$F11 : GHC.Types.Bool | [$k__273[VV$35$272:=VV$35$F11][VV$35$F:=VV$35$F11][VV$35$483:=VV$35$F11]]}
+  id 11 tag [6]
+  // META constraint id 11 : tests/pos/test000.hs:10:33-50
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       82;
+       3;
+       19;
+       4;
+       20;
+       5;
+       6;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       11;
+       12;
+       28;
+       13;
+       29;
+       14;
+       15]
+  lhs {VV$35$F12 : GHC.Types.Bool | [(VV$35$F12 = lq_anf__d12t)]}
+  rhs {VV$35$F12 : GHC.Types.Bool | [(? Prop([VV$35$F12]))]}
+  id 12 tag [6]
+  // META constraint id 12 : tests/pos/test000.hs:10:47-50
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       19;
+       4;
+       20;
+       84;
+       5;
+       6;
+       7;
+       23;
+       8;
+       24;
+       9;
+       25;
+       10;
+       26;
+       11;
+       27;
+       12;
+       13;
+       14;
+       15]
+  lhs {VV$35$F13 : GHC.Types.Bool | [(VV$35$F13 = GHC.Types.False$35$68)]}
+  rhs {VV$35$F13 : GHC.Types.Bool | [$k__273[VV$35$272:=VV$35$F13][VV$35$489:=VV$35$F13][VV$35$F:=VV$35$F13]]}
+  id 13 tag [6]
+  // META constraint id 13 : tests/pos/test000.hs:10:57-61
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       19;
+       4;
+       20;
+       5;
+       21;
+       6;
+       22;
+       86;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15]
+  lhs {VV$35$F14 : GHC.Types.Bool | [(VV$35$F14 = GHC.Types.False$35$68)]}
+  rhs {VV$35$F14 : GHC.Types.Bool | [$k__273[VV$35$272:=VV$35$F14][VV$35$F:=VV$35$F14][VV$35$492:=VV$35$F14]]}
+  id 14 tag [6]
+  // META constraint id 14 : tests/pos/test000.hs:11:19-23
+
+
+constraint:
+  env [0;
+       16;
+       1;
+       17;
+       2;
+       18;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       88;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       15]
+  lhs {VV$35$F15 : GHC.Types.Bool | [((? Prop([VV$35$F15])) <=> (lq_anf__d12q > lq_anf__d12r))]}
+  rhs {VV$35$F15 : GHC.Types.Bool | [$k__235[VV$35$F:=VV$35$F15][VV$35$495:=VV$35$F15][VV$35$234:=VV$35$F15]]}
+  id 15 tag [5]
+  // META constraint id 15 : tests/pos/test000.hs:6:1-22
+
+
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15]
+  reft {VV$35$234 : GHC.Types.Bool | [$k__235]}
+  // META wf : <no location info>
+
+
+wf:
+  env [0; 1; 2; 3; 19; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 30; 15]
+  reft {VV$35$307 : int | [$k__308]}
+  // META wf : <no location info>
+
+
+wf:
+  env [0; 1; 2; 3; 19; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15]
+  reft {VV$35$272 : GHC.Types.Bool | [$k__273]}
+  // META wf : tests/pos/test000.hs:(9,1)-(11,23)
+
+
+
+
+
+
+
diff --git a/liquid-fixpoint/tests/pos/test00a.fq b/liquid-fixpoint/tests/pos/test00a.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test00a.fq
@@ -0,0 +1,28 @@
+// This qualifier saves the day; solve constraints WITHOUT IT
+qualif Zog(v:a) : (10 <= v)
+
+bind 0 x : {v : int | true}
+bind 1 y : {v : int | true}
+bind 2 z : {v : int | true}
+
+constraint:
+  env [0]
+  lhs {v : int | (x = 10)}
+  rhs {v : int | $k0[v:=x]}
+  id 1 tag []
+
+constraint:
+  env [1]
+  lhs {v : int | y = 20}
+  rhs {v : int | $k0[v:=y]}
+  id 2 tag []
+
+constraint:
+  env [2]
+  lhs {v : int | $k0[v:=z]}
+  rhs {v : int | 10 <= z}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
diff --git a/liquid-fixpoint/tests/pos/test1.fq b/liquid-fixpoint/tests/pos/test1.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test1.fq
@@ -0,0 +1,29 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+qualif Zog(v:a) : (10 <= v)
+
+bind 0 x : {v : int | v = 10}
+bind 1 y : {v : int | v = 20}
+bind 2 a : {v : int | $k0    }
+      
+constraint:
+  env [0]
+  lhs {v : int | v = x}
+  rhs {v : int | $k0   }
+  id 1 tag []
+
+constraint:
+  env [1]
+  lhs {v : int | v = y}
+  rhs {v : int | $k0   }
+  id 2 tag []
+
+constraint:
+  env [2]
+  lhs {v : int | v = a  }
+  rhs {v : int | 10 <= v}
+  id 3 tag []
+
+wf:
+  env [ ]
+  reft {v : int | $k0}
diff --git a/liquid-fixpoint/tests/pos/test2.fq b/liquid-fixpoint/tests/pos/test2.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test2.fq
@@ -0,0 +1,51 @@
+
+// This qualifier saves the day; solve constraints WITHOUT IT
+qualif Zog(v:a): (10 <= v)
+
+// But you may use this one
+qualif Pog(v:a): (0 <= v)
+
+bind 0 x: {v: int | v = 10}
+bind 1 a: {v: int | $k1    }
+bind 2 y: {v: int | v = 20}
+bind 3 b: {v: int | $k1    }
+bind 4 c: {v: int | $k0    }
+
+constraint:
+  env [ ]
+  lhs {v : int | v = 0}
+  rhs {v : int | $k1 }
+  id 0 tag []
+
+
+constraint:
+  env [0; 1]
+  lhs {v : int | v = x + a}
+  rhs {v : int | $k0}
+  id 1 tag []
+
+constraint:
+  env [2; 3]
+  lhs {v : int | v = y + b}
+  rhs {v : int | $k0}
+  id 2 tag []
+
+constraint:
+  env [ ]
+  lhs {v : int | $k0}
+  rhs {v : int | $k1}
+  id 3 tag []
+
+constraint:
+  env [4]
+  lhs {v : int | v = c  }
+  rhs {v : int | 10 <= v}
+  id 4 tag []
+
+wf:
+  env [ ]
+  reft {v: int | $k0}
+
+wf:
+  env [ ]
+  reft {v: int | $k1}
diff --git a/liquid-fixpoint/tests/pos/test3.fq b/liquid-fixpoint/tests/pos/test3.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test3.fq
@@ -0,0 +1,22 @@
+
+qualif Zog(v:a, z:b) : (v = z)
+
+bind 0 x : {v : int | true}
+bind 1 q : {v : int | true}
+bind 2 y : {v : int | v = 10}
+
+constraint:
+  env [1]
+  lhs {v : int | v = q}
+  rhs {v : int | $k0[x:=q] }
+  id 1 tag []
+
+constraint:
+  env [2]
+  lhs {v : int | $k0[x:=y]}
+  rhs {v : int | v = 10}
+  id 2 tag []
+
+wf:
+  env [0]
+  reft {v : int | $k0}
diff --git a/liquid-fixpoint/tests/pos/test4.fq b/liquid-fixpoint/tests/pos/test4.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/test4.fq
@@ -0,0 +1,19 @@
+qualif Auto(v_2 : a_ax6, A0 : a_ax6): (v_2 = A0)
+
+bind 20 ds_dxx : {VV263 : a_ax6 | []}
+
+constraint:
+  env [20]
+  lhs {VVF4 : a_ax6 | [$k__511[VV510:=VVF4]]}
+  rhs {VVF4 : a_ax6 | [(VVF4 = ds_dxx)]}
+  id 4 tag [3]
+
+constraint:
+  env [20]
+  lhs {VVF9 : a_ax6 | [(VVF9 = ds_dxx)]}
+  rhs {VVF9 : a_ax6 | [$k__511[VV510:=VVF9]]}
+  id 9 tag [3]
+
+wf:
+  env [20]
+  reft {VV510 : a_ax6 | [$k__511]}
diff --git a/liquid-fixpoint/tests/pos/unexpected-ge.fq b/liquid-fixpoint/tests/pos/unexpected-ge.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/unexpected-ge.fq
@@ -0,0 +1,2 @@
+
+qualif Auto(v : int, x : int): (v = (if (x > 0) then 0 else 0))
diff --git a/liquid-fixpoint/tests/pos/unused.fq b/liquid-fixpoint/tests/pos/unused.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/unused.fq
@@ -0,0 +1,11 @@
+constant len : func(0, [Tree; int])
+
+bind 0 x : {v : int  | true} 
+bind 1 x : {v : Tree | true} 
+bind 2 y : {v : int  | v = len x } 
+
+constraint:
+  env [ ]
+  lhs {v : Tree | 666 < len v }
+  rhs {v : Tree | 66  < len v }
+  id 1 tag []
diff --git a/liquid-fixpoint/tests/pos/wl00.fq b/liquid-fixpoint/tests/pos/wl00.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/wl00.fq
@@ -0,0 +1,50 @@
+qualif Nat(v:int) : (0 <= v)
+qualif N10(v:int) : (10 = v)
+qualif N20(v:int) : (20 = v)
+
+bind 0 x0 : {v: int | [$k0]}
+
+bind 1 x1 : {v: int | [$k1]}
+
+cut $k0
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 10]}
+  rhs {v : int | [$k0]}
+  id 1 tag [0]
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 20]}
+  rhs {v : int | [$k0]}
+  id 2 tag [0]
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | [v = x0 + 7]}
+  rhs {v : int | [$k1]}
+  id 3 tag [0]
+
+
+constraint:
+  env [ 1 ]
+  lhs {v : int | [v = x1 + 9]}
+  rhs {v : int | [$k0]}
+  id 4 tag [0]
+
+
+constraint:
+  env [ 1 ]
+  lhs {v : int | [v = x1]}
+  rhs {v : int | [0 <= v]}
+  id 5 tag [0]
+
+wf:
+  env [ ]
+  reft {v: int | [$k0]}
+
+
+wf:
+  env [ ]
+  reft {v: int | [$k1]}
diff --git a/liquid-fixpoint/tests/pos/wl01.fq b/liquid-fixpoint/tests/pos/wl01.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/wl01.fq
@@ -0,0 +1,39 @@
+qualif Nat(v:int) : (0 <= v)
+
+bind 0 x : {v: int | [$k0]}
+bind 1 y : {v: int | [$k0]}
+bind 2 z : {v: int | [$k1]}
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 10]}
+  rhs {v : int | [$k0]}
+  id 1 tag [0]
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | [v = x + x]}
+  rhs {v : int | [$k0]}
+  id 2 tag [0]
+
+constraint:
+  env [ 0; 1 ]
+  lhs {v : int | [v = x + y ]}
+  rhs {v : int | [$k1]}
+  id 3 tag [0]
+
+
+constraint:
+  env [ 2 ]
+  lhs {v : int | [v =  z]}
+  rhs {v : int | [0 <= v]}
+  id 4 tag [0]
+
+wf:
+  env [ ]
+  reft {v: int | [$k0]}
+
+
+wf:
+  env [ ]
+  reft {v: int | [$k1]}
diff --git a/liquid-fixpoint/tests/pos/wl02.fq b/liquid-fixpoint/tests/pos/wl02.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/wl02.fq
@@ -0,0 +1,242 @@
+qualif Nat(v:int) : (0 <= v)
+
+bind 0  x0  : {v: int | [$k0]}
+bind 1  x1  : {v: int | [$k1]}
+bind 2  x2  : {v: int | [$k2]}
+bind 3  x3  : {v: int | [$k3]}
+bind 4  x4  : {v: int | [$k4]}
+bind 5  x5  : {v: int | [$k5]}
+bind 6  x6  : {v: int | [$k6]}
+bind 7  x7  : {v: int | [$k7]}
+bind 8  x8  : {v: int | [$k8]}
+bind 9  x9  : {v: int | [$k9]}
+bind 10 x10 : {v: int | [$k10]}
+bind 11 x11 : {v: int | [$k11]}
+bind 12 x12 : {v: int | [$k12]}
+bind 13 x13 : {v: int | [$k13]}
+bind 14 x14 : {v: int | [$k14]}
+bind 15 x15 : {v: int | [$k15]}
+bind 16 x16 : {v: int | [$k16]}
+bind 17 x17 : {v: int | [$k17]}
+bind 18 x18 : {v: int | [$k18]}
+bind 19 x19 : {v: int | [$k19]}
+bind 20 x20 : {v: int | [$k20]}
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 10]}
+  rhs {v : int | [$k0]}
+  id 0 tag [0]
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | [v = x0]}
+  rhs {v : int | [$k1]}
+  id 1 tag [0]
+
+constraint:
+  env [ 1 ]
+  lhs {v : int | [v = x1]}
+  rhs {v : int | [$k2]}
+  id 2 tag [0]
+
+
+constraint:
+  env [ 2 ]
+  lhs {v : int | [v = x2]}
+  rhs {v : int | [$k3]}
+  id 3 tag [0]
+
+constraint:
+  env [ 3 ]
+  lhs {v : int | [v = x3]}
+  rhs {v : int | [$k4]}
+  id 4 tag [0]
+
+constraint:
+  env [ 4 ]
+  lhs {v : int | [v = x4]}
+  rhs {v : int | [$k5]}
+  id 5 tag [0]
+
+constraint:
+  env [ 5 ]
+  lhs {v : int | [v = x5]}
+  rhs {v : int | [$k6]}
+  id 6 tag [0]
+
+constraint:
+  env [ 6 ]
+  lhs {v : int | [v = x6]}
+  rhs {v : int | [$k7]}
+  id 7 tag [0]
+
+constraint:
+  env [ 7 ]
+  lhs {v : int | [v = x7]}
+  rhs {v : int | [$k8]}
+  id 8 tag [0]
+
+constraint:
+  env [ 8 ]
+  lhs {v : int | [v = x8]}
+  rhs {v : int | [$k9]}
+  id 9 tag [0]
+
+constraint:
+  env [ 9 ]
+  lhs {v : int | [v = x9]}
+  rhs {v : int | [$k10]}
+  id 10 tag [0]
+
+constraint:
+  env [ 10 ]
+  lhs {v : int | [v = x10]}
+  rhs {v : int | [$k11]}
+  id 11 tag [0]
+
+constraint:
+  env [ 11 ]
+  lhs {v : int | [v = x11]}
+  rhs {v : int | [$k12]}
+  id 12 tag [0]
+
+
+constraint:
+  env [ 12 ]
+  lhs {v : int | [v = x12]}
+  rhs {v : int | [$k13]}
+  id 13 tag [0]
+
+constraint:
+  env [ 13 ]
+  lhs {v : int | [v = x13]}
+  rhs {v : int | [$k14]}
+  id 14 tag [0]
+
+constraint:
+  env [ 14 ]
+  lhs {v : int | [v = x14]}
+  rhs {v : int | [$k15]}
+  id 15 tag [0]
+
+constraint:
+  env [ 15 ]
+  lhs {v : int | [v = x15]}
+  rhs {v : int | [$k16]}
+  id 16 tag [0]
+
+constraint:
+  env [ 16 ]
+  lhs {v : int | [v = x16]}
+  rhs {v : int | [$k17]}
+  id 17 tag [0]
+
+constraint:
+  env [ 17 ]
+  lhs {v : int | [v = x17]}
+  rhs {v : int | [$k18]}
+  id 18 tag [0]
+
+constraint:
+  env [ 18 ]
+  lhs {v : int | [v = x18]}
+  rhs {v : int | [$k19]}
+  id 19 tag [0]
+
+constraint:
+  env [ 19 ]
+  lhs {v : int | [v = x19]}
+  rhs {v : int | [$k20]}
+  id 20 tag [0]
+
+constraint:
+  env [ 20 ]
+  lhs {v : int | [v = x20]}
+  rhs {v : int | [0 <= v]}
+  id 100 tag [0]
+
+wf:
+  env [ ]
+  reft {v: int | [$k0]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k1]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k2]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k3]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k4]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k5]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k6]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k7]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k8]}
+
+
+wf:
+  env [ ]
+  reft {v: int | [$k9]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k10]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k11]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k12]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k13]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k14]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k15]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k16]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k17]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k18]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k19]}
+
+wf:
+  env [ ]
+  reft {v: int | [$k20]}
diff --git a/liquid-fixpoint/tests/pos/wrong-arity.fq b/liquid-fixpoint/tests/pos/wrong-arity.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/pos/wrong-arity.fq
@@ -0,0 +1,16 @@
+// adapted from LH test vector2.hs
+
+constant foo : func(0, [int; int])
+
+// UNCOMMENT THIS FOR CRASH
+bind 1 foo : {v: func(0, [int; int]) | true }
+
+bind 2 foo : {v: func(0, [int; int]) | true }
+
+bind 3 z   : {v : int | [ v = foo 42 ]}
+
+constraint:
+  env [3]
+  lhs {VV : int | [(VV >= 0)]}
+  rhs {VV : int | [(VV >= 0)]}
+  id 107 tag [1]
diff --git a/liquid-fixpoint/tests/smt2/Smt.hs b/liquid-fixpoint/tests/smt2/Smt.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/smt2/Smt.hs
@@ -0,0 +1,28 @@
+-- just fire up ghci, :load Smt.hs and run `go file.smt2`
+
+module Smt where
+
+import qualified Data.Text.Lazy.IO as T
+
+import Language.Fixpoint.Types.Config (SMTSolver (..))
+import Language.Fixpoint.Parse
+import Language.Fixpoint.SmtLib2
+import System.Environment
+
+main    = do f:_ <- getArgs
+             _   <- go f
+             return ()
+
+runFile f
+  = readFile f >>= runString
+
+runString str
+  = runCommands $ rr str
+
+runCommands cmds 
+  = do me   <- makeContext Z3
+       mapM_ (T.putStrLn . smt2) cmds
+       zs   <- mapM (command me) cmds
+       return zs
+
+
diff --git a/liquid-fixpoint/tests/test.hs b/liquid-fixpoint/tests/test.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/test.hs
@@ -0,0 +1,251 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Main where
+
+import Control.Applicative
+import System.Directory
+import System.Exit
+import System.FilePath
+import System.Environment
+import System.IO
+import System.IO.Error
+import System.Process
+import Test.Tasty
+import Test.Tasty.HUnit
+import Text.Printf
+
+main :: IO ()
+main = defaultMain =<< group "Tests" [unitTests]
+
+unitTests
+  = group "Unit" [
+      testGroup "native-pos" <$> dirTests nativeCmd "tests/pos"    skipNativePos  ExitSuccess
+    , testGroup "native-neg" <$> dirTests nativeCmd "tests/neg"    []             (ExitFailure 1)
+    , testGroup "elim-crash" <$> dirTests nativeCmd "tests/crash"  []             (ExitFailure 2)
+    , testGroup "elim-pos1"  <$> dirTests elimCmd   "tests/pos"    []             ExitSuccess
+    , testGroup "elim-pos2"  <$> dirTests elimCmd   "tests/elim"   []             ExitSuccess
+    , testGroup "elim-neg"   <$> dirTests elimCmd   "tests/neg"    []             (ExitFailure 1)
+    , testGroup "elim-crash" <$> dirTests elimCmd   "tests/crash"  []             (ExitFailure 2)
+   ]
+
+skipNativePos :: [FilePath]
+skipNativePos = ["NonLinear-pack.fq"]
+
+---------------------------------------------------------------------------
+dirTests :: TestCmd -> FilePath -> [FilePath] -> ExitCode -> IO [TestTree]
+---------------------------------------------------------------------------
+dirTests testCmd root ignored code
+  = do files    <- walkDirectory root
+       let tests = [ rel | f <- files, isTest f, let rel = makeRelative root f, rel `notElem` ignored ]
+       return    $ mkTest testCmd code root <$> tests
+
+isTest   :: FilePath -> Bool
+isTest f = takeExtension f `elem` [".fq"]
+
+---------------------------------------------------------------------------
+mkTest :: TestCmd -> ExitCode -> FilePath -> FilePath -> TestTree
+---------------------------------------------------------------------------
+mkTest testCmd code dir file
+  = testCase file $
+      if test `elem` knownToFail
+      then do
+        printf "%s is known to fail: SKIPPING" test
+        assertEqual "" True True
+      else do
+        createDirectoryIfMissing True $ takeDirectory log
+        bin <- binPath "fixpoint"
+        withFile log WriteMode $ \h -> do
+          let cmd     = testCmd bin dir file
+          (_,_,_,ph) <- createProcess $ (shell cmd) {std_out = UseHandle h, std_err = UseHandle h}
+          c          <- waitForProcess ph
+          assertEqual "Wrong exit code" code c
+  where
+    test = dir </> file
+    log  = let (d,f) = splitFileName file in dir </> d </> ".liquid" </> f <.> "log"
+
+binPath pkgName = do
+  testPath <- getExecutablePath
+  return    $ (takeDirectory $ takeDirectory testPath) </> pkgName </> pkgName
+
+knownToFail = []
+---------------------------------------------------------------------------
+type TestCmd = FilePath -> FilePath -> FilePath -> String
+
+nativeCmd :: TestCmd
+nativeCmd bin dir file = printf "cd %s && %s %s" dir bin file
+
+elimCmd :: TestCmd
+elimCmd bin dir file = printf "cd %s && %s --eliminate=some %s" dir bin file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+---------------------------------------------------------------------------
+
+{-
+
+quickCheckTests :: TestTree
+quickCheckTests
+  = testGroup "Properties"
+      [ testProperty "prop_pprint_parse_inv_expr" prop_pprint_parse_inv_expr
+      , testProperty "prop_pprint_parse_inv_pred" prop_pprint_parse_inv_pred
+      ]
+
+prop_pprint_parse_inv_pred :: Pred -> Bool
+prop_pprint_parse_inv_pred p = p == rr (showpp p)
+
+prop_pprint_parse_inv_expr :: Expr -> Bool
+prop_pprint_parse_inv_expr p = simplify p == rr (showpp $ simplify p)
+
+instance Arbitrary Sort where
+  arbitrary = sized arbSort
+
+arbSort 0 = oneof [return FInt, return FReal, return FNum]
+arbSort n = frequency
+              [(1, return FInt)
+              ,(1, return FReal)
+              ,(1, return FNum)
+              ,(2, fmap FObj arbitrary)
+              ]
+
+
+instance Arbitrary Pred where
+  arbitrary = sized arbPred
+  shrink = filter valid . genericShrink
+    where
+      valid (PAnd [])  = False
+      valid (PAnd [_]) = False
+      valid (POr [])   = False
+      valid (POr [_])  = False
+      valid (PBexp (EBin _ _ _)) = True
+      valid (PBexp _)  = False
+      valid _          = True
+
+arbPred 0 = elements [PTrue, PFalse]
+arbPred n = frequency
+              [(1, return PTrue)
+              ,(1, return PFalse)
+              ,(2, fmap PAnd  twoPreds)
+              ,(2, fmap POr   twoPreds)
+              ,(2, fmap PNot (arbPred (n `div` 2)))
+              ,(2, liftM2 PImp (arbPred (n `div` 2)) (arbPred (n `div` 2)))
+              ,(2, liftM2 PIff (arbPred (n `div` 2)) (arbPred (n `div` 2)))
+              ,(2, fmap PBexp (arbExpr (n `div` 2)))
+              ,(2, liftM3 PAtom arbitrary (arbExpr (n `div` 2)) (arbExpr (n `div` 2)))
+              -- ,liftM2 PAll arbitrary arbitrary
+              -- ,return PTop
+              ]
+  where
+    twoPreds = do
+      x <- arbPred (n `div` 2)
+      y <- arbPred (n `div` 2)
+      return [x,y]
+
+instance Arbitrary Expr where
+  arbitrary = sized arbExpr
+  shrink = filter valid . genericShrink
+    where valid (EApp _ []) = False
+          valid _           = True
+
+arbExpr 0 = oneof [fmap ESym arbitrary, fmap ECon arbitrary, fmap EVar arbitrary, return EBot]
+arbExpr n = frequency
+              [(1, fmap ESym arbitrary)
+              ,(1, fmap ECon arbitrary)
+              ,(1, fmap EVar arbitrary)
+              ,(1, return EBot)
+              -- ,liftM2 ELit arbitrary arbitrary -- restrict literals somehow
+              ,(2, choose (1,3) >>= \m -> liftM2 EApp arbitrary (vectorOf m (arbExpr (n `div` 2))))
+              ,(2, liftM3 EBin arbitrary (arbExpr (n `div` 2)) (arbExpr (n `div` 2)))
+              ,(2, liftM3 EIte (arbPred (max 2 (n `div` 2)) `suchThat` isRel)
+                               (arbExpr (n `div` 2))
+                               (arbExpr (n `div` 2)))
+              ,(2, liftM2 ECst (arbExpr (n `div` 2)) (arbSort (n `div` 2)))
+              ]
+  where
+    isRel (PAtom _ _ _) = True
+    isRel _             = False
+
+instance Arbitrary Brel where
+  arbitrary = oneof (map return [Eq, Ne, Gt, Ge, Lt, Le, Ueq, Une])
+
+instance Arbitrary Bop where
+  arbitrary = oneof (map return [Plus, Minus, Times, Div, Mod])
+
+instance Arbitrary SymConst where
+  arbitrary = fmap SL arbitrary
+
+instance Arbitrary Symbol where
+  arbitrary = fmap (symbol :: Text -> Symbol) arbitrary
+
+instance Arbitrary Text where
+  arbitrary = choose (1,4) >>= \n ->
+                fmap pack (vectorOf n char `suchThat` valid)
+    where
+      char = elements ['a'..'z']
+      valid x = x `notElem` fixpointNames && not (isFixKey x)
+
+instance Arbitrary FTycon where
+  arbitrary = do
+    c <- elements ['A'..'Z']
+    t <- arbitrary
+    return $ symbolFTycon $ dummyLoc $ symbol $ cons c t
+
+instance Arbitrary Constant where
+  arbitrary = oneof [fmap I (arbitrary `suchThat` (>=0))
+                    -- ,fmap R arbitrary
+                    ]
+  shrink = genericShrink
+
+instance Arbitrary a => Arbitrary (Located a) where
+  arbitrary = fmap dummyLoc arbitrary
+  shrink = fmap dummyLoc . shrink . val
+
+-}
+
+----------------------------------------------------------------------------------------
+-- Generic Helpers
+----------------------------------------------------------------------------------------
+
+group n xs = testGroup n <$> sequence xs
+
+----------------------------------------------------------------------------------------
+walkDirectory :: FilePath -> IO [FilePath]
+----------------------------------------------------------------------------------------
+walkDirectory root
+  = do (ds,fs) <- partitionM doesDirectoryExist . candidates =<< (getDirectoryContents root `catchIOError` const (return []))
+       (fs++) <$> concatMapM walkDirectory ds
+  where
+    candidates fs = [root </> f | f <- fs, not (isExtSeparator (head f))]
+
+partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a],[a])
+partitionM f = go [] []
+  where
+    go ls rs []     = return (ls,rs)
+    go ls rs (x:xs) = do b <- f x
+                         if b then go (x:ls) rs xs
+                              else go ls (x:rs) xs
+
+-- isDirectory :: FilePath -> IO Bool
+-- isDirectory = fmap Posix.isDirectory . Posix.getFileStatus
+
+concatMapM :: Applicative m => (a -> m [b]) -> [a] -> m [b]
+concatMapM _ []     = pure []
+concatMapM f (x:xs) = (++) <$> f x <*> concatMapM f xs
diff --git a/liquid-fixpoint/tests/testParser.hs b/liquid-fixpoint/tests/testParser.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/testParser.hs
@@ -0,0 +1,308 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import Language.Fixpoint.Parse
+import Test.Tasty
+import Test.Tasty.HUnit
+
+main :: IO ()
+main = defaultMain $ parserTests
+
+parserTests :: TestTree
+parserTests =
+  testGroup "Tests"
+    [
+      testSortP
+    , testFunAppP
+    , testExpr0P
+    , testPredP
+    ]
+
+-- ---------------------------------------------------------------------
+{-
+
+sort = '(' sort ')'
+     | 'func' funcSort
+     | '[' sort ']'
+     | bvsort
+     | fTyCon
+     | tVar
+
+sorts = '[' sortslist ']'
+
+sortslist = sort
+          | sort `;` sortslist
+
+funcSort = '(' int `,` sorts ')'
+
+     e.g.(func(1, [int; @(0)]))
+
+bvsort = '(' 'BitVec' 'Size32' ')'
+       | '(' 'BitVec' 'Size64' ')'
+
+fTyCon = 'int' | 'Integer' | 'Int' | 'real' | 'num' | 'Str'
+       | SYMBOL
+
+SYMBOL = upper case char or _, followed by many of '%' '#' '$' '\'
+
+tVar = '@' varSort
+     | LOWERID
+
+varSort = '(' INT ')'
+-}
+
+testSortP :: TestTree
+testSortP =
+  testGroup "SortP"
+    [ testCase "FAbs" $
+        show (doParse' sortP "test" "(func(1, [int; @(0)]))") @?= "FAbs 0 (FFunc FInt (FVar 0))"
+
+    , testCase "(FAbs)" $
+        show (doParse' sortP "test" "((func(1, [int; @(0)])))") @?= "FAbs 0 (FFunc FInt (FVar 0))"
+
+    , testCase "FApp FInt" $
+        show (doParse' sortP "test" "[int]") @?=
+              "FApp (FTC (TC \"[]\" (dummyLoc) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False}))) FInt"
+
+    , testCase "bv32" $
+        show (doParse' sortP "test" "BitVec Size32") @?=
+              "FApp (FTC (TC \"BitVec\" defined from: \"test\" (line 1, column 1) to: \"test\" (line 1, column 8) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False}))) (FTC (TC \"Size32\" defined from: \"test\" (line 1, column 8) to: \"test\" (line 1, column 14) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False})))"
+
+    , testCase "bv64" $
+        show (doParse' sortP "test" "BitVec Size64") @?=
+              "FApp (FTC (TC \"BitVec\" defined from: \"test\" (line 1, column 1) to: \"test\" (line 1, column 8) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False}))) (FTC (TC \"Size64\" defined from: \"test\" (line 1, column 8) to: \"test\" (line 1, column 14) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False})))"
+
+    , testCase "FInt int" $
+        show (doParse' sortP "test" "int") @?= "FInt"
+
+    , testCase "FInt Integer" $
+        show (doParse' sortP "test" "Integer") @?= "FInt"
+
+    , testCase "FInt Int" $
+        show (doParse' sortP "test" "Int") @?= "FInt"
+
+    , testCase "FReal real" $
+        show (doParse' sortP "test" "real") @?= "FReal"
+
+    , testCase "FNum num" $
+        show (doParse' sortP "test" "num") @?= "FNum"
+
+    , testCase "FStr" $
+        show (doParse' sortP "test" "Str") @?=
+             "FTC (TC \"Str\" (dummyLoc) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = True}))"
+
+    , testCase "SYMBOL" $
+        show (doParse' sortP "test" "F#y") @?=
+             "FTC (TC \"F#y\" defined from: \"test\" (line 1, column 1) to: \"test\" (line 1, column 4) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False}))"
+
+    , testCase "FVar 3" $
+        show (doParse' sortP "test" "@(3)") @?= "FVar 3"
+
+    , testCase "FObj " $
+        show (doParse' sortP "test" "foo") @?= "FObj \"foo\""
+
+    , testCase "FObj " $
+        show (doParse' sortP "test" "_foo") @?= "FObj \"_foo\""
+    ]
+
+-- ---------------------------------------------------------------------
+{-
+
+funApp = lit
+       | exprFunSpaces
+       | expFunSemis
+       | expFunCommas
+       | simpleApp
+
+lit = 'lit' stringLiteral sort
+
+exprFunSpaces =
+
+exprFunSemis =
+
+exprFunCommas =
+
+simpleApp = 
+-}
+testFunAppP :: TestTree
+testFunAppP =
+  testGroup "FunAppP"
+    [ testCase "ECon (litP)" $
+        show (doParse' funAppP "test" "lit \"#x00000008\" (BitVec  Size32)") @?=
+          "ECon (L \"#x00000008\" (FApp (FTC (TC \"BitVec\" defined from: \"test\" (line 1, column 19) to: \"test\" (line 1, column 27) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False}))) (FTC (TC \"Size32\" defined from: \"test\" (line 1, column 27) to: \"test\" (line 1, column 33) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False})))))"
+
+    , testCase "ECon (exprFunSpacesP)" $
+        show (doParse' funAppP "test" "fooBar baz qux") @?= "EApp (EApp (EVar \"fooBar\") (EVar \"baz\")) (EVar \"qux\")"
+
+    , testCase "ECon (exprFunCommasP)" $
+        show (doParse' funAppP "test" "fooBar (baz, qux)") @?= "EApp (EApp (EVar \"fooBar\") (EVar \"baz\")) (EVar \"qux\")"
+
+    , testCase "ECon (exprFunSemisP)" $
+        show (doParse' funAppP "test" "fooBar ([baz; qux])") @?= "EApp (EApp (EVar \"fooBar\") (EVar \"baz\")) (EVar \"qux\")"
+
+    , testCase "ECon (simpleAppP)" $
+        show (doParse' funAppP "test" "fooBar (baz + 1)") @?= "EApp (EVar \"fooBar\") (EBin Plus (EVar \"baz\") (ECon (I 1)))"
+    ]
+
+-- ---------------------------------------------------------------------
+{-
+expr0 = fastIf
+      | symconst
+      | constant
+      | '_|_'
+      | lam
+      | '(' expr ')'
+      | '(' exprCast ')'
+      | symChars
+
+-}
+testExpr0P :: TestTree
+testExpr0P =
+  testGroup "expr0P"
+    [ testCase "EIte" $
+        show (doParse' expr0P "test" "if true then x else y") @?= "EIte (PAnd []) (EVar \"x\") (EVar \"y\")"
+
+    , testCase "ESym SL" $
+        show (doParse' expr0P "test" "\"foo\" ") @?= "ESym (SL \"foo\")"
+
+    , testCase "ECon R" $
+        show (doParse' expr0P "test" "0.0") @?= "ECon (R 0.0)"
+
+    , testCase "ECon I" $
+        show (doParse' expr0P "test" "0") @?= "ECon (I 0)"
+
+    , testCase "ECon I" $
+        show (doParse' expr0P "test" "0") @?= "ECon (I 0)"
+
+    , testCase "EBot / POr []" $
+        show (doParse' expr0P "test" "_|_") @?= "POr []" -- pattern for "EBot"
+
+    , testCase "ELam" $
+        show (doParse' expr0P "test" "\\ foo : Int -> true") @?= "ELam (\"foo\",FInt) (EVar \"true\")"
+
+    , testCase "Expr" $
+        show (doParse' expr0P "test" "(1)") @?= "ECon (I 1)"
+
+    , testCase "ECst dcolon" $
+        show (doParse' expr0P "test" "(1 :: Int)") @?= "ECst (ECon (I 1)) FInt"
+
+    , testCase "ECst colon" $
+        show (doParse' expr0P "test" "(1 : Int)") @?= "ECst (ECon (I 1)) FInt"
+
+    , testCase "charsExpr EVar" $
+        show (doParse' expr0P "test" "foo") @?= "EVar \"foo\""
+
+    , testCase "charsExpr ECon" $
+        show (doParse' expr0P "test" "1") @?= "ECon (I 1)"
+    ]
+
+-- ---------------------------------------------------------------------
+{-
+
+pred = expressionParse (prefixOp++infixOp) pred0
+
+prefixOp = '~' | 'not'
+
+infixOp  = '&&' | '||' | '=>' | '==>' | '<=>'
+
+-- terms are pred0
+pred0 = 'true' | 'false'
+      | '??'
+      | kvarPred
+      | fastIfP
+      | predr
+      | '(' pred ')'
+      | '?' expr
+      | funApp
+      | symbol
+      | '&&' preds
+      | '||' preds
+
+kvarPred = kvar substs
+
+kvar = '$' symbol
+
+substs = {- empty -}
+       | subst substs
+
+subst = '[' symbol ':=' expr ']'
+
+preds = '[' predslist ']'
+
+predslist = pred
+          | pred `;` predslist
+
+fastIf = 'if' pred 'then' pred 'else' pred
+
+predr = expr brel expr
+
+brelP = '==' | '=' | '~~' | '!=' | '/=' | '!~' | '<' | '<=' | '>' | '>='
+
+-}
+
+testPredP :: TestTree
+testPredP =
+  testGroup "predP"
+    [ testCase "PTrue" $
+        show (doParse' predP "test" "true") @?= "PAnd []" -- pattern for PTrue
+
+    , testCase "PFalse" $
+        show (doParse' predP "test" "false") @?= "POr []" -- pattern for PFalse
+
+    , testCase "PGrad / ??" $
+        show (doParse' predP "test" "??") @?= "PGrad $\"\\\"test\\\" (line 1, column 3)\"  (PAnd [])"
+
+    , testCase "kvarPred empty" $
+        show (doParse' predP "test" "$foo") @?= "PKVar $\"foo\" "
+
+    , testCase "kvarPred one" $
+        show (doParse' predP "test" "$foo  [x := 1]") @?= "PKVar $\"foo\" [x:=1]"
+
+    , testCase "kvarPred two" $
+        show (doParse' predP "test" "$foo  [x := 1] [ y := true ]") @?= "PKVar $\"foo\" [x:=1][y:=true]"
+
+    , testCase "fastIf" $
+        show (doParse' predP "test" "if true then true else false" ) @?=
+          -- note conversion
+          "PAnd [PImp (PAnd []) (PAnd []),PImp (PNot (PAnd [])) (POr [])]"
+
+    , testCase "brel" $
+        show (doParse' predP "test" "1 == 2") @?= "PAtom Eq (ECon (I 1)) (ECon (I 2))"
+
+    , testCase "parens pred" $
+        show (doParse' predP "test" "((1 == 2))") @?= "PAtom Eq (ECon (I 1)) (ECon (I 2))"
+
+    , testCase "? expr" $
+        show (doParse' predP "test" "? (1+2)") @?= "EBin Plus (ECon (I 1)) (ECon (I 2))"
+
+    , testCase "funApp 1" $
+        show (doParse' predP "test" "f a b") @?= "EApp (EApp (EVar \"f\") (EVar \"a\")) (EVar \"b\")"
+
+    , testCase "funApp 2" $
+        show (doParse' predP "test" "f (a, b)") @?= "EApp (EApp (EVar \"f\") (EVar \"a\")) (EVar \"b\")"
+
+    , testCase "funApp 3" $
+        show (doParse' predP "test" "f ([a; b])") @?= "EApp (EApp (EVar \"f\") (EVar \"a\")) (EVar \"b\")"
+
+    , testCase "symbol" $
+        show (doParse' predP "test" "f") @?= "EVar \"f\""
+
+    , testCase "&& 0" $
+        show (doParse' predP "test" "&& []") @?= "PAnd []"
+
+    , testCase "&& 1" $
+        show (doParse' predP "test" "&& [x]") @?= "PAnd [EVar \"x\"]"
+
+    , testCase "&& 2" $
+        show (doParse' predP "test" "&& [x;y]") @?= "PAnd [EVar \"x\",EVar \"y\"]"
+
+    , testCase "|| 0" $
+        show (doParse' predP "test" "|| []") @?= "POr []"
+
+    , testCase "|| 1" $
+        show (doParse' predP "test" "|| [x]") @?= "POr [EVar \"x\"]"
+
+    , testCase "|| 2" $
+        show (doParse' predP "test" "|| [x;y]") @?= "POr [EVar \"x\",EVar \"y\"]"
+    ]
diff --git a/liquid-fixpoint/tests/todo/MergeSort.fq b/liquid-fixpoint/tests/todo/MergeSort.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/todo/MergeSort.fq
@@ -0,0 +1,3234 @@
+qualif Fst(v : @(1), y : @(0)): ((v = (fst y))) // "tests/todo/MergeSort.new.min.fq" (line 1, column 8)
+qualif Snd(v : @(1), y : @(0)): ((v = (snd y))) // "tests/todo/MergeSort.new.min.fq" (line 2, column 8)
+qualif Auto(VV : @(0), fld##0 : @(0)): ((VV >= fld##0)) // "tests/todo/MergeSort.new.min.fq" (line 3, column 8)
+qualif Auto(VV : @(0), fld##0 : @(0)): ((VV >= fld##0)) // "tests/todo/MergeSort.new.min.fq" (line 4, column 8)
+qualif Auto(VV : [@(0)], xs : [@(0)], ys : [@(0)]): (((len VV) = ((len xs) + (len ys)))) // "tests/todo/MergeSort.new.min.fq" (line 5, column 8)
+qualif Auto(VV : @(0), fld##0 : @(0)): ((VV >= fld##0)) // "tests/todo/MergeSort.new.min.fq" (line 6, column 8)
+qualif Auto(VV : [@(0)], xs : [@(0)]): (((len VV) = (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 7, column 8)
+qualif Auto(VV : @(0), fld##0 : @(0)): ((VV >= fld##0)) // "tests/todo/MergeSort.new.min.fq" (line 8, column 8)
+qualif Auto(v##0 : (Tuple  [@(0)]  [@(0)]), xs : [@(0)]): ((((len (fst v##0)) + (len (snd v##0))) = (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 9, column 8)
+qualif Auto(v##0 : [@(0)], xs : [@(0)]): ((((len v##0) > 1) => ((len v##0) < (len xs)))) // "tests/todo/MergeSort.new.min.fq" (line 10, column 8)
+qualif Auto(v##0 : [@(0)], xs : [@(0)]): ((((len v##0) > 1) => ((len v##0) < (len xs)))) // "tests/todo/MergeSort.new.min.fq" (line 11, column 8)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): (((Prop v) <=> ((len xs) > 0))) // "tests/todo/MergeSort.new.min.fq" (line 12, column 8)
+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): (((Prop v) <=> ((len xs) = 0))) // "tests/todo/MergeSort.new.min.fq" (line 13, column 8)
+qualif ListZ(v : [@(0)]): (((len v) = 0)) // "tests/todo/MergeSort.new.min.fq" (line 14, column 8)
+qualif ListZ(v : [@(0)]): (((len v) >= 0)) // "tests/todo/MergeSort.new.min.fq" (line 15, column 8)
+qualif ListZ(v : [@(0)]): (((len v) > 0)) // "tests/todo/MergeSort.new.min.fq" (line 16, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) = (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 17, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) >= (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 18, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) > (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 19, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) <= (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 20, column 8)
+qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) < (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 21, column 8)
+qualif EqLen(v : int, xs : [@(0)]): ((v = (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 22, column 8)
+qualif LenEq(v : [@(0)], x : int): ((x = (len v))) // "tests/todo/MergeSort.new.min.fq" (line 23, column 8)
+qualif LenDiff(v : [@(0)], x : int): (((len v) = (x + 1))) // "tests/todo/MergeSort.new.min.fq" (line 24, column 8)
+qualif LenDiff(v : [@(0)], x : int): (((len v) = (x - 1))) // "tests/todo/MergeSort.new.min.fq" (line 25, column 8)
+qualif LenAcc(v : int, xs : [@(0)], n : int): ((v = ((len xs) + n))) // "tests/todo/MergeSort.new.min.fq" (line 26, column 8)
+qualif Bot(v : @(0)): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 27, column 8)
+qualif Bot(v : @(0)): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 28, column 8)
+qualif Bot(v : @(0)): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 29, column 8)
+qualif Bot(v : bool): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 30, column 8)
+qualif Bot(v : int): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 31, column 8)
+qualif CmpZ(v : @(0)): ((v < 0)) // "tests/todo/MergeSort.new.min.fq" (line 32, column 8)
+qualif CmpZ(v : @(0)): ((v <= 0)) // "tests/todo/MergeSort.new.min.fq" (line 33, column 8)
+qualif CmpZ(v : @(0)): ((v > 0)) // "tests/todo/MergeSort.new.min.fq" (line 34, column 8)
+qualif CmpZ(v : @(0)): ((v >= 0)) // "tests/todo/MergeSort.new.min.fq" (line 35, column 8)
+qualif CmpZ(v : @(0)): ((v = 0)) // "tests/todo/MergeSort.new.min.fq" (line 36, column 8)
+qualif CmpZ(v : @(0)): ((v != 0)) // "tests/todo/MergeSort.new.min.fq" (line 37, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v < x)) // "tests/todo/MergeSort.new.min.fq" (line 38, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v <= x)) // "tests/todo/MergeSort.new.min.fq" (line 39, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v > x)) // "tests/todo/MergeSort.new.min.fq" (line 40, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v >= x)) // "tests/todo/MergeSort.new.min.fq" (line 41, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v = x)) // "tests/todo/MergeSort.new.min.fq" (line 42, column 8)
+qualif Cmp(v : @(0), x : @(0)): ((v != x)) // "tests/todo/MergeSort.new.min.fq" (line 43, column 8)
+qualif One(v : int): ((v = 1)) // "tests/todo/MergeSort.new.min.fq" (line 44, column 8)
+qualif True1(v : GHC.Types.Bool): ((Prop v)) // "tests/todo/MergeSort.new.min.fq" (line 45, column 8)
+qualif False1(v : GHC.Types.Bool): ((~ ((Prop v)))) // "tests/todo/MergeSort.new.min.fq" (line 46, column 8)
+qualif Papp(v : @(0), p : (Pred  @(0))): ((papp1 p v)) // "tests/todo/MergeSort.new.min.fq" (line 47, column 8)
+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): ((papp2 p v x)) // "tests/todo/MergeSort.new.min.fq" (line 48, column 8)
+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): ((papp3 p v x y)) // "tests/todo/MergeSort.new.min.fq" (line 49, column 8)
+
+
+cut $k_##795
+cut $k_##1160
+cut $k_##1118
+cut $k_##753
+cut $k_##1115
+cut $k_##792
+cut $k_##750
+cut $k_##746
+cut $k_##1111
+cut $k_##1153
+cut $k_##788
+cut $k_##1157
+
+
+pack $k_##686 : 0
+pack $k_##671 : 0
+pack $k_##655 : 0
+pack $k_##679 : 0
+pack $k_##667 : 0
+pack $k_##659 : 0
+pack $k_##662 : 0
+pack $k_##674 : 0
+pack $k_##683 : 0
+pack $k_##572 : 1
+pack $k_##560 : 1
+pack $k_##556 : 1
+pack $k_##584 : 1
+pack $k_##575 : 1
+pack $k_##587 : 1
+pack $k_##563 : 1
+pack $k_##568 : 1
+pack $k_##580 : 1
+pack $k_##883 : 2
+pack $k_##907 : 2
+pack $k_##890 : 2
+pack $k_##914 : 2
+pack $k_##899 : 2
+pack $k_##902 : 2
+pack $k_##911 : 2
+pack $k_##895 : 2
+pack $k_##887 : 2
+pack $k_##314 : 3
+pack $k_##321 : 3
+pack $k_##318 : 3
+pack $k_##753 : 4
+pack $k_##750 : 4
+pack $k_##746 : 4
+pack $k_##1020 : 5
+pack $k_##1017 : 5
+pack $k_##540 : 6
+pack $k_##543 : 6
+pack $k_##639 : 7
+pack $k_##642 : 7
+pack $k_##971 : 8
+pack $k_##968 : 8
+pack $k_##168 : 9
+pack $k_##175 : 9
+pack $k_##172 : 9
+pack $k_##1118 : 10
+pack $k_##1115 : 10
+pack $k_##1111 : 10
+pack $k_##256 : 11
+pack $k_##259 : 11
+pack $k_##252 : 11
+pack $k_##1037 : 12
+pack $k_##1040 : 12
+pack $k_##237 : 13
+pack $k_##241 : 13
+pack $k_##244 : 13
+pack $k_##467 : 14
+pack $k_##470 : 14
+pack $k_##415 : 15
+pack $k_##418 : 15
+pack $k_##1160 : 16
+pack $k_##1153 : 16
+pack $k_##1157 : 16
+pack $k_##387 : 17
+pack $k_##390 : 17
+pack $k_##867 : 18
+pack $k_##864 : 18
+pack $k_##844 : 19
+pack $k_##841 : 19
+pack $k_##1076 : 20
+pack $k_##1080 : 20
+pack $k_##1083 : 20
+pack $k_##338 : 21
+pack $k_##335 : 21
+pack $k_##795 : 22
+pack $k_##792 : 22
+pack $k_##788 : 22
+
+
+constant runFun : (func(2, [(Arrow  @(0)  @(1)); @(0); @(1)]))
+constant addrLen : (func(0, [int; int]))
+constant lit$36$$47$Users$47$rjhala$47$research$47$stack$47$liquidhaskell$47$tests$47$pos$47$MergeSort.hs$58$$40$48$44$1$41$$45$$40$52$44$41$41$$124$function$32$merge : (Str)
+constant papp5 : (func(10, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4));
+                            @(5);
+                            @(6);
+                            @(7);
+                            @(8);
+                            @(9);
+                            bool]))
+constant x_Tuple21 : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant GHC.Types.False##68 : (GHC.Types.Bool)
+constant x_Tuple65 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(4)]))
+constant x_Tuple55 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(4)]))
+constant x_Tuple33 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(2)]))
+constant x_Tuple77 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(6)]))
+constant papp3 : (func(6, [(Pred  @(0)  @(1)  @(2));
+                           @(3);
+                           @(4);
+                           @(5);
+                           bool]))
+constant GHC.Types.True##6u : (GHC.Types.Bool)
+constant x_Tuple63 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(2)]))
+constant x_Tuple41 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(0)]))
+constant GHC.Types.LT##6S : (GHC.Types.Ordering)
+constant papp4 : (func(8, [(Pred  @(0)  @(1)  @(2)  @(3));
+                           @(4);
+                           @(5);
+                           @(6);
+                           @(7);
+                           bool]))
+constant x_Tuple64 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(3)]))
+constant GHC.Types.GT##6W : (GHC.Types.Ordering)
+constant GHC.Types.$58$$35$$35$64 : (func(1, [@(0);
+                                              [@(0)];
+                                              [@(0)]]))
+constant autolen : (func(1, [@(0); int]))
+constant x_Tuple52 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(1)]))
+constant head : (func(1, [[@(0)]; @(0)]))
+constant MergeSort.split##rlx : (func(1, [[@(0)];
+                                          (Tuple  [@(0)]  [@(0)])]))
+constant null : (func(1, [[@(0)]; bool]))
+constant GHC.Classes.$60$$61$$35$$35$r4 : (func(1, [@(0);
+                                                    @(0);
+                                                    GHC.Types.Bool]))
+constant papp2 : (func(4, [(Pred  @(0)  @(1)); @(2); @(3); bool]))
+constant x_Tuple62 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(1)]))
+constant GHC.Tuple.$40$$44$$41$$35$$35$74 : (func(2, [@(0);
+                                                      @(1);
+                                                      (Tuple  @(0)  @(1))]))
+constant fromJust : (func(1, [(GHC.Base.Maybe  @(0)); @(0)]))
+constant papp7 : (func(14, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                            @(7);
+                            @(8);
+                            @(9);
+                            @(10);
+                            @(11);
+                            @(12);
+                            @(13);
+                            bool]))
+constant MergeSort.sort##rjG : (func(1, [[@(0)]; [@(0)]]))
+constant x_Tuple53 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(2)]))
+constant x_Tuple71 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(0)]))
+constant x_Tuple74 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(3)]))
+constant len : (func(2, [(@(0)  @(1)); int]))
+constant papp6 : (func(12, [(Pred  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                            @(6);
+                            @(7);
+                            @(8);
+                            @(9);
+                            @(10);
+                            @(11);
+                            bool]))
+constant x_Tuple22 : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant x_Tuple66 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(5)]))
+constant x_Tuple44 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(3)]))
+constant strLen : (func(0, [int; int]))
+constant x_Tuple72 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(1)]))
+constant isJust : (func(1, [(GHC.Base.Maybe  @(0)); bool]))
+constant Prop : (func(0, [GHC.Types.Bool; bool]))
+constant x_Tuple31 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(0)]))
+constant x_Tuple75 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(4)]))
+constant papp1 : (func(2, [(Pred  @(0)); @(1); bool]))
+constant x_Tuple61 : (func(6, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5));
+                               @(0)]))
+constant x_Tuple43 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(2)]))
+constant tail : (func(1, [[@(0)]; [@(0)]]))
+constant GHC.Types.EQ##6U : (GHC.Types.Ordering)
+constant Control.Exception.Base.patError##0e : (func(1, [int;
+                                                         @(0)]))
+constant MergeSort.merge##rly : (func(1, [[@(0)]; [@(0)]; [@(0)]]))
+constant x_Tuple51 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(0)]))
+constant x_Tuple73 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(2)]))
+constant GHC.Types.$91$$93$$35$$35$6m : (func(1, [[@(0)]]))
+constant x_Tuple54 : (func(5, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4));
+                               @(3)]))
+constant cmp : (func(0, [GHC.Types.Ordering; GHC.Types.Ordering]))
+constant x_Tuple32 : (func(3, [(Tuple  @(0)  @(1)  @(2)); @(1)]))
+constant x_Tuple76 : (func(7, [(Tuple  @(0)  @(1)  @(2)  @(3)  @(4)  @(5)  @(6));
+                               @(5)]))
+constant snd : (func(2, [(Tuple  @(0)  @(1)); @(1)]))
+constant fst : (func(2, [(Tuple  @(0)  @(1)); @(0)]))
+constant x_Tuple42 : (func(4, [(Tuple  @(0)  @(1)  @(2)  @(3));
+                               @(1)]))
+constant GHC.Prim.void###0l : (GHC.Prim.Void#)
+
+
+bind 0 GHC.Prim.void###0l : {VV##84 : GHC.Prim.Void# | []}
+bind 1 GHC.Types.False##68 : {VV##86 : GHC.Types.Bool | []}
+bind 2 GHC.Types.$91$$93$$35$$35$6m : {VV : func(1, [[@(0)]]) | []}
+bind 3 GHC.Types.True##6u : {VV##88 : GHC.Types.Bool | []}
+bind 4 GHC.Types.EQ##6U : {VV##91 : GHC.Types.Ordering | [(VV##91 = GHC.Types.EQ##6U)]}
+bind 5 GHC.Types.LT##6S : {VV##92 : GHC.Types.Ordering | [(VV##92 = GHC.Types.LT##6S)]}
+bind 6 GHC.Types.GT##6W : {VV##93 : GHC.Types.Ordering | [(VV##93 = GHC.Types.GT##6W)]}
+bind 7 GHC.Types.True##6u : {v##4 : GHC.Types.Bool | [(Prop v##4)]}
+bind 8 GHC.Types.False##68 : {v##5 : GHC.Types.Bool | [(~ ((Prop v##5)))]}
+bind 9 GHC.Types.False##68 : {v##5 : GHC.Types.Bool | [(~ ((Prop v##5)))]}
+bind 10 GHC.Types.$91$$93$$35$$35$6m : {VV : func(1, [[@(0)]]) | []}
+bind 11 GHC.Types.True##6u : {v##4 : GHC.Types.Bool | [(Prop v##4)]}
+bind 12 fix$36$$36$dOrd_azK : {VV##119 : (GHC.Classes.Ord  a_azo) | []}
+bind 13 xs##ayP : {VV##120 : [a_azo] | [((len VV##120) >= 0)]}
+bind 14 ds_dMl : {VV##121 : [a_azo] | [((len VV##121) >= 0)]}
+bind 15 lq_anf$##dMK : {lq_tmp$x##123 : [a_azo] | [((len lq_tmp$x##123) >= 0);
+                                                   (lq_tmp$x##123 = ds_dMl);
+                                                   ((len lq_tmp$x##123) >= 0)]}
+bind 16 lq_anf$##dMK : {lq_tmp$x##127 : [a_azo] | [((len lq_tmp$x##127) >= 0);
+                                                   (lq_tmp$x##127 = ds_dMl);
+                                                   ((len lq_tmp$x##127) >= 0);
+                                                   ((len lq_tmp$x##127) >= 0)]}
+bind 17 lq_anf$##dMK : {lq_tmp$x##127 : [a_azo] | [((len lq_tmp$x##127) >= 0);
+                                                   (lq_tmp$x##127 = ds_dMl);
+                                                   ((len lq_tmp$x##127) >= 0);
+                                                   ((len lq_tmp$x##127) = 0);
+                                                   ((null lq_tmp$x##127) <=> true);
+                                                   (lq_tmp$x##127 = GHC.Types.$91$$93$$35$$35$6m);
+                                                   ((len lq_tmp$x##127) = 0);
+                                                   ((null lq_tmp$x##127) <=> true);
+                                                   ((len lq_tmp$x##127) >= 0)]}
+bind 18 lq_anf$##dMK : {lq_tmp$x##140 : [a_azo] | [((len lq_tmp$x##140) >= 0);
+                                                   (lq_tmp$x##140 = ds_dMl);
+                                                   ((len lq_tmp$x##140) >= 0);
+                                                   ((len lq_tmp$x##140) >= 0)]}
+bind 19 lq_anf$##dMU : {VV : a_azo | []}
+bind 20 lq_anf$##dMV : {lq_tmp$x##154 : [a_azo] | [((len lq_tmp$x##154) >= 0)]}
+bind 21 lq_anf$##dMK : {lq_tmp$x##140 : [a_azo] | [((len lq_tmp$x##140) >= 0);
+                                                   (lq_tmp$x##140 = ds_dMl);
+                                                   ((len lq_tmp$x##140) >= 0);
+                                                   ((len lq_tmp$x##140) = (1 + (len lq_anf$##dMV)));
+                                                   ((null lq_tmp$x##140) <=> false);
+                                                   ((tail lq_tmp$x##140) = lq_anf$##dMV);
+                                                   ((head lq_tmp$x##140) = lq_anf$##dMU);
+                                                   (lq_tmp$x##140 = (GHC.Types.$58$$35$$35$64 lq_anf$##dMU lq_anf$##dMV));
+                                                   ((len lq_tmp$x##140) = (1 + (len lq_anf$##dMV)));
+                                                   ((null lq_tmp$x##140) <=> false);
+                                                   ((tail lq_tmp$x##140) = lq_anf$##dMV);
+                                                   ((head lq_tmp$x##140) = lq_anf$##dMU);
+                                                   ((len lq_tmp$x##140) >= 0)]}
+bind 22 ds_dMr : {VV##163 : GHC.Prim.Void# | [$k_##164]}
+bind 23 lq_anf$##dML : {lq_tmp$x##178 : [a_azo] | [((len lq_tmp$x##178) >= 0);
+                                                   (lq_tmp$x##178 = xs##ayP);
+                                                   ((len lq_tmp$x##178) >= 0)]}
+bind 24 lq_anf$##dML : {lq_tmp$x##182 : [a_azo] | [((len lq_tmp$x##182) >= 0);
+                                                   (lq_tmp$x##182 = xs##ayP);
+                                                   ((len lq_tmp$x##182) >= 0);
+                                                   ((len lq_tmp$x##182) >= 0)]}
+bind 25 lq_anf$##dML : {lq_tmp$x##182 : [a_azo] | [((len lq_tmp$x##182) >= 0);
+                                                   (lq_tmp$x##182 = xs##ayP);
+                                                   ((len lq_tmp$x##182) >= 0);
+                                                   ((len lq_tmp$x##182) = 0);
+                                                   ((null lq_tmp$x##182) <=> true);
+                                                   (lq_tmp$x##182 = GHC.Types.$91$$93$$35$$35$6m);
+                                                   ((len lq_tmp$x##182) = 0);
+                                                   ((null lq_tmp$x##182) <=> true);
+                                                   ((len lq_tmp$x##182) >= 0)]}
+bind 26 lq_anf$##dML : {lq_tmp$x##195 : [a_azo] | [((len lq_tmp$x##195) >= 0);
+                                                   (lq_tmp$x##195 = xs##ayP);
+                                                   ((len lq_tmp$x##195) >= 0);
+                                                   ((len lq_tmp$x##195) >= 0)]}
+bind 27 x##ayR : {VV : a_azo | []}
+bind 28 xs##ayS : {lq_tmp$x##209 : [a_azo] | [((len lq_tmp$x##209) >= 0)]}
+bind 29 lq_anf$##dML : {lq_tmp$x##195 : [a_azo] | [((len lq_tmp$x##195) >= 0);
+                                                   (lq_tmp$x##195 = xs##ayP);
+                                                   ((len lq_tmp$x##195) >= 0);
+                                                   ((len lq_tmp$x##195) = (1 + (len xs##ayS)));
+                                                   ((null lq_tmp$x##195) <=> false);
+                                                   ((tail lq_tmp$x##195) = xs##ayS);
+                                                   ((head lq_tmp$x##195) = x##ayR);
+                                                   (lq_tmp$x##195 = (GHC.Types.$58$$35$$35$64 x##ayR xs##ayS));
+                                                   ((len lq_tmp$x##195) = (1 + (len xs##ayS)));
+                                                   ((null lq_tmp$x##195) <=> false);
+                                                   ((tail lq_tmp$x##195) = xs##ayS);
+                                                   ((head lq_tmp$x##195) = x##ayR);
+                                                   ((len lq_tmp$x##195) >= 0)]}
+bind 30 lq_anf$##dMM : {lq_tmp$x##219 : [a_azo] | [((len lq_tmp$x##219) >= 0);
+                                                   (lq_tmp$x##219 = ds_dMl);
+                                                   ((len lq_tmp$x##219) >= 0)]}
+bind 31 lq_anf$##dMM : {lq_tmp$x##223 : [a_azo] | [((len lq_tmp$x##223) >= 0);
+                                                   (lq_tmp$x##223 = ds_dMl);
+                                                   ((len lq_tmp$x##223) >= 0);
+                                                   ((len lq_tmp$x##223) >= 0)]}
+bind 32 lq_anf$##dMM : {lq_tmp$x##223 : [a_azo] | [((len lq_tmp$x##223) >= 0);
+                                                   (lq_tmp$x##223 = ds_dMl);
+                                                   ((len lq_tmp$x##223) >= 0);
+                                                   ((len lq_tmp$x##223) = 0);
+                                                   ((null lq_tmp$x##223) <=> true);
+                                                   (lq_tmp$x##223 = GHC.Types.$91$$93$$35$$35$6m);
+                                                   ((len lq_tmp$x##223) = 0);
+                                                   ((null lq_tmp$x##223) <=> true);
+                                                   ((len lq_tmp$x##223) >= 0)]}
+bind 33 ds_dMn : {VV##232 : GHC.Prim.Void# | [$k_##233]}
+bind 34 lq_anf$##dMN : {lq_tmp$x##246 : int | [(lq_tmp$x##246 ~~ lit$36$$47$Users$47$rjhala$47$research$47$stack$47$liquidhaskell$47$tests$47$pos$47$MergeSort.hs$58$$40$48$44$1$41$$45$$40$52$44$41$41$$124$function$32$merge);
+                                               ((strLen lq_tmp$x##246) = 95)]}
+bind 35 lq_anf$##dMM : {lq_tmp$x##266 : [a_azo] | [((len lq_tmp$x##266) >= 0);
+                                                   (lq_tmp$x##266 = ds_dMl);
+                                                   ((len lq_tmp$x##266) >= 0);
+                                                   ((len lq_tmp$x##266) >= 0)]}
+bind 36 y##ayT : {VV : a_azo | []}
+bind 37 ys##ayU : {lq_tmp$x##280 : [a_azo] | [((len lq_tmp$x##280) >= 0)]}
+bind 38 lq_anf$##dMM : {lq_tmp$x##266 : [a_azo] | [((len lq_tmp$x##266) >= 0);
+                                                   (lq_tmp$x##266 = ds_dMl);
+                                                   ((len lq_tmp$x##266) >= 0);
+                                                   ((len lq_tmp$x##266) = (1 + (len ys##ayU)));
+                                                   ((null lq_tmp$x##266) <=> false);
+                                                   ((tail lq_tmp$x##266) = ys##ayU);
+                                                   ((head lq_tmp$x##266) = y##ayT);
+                                                   (lq_tmp$x##266 = (GHC.Types.$58$$35$$35$64 y##ayT ys##ayU));
+                                                   ((len lq_tmp$x##266) = (1 + (len ys##ayU)));
+                                                   ((null lq_tmp$x##266) <=> false);
+                                                   ((tail lq_tmp$x##266) = ys##ayU);
+                                                   ((head lq_tmp$x##266) = y##ayT);
+                                                   ((len lq_tmp$x##266) >= 0)]}
+bind 39 lq_anf$##dMO : {lq_tmp$x##290 : GHC.Types.Bool | [((Prop lq_tmp$x##290) <=> (x##ayR <= y##ayT))]}
+bind 40 lq_anf$##dMP : {lq_tmp$x##302 : GHC.Types.Bool | [((Prop lq_tmp$x##302) <=> (x##ayR <= y##ayT));
+                                                          (lq_tmp$x##302 = lq_anf$##dMO)]}
+bind 41 lq_anf$##dMP : {lq_tmp$x##304 : GHC.Types.Bool | [((Prop lq_tmp$x##304) <=> (x##ayR <= y##ayT));
+                                                          (lq_tmp$x##304 = lq_anf$##dMO)]}
+bind 42 lq_anf$##dMP : {lq_tmp$x##304 : GHC.Types.Bool | [((Prop lq_tmp$x##304) <=> (x##ayR <= y##ayT));
+                                                          (lq_tmp$x##304 = lq_anf$##dMO);
+                                                          (~ ((Prop lq_tmp$x##304)));
+                                                          (~ ((Prop lq_tmp$x##304)));
+                                                          (~ ((Prop lq_tmp$x##304)))]}
+bind 43 ds_dMp : {VV##309 : GHC.Prim.Void# | [$k_##310]}
+bind 44 lq_tmp$x##340 : {VV : a_azo | []}
+bind 45 lq_anf$##dMQ : {lq_tmp$x##326 : [a_azo] | [((len lq_tmp$x##326) = (1 + (len xs##ayS)));
+                                                   ((null lq_tmp$x##326) <=> false);
+                                                   ((tail lq_tmp$x##326) = xs##ayS);
+                                                   ((head lq_tmp$x##326) = x##ayR);
+                                                   ((len lq_tmp$x##326) >= 0)]}
+bind 46 lq_anf$##dMR : {VV##374 : [a_azo] | [((len VV##374) = ((len lq_anf$##dMQ) + (len ys##ayU)));
+                                             ((len VV##374) >= 0)]}
+bind 47 lq_tmp$x##392 : {VV : a_azo | []}
+bind 48 lq_anf$##dMP : {lq_tmp$x##398 : GHC.Types.Bool | [((Prop lq_tmp$x##398) <=> (x##ayR <= y##ayT));
+                                                          (lq_tmp$x##398 = lq_anf$##dMO)]}
+bind 49 lq_anf$##dMP : {lq_tmp$x##398 : GHC.Types.Bool | [((Prop lq_tmp$x##398) <=> (x##ayR <= y##ayT));
+                                                          (lq_tmp$x##398 = lq_anf$##dMO);
+                                                          (Prop lq_tmp$x##398);
+                                                          (Prop lq_tmp$x##398);
+                                                          (Prop lq_tmp$x##398)]}
+bind 50 lq_tmp$x##420 : {VV : a_azo | []}
+bind 51 lq_anf$##dMS : {lq_tmp$x##406 : [a_azo] | [((len lq_tmp$x##406) = (1 + (len ys##ayU)));
+                                                   ((null lq_tmp$x##406) <=> false);
+                                                   ((tail lq_tmp$x##406) = ys##ayU);
+                                                   ((head lq_tmp$x##406) = y##ayT);
+                                                   ((len lq_tmp$x##406) >= 0)]}
+bind 52 lq_anf$##dMT : {VV##454 : [a_azo] | [((len VV##454) = ((len xs##ayS) + (len lq_anf$##dMS)));
+                                             ((len VV##454) >= 0)]}
+bind 53 lq_tmp$x##472 : {VV : a_azo | []}
+bind 54 ds_dMs : {VV##521 : [a_azx] | [((len VV##521) >= 0)]}
+bind 55 lq_anf$##dMW : {lq_tmp$x##523 : [a_azx] | [((len lq_tmp$x##523) >= 0);
+                                                   (lq_tmp$x##523 = ds_dMs);
+                                                   ((len lq_tmp$x##523) >= 0)]}
+bind 56 lq_anf$##dMW : {lq_tmp$x##527 : [a_azx] | [((len lq_tmp$x##527) >= 0);
+                                                   (lq_tmp$x##527 = ds_dMs);
+                                                   ((len lq_tmp$x##527) >= 0);
+                                                   ((len lq_tmp$x##527) >= 0)]}
+bind 57 lq_anf$##dMW : {lq_tmp$x##527 : [a_azx] | [((len lq_tmp$x##527) >= 0);
+                                                   (lq_tmp$x##527 = ds_dMs);
+                                                   ((len lq_tmp$x##527) >= 0);
+                                                   ((len lq_tmp$x##527) = 0);
+                                                   ((null lq_tmp$x##527) <=> true);
+                                                   (lq_tmp$x##527 = GHC.Types.$91$$93$$35$$35$6m);
+                                                   ((len lq_tmp$x##527) = 0);
+                                                   ((null lq_tmp$x##527) <=> true);
+                                                   ((len lq_tmp$x##527) >= 0)]}
+bind 58 lq_tmp$x##545 : {VV : a_azx | []}
+bind 59 lq_anf$##dMX : {lq_tmp$x##537 : [a_azx] | [((len lq_tmp$x##537) = 0);
+                                                   ((null lq_tmp$x##537) <=> true);
+                                                   ((len lq_tmp$x##537) >= 0)]}
+bind 60 lq_tmp$x##589 : {VV##590 : [a_azx] | [((len VV##590) >= 0)]}
+bind 61 lq_anf$##dMW : {lq_tmp$x##598 : [a_azx] | [((len lq_tmp$x##598) >= 0);
+                                                   (lq_tmp$x##598 = ds_dMs);
+                                                   ((len lq_tmp$x##598) >= 0);
+                                                   ((len lq_tmp$x##598) >= 0)]}
+bind 62 x##ayC : {VV : a_azx | []}
+bind 63 ds_dMt : {lq_tmp$x##612 : [a_azx] | [((len lq_tmp$x##612) >= 0)]}
+bind 64 lq_anf$##dMW : {lq_tmp$x##598 : [a_azx] | [((len lq_tmp$x##598) >= 0);
+                                                   (lq_tmp$x##598 = ds_dMs);
+                                                   ((len lq_tmp$x##598) >= 0);
+                                                   ((len lq_tmp$x##598) = (1 + (len ds_dMt)));
+                                                   ((null lq_tmp$x##598) <=> false);
+                                                   ((tail lq_tmp$x##598) = ds_dMt);
+                                                   ((head lq_tmp$x##598) = x##ayC);
+                                                   (lq_tmp$x##598 = (GHC.Types.$58$$35$$35$64 x##ayC ds_dMt));
+                                                   ((len lq_tmp$x##598) = (1 + (len ds_dMt)));
+                                                   ((null lq_tmp$x##598) <=> false);
+                                                   ((tail lq_tmp$x##598) = ds_dMt);
+                                                   ((head lq_tmp$x##598) = x##ayC);
+                                                   ((len lq_tmp$x##598) >= 0)]}
+bind 65 lq_anf$##dMY : {lq_tmp$x##622 : [a_azx] | [((len lq_tmp$x##622) >= 0);
+                                                   (lq_tmp$x##622 = ds_dMt);
+                                                   ((len lq_tmp$x##622) >= 0)]}
+bind 66 lq_anf$##dMY : {lq_tmp$x##626 : [a_azx] | [((len lq_tmp$x##626) >= 0);
+                                                   (lq_tmp$x##626 = ds_dMt);
+                                                   ((len lq_tmp$x##626) >= 0);
+                                                   ((len lq_tmp$x##626) >= 0)]}
+bind 67 lq_anf$##dMY : {lq_tmp$x##626 : [a_azx] | [((len lq_tmp$x##626) >= 0);
+                                                   (lq_tmp$x##626 = ds_dMt);
+                                                   ((len lq_tmp$x##626) >= 0);
+                                                   ((len lq_tmp$x##626) = 0);
+                                                   ((null lq_tmp$x##626) <=> true);
+                                                   (lq_tmp$x##626 = GHC.Types.$91$$93$$35$$35$6m);
+                                                   ((len lq_tmp$x##626) = 0);
+                                                   ((null lq_tmp$x##626) <=> true);
+                                                   ((len lq_tmp$x##626) >= 0)]}
+bind 68 lq_tmp$x##644 : {VV : a_azx | []}
+bind 69 lq_anf$##dMZ : {lq_tmp$x##636 : [a_azx] | [((len lq_tmp$x##636) = 0);
+                                                   ((null lq_tmp$x##636) <=> true);
+                                                   ((len lq_tmp$x##636) >= 0)]}
+bind 70 lq_tmp$x##688 : {VV##689 : [a_azx] | [((len VV##689) >= 0)]}
+bind 71 lq_anf$##dMY : {lq_tmp$x##697 : [a_azx] | [((len lq_tmp$x##697) >= 0);
+                                                   (lq_tmp$x##697 = ds_dMt);
+                                                   ((len lq_tmp$x##697) >= 0);
+                                                   ((len lq_tmp$x##697) >= 0)]}
+bind 72 y##ayD : {VV : a_azx | []}
+bind 73 zs##ayE : {lq_tmp$x##711 : [a_azx] | [((len lq_tmp$x##711) >= 0)]}
+bind 74 lq_anf$##dMY : {lq_tmp$x##697 : [a_azx] | [((len lq_tmp$x##697) >= 0);
+                                                   (lq_tmp$x##697 = ds_dMt);
+                                                   ((len lq_tmp$x##697) >= 0);
+                                                   ((len lq_tmp$x##697) = (1 + (len zs##ayE)));
+                                                   ((null lq_tmp$x##697) <=> false);
+                                                   ((tail lq_tmp$x##697) = zs##ayE);
+                                                   ((head lq_tmp$x##697) = y##ayD);
+                                                   (lq_tmp$x##697 = (GHC.Types.$58$$35$$35$64 y##ayD zs##ayE));
+                                                   ((len lq_tmp$x##697) = (1 + (len zs##ayE)));
+                                                   ((null lq_tmp$x##697) <=> false);
+                                                   ((tail lq_tmp$x##697) = zs##ayE);
+                                                   ((head lq_tmp$x##697) = y##ayD);
+                                                   ((len lq_tmp$x##697) >= 0)]}
+bind 75 ds_dMw : {v##0 : (Tuple  [a_azx]  [a_azx]) | [(((len (fst v##0)) + (len (snd v##0))) = (len zs##ayE))]}
+bind 76 ds_dMw : {lq_tmp$x##762 : (Tuple  [a_azx]  [a_azx]) | [(((len (fst lq_tmp$x##762)) + (len (snd lq_tmp$x##762))) = (len zs##ayE))]}
+bind 77 xs##aA4 : {lq_tmp$x##756 : [a_azx] | [(((len lq_tmp$x##756) > 1) => ((len lq_tmp$x##756) < (len zs##ayE)));
+                                              ((len lq_tmp$x##756) >= 0)]}
+bind 78 ys##XAl : {lq_tmp$x##758 : [a_azx] | [((len lq_tmp$x##758) >= 0)]}
+bind 79 ds_dMw : {lq_tmp$x##762 : (Tuple  [a_azx]  [a_azx]) | [(((len (fst lq_tmp$x##762)) + (len (snd lq_tmp$x##762))) = (len zs##ayE));
+                                                               ((snd lq_tmp$x##762) = ys##XAl);
+                                                               ((fst lq_tmp$x##762) = xs##aA4);
+                                                               ((x_Tuple22 lq_tmp$x##762) = ys##XAl);
+                                                               ((x_Tuple21 lq_tmp$x##762) = xs##aA4);
+                                                               (lq_tmp$x##762 = (GHC.Tuple.$40$$44$$41$$35$$35$74 xs##aA4 ys##XAl));
+                                                               ((snd lq_tmp$x##762) = ys##XAl);
+                                                               ((fst lq_tmp$x##762) = xs##aA4);
+                                                               ((x_Tuple22 lq_tmp$x##762) = ys##XAl);
+                                                               ((x_Tuple21 lq_tmp$x##762) = xs##aA4)]}
+bind 80 xs##aA4 : {VV##752 : [a_azx] | [$k_##753;
+                                        ((len VV##752) >= 0)]}
+bind 81 ds_dMw : {lq_tmp$x##804 : (Tuple  [a_azx]  [a_azx]) | [(((len (fst lq_tmp$x##804)) + (len (snd lq_tmp$x##804))) = (len zs##ayE))]}
+bind 82 xs##aA4 : {lq_tmp$x##798 : [a_azx] | [((len lq_tmp$x##798) >= 0)]}
+bind 83 ys##aA5 : {lq_tmp$x##800 : [a_azx] | [(((len lq_tmp$x##800) > 1) => ((len lq_tmp$x##800) < (len zs##ayE)));
+                                              ((len lq_tmp$x##800) >= 0)]}
+bind 84 ds_dMw : {lq_tmp$x##804 : (Tuple  [a_azx]  [a_azx]) | [(((len (fst lq_tmp$x##804)) + (len (snd lq_tmp$x##804))) = (len zs##ayE));
+                                                               ((snd lq_tmp$x##804) = ys##aA5);
+                                                               ((fst lq_tmp$x##804) = xs##aA4);
+                                                               ((x_Tuple22 lq_tmp$x##804) = ys##aA5);
+                                                               ((x_Tuple21 lq_tmp$x##804) = xs##aA4);
+                                                               (lq_tmp$x##804 = (GHC.Tuple.$40$$44$$41$$35$$35$74 xs##aA4 ys##aA5));
+                                                               ((snd lq_tmp$x##804) = ys##aA5);
+                                                               ((fst lq_tmp$x##804) = xs##aA4);
+                                                               ((x_Tuple22 lq_tmp$x##804) = ys##aA5);
+                                                               ((x_Tuple21 lq_tmp$x##804) = xs##aA4)]}
+bind 85 ys##aA5 : {VV##794 : [a_azx] | [$k_##795;
+                                        ((len VV##794) >= 0)]}
+bind 86 lq_tmp$x##846 : {VV : a_azx | []}
+bind 87 lq_anf$##dN0 : {lq_tmp$x##832 : [a_azx] | [((len lq_tmp$x##832) = (1 + (len xs##aA4)));
+                                                   ((null lq_tmp$x##832) <=> false);
+                                                   ((tail lq_tmp$x##832) = xs##aA4);
+                                                   ((head lq_tmp$x##832) = x##ayC);
+                                                   ((len lq_tmp$x##832) >= 0)]}
+bind 88 lq_tmp$x##869 : {VV : a_azx | []}
+bind 89 lq_anf$##dN1 : {lq_tmp$x##855 : [a_azx] | [((len lq_tmp$x##855) = (1 + (len ys##aA5)));
+                                                   ((null lq_tmp$x##855) <=> false);
+                                                   ((tail lq_tmp$x##855) = ys##aA5);
+                                                   ((head lq_tmp$x##855) = y##ayD);
+                                                   ((len lq_tmp$x##855) >= 0)]}
+bind 90 lq_tmp$x##916 : {VV##917 : [a_azx] | [((len VV##917) >= 0)]}
+bind 91 fix$36$$36$dOrd_aAe : {VV##948 : (GHC.Classes.Ord  a_azJ) | []}
+bind 92 ds_dMB : {VV##949 : [a_azJ] | [((len VV##949) >= 0)]}
+bind 93 lq_anf$##dN2 : {lq_tmp$x##951 : [a_azJ] | [((len lq_tmp$x##951) >= 0);
+                                                   (lq_tmp$x##951 = ds_dMB);
+                                                   ((len lq_tmp$x##951) >= 0)]}
+bind 94 lq_anf$##dN2 : {lq_tmp$x##955 : [a_azJ] | [((len lq_tmp$x##955) >= 0);
+                                                   (lq_tmp$x##955 = ds_dMB);
+                                                   ((len lq_tmp$x##955) >= 0);
+                                                   ((len lq_tmp$x##955) >= 0)]}
+bind 95 lq_anf$##dN2 : {lq_tmp$x##955 : [a_azJ] | [((len lq_tmp$x##955) >= 0);
+                                                   (lq_tmp$x##955 = ds_dMB);
+                                                   ((len lq_tmp$x##955) >= 0);
+                                                   ((len lq_tmp$x##955) = 0);
+                                                   ((null lq_tmp$x##955) <=> true);
+                                                   (lq_tmp$x##955 = GHC.Types.$91$$93$$35$$35$6m);
+                                                   ((len lq_tmp$x##955) = 0);
+                                                   ((null lq_tmp$x##955) <=> true);
+                                                   ((len lq_tmp$x##955) >= 0)]}
+bind 96 lq_tmp$x##973 : {VV : a_azJ | []}
+bind 97 lq_anf$##dN2 : {lq_tmp$x##976 : [a_azJ] | [((len lq_tmp$x##976) >= 0);
+                                                   (lq_tmp$x##976 = ds_dMB);
+                                                   ((len lq_tmp$x##976) >= 0);
+                                                   ((len lq_tmp$x##976) >= 0)]}
+bind 98 x##ayy : {VV : a_azJ | []}
+bind 99 ds_dMC : {lq_tmp$x##990 : [a_azJ] | [((len lq_tmp$x##990) >= 0)]}
+bind 100 lq_anf$##dN2 : {lq_tmp$x##976 : [a_azJ] | [((len lq_tmp$x##976) >= 0);
+                                                    (lq_tmp$x##976 = ds_dMB);
+                                                    ((len lq_tmp$x##976) >= 0);
+                                                    ((len lq_tmp$x##976) = (1 + (len ds_dMC)));
+                                                    ((null lq_tmp$x##976) <=> false);
+                                                    ((tail lq_tmp$x##976) = ds_dMC);
+                                                    ((head lq_tmp$x##976) = x##ayy);
+                                                    (lq_tmp$x##976 = (GHC.Types.$58$$35$$35$64 x##ayy ds_dMC));
+                                                    ((len lq_tmp$x##976) = (1 + (len ds_dMC)));
+                                                    ((null lq_tmp$x##976) <=> false);
+                                                    ((tail lq_tmp$x##976) = ds_dMC);
+                                                    ((head lq_tmp$x##976) = x##ayy);
+                                                    ((len lq_tmp$x##976) >= 0)]}
+bind 101 lq_anf$##dN3 : {lq_tmp$x##1000 : [a_azJ] | [((len lq_tmp$x##1000) >= 0);
+                                                     (lq_tmp$x##1000 = ds_dMC);
+                                                     ((len lq_tmp$x##1000) >= 0)]}
+bind 102 lq_anf$##dN3 : {lq_tmp$x##1004 : [a_azJ] | [((len lq_tmp$x##1004) >= 0);
+                                                     (lq_tmp$x##1004 = ds_dMC);
+                                                     ((len lq_tmp$x##1004) >= 0);
+                                                     ((len lq_tmp$x##1004) >= 0)]}
+bind 103 lq_anf$##dN3 : {lq_tmp$x##1004 : [a_azJ] | [((len lq_tmp$x##1004) >= 0);
+                                                     (lq_tmp$x##1004 = ds_dMC);
+                                                     ((len lq_tmp$x##1004) >= 0);
+                                                     ((len lq_tmp$x##1004) = 0);
+                                                     ((null lq_tmp$x##1004) <=> true);
+                                                     (lq_tmp$x##1004 = GHC.Types.$91$$93$$35$$35$6m);
+                                                     ((len lq_tmp$x##1004) = 0);
+                                                     ((null lq_tmp$x##1004) <=> true);
+                                                     ((len lq_tmp$x##1004) >= 0)]}
+bind 104 lq_tmp$x##1022 : {VV : a_azJ | []}
+bind 105 lq_anf$##dN6 : {lq_tmp$x##1014 : [a_azJ] | [((len lq_tmp$x##1014) = 0);
+                                                     ((null lq_tmp$x##1014) <=> true);
+                                                     ((len lq_tmp$x##1014) >= 0)]}
+bind 106 lq_tmp$x##1042 : {VV : a_azJ | []}
+bind 107 lq_anf$##dN3 : {lq_tmp$x##1048 : [a_azJ] | [((len lq_tmp$x##1048) >= 0);
+                                                     (lq_tmp$x##1048 = ds_dMC);
+                                                     ((len lq_tmp$x##1048) >= 0);
+                                                     ((len lq_tmp$x##1048) >= 0)]}
+bind 108 lq_anf$##dN7 : {VV : a_azJ | []}
+bind 109 lq_anf$##dN8 : {lq_tmp$x##1062 : [a_azJ] | [((len lq_tmp$x##1062) >= 0)]}
+bind 110 lq_anf$##dN3 : {lq_tmp$x##1048 : [a_azJ] | [((len lq_tmp$x##1048) >= 0);
+                                                     (lq_tmp$x##1048 = ds_dMC);
+                                                     ((len lq_tmp$x##1048) >= 0);
+                                                     ((len lq_tmp$x##1048) = (1 + (len lq_anf$##dN8)));
+                                                     ((null lq_tmp$x##1048) <=> false);
+                                                     ((tail lq_tmp$x##1048) = lq_anf$##dN8);
+                                                     ((head lq_tmp$x##1048) = lq_anf$##dN7);
+                                                     (lq_tmp$x##1048 = (GHC.Types.$58$$35$$35$64 lq_anf$##dN7 lq_anf$##dN8));
+                                                     ((len lq_tmp$x##1048) = (1 + (len lq_anf$##dN8)));
+                                                     ((null lq_tmp$x##1048) <=> false);
+                                                     ((tail lq_tmp$x##1048) = lq_anf$##dN8);
+                                                     ((head lq_tmp$x##1048) = lq_anf$##dN7);
+                                                     ((len lq_tmp$x##1048) >= 0)]}
+bind 111 ds_dMJ : {VV##1071 : GHC.Prim.Void# | [$k_##1072]}
+bind 112 ds_dMD : {lq_tmp$x##1094 : (Tuple  [a_azJ]  [a_azJ]) | [(((len (fst lq_tmp$x##1094)) + (len (snd lq_tmp$x##1094))) = (len ds_dMB))]}
+bind 113 ds_dMD : {lq_tmp$x##1127 : (Tuple  [a_azJ]  [a_azJ]) | [(((len (fst lq_tmp$x##1127)) + (len (snd lq_tmp$x##1127))) = (len ds_dMB))]}
+bind 114 xs1##aAj : {lq_tmp$x##1121 : [a_azJ] | [(((len lq_tmp$x##1121) > 1) => ((len lq_tmp$x##1121) < (len ds_dMB)));
+                                                 ((len lq_tmp$x##1121) >= 0)]}
+bind 115 xs2##XAw : {lq_tmp$x##1123 : [a_azJ] | [((len lq_tmp$x##1123) >= 0)]}
+bind 116 ds_dMD : {lq_tmp$x##1127 : (Tuple  [a_azJ]  [a_azJ]) | [(((len (fst lq_tmp$x##1127)) + (len (snd lq_tmp$x##1127))) = (len ds_dMB));
+                                                                 ((snd lq_tmp$x##1127) = xs2##XAw);
+                                                                 ((fst lq_tmp$x##1127) = xs1##aAj);
+                                                                 ((x_Tuple22 lq_tmp$x##1127) = xs2##XAw);
+                                                                 ((x_Tuple21 lq_tmp$x##1127) = xs1##aAj);
+                                                                 (lq_tmp$x##1127 = (GHC.Tuple.$40$$44$$41$$35$$35$74 xs1##aAj xs2##XAw));
+                                                                 ((snd lq_tmp$x##1127) = xs2##XAw);
+                                                                 ((fst lq_tmp$x##1127) = xs1##aAj);
+                                                                 ((x_Tuple22 lq_tmp$x##1127) = xs2##XAw);
+                                                                 ((x_Tuple21 lq_tmp$x##1127) = xs1##aAj)]}
+bind 117 xs1##aAj : {VV##1117 : [a_azJ] | [$k_##1118;
+                                           ((len VV##1117) >= 0)]}
+bind 118 ds_dMD : {lq_tmp$x##1169 : (Tuple  [a_azJ]  [a_azJ]) | [(((len (fst lq_tmp$x##1169)) + (len (snd lq_tmp$x##1169))) = (len ds_dMB))]}
+bind 119 xs1##aAj : {lq_tmp$x##1163 : [a_azJ] | [((len lq_tmp$x##1163) >= 0)]}
+bind 120 xs2##aAk : {lq_tmp$x##1165 : [a_azJ] | [(((len lq_tmp$x##1165) > 1) => ((len lq_tmp$x##1165) < (len ds_dMB)));
+                                                 ((len lq_tmp$x##1165) >= 0)]}
+bind 121 ds_dMD : {lq_tmp$x##1169 : (Tuple  [a_azJ]  [a_azJ]) | [(((len (fst lq_tmp$x##1169)) + (len (snd lq_tmp$x##1169))) = (len ds_dMB));
+                                                                 ((snd lq_tmp$x##1169) = xs2##aAk);
+                                                                 ((fst lq_tmp$x##1169) = xs1##aAj);
+                                                                 ((x_Tuple22 lq_tmp$x##1169) = xs2##aAk);
+                                                                 ((x_Tuple21 lq_tmp$x##1169) = xs1##aAj);
+                                                                 (lq_tmp$x##1169 = (GHC.Tuple.$40$$44$$41$$35$$35$74 xs1##aAj xs2##aAk));
+                                                                 ((snd lq_tmp$x##1169) = xs2##aAk);
+                                                                 ((fst lq_tmp$x##1169) = xs1##aAj);
+                                                                 ((x_Tuple22 lq_tmp$x##1169) = xs2##aAk);
+                                                                 ((x_Tuple21 lq_tmp$x##1169) = xs1##aAj)]}
+bind 122 xs2##aAk : {VV##1159 : [a_azJ] | [$k_##1160;
+                                           ((len VV##1159) >= 0)]}
+bind 123 lq_anf$##dN4 : {VV##1213 : [a_azJ] | [((len VV##1213) = (len xs1##aAj));
+                                               ((len VV##1213) >= 0)]}
+bind 124 lq_anf$##dN5 : {VV##1233 : [a_azJ] | [((len VV##1233) = (len xs2##aAk));
+                                               ((len VV##1233) >= 0)]}
+bind 125 fix$36$$36$dOrd_aAe : {VV##1277 : (GHC.Classes.Ord  a_azJ) | []}
+bind 126 VV##1278 : {VV##1278 : [a_azJ] | [((len VV##1278) >= 0)]}
+bind 127 lq_tmp$x##945 : {VV : a_azJ | []}
+bind 128 lq_tmp$x##1270 : {VV##1281 : [a_azJ] | [((len VV##1281) >= 0)]}
+bind 129 VV##1282 : {VV##1282 : [a_azJ] | [((len VV##1282) >= 0)]}
+bind 130 lq_tmp$x##946 : {VV : a_azJ | []}
+bind 131 VV##1285 : {VV##1285 : [a_azJ] | [((len VV##1285) >= 0)]}
+bind 132 lq_tmp$x##945 : {VV : a_azJ | []}
+bind 133 ds_dMB : {VV##1288 : [a_azJ] | [((len VV##1288) >= 0)]}
+bind 134 VV##1289 : {VV##1289 : [a_azJ] | [((len VV##1289) >= 0)]}
+bind 135 lq_tmp$x##946 : {VV : a_azJ | []}
+bind 136 VV##1292 : {VV##1292 : [a_azJ] | [$k_##1083[VV##1082:=VV##1292][ds_dMJ:=GHC.Prim.void###0l];
+                                           ((len VV##1292) >= 0)]}
+bind 137 lq_tmp$x##946 : {VV : a_azJ | []}
+bind 138 VV##1295 : {VV##1295 : GHC.Prim.Void# | [(VV##1295 = GHC.Prim.void###0l)]}
+bind 139 VV##1297 : {VV##1297 : [a_azJ] | [((len VV##1297) = ((len lq_anf$##dN4) + (len lq_anf$##dN5)));
+                                           ((len VV##1297) >= 0)]}
+bind 140 lq_tmp$x##1078 : {VV : a_azJ | []}
+bind 141 VV##1300 : {VV##1300 : [a_azJ] | [((len VV##1300) = (len xs2##aAk));
+                                           ((len VV##1300) >= 0);
+                                           (VV##1300 = lq_anf$##dN5);
+                                           ((len VV##1300) >= 0)]}
+bind 142 lq_tmp$x##1250 : {VV : a_azJ | []}
+bind 143 VV##1303 : {VV##1303 : [a_azJ] | [((len VV##1303) = (len xs1##aAj));
+                                           ((len VV##1303) >= 0);
+                                           (VV##1303 = lq_anf$##dN4);
+                                           ((len VV##1303) >= 0)]}
+bind 144 lq_tmp$x##1249 : {VV : a_azJ | []}
+bind 145 VV##1306 : {VV##1306 : [a_azJ] | [$k_##1160[VV##1159:=VV##1306][lq_tmp$x##1231:=VV##1306];
+                                           ((len VV##1306) >= 0);
+                                           (VV##1306 = xs2##aAk);
+                                           ((len VV##1306) >= 0)]}
+bind 146 lq_tmp$x##945 : {VV : a_azJ | []}
+bind 147 VV##1309 : {VV##1309 : [a_azJ] | [$k_##1118[VV##1117:=VV##1309][lq_tmp$x##1211:=VV##1309];
+                                           ((len VV##1309) >= 0);
+                                           (VV##1309 = xs1##aAj);
+                                           ((len VV##1309) >= 0)]}
+bind 148 lq_tmp$x##945 : {VV : a_azJ | []}
+bind 149 VV##1312 : {VV##1312 : [a_azJ] | [(((len VV##1312) > 1) => ((len VV##1312) < (len ds_dMB)));
+                                           ((len VV##1312) >= 0);
+                                           (VV##1312 = xs2##aAk);
+                                           ((len VV##1312) >= 0)]}
+bind 150 lq_tmp$x##1155 : {VV : a_azJ | []}
+bind 151 VV##1315 : {VV##1315 : [a_azJ] | [(((len VV##1315) > 1) => ((len VV##1315) < (len ds_dMB)));
+                                           ((len VV##1315) >= 0);
+                                           (VV##1315 = xs1##aAj);
+                                           ((len VV##1315) >= 0)]}
+bind 152 lq_tmp$x##1113 : {VV : a_azJ | []}
+bind 153 VV##1318 : {VV##1318 : [a_azJ] | [((len VV##1318) >= 0);
+                                           (VV##1318 = ds_dMB);
+                                           ((len VV##1318) >= 0)]}
+bind 154 lq_tmp$x##1098 : {VV : a_azJ | []}
+bind 155 VV##1321 : {VV##1321 : [a_azJ] | [((len VV##1321) = (1 + (len lq_anf$##dN6)));
+                                           ((null VV##1321) <=> false);
+                                           ((tail VV##1321) = lq_anf$##dN6);
+                                           ((head VV##1321) = x##ayy);
+                                           ((len VV##1321) >= 0)]}
+bind 156 lq_tmp$x##946 : {VV : a_azJ | []}
+bind 157 VV##1324 : {VV##1324 : [a_azJ] | [((len VV##1324) = 0);
+                                           ((null VV##1324) <=> true);
+                                           ((len VV##1324) >= 0);
+                                           (VV##1324 = lq_anf$##dN6);
+                                           ((len VV##1324) >= 0)]}
+bind 158 lq_tmp$x##1034 : {VV : a_azJ | []}
+bind 159 VV##1327 : {VV##1327 : [a_azJ] | [((len VV##1327) = 0);
+                                           ((null VV##1327) <=> true);
+                                           ((len VV##1327) >= 0)]}
+bind 160 lq_tmp$x##946 : {VV : a_azJ | []}
+bind 161 VV##1330 : {VV##1330 : [a_azx] | [((len VV##1330) >= 0)]}
+bind 162 lq_tmp$x##515 : {VV : a_azx | []}
+bind 163 ds_dMs : {VV##1333 : [a_azx] | [((len VV##1333) >= 0)]}
+bind 164 VV##1334 : {VV##1334 : (Tuple  [a_azx]  [a_azx]) | []}
+bind 165 VV##1336 : {VV##1336 : [a_azx] | [((len VV##1336) >= 0)]}
+bind 166 lq_tmp$x##516 : {VV : a_azx | []}
+bind 167 VV##1339 : {VV##1339 : [a_azx] | [((len VV##1339) >= 0)]}
+bind 168 lq_tmp$x##517 : {VV : a_azx | []}
+bind 169 lq_tmp$x##519 : {VV##1342 : [a_azx] | [((len VV##1342) >= 0)]}
+bind 170 VV##1343 : {VV##1343 : [a_azx] | [((len VV##1343) >= 0)]}
+bind 171 lq_tmp$x##518 : {VV : a_azx | []}
+bind 172 VV##1346 : {VV##1346 : (Tuple  [a_azx]  [a_azx]) | [((snd VV##1346) = lq_anf$##dN1);
+                                                             ((fst VV##1346) = lq_anf$##dN0);
+                                                             ((x_Tuple22 VV##1346) = lq_anf$##dN1);
+                                                             ((x_Tuple21 VV##1346) = lq_anf$##dN0)]}
+bind 173 VV##1348 : {VV##1348 : [a_azx] | [$k_##890[VV##889:=VV##1348][lq_tmp$x##893:=VV##1348][lq_tmp$x##879:=lq_anf$##dN0][lq_tmp$x##880:=lq_anf$##dN1][lq_tmp$x##876:=VV##1346];
+                                           ((len VV##1348) >= 0)]}
+bind 174 lq_tmp$x##516 : {VV : a_azx | []}
+bind 175 VV##1351 : {VV##1351 : [a_azx] | [$k_##902[lq_tmp$x##879:=lq_anf$##dN0][lq_tmp$x##905:=VV##1351][lq_tmp$x##880:=lq_anf$##dN1][VV##901:=VV##1351][lq_tmp$x##876:=VV##1346];
+                                           ((len VV##1351) >= 0)]}
+bind 176 lq_tmp$x##517 : {VV : a_azx | []}
+bind 177 lq_tmp$x##519 : {VV##1354 : [a_azx] | [((len VV##1354) >= 0)]}
+bind 178 VV##1355 : {VV##1355 : [a_azx] | [$k_##914[lq_tmp$x##881:=lq_tmp$x##519][VV##913:=VV##1355][lq_tmp$x##879:=lq_anf$##dN0][lq_tmp$x##916:=lq_tmp$x##519][lq_tmp$x##905:=VV##1355][lq_tmp$x##880:=lq_anf$##dN1][lq_tmp$x##876:=VV##1346];
+                                           ((len VV##1355) >= 0)]}
+bind 179 lq_tmp$x##518 : {VV : a_azx | []}
+bind 180 VV##1358 : {VV##1358 : [a_azx] | [((len VV##1358) = (1 + (len ys##aA5)));
+                                           ((null VV##1358) <=> false);
+                                           ((tail VV##1358) = ys##aA5);
+                                           ((head VV##1358) = y##ayD);
+                                           ((len VV##1358) >= 0);
+                                           (VV##1358 = lq_anf$##dN1);
+                                           ((len VV##1358) >= 0)]}
+bind 181 lq_tmp$x##904 : {VV : a_azx | []}
+bind 182 VV##1361 : {VV##1361 : [a_azx] | [((len VV##1361) = (1 + (len xs##aA4)));
+                                           ((null VV##1361) <=> false);
+                                           ((tail VV##1361) = xs##aA4);
+                                           ((head VV##1361) = x##ayC);
+                                           ((len VV##1361) >= 0);
+                                           (VV##1361 = lq_anf$##dN0);
+                                           ((len VV##1361) >= 0)]}
+bind 183 lq_tmp$x##892 : {VV : a_azx | []}
+bind 184 VV##1364 : {VV##1364 : [a_azx] | [$k_##795[lq_tmp$x##872:=VV##1364][VV##794:=VV##1364];
+                                           ((len VV##1364) >= 0);
+                                           (VV##1364 = ys##aA5);
+                                           ((len VV##1364) >= 0)]}
+bind 185 lq_tmp$x##861 : {VV : a_azx | []}
+bind 186 VV##1367 : {VV##1367 : [a_azx] | [$k_##753[VV##752:=VV##1367][lq_tmp$x##849:=VV##1367];
+                                           ((len VV##1367) >= 0);
+                                           (VV##1367 = xs##aA4);
+                                           ((len VV##1367) >= 0)]}
+bind 187 lq_tmp$x##838 : {VV : a_azx | []}
+bind 188 VV##1370 : {VV##1370 : [a_azx] | [(((len VV##1370) > 1) => ((len VV##1370) < (len zs##ayE)));
+                                           ((len VV##1370) >= 0);
+                                           (VV##1370 = ys##aA5);
+                                           ((len VV##1370) >= 0)]}
+bind 189 lq_tmp$x##790 : {VV : a_azx | []}
+bind 190 VV##1373 : {VV##1373 : [a_azx] | [(((len VV##1373) > 1) => ((len VV##1373) < (len zs##ayE)));
+                                           ((len VV##1373) >= 0);
+                                           (VV##1373 = xs##aA4);
+                                           ((len VV##1373) >= 0)]}
+bind 191 lq_tmp$x##748 : {VV : a_azx | []}
+bind 192 VV##1376 : {VV##1376 : [a_azx] | [((len VV##1376) >= 0);
+                                           (VV##1376 = zs##ayE);
+                                           ((len VV##1376) >= 0)]}
+bind 193 lq_tmp$x##515 : {VV : a_azx | []}
+bind 194 VV##1379 : {VV##1379 : (Tuple  [a_azx]  [a_azx]) | [((snd VV##1379) = lq_anf$##dMZ);
+                                                             ((fst VV##1379) = ds_dMs);
+                                                             ((x_Tuple22 VV##1379) = lq_anf$##dMZ);
+                                                             ((x_Tuple21 VV##1379) = ds_dMs)]}
+bind 195 VV##1381 : {VV##1381 : [a_azx] | [$k_##662[lq_tmp$x##652:=lq_anf$##dMZ][lq_tmp$x##665:=VV##1381][lq_tmp$x##648:=VV##1379][lq_tmp$x##651:=ds_dMs][VV##661:=VV##1381];
+                                           ((len VV##1381) >= 0)]}
+bind 196 lq_tmp$x##516 : {VV : a_azx | []}
+bind 197 VV##1384 : {VV##1384 : [a_azx] | [$k_##674[lq_tmp$x##652:=lq_anf$##dMZ][VV##673:=VV##1384][lq_tmp$x##648:=VV##1379][lq_tmp$x##651:=ds_dMs][lq_tmp$x##677:=VV##1384];
+                                           ((len VV##1384) >= 0)]}
+bind 198 lq_tmp$x##517 : {VV : a_azx | []}
+bind 199 lq_tmp$x##519 : {VV##1387 : [a_azx] | [((len VV##1387) >= 0)]}
+bind 200 VV##1388 : {VV##1388 : [a_azx] | [$k_##686[lq_tmp$x##652:=lq_anf$##dMZ][lq_tmp$x##688:=lq_tmp$x##519][lq_tmp$x##648:=VV##1379][VV##685:=VV##1388][lq_tmp$x##651:=ds_dMs][lq_tmp$x##653:=lq_tmp$x##519][lq_tmp$x##677:=VV##1388];
+                                           ((len VV##1388) >= 0)]}
+bind 201 lq_tmp$x##518 : {VV : a_azx | []}
+bind 202 VV##1391 : {VV##1391 : [a_azx] | [((len VV##1391) = 0);
+                                           ((null VV##1391) <=> true);
+                                           ((len VV##1391) >= 0);
+                                           (VV##1391 = lq_anf$##dMZ);
+                                           ((len VV##1391) >= 0)]}
+bind 203 lq_tmp$x##676 : {VV : a_azx | []}
+bind 204 VV##1394 : {VV##1394 : [a_azx] | [((len VV##1394) >= 0);
+                                           (VV##1394 = ds_dMs);
+                                           ((len VV##1394) >= 0)]}
+bind 205 lq_tmp$x##664 : {VV : a_azx | []}
+bind 206 VV##1397 : {VV##1397 : (Tuple  [a_azx]  [a_azx]) | [((snd VV##1397) = lq_anf$##dMX);
+                                                             ((fst VV##1397) = ds_dMs);
+                                                             ((x_Tuple22 VV##1397) = lq_anf$##dMX);
+                                                             ((x_Tuple21 VV##1397) = ds_dMs)]}
+bind 207 VV##1399 : {VV##1399 : [a_azx] | [$k_##563[lq_tmp$x##553:=lq_anf$##dMX][lq_tmp$x##566:=VV##1399][lq_tmp$x##552:=ds_dMs][VV##562:=VV##1399][lq_tmp$x##549:=VV##1397];
+                                           ((len VV##1399) >= 0)]}
+bind 208 lq_tmp$x##516 : {VV : a_azx | []}
+bind 209 VV##1402 : {VV##1402 : [a_azx] | [$k_##575[VV##574:=VV##1402][lq_tmp$x##553:=lq_anf$##dMX][lq_tmp$x##578:=VV##1402][lq_tmp$x##552:=ds_dMs][lq_tmp$x##549:=VV##1397];
+                                           ((len VV##1402) >= 0)]}
+bind 210 lq_tmp$x##517 : {VV : a_azx | []}
+bind 211 lq_tmp$x##519 : {VV##1405 : [a_azx] | [((len VV##1405) >= 0)]}
+bind 212 VV##1406 : {VV##1406 : [a_azx] | [$k_##587[lq_tmp$x##554:=lq_tmp$x##519][lq_tmp$x##553:=lq_anf$##dMX][lq_tmp$x##589:=lq_tmp$x##519][lq_tmp$x##578:=VV##1406][VV##586:=VV##1406][lq_tmp$x##552:=ds_dMs][lq_tmp$x##549:=VV##1397];
+                                           ((len VV##1406) >= 0)]}
+bind 213 lq_tmp$x##518 : {VV : a_azx | []}
+bind 214 VV##1409 : {VV##1409 : [a_azx] | [((len VV##1409) = 0);
+                                           ((null VV##1409) <=> true);
+                                           ((len VV##1409) >= 0);
+                                           (VV##1409 = lq_anf$##dMX);
+                                           ((len VV##1409) >= 0)]}
+bind 215 lq_tmp$x##577 : {VV : a_azx | []}
+bind 216 VV##1412 : {VV##1412 : [a_azx] | [((len VV##1412) >= 0);
+                                           (VV##1412 = ds_dMs);
+                                           ((len VV##1412) >= 0)]}
+bind 217 lq_tmp$x##565 : {VV : a_azx | []}
+bind 218 fix$36$$36$dOrd_azK : {VV##1415 : (GHC.Classes.Ord  a_azo) | []}
+bind 219 VV##1416 : {VV##1416 : [a_azo] | [((len VV##1416) >= 0)]}
+bind 220 lq_tmp$x##115 : {VV : a_azo | []}
+bind 221 lq_tmp$x##495 : {VV##1419 : [a_azo] | [((len VV##1419) >= 0)]}
+bind 222 VV##1420 : {VV##1420 : [a_azo] | [((len VV##1420) >= 0)]}
+bind 223 lq_tmp$x##116 : {VV : a_azo | []}
+bind 224 lq_tmp$x##499 : {VV##1423 : [a_azo] | [((len VV##1423) >= 0)]}
+bind 225 VV##1424 : {VV##1424 : [a_azo] | [((len VV##1424) >= 0)]}
+bind 226 lq_tmp$x##117 : {VV : a_azo | []}
+bind 227 VV##1427 : {VV##1427 : [a_azo] | [((len VV##1427) >= 0)]}
+bind 228 lq_tmp$x##115 : {VV : a_azo | []}
+bind 229 xs##ayP : {VV##1430 : [a_azo] | [((len VV##1430) >= 0)]}
+bind 230 VV##1431 : {VV##1431 : [a_azo] | [((len VV##1431) >= 0)]}
+bind 231 lq_tmp$x##116 : {VV : a_azo | []}
+bind 232 lq_tmp$x##487 : {VV##1434 : [a_azo] | [((len VV##1434) >= 0)]}
+bind 233 VV##1435 : {VV##1435 : [a_azo] | [((len VV##1435) >= 0)]}
+bind 234 lq_tmp$x##117 : {VV : a_azo | []}
+bind 235 VV##1438 : {VV##1438 : [a_azo] | [((len VV##1438) >= 0)]}
+bind 236 lq_tmp$x##116 : {VV : a_azo | []}
+bind 237 ds_dMl : {VV##1441 : [a_azo] | [((len VV##1441) >= 0)]}
+bind 238 VV##1442 : {VV##1442 : [a_azo] | [((len VV##1442) >= 0)]}
+bind 239 lq_tmp$x##117 : {VV : a_azo | []}
+bind 240 VV##1445 : {VV##1445 : [a_azo] | [$k_##175[VV##174:=VV##1445][ds_dMr:=GHC.Prim.void###0l];
+                                           ((len VV##1445) >= 0)]}
+bind 241 lq_tmp$x##117 : {VV : a_azo | []}
+bind 242 VV##1448 : {VV##1448 : GHC.Prim.Void# | [(VV##1448 = GHC.Prim.void###0l)]}
+bind 243 VV##1450 : {VV##1450 : [a_azo] | [((len VV##1450) = (1 + (len lq_anf$##dMT)));
+                                           ((null VV##1450) <=> false);
+                                           ((tail VV##1450) = lq_anf$##dMT);
+                                           ((head VV##1450) = x##ayR);
+                                           ((len VV##1450) >= 0)]}
+bind 244 lq_tmp$x##170 : {VV : a_azo | []}
+bind 245 VV##1453 : {VV##1453 : [a_azo] | [((len VV##1453) = ((len xs##ayS) + (len lq_anf$##dMS)));
+                                           ((len VV##1453) >= 0);
+                                           (VV##1453 = lq_anf$##dMT);
+                                           ((len VV##1453) >= 0)]}
+bind 246 lq_tmp$x##464 : {VV : a_azo | []}
+bind 247 VV##1456 : {VV##1456 : [a_azo] | [((len VV##1456) = (1 + (len ys##ayU)));
+                                           ((null VV##1456) <=> false);
+                                           ((tail VV##1456) = ys##ayU);
+                                           ((head VV##1456) = y##ayT);
+                                           ((len VV##1456) >= 0);
+                                           (VV##1456 = lq_anf$##dMS);
+                                           ((len VV##1456) >= 0)]}
+bind 248 lq_tmp$x##116 : {VV : a_azo | []}
+bind 249 VV##1459 : {VV##1459 : [a_azo] | [((len VV##1459) >= 0);
+                                           (VV##1459 = xs##ayS);
+                                           ((len VV##1459) >= 0)]}
+bind 250 lq_tmp$x##115 : {VV : a_azo | []}
+bind 251 VV##1462 : {VV##1462 : [a_azo] | [((len VV##1462) >= 0);
+                                           (VV##1462 = ys##ayU);
+                                           ((len VV##1462) >= 0)]}
+bind 252 lq_tmp$x##412 : {VV : a_azo | []}
+bind 253 VV##1465 : {VV##1465 : [a_azo] | [$k_##321[VV##320:=VV##1465][ds_dMp:=GHC.Prim.void###0l];
+                                           ((len VV##1465) >= 0)]}
+bind 254 lq_tmp$x##170 : {VV : a_azo | []}
+bind 255 VV##1468 : {VV##1468 : GHC.Prim.Void# | [(VV##1468 = GHC.Prim.void###0l)]}
+bind 256 VV##1470 : {VV##1470 : [a_azo] | [((len VV##1470) = (1 + (len lq_anf$##dMR)));
+                                           ((null VV##1470) <=> false);
+                                           ((tail VV##1470) = lq_anf$##dMR);
+                                           ((head VV##1470) = y##ayT);
+                                           ((len VV##1470) >= 0)]}
+bind 257 lq_tmp$x##316 : {VV : a_azo | []}
+bind 258 VV##1473 : {VV##1473 : [a_azo] | [((len VV##1473) = ((len lq_anf$##dMQ) + (len ys##ayU)));
+                                           ((len VV##1473) >= 0);
+                                           (VV##1473 = lq_anf$##dMR);
+                                           ((len VV##1473) >= 0)]}
+bind 259 lq_tmp$x##384 : {VV : a_azo | []}
+bind 260 VV##1476 : {VV##1476 : [a_azo] | [((len VV##1476) >= 0);
+                                           (VV##1476 = ys##ayU);
+                                           ((len VV##1476) >= 0)]}
+bind 261 lq_tmp$x##116 : {VV : a_azo | []}
+bind 262 VV##1479 : {VV##1479 : [a_azo] | [((len VV##1479) = (1 + (len xs##ayS)));
+                                           ((null VV##1479) <=> false);
+                                           ((tail VV##1479) = xs##ayS);
+                                           ((head VV##1479) = x##ayR);
+                                           ((len VV##1479) >= 0);
+                                           (VV##1479 = lq_anf$##dMQ);
+                                           ((len VV##1479) >= 0)]}
+bind 263 lq_tmp$x##115 : {VV : a_azo | []}
+bind 264 VV##1482 : {VV##1482 : [a_azo] | [((len VV##1482) >= 0);
+                                           (VV##1482 = xs##ayS);
+                                           ((len VV##1482) >= 0)]}
+bind 265 lq_tmp$x##332 : {VV : a_azo | []}
+bind 266 VV##1485 : {VV##1485 : [a_azo] | [$k_##244[ds_dMn:=GHC.Prim.void###0l][VV##243:=VV##1485];
+                                           ((len VV##1485) >= 0)]}
+bind 267 lq_tmp$x##170 : {VV : a_azo | []}
+bind 268 VV##1488 : {VV##1488 : GHC.Prim.Void# | [(VV##1488 = GHC.Prim.void###0l)]}
+bind 269 VV##1490 : {VV##1490 : [a_azo] | [$k_##259[VV##258:=VV##1490][lq_tmp$x##262:=VV##1490][lq_tmp$x##250:=lq_anf$##dMN];
+                                           ((len VV##1490) >= 0)]}
+bind 270 lq_tmp$x##239 : {VV : a_azo | []}
+bind 271 VV##1493 : {VV##1493 : int | [(VV##1493 ~~ lit$36$$47$Users$47$rjhala$47$research$47$stack$47$liquidhaskell$47$tests$47$pos$47$MergeSort.hs$58$$40$48$44$1$41$$45$$40$52$44$41$41$$124$function$32$merge);
+                                       ((strLen VV##1493) = 95);
+                                       (VV##1493 = lq_anf$##dMN)]}
+bind 272 VV##1495 : {VV##1495 : [a_azo] | [((len VV##1495) >= 0);
+                                           (VV##1495 = ds_dMl);
+                                           ((len VV##1495) >= 0)]}
+bind 273 lq_tmp$x##170 : {VV : a_azo | []}
+bind 274 VV##1498 : {VV##1498 : [a_azo] | [((len VV##1498) >= 0);
+                                           (VV##1498 = xs##ayP);
+                                           ((len VV##1498) >= 0)]}
+bind 275 lq_tmp$x##117 : {VV : a_azo | []}
+bind 276 VV##1071 : {VV##1071 : GHC.Prim.Void# | [$k_##1072]}
+bind 277 VV##1159 : {VV##1159 : [a_azJ] | [$k_##1160;
+                                           ((len VV##1159) >= 0)]}
+bind 278 lq_tmp$x##1155 : {VV : a_azJ | []}
+bind 279 VV##1117 : {VV##1117 : [a_azJ] | [$k_##1118;
+                                           ((len VV##1117) >= 0)]}
+bind 280 lq_tmp$x##1113 : {VV : a_azJ | []}
+bind 281 VV##1082 : {VV##1082 : [a_azJ] | [$k_##1083;
+                                           ((len VV##1082) >= 0)]}
+bind 282 lq_tmp$x##1078 : {VV : a_azJ | []}
+bind 283 VV##913 : {VV##913 : [a_azx] | [$k_##914;
+                                         ((len VV##913) >= 0)]}
+bind 284 lq_tmp$x##909 : {VV : a_azx | []}
+bind 285 VV##901 : {VV##901 : [a_azx] | [$k_##902;
+                                         ((len VV##901) >= 0)]}
+bind 286 lq_tmp$x##897 : {VV : a_azx | []}
+bind 287 VV##889 : {VV##889 : [a_azx] | [$k_##890;
+                                         ((len VV##889) >= 0)]}
+bind 288 lq_tmp$x##885 : {VV : a_azx | []}
+bind 289 VV##794 : {VV##794 : [a_azx] | [$k_##795;
+                                         ((len VV##794) >= 0)]}
+bind 290 lq_tmp$x##790 : {VV : a_azx | []}
+bind 291 VV##752 : {VV##752 : [a_azx] | [$k_##753;
+                                         ((len VV##752) >= 0)]}
+bind 292 lq_tmp$x##748 : {VV : a_azx | []}
+bind 293 VV##685 : {VV##685 : [a_azx] | [$k_##686;
+                                         ((len VV##685) >= 0)]}
+bind 294 lq_tmp$x##681 : {VV : a_azx | []}
+bind 295 VV##673 : {VV##673 : [a_azx] | [$k_##674;
+                                         ((len VV##673) >= 0)]}
+bind 296 lq_tmp$x##669 : {VV : a_azx | []}
+bind 297 VV##661 : {VV##661 : [a_azx] | [$k_##662;
+                                         ((len VV##661) >= 0)]}
+bind 298 lq_tmp$x##657 : {VV : a_azx | []}
+bind 299 VV##586 : {VV##586 : [a_azx] | [$k_##587;
+                                         ((len VV##586) >= 0)]}
+bind 300 lq_tmp$x##582 : {VV : a_azx | []}
+bind 301 VV##574 : {VV##574 : [a_azx] | [$k_##575;
+                                         ((len VV##574) >= 0)]}
+bind 302 lq_tmp$x##570 : {VV : a_azx | []}
+bind 303 VV##562 : {VV##562 : [a_azx] | [$k_##563;
+                                         ((len VV##562) >= 0)]}
+bind 304 lq_tmp$x##558 : {VV : a_azx | []}
+bind 305 VV##163 : {VV##163 : GHC.Prim.Void# | [$k_##164]}
+bind 306 VV##309 : {VV##309 : GHC.Prim.Void# | [$k_##310]}
+bind 307 VV##320 : {VV##320 : [a_azo] | [$k_##321;
+                                         ((len VV##320) >= 0)]}
+bind 308 lq_tmp$x##316 : {VV : a_azo | []}
+bind 309 VV##232 : {VV##232 : GHC.Prim.Void# | [$k_##233]}
+bind 310 VV##258 : {VV##258 : [a_azo] | [$k_##259;
+                                         ((len VV##258) >= 0)]}
+bind 311 lq_tmp$x##254 : {VV : a_azo | []}
+bind 312 VV##243 : {VV##243 : [a_azo] | [$k_##244;
+                                         ((len VV##243) >= 0)]}
+bind 313 lq_tmp$x##239 : {VV : a_azo | []}
+bind 314 VV##174 : {VV##174 : [a_azo] | [$k_##175;
+                                         ((len VV##174) >= 0)]}
+bind 315 lq_tmp$x##170 : {VV : a_azo | []}
+
+
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       80;
+       82;
+       83;
+       84]
+  lhs {VV##50 : [a_azx] | [(((len VV##50) > 1) => ((len VV##50) < (len zs##ayE)));
+                           ((len VV##50) >= 0);
+                           (VV##50 = ys##aA5);
+                           ((len VV##50) >= 0)]}
+  rhs {VV##50 : [a_azx] | [$k_##795[VV##794:=VV##50][VV##1370:=VV##50][VV##F:=VV##50][VV##F##50:=VV##50]]}
+  id 50 tag [2]
+  // META constraint id 50 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       77;
+       78;
+       79]
+  lhs {VV##53 : [a_azx] | [(((len VV##53) > 1) => ((len VV##53) < (len zs##ayE)));
+                           ((len VV##53) >= 0);
+                           (VV##53 = xs##aA4);
+                           ((len VV##53) >= 0)]}
+  rhs {VV##53 : [a_azx] | [$k_##753[VV##752:=VV##53][VV##1373:=VV##53][VV##F##53:=VV##53][VV##F:=VV##53]]}
+  id 53 tag [2]
+  // META constraint id 53 : ()
+
+
+constraint:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89]
+  lhs {VV##30 : (Tuple  [a_azx]  [a_azx]) | [((snd VV##30) = lq_anf$##dN1);
+                                             ((fst VV##30) = lq_anf$##dN0);
+                                             ((x_Tuple22 VV##30) = lq_anf$##dN1);
+                                             ((x_Tuple21 VV##30) = lq_anf$##dN0)]}
+  rhs {VV##30 : (Tuple  [a_azx]  [a_azx]) | [(((len (fst VV##30)) + (len (snd VV##30))) = (len ds_dMs))]}
+  id 30 tag [2]
+  // META constraint id 30 : ()
+
+
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       67;
+       69;
+       70]
+  reft {VV##685 : [a_azx] | [$k_##686]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       49]
+  reft {VV##414 : a_azo | [$k_##415]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59; 302]
+  reft {VV##571 : a_azx | [$k_##572]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       67;
+       69;
+       296]
+  reft {VV##670 : a_azx | [$k_##671]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       86]
+  reft {VV##843 : a_azx | [$k_##844]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 19; 20; 21]
+  reft {VV##163 : GHC.Prim.Void# | [$k_##164]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89;
+       287]
+  reft {VV##882 : a_azx | [$k_##883]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80]
+  reft {VV##794 : [a_azx] | [$k_##795]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59; 304]
+  reft {VV##559 : a_azx | [$k_##560]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59; 303]
+  reft {VV##555 : a_azx | [$k_##556]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112;
+       117;
+       122;
+       123]
+  reft {VV##1226 : a_azJ | [$k_##1227]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89;
+       90;
+       283]
+  reft {VV##906 : a_azx | [$k_##907]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42;
+       43;
+       307]
+  reft {VV##313 : a_azo | [$k_##314]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       67;
+       69;
+       297]
+  reft {VV##654 : a_azx | [$k_##655]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       32;
+       33;
+       312]
+  reft {VV##236 : a_azo | [$k_##237]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112;
+       117]
+  reft {VV##1159 : [a_azJ] | [$k_##1160]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112]
+  reft {VV##1117 : [a_azJ] | [$k_##1118]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89]
+  reft {VV##889 : [a_azx] | [$k_##890]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75]
+  reft {VV##752 : [a_azx] | [$k_##753]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       88]
+  reft {VV##866 : a_azx | [$k_##867]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       32;
+       33;
+       34;
+       311]
+  reft {VV##255 : a_azo | [$k_##256]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59; 60; 300]
+  reft {VV##583 : a_azx | [$k_##584]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89;
+       90]
+  reft {VV##913 : [a_azx] | [$k_##914]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110]
+  reft {VV##1071 : GHC.Prim.Void# | [$k_##1072]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 62; 63; 64; 67]
+  reft {VV##638 : a_azx | [$k_##639]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112;
+       280]
+  reft {VV##1114 : a_azJ | [$k_##1115]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       290]
+  reft {VV##791 : a_azx | [$k_##792]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59]
+  reft {VV##574 : [a_azx] | [$k_##575]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       314]
+  reft {VV##167 : a_azo | [$k_##168]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87]
+  reft {VV##863 : a_azx | [$k_##864]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59; 60]
+  reft {VV##586 : [a_azx] | [$k_##587]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42]
+  reft {VV##309 : GHC.Prim.Void# | [$k_##310]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       32]
+  reft {VV##232 : GHC.Prim.Void# | [$k_##233]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       292]
+  reft {VV##749 : a_azx | [$k_##750]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       291]
+  reft {VV##745 : a_azx | [$k_##746]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       49;
+       51]
+  reft {VV##444 : a_azo | [$k_##445]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       103;
+       105]
+  reft {VV##1036 : a_azJ | [$k_##1037]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       49;
+       51;
+       52]
+  reft {VV##466 : a_azo | [$k_##467]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74]
+  reft {VV##738 : a_azx | [$k_##739]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112;
+       117;
+       122;
+       123;
+       124]
+  reft {VV##1252 : a_azJ | [$k_##1253]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       49;
+       50]
+  reft {VV##417 : a_azo | [$k_##418]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59]
+  reft {VV##562 : [a_azx] | [$k_##563]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 62; 63; 64; 67; 68]
+  reft {VV##641 : a_azx | [$k_##642]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112;
+       279]
+  reft {VV##1110 : a_azJ | [$k_##1111]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42;
+       43]
+  reft {VV##320 : [a_azo] | [$k_##321]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89;
+       286]
+  reft {VV##898 : a_azx | [$k_##899]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42;
+       43;
+       44]
+  reft {VV##337 : a_azo | [$k_##338]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       67;
+       69;
+       70;
+       293]
+  reft {VV##678 : a_azx | [$k_##679]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42;
+       43;
+       45]
+  reft {VV##364 : a_azo | [$k_##365]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       281]
+  reft {VV##1075 : a_azJ | [$k_##1076]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       103;
+       104]
+  reft {VV##1019 : a_azJ | [$k_##1020]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       49;
+       51;
+       52;
+       53]
+  reft {VV##469 : a_azo | [$k_##470]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59; 301]
+  reft {VV##567 : a_azx | [$k_##568]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89]
+  reft {VV##901 : [a_azx] | [$k_##902]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38]
+  reft {VV##297 : a_azo | [$k_##298]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22]
+  reft {VV##174 : [a_azo] | [$k_##175]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       32;
+       33;
+       34]
+  reft {VV##258 : [a_azo] | [$k_##259]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112;
+       117;
+       277]
+  reft {VV##1152 : a_azJ | [$k_##1153]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89;
+       90;
+       284]
+  reft {VV##910 : a_azx | [$k_##911]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       282]
+  reft {VV##1079 : a_azJ | [$k_##1080]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57]
+  reft {VV##539 : a_azx | [$k_##540]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111]
+  reft {VV##1103 : a_azJ | [$k_##1104]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       315]
+  reft {VV##171 : a_azo | [$k_##172]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42;
+       43;
+       45;
+       46]
+  reft {VV##386 : a_azo | [$k_##387]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112;
+       117;
+       122]
+  reft {VV##1206 : a_azJ | [$k_##1207]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89;
+       285]
+  reft {VV##894 : a_azx | [$k_##895]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       67;
+       69;
+       295]
+  reft {VV##666 : a_azx | [$k_##667]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       103]
+  reft {VV##1016 : a_azJ | [$k_##1017]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 91; 92; 95; 96]
+  reft {VV##970 : a_azJ | [$k_##971]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85;
+       87;
+       89;
+       288]
+  reft {VV##886 : a_azx | [$k_##887]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 91; 92; 95]
+  reft {VV##967 : a_azJ | [$k_##968]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       289]
+  reft {VV##787 : a_azx | [$k_##788]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       32;
+       33;
+       313]
+  reft {VV##240 : a_azo | [$k_##241]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42;
+       43;
+       308]
+  reft {VV##317 : a_azo | [$k_##318]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       67;
+       69;
+       298]
+  reft {VV##658 : a_azx | [$k_##659]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       32;
+       33]
+  reft {VV##243 : [a_azo] | [$k_##244]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 58]
+  reft {VV##542 : a_azx | [$k_##543]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 62; 63; 64; 67; 69]
+  reft {VV##661 : [a_azx] | [$k_##662]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111;
+       112;
+       117;
+       278]
+  reft {VV##1156 : a_azJ | [$k_##1157]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42;
+       43;
+       45;
+       46;
+       47]
+  reft {VV##389 : a_azo | [$k_##390]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       108;
+       109;
+       110;
+       111]
+  reft {VV##1082 : [a_azJ] | [$k_##1083]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 57; 59; 60; 299]
+  reft {VV##579 : a_azx | [$k_##580]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       91;
+       92;
+       98;
+       99;
+       100;
+       103;
+       105;
+       106]
+  reft {VV##1039 : a_azJ | [$k_##1040]}
+  // META wf : ()
+
+
+wf:
+  env [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 54; 62; 63; 64; 67; 69]
+  reft {VV##673 : [a_azx] | [$k_##674]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       36;
+       37;
+       38;
+       39;
+       42;
+       43]
+  reft {VV##334 : a_azo | [$k_##335]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       72;
+       73;
+       74;
+       75;
+       80;
+       85]
+  reft {VV##840 : a_azx | [$k_##841]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       54;
+       62;
+       63;
+       64;
+       67;
+       69;
+       70;
+       294]
+  reft {VV##682 : a_azx | [$k_##683]}
+  // META wf : ()
+
+
+wf:
+  env [0;
+       1;
+       2;
+       3;
+       4;
+       5;
+       6;
+       7;
+       8;
+       9;
+       10;
+       11;
+       12;
+       13;
+       14;
+       19;
+       20;
+       21;
+       22;
+       27;
+       28;
+       29;
+       32;
+       33;
+       34;
+       310]
+  reft {VV##251 : a_azo | [$k_##252]}
+  // META wf : ()
+
+
+
+
+
+
+
diff --git a/liquid-fixpoint/tests/todo/baz.fq b/liquid-fixpoint/tests/todo/baz.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/todo/baz.fq
@@ -0,0 +1,22 @@
+// Uncommenting the WF renders the constraints "unsafe" but right now its SAFE
+// which is bad. We should fail with "missing WF" or somesuch.
+
+
+bind 0 x : {v: int | $k1 }
+
+constraint:
+  env []
+  lhs {v : int | [v = 6] }
+  rhs {v : int | $k1      }
+  id 0 tag []
+
+constraint:
+  env [0]
+  lhs {v : int | [v = x] }
+  rhs {v : int | v = 0   }
+  id 0 tag []
+
+// wf:
+//  env []
+//  reft {v: int | $k1 }
+
diff --git a/liquid-fixpoint/tests/todo/poly.fq b/liquid-fixpoint/tests/todo/poly.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/todo/poly.fq
@@ -0,0 +1,14 @@
+
+// This definition works fine ...
+// constant offset : (func(0, [int ; int ; (BitVec Size32) ]))
+
+// But this crashes as 'offset 0' is embedded as int not bv...
+constant offset : (func(1, [int; int; @(0)]))
+
+bind 0 x  : {VV : (BitVec  Size32) | [ VV = offset 0 0 ]}
+
+constraint:
+  env [0]
+  lhs {VV : (BitVec Size32) | [ VV = x ] }
+  rhs {VV : (BitVec Size32) | [ VV = x ] }
+  id 1 tag [1]
diff --git a/liquid-fixpoint/tests/todo/wl01.fq b/liquid-fixpoint/tests/todo/wl01.fq
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/tests/todo/wl01.fq
@@ -0,0 +1,39 @@
+qualif Nat(v:int) : (0 <= v)
+
+bind 0 x : {v: int | [$k0]}
+bind 1 y : {v: int | [$k0]}
+bind 2 z : {v: int | [$k1]}
+
+constraint:
+  env [ ]
+  lhs {v : int | [v = 10]}
+  rhs {v : int | [$k0]}
+  id 1 tag [0]
+
+constraint:
+  env [ 0 ]
+  lhs {v : int | [v = x + x]}
+  rhs {v : int | [$k0]}
+  id 2 tag [0]
+
+constraint:
+  env [ 0; 1 ]
+  lhs {v : int | [v = x + y ]}
+  rhs {v : int | [$k1]}
+  id 3 tag [0]
+
+
+constraint:
+  env [ 1 ]
+  lhs {v : int | [v =  z]}
+  rhs {v : int | [0 <= v]}
+  id 4 tag [0]
+
+wf:
+  env [ ]
+  reft {v: int | [$k0]}
+
+
+wf:
+  env [ ]
+  reft {v: int | [$k1]}
diff --git a/liquid-fixpoint/unix/Language/Fixpoint/Utils/Progress.hs b/liquid-fixpoint/unix/Language/Fixpoint/Utils/Progress.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/unix/Language/Fixpoint/Utils/Progress.hs
@@ -0,0 +1,55 @@
+-- | Progress Bar API
+module Language.Fixpoint.Utils.Progress (
+      withProgress
+    , progressInit
+    , progressTick
+    , progressClose
+    ) where
+
+import           Control.Monad                    (when)
+import           System.IO.Unsafe                 (unsafePerformIO)
+import           System.Console.CmdArgs.Verbosity (isNormal)
+import           Data.IORef
+
+
+import           System.Console.AsciiProgress
+
+{-# NOINLINE pbRef #-}
+pbRef :: IORef (Maybe ProgressBar)
+pbRef = unsafePerformIO (newIORef Nothing)
+
+withProgress :: Int -> IO a -> IO a
+withProgress n act = displayConsoleRegions $ do
+  -- putStrLn $ "withProgress: " ++ show n
+  progressInit n
+  r <- act
+  progressClose
+  return r
+
+progressInit :: Int -> IO ()
+progressInit n = do
+  normal <- isNormal 
+  when normal $ do
+    pr <- mkPB n
+    writeIORef pbRef (Just pr)
+
+mkPB   :: Int -> IO ProgressBar
+
+mkPB n = newProgressBar def { pgWidth       = 80
+                            , pgTotal       = toInteger n
+                            , pgFormat      = "Working :percent [:bar]"
+                            , pgPendingChar = '.'
+                            , pgOnCompletion = Just "Done solving." --  :percent."
+                            }
+
+progressTick :: IO ()
+progressTick    = go =<< readIORef pbRef
+  where
+   go (Just pr) = tick pr
+   go _         = return ()
+
+progressClose :: IO ()
+progressClose = go =<< readIORef pbRef
+  where
+    go (Just p) = complete p
+    go _        = return ()
diff --git a/liquid-fixpoint/win/Language/Fixpoint/Utils/Progress.hs b/liquid-fixpoint/win/Language/Fixpoint/Utils/Progress.hs
new file mode 100644
--- /dev/null
+++ b/liquid-fixpoint/win/Language/Fixpoint/Utils/Progress.hs
@@ -0,0 +1,19 @@
+-- | Progress Bar API
+module Language.Fixpoint.Utils.Progress (
+      withProgress
+    , progressInit
+    , progressTick
+    , progressClose
+    ) where
+
+withProgress :: Int -> IO a -> IO a
+withProgress _ x = x
+
+progressInit :: Int -> IO ()
+progressInit _ = return ()
+
+progressTick :: IO ()
+progressTick = return ()
+
+progressClose :: IO ()
+progressClose = return ()
diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal
--- a/liquidhaskell.cabal
+++ b/liquidhaskell.cabal
@@ -1,5 +1,5 @@
 Name:                liquidhaskell
-Version:             0.6.0.1
+Version:             0.7.0.0
 Copyright:           2010-15 Ranjit Jhala, University of California, San Diego.
 build-type:          Simple
 Synopsis:            Liquid Types for Haskell
@@ -14,11 +14,13 @@
 Cabal-version:       >=1.18
 
 
+
 data-files: include/*.hquals
           , include/*.hs
           , include/*.spec
           , include/CoreToLogic.lg
           , include/Control/*.spec
+          , include/Control/Parallel/*.spec
           , include/Data/*.hquals
           , include/Data/*.spec
           , include/Data/Text/*.spec
@@ -52,21 +54,21 @@
   Default:     False
   Manual:      True
 
--- Flag include
---   Description: use in-tree include directory
---   Default:     False
+Flag include
+  Description: use in-tree include directory
+  Default:     False
 
 Executable liquid
   default-language: Haskell98
   Build-Depends: base >= 4 && < 5
                , ghc
                , cmdargs
+               , time
                , deepseq
                , pretty
                , process
-               , liquid-fixpoint
+               , liquid-fixpoint >= 0.6
                , located-base
-               -- , prover
                , liquidhaskell
 
   Main-is: src/Liquid.hs
@@ -75,43 +77,51 @@
     ghc-options: -Werror
   Default-Extensions: PatternGuards
 
-Executable lhi
-  default-language: Haskell98
-  Build-Depends: base >= 4 && < 5
-               , ghc
-               , cmdargs
-               , deepseq
-               , pretty
-               , liquid-fixpoint
-               , located-base
-               -- , prover
-               , liquidhaskell
-               , network
-               , directory
-               , unix
-               , daemons
-               , bytestring
-               , data-default
-               , unordered-containers
-               , cereal
-               , process
-  Main-is: src/LHi.hs
-  ghc-options: -W -threaded
-  if flag(devel)
-    ghc-options: -Werror
-  Default-Extensions: PatternGuards
+-- Executable lhi
+--   default-language: Haskell98
+--   Build-Depends: base >= 4 && < 5
+--                , ghc
+--                , cmdargs
+--                , time
+--                , deepseq
+--                , pretty
+--                , liquid-fixpoint
+--                , located-base
+--                , liquidhaskell
+--                , network
+--                , directory
+--                , unix
+--                , daemons
+--                , bytestring
+--                , data-default
+--                , unordered-containers
+--                , cereal
+--                , process
+--   Main-is: src/LHi.hs
+--   ghc-options: -W -threaded
+--   if flag(devel)
+--     ghc-options: -Werror
+--   Default-Extensions: PatternGuards
 
+executable target
+  default-language: Haskell2010
+  main-is:        src/Target.hs
+  build-depends:  base,
+                  hint,
+                  liquidhaskell
+
 Library
    Default-Language: Haskell98
    Build-Depends: base >= 4 && < 5
                 , ghc >= 7.10.2 && < 7.11
+                , liquiddesugar >= 7.10 && < 7.11
                 , template-haskell >= 2.9
                 , time >= 1.4
                 , array >= 0.5
                 , hpc >= 0.6
                 , cmdargs >= 0.10
+                , time
                 , containers >= 0.5
-                , cpphs >= 1.19
                 , data-default >= 0.5
                 , deepseq >= 1.3
                 , directory >= 1.2
@@ -128,30 +138,41 @@
                 , vector >= 0.10
                 , hashable >= 1.2
                 , unordered-containers >= 0.2
-                , liquid-fixpoint >= 0.5 && < 0.6
+                , liquid-fixpoint >= 0.6
                 , located-base
-                -- , prover
-                , aeson >= 0.10
+                , aeson >= 0.10 && < 1.0 
                 , bytestring >= 0.10
                 , fingertree >= 0.1
                 , Cabal >= 1.18
                 , bifunctors >= 5.1
                 , cereal
+                , binary
                 , temporary >= 1.2
+                , transformers >= 0.3
+                , text-format
+                , th-lift
+                , exceptions >= 0.6
+                , QuickCheck >= 2.7
+                , ghc-prim
 
+
    hs-source-dirs:  src, include
 
-   Exposed-Modules: Language.Haskell.Liquid.Prelude,
+   Exposed-Modules: LiquidHaskell,
+
+                    Language.Haskell.Liquid.Prelude,
+                    Language.Haskell.Liquid.ProofCombinators,
                     Language.Haskell.Liquid.Foreign,
                     Language.Haskell.Liquid.List,
                     Language.Haskell.Liquid.Bare,
                     Language.Haskell.Liquid.Constraint.Constraint,
+                    Language.Haskell.Liquid.Constraint.Init,
                     Language.Haskell.Liquid.Constraint.Monad,
                     Language.Haskell.Liquid.Constraint.Env,
                     Language.Haskell.Liquid.Constraint.Types,
                     Language.Haskell.Liquid.Constraint.Split,
-                    Language.Haskell.Liquid.Constraint.Axioms,
-                    Language.Haskell.Liquid.Constraint.ProofToCore,
+                    -- Language.Haskell.Liquid.Constraint.Axioms,
+                    -- Language.Haskell.Liquid.Constraint.ProofToCore,
                     Language.Haskell.Liquid.Constraint.Generate,
                     Language.Haskell.Liquid.Constraint.ToFixpoint,
                     Language.Haskell.Liquid.Measure,
@@ -166,6 +187,8 @@
                     Language.Haskell.Liquid.Types.Meet,
                     Language.Haskell.Liquid.UX.ACSS,
                     Language.Haskell.Liquid.UX.DiffCheck,
+                    Language.Haskell.Liquid.UX.QuasiQuoter,
+                    Language.Haskell.Liquid.Transforms.Rewrite,
                     Language.Haskell.Liquid.Transforms.ANF,
                     Language.Haskell.Liquid.Transforms.RefSplit,
                     Language.Haskell.Liquid.Transforms.CoreToLogic,
@@ -178,6 +201,7 @@
                     Language.Haskell.Liquid.UX.CmdLine,
                     Language.Haskell.Liquid.GHC.Misc,
                     Language.Haskell.Liquid.GHC.Play,
+                    Language.Haskell.Liquid.GHC.Resugar,
                     Language.Haskell.Liquid.Misc,
                     Language.Haskell.Liquid.Types.Variance,
                     Language.Haskell.Liquid.Types.Bounds,
@@ -195,58 +219,43 @@
                     Paths_liquidhaskell,
 
                     -- FIXME: These shouldn't really be exposed, but the linker complains otherwise...
-                    Language.Haskell.Liquid.Bare.RefToLogic,
                     Language.Haskell.Liquid.Bare.Check,
                     Language.Haskell.Liquid.Bare.DataType,
                     Language.Haskell.Liquid.Bare.Env,
                     Language.Haskell.Liquid.Bare.Expand,
                     Language.Haskell.Liquid.Bare.Existential,
-                    Language.Haskell.Liquid.Bare.GhcSpec,
                     Language.Haskell.Liquid.Bare.Lookup,
                     Language.Haskell.Liquid.Bare.Axiom,
                     Language.Haskell.Liquid.Bare.Measure,
                     Language.Haskell.Liquid.Bare.Misc,
                     Language.Haskell.Liquid.Bare.OfType,
                     Language.Haskell.Liquid.Bare.Plugged,
+                    Language.Haskell.Liquid.Bare.ToBare, 
                     Language.Haskell.Liquid.Bare.Resolve,
                     Language.Haskell.Liquid.Bare.RTEnv,
                     Language.Haskell.Liquid.Bare.SymSort,
                     Language.Haskell.Liquid.Bare.Spec,
                     Language.Haskell.Liquid.Interactive.Types,
                     Language.Haskell.Liquid.Interactive.Handler,
+                    Language.Haskell.Liquid.Model,
 
-                    Language.Haskell.Liquid.Prover.Constants,
-                    Language.Haskell.Liquid.Prover.Misc,
-                    Language.Haskell.Liquid.Prover.Parser,
-                    Language.Haskell.Liquid.Prover.Pretty,
-                    Language.Haskell.Liquid.Prover.SMTInterface,
-                    Language.Haskell.Liquid.Prover.Solve,
-                    Language.Haskell.Liquid.Prover.Types,
-                    Language.Haskell.Liquid.Prover.Names,
+                    Test.Target,
+                    Test.Target.Eval,
+                    Test.Target.Expr,
+                    Test.Target.Monad,
+                    Test.Target.Serialize,
+                    Test.Target.Targetable,
+                    Test.Target.Targetable.Function,
+                    Test.Target.Testable,
+                    Test.Target.Types,
+                    Test.Target.Util
 
-                    -- NOTE: these need to be exposed so GHC generates .dyn_o files for them..
-                    Language.Haskell.Liquid.Desugar710.Check,
-                    Language.Haskell.Liquid.Desugar710.Coverage,
-                    Language.Haskell.Liquid.Desugar710.Desugar,
-                    Language.Haskell.Liquid.Desugar710.DsArrows,
-                    Language.Haskell.Liquid.Desugar710.DsBinds,
-                    Language.Haskell.Liquid.Desugar710.DsCCall,
-                    Language.Haskell.Liquid.Desugar710.DsExpr,
-                    Language.Haskell.Liquid.Desugar710.DsForeign,
-                    Language.Haskell.Liquid.Desugar710.DsGRHSs,
-                    Language.Haskell.Liquid.Desugar710.DsListComp,
-                    Language.Haskell.Liquid.Desugar710.DsMeta,
-                    Language.Haskell.Liquid.Desugar710.DsUtils,
-                    Language.Haskell.Liquid.Desugar710.HscMain,
-                    Language.Haskell.Liquid.Desugar710.Match,
-                    Language.Haskell.Liquid.Desugar710.MatchCon,
-                    Language.Haskell.Liquid.Desugar710.MatchLit
-   ghc-options: -W
---   if flag(include)
---     hs-source-dirs: devel
+   ghc-options: -W -fwarn-missing-signatures
+   if flag(include)
+     hs-source-dirs: devel
    if flag(devel)
      ghc-options: -Werror
-     ghc-prof-options: -fprof-auto
+   ghc-prof-options: -fprof-auto
    Default-Extensions: PatternGuards
 
 test-suite test
@@ -263,7 +272,7 @@
                ,     filepath >= 1.3
                ,     mtl >= 2.1
                ,     process >= 1.2
-               ,     optparse-applicative >= 0.11
+               ,     optparse-applicative >= 0.11 && <= 0.12.1.0
                ,     stm >= 2.4
                ,     tagged >= 0.7.3
                ,     tasty >= 0.10
@@ -271,3 +280,43 @@
                ,     tasty-hunit >= 0.9
                ,     tasty-rerun >= 1.1
                ,     transformers >= 0.3
+
+test-suite liquidhaskell-parser
+  default-language: Haskell2010
+  type: exitcode-stdio-1.0
+  hs-source-dirs: tests
+  ghc-options: -W
+  main-is: Parser.hs
+  build-depends:
+                     base  >= 4 && < 5
+               ,     containers >= 0.5
+               ,     parsec
+               ,     tasty >= 0.10
+               ,     tasty-ant-xml
+               ,     tasty-hunit >= 0.9
+               ,     tasty-rerun >= 1.1
+               ,     text
+               ,     transformers >= 0.3
+  if flag(devel)
+    hs-source-dirs:   tests src
+    build-depends:
+                  aeson >= 0.10 && < 1.0
+                , binary
+                , bytestring
+                , cereal
+                , cmdargs >= 0.10
+                , data-default >= 0.5
+                , deepseq
+                , directory >= 1.2
+                , filepath >= 1.3
+                , mtl >= 2.1
+                , ghc >= 7.10.2 && < 7.11
+                , hashable >= 1.2
+                , liquid-fixpoint >= 0.6
+                , liquiddesugar >= 7.10 && < 7.11
+                , pretty
+                , syb >= 0.4.4
+                , time
+                , unordered-containers >= 0.2
+  else
+    build-depends: liquidhaskell
diff --git a/resources/icon.png b/resources/icon.png
new file mode 100644
Binary files /dev/null and b/resources/icon.png differ
diff --git a/resources/icon.svg b/resources/icon.svg
new file mode 100644
--- /dev/null
+++ b/resources/icon.svg
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="29.703594mm"
+   height="39.899921mm"
+   viewBox="0 0 105.24896 141.37768"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="icon.svg"
+   inkscape:export-filename="C:\Users\mdsmt\Downloads\lh_revised2.png"
+   inkscape:export-xdpi="235.685"
+   inkscape:export-ydpi="235.685">
+  <defs
+     id="defs4">
+    <clipPath
+       id="clip1">
+      <path
+         inkscape:connector-curvature="0"
+         d="m 0,340.15625 481.89062,0 L 481.89062,0 0,0 0,340.15625 Z m 0,0"
+         id="path4220" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath7186">
+      <g
+         id="g7188">
+        <path
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 84.794583,521.06991 14.010237,0 23.34623,40.52476 -21.34623,40.52194 -16.010237,0 21.346227,-40.52194 z"
+           id="path7190"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccccc" />
+        <path
+           sodipodi:nodetypes="ccccccccc"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 102.14081,517.01175 8.01023,-10.84724 54.69249,95.9521 -16.01024,0 -13.33999,-25.32586 -13.34225,25.32586 -16.01024,0 21.34846,-40.52194 z"
+           id="path7192"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 139.94069,548.53025 38.40551,0 0,12.60994 -30.72442,0 -7.68109,-12.60994 z"
+           id="path7194"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 150.61272,567.44386 26.90505,0 0,12.60732 -19.78966,0 z"
+           id="path7196"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccc" />
+      </g>
+    </clipPath>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1"
+     inkscape:cx="420.32985"
+     inkscape:cy="245.30718"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     showguides="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1057"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     fit-margin-top="3"
+     fit-margin-left="3"
+     fit-margin-right="3"
+     fit-margin-bottom="3" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-81.531717,-469.11796)">
+    <path
+       style="fill:#0264c0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 59.990234,10.630859 C 54.173316,21.067707 46.657394,32.271636 39.59375,43.375 l 45.373047,79.60352 c 4.666674,-3.15931 8.700176,-7.21939 11.673828,-12.04493 l -13.078125,0 -7.115234,-12.607418 24.998044,0 c 0.26827,-1.521339 0.44649,-3.086134 0.52344,-4.69336 0.0194,-0.528607 0.008,-1.068833 -0.004,-1.609374 l -28.507809,0 -7.68164,-12.609376 33.716797,0 C 92.505251,58.605472 72.389306,32.877514 59.990234,10.630859 Z M 32.216797,55.351562 c -0.968127,1.637942 -1.900951,3.264431 -2.806641,4.88086 L 47.986328,92.478516 32.779297,121.34766 c 1.252735,0.97118 2.556275,1.87737 3.910156,2.70703 L 53.324219,92.478516 32.216797,55.351562 Z m -9.798828,18.980469 c -2.902037,6.972944 -4.61497,13.505235 -4.402344,19.300781 0.291245,6.082803 2.013151,11.557818 4.751953,16.326168 L 31.976562,92.478516 22.417969,74.332031 Z m 38.910156,33.341799 -11.492187,21.81445 c 3.341504,0.80593 6.75804,1.24152 10.154296,1.25977 4.194017,-0.0225 8.421216,-0.67523 12.496094,-1.88867 L 61.328125,107.67383 Z"
+       id="path6853"
+       transform="translate(74.164662,469.11702)"
+       inkscape:connector-curvature="0" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path7178"
+       d="m 134.15547,479.74694 c -15.42062,27.66803 -42.79313,60.73047 -41.975971,83.00381 1.085444,22.67002 21.923071,37.00723 41.975971,37.11498 20.05291,-0.10779 40.89193,-14.44496 41.97737,-37.11498 0.81718,-22.27334 -26.55672,-55.33578 -41.97737,-83.00381 z"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       clip-path="url(#clipPath7186)" />
+  </g>
+</svg>
diff --git a/resources/logo.png b/resources/logo.png
new file mode 100644
Binary files /dev/null and b/resources/logo.png differ
diff --git a/resources/logo.svg b/resources/logo.svg
new file mode 100644
--- /dev/null
+++ b/resources/logo.svg
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="186.13966mm"
+   height="42.912865mm"
+   viewBox="0 0 659.55 152.05346"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="lh_revised2.svg"
+   inkscape:export-filename="C:\Users\mdsmt\Downloads\lh_revised2.png"
+   inkscape:export-xdpi="235.685"
+   inkscape:export-ydpi="235.685">
+  <defs
+     id="defs4">
+    <clipPath
+       id="clip1">
+      <path
+         inkscape:connector-curvature="0"
+         d="m 0,340.15625 481.89062,0 L 481.89062,0 0,0 0,340.15625 Z m 0,0"
+         id="path4220" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath7186">
+      <g
+         id="g7188">
+        <path
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 84.794583,521.06991 14.010237,0 23.34623,40.52476 -21.34623,40.52194 -16.010237,0 21.346227,-40.52194 z"
+           id="path7190"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccccc" />
+        <path
+           sodipodi:nodetypes="ccccccccc"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 102.14081,517.01175 8.01023,-10.84724 54.69249,95.9521 -16.01024,0 -13.33999,-25.32586 -13.34225,25.32586 -16.01024,0 21.34846,-40.52194 z"
+           id="path7192"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 139.94069,548.53025 38.40551,0 0,12.60994 -30.72442,0 -7.68109,-12.60994 z"
+           id="path7194"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 150.61272,567.44386 26.90505,0 0,12.60732 -19.78966,0 z"
+           id="path7196"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccc" />
+      </g>
+    </clipPath>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.70710678"
+     inkscape:cx="512.42856"
+     inkscape:cy="361.49986"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     showguides="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1057"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     fit-margin-top="3"
+     fit-margin-left="3"
+     fit-margin-right="3"
+     fit-margin-bottom="3" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-81.531688,-469.11796)">
+    <g
+       transform="translate(-121.00001,52.939233)"
+       id="text4830"
+       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:90px;line-height:125%;font-family:'Titillium Web';-inkscape-font-specification:'Titillium Web, Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#00872a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1">
+      <path
+         style="fill:#00872a;fill-opacity:1"
+         inkscape:connector-curvature="0"
+         id="path4877"
+         d="m 593.64984,533.48008 0,-32.97577 -28.38668,0 0,32.97577 -15.48364,0 0,-79.51602 15.48364,0 0,32.50802 28.38668,0 0,-32.50802 15.48364,0 0,79.51602 -15.48364,0 z" />
+      <path
+         style="fill:#00872a;fill-opacity:1"
+         inkscape:connector-curvature="0"
+         id="path4879"
+         d="m 658.99691,493.25432 0,24.32254 q 0.2244,2.80646 0.8976,3.97581 0.6732,1.05241 2.80501,1.52016 l -0.4488,11.81046 q -5.72222,0 -9.20043,-0.81855 -3.36601,-0.81854 -6.84422,-3.27419 -8.07842,4.09274 -16.49344,4.09274 -17.39105,0 -17.39105,-19.17739 0,-9.35482 4.82461,-13.21368 4.82462,-3.97581 14.81044,-4.67741 l 12.00544,-0.9355 0,-3.62499 q 0,-3.62498 -1.57081,-4.91128 -1.5708,-1.40322 -5.04901,-1.40322 l -21.09366,0.93548 -0.4488,-10.87498 q 12.00543,-3.39114 22.77666,-3.39114 10.88343,0 15.59584,4.67743 4.82462,4.6774 4.82462,14.96771 z m -25.24507,15.43546 q -6.28322,0.58469 -6.28322,7.01612 0,6.43145 5.49782,6.43145 4.26361,0 9.31262,-1.40323 l 1.68301,-0.46774 0,-12.51208 -10.21023,0.93548 z" />
+      <path
+         style="fill:#00872a;fill-opacity:1"
+         inkscape:connector-curvature="0"
+         id="path4881"
+         d="m 709.08473,489.62934 q -13.91284,-1.87097 -19.52285,-1.87097 -5.49782,0 -7.18082,1.05241 -1.57081,1.05243 -1.57081,3.39113 0,2.22176 2.13181,3.15725 2.24401,0.81854 11.22003,2.57258 9.08822,1.63709 12.90303,5.49596 3.81482,3.85886 3.81482,12.51207 0,18.94352 -22.55227,18.94352 -7.40522,0 -17.95204,-2.10483 l -3.59041,-0.70161 0.4488,-13.09676 q 13.91283,1.87097 19.29845,1.87097 5.49781,0 7.40522,-1.05242 2.0196,-1.16935 2.0196,-3.39113 0,-2.22177 -2.1318,-3.27419 -2.01961,-1.05242 -10.77123,-2.57256 -8.63942,-1.52016 -12.90304,-5.14515 -4.26361,-3.62501 -4.26361,-12.86291 0,-9.35482 6.05882,-14.03222 6.05882,-4.79436 15.59584,-4.79436 6.61982,0 18.06425,2.22177 l 3.70261,0.70162 -0.2244,12.97983 z" />
+      <path
+         style="fill:#00872a;fill-opacity:1"
+         inkscape:connector-curvature="0"
+         id="path4883"
+         d="m 729.10293,533.48008 -15.03484,0 0,-81.85472 15.03484,0 0,46.54025 5.72222,-1.05242 11.10783,-22.10077 16.83005,0 -14.58604,27.71366 15.37144,30.754 -16.94225,0 -11.33223,-22.80239 -6.17102,1.05241 0,21.74998 z" />
+      <path
+         style="fill:#00872a;fill-opacity:1"
+         inkscape:connector-curvature="0"
+         id="path4885"
+         d="m 776.89691,510.91156 q 0.1122,5.37902 2.69281,7.83466 2.69281,2.33871 7.62962,2.33871 10.43463,0 18.62525,-0.70161 l 3.14161,-0.35081 0.2244,11.57659 q -12.90304,3.27419 -23.33767,3.27419 -12.67863,0 -18.40084,-7.01612 -5.72222,-7.01611 -5.72222,-22.80238 0,-31.45561 24.79627,-31.45561 24.45966,0 24.45966,26.42739 l -1.122,10.87499 -32.98689,0 z m 19.29845,-11.9274 q 0,-7.01612 -2.1318,-9.70564 -2.13181,-2.80644 -7.51742,-2.80644 -5.27342,0 -7.51742,2.92337 -2.13181,2.80646 -2.24401,9.58871 l 19.41065,0 z" />
+      <path
+         style="fill:#00872a;fill-opacity:1"
+         inkscape:connector-curvature="0"
+         id="path4887"
+         d="m 816.19394,533.48008 0,-81.85472 15.03484,0 0,81.85472 -15.03484,0 z" />
+      <path
+         style="fill:#00872a;fill-opacity:1"
+         inkscape:connector-curvature="0"
+         id="path4889"
+         d="m 836.4169,533.48008 0,-81.85472 15.03484,0 0,81.85472 -15.03484,0 z" />
+    </g>
+    <path
+       style="fill:#0264c0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 59.990234,10.630859 C 54.173316,21.067707 46.657394,32.271636 39.59375,43.375 l 45.373047,79.60352 c 4.666674,-3.15931 8.700176,-7.21939 11.673828,-12.04493 l -13.078125,0 -7.115234,-12.607418 24.998044,0 c 0.26827,-1.521339 0.44649,-3.086134 0.52344,-4.69336 0.0194,-0.528607 0.008,-1.068833 -0.004,-1.609374 l -28.507809,0 -7.68164,-12.609376 33.716797,0 C 92.505251,58.605472 72.389306,32.877514 59.990234,10.630859 Z M 32.216797,55.351562 c -0.968127,1.637942 -1.900951,3.264431 -2.806641,4.88086 L 47.986328,92.478516 32.779297,121.34766 c 1.252735,0.97118 2.556275,1.87737 3.910156,2.70703 L 53.324219,92.478516 32.216797,55.351562 Z m -9.798828,18.980469 c -2.902037,6.972944 -4.61497,13.505235 -4.402344,19.300781 0.291245,6.082803 2.013151,11.557818 4.751953,16.326168 L 31.976562,92.478516 22.417969,74.332031 Z m 38.910156,33.341799 -11.492187,21.81445 c 3.341504,0.80593 6.75804,1.24152 10.154296,1.25977 4.194017,-0.0225 8.421216,-0.67523 12.496094,-1.88867 L 61.328125,107.67383 Z"
+       id="path6853"
+       transform="translate(74.164662,469.11702)"
+       inkscape:connector-curvature="0" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path7178"
+       d="m 134.15547,479.74694 c -15.42062,27.66803 -42.79313,60.73047 -41.975971,83.00381 1.085444,22.67002 21.923071,37.00723 41.975971,37.11498 20.05291,-0.10779 40.89193,-14.44496 41.97737,-37.11498 0.81718,-22.27334 -26.55672,-55.33578 -41.97737,-83.00381 z"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.05262315px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       clip-path="url(#clipPath7186)" />
+    <g
+       transform="matrix(1.24667,0,0,1.24667,-75.199562,-49.505648)"
+       id="text4859"
+       style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:90px;line-height:125%;font-family:'Titillium Web';-inkscape-font-specification:'Titillium Web, Semi-Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#0264c0;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4864"
+         style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:90px;line-height:125%;font-family:'Titillium Web';-inkscape-font-specification:'Titillium Web, Semi-Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#0264c0;fill-opacity:1"
+         d="m 245.99829,510.09816 -34.56,0 0,-61.65 9.99,0 0,52.74 24.57,0 0,8.91 z" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path4866"
+         style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:90px;line-height:125%;font-family:'Titillium Web';-inkscape-font-specification:'Titillium Web, Semi-Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#0264c0;fill-opacity:1"
+         d="m 249.55594,510.09816 0,-45 9.81,0 0,45 -9.81,0 z m 0,-52.65 0,-10.35 9.81,0 0,10.35 -9.81,0 z" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path4868"
+         style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:90px;line-height:125%;font-family:'Titillium Web';-inkscape-font-specification:'Titillium Web, Semi-Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#0264c0;fill-opacity:1"
+         d="m 280.56359,511.08816 q -9.27,0 -13.5,-5.22 -4.14,-5.22 -4.14,-18.27 0,-13.14 4.86,-18.27 4.95,-5.22 17.01,-5.22 4.41,0 13.5,0.81 l 2.97,0.27 0,64.26 -9.72,0 0,-21.06 q -6.03,2.7 -10.98,2.7 z m 4.23,-38.52 q -7.11,0 -9.63,3.6 -2.43,3.51 -2.43,11.52 0,8.01 2.16,11.34 2.25,3.33 6.84,3.33 4.23,0 8.46,-1.35 l 1.35,-0.45 0,-27.63 q -4.32,-0.36 -6.75,-0.36 z" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path4870"
+         style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:90px;line-height:125%;font-family:'Titillium Web';-inkscape-font-specification:'Titillium Web, Semi-Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#0264c0;fill-opacity:1"
+         d="m 332.54123,465.09816 9.72,0 0,45 -9.72,0 0,-2.79 q -6.57,3.78 -12.15,3.78 -9.27,0 -12.42,-4.95 -3.15,-5.04 -3.15,-17.55 l 0,-23.49 9.81,0 0,23.58 q 0,8.1 1.35,10.89 1.35,2.79 6.3,2.79 4.86,0 8.91,-1.8 l 1.35,-0.54 0,-34.92 z" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path4872"
+         style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:90px;line-height:125%;font-family:'Titillium Web';-inkscape-font-specification:'Titillium Web, Semi-Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#0264c0;fill-opacity:1"
+         d="m 345.81888,510.09816 0,-45 9.81,0 0,45 -9.81,0 z m 0,-52.65 0,-10.35 9.81,0 0,10.35 -9.81,0 z" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path4874"
+         style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:90px;line-height:125%;font-family:'Titillium Web';-inkscape-font-specification:'Titillium Web, Semi-Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#0264c0;fill-opacity:1"
+         d="m 397.97652,446.37816 0,63.72 -9.72,0 0,-2.34 q -6.57,3.33 -12.06,3.33 -8.82,0 -12.96,-5.31 -4.05,-5.31 -4.05,-17.82 0,-12.51 4.5,-18.18 4.59,-5.67 14.22,-5.67 3.24,0 10.26,1.17 l 0,-18.9 9.81,0 z m -11.34,54.36 1.53,-0.63 0,-26.64 q -5.4,-0.9 -9.99,-0.9 -9.09,0 -9.09,15.12 0,8.28 2.07,11.52 2.16,3.15 6.75,3.15 4.59,0 8.73,-1.62 z" />
+    </g>
+  </g>
+</svg>
diff --git a/scripts/CountBinders.hs b/scripts/CountBinders.hs
new file mode 100644
--- /dev/null
+++ b/scripts/CountBinders.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+module Main where
+
+
+import           Control.Applicative
+import           Data.Function
+import           Data.Generics
+import           Data.List
+import           System.Environment
+import           Text.Printf
+
+import           CoreMonad
+import           CoreSyn
+import           DynFlags
+import           GHC
+import           GHC.Paths
+import           HscTypes
+import qualified Outputable as Out
+import           Type
+import           Var
+
+import           Language.Haskell.Liquid.GhcMisc
+import           Language.Haskell.Liquid.Misc
+
+getCoreBinds :: FilePath -> IO [CoreBind]
+getCoreBinds target = runGhc (Just libdir) $ do
+  addTarget =<< guessTarget target Nothing
+  flags <- getSessionDynFlags
+  inc <- liftIO getIncludeDir
+  setSessionDynFlags $ updateDynFlags flags [inc]
+  load LoadAllTargets
+  modGraph <- getModuleGraph
+  case find ((== target) . msHsFilePath) modGraph of
+    Just modSummary -> do
+      mod_guts <- coreModule <$> (desugarModule =<< typecheckModule =<< parseModule modSummary)
+      return   $! mg_binds mod_guts
+    Nothing     -> error "Ghc Interface: Unable to get GhcModGuts"
+
+
+updateDynFlags :: DynFlags -> [FilePath] -> DynFlags
+updateDynFlags df ps
+  = df { importPaths  = ps ++ importPaths df
+       , libraryPaths = ps ++ libraryPaths df
+       , profAuto     = ProfAutoCalls
+       , ghcLink      = NoLink
+       , hscTarget    = HscInterpreted
+       , ghcMode      = CompManager
+       } `xopt_set` Opt_MagicHash
+         `dopt_set` Opt_ImplicitImportQualified
+
+
+allBinders :: [CoreBind] -> [CoreBind]
+allBinders cbs = cbs ++ map bind (concatMap (listify isBinder) cbs)
+  where
+    bind (Let x _)     = x
+    isBinder (Let _ _) = True
+    isBinder _         = False
+
+
+recsAndFuns :: [CoreBind] -> ([Var],[Var],[Var])
+recsAndFuns binds = (recs,recfuns,funs)
+  where
+    recs    = [v | Rec bs <- binds, (v,_)  <- bs]
+    recfuns = filter isFun recs
+    -- GHC does transforms recursive functions (at least with tyvars)
+    -- into a let binding that quantifies over the tyvar followed by a
+    -- letrec that defines the function, e.g.
+    --     let foo = \ @a -> { letrec foo = ... in foo }
+    -- but we don't want to count foo as rec and nonrec
+    funs    = nubBy ((==) `on` getOccName)
+            $ [v | NonRec v _ <- binds, isFun v]
+           ++ recfuns
+    isFun   = isFunTy . snd . splitForAllTys . varType
+
+
+main :: IO ()
+main = do
+  target <- head <$> getArgs
+  binds  <- allBinders <$> getCoreBinds target
+
+  let (recs,recfuns,funs) = recsAndFuns binds
+
+  printf "funs:     %d\n" (length funs)
+  printf "recs:     %d\n" (length recs)
+  printf "recsFuns: %d\n" (length recfuns)
+
+
+instance Show CoreBind where
+  show = showPpr
+
+instance Show (Expr CoreBndr) where
+  show = showPpr
diff --git a/scripts/haskell_count b/scripts/haskell_count
new file mode 100644
--- /dev/null
+++ b/scripts/haskell_count
@@ -0,0 +1,122 @@
+#!/usr/bin/perl -w
+# haskell_count - count physical lines of code
+# Strips out {- .. -} and -- comments and counts the rest.
+# Pragmas, {-#...}, are counted as SLOC.
+# BUG: Doesn't handle strings with embedded block comment markers gracefully.
+#      In practice, that shouldn't be a problem.
+# Usage: haskell_count [-f file] [list_of_files]
+#  file: file with a list of files to count (if "-", read list from stdin)
+#  list_of_files: list of files to count
+#  -f file or list_of_files can be used, or both
+
+# This is part of SLOCCount, a toolsuite that counts
+# source lines of code (SLOC).
+# Copyright (C) 2001-2004 David A. Wheeler.
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# 
+# To contact David A. Wheeler, see his website at:
+#  http://www.dwheeler.com.
+# 
+
+
+
+
+
+$total_sloc = 0;
+
+# Do we have "-f" (read list of files from second argument)?
+if (($#ARGV >= 1) && ($ARGV[0] eq "-f")) {
+  # Yes, we have -f
+  if ($ARGV[1] eq "-") {
+    # The list of files is in STDIN
+    while (<STDIN>) {
+      chomp ($_);
+      &count_file ($_);
+    }
+  } else {
+    # The list of files is in the file $ARGV[1]
+    open (FILEWITHLIST, $ARGV[1]) || die "Error: Could not open $ARGV[1]\n";
+    while (<FILEWITHLIST>) {
+      chomp ($_);
+      &count_file ($_);
+    }
+    close FILEWITHLIST;
+  }
+  shift @ARGV; shift @ARGV;
+}
+# Process all (remaining) arguments as file names
+while ($file = shift @ARGV) {
+  &count_file ($file);
+}
+
+print "Total:\n";
+print "$total_sloc\n";
+
+sub determine_lit_type {
+  my ($file) = @_;
+
+  open (FILE, $file);
+  while (<FILE>) {
+    if (m/^\\begin{code}/) { close FILE; return 2; }
+    if (m/^>\s/) { close FILE; return 1; }
+  }
+
+  return 0;
+}
+
+sub count_file {
+  my ($file) = @_;
+  my $sloc = 0;
+  my $incomment = 0;
+  my ($literate, $inlitblock) = (0,0);
+
+  $literate = 1 if $file =~ /\.lhs$/;
+  if($literate) { $literate = determine_lit_type($file) }
+
+  open (FILE, $file);
+  while (<FILE>) {
+    if ($literate == 1) {
+      if (!s/^>//) { s/.*//; }
+    } elsif ($literate == 2) {
+      if ($inlitblock) {
+        if (m/^\\end{code}/) { s/.*//; $inlitblock = 0; }
+      } elsif (!$inlitblock) {
+        if (m/^\\begin{code}/) { s/.*//; $inlitblock = 1; }
+        else { s/.*//; }
+      }
+    }
+
+    if ($incomment) {
+      if (m/\-\}/) { s/^.*?\-\}//;  $incomment = 0;}
+      else { s/.*//; }
+    }
+    if (!$incomment) {
+      s!{-[^#].*?-}!!g;
+      s/--.*//;
+      if (m/{-/ && (!m/{-#/)) {
+        s/{-.*//;
+	$incomment = 1;
+      }
+    }
+    if (m/\S/) {$sloc++;}
+  }
+  print "$sloc $file\n";
+  if ($incomment) {print "ERROR: ended in comment in $ARGV\n";}
+  $total_sloc += $sloc;
+  $sloc = 0;
+  $incomment = 0;
+  close (FILE);
+}
diff --git a/scripts/metrics.py b/scripts/metrics.py
new file mode 100644
--- /dev/null
+++ b/scripts/metrics.py
@@ -0,0 +1,200 @@
+#!/usr/bin/python
+
+from collections import defaultdict
+from datetime import datetime
+import os
+import re
+import string
+import subprocess
+import sys
+
+benchmarks = {
+    'benchmarks/text-0.11.2.3': [ 'Data/Text.hs'
+                                , 'Data/Text/Array.hs'
+                                , 'Data/Text/Encoding.hs'
+                                , 'Data/Text/Foreign.hs'
+                                , 'Data/Text/Fusion.hs'
+                                , 'Data/Text/Fusion/Size.hs'
+                                , 'Data/Text/Internal.hs'
+                                , 'Data/Text/Lazy.hs'
+                                , 'Data/Text/Lazy/Builder.hs'
+                                , 'Data/Text/Lazy/Encoding.hs'
+                                , 'Data/Text/Lazy/Fusion.hs'
+                                , 'Data/Text/Lazy/Internal.hs'
+                                , 'Data/Text/Lazy/Search.hs'
+                                , 'Data/Text/Private.hs'
+                                , 'Data/Text/Search.hs'
+                                , 'Data/Text/Unsafe.hs'
+                                , 'Data/Text/UnsafeChar.hs' ],
+
+    'benchmarks/bytestring-0.9.2.1': [ 'Data/ByteString.T.hs'
+                                     , 'Data/ByteString/Char8.hs'
+                                     , 'Data/ByteString/Fusion.T.hs'
+                                     , 'Data/ByteString/Internal.hs'
+                                     , 'Data/ByteString/Lazy.hs'
+                                     # , 'Data/ByteString/LazyZip.hs'
+                                     , 'Data/ByteString/Lazy/Char8.hs'
+                                     , 'Data/ByteString/Lazy/Internal.hs'
+                                     , 'Data/ByteString/Unsafe.hs' ],
+
+    'benchmarks/vector-algorithms-0.5.4.2': [ 'Data/Vector/Algorithms/AmericanFlag.hs'
+                                            , 'Data/Vector/Algorithms/Combinators.hs'
+                                            , 'Data/Vector/Algorithms/Common.hs'
+                                            , 'Data/Vector/Algorithms/Heap.hs'
+                                            , 'Data/Vector/Algorithms/Insertion.hs'
+                                            , 'Data/Vector/Algorithms/Intro.hs'
+                                            , 'Data/Vector/Algorithms/Merge.hs'
+                                            , 'Data/Vector/Algorithms/Optimal.hs'
+                                            , 'Data/Vector/Algorithms/Radix.hs'
+                                            , 'Data/Vector/Algorithms/Search.hs' ],
+
+    'benchmarks/esop2013-submission': [ 'Base.hs', 'Splay.hs' ],
+
+    'benchmarks/hscolour-1.20.0.0': [ 'Language/Haskell/HsColour.hs'
+                                    , 'Language/Haskell/HsColour/ACSS.hs'
+                                    , 'Language/Haskell/HsColour/Anchors.hs'
+                                    , 'Language/Haskell/HsColour/ANSI.hs'
+                                    , 'Language/Haskell/HsColour/Classify.hs'
+                                    , 'Language/Haskell/HsColour/ColourHighlight.hs'
+                                    , 'Language/Haskell/HsColour/Colourise.hs'
+                                    , 'Language/Haskell/HsColour/CSS.hs'
+                                    , 'Language/Haskell/HsColour/General.hs'
+                                    , 'Language/Haskell/HsColour/HTML.hs'
+                                    , 'Language/Haskell/HsColour/InlineCSS.hs'
+                                    , 'Language/Haskell/HsColour/LaTeX.hs'
+                                    , 'Language/Haskell/HsColour/MIRC.hs'
+                                    , 'Language/Haskell/HsColour/Options.hs'
+                                    , 'Language/Haskell/HsColour/Output.hs'
+                                    , 'Language/Haskell/HsColour/TTY.hs' ],
+
+    'benchmarks/xmonad': [ 'XMonad/StackSet.hs' ],
+
+    'include': [ 'GHC/List.lhs' ],
+
+    '.': [ 'benchmarks/base-4.5.1.0/Data/List.hs' ]
+}
+
+def time(fn):
+    start = datetime.now()
+    with open(fn+'.log', 'w') as out:
+        subprocess.call(['liquid', '--smtsolver', 'z3mem', fn], stdout=out, stderr=out)
+    return (datetime.now() - start).total_seconds()
+
+def errors(fn):
+    with open(fn+'.log') as fd:
+        log = fd.readlines()
+    unsafes = [l for l in log if l.startswith('**** UNSAFE:')]
+    return unsafes
+
+def sloc(scripts,fn):
+    return int(subprocess.check_output(
+        '%s/haskell_count %s | tail -n1' % (scripts, fn), shell=True))
+
+def lines(anns):
+    return sum(map(lambda x:(1+x.count('\n')), anns))
+
+def recs(fn):
+    out = subprocess.check_output('liquid-count-binders %s 2>/dev/null' % fn, shell=True)
+    return [int(n) for n in re.findall('(\d+)', out)]
+
+def find(rx, str):
+    return [(str[a.start():(3+string.find(str,"@-}", a.start()))])
+            for a in list(re.finditer(rx, str))]
+
+qualif_re = '{-@ qualif'
+other = 'import|include|invariant|embed|Decrease|LAZYVAR|Strict|Lazy'
+other_re = '{-@ (%s)' % other
+spec_re = '{-@ (?!(%s|qualif|LIQUID))' % other
+dec_re = '{-@ Decrease'
+div_re = '{-@ (Strict|Lazy)'
+wit_re = '{- LIQUID WITNESS'
+mod_re = '^module ([\w\.]+)'
+
+def combine(x, y):
+    return {k:x[k] + y[k] for k in y.keys()}
+
+def texify(fn, metrics):
+    return '\\texttt{%s} & %d & %d / %d & %d / %d & %d / %d & %d & %d & %d & %d & %d \\\\\n' % (
+        fn, metrics['sloc'], metrics['specs'], metrics['specs_lines'],
+        metrics['others'], metrics['others_lines'],
+        metrics['qualifs'], metrics['qualifs_lines'],
+        metrics['funs'], metrics['recfuns'], metrics['divs'],
+        metrics['hints'], metrics['time'])
+
+def texify_term(fn, metrics):
+    return '\\texttt{%s} & %d & %d & %d & %d & %d & %d & %d \\\\\n' % (
+        fn, metrics['sloc'], metrics['errs'],
+        metrics['funs'], metrics['recfuns'], metrics['divs'],
+        metrics['hints'], metrics['time'])
+
+def main():
+    if len(sys.argv) >= 2 and sys.argv[1] == '--only-term':
+        print 'ONLY COLLECTING TERMINATION DATA!'
+        colformat = '|l|rr|rrrr|r|'
+        headers = ['Module', 'LOC', 'Err', 'Fun', 'Rec', 'Div', 'Hint', 'Time']
+        pptex = texify_term
+    else:
+        colformat = '|l|rrrr|rrrr|r|'
+        headers = ['Module', 'LOC', 'Specs', 'Annot', 'Qualif',
+                   'Fun', 'Rec', 'Div', 'Hint', 'Time']
+        pptex = texify
+    results = {}
+    pwd = os.getcwd()
+    for d, fs in benchmarks.iteritems():
+        os.chdir(d)
+        results[d] = {}
+        for fn in fs:
+            print fn
+            f_res = {}
+            f_res['time'] = time(fn)
+            f_res['sloc'] = sloc(os.path.join(pwd,'scripts'),fn)
+            [fs,rs,rfs] = recs(fn)
+            f_res['funs'] = fs
+            f_res['recs'] = rs
+            f_res['recfuns'] = rfs
+
+            errs = set(errors(fn))
+            import pprint
+            pprint.pprint(errs)
+            f_res['errs'] = len(errs)
+
+            str = (open(fn, 'r')).read()
+            mod = re.search(mod_re, str, re.M).group(1)
+
+            specs = find(spec_re, str)
+            f_res['specs'] = len(specs)
+            f_res['specs_lines'] = lines(specs)
+
+            qualifs = find(qualif_re, str)
+            f_res['qualifs'] = len(qualifs)
+            f_res['qualifs_lines'] = lines(qualifs)
+
+            others = find(other_re, str)
+            f_res['others'] = len(others)
+            f_res['others_lines'] = lines(others)
+
+            f_res['divs'] = len(re.findall(div_re, str))
+            f_res['hints'] = len(re.findall(wit_re, str)) + len(re.findall(dec_re, str))
+            results[d][mod] = f_res
+
+        os.chdir(pwd)
+
+    with open('metrics.tex', 'w') as out:
+        out.write('\\begin{tabular}{%s}\n' % colformat)
+        out.write('\\hline\n')
+        out.write(' & '.join('\\textbf{%s}' % h for h in headers) + '\\\\\n')
+        out.write('\\hline\\hline\n')
+        totals = defaultdict(int)
+        for d, fs in results.iteritems():
+            dirtotals = defaultdict(int)
+            for fn, metrics in sorted(fs.iteritems()):
+                out.write(pptex(fn, metrics))
+                dirtotals = combine(dirtotals, metrics)
+            out.write(pptex(d, dirtotals))
+            out.write('\\hline\n\n')
+            totals = combine(totals, dirtotals)
+        out.write(pptex('Total', totals))
+        out.write('\\hline\n\\end{tabular}\n')
+
+if __name__ == '__main__':
+    main()
diff --git a/scripts/performance/cleanup.bash b/scripts/performance/cleanup.bash
new file mode 100644
--- /dev/null
+++ b/scripts/performance/cleanup.bash
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+SCRIPT_DIR=`dirname $0`;
+SCRIPT_LOGS="$SCRIPT_DIR/logs";
+FAILURES_OCCURRED=false;
+
+function notify_if_failed {
+    local EXIT_CODE=$?;
+    if [ $EXIT_CODE != 0 ]
+    then
+        echo $1;
+        echo "Exit code was: $EXIT_CODE";
+        $FAILURES_OCCURRED=true;
+    fi
+}
+
+echo "Deleting $SCRIPT_LOGS...";
+rm -rf $SCRIPT_LOGS;
+notify_if_failed "Failed to delete $SCRIPT_LOGS...";
+
+if [ $FAILURES_OCCURRED = true ]
+then
+    echo "Cleanup failures occurred, please investigate...";
+else
+    echo "Cleanup completed successfully!";
+fi
diff --git a/scripts/performance/generate.bash b/scripts/performance/generate.bash
new file mode 100644
--- /dev/null
+++ b/scripts/performance/generate.bash
@@ -0,0 +1,248 @@
+#!/bin/bash
+
+GIT=`which git`;
+MAKE=`which make`;
+CABAL=`which cabal`;
+ALL_FOUND=true;
+
+SCRIPT_DIR=`dirname $0`;
+
+SCRIPT_LOGS="$SCRIPT_DIR/logs";
+SCRIPT_REPO="$SCRIPT_LOGS/repository";
+SCRIPT_FIXPOINT="$SCRIPT_REPO/liquid-fixpoint";
+REPO_TEST="$SCRIPT_REPO/dist/build/test/test";
+REPO_TEST_ARGS=" --timeout 10m";
+REPO_LOG="$SCRIPT_REPO/tests/logs/cur/summary.csv";
+
+ALL_GIT_TAGS="$GIT show-ref --tags | grep liquidhaskell | cut -c -40";
+ALL_GIT_HASHES="$GIT log --format=%H";
+
+START=0;
+END=0;
+FORCE=false;
+MAX_LOGS=-1;
+DONE_LOGS=0;
+
+START_FOUND=false;
+END_FOUND=false;
+
+function refresh_repo {
+    cd $SCRIPT_REPO;
+    abort_if_failed "Couldn't change to $SCRIPT_REPO...";
+
+    $GIT pull origin master;
+
+    if [ $END != 0 ]
+    then
+        $GIT checkout master;
+        $GIT submodule update;
+    fi
+
+    abort_if_failed "Couldn't pull Liquid Haskell from remote...";
+
+    $GIT reset;
+    abort_if_failed "Couldn't reset the the liquid-haskell repository...";
+
+    $GIT checkout .;
+    abort_if_failed "Couldn't discard changes to liquid-haskell...";
+
+    $GIT submodule foreach 'git reset ; git checkout . ;';
+    abort_if_failed "Couldn't reset and discard changes to submodules...";
+}
+
+function generate_log {
+    local HASH=$1;
+    local RESULT=$SCRIPT_LOGS/$HASH.csv;
+    local SHOULD_GEN=true;
+
+    if [ -e $RESULT ]
+    then
+        if [ $FORCE = false ]
+        then
+            SHOULD_GEN=false;
+        fi
+    fi
+
+    if [ $SHOULD_GEN = true ]
+    then
+        DONE_LOGS=`expr $DONE_LOGS + 1`
+        $GIT checkout $HASH;
+        $GIT submodule update;
+        $MAKE clean;
+        if [ $? != 0 ]
+        then
+            return 1;
+        fi
+
+        rm -rf .cabal-sandbox;
+        rm cabal.sandbox.config;
+
+        $CABAL sandbox init;
+        if [ $? != 0 ]
+        then
+            return 1;
+        fi
+
+        $CABAL sandbox add-source $SCRIPT_FIXPOINT;
+
+        $CABAL install --enable-tests;
+        if [ $? != 0 ]
+        then
+            return 1;
+        fi
+
+        $CABAL configure --enable-tests --disable-library-profiling -O2;
+        if [ $? != 0 ]
+        then
+            return 1;
+        fi
+
+        $CABAL build;
+        if [ $? != 0 ]
+        then
+            return 1;
+        fi
+
+        $CABAL exec $REPO_TEST -- $REPO_TEST_ARGS;
+        # Not testing for failure; failed tests shouldn't prevent the site from
+        # being generated.
+
+        cp $REPO_LOG $RESULT
+        if [ $? != 0 ]
+        then
+            return 1;
+        fi
+    fi
+
+    return 0;
+}
+
+function abort_if_failed {
+    local EXIT_CODE=$?;
+    if [ $EXIT_CODE != 0 ]
+    then
+        echo $1;
+        exit $EXIT_CODE;
+    fi
+}
+
+function usage {
+    echo "$0 -s [START HASH] -e [END HASH] -f -n [MAX LOGS TO GENERATE]"
+    echo "   -s - hash to start generating logs at";
+    echo "   -e - hash to end generating logs at";
+    echo "   -f - If passed, will force re-creation of all logs. This will take an extremely long time!";
+    echo "   -n - Only generate n logs (useful for cron jobs and such)"
+    exit 1;
+}
+
+# Get options
+
+while getopts ":s:e:n:f" OPT; do
+    case $OPT in
+        s)
+            START=$OPTARG;;
+        e)
+            END=$OPTARG;;
+        f)
+            FORCE=true;;
+        n)
+            MAX_LOGS=$OPTARG;;
+        *)
+            usage;;
+    esac
+done
+
+# Check dependencies
+
+if [ $GIT = "" ]
+then
+    echo "Git not found...";
+    ALL_FOUND=false;
+fi
+
+if [ $MAKE = "" ]
+then
+    echo "Make not found...";
+    ALL_FOUND=false;
+fi
+
+if [ $CABAL = "" ]
+then
+    echo "Cabal not found...";
+    ALL_FOUND=false;
+else
+    cabal sandbox --help &> /dev/null;
+    if [ $? != 0 ]
+    then
+        echo "Cabal sandboxes not supported...";
+        CABAL_VER=`cabal --numeric-version`;
+        echo "Found Cabal version: $CABAL_VER, need 1.18 or greater..."
+        ALL_FOUND=false;
+    fi
+fi
+
+if [ $ALL_FOUND = true ]
+then
+    echo "All dependencies met...";
+else
+    echo "Some dependencies are unmet...";
+    exit 1;
+fi
+
+$CABAL update;
+abort_if_failed "Couldn't perform cabal update...";
+
+# generate logs
+
+if [ ! -e $SCRIPT_LOGS ]
+then
+    mkdir $SCRIPT_LOGS;
+    abort_if_failed "$SCRIPT_LOGS doesn't exist and couldn't be created...";
+fi
+
+# Refresh the repo prior to working
+refresh_repo;
+
+if [ $END = 0 ]
+then
+    END_FOUND=true;
+fi
+
+for CURR in `$ALL_GIT_HASHES`
+do
+    if [ $START_FOUND = false ]
+    then
+        if [ $END_FOUND = false ]
+        then
+            if [ $CURR = $END ]
+            then
+                END_FOUND=true;
+            fi
+        fi
+
+        if [ $END_FOUND = true ]
+        then
+            echo "Processing: $CURR";
+            generate_log $CURR;
+        fi
+
+        if [ ! $? = 0 ]
+        then
+            echo "Log generation for $CURR failed...";
+        fi
+
+        if [ $CURR = $START ]
+        then
+            START_FOUND=true;
+        fi
+
+        if [ $MAX_LOGS = $DONE_LOGS  ]
+        then
+            START_FOUND=true;
+        fi
+
+        rm -rf /tmp/ghc*;
+        rm -rf /tmp/cabal*;
+    fi
+
+done
diff --git a/scripts/performance/initialize.bash b/scripts/performance/initialize.bash
new file mode 100644
--- /dev/null
+++ b/scripts/performance/initialize.bash
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+GIT=`which git`;
+CABAL=`which cabal`;
+GHC=`which ghc`;
+ALL_FOUND=true;
+
+SCRIPT_DIR=`dirname $0`;
+SCRIPT_LOGS="$SCRIPT_DIR/logs";
+SCRIPT_REPO="$SCRIPT_LOGS/repository";
+
+LIQUID_URL="https://github.com/ucsd-progsys/liquidhaskell.git";
+
+function abort_if_failed {
+    local EXIT_CODE=$?;
+    if [ $EXIT_CODE != 0 ]
+    then
+        echo $1;
+        exit $EXIT_CODE;
+    fi
+}
+
+# Check dependencies
+
+if [ $GIT = "" ]
+then
+    echo "Git not found...";
+    ALL_FOUND=false;
+fi
+
+if [ $CABAL = "" ]
+then
+    echo "Cabal not found...";
+    ALL_FOUND=false;
+else
+    cabal sandbox --help &> /dev/null;
+    if [ $? != 0 ]
+    then
+        echo "Cabal sandboxes not supported...";
+        CABAL_VER=`cabal --numeric-version`;
+        echo "Found Cabal version: $CABAL_VER, need 1.18 or greater..."
+        ALL_FOUND=false;
+    fi
+fi
+
+if [ $GHC = "" ]
+then
+    echo "GHC not found...";
+    ALL_FOUND=false;
+fi
+
+if [ $ALL_FOUND = true ]
+then
+    echo "All dependencies met...";
+else
+    echo "Some dependencies are unmet...";
+    exit 1;
+fi
+
+if [ -e $SCRIPT_LOGS ]
+then
+    echo "$SCRIPT_LOGS already exists, aborting..."
+    exit 1;
+fi
+
+# clone repos
+
+$GIT clone $LIQUID_URL $SCRIPT_REPO
+abort_if_failed "Unable to clone Liquid Haskell...";
+
+cd $SCRIPT_REPO;
+abort_if_failed "Unable to change to $SCRIPT_REPO...";
+
+$GIT submodule update --init;
+abort_if_failed "Unable to initialize the git submodules...";
+
+echo "Initialization completed successfully!";
diff --git a/scripts/plot-benchmarks/README.md b/scripts/plot-benchmarks/README.md
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/README.md
@@ -0,0 +1,51 @@
+Plot-Benchmarks
+===============
+
+Overview
+--------
+
+Plot-Benchmarks is a tool designed to ingest a directory full of LiquidHaskell test suite logs and generate graphs of performance data over time.
+
+Usage
+-----
+
+```
+  -l --logdir=ITEM            The directory that contains the logs
+  -o --outputdir=ITEM         The diretory to output graphs to
+     --plotcompare=ITEM,ITEM  Pairs of benchmarks to compare
+     --plot=ITEM              Benchmarks to plot
+  -? --help                   Display help message
+  -V --version                Print version information
+     --numeric-version        Print just the version number
+```
+
+* `logdir`: The directory that contains log files to be considered. Defaults to the current directory (`./`).
+
+* `outputdir`: The directory to write resulting graphs to. Defaults to the current directory (`./`).
+
+* `plot`: A benchmark to plot. This is drawn from the first column of the LiquidHaskell log file and takes the form of `/intermediate/suite/container/TestFile.hs`. For each benchmark, one .svg file will be produced in the output directory.
+
+* `plotcompare`: Two benchmarks to plot against each other. This is drawn from the first column of the LiquidHaskell log file and takes the form of `/intermediate/suite/container/TestFileLHS.hs,/some/other/suite/TestFileRHS.hs`. For each pair of benchmarks, one .svg file will be produced in the output directory.
+
+Prerequisites
+-------------
+
+This program relies on a special header being present in the test suite output. This header is implemented in the master branch as of commit `29d72f62fd7f2d90574ad0d587185101ad960b23`. For any log file created prior to this commit, the following header can be prepended to the log file:
+
+```
+Epoch Timestamp: 1454554725
+--------------------------------------------------------------------------------
+```
+
+This timestamp is required for plot-benchmarks to properly order each log. This time should be the *commiter* date of the git commit. An appropriate timestamp will be produced by git using the following command: `git show --format="%ct" --quiet`
+
+Examples
+--------
+
+* `plot-benchmarks --plot Tests/Unit/pos/PointDist.hs --plotcompare Tests/Unit/pos/vector0.hs,Tests/Unit/neg/vector0.hs`
+
+This will produce two .svg files in the current directory: one that plots the results of `Tests/Unit/pos/PointDist.hs`, and one that plots both `Tests/Unit/pos/vector0.hs` and `Tests/Unit/neg/vector0.hs`.
+
+* `plot-benchmarks --logdir /tmp --plot Tests/Unit/pos/PointDist.hs --outputdir /tmp/results`
+
+This will read log data from `/tmp` and create one .svg file for `Tests/Unit/pos/PointDist.hs` in `/tmp/results`
diff --git a/scripts/plot-benchmarks/Setup.hs b/scripts/plot-benchmarks/Setup.hs
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/scripts/plot-benchmarks/plot-benchmarks.cabal b/scripts/plot-benchmarks/plot-benchmarks.cabal
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/plot-benchmarks.cabal
@@ -0,0 +1,36 @@
+-- Initial plot-benchmarks.cabal generated by cabal init.  For further
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                plot-benchmarks
+version:             0.2.0.0
+synopsis:            Plot benchmarks in .csv format over time
+license:             BSD3
+license-file:        ../../LICENSE
+author:              Chris Tetreault
+maintainer:          ctetreau@ucsd.edu
+copyright:           University of California, San Diego.
+category:            Graphics
+build-type:          Simple
+-- extra-source-files:
+cabal-version:       >=1.10
+
+executable plot-benchmarks
+  main-is:             Main.hs
+  -- other-modules:
+  -- other-extensions:
+  build-depends:       base >=4.8 && <4.9
+                     , Chart >= 1.5 && < 1.6
+                     , Chart-diagrams >= 1.5 && < 1.6
+                     , cassava >= 0.4 && < 0.5
+                     , bytestring >= 0.10 && < 0.11
+                     , vector >= 0.11 && < 0.12
+                     , containers >= 0.5 && < 0.6
+                     , time >= 1.5 && < 1.6
+                     , process >= 1.2 && < 1.3
+                     , directory >= 1.2 && < 1.3
+                     , unordered-containers >= 0.2 && < 0.2.6
+                     , colour >= 2.3 && < 2.4
+                     , cmdargs >= 0.10 && < 0.11
+                     , filepath >= 1.4 && < 1.5
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/scripts/plot-benchmarks/src/Benchmark.hs b/scripts/plot-benchmarks/src/Benchmark.hs
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/src/Benchmark.hs
@@ -0,0 +1,56 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE FlexibleInstances #-}
+
+module Benchmark where
+
+import Data.Csv
+import qualified Data.Map as Map
+import Data.Foldable
+import Data.Time.LocalTime
+
+data Benchmark =
+   Benchmark { benchName :: String,
+               benchTimestamp :: LocalTime,
+               benchTime :: Double,
+               benchPass :: Bool
+               }
+   deriving (Eq)
+
+instance Ord Benchmark where
+   compare lhs rhs = compare (benchTimestamp lhs) (benchTimestamp rhs)
+
+unionAppend :: Map.Map String [Benchmark]
+               -> Map.Map String Benchmark
+               -> Map.Map String [Benchmark]
+unionAppend l r = Map.unionWith (++) l r'
+   where
+      r' = fmap (\a -> [a]) r
+
+toBenchMap :: (Foldable f)
+              => f Benchmark
+              -> Map.Map String Benchmark
+toBenchMap f = foldl' fn Map.empty f
+   where
+      fn m b = Map.insert (benchName b) b m
+
+instance FromRecord Benchmark where
+   parseRecord r = Benchmark
+                   <$> r .! 0
+                   <*> pure (error ("Shouldn't be evaluated until after"
+                                    ++ " reassignment!"))
+                   <*> r .! 1
+                   <*> do asStr <- r .! 2
+                          return $ read asStr {- Since the test suite
+   generates this field by calling show, this read Should Be Safe (TM) -}
+
+csvOutName = "Name"
+csvOutDate = "Committer Date"
+csvOutTime = "Time (Seconds)"
+csvOutPass = "Success"
+
+instance ToNamedRecord (LocalTime, Benchmark) where
+   toNamedRecord (_, bm) = namedRecord [csvOutName .= benchName bm,
+                                   csvOutDate .= (show $ benchTimestamp bm),
+                                   csvOutTime .= (benchTime bm),
+                                   csvOutPass .= (show $ benchPass bm)]
diff --git a/scripts/plot-benchmarks/src/Config.hs b/scripts/plot-benchmarks/src/Config.hs
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/src/Config.hs
@@ -0,0 +1,50 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module Config where
+
+import System.Console.CmdArgs
+import System.Directory
+
+data OutputType =
+   Svg
+   | Csv
+     deriving (Eq, Data, Typeable, Show)
+
+data Config =
+   Config { logDir :: FilePath,
+            outputDir :: FilePath,
+            outputType :: OutputType,
+            plotCompare :: [(String, String)],
+            plot :: [String]
+          } deriving (Eq, Data, Typeable, Show)
+
+pwd :: FilePath
+pwd = "."
+
+instance Default Config where
+   def = Config { logDir = pwd,
+                  outputDir = pwd,
+                  outputType = Csv,
+                  plotCompare = def,
+                  plot = def
+                }
+
+config :: Config
+config = Config
+            { logDir = pwd &= help "The directory that contains the logs",
+              outputDir = pwd &= help "The diretory to output graphs to",
+              outputType = Csv &= help "The type of output to produce",
+              plotCompare = def &= help "Pairs of benchmarks to compare",
+              plot = def &= help "Benchmarks to plot"
+            }
+            &= program "plot-benchmarks"
+            &= summary ("plot-benchmarks - Copyright 2016 Regents of"
+                        ++ "the University of California.")
+            &= details ["Plot LiquidHaskell benchmarks over time"]
+
+getConfig :: IO Config
+getConfig = do
+   conf <- cmdArgs config
+   ld <- makeAbsolute $ logDir conf
+   od <- makeAbsolute $ outputDir conf
+   return $ conf {logDir = ld, outputDir = od}
diff --git a/scripts/plot-benchmarks/src/Main.hs b/scripts/plot-benchmarks/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/src/Main.hs
@@ -0,0 +1,30 @@
+module Main where
+
+import Plot
+import Config
+import Parse
+
+main :: IO ()
+main = do
+   conf <- getConfig
+   case (outputType conf) of
+      Csv -> do
+         csvData <- getAllData
+                       (logDir conf)
+                       (plot conf)
+         dumpLogs
+            (outputDir conf)
+            csvData
+      Svg -> do
+         timeData <- getTimeData
+                        (logDir conf)
+                        (plot conf)
+         plotTimeData
+            (outputDir conf)
+            timeData
+         compareTimeData <- getCompareTimeData
+                               (logDir conf)
+                               (plotCompare conf)
+         plotCompareTimeData
+            (outputDir conf)
+            compareTimeData
diff --git a/scripts/plot-benchmarks/src/Parse.hs b/scripts/plot-benchmarks/src/Parse.hs
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/src/Parse.hs
@@ -0,0 +1,80 @@
+module Parse where
+
+import Benchmark
+import Data.Csv
+import Data.List
+import System.Directory
+import Data.Either
+import qualified Data.Vector as V
+import qualified Data.ByteString.Lazy.Char8 as BS
+import Data.Time.Clock.POSIX
+import Data.Time.LocalTime
+import System.FilePath
+
+gulpLogs :: FilePath -> IO [V.Vector Benchmark]
+gulpLogs f = do
+   conts <- getDirectoryContents f
+   let justCsv = filter (isSuffixOf ".csv") conts
+   let noHidden = filter (\a -> not (isPrefixOf "." a)) justCsv
+   let toGulp = fmap (\a -> f </> a) noHidden
+   logs <- sequence $ fmap parseLog toGulp
+   return $ rights logs
+
+parseLog :: FilePath -> IO (Either String (V.Vector Benchmark))
+parseLog p = do
+   file <- BS.readFile p
+   let (hdr, csv) = splitHeader file delimiter
+   timezone <- getCurrentTimeZone
+   case (getEpochTime hdr) of
+      Nothing -> return $ Left "missing timestamp!"
+      Just ts -> case (decode HasHeader csv) of
+         Right bm ->
+            return $ Right $ fmap
+               (\a -> a {benchTimestamp = utcToLocalTime
+                                             timezone
+                                             $ posixSecondsToUTCTime
+                                               $ realToFrac ts})
+               bm
+
+delimiter :: String
+delimiter = take 80 $ repeat '-'
+
+getEpochTime :: [String] -> Maybe Int
+getEpochTime s = do
+   elm <- find (isPrefixOf "Epoch Timestamp:") s
+   elm' <- stripPrefix "Epoch Timestamp:" elm
+   return (read elm' :: Int)
+
+splitHeader :: BS.ByteString -> String -> ([String], BS.ByteString)
+splitHeader msg delim = (hdr, BS.pack $ unlines csv)
+   where
+      (hdr, csv) = let ((hdrr, csvr), _) = foldl' foldFn initAcc lns in
+         (reverse hdrr, reverse csvr)
+      lns = lines $ BS.unpack msg
+      initAcc = (([],[]), False)
+      foldFn ((ls, rs), True) e = ((ls, e:rs), True)
+      foldFn ((ls, rs), False) e = if e == delim
+                                      then
+                                      ((ls, rs), True)
+                                      else
+                                      ((e:ls, rs), False)
+
+dumpLogs :: FilePath -> [(String, [(LocalTime, Benchmark)])] -> IO ()
+dumpLogs out dps = sequence_ $ fmap dumpLog dps
+   where
+      dumpLog :: (String, [(LocalTime, Benchmark)]) -> IO ()
+      dumpLog (n, dps') = do
+         let n' = specToUscore n
+         let dps'' = encodeByName
+                        (V.fromList [csvOutName,
+                                     csvOutDate,
+                                     csvOutTime,
+                                     csvOutPass])
+                        dps'
+         BS.writeFile (out </> n' ++ ".csv") dps''
+      specToUscore s = fmap mapper s
+         where
+            mapper c = case c of
+               '/' -> '_'
+               '.' -> '_'
+               c' -> c'
diff --git a/scripts/plot-benchmarks/src/Plot.hs b/scripts/plot-benchmarks/src/Plot.hs
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/src/Plot.hs
@@ -0,0 +1,161 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleContexts #-}
+
+module Plot where
+
+import Benchmark
+import Parse
+import qualified Data.Map as Map
+import Data.Foldable
+import Data.List
+import Graphics.Rendering.Chart.Easy
+import Graphics.Rendering.Chart.Backend.Diagrams
+import Data.Time.LocalTime
+import Data.Colour ()
+import Data.Colour.Names ()
+import System.FilePath
+
+fileOptions :: FileOptions
+fileOptions = def-- (def {_fo_size = (1024, 768)} :: FileOptions)
+
+lineColor1 :: AlphaColour Double
+lineColor1 = withOpacity darkred 0.5
+
+pointColor1 :: AlphaColour Double
+pointColor1 = opaque red
+
+lineColor2 :: AlphaColour Double
+lineColor2 = withOpacity darkgreen 0.5
+
+pointColor2 :: AlphaColour Double
+pointColor2 = opaque green
+
+plotData :: (Default r, ToRenderable r)
+            => FilePath
+            -> [(String, [(LocalTime, a)])]
+            -> (String -> [(LocalTime, a)] -> EC r ())
+            -> IO ()
+plotData out dps with = sequence_ $ fmap plotDp dps
+   where
+      plotDp (n, dps') = do
+         let n' = specToUscore n
+         let options = fileOptions
+         toFile options (out </> n' ++ ".svg") $ with n dps'
+      specToUscore s = fmap mapper s
+         where
+            mapper c = case c of
+               '/' -> '_'
+               '.' -> '_'
+               c' -> c'
+
+plotCompareData :: (Default r, ToRenderable r)
+                   => FilePath
+                   -> [((String, [(LocalTime, a)]),(String, [(LocalTime, a)]))]
+                   -> (String
+                       -> String
+                       -> ([(LocalTime, a)],[(LocalTime, a)]) -> EC r ())
+                   -> IO ()
+plotCompareData out dps with = sequence_ $ fmap plotDp dps
+   where
+      plotDp ((ln, ldps'), (rn, rdps')) = do
+         let ln' = specToUscore ln
+         let rn' = specToUscore rn
+         let dps' = (ldps', rdps')
+         let options = fileOptions
+         toFile
+            options
+            (out </> ln' ++ "_vs_" ++ rn' ++ ".svg")
+            $ with ln rn dps'
+      specToUscore s = fmap mapper s
+         where
+            mapper c = case c of
+               '/' -> '_'
+               '.' -> '_'
+               c' -> c'
+
+plotCompareTimeData :: FilePath
+                       -> [((String, [(LocalTime, Double)]),
+                            (String, [(LocalTime, Double)]))]
+                       -> IO ()
+plotCompareTimeData out dps = plotCompareData out dps with
+   where
+      with ln rn (ldps, rdps) = do
+         layoutlr_title .= ln ++ " vs. " ++ rn ++ " Times"
+         setColors [lineColor1, lineColor2, pointColor1, pointColor2]
+         setShapes [PointShapeCircle, PointShapeCircle]
+         plotLeft $ line "" [ldps]
+         plotRight $ line "" [rdps]
+         plotLeft $ points ln ldps
+         plotRight $ points rn rdps
+
+plotTimeData :: FilePath -> [(String, [(LocalTime, Double)])] -> IO ()
+plotTimeData out dps = plotData out dps with
+   where
+      with n' dps' = do
+            layout_title .= n' ++ " Times"
+            setColors [lineColor1, pointColor1]
+            plot $ line "" [dps']
+            plot $ points n' dps'
+
+getCompareData :: ([Benchmark] -> [(LocalTime, a)])
+                  -> FilePath
+                  -> [(String, String)]
+                  -> IO [((String, [(LocalTime, a)]),
+                          (String, [(LocalTime, a)]))]
+getCompareData mapper f bps = sequence $ fmap pairUp bps
+   where
+      pairUp (l, r) = do
+         [l'] <- getData mapper f [l]
+         [r'] <- getData mapper f [r]
+         return (l', r')
+
+getData :: ([Benchmark] -> [(LocalTime, a)])
+                -> FilePath
+                -> [String]
+                -> IO [(String, [(LocalTime, a)])]
+getData mapper f bs = do
+   logs <- gulpLogs f
+   let logMaps = fmap toBenchMap logs
+   let combined = foldl' unionAppend Map.empty logMaps
+   let onlyBs = Map.filterWithKey (\k _ -> k `elem` bs) combined
+   let dataPs = Map.toList $ fmap mapper onlyBs
+   let sorted =  fmap sortMapper dataPs
+   return sorted
+   where
+      comparator (tsl, _) (tsr, _) = compare tsl tsr
+      sortMapper (name, dps) = (name, sortBy comparator dps)
+
+getTimeData :: FilePath -> [String] -> IO [(String, [(LocalTime, Double)])]
+getTimeData = getData timeDataMapper
+
+
+getCompareTimeData :: FilePath
+                   -> [(String, String)]
+                   -> IO [((String, [(LocalTime, Double)]),
+                           (String, [(LocalTime, Double)]))]
+getCompareTimeData = getCompareData timeDataMapper
+
+timeDataMapper :: [Benchmark] -> [(LocalTime, Double)]
+timeDataMapper bs' = [(benchTimestamp x, benchTime x) | x <- bs' ]
+
+
+
+getSuccessData :: FilePath -> [String] -> IO [(String, [(LocalTime, Bool)])]
+getSuccessData = getData mapper
+   where
+      mapper bs' = [(benchTimestamp x, benchPass x) | x <- bs' ]
+
+plotSuccessData :: FilePath -> [(String, [(LocalTime, Bool)])] -> IO ()
+plotSuccessData out dps = plotData out dps with
+   where
+      dps'' v = fmap (\(l, r) -> case r of
+                                  True -> (l, (1 :: Integer))
+                                  False -> (l, 0)) v
+      with n' dps' = do
+         layout_title .= n' ++ " Test Result"
+         plot (line n' [dps'' dps'])
+
+getAllData :: FilePath -> [String] -> IO [(String, [(LocalTime, Benchmark)])]
+getAllData = getData mapper
+   where
+      mapper bs' = [(benchTimestamp x, x) | x <- bs']
diff --git a/scripts/plot-benchmarks/stack.yaml b/scripts/plot-benchmarks/stack.yaml
new file mode 100644
--- /dev/null
+++ b/scripts/plot-benchmarks/stack.yaml
@@ -0,0 +1,11 @@
+resolver: lts-4.0
+
+packages:
+- .
+
+extra-deps:
+- Chart-diagrams-1.5.4 
+- SVGFonts-1.5.0.0
+- tuple-0.3.0.2
+- OneTuple-0.2.1
+- lucid-svg-0.5.0.0
diff --git a/scripts/travis b/scripts/travis
new file mode 100644
--- /dev/null
+++ b/scripts/travis
@@ -0,0 +1,162 @@
+#!/bin/bash
+
+set -eu
+set -o pipefail
+
+## Helper Functions
+
+function loud {
+  echo "$ $@"
+  $@
+}
+
+function stack {
+  $HOME/.local/bin/stack --no-terminal "$@"
+}
+
+# Source: https://github.com/travis-ci/travis-build/blob/fc4ae8a2ffa1f2b3a2f62533bbc4f8a9be19a8ae/lib/travis/build/script/templates/header.sh#L104-L123
+RED="\033[31;1m"
+GREEN="\033[32;1m"
+RESET="\033[0m"
+function travis_retry {
+  local result=0
+  local count=1
+  while [ $count -le 3 ]; do
+    [ $result -ne 0 ] && {
+      echo -e "\n${RED}The command \"$@\" failed. Retrying, $count of 3.${RESET}\n" >&2
+    }
+    set +e
+    "$@"
+    result=$?
+    set -e
+    [ $result -eq 0 ] && break
+    count=$(($count + 1))
+    sleep 1
+  done
+
+  [ $count -eq 4 ] && {
+    echo "\n${RED}The command \"$@\" failed 3 times.${RESET}\n" >&2
+  }
+
+  return $result
+}
+
+function prevent_timeout {
+  local cmd="$@"
+
+  $cmd &
+  local cmd_pid=$!
+
+  poke_stdout &
+  local poke_pid=$!
+
+  wait $cmd_pid
+  exit_code=$?
+
+  kill $poke_pid
+  (wait $poke_pid 2>/dev/null) || true
+
+  return $exit_code
+}
+
+function poke_stdout {
+  # Print an invisible character every minute
+  while true; do
+    echo -ne "\xE2\x80\x8B"
+    sleep 60
+  done
+}
+
+function pastebin {
+  curl -s -F 'clbin=<-' https://clbin.com
+}
+
+## Setup Stages
+
+function install_smt {
+  local smt="$1"
+
+  mkdir -p "${HOME}/.local/bin"
+  loud curl "http://goto.ucsd.edu/~gridaphobe/$smt" -o "${HOME}/.local/bin/$smt"
+  loud chmod a+x "${HOME}/.local/bin/$smt"
+}
+
+function install_stack {
+  local stack_version="$1"
+
+  mkdir -p "${HOME}/.local/bin"
+  mkdir -p '/tmp/stack'
+
+  pushd '/tmp/stack'
+
+  local dir_name="stack-${stack_version}-x86_64-linux"
+  local archive_name="${dir_name}.tar.gz"
+  local stack_url="https://github.com/commercialhaskell/stack/releases/download/v${stack_version}/${archive_name}"
+
+  loud wget "${stack_url}"
+  loud tar -xzvf "./${archive_name}"
+  loud cp "./${dir_name}/stack" "${HOME}/.local/bin/stack"
+  loud chmod a+x "${HOME}/.local/bin/stack"
+
+  popd
+}
+
+function configure_stack {
+  local ghc_version="$1"
+
+  echo "Configuring stack.yaml for ${ghc_version}..."
+
+  cat << EOF > 'stack.yaml'
+resolver: ${ghc_version}
+
+packages:
+- ./liquid-fixpoint
+- .
+EOF
+
+  loud cat stack.yaml
+}
+
+function setup_ghc {
+  loud stack setup
+  loud stack ghc -- --version
+}
+
+function install_dependencies {
+  echo "Solving dependency constraints..."
+  loud stack update
+  loud stack solver --update-config
+
+  echo "Installing dependencies..."
+  loud stack build liquidhaskell --only-dependencies --test --no-run-tests --no-haddock-deps
+}
+
+## Building & Testing Stages
+
+function do_build {
+  loud stack build liquidhaskell --test --no-run-tests --haddock --no-haddock-deps --flag liquidhaskell:devel
+}
+
+function do_test {
+  local tests="$1"
+  local smt="$2"
+
+  local test_runner="$(stack path --dist-dir)/build/test/test"
+
+  loud prevent_timeout stack exec -- "${test_runner}" --pattern "$tests/" --smtsolver "$smt" -j2 +RTS -N2 -RTS
+}
+
+function dump_fail_logs {
+  find tests/logs/cur -type f -name '*log.fail' -print0 | while IFS= read -r -d $'\0' file; do
+    echo "${file}:"
+    echo "    $(pastebin < "${file}")"
+  done
+}
+
+## Run Test Stage
+
+stage="$1"
+shift
+
+$stage "$@"
+
diff --git a/shell.nix b/shell.nix
new file mode 100644
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,27 @@
+{ nixpkgs ? import <nixpkgs> {}, compiler ? "default", profiling ? false }:
+
+let
+
+  inherit (nixpkgs) pkgs;
+
+  liquid-fixpoint = import ./liquid-fixpoint { inherit (pkgs) fetchgitLocal; };
+  liquiddesugar = import ./liquiddesugar { inherit (pkgs) fetchgitLocal; };
+
+  f = import ./default.nix { inherit (pkgs) fetchgitLocal; };
+
+  haskellPackages = (if compiler == "default"
+                     then pkgs.haskellPackages
+                     else pkgs.haskell.packages.${compiler}
+                    ).override {
+                      overrides = self: super: {
+                        liquid-fixpoint = (self.callPackage liquid-fixpoint { inherit (pkgs) z3; }).overrideDerivation (drv: { doCheck = false; });
+
+                        mkDerivation = drv: super.mkDerivation (drv // { enableLibraryProfiling = profiling; });
+                      };
+                    };
+
+  drv = haskellPackages.callPackage f { inherit (pkgs) z3; };
+
+in
+
+  if pkgs.lib.inNixShell then drv.env else drv
diff --git a/src/Language/Haskell/Liquid/Bare.hs b/src/Language/Haskell/Liquid/Bare.hs
--- a/src/Language/Haskell/Liquid/Bare.hs
+++ b/src/Language/Haskell/Liquid/Bare.hs
@@ -1,3 +1,9 @@
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE RecordWildCards           #-}
+{-# LANGUAGE ViewPatterns              #-}
+
 -- | This module contains the functions that convert /from/ descriptions of
 -- symbols, names and types (over freshly parsed /bare/ Strings),
 -- /to/ representations connected to GHC vars, names, and types.
@@ -5,8 +11,674 @@
 -- in `RefType` -- they are different instances of `RType`
 
 module Language.Haskell.Liquid.Bare (
-    GhcSpec (..)
+    GhcSpec(..)
   , makeGhcSpec
+
+  -- * Lifted Spec
+  , loadLiftedSpec
+  , saveLiftedSpec
   ) where
 
-import Language.Haskell.Liquid.Bare.GhcSpec
+-- import Debug.Trace (trace)
+import           Prelude                                    hiding (error)
+import           CoreSyn                                    hiding (Expr)
+import qualified CoreSyn
+import           HscTypes
+import           Id
+import           NameSet
+import           Name
+import           TyCon
+import           Var
+import           TysWiredIn
+import           DataCon                                    (DataCon)
+import           InstEnv
+
+import           Control.Monad.Reader
+import           Control.Monad.State
+import           Data.Bifunctor
+import qualified Data.Binary                                as B
+import           Data.Maybe
+
+
+import           Control.Monad.Except                       (catchError)
+import           TypeRep                                    (Type(TyConApp))
+
+import           Text.PrettyPrint.HughesPJ (text)
+
+import qualified Control.Exception                          as Ex
+import qualified Data.List                                  as L
+import qualified Data.HashMap.Strict                        as M
+import qualified Data.HashSet                               as S
+import           System.Directory                           (doesFileExist)
+
+import           Language.Fixpoint.Utils.Files              -- (extFileName)
+import           Language.Fixpoint.Misc                     (traceShow, ensurePath, thd3, mapSnd)
+import           Language.Fixpoint.Types                    hiding (Error)
+
+import           Language.Haskell.Liquid.Types.Dictionaries
+-- import           Language.Haskell.Liquid.Misc               (ifM)
+import qualified Language.Haskell.Liquid.GHC.Misc  as GM -- (getSourcePosE, getSourcePos, sourcePosSrcSpa)
+import           Language.Haskell.Liquid.Types.PredType     (makeTyConInfo)
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.WiredIn
+
+import qualified Language.Haskell.Liquid.Measure            as Ms
+
+import           Language.Haskell.Liquid.Bare.Check
+import           Language.Haskell.Liquid.Bare.DataType
+import           Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.Existential
+import           Language.Haskell.Liquid.Bare.Measure
+import           Language.Haskell.Liquid.Bare.Axiom
+import           Language.Haskell.Liquid.Bare.Misc          (makeSymbols, mkVarExpr)
+import           Language.Haskell.Liquid.Bare.Plugged
+import           Language.Haskell.Liquid.Bare.RTEnv
+import           Language.Haskell.Liquid.Bare.Spec
+import           Language.Haskell.Liquid.Bare.Expand
+import           Language.Haskell.Liquid.Bare.SymSort
+import           Language.Haskell.Liquid.Bare.Lookup        (lookupGhcTyCon)
+import           Language.Haskell.Liquid.Bare.ToBare
+
+--------------------------------------------------------------------------------
+makeGhcSpec :: Config
+            -> FilePath
+            -> ModName
+            -> [CoreBind]
+            -> Maybe [ClsInst]
+            -> [Var]
+            -> [Var]
+            -> NameSet
+            -> HscEnv
+            -> Either Error LogicMap
+            -> [(ModName, Ms.BareSpec)]
+            -> IO GhcSpec
+--------------------------------------------------------------------------------
+makeGhcSpec cfg file name cbs instenv vars defVars exports env lmap specs = do
+  sp <- throwLeft =<< execBare act initEnv
+  let renv = ghcSpecEnv sp
+  throwLeft . checkGhcSpec specs renv $ postProcess cbs renv sp
+  where
+    act       = makeGhcSpec' cfg file cbs instenv vars defVars exports specs
+    throwLeft = either Ex.throw return
+    initEnv   = BE name mempty mempty mempty env lmap' mempty mempty axs
+    axs       = initAxSymbols name specs
+    lmap'     = case lmap of { Left e -> Ex.throw e; Right x -> x `mappend` listLMap}
+
+initAxSymbols :: ModName -> [(ModName, Ms.BareSpec)] -> M.HashMap Symbol LocSymbol
+initAxSymbols name = locMap . {- Ms.axioms -} Ms.reflects . fromMaybe mempty . lookup name
+  where
+    locMap xs      = M.fromList [ (val x, x) | x <- S.toList xs]
+
+listLMap :: LogicMap
+listLMap  = toLogicMap [ (dummyLoc nilName , []     , hNil)
+                       , (dummyLoc consName, [x, xs], hCons (EVar <$> [x, xs])) ]
+  where
+    x     = symbol "x"
+    xs    = symbol "xs"
+    hNil  = mkEApp (dcSym nilDataCon ) []
+    hCons = mkEApp (dcSym consDataCon)
+    dcSym = dummyLoc . GM.dropModuleUnique . symbol
+
+postProcess :: [CoreBind] -> SEnv SortedReft -> GhcSpec -> GhcSpec
+postProcess cbs specEnv sp@(SP {..})
+  = sp { gsTySigs     = mapSnd addTCI <$> sigs
+       , gsInSigs     = mapSnd addTCI <$> insigs
+       , gsAsmSigs    = mapSnd addTCI <$> assms
+       , gsInvariants = mapSnd addTCI <$> gsInvariants
+       , gsLits       = txSort        <$> gsLits
+       , gsMeas       = txSort        <$> gsMeas
+       , gsDicts      = dmapty addTCI'    gsDicts
+       , gsTexprs     = ts
+       }
+  where
+    (sigs,   ts')     = replaceLocBinds gsTySigs  gsTexprs
+    (assms,  ts'')    = replaceLocBinds gsAsmSigs ts'
+    (insigs, ts)      = replaceLocBinds gsInSigs  ts''
+    replaceLocBinds   = replaceLocalBinds allowHO gsTcEmbeds gsTyconEnv specEnv cbs
+    txSort            = mapSnd (addTCI . txRefSort gsTyconEnv gsTcEmbeds)
+    addTCI            = (addTCI' <$>)
+    addTCI'           = addTyConInfo gsTcEmbeds gsTyconEnv
+    allowHO           = higherOrderFlag gsConfig
+
+ghcSpecEnv :: GhcSpec -> SEnv SortedReft
+ghcSpecEnv sp        = fromListSEnv binds
+  where
+    emb              = gsTcEmbeds sp
+    binds            =  [(x,        rSort t) | (x, Loc _ _ t) <- gsMeas sp]
+                     ++ [(symbol v, rSort t) | (v, Loc _ _ t) <- gsCtors sp]
+                     ++ [(x,        vSort v) | (x, v)         <- gsFreeSyms sp, isConLikeId v]
+    rSort            = rTypeSortedReft emb
+    vSort            = rSort . varRSort
+    varRSort         :: Var -> RSort
+    varRSort         = ofType . varType
+
+--------------------------------------------------------------------------------
+-- | [NOTE]: REFLECT-IMPORTS
+--
+-- 1. MAKE the full LiftedSpec, which will eventually, contain:
+--      makeHaskell{Inlines, Measures, Axioms, Bounds}
+-- 2. SAVE the LiftedSpec, which will be reloaded
+
+-- | This step creates the aliases and inlines etc. It must be done BEFORE
+--   we compute the `SpecType` for (all, including the reflected binders),
+--   as we need the inlines and aliases to properly `expand` the SpecTypes.
+--------------------------------------------------------------------------------
+
+makeLiftedSpec0 :: TCEmb TyCon -> [CoreBind] -> Ms.BareSpec -> BareM Ms.BareSpec
+makeLiftedSpec0 embs cbs mySpec = do
+  xils   <- makeHaskellInlines  embs cbs mySpec
+  ms     <- makeHaskellMeasures embs cbs mySpec
+  return  $ mempty { Ms.ealiases = lmapEAlias . snd <$> xils
+                   , Ms.measures = ms
+                   , Ms.reflects = Ms.reflects mySpec      }
+
+makeLiftedSpec1 :: FilePath -> ModName -> Ms.BareSpec -> [(Var,LocSpecType)] -> BareM ()
+makeLiftedSpec1 file name lSpec0 xts
+  = liftIO $ saveLiftedSpec file name lSpec1
+  where
+    xbs    = [ (GM.namedLocSymbol x, specToBare <$> t) | (x, t) <- xts ]
+    lSpec1 = lSpec0 { Ms.asmSigs  = xbs
+                    , Ms.reflSigs = xbs }
+
+saveLiftedSpec :: FilePath -> ModName -> Ms.BareSpec -> IO ()
+saveLiftedSpec srcF _ lspec = do
+  -- putStrLn $ "Saving Binary Lifted Spec: " ++ specF
+  ensurePath specF
+  B.encodeFile specF lspec
+  where
+    specF = extFileName BinSpec srcF
+
+loadLiftedSpec :: FilePath -> IO Ms.BareSpec
+loadLiftedSpec srcF = do
+  let specF = extFileName BinSpec srcF
+  ex  <- doesFileExist specF
+  -- putStrLn $ "Loading Binary Lifted Spec: " ++ specF ++ " " ++ show ex
+  lSp <- if ex then B.decodeFile specF else return mempty
+  -- putStrLn $ "Loaded Spec: " ++ showpp (Ms.reflSigs lSp)
+  return lSp
+
+insert :: (Eq k) => k -> v -> [(k, v)] -> [(k, v)]
+insert k v []              = [(k, v)]
+insert k v ((k', v') : kvs)
+  | k == k'                = (k, v)   : kvs
+  | otherwise              = (k', v') : insert k v kvs
+
+_dumpSigs :: [(ModName, Ms.BareSpec)] -> IO ()
+_dumpSigs specs0 = putStrLn $ "DUMPSIGS:" ++  showpp [ (m, dump sp) | (m, sp) <- specs0 ]
+  where
+    dump sp = Ms.asmSigs sp ++ Ms.sigs sp ++ Ms.localSigs sp
+
+--------------------------------------------------------------------------------
+makeGhcSpec'
+  :: Config -> FilePath -> [CoreBind] -> Maybe [ClsInst] -> [Var] -> [Var]
+  -> NameSet -> [(ModName, Ms.BareSpec)]
+  -> BareM GhcSpec
+------------------------------------------------------------------------------------------------
+makeGhcSpec' cfg file cbs instenv vars defVars exports specs0 = do
+  -- liftIO $ dumpSigs specs0
+  name           <- modName <$> get
+  let mySpec      = fromMaybe mempty (lookup name specs0)
+  embs           <- makeNumericInfo instenv <$> (mconcat <$> mapM makeTyConEmbeds specs0)
+  lSpec0         <- makeLiftedSpec0 embs cbs mySpec
+  let fullSpec    = mySpec `mappend` lSpec0
+  lmap           <- logic_map . logicEnv    <$> get
+  let specs       = insert name fullSpec specs0
+  makeRTEnv name lSpec0 specs lmap
+  (tycons, datacons, dcSs, recSs, tyi) <- makeGhcSpecCHOP1 cfg specs embs
+  makeBounds embs name defVars cbs specs
+  modify                                   $ \be -> be { tcEnv = tyi }
+  (cls, mts)                              <- second mconcat . unzip . mconcat <$> mapM (makeClasses name cfg vars) specs
+  (measures, cms', ms', cs', xs')         <- makeGhcSpecCHOP2 cbs specs dcSs datacons cls embs
+  (invs, ntys, ialias, sigs, asms)        <- makeGhcSpecCHOP3 cfg vars defVars specs name mts embs
+  quals   <- mconcat <$> mapM makeQualifiers specs
+  syms                                    <- makeSymbols (varInModule name) (vars ++ map fst cs') xs' (sigs ++ asms ++ cs') ms' (map snd invs ++ (snd <$> ialias))
+  let su  = mkSubst [ (x, mkVarExpr v) | (x, v) <- syms]
+  makeGhcSpec0 cfg defVars exports name (emptySpec cfg)
+    >>= makeGhcSpec1 vars defVars embs tyi exports name sigs (recSs ++ asms) cs' ms' cms' su
+    >>= makeGhcSpec2 invs ntys ialias measures su
+    >>= makeGhcSpec3 (datacons ++ cls) tycons embs syms
+    >>= makeSpecDictionaries embs vars specs
+    >>= makeGhcAxioms file name embs cbs specs lSpec0
+    >>= makeLogicMap
+    >>= makeExactDataCons name (exactDC cfg) (snd <$> syms)
+    -- This step needs the UPDATED logic map, ie should happen AFTER makeLogicMap
+    >>= makeGhcSpec4 quals defVars specs name su
+    >>= addProofType
+    >>= addRTEnv
+
+addProofType :: GhcSpec -> BareM GhcSpec
+addProofType spec = do
+  tycon <- (Just <$> lookupGhcTyCon (dummyLoc proofTyConName)) `catchError` (\_ -> return Nothing)
+  return $ spec { gsProofType = (`TyConApp` []) <$> tycon }
+
+addRTEnv :: GhcSpec -> BareM GhcSpec
+addRTEnv spec = do
+  rt <- rtEnv <$> get
+  return $ spec { gsRTAliases = rt }
+
+
+makeExactDataCons :: ModName -> Bool -> [Var] -> GhcSpec -> BareM GhcSpec
+makeExactDataCons _n flag vs0 spec
+  | flag      = return $ spec { gsTySigs = gsTySigs spec ++ xts}
+  | otherwise = return spec
+  where
+    xts       = makeExact <$> filter f vs
+    f v       = GM.isDataConId v -- TODO:reflect-datacons && varInModule _n v
+    vs        = traceShow "makeExactDataCons vs  = " $ filter f vs1
+    vs1       = traceShow "makeExactDataCons vs0 = " vs0
+
+varInModule :: (Show a, Show a1) => a -> a1 -> Bool
+varInModule n v = L.isPrefixOf (show n) $ show v
+
+makeExact :: Var -> (Var, LocSpecType)
+makeExact x = (x, dummyLoc . fromRTypeRep $ trep{ty_res = res, ty_binds = xs})
+  where
+    t    :: SpecType
+    t    = ofType $ varType x
+    trep = toRTypeRep t
+    xs   = zipWith (\_ i -> (symbol ("x" ++ show i))) (ty_args trep) [1..]
+
+    res  = ty_res trep `strengthen` MkUReft ref mempty mempty
+    vv   = vv_
+    x'   = symbol x --  simpleSymbolVar x
+    ref  = Reft (vv, PAtom Eq (EVar vv) eq)
+    eq   | null (ty_vars trep) && null xs = EVar x'
+         | otherwise = mkEApp (dummyLoc x') (EVar <$> xs)
+
+getReflects :: [(ModName, Ms.BareSpec)] -> [Symbol]
+getReflects = fmap val . S.toList . S.unions . fmap (Ms.reflects . snd)
+
+-- TODO: pull the `makeLiftedSpec1` out; a function should do ONE thing.
+makeGhcAxioms
+  :: FilePath -> ModName -> TCEmb TyCon -> [CoreBind]
+  -> [(ModName, Ms.BareSpec)] -> Ms.BareSpec
+  -> GhcSpec -> BareM GhcSpec
+makeGhcAxioms file name embs cbs specs lSpec0 sp = do
+  let mSpc = fromMaybe mempty (lookup name specs)
+  let rfls = S.fromList (getReflects specs)
+  xtes    <- makeHaskellAxioms embs cbs sp mSpc
+  let xts  = [(x, t) | (x, t, _) <- xtes ]
+  let axs  = [ e     | (_, _, e) <- xtes ]
+  _       <- makeLiftedSpec1 file name lSpec0 xts
+  let xts' = xts ++ gsAsmSigs sp
+  let vts  = [ (v, vx, t) | (v, t) <- xts', let vx = varSymbol v, S.member vx rfls ]
+  let msR  = [ (vx, t)    | (_, vx, t) <- vts ]
+  let vs   = [ v          | (v,  _, _) <- vts ]
+  return   $ sp { gsAsmSigs  = xts'                   -- the IMPORTED refl-sigs are in gsAsmSigs sp
+                , gsMeas     = msR ++ gsMeas     sp   -- we must add them to gsMeas to allow the names in specifications
+                , gsReflects = vs  ++ gsReflects sp
+                , gsAxioms   = axs ++ gsAxioms   sp
+                }
+
+varSymbol :: Var -> Symbol
+varSymbol = GM.dropModuleNames . GM.simplesymbol
+
+makeLogicMap :: GhcSpec -> BareM GhcSpec
+makeLogicMap sp = do
+  lmap  <- logicEnv <$> get
+  return $ sp { gsLogicMap = lmap }
+
+emptySpec     :: Config -> GhcSpec
+emptySpec cfg = SP
+  { gsTySigs     = mempty
+  , gsAsmSigs    = mempty
+  , gsInSigs     = mempty
+  , gsCtors      = mempty
+  , gsLits       = mempty
+  , gsMeas       = mempty
+  , gsInvariants = mempty
+  , gsIaliases   = mempty
+  , gsDconsP     = mempty
+  , gsTconsP     = mempty
+  , gsFreeSyms   = mempty
+  , gsTcEmbeds   = mempty
+  , gsQualifiers = mempty
+  , gsTgtVars    = mempty
+  , gsDecr       = mempty
+  , gsTexprs     = mempty
+  , gsNewTypes   = mempty
+  , gsLvars      = mempty
+  , gsLazy       = mempty
+  , gsAutoInst   = mempty
+  , gsAutosize   = mempty
+  , gsConfig     = cfg
+  , gsExports    = mempty
+  , gsMeasures   = mempty
+  , gsTyconEnv   = mempty
+  , gsDicts      = mempty
+  , gsAxioms     = mempty
+  , gsReflects   = mempty
+  , gsLogicMap   = mempty
+  , gsProofType  = Nothing
+  , gsRTAliases  = mempty
+  }
+
+
+makeGhcSpec0 :: Config
+             -> [Var]
+             -> NameSet
+             -> ModName
+             -> GhcSpec
+             -> BareM GhcSpec
+makeGhcSpec0 cfg defVars exports name sp
+  = do targetVars <- makeTargetVars name defVars $ checks cfg
+       return      $ sp { gsConfig  = cfg
+                        , gsExports = exports
+                        , gsTgtVars = targetVars }
+
+makeGhcSpec1 :: [Var]
+             -> [Var]
+             -> TCEmb TyCon
+             -> M.HashMap TyCon RTyCon
+             -> NameSet
+             -> ModName
+             -> [(Var,    LocSpecType)]
+             -> [(Var,    LocSpecType)]
+             -> [(Var,    LocSpecType)]
+             -> [(Symbol, Located (RRType Reft))]
+             -> [(Symbol, Located (RRType Reft))]
+             -> Subst
+             -> GhcSpec
+             -> BareM GhcSpec
+makeGhcSpec1 vars defVars embs tyi exports name sigs asms cs' ms' cms' su sp
+  = do tySigs      <- makePluggedSigs name embs tyi exports $ tx sigs
+       asmSigs     <- makePluggedAsmSigs embs tyi           $ tx asms
+       ctors       <- makePluggedAsmSigs embs tyi           $ tx cs'
+       return $ sp { gsTySigs   = filter (\(v,_) -> v `elem` vs) tySigs
+                   , gsAsmSigs  = filter (\(v,_) -> v `elem` vs) asmSigs
+                   , gsCtors    = filter (\(v,_) -> v `elem` vs) ctors
+                   , gsMeas     = measSyms
+                   , gsLits     = measSyms -- RJ: we will be adding *more* things to `meas` but not `lits`
+                   }
+    where
+      tx       = fmap . mapSnd . subst $ su
+      tx'      = fmap (mapSnd $ fmap uRType)
+      vs       = vars ++ defVars
+      measSyms = tx' $ tx $ ms' ++ varMeasures vars ++ cms'
+
+makeGhcSpec2 :: Monad m
+             => [(Maybe Var  , LocSpecType)]
+             -> [(TyCon      , LocSpecType)]
+             -> [(LocSpecType, LocSpecType)]
+             -> MSpec SpecType DataCon
+             -> Subst
+             -> GhcSpec
+             -> m GhcSpec
+makeGhcSpec2 invs ntys ialias measures su sp
+  = return $ sp { gsInvariants = mapSnd (subst su) <$> invs
+                , gsNewTypes   = mapSnd (subst su) <$> ntys
+                , gsIaliases   = subst su ialias
+                , gsMeasures   = subst su
+                                 <$> M.elems (Ms.measMap measures)
+                                  ++ Ms.imeas measures
+                }
+
+makeGhcSpec3 :: [(DataCon, DataConP)] -> [(TyCon, TyConP)] -> TCEmb TyCon -> [(t, Var)] -> GhcSpec -> BareM GhcSpec
+makeGhcSpec3 datacons tycons embs syms sp = do
+  tcEnv  <- tcEnv    <$> get
+  return  $ sp { gsTyconEnv = tcEnv
+               , gsDconsP   = datacons -- dcons'
+               , gsTconsP   = tycons
+               , gsTcEmbeds = embs
+               , gsFreeSyms = [(symbol v, v) | (_, v) <- syms]
+               }
+
+makeGhcSpec4 :: [Qualifier]
+             -> [Var]
+             -> [(ModName, Ms.Spec ty bndr)]
+             -> ModName
+             -> Subst
+             -> GhcSpec
+             -> BareM GhcSpec
+makeGhcSpec4 quals defVars specs name su sp = do
+  decr'   <- mconcat <$> mapM (makeHints defVars . snd) specs
+  gsTexprs' <- mconcat <$> mapM (makeTExpr defVars . snd) specs
+  lazies  <- mkThing makeLazy
+  lvars'  <- mkThing makeLVar
+  autois  <- mkThing makeAutoInsts
+  defs'   <- mkThing makeDefs
+  addDefs defs'
+  asize'  <- S.fromList <$> makeASize
+  hmeas   <- mkThing makeHMeas
+  hinls   <- mkThing makeHInlines
+  mapM_ (\(v, s) -> insertAxiom (val v) (val s)) $ S.toList hmeas
+  mapM_ (\(v, s) -> insertAxiom (val v) (val s)) $ S.toList hinls
+  mapM_ insertHMeasLogicEnv $ S.toList hmeas
+  mapM_ insertHMeasLogicEnv $ S.toList hinls
+  lmap'       <- logicEnv <$> get
+  isgs        <- expand $ strengthenHaskellInlines  (S.map fst hinls) (gsTySigs sp)
+  gsTySigs'   <- expand $ strengthenHaskellMeasures (S.map fst hmeas) isgs
+  gsMeasures' <- expand $ gsMeasures   sp
+  gsAsmSigs'  <- expand $ gsAsmSigs    sp
+  gsInSigs'   <- expand $ gsInSigs     sp
+  gsInvarnts' <- expand $ gsInvariants sp
+  gsCtors'    <- expand $ gsCtors      sp
+  gsIaliases' <- expand $ gsIaliases   sp
+  gsDconsP'   <- expand $ gsDconsP     sp
+  return   $ sp { gsQualifiers = subst su quals
+                , gsDecr       = decr'
+                , gsLvars      = lvars'
+                , gsAutoInst   = M.fromList $ S.toList autois
+                , gsAutosize   = asize'
+                , gsLazy       = S.insert dictionaryVar lazies
+                , gsLogicMap   = lmap'
+                , gsTySigs     = gsTySigs'
+                , gsTexprs     = gsTexprs'
+                , gsMeasures   = gsMeasures'
+                , gsAsmSigs    = gsAsmSigs'
+                , gsInSigs     = gsInSigs'
+                , gsInvariants = gsInvarnts'
+                , gsCtors      = gsCtors'
+                , gsIaliases   = gsIaliases'
+                , gsDconsP     = gsDconsP'
+                }
+  where
+    mkThing mk = S.fromList . mconcat <$> sequence [ mk defVars s | (m, s) <- specs, m == name ]
+    makeASize  = mapM lookupGhcTyCon [v | (m, s) <- specs, m == name, v <- S.toList (Ms.autosize s)]
+
+
+insertHMeasLogicEnv :: (Located Var, LocSymbol) -> BareM ()
+insertHMeasLogicEnv (x, s)
+  -- / | isBool res
+  = insertLogicEnv "insertHMeasLogicENV" s (fst <$> vxs) $ mkEApp s ((EVar . fst) <$> vxs)
+  where
+    -- res = ty_res rep
+    rep = toRTypeRep  t
+    t   = (ofType $ varType $ val x) :: SpecType
+    xs  = intSymbol (symbol ("x" :: String)) <$> [1..length $ ty_binds rep]
+    vxs = dropWhile (isClassType.snd) $ zip xs (ty_args rep)
+-- insertHMeasLogicEnv _
+--   = return ()
+
+makeGhcSpecCHOP1
+  :: Config -> [(ModName,Ms.Spec ty bndr)] -> TCEmb TyCon
+  -> BareM ( [(TyCon,TyConP)]
+           , [(DataCon,DataConP)]
+           , [Measure SpecType DataCon]
+           , [(Var, Located SpecType)]
+           , M.HashMap TyCon RTyCon     )
+makeGhcSpecCHOP1 cfg specs embs = do
+  (tcs, dcs)      <- mconcat <$> mapM makeConTypes specs
+  let tycons       = tcs        ++ wiredTyCons
+  let tyi          = makeTyConInfo tycons
+  datacons        <- makePluggedDataCons embs tyi (concat dcs ++ wiredDataCons)
+  let dcSelectors  = concatMap (makeMeasureSelectors (exactDC cfg) (not $ noMeasureFields cfg)) datacons
+  recSels         <- makeRecordSelectorSigs datacons
+  return             (tycons, second val <$> datacons, dcSelectors, recSels, tyi)
+
+makeGhcSpecCHOP3 :: Config -> [Var] -> [Var] -> [(ModName, Ms.BareSpec)]
+                 -> ModName -> [(ModName, Var, LocSpecType)]
+                 -> TCEmb TyCon
+                 -> BareM ( [(Maybe Var, LocSpecType)]
+                          , [(TyCon, LocSpecType)]
+                          , [(LocSpecType, LocSpecType)]
+                          , [(Var, LocSpecType)]
+                          , [(Var, LocSpecType)] )
+makeGhcSpecCHOP3 cfg vars defVars specs name mts embs = do
+  sigs'    <- mconcat <$> mapM (makeAssertSpec name cfg vars defVars) specs
+  asms'    <- mconcat <$> mapM (makeAssumeSpec name cfg vars defVars) specs
+  invs     <- mconcat <$> mapM makeInvariants specs
+  ialias   <- mconcat <$> mapM makeIAliases   specs
+  ntys     <- mconcat <$> mapM makeNewTypes   specs
+  let dms   = makeDefaultMethods vars mts
+  tyi      <- gets tcEnv
+  let sigs  = [ (x, txRefSort tyi embs $ fmap txExpToBind t) | (_, x, t) <- sigs' ++ mts ++ dms ]
+  let asms  = [ (x, txRefSort tyi embs $ fmap txExpToBind t) | (_, x, t) <- asms' ]
+  let hms   = concatMap (S.toList . Ms.hmeas . snd) (filter ((==name) . fst) specs)
+  let minvs = makeMeasureInvariants sigs hms
+  return     (invs ++ minvs, ntys, ialias, sigs, asms)
+
+makeMeasureInvariants :: [(Var, LocSpecType)] -> [LocSymbol] -> [(Maybe Var, LocSpecType)]
+makeMeasureInvariants sigs xs = measureTypeToInv <$> [(x, (y, ty)) | x <- xs, (y, ty) <- sigs, val x == symbol' y]
+  where
+    symbol' :: Var -> Symbol
+    symbol' = GM.dropModuleNames . symbol . getName
+
+measureTypeToInv :: (LocSymbol, (Var, LocSpecType)) -> (Maybe Var, LocSpecType)
+measureTypeToInv (x, (v, t)) = (Just v, t {val = mtype})
+  where
+    trep = toRTypeRep $ val t
+    ts   = ty_args trep
+    mtype
+      | isBool $ ty_res trep
+      = uError $ ErrHMeas (GM.sourcePosSrcSpan $ loc t) (pprint x)
+                          (text "Specification of boolean measures is not allowed")
+{-
+      | [tx] <- ts, not (isTauto tx)
+      = uError $ ErrHMeas (sourcePosSrcSpan $ loc t) (pprint x)
+                          (text "Measures' types cannot have preconditions")
+-}
+      | [tx] <- ts
+      = mkInvariant (head $ ty_binds trep) tx $ ty_res trep
+      | otherwise
+      = uError $ ErrHMeas (GM.sourcePosSrcSpan $ loc t) (pprint x)
+                          (text "Measures has more than one arguments")
+
+
+    mkInvariant :: Symbol -> SpecType -> SpecType -> SpecType
+    mkInvariant z t tr = strengthen (top <$> t) (MkUReft reft mempty mempty)
+      where
+        Reft (v, p) = toReft $ fromMaybe mempty $ stripRTypeBase tr
+        su    = mkSubst [(v, mkEApp x [EVar v])]
+        reft  = Reft (v, subst su p')
+
+        p'    = pAnd $ filter (\e -> z `notElem` syms e) $ conjuncts p
+
+makeGhcSpecCHOP2 :: [CoreBind]
+                 -> [(ModName, Ms.BareSpec)]
+                 -> [Measure SpecType DataCon]
+                 -> [(DataCon, DataConP)]
+                 -> [(DataCon, DataConP)]
+                 -> TCEmb TyCon
+                 -> BareM ( MSpec SpecType DataCon
+                          , [(Symbol, Located (RRType Reft))]
+                          , [(Symbol, Located (RRType Reft))]
+                          , [(Var,    LocSpecType)]
+                          , [Symbol] )
+makeGhcSpecCHOP2 _cbs specs dcSelectors datacons cls embs = do
+  measures'   <- mconcat <$> mapM makeMeasureSpec specs
+  tyi         <- gets tcEnv
+  let measures = mconcat [measures' , Ms.mkMSpec' dcSelectors]
+  let (cs, ms) = makeMeasureSpec' measures
+  let cms      = makeClassMeasureSpec measures
+  let cms'     = [ (x, Loc l l' $ cSort t) | (Loc l l' x, t) <- cms ]
+  let ms'      = [ (x, Loc l l' t) | (Loc l l' x, t) <- ms, isNothing $ lookup x cms' ]
+  let cs'      = [ (v, txRefSort' v tyi embs t) | (v, t) <- meetDataConSpec cs (datacons ++ cls)]
+  let xs'      = val . fst <$> ms
+  return (measures, cms', ms', cs', xs')
+
+txRefSort' :: NamedThing a => a -> TCEnv -> TCEmb TyCon -> SpecType -> LocSpecType
+txRefSort' v tyi embs t = txRefSort tyi embs (const t <$> GM.locNamedThing v) -- (atLoc' v t)
+
+-- atLoc' :: NamedThing t => t -> a -> Located a
+-- atLoc' v t = Loc (getSourcePos v) (getSourcePosE v)
+
+data ReplaceEnv = RE
+  { _reEnv  :: M.HashMap Symbol Symbol
+  , _reFEnv :: SEnv SortedReft
+  , _reEmb  :: TCEmb TyCon
+  , _reTyi  :: M.HashMap TyCon RTyCon
+  }
+
+type ReplaceState = ( M.HashMap Var LocSpecType
+                    , M.HashMap Var [Located Expr]
+                    )
+
+type ReplaceM = ReaderT ReplaceEnv (State ReplaceState)
+
+-- ASKNIKI: WHAT DOES THIS FUNCTION DO?!!!!
+replaceLocalBinds :: Bool
+                  -> TCEmb TyCon
+                  -> M.HashMap TyCon RTyCon
+                  -> SEnv SortedReft
+                  -> CoreProgram
+                  -> [(Var, LocSpecType)]
+                  -> [(Var, [Located Expr])]
+                  -> ([(Var, LocSpecType)], [(Var, [Located Expr])])
+replaceLocalBinds allowHO emb tyi senv cbs sigs texprs
+  = (M.toList s, M.toList t)
+  where
+    (s, t) = execState (runReaderT (mapM_ (\x -> traverseBinds allowHO x (return ())) cbs)
+                                   (RE M.empty senv emb tyi))
+                       (M.fromList sigs, M.fromList texprs)
+
+traverseExprs :: Bool -> CoreSyn.Expr Var -> ReplaceM ()
+traverseExprs allowHO (Let b e)
+  = traverseBinds allowHO b (traverseExprs allowHO e)
+traverseExprs allowHO (Lam b e)
+  = withExtendedEnv allowHO [b] (traverseExprs allowHO e)
+traverseExprs allowHO (App x y)
+  = traverseExprs allowHO x >> traverseExprs allowHO y
+traverseExprs allowHO (Case e _ _ as)
+  = traverseExprs allowHO e >> mapM_ (traverseExprs allowHO . thd3) as
+traverseExprs allowHO (Cast e _)
+  = traverseExprs allowHO e
+traverseExprs allowHO (Tick _ e)
+  = traverseExprs allowHO e
+traverseExprs _ _
+  = return ()
+
+traverseBinds :: Bool -> Bind Var -> ReplaceM b -> ReplaceM b
+traverseBinds allowHO b k = withExtendedEnv allowHO (bindersOf b) $ do
+  mapM_ (traverseExprs allowHO) (rhssOfBind b)
+  k
+
+-- RJ: this function is incomprehensible, what does it do?!
+withExtendedEnv :: Bool -> [Var] -> ReplaceM b -> ReplaceM b
+withExtendedEnv allowHO vs k = do
+  RE env' fenv' emb tyi <- ask
+  let env  = L.foldl' (\m v -> M.insert (varShortSymbol v) (symbol v) m) env' vs
+      fenv = L.foldl' (\m v -> insertSEnv (symbol v) (rTypeSortedReft emb (ofType $ varType v :: RSort)) m) fenv' vs
+  withReaderT (const (RE env fenv emb tyi)) $ do
+    mapM_ (replaceLocalBindsOne allowHO) vs
+    k
+
+varShortSymbol :: Var -> Symbol
+varShortSymbol = symbol . takeWhile (/= '#') . GM.showPpr . getName
+
+-- RJ: this function is incomprehensible, what does it do?!
+replaceLocalBindsOne :: Bool -> Var -> ReplaceM ()
+replaceLocalBindsOne allowHO v
+  = do mt <- gets (M.lookup v . fst)
+       case mt of
+         Nothing -> return ()
+         Just (Loc l l' (toRTypeRep -> t@(RTypeRep {..}))) -> do
+           (RE env' fenv emb tyi) <- ask
+           let f m k = M.lookupDefault k k m
+           let (env,args) = L.mapAccumL (\e (v, t) -> (M.insert v v e, substa (f e) t))
+                             env' (zip ty_binds ty_args)
+           let res  = substa (f env) ty_res
+           let t'   = fromRTypeRep $ t { ty_args = args, ty_res = res }
+           let msg  = ErrTySpec (GM.sourcePosSrcSpan l) ({- text "replaceLocalBindsOne" <+> -} pprint v) t'
+           case checkTy allowHO msg emb tyi fenv (Loc l l' t') of
+             Just err -> Ex.throw err
+             Nothing  -> modify (first $ M.insert v (Loc l l' t'))
+           mes <- gets (M.lookup v . snd)
+           case mes of
+             Nothing -> return ()
+             Just es -> do
+               let es'  = substa (f env) es
+               case checkTerminationExpr emb fenv (v, Loc l l' t', es') of
+                 Just err -> Ex.throw err
+                 Nothing  -> modify (second $ M.insert v es')
diff --git a/src/Language/Haskell/Liquid/Bare/Axiom.hs b/src/Language/Haskell/Liquid/Bare/Axiom.hs
--- a/src/Language/Haskell/Liquid/Bare/Axiom.hs
+++ b/src/Language/Haskell/Liquid/Bare/Axiom.hs
@@ -3,230 +3,196 @@
 {-# LANGUAGE TypeSynonymInstances #-}
 {-# LANGUAGE FlexibleInstances    #-}
 
-module Language.Haskell.Liquid.Bare.Axiom (makeAxiom) where
+module Language.Haskell.Liquid.Bare.Axiom (makeHaskellAxioms) where
 
 import Prelude hiding (error)
 import CoreSyn
 import TyCon
 import Id
 import Name
-import Type hiding (isFunTy)
 import Var
-
 import TypeRep
 
 import Prelude hiding (mapM)
 
-
-import Control.Monad hiding (forM, mapM)
-import Control.Monad.Except hiding (forM, mapM)
-import Control.Monad.State hiding (forM, mapM)
-import Data.Bifunctor
-
-
-
-
-import Text.PrettyPrint.HughesPJ (text)
-
-
-import qualified Data.List as L
-
-
-import Language.Fixpoint.Misc
-import Language.Fixpoint.Types (Symbol, symbol, symbolString)
-
-import qualified Language.Fixpoint.Types as F
-import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.Transforms.CoreToLogic
-
-import Language.Haskell.Liquid.GHC.Misc (showPpr, sourcePosSrcSpan, dropModuleNames)
--- import Language.Haskell.Liquid.Types.RefType (generalize, ofType, uRType, typeSort)
-
-import Language.Haskell.Liquid.Types hiding (binders)
-
-
+import           Control.Monad.Except hiding (forM, mapM)
+import           Control.Monad.State hiding (forM, mapM)
+import           Text.PrettyPrint.HughesPJ (text)
+import qualified Data.HashSet as S
+import           Data.Maybe (fromMaybe)
+import           Language.Fixpoint.Misc
+import           Language.Fixpoint.Types (Symbol, symbol)
 import qualified Language.Haskell.Liquid.Measure as Ms
-
-import Language.Haskell.Liquid.Bare.Env
-
-
-
-
-
-
-
-
+import qualified Language.Fixpoint.Types as F
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Transforms.CoreToLogic
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Bare.Env
 
+--------------------------------------------------------------------------------
+makeHaskellAxioms
+  :: F.TCEmb TyCon -> [CoreBind] -> GhcSpec -> Ms.BareSpec
+  -> BareM [ (Var, LocSpecType, AxiomEq)]
+--------------------------------------------------------------------------------
+makeHaskellAxioms tce cbs spec sp = do
+  xtvds <- getReflectDefs spec sp cbs
+  forM_ xtvds $ \(x,_,v,_) -> updateLMapXV x v
+  lmap <- logicEnv <$> get
+  mapM (makeAxiom tce lmap cbs) xtvds
 
+updateLMapXV :: LocSymbol -> Var -> BareM ()
+updateLMapXV x v = do
+  updateLMap x x v
+  updateLMap (x {val = (symbol . showPpr . getName) v}) x v
 
-makeAxiom :: F.TCEmb TyCon -> LogicMap -> [CoreBind] -> GhcSpec -> Ms.BareSpec -> LocSymbol
-          -> BareM ((Symbol, Located SpecType), [(Var, Located SpecType)], [HAxiom])
-makeAxiom tce lmap cbs _ _ x
-  = case filter ((val x `elem`) . map (dropModuleNames . simplesymbol) . binders) cbs of
-        (NonRec v def:_)   -> do vts <- zipWithM (makeAxiomType tce lmap x) (reverse $ findAxiomNames x cbs) (defAxioms v def)
-                                 insertAxiom v (val x)
-                                 updateLMap lmap x x v
-                                 updateLMap lmap (x{val = (symbol . showPpr . getName) v}) x v
-                                 return ((val x, makeType v),
-                                         (v, makeAssumeType v):vts, defAxioms v def)
-        (Rec [(v, def)]:_) -> do vts <- zipWithM (makeAxiomType tce lmap x) (reverse $ findAxiomNames x cbs) (defAxioms v def)
-                                 insertAxiom v (val x)
-                                 updateLMap lmap x x v -- (reverse $ findAxiomNames x cbs) (defAxioms v def)
-                                 updateLMap lmap (x{val = (symbol . showPpr . getName) v}) x v
-                                 return ((val x, makeType v),
-                                         ((v, makeAssumeType v): vts),
-                                         defAxioms v def)
-        _                  -> throwError $ mkError "Cannot extract measure from haskell function"
+getReflectDefs
+  :: GhcSpec -> Ms.BareSpec -> [CoreBind]
+  -> BareM [(LocSymbol, Maybe SpecType, Var, CoreExpr)]
+getReflectDefs spec sp cbs  = mapM (findVarDefType cbs sigs) xs
   where
-
-    --coreToDef' x v def = case runToLogic lmap mkError $ coreToDef x v def of
-    --                        Left l  -> l :: [Def (RRType ()) DataCon] -- return     l
-    --                        Right _ -> error $ "ERROR" -- throwError e
-
-    mkError :: String -> Error
-    mkError str = ErrHMeas (sourcePosSrcSpan $ loc x) (pprint $ val x) (text str)
-
-    makeType v       = x{val = ufType    $ varType v}
-    makeAssumeType v = x{val = axiomType x $ varType v}
-
+    sigs                    = gsTySigs spec
+    xs                      = S.toList (Ms.reflects sp)
 
+findVarDefType
+  :: [CoreBind] -> [(Var, LocSpecType)] -> LocSymbol
+  -> BareM (LocSymbol, Maybe SpecType, Var, CoreExpr)
+findVarDefType cbs sigs x = case findVarDef (val x) cbs of
+  Just (v, e) -> return (x, val <$> lookup v sigs, v, e)
+  Nothing     -> throwError $ mkError x "Cannot lift haskell function"
 
-binders (NonRec x _) = [x]
-binders (Rec xes)    = fst <$> xes
+--------------------------------------------------------------------------------
+makeAxiom :: F.TCEmb TyCon
+          -> LogicMap
+          -> [CoreBind]
+          -> (LocSymbol, Maybe SpecType, Var, CoreExpr)
+          -> BareM (Var, LocSpecType, AxiomEq)
+--------------------------------------------------------------------------------
+makeAxiom tce lmap _cbs (x, mbT, v, def) = do
+  insertAxiom v (val x)
+  updateLMap x x v
+  updateLMap (x{val = (symbol . showPpr . getName) v}) x v
+  let (t, e) = makeAssumeType tce lmap x mbT v def
+  return (v, t, e)
 
-updateLMap :: LogicMap -> LocSymbol -> LocSymbol -> Var -> BareM ()
-updateLMap _ _ _ v | not (isFun $ varType v)
-  = return ()
-  where
-    isFun (FunTy _ _)    = True
-    isFun (ForAllTy _ t) = isFun t
-    isFun  _             = False
+mkError :: LocSymbol -> String -> Error
+mkError x str = ErrHMeas (sourcePosSrcSpan $ loc x) (pprint $ val x) (text str)
 
-updateLMap _ x y vv -- v axm@(Axiom (vv, _) xs _ lhs rhs)
-  = insertLogicEnv (val x) ys (F.eApps (F.EVar $ val y) (F.EVar <$> ys))
+makeSMTAxiom :: LocSymbol -> [(Symbol, F.Sort)] -> F.Expr -> AxiomEq
+makeSMTAxiom f xts e = AxiomEq (val f) xs e (F.PAll xts (F.EEq f_xs e))
   where
-    nargs = dropWhile isClassType $ ty_args $ toRTypeRep $ ((ofType $ varType vv) :: RRType ())
-
-    ys = zipWith (\i _ -> symbol (("x" ++ show i) :: String)) [1..] nargs
+    xs               = fst <$> xts
+    f_xs             = F.mkEApp f (F.EVar <$> xs)
 
-makeAxiomType :: F.TCEmb TyCon -> LogicMap -> LocSymbol -> Var -> HAxiom -> BareM (Var, Located SpecType)
-makeAxiomType tce lmap x v (Axiom _ xs _ lhs rhs)
-  = do foldM (\lm x -> (updateLMap lm (dummyLoc $ F.symbol x) (dummyLoc $ F.symbol x) x >> (logicEnv <$> get))) lmap xs
-       return (v, x{val = t})
+makeAssumeType
+  :: F.TCEmb TyCon -> LogicMap -> LocSymbol -> Maybe SpecType ->  Var -> CoreExpr
+  -> (LocSpecType, AxiomEq)
+makeAssumeType tce lmap x mbT v def
+  = (x {val = at `strengthenRes` F.subst su ref},  makeSMTAxiom x xss le )
   where
-    t   = fromRTypeRep $  tr{ty_res = res, ty_binds = symbol <$> xs}
-    tt  = ofType $ varType v
-    tr  = toRTypeRep tt
-    res = ty_res tr `strengthen` MkUReft ref mempty mempty
-
-    llhs = case runToLogic tce lmap' mkErr (coreToLogic lhs) of
-       Left e -> e
-       Right e -> panic Nothing $ show e
-    lrhs = case runToLogic tce lmap' mkErr (coreToLogic rhs) of
-       Left e -> e
-       Right e -> panic Nothing $ show e
-    ref = F.Reft (F.vv_, F.PAtom F.Eq llhs lrhs)
-
-    -- nargs = dropWhile isClassType $ ty_args $ toRTypeRep $ ((ofType $ varType vv) :: RRType ())
-
+    t    = fromMaybe (ofType $ varType v) mbT
+    at   = {- F.tracepp ("axiomType: " ++ msg) $ -} axiomType x mbT t
+    _msg  = unwords [showpp x, showpp mbT]
+    le   = case runToLogicWithBoolBinds bbs tce lmap mkErr (coreToLogic def') of
+             Right e -> e
+             Left  e -> panic Nothing $ show e
 
-    lmap' = lmap -- M.insert v' (LMap v' ys runFun) lmap
+    ref  = F.Reft (F.vv_, F.PAtom F.Eq (F.EVar F.vv_) le)
 
     mkErr s = ErrHMeas (sourcePosSrcSpan $ loc x) (pprint $ val x) (text s)
 
-    --mkBinds (_:xs) (v:vs) = v:mkBinds xs vs
-    --mkBinds _ _ = []
-
-    -- v' = val x -- symbol $ showPpr $ getName vv
+    bbs     = filter isBoolBind xs
 
+    (xs, def') = grapBody $ normalize def
+    su = F.mkSubst $ zip (F.symbol     <$> xs) (F.EVar <$> ty_non_dict_binds (toRTypeRep at))
+                  ++ zip (simplesymbol <$> xs) (F.EVar <$> ty_non_dict_binds (toRTypeRep at))
 
+    grapBody (Lam x e)  = let (xs, e') = grapBody e in (x:xs, e')
+    grapBody (Tick _ e) = grapBody e
+    grapBody e          = ([], e)
 
+    xss = zipWith (\x t -> (mkSymbol x t, rTypeSort tce t)) xs (filter (not . isClassType) (ty_args (toRTypeRep at))) 
 
-findAxiomNames x (NonRec v _ :cbs) | isAxiomName x v = v:findAxiomNames x cbs
-findAxiomNames x (Rec [(v,_)]:cbs) | isAxiomName x v = v:findAxiomNames x cbs
-findAxiomNames x (_:cbs) = findAxiomNames x cbs
-findAxiomNames _ [] = []
+    mkSymbol x t = if isFunTy t then simplesymbol x else F.symbol x
+    ty_non_dict_binds trep = [x | (x, t) <- zip (ty_binds trep) (ty_args trep), not (isClassType t)]
 
-isAxiomName x v =
-  (("axiom_" ++ symbolString (val x)) `L.isPrefixOf`) (symbolString $ dropModuleNames $ simplesymbol v)
+isBoolBind :: Var -> Bool
+isBoolBind v = isBool (ty_res $ toRTypeRep ((ofType $ varType v) :: RRType ()))
 
-defAxioms :: Var -> CoreExpr -> [Axiom Var Kind (Expr Var)]
-defAxioms v e = go [] $ simplify e
+strengthenRes :: SpecType -> F.Reft -> SpecType
+strengthenRes t r = fromRTypeRep $ trep {ty_res = ty_res trep `strengthen` F.ofReft r }
   where
-     go bs (Tick _ e) = go bs e
-     go bs (Lam x e) | isTyVar x               = go bs e
-     go bs (Lam x e) | isClassPred (varType x) = go bs e
-     go bs (Lam x e) = go (bs++[x]) e
-     go bs (Case  (Var x) _ _ alts)  = goalt x bs  <$> alts
-     go bs e          = [Axiom (v, Nothing) bs (varType <$> bs) (foldl App (Var v) (Var <$> bs)) e]
-
-     goalt x bs (DataAlt c, ys, e) = let vs = [b | b<- bs , b /= x] ++ ys in
-        Axiom (v, Just c) vs (varType <$> vs) (mkApp bs x c ys) $ simplify e
-     goalt _ _  (LitAlt _,  _,  _) = todo Nothing "defAxioms: goalt Lit"
-     goalt _ _  (DEFAULT,   _,  _) = todo Nothing "defAxioms: goalt Def"
-
-     mkApp bs x c ys = foldl App (Var v) ((\y -> if y == x then (mkConApp c (Var <$> ys)) else Var y)<$> bs)
-
-
-class Simplifiable a where
-   simplify :: a -> a
-
-instance Simplifiable CoreExpr where
-  simplify (Tick _ e) = simplify e
-  simplify (Lam x e) | isTyVar x = simplify e
-  simplify (Lam x e) | isClassPred (varType x) = simplify e
-  simplify (Lam x e) = Lam x $ simplify e
-  simplify (Let b e) = unANF (simplify b) (simplify e)
-  simplify (Case e v t alts) = Case e v t alts
-  simplify (Cast e _) = simplify e
-  simplify (App e (Type _)) = simplify e
-  simplify (App e (Var x)) | isClassPred (varType x) = simplify e
-  simplify (App f e) = App (simplify f) (simplify e)
-  simplify e@(Var _) = e
-  simplify e = todo Nothing ("simplify" ++ showPpr e)
-
-unANF (NonRec x ex) e | L.isPrefixOf "lq_anf" (show x)
-  = subst (x, ex) e
-unANF b e = Let b e
+    trep = toRTypeRep t
 
-instance Simplifiable CoreBind where
-  simplify (NonRec x e) = NonRec x $ simplify e
-  simplify (Rec xes)    = Rec (second simplify <$> xes)
+updateLMap :: LocSymbol -> LocSymbol -> Var -> BareM ()
+updateLMap x y vv
+  | val x /= val y && isFun (varType vv)
+  = insertLogicEnv ("UPDATELMAP: vv =" ++ show vv) x ys (F.eApps (F.EVar $ val y) (F.EVar <$> ys))
+  | otherwise
+  = return ()
+  where
+    nargs = dropWhile isClassType $ ty_args trep
+    trep  = toRTypeRep ((ofType $ varType vv) :: RRType ())
+    ys    = zipWith (\i _ -> symbol ("x" ++ show i)) [1..] nargs
 
+    isFun (FunTy _ _)    = True
+    isFun (ForAllTy _ t) = isFun t
+    isFun  _             = False
 
 class Subable a where
   subst :: (Var, CoreExpr) -> a -> a
 
+instance Subable Var where
+  subst (x, ex) z | x == z, Var y <- ex = y
+                  | otherwise           = z
+
 instance Subable CoreExpr where
-  subst (x, ex) (Var y) | x == y    = ex
-                        | otherwise = Var y
-  subst su (App f e) = App (subst su f) (subst su e)
-  subst su (Lam x e) = Lam x (subst su e)
-  subst _ _          = todo Nothing "Subable"
+  subst (x, ex) (Var y)
+    | x == y    = ex
+    | otherwise = Var y
+  subst su (App f e)
+    = App (subst su f) (subst su e)
+  subst su (Lam x e)
+    = Lam x (subst su e)
+  subst su (Case e x t alts)
+    = Case (subst su e) x t (subst su <$> alts)
+  subst su (Let (Rec xes) e)
+    = Let (Rec (mapSnd (subst su) <$> xes)) (subst su e)
+  subst su (Let (NonRec x ex) e)
+    = Let (NonRec x (subst su ex)) (subst su e)
+  subst su (Cast e t)
+    = Cast (subst su e) t
+  subst su (Tick t e)
+    = Tick t (subst su e)
+  subst _ (Lit l)
+    = Lit l
+  subst _ (Coercion c)
+    = Coercion c
+  subst _ (Type t)
+    = Type t
 
+instance Subable CoreAlt where
+  subst su (c, xs, e) = (c, xs, subst su e)
+
 -- | Specification for Haskell function
-axiomType :: LocSymbol -> Type -> SpecType
-axiomType s τ = fromRTypeRep $ t{ty_res = res, ty_binds = xs}
+axiomType
+  :: (TyConable c) => LocSymbol -> Maybe SpecType -> RType c tv RReft
+  -> RType c tv RReft
+axiomType s _mbT t = fromRTypeRep (tr {ty_res = res, ty_binds = xs})
   where
-    t  = toRTypeRep $ ofType τ
-    ys = dropWhile isClassType $ ty_args t
-    xs = (\i -> symbol ("x" ++ show i)) <$> [1..(length ys)]
-    x  = F.vv_
-
-    res = ty_res t `strengthen` MkUReft ref mempty mempty
-
-    ref = F.Reft (x, F.PAtom F.Eq (F.EVar x) (mkApp xs))
-
-    mkApp = F.mkEApp s . map F.EVar
+    res           = strengthen (ty_res tr) (singletonApp s ys)
+    ys            = fst $ unzip $ dropWhile (isClassType . snd) xts
+    xts           = safeZip "axiomBinds" xs (ty_args tr)
+    xs            = zipWith unDummy bs [1..]
+    tr            = toRTypeRep t
+    bs            = ty_binds tr
 
+unDummy :: F.Symbol -> Int -> F.Symbol
+unDummy x i
+  | x /= F.dummySymbol = x
+  | otherwise          = symbol ("lq" ++ show i)
 
--- | Type for uninterpreted function that approximated Haskell function into logic
-ufType :: (F.Reftable r) => Type -> RRType r
-ufType τ = fromRTypeRep $ t{ty_args = args, ty_binds = xs, ty_refts = rs}
+singletonApp :: F.Symbolic a => LocSymbol -> [a] -> UReft F.Reft
+singletonApp s ys = MkUReft r mempty mempty
   where
-    t          = toRTypeRep $ ofType τ
-    (args, xs, rs) = unzip3 $ dropWhile (isClassType . fst3) $ zip3 (ty_args t) (ty_binds t) (ty_refts t)
-
-
-simplesymbol :: CoreBndr -> Symbol
-simplesymbol = symbol . getName
+    r             = F.exprReft (F.mkEApp s (F.eVar <$> ys))
diff --git a/src/Language/Haskell/Liquid/Bare/Check.hs b/src/Language/Haskell/Liquid/Bare/Check.hs
--- a/src/Language/Haskell/Liquid/Bare/Check.hs
+++ b/src/Language/Haskell/Liquid/Bare/Check.hs
@@ -1,6 +1,9 @@
-{-# LANGUAGE ParallelListComp #-}
+{-# LANGUAGE ParallelListComp    #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE TupleSections       #-}
+{-# LANGUAGE RecordWildCards     #-}
+{-# LANGUAGE OverloadedStrings   #-}
 
 module Language.Haskell.Liquid.Bare.Check (
     checkGhcSpec
@@ -9,45 +12,47 @@
   , checkTy
   ) where
 
-import Debug.Trace
+import           BasicTypes
+import           DataCon
+import           Id
+import           Name                                      (getSrcSpan)
+import           Prelude                                   hiding (error)
+import           TyCon
+import           Var
+import           TypeRep (Type(TyConApp, TyVarTy))
 
+import           Control.Applicative                       ((<|>))
+import           Control.Arrow                             ((&&&))
 
-import Prelude hiding (error)
-import DataCon
-import Name (getSrcSpan)
-import TyCon
-import Id
-import Var
+import           Data.Maybe
+import           Data.Function                             (on)
+import           Text.PrettyPrint.HughesPJ
 
-import Control.Applicative ((<|>))
-import Control.Arrow ((&&&))
+import qualified Data.List                                 as L
+import qualified Data.HashMap.Strict                       as M
 
-import Data.Maybe
-import Data.Function (on)
-import Text.PrettyPrint.HughesPJ
+import           Language.Fixpoint.Misc                    (applyNonNull, group, safeHead, mapSnd)
+import           Language.Fixpoint.SortCheck               (checkSorted, checkSortedReftFull, checkSortFull)
+import           Language.Fixpoint.Types                   hiding (Error, R)
 
-import qualified Data.List           as L
-import qualified Data.HashMap.Strict as M
+import           Language.Haskell.Liquid.GHC.Misc          (realTcArity, showPpr, fSrcSpan, sourcePosSrcSpan)
+import           Language.Haskell.Liquid.Misc              (snd4)
+import           Language.Haskell.Liquid.Types.PredType    (pvarRType)
+import           Language.Haskell.Liquid.Types.PrettyPrint (pprintSymbol)
+import           Language.Haskell.Liquid.Types.RefType     (classBinds, ofType, rTypeSort, rTypeSortedReft, subsTyVars_meet, toType)
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.WiredIn
 
-import Language.Fixpoint.Misc (applyNonNull, group, safeHead)
-import Language.Fixpoint.SortCheck  (checkSorted, checkSortedReftFull, checkSortFull)
-import Language.Fixpoint.Types      hiding (Error, R)
 
-import Language.Haskell.Liquid.GHC.Misc (realTcArity, showPpr, fSrcSpan, sourcePosSrcSpan)
-import Language.Haskell.Liquid.Misc (snd4, mapSnd)
-import Language.Haskell.Liquid.Types.PredType (pvarRType)
-import Language.Haskell.Liquid.Types.PrettyPrint (pprintSymbol)
-import Language.Haskell.Liquid.Types.RefType (classBinds, ofType, rTypeSort, rTypeSortedReft, subsTyVars_meet, toType)
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.WiredIn
 
+import qualified Language.Haskell.Liquid.Measure           as Ms
 
+import           Language.Haskell.Liquid.Bare.DataType     (dataConSpec)
+import           Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.SymSort      (txRefSort)
 
-import qualified Language.Haskell.Liquid.Measure as Ms
+import           Debug.Trace (trace)
 
-import Language.Haskell.Liquid.Bare.DataType (dataConSpec)
-import Language.Haskell.Liquid.Bare.Env
-import Language.Haskell.Liquid.Bare.SymSort (txRefSort)
 
 ----------------------------------------------------------------------------------------------
 ----- Checking GhcSpec -----------------------------------------------------------------------
@@ -60,66 +65,83 @@
 
 checkGhcSpec specs env sp =  applyNonNull (Right sp) Left errors
   where
-    errors           =  mapMaybe (checkBind "constructor"  emb tcEnv env) (dcons      sp)
-                     ++ mapMaybe (checkBind "measure"      emb tcEnv env) (meas       sp)
-                     ++ mapMaybe (checkBind "assumed type" emb tcEnv env) (asmSigs    sp)
-                     ++ mapMaybe (checkBind "class method" emb tcEnv env) (clsSigs    sp)
-                     ++ mapMaybe (checkInv  emb tcEnv env)               (invariants sp)
-                     ++ checkIAl  emb tcEnv env (ialiases   sp)
+    errors           =  mapMaybe (checkBind allowHO "constructor"  emb tcEnv env) (dcons      sp)
+                     ++ mapMaybe (checkBind allowHO "measure"      emb tcEnv env) (gsMeas       sp)
+                     ++ mapMaybe (checkBind allowHO "assumed type" emb tcEnv env) (gsAsmSigs    sp)
+                     ++ mapMaybe (checkBind allowHO "class method" emb tcEnv env) (clsSigs    sp)
+                     ++ mapMaybe (checkInv allowHO emb tcEnv env)                 (gsInvariants sp)
+                     ++ checkIAl allowHO emb tcEnv env (gsIaliases   sp)
                      ++ checkMeasures emb env ms
-                     ++ checkClassMeasures (measures sp)
+                     ++ checkClassMeasures (gsMeasures sp)
                      ++ mapMaybe checkMismatch                     sigs
-                     ++ checkDuplicate                             (tySigs sp)
-                     ++ checkQualifiers env                        (qualifiers sp)
-                     ++ checkDuplicate                             (asmSigs sp)
-                     ++ checkDupIntersect                          (tySigs sp) (asmSigs sp)
+                     ++ checkDuplicate                             (gsTySigs sp)
+                     ++ checkQualifiers env                        (gsQualifiers sp)
+                     ++ checkDuplicate                             (gsAsmSigs sp)
+                     ++ checkDupIntersect                          (gsTySigs sp) (gsAsmSigs sp)
                      ++ checkRTAliases "Type Alias" env            tAliases
                      ++ checkRTAliases "Pred Alias" env            eAliases
-                     ++ checkDuplicateFieldNames                   (dconsP sp)
-                     ++ checkRefinedClasses                        (concatMap (Ms.classes . snd) specs) (concatMap (Ms.rinstance . snd) specs)
-
-
-    tAliases         =  concat [Ms.aliases sp  | (_, sp) <- specs]
-    eAliases         =  concat [Ms.ealiases sp | (_, sp) <- specs]
-    dcons spec       =  [(v, Loc l l' t) | (v, t)   <- dataConSpec (dconsP spec)
-                                         | (_, dcp) <- dconsP spec
-                                         , let l     = dc_loc  dcp
-                                         , let l'    = dc_locE dcp
-                                         ]
-    emb              =  tcEmbeds sp
-    tcEnv            =  tyconEnv sp
-    ms               =  measures sp
-    clsSigs sp       =  [ (v, t) | (v, t) <- tySigs sp, isJust (isClassOpId_maybe v) ]
-    sigs             =  tySigs sp ++ asmSigs sp
+                     ++ checkDuplicateFieldNames                   (gsDconsP sp)
+                     -- NV TODO: allow instances of refined classes to be refined
+                     -- but make sure that all the specs are checked.
+                     -- ++ checkRefinedClasses                        rClasses rInsts
+                     ++ checkSizeFun emb env                        (gsTconsP sp)
+    _rClasses         = concatMap (Ms.classes   . snd) specs
+    _rInsts           = concatMap (Ms.rinstance . snd) specs
+    tAliases         = concat [Ms.aliases sp  | (_, sp) <- specs]
+    eAliases         = concat [Ms.ealiases sp | (_, sp) <- specs]
+    dcons spec       = [(v, Loc l l' t) | (v, t)   <- dataConSpec (gsDconsP spec)
+                                        | (_, dcp) <- gsDconsP spec
+                                        , let l     = dc_loc  dcp
+                                        , let l'    = dc_locE dcp ]
+    emb              = gsTcEmbeds sp
+    tcEnv            = gsTyconEnv sp
+    ms               = gsMeasures sp
+    clsSigs sp       = [ (v, t) | (v, t) <- gsTySigs sp, isJust (isClassOpId_maybe v) ]
+    sigs             = gsTySigs sp ++ gsAsmSigs sp
+    allowHO          = higherOrderFlag sp
 
 
 checkQualifiers :: SEnv SortedReft -> [Qualifier] -> [Error]
 checkQualifiers = mapMaybe . checkQualifier
 
 checkQualifier       :: SEnv SortedReft -> Qualifier -> Maybe Error
-checkQualifier env q =  mkE <$> checkSortFull γ boolSort  (q_body q)
-  where γ   = foldl (\e (x, s) -> insertSEnv x (RR s mempty) e) env (q_params q ++ wiredSortedSyms)
-        mkE = ErrBadQual (sourcePosSrcSpan $ q_pos q) (pprint $ q_name q)
+checkQualifier env q =  mkE <$> checkSortFull γ boolSort  (qBody q)
+  where γ   = foldl (\e (x, s) -> insertSEnv x (RR s mempty) e) env (qParams q ++ wiredSortedSyms)
+        mkE = ErrBadQual (sourcePosSrcSpan $ qPos q) (pprint $ qName q)
 
-checkRefinedClasses :: [RClass BareType] -> [RInstance BareType] -> [Error]
-checkRefinedClasses definitions instances
+
+checkSizeFun :: TCEmb TyCon -> SEnv SortedReft -> [(TyCon, TyConP)] -> [Error]
+checkSizeFun emb env tys = mkError <$> mapMaybe go tys
+  where
+    mkError ((f, tc, tcp), msg)  = ErrTyCon (sourcePosSrcSpan $ ty_loc tcp)
+                                   (text "Size function" <+> pprint (f x) <+> text "should have type int." $+$   msg)
+                                   (pprint tc)
+    go (tc, tcp)      = case sizeFun tcp of
+                          Nothing  -> Nothing
+                          Just f   -> checkWFSize (szFun f) tc tcp
+
+    checkWFSize f tc tcp = ((f, tc, tcp),) <$> checkSortFull (insertSEnv x (mkTySort tc) env) intSort (f x)
+    x                    = "x" :: Symbol
+    mkTySort tc          = rTypeSortedReft emb (ofType $ TyConApp tc (TyVarTy <$> tyConTyVars tc) :: RRType ())
+
+_checkRefinedClasses :: [RClass (Located BareType)] -> [RInstance (Located BareType)] -> [Error]
+_checkRefinedClasses definitions instances
   = mkError <$> duplicates
   where
     duplicates
       = mapMaybe checkCls (rcName <$> definitions)
     checkCls cls
       = case findConflicts cls of
-          [] ->
-            Nothing
-          conflicts ->
-            Just (cls, conflicts)
+          []        -> Nothing
+          conflicts -> Just (cls, conflicts)
     findConflicts cls
       = filter ((== cls) . riclass) instances
 
     mkError (cls, conflicts)
-      = ErrRClass (sourcePosSrcSpan $ loc cls) (pprint cls) (ofConflict <$> conflicts)
+      = ErrRClass (sourcePosSrcSpan $ loc $ btc_tc cls)
+                  (pprint cls) (ofConflict <$> conflicts)
     ofConflict
-      = sourcePosSrcSpan . loc . riclass &&& pprint . ritype
+      = sourcePosSrcSpan . loc . btc_tc . riclass &&& pprint . ritype
 
 checkDuplicateFieldNames :: [(DataCon, DataConP)]  -> [Error]
 checkDuplicateFieldNames = mapMaybe go
@@ -138,17 +160,23 @@
                 | otherwise = go (x:xs)
     go _                    = Nothing
 
-checkInv :: TCEmb TyCon -> TCEnv -> SEnv SortedReft -> Located SpecType -> Maybe Error
-checkInv emb tcEnv env t   = checkTy err emb tcEnv env t
+checkInv :: Bool -> TCEmb TyCon -> TCEnv -> SEnv SortedReft -> (Maybe Var, Located SpecType) -> Maybe Error
+checkInv allowHO emb tcEnv env (_, t)   = checkTy allowHO err emb tcEnv env t
   where
     err              = ErrInvt (sourcePosSrcSpan $ loc t) (val t)
 
-checkIAl :: TCEmb TyCon -> TCEnv -> SEnv SortedReft -> [(Located SpecType, Located SpecType)] -> [Error]
-checkIAl emb tcEnv env ials = catMaybes $ concatMap (checkIAlOne emb tcEnv env) ials
+checkIAl :: Bool -> TCEmb TyCon -> TCEnv -> SEnv SortedReft -> [(Located SpecType, Located SpecType)] -> [Error]
+checkIAl allowHO emb tcEnv env ials = catMaybes $ concatMap (checkIAlOne allowHO emb tcEnv env) ials
 
-checkIAlOne emb tcEnv env (t1, t2) = checkEq : (tcheck <$> [t1, t2])
+checkIAlOne :: Bool
+            -> TCEmb TyCon
+            -> TCEnv
+            -> SEnv SortedReft
+            -> (Located SpecType, Located SpecType)
+            -> [Maybe (TError SpecType)]
+checkIAlOne allowHO emb tcEnv env (t1, t2) = checkEq : (tcheck <$> [t1, t2])
   where
-    tcheck t = checkTy (err t) emb tcEnv env t
+    tcheck t = checkTy allowHO (err t) emb tcEnv env t
     err    t = ErrIAl (sourcePosSrcSpan $ loc t) (val t)
     t1'      :: RSort
     t1'      = toRSort $ val t1
@@ -160,23 +188,26 @@
 
 
 -- FIXME: Should _ be removed if it isn't used?
+checkRTAliases :: String -> t -> [RTAlias s a] -> [Error]
 checkRTAliases msg _ as = err1s
   where
     err1s                  = checkDuplicateRTAlias msg as
 
-checkBind :: (PPrint v) => String -> TCEmb TyCon -> TCEnv -> SEnv SortedReft -> (v, Located SpecType) -> Maybe Error
-checkBind s emb tcEnv env (v, t) = checkTy msg emb tcEnv env' t
+checkBind :: (PPrint v) => Bool -> String -> TCEmb TyCon -> TCEnv -> SEnv SortedReft -> (v, Located SpecType) -> Maybe Error
+checkBind allowHO s emb tcEnv env (v, t) = checkTy allowHO msg emb tcEnv env' t
   where
     msg                      = ErrTySpec (fSrcSpan t) (text s <+> pprint v) (val t)
     env'                     = foldl (\e (x, s) -> insertSEnv x (RR s mempty) e) env wiredSortedSyms
 
-checkTerminationExpr :: (Eq v, PPrint v) => TCEmb TyCon -> SEnv SortedReft -> (v, Located SpecType, [Expr])-> Maybe Error
-checkTerminationExpr emb env (v, Loc l _ t, es) = (mkErr <$> go es) <|> (mkErr' <$> go' es)
+checkTerminationExpr :: (Eq v, PPrint v) => TCEmb TyCon -> SEnv SortedReft -> (v, LocSpecType, [Located Expr])-> Maybe Error
+checkTerminationExpr emb env (v, Loc l _ t, les)
+            = (mkErr <$> go es) <|> (mkErr' <$> go' es)
   where
+    es      = val <$> les
     mkErr   = uncurry (ErrTermSpec (sourcePosSrcSpan l) (text "termination expression" <+> pprint v))
     mkErr'  = uncurry (ErrTermSpec (sourcePosSrcSpan l) (text "termination expression is not numeric"))
-    go      = foldl (\err e -> err <|> fmap (e,) (checkSorted env' e)) Nothing
-    go'     = foldl (\err e -> err <|> fmap (e,) (checkSorted env' (cmpZero e))) Nothing
+    go      = foldl (\err e -> err <|> (e,) <$> checkSorted env' e)           Nothing
+    go'     = foldl (\err e -> err <|> (e,) <$> checkSorted env' (cmpZero e)) Nothing
     env'    = foldl (\e (x, s) -> insertSEnv x s e) env'' wiredSortedSyms
     env''   = sr_sort <$> foldl (\e (x,s) -> insertSEnv x s e) env xts
     xts     = concatMap mkClass $ zip (ty_binds trep) (ty_args trep)
@@ -188,15 +219,18 @@
     rSort   = rTypeSortedReft emb
     cmpZero = PAtom Le $ expr (0 :: Int) -- zero
 
-checkTy :: (Doc -> Error) -> TCEmb TyCon -> TCEnv -> SEnv SortedReft -> Located SpecType -> Maybe Error
-checkTy mkE emb tcEnv env t = mkE <$> checkRType emb env (val $ txRefSort tcEnv emb t)
+checkTy :: Bool -> (Doc -> Error) -> TCEmb TyCon -> TCEnv -> SEnv SortedReft -> Located SpecType -> Maybe Error
+checkTy allowHO mkE emb tcEnv env t = mkE <$> checkRType allowHO emb env (val $ txRefSort tcEnv emb t)
 
 checkDupIntersect     :: [(Var, Located SpecType)] -> [(Var, Located SpecType)] -> [Error]
-checkDupIntersect xts mxts = concatMap mkWrn dups
+checkDupIntersect xts asmSigs = concatMap mkWrn {- trace msg -} dups
   where
     mkWrn (x, t)     = pprWrn x (sourcePosSrcSpan $ loc t)
-    dups             = L.intersectBy ((==) `on` fst) mxts xts
+    dups             = L.intersectBy ((==) `on` fst) asmSigs xts
     pprWrn v l       = trace ("WARNING: Assume Overwrites Specifications for "++ show v ++ " : " ++ showPpr l) []
+    -- msg              = "CHECKDUPINTERSECT:" ++ msg1 ++ msg2
+    -- msg1             = "\nCheckd-SIGS:\n" ++ showpp (M.fromList xts)
+    -- msg2             = "\nAssume-SIGS:\n" ++ showpp (M.fromList asmSigs)
 
 checkDuplicate        :: [(Var, Located SpecType)] -> [Error]
 checkDuplicate xts = mkErr <$> dups
@@ -221,6 +255,7 @@
     ok               = tyCompat x (val t)
     err              = errTypeMismatch x t
 
+tyCompat :: Var -> RType RTyCon RTyVar r -> Bool
 tyCompat x t         = lhs == rhs
   where
     lhs :: RSort     = toRSort t
@@ -237,18 +272,27 @@
 ------------------------------------------------------------------------------------------------
 -- | @checkRType@ determines if a type is malformed in a given environment ---------------------
 ------------------------------------------------------------------------------------------------
-checkRType :: (PPrint r, Reftable r) => TCEmb TyCon -> SEnv SortedReft -> RRType (UReft r) -> Maybe Doc
+checkRType :: (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r) => Bool -> TCEmb TyCon -> SEnv SortedReft -> RRType (UReft r) -> Maybe Doc
 ------------------------------------------------------------------------------------------------
 
-checkRType emb env t   =  checkAppTys t
-                      <|> checkAbstractRefs t
-                      <|> efoldReft cb (rTypeSortedReft emb) f insertPEnv env Nothing t
+checkRType allowHO emb env t
+  =   checkAppTys t
+  <|> checkAbstractRefs t
+  <|> efoldReft farg cb (tyToBind emb) (rTypeSortedReft emb) f insertPEnv env Nothing t
   where
     cb c ts            = classBinds (rRCls c ts)
+    farg _ t           = allowHO || isBase t  -- this check should be the same as the one in addCGEnv
     f env me r err     = err <|> checkReft env emb me r
     insertPEnv p γ     = insertsSEnv γ (mapSnd (rTypeSortedReft emb) <$> pbinds p)
     pbinds p           = (pname p, pvarRType p :: RSort) : [(x, tx) | (tx, x, _) <- pargs p]
 
+tyToBind :: TCEmb TyCon -> RTVar RTyVar RSort  -> [(Symbol, SortedReft)]
+tyToBind emb = go . ty_var_info
+  where
+    go (RTVInfo {..}) = [(rtv_name, rTypeSortedReft emb rtv_kind)]
+    go RTVNoInfo      = []
+
+checkAppTys :: RType RTyCon t t1 -> Maybe Doc
 checkAppTys = go
   where
     go (RAllT _ t)      = go t
@@ -266,6 +310,7 @@
     go (RExprArg _)     = Just $ text "Logical expressions cannot appear inside a Haskell type"
     go (RHole _)        = Nothing
 
+checkTcArity :: RTyCon -> Arity -> Maybe Doc
 checkTcArity (RTyCon { rtc_tc = tc }) givenArity
   | expectedArity < givenArity
     = Just $ text "Type constructor" <+> pprint tc
@@ -277,7 +322,7 @@
   where
     expectedArity = realTcArity tc
 
-{- 
+{-
 checkFunRefs t = go t
   where
     go (RAllT _ t)      = go t
@@ -294,8 +339,11 @@
     go (RFun _ t1 t2 r)
       | isTauto r       = go t1 <|> go t2
       | otherwise       = Just $ text "Function types cannot have refinements:" <+> (pprint r)
--} 
+-}
 
+checkAbstractRefs
+  :: (PPrint t, Reftable t, SubsTy RTyVar RSort t) =>
+     RType RTyCon RTyVar (UReft t) -> Maybe Doc
 checkAbstractRefs t = go t
   where
     penv = mkPEnv t
@@ -358,7 +406,7 @@
 
 
 
-checkReft                    :: (PPrint r, Reftable r) => SEnv SortedReft -> TCEmb TyCon -> Maybe (RRType (UReft r)) -> (UReft r) -> Maybe Doc
+checkReft                    :: (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r) => SEnv SortedReft -> TCEmb TyCon -> Maybe (RRType (UReft r)) -> UReft r -> Maybe Doc
 checkReft _   _   Nothing _  = Nothing -- TODO:RPropP/Ref case, not sure how to check these yet.
 checkReft env emb (Just t) _ = (dr $+$) <$> checkSortedReftFull env' r
   where
@@ -390,22 +438,38 @@
   where
     txerror = ErrMeas (sourcePosSrcSpan src) (pprint n)
 
-checkMBody γ emb _ sort (Def _ as c _ bs body) = checkMBody' emb sort γ' body
+checkMBody :: (PPrint r,Reftable r,SubsTy RTyVar RSort r)
+           => SEnv SortedReft
+           -> TCEmb TyCon
+           -> t
+           -> SpecType
+           -> Def (RRType r) DataCon
+           -> Maybe Doc
+checkMBody γ emb _ sort (Def _ as c _ bs body) = checkMBody' emb sort' γ' body
   where
-    γ'   = L.foldl' (\γ (x, t) -> insertSEnv x t γ) γ (ats ++ xts)
-    ats  = (mapSnd (rTypeSortedReft emb) <$> as)
-    xts  = zip (fst <$> bs) $ rTypeSortedReft emb . subsTyVars_meet su <$> ty_args trep
-    trep = toRTypeRep ct
-    su   = checkMBodyUnify (ty_res trep) (last txs)
-    txs  = snd4 $ bkArrowDeep sort
-    ct   = ofType $ dataConUserType c :: SpecType
+    γ'    = L.foldl' (\γ (x, t) -> insertSEnv x t γ) γ (ats ++ xts)
+    ats   = mapSnd (rTypeSortedReft emb) <$> as
+    xts   = zip (fst <$> bs) $ rTypeSortedReft emb . subsTyVars_meet su <$> ty_args trep
+    trep  = toRTypeRep ct
+    su    = checkMBodyUnify (ty_res trep) (last txs)
+    txs   = snd4 $ bkArrowDeep sort
+    ct    = ofType $ dataConUserType c :: SpecType
+    sort' = dropNArgs (length as) sort
 
+checkMBodyUnify
+  :: RType t t2 t1 -> RType c tv r -> [(t2,RType c tv (),RType c tv r)]
 checkMBodyUnify                 = go
   where
     go (RVar tv _) t            = [(tv, toRSort t, t)]
     go t@(RApp {}) t'@(RApp {}) = concat $ zipWith go (rt_args t) (rt_args t')
     go _ _                      = []
 
+checkMBody' :: (PPrint r,Reftable r,SubsTy RTyVar RSort r)
+            => TCEmb TyCon
+            -> RType RTyCon RTyVar r
+            -> SEnv SortedReft
+            -> Body
+            -> Maybe Doc
 checkMBody' emb sort γ body = case body of
     E e   -> checkSortFull γ (rTypeSort emb sort') e
     P p   -> checkSortFull γ boolSort  p
@@ -413,7 +477,16 @@
   where
     -- psort = FApp propFTyCon []
     sty   = rTypeSortedReft emb sort'
-    sort' = ty_res $ toRTypeRep sort
+    sort' = dropNArgs 1 sort
+
+dropNArgs :: Int -> RType RTyCon RTyVar r -> RType RTyCon RTyVar r
+dropNArgs i t = fromRTypeRep $ trep {ty_binds = xs, ty_args = ts, ty_refts = rs}
+  where
+    xs   = drop i $ ty_binds trep
+    ts   = drop i $ ty_args  trep
+    rs   = drop i $ ty_refts trep
+    trep = toRTypeRep t
+
 
 checkClassMeasures :: [Measure SpecType DataCon] -> [Error]
 checkClassMeasures ms = mapMaybe checkOne byTyCon
diff --git a/src/Language/Haskell/Liquid/Bare/DataType.hs b/src/Language/Haskell/Liquid/Bare/DataType.hs
--- a/src/Language/Haskell/Liquid/Bare/DataType.hs
+++ b/src/Language/Haskell/Liquid/Bare/DataType.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE TupleSections     #-}
 
 module Language.Haskell.Liquid.Bare.DataType (
     makeConTypes
@@ -8,44 +8,70 @@
   , makeRecordSelectorSigs
   , dataConSpec
   , meetDataConSpec
+  , makeNumericInfo
   ) where
 
-import Prelude hiding (error)
-import DataCon
-import TyCon
-import Var
-import SrcLoc (SrcSpan)
-import Name (getSrcSpan)
+import           DataCon
+import           Name                                   (getSrcSpan)
+import           Prelude                                hiding (error)
+import           SrcLoc                                 (SrcSpan)
+import           Text.Parsec
+import           TyCon                                  hiding (tyConName)
+import           Var
+import           InstEnv
+import           Class
+import           Data.Maybe
+import           TypeRep
 
-import Data.Maybe
+import qualified Data.List                              as L
+import qualified Data.HashMap.Strict                    as M
 
+import           Language.Fixpoint.Types                (mappendFTC, Symbol, TCEmb, mkSubst, Expr(..), Brel(..), subst, symbolNumInfoFTyCon, dummyPos)
+import           Language.Haskell.Liquid.GHC.Misc       (sourcePos2SrcSpan, symbolTyVar)
+import           Language.Haskell.Liquid.Types.PredType (dataConPSpecType)
+import           Language.Haskell.Liquid.Types.RefType  (mkDataConIdsTy, ofType, rApp, rVar, strengthen, uPVar, uReft, tyConName)
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Types.Meet
+import           Language.Fixpoint.Misc                 (mapSnd)
+import           Language.Haskell.Liquid.Types.Variance
+import           Language.Haskell.Liquid.WiredIn
 
-import qualified Data.List           as L
-import qualified Data.HashMap.Strict as M
+import qualified Language.Haskell.Liquid.Measure        as Ms
 
-import Language.Fixpoint.Types (Symbol, TCEmb, mkSubst, Expr(..), Brel(..), subst)
+import           Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.Lookup
+import           Language.Haskell.Liquid.Bare.OfType
 
-import Language.Haskell.Liquid.GHC.Misc (sourcePos2SrcSpan, symbolTyVar)
-import Language.Haskell.Liquid.Types.PredType (dataConPSpecType)
-import Language.Haskell.Liquid.Types.RefType (mkDataConIdsTy, ofType, rApp, rVar, strengthen, uPVar, uReft)
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Types.Meet
-import Language.Haskell.Liquid.Misc (mapSnd)
-import Language.Haskell.Liquid.Types.Variance
-import Language.Haskell.Liquid.WiredIn
 
-import qualified Language.Haskell.Liquid.Measure as Ms
 
-import Language.Haskell.Liquid.Bare.Env
-import Language.Haskell.Liquid.Bare.Lookup
-import Language.Haskell.Liquid.Bare.OfType
+makeNumericInfo :: Maybe [ClsInst] -> TCEmb TyCon -> TCEmb TyCon
+makeNumericInfo Nothing x   = x
+makeNumericInfo (Just is) x = foldl makeNumericInfoOne x is
 
--- import Debug.Trace
+makeNumericInfoOne :: TCEmb TyCon -> ClsInst -> TCEmb TyCon
+makeNumericInfoOne m is
+  | isFracCls $ classTyCon $ is_cls is, Just tc <- instanceTyCon is
+  = M.insertWith (flip mappendFTC) tc (ftc tc True True) m
+  | isNumCls $ classTyCon $ is_cls is, Just tc <- instanceTyCon is
+  = M.insertWith (flip mappendFTC) tc (ftc tc True False) m
+  | otherwise
+  = m
+  where
+    ftc c = symbolNumInfoFTyCon (dummyLoc $ tyConName c)
 
+instanceTyCon :: ClsInst -> Maybe TyCon
+instanceTyCon = go . is_tys
+  where
+    go [TyConApp c _] = Just c
+    go _              = Nothing
+
 -----------------------------------------------------------------------
 -- Bare Predicate: DataCon Definitions --------------------------------
 -----------------------------------------------------------------------
 
+makeConTypes
+  :: (ModName,Ms.Spec ty bndr)
+  -> BareM ([(TyCon,TyConP)],[[(DataCon,Located DataConP)]])
 makeConTypes (name,spec) = inModule name $ makeConTypes' (Ms.dataDecls spec) (Ms.dvariance spec)
 
 makeConTypes' :: [DataDecl] -> [(LocSymbol, [Variance])] -> BareM ([(TyCon, TyConP)], [[(DataCon, Located DataConP)]])
@@ -92,7 +118,7 @@
        let varInfo = L.nub $  concatMap (getPsSig initmap True) tys
        let defaultPs = varSignToVariance varInfo <$> [0 .. (length πs - 1)]
        let (tvarinfo, pvarinfo) = f defaultPs
-       return ((tc', TyConP αs πs ls tvarinfo pvarinfo sfun), (mapSnd (Loc lc lc') <$> cts'))
+       return ((tc', TyConP lc αs πs ls tvarinfo pvarinfo sfun), (mapSnd (Loc lc lc') <$> cts'))
     where
        αs          = RTV . symbolTyVar <$> as
        n           = length αs
@@ -110,13 +136,15 @@
 
 ofBDataDecl Nothing (Just (tc, is))
   = do tc'        <- lookupGhcTyCon tc
-       return ((tc', TyConP [] [] [] tcov tcontr Nothing), [])
+       return ((tc', TyConP srcpos [] [] [] tcov tcontr Nothing), [])
   where
     (tcov, tcontr) = (is, [])
+    srcpos = dummyPos "LH.DataType.Variance"
 
 ofBDataDecl Nothing Nothing
   = panic Nothing "Bare.DataType.ofBDataDecl called on invalid inputs"
 
+getPsSig :: [(UsedPVar, a)] -> Bool -> SpecType -> [(a, Bool)]
 getPsSig m pos (RAllT _ t)
   = getPsSig m pos t
 getPsSig m pos (RApp _ ts rs r)
@@ -133,13 +161,24 @@
 getPsSig _ _ z
   = panic Nothing $ "getPsSig" ++ show z
 
+getPsSigPs :: [(UsedPVar, a)] -> Bool -> SpecProp -> [(a, Bool)]
 getPsSigPs m pos (RProp _ (RHole r)) = addps m pos r
 getPsSigPs m pos (RProp _ t) = getPsSig m pos t
 
+addps :: [(UsedPVar, a)] -> b -> UReft t -> [(a, b)]
 addps m pos (MkUReft _ ps _) = (flip (,)) pos . f  <$> pvars ps
   where f = fromMaybe (panic Nothing "Bare.addPs: notfound") . (`L.lookup` m) . uPVar
 
 -- TODO:EFFECTS:ofBDataCon
+ofBDataCon :: SourcePos
+           -> SourcePos
+           -> TyCon
+           -> [RTyVar]
+           -> [PVar BSort]
+           -> [Symbol]
+           -> [PVar RSort]
+           -> (Located Symbol,[(Symbol,BareType)])
+           -> BareM (DataCon, DataConP)
 ofBDataCon l l' tc αs ps ls πs (c, xts)
   = do c'      <- lookupGhcDataCon c
        ts'     <- mapM (mkSpecType' l ps) ts
@@ -151,6 +190,7 @@
        rs       = [rVar α | RTV α <- αs]
 
 
+makeTyConEmbeds :: (ModName,Ms.Spec ty bndr) -> BareM (TCEmb TyCon)
 makeTyConEmbeds (mod, spec)
   = inModule mod $ makeTyConEmbeds' $ Ms.embeds spec
 
@@ -164,16 +204,17 @@
   where
   makeOne (dc, Loc l l' dcp)
     | null (dataConFieldLabels dc)
+    -- do not make record selectors for data cons with functional arguments
+    || any (isFunTy . snd) (args)
     = return []
     | otherwise = do
         fs <- mapM lookupGhcVar (dataConFieldLabels dc)
-        return (fs `zip` ts)
+        return $ zip fs ts
     where
-    ts   = [ Loc l l' (mkArrow (freeTyVars dcp) [] (freeLabels dcp)
+    ts = [ Loc l l' (mkArrow (makeRTVar <$> freeTyVars dcp) [] (freeLabels dcp)
                                [(z, res, mempty)]
                                (dropPreds (subst su t `strengthen` mt)))
            | (x, t) <- reverse args -- NOTE: the reverse here is correct
-           , not (isFunTy t) -- NOTE: we only have measures for non-function fields
            , let vv = rTypeValueVar t
              -- the measure singleton refinement, eg `v = getBar foo`
            , let mt = uReft (vv, PAtom Eq (EVar vv) (EApp (EVar x) (EVar z)))
diff --git a/src/Language/Haskell/Liquid/Bare/Env.hs b/src/Language/Haskell/Liquid/Bare/Env.hs
--- a/src/Language/Haskell/Liquid/Bare/Env.hs
+++ b/src/Language/Haskell/Liquid/Bare/Env.hs
@@ -7,43 +7,48 @@
 
   , BareEnv(..)
 
-  , TInline(..), InlnEnv
+  -- , TInline(..)
+  , InlnEnv
 
   , inModule
   , withVArgs
 
   , setRTAlias
   , setREAlias
+  , setEmbeds
 
   , execBare
 
   , insertLogicEnv
   , insertAxiom
+  , addDefs
   ) where
 
-import Prelude hiding (error)
-import HscTypes
-import TyCon
-import Var
+import           HscTypes
+import           Prelude                              hiding (error)
+import           Text.Parsec.Pos
+import           TyCon
+import           Var
 
-import Control.Monad.Except
-import Control.Monad.State
-import Control.Monad.Writer
+import           Control.Monad.Except
+import           Control.Monad.State
+import           Control.Monad.Writer
 
-import qualified Control.Exception   as Ex
-import qualified Data.HashMap.Strict as M
+import qualified Control.Exception                    as Ex
+import qualified Data.HashMap.Strict                  as M
+import qualified Data.HashSet                         as S
 
 
-import Language.Fixpoint.Types (Expr(..), Symbol, symbol)
+import           Language.Fixpoint.Types              (Expr(..), Symbol, symbol, TCEmb)
 
-import Language.Haskell.Liquid.UX.Errors ()
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Types.Bounds
+import           Language.Haskell.Liquid.UX.Errors    ()
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Types.Bounds
 
 
------------------------------------------------------------------------------------
--- | Error-Reader-IO For Bare Transformation --------------------------------------
------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Error-Reader-IO For Bare Transformation -----------------------------------
+--------------------------------------------------------------------------------
 
 -- FIXME: don't use WriterT [], very slow
 type BareM = WriterT [Warn] (ExceptT Error (StateT BareEnv IO))
@@ -52,34 +57,40 @@
 
 type TCEnv = M.HashMap TyCon RTyCon
 
-type InlnEnv = M.HashMap Symbol TInline
-
-data TInline = TI { tiargs :: [Symbol]
-                  , tibody :: Expr
-                  } deriving (Show)
-
-
+type InlnEnv = M.HashMap Symbol LMap
 
-data BareEnv = BE { modName  :: !ModName
-                  , tcEnv    :: !TCEnv
-                  , rtEnv    :: !RTEnv
-                  , varEnv   :: ![(Symbol,Var)]
-                  , hscEnv   :: HscEnv
-                  , logicEnv :: LogicMap
-                  , inlines  :: InlnEnv
-                  , bounds   :: RBEnv
-                  }
+data BareEnv = BE
+  { modName  :: !ModName
+  , tcEnv    :: !TCEnv
+  , rtEnv    :: !RTEnv
+  , varEnv   :: ![(Symbol, Var)]
+  , hscEnv   :: HscEnv
+  , logicEnv :: LogicMap
+  , bounds   :: RBEnv
+  , embeds   :: TCEmb TyCon
+  , axSyms   :: M.HashMap Symbol LocSymbol
+  }
 
+setEmbeds :: TCEmb TyCon -> BareM ()
+setEmbeds emb
+  = modify $ \be -> be {embeds = emb}
 
+addDefs :: S.HashSet (Var, Symbol) -> BareM ()
+addDefs ds
+  = modify $ \be -> be {logicEnv = (logicEnv be) {axiom_map =  M.union (axiom_map $ logicEnv be) (M.fromList $ S.toList ds)}}
 
-insertLogicEnv x ys e
-  = modify $ \be -> be {logicEnv = (logicEnv be) {logic_map = M.insert x (LMap x ys e) $ logic_map $ logicEnv be}}
+insertLogicEnv :: String -> LocSymbol -> [Symbol] -> Expr -> BareM ()
+insertLogicEnv _msg x ys e
+  = modify $ \be -> be {logicEnv = (logicEnv be) {logic_map = M.insert (val x) (LMap x ys e) $ logic_map $ logicEnv be}}
 
+insertAxiom :: Var -> Symbol -> BareM ()
 insertAxiom x s
   = modify $ \be -> be {logicEnv = (logicEnv be){axiom_map = M.insert x s $ axiom_map $ logicEnv be}}
 
+setModule :: ModName -> BareEnv -> BareEnv
 setModule m b = b { modName = m }
 
+inModule :: ModName -> BareM b -> BareM b
 inModule m act = do
   old <- gets modName
   modify $ setModule m
@@ -87,6 +98,12 @@
   modify $ setModule old
   return res
 
+withVArgs :: (Foldable t, PPrint a)
+          => SourcePos
+          -> SourcePos
+          -> t a
+          -> BareM b
+          -> BareM b
 withVArgs l l' vs act = do
   old <- gets rtEnv
   mapM_ (mkExprAlias l l' . symbol . showpp) vs
@@ -94,15 +111,14 @@
   modify $ \be -> be { rtEnv = old }
   return res
 
-mkExprAlias l l' v
-  = setRTAlias v (RTA v [] [] (RExprArg (Loc l l' $ EVar $ symbol v)) l l')
-
-setRTAlias s a =
-  modify $ \b -> b { rtEnv = mapRT (M.insert s a) $ rtEnv b }
+mkExprAlias :: SourcePos -> SourcePos -> Symbol -> BareM ()
+mkExprAlias l l' v = setRTAlias v (RTA v [] [] (RExprArg (Loc l l' $ EVar $ symbol v)) l l')
 
+setRTAlias :: Symbol -> RTAlias RTyVar SpecType -> BareM ()
+setRTAlias s a = modify $ \b -> b { rtEnv = mapRT (M.insert s a) $ rtEnv b }
 
-setREAlias s a =
-  modify $ \b -> b { rtEnv = mapRE (M.insert s a) $ rtEnv b }
+setREAlias :: Symbol -> RTAlias Symbol Expr -> BareM ()
+setREAlias s a = modify $ \b -> b { rtEnv = mapRE (M.insert s a) $ rtEnv b }
 
 ------------------------------------------------------------------
 execBare :: BareM a -> BareEnv -> IO (Either Error a)
diff --git a/src/Language/Haskell/Liquid/Bare/Existential.hs b/src/Language/Haskell/Liquid/Bare/Existential.hs
--- a/src/Language/Haskell/Liquid/Bare/Existential.hs
+++ b/src/Language/Haskell/Liquid/Bare/Existential.hs
@@ -73,8 +73,10 @@
        modify $ \st -> st{emap = M.empty}
        return bds
 
+addExists :: SpecType -> State ExSt SpecType
 addExists t = liftM (M.foldlWithKey' addExist t) getBinds
 
+addExist :: SpecType -> Symbol -> (RSort, Expr) -> SpecType
 addExist t x (tx, e) = REx x t' t
   where t' = (ofRSort tx) `strengthen` uTop r
         r  = exprReft e
diff --git a/src/Language/Haskell/Liquid/Bare/Expand.hs b/src/Language/Haskell/Liquid/Bare/Expand.hs
--- a/src/Language/Haskell/Liquid/Bare/Expand.hs
+++ b/src/Language/Haskell/Liquid/Bare/Expand.hs
@@ -1,114 +1,133 @@
-{-# LANGUAGE TupleSections #-}
-
-module Language.Haskell.Liquid.Bare.Expand (
-    expandReft
-  , expandExpr
-  ) where
-
-import Prelude hiding (error)
-
-import Control.Monad.State hiding (forM)
-
-import qualified Data.HashMap.Strict as M
-
-import Language.Fixpoint.Types (Expr(..), Reft(..), mkSubst, subst, eApps, splitEApp)
-
-import Language.Haskell.Liquid.Misc (safeZipWithError)
-import Language.Haskell.Liquid.Types
+{-# LANGUAGE TupleSections        #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleInstances    #-}
 
+module Language.Haskell.Liquid.Bare.Expand ( ExpandAliases (..) ) where
 
-import Language.Haskell.Liquid.Bare.Env
+import           Prelude                          hiding (error)
+import           Control.Monad.State              hiding (forM)
+import qualified Data.HashMap.Strict              as M
+import           Language.Fixpoint.Types          (Expr(..), Reft(..), mkSubst, subst, eApps, splitEApp, Symbol, Subable)
+import           Language.Haskell.Liquid.Misc     (firstMaybes, safeZipWithError)
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Bare.Env
 
---------------------------------------------------------------------------------
--- Expand Reft Preds & Exprs ---------------------------------------------------
---------------------------------------------------------------------------------
+class ExpandAliases a where
+  expand :: a -> BareM a
 
-expandReft :: RReft -> BareM RReft
-expandReft = txPredReft expandExpr
+instance ExpandAliases Expr where
+  expand = expandExpr
 
-txPredReft :: (Expr -> BareM Expr) -> RReft -> BareM RReft
-txPredReft f u = (\r -> u {ur_reft = r}) <$> txPredReft' (ur_reft u)
-  where
-    txPredReft' (Reft (v, ra)) = Reft . (v,) <$> f ra 
+instance ExpandAliases Reft where
+  expand = txPredReft' expandExpr
 
---------------------------------------------------------------------------------
--- Expand Exprs ----------------------------------------------------------------
---------------------------------------------------------------------------------
+instance ExpandAliases SpecType where
+  expand = mapReftM expand
 
+instance ExpandAliases Body where
+  expand (E e)   = E   <$> expand e
+  expand (P e)   = P   <$> expand e
+  expand (R x e) = R x <$> expand e
 
+instance ExpandAliases ty => ExpandAliases (Def ty ctor) where
+  expand (Def f xts c t bxts b) =
+    Def f <$> expand xts
+          <*> pure c
+          <*> expand t
+          <*> expand bxts
+          <*> expand b
 
-expandExpr :: Expr -> BareM Expr
+instance ExpandAliases ty => ExpandAliases (Measure ty ctor) where
+  expand (M n t ds) =
+    M n <$> expand t <*> expand ds
 
-expandExpr e@(EApp _ _)
-  = expandEApp $ splitEApp e 
+instance ExpandAliases DataConP where
+  expand d = do
+    tyRes'    <- expand $ tyRes    d
+    tyConsts' <- expand $ tyConsts d
+    tyArgs'   <- expand $ tyArgs   d
+    return d { tyRes = tyRes', tyConsts = tyConsts', tyArgs = tyArgs' }
 
-expandExpr (ENeg e)
-  = ENeg <$> expandExpr e
-expandExpr (EBin op e1 e2)
-  = EBin op <$> expandExpr e1 <*> expandExpr e2
-expandExpr (EIte p e1 e2)
-  = EIte <$> expandExpr p <*> expandExpr e1 <*> expandExpr e2
-expandExpr (ECst e s)
-  = (`ECst` s) <$> expandExpr e
+instance ExpandAliases RReft where
+  expand = mapM expand
 
-expandExpr e@(EVar _)
-  = return e
-expandExpr e@(ESym _)
-  = return e
-expandExpr e@(ECon _)
-  = return e
+instance (ExpandAliases a) => ExpandAliases (Located a) where
+  expand = mapM expand
 
-expandExpr (PAnd ps)
-  = PAnd <$> mapM expandExpr ps
-expandExpr (POr ps)
-  = POr <$> mapM expandExpr ps
-expandExpr (PNot p)
-  = PNot <$> expandExpr p
-expandExpr (PImp p q)
-  = PImp <$> expandExpr p <*> expandExpr q
-expandExpr (PIff p q)
-  = PIff <$> expandExpr p <*> expandExpr q
-expandExpr (PAll xs p)
-  = PAll xs <$> expandExpr p
-expandExpr (ELam xt e)
-  = ELam xt <$> expandExpr e
+instance (ExpandAliases a) => ExpandAliases (Maybe a) where
+  expand = mapM expand
 
-expandExpr (ETApp e s)
-  = (`ETApp` s) <$> expandExpr e 
-expandExpr (ETAbs e s)
-  = (`ETAbs` s) <$> expandExpr e 
+instance (ExpandAliases a) => ExpandAliases [a] where
+  expand = mapM expand
 
-expandExpr (PAtom b e1 e2)
-  = PAtom b <$> expandExpr e1 <*> expandExpr e2 
+instance (ExpandAliases b) => ExpandAliases (a, b) where
+  expand = mapM expand
 
-expandExpr (PKVar k s)
-  = return $ PKVar k s 
+--------------------------------------------------------------------------------
+-- Expand Reft Preds & Exprs ---------------------------------------------------
+--------------------------------------------------------------------------------
+txPredReft' :: (Expr -> BareM Expr) -> Reft -> BareM Reft
+txPredReft' f (Reft (v, ra)) = Reft . (v,) <$> f ra
 
-expandExpr PGrad
-  = return PGrad
+--------------------------------------------------------------------------------
+-- Expand Exprs ----------------------------------------------------------------
+--------------------------------------------------------------------------------
+expandExpr :: Expr -> BareM Expr
+expandExpr = go
+  where
+    go e@(EApp _ _)    = {- tracepp ("EXPANDEAPP e = " ++ showpp e ) <$> -} expandEApp (splitEApp e)
+    go (EVar x)        = expandSym x
+    go (ENeg e)        = ENeg        <$> go e
+    go (ECst e s)      = (`ECst` s)  <$> go e
+    go (PAnd ps)       = PAnd        <$> mapM go ps
+    go (POr ps)        = POr         <$> mapM go ps
+    go (PNot p)        = PNot        <$> go p
+    go (PAll xs p)     = PAll xs     <$> go p
+    go (PExist s e)    = PExist s    <$> go e
+    go (ELam xt e)     = ELam xt     <$> go e
+    go (ETApp e s)     = (`ETApp` s) <$> go e
+    go (ETAbs e s)     = (`ETAbs` s) <$> go e
+    go (EBin op e1 e2) = EBin op     <$> go e1  <*> go e2
+    go (PImp p q)      = PImp        <$> go p   <*> go q
+    go (PIff p q)      = PIff        <$> go p   <*> go q
+    go (PAtom b e e')  = PAtom b     <$> go e   <*> go e'
+    go (EIte p e1 e2)  = EIte        <$> go p   <*> go e1 <*> go e2
+    -- go e@(EVar _)      = return e
+    go e@(PKVar _ _)   = return e
+    go (PGrad k su e)  = PGrad k su <$> go e 
+    go e@(ESym _)      = return e
+    go e@(ECon _)      = return e
 
-expandExpr (PExist s e)
-  = PExist s <$> expandExpr e 
+expandSym :: Symbol -> BareM Expr
+expandSym s = do
+  s' <- expandSym' s
+  expandEApp (EVar s', [])
 
+expandSym' :: Symbol -> BareM Symbol
+expandSym' s = do
+  axs <- gets axSyms
+  let s' = dropModuleNamesAndUnique s
+  return $ if M.member s' axs then s' else s
 
-expandEApp (EVar f, es)
-  = do env <- gets (exprAliases.rtEnv)
-       case M.lookup f env of
-         Just re ->
-           expandApp re <$> mapM expandExpr es 
-         Nothing ->
-           eApps (EVar f) <$> mapM expandExpr es 
-expandEApp (f, es)
-  = return $ eApps f es 
+expandEApp :: (Expr, [Expr]) -> BareM Expr
+expandEApp (EVar f, es) = do
+  eAs   <- gets (exprAliases . rtEnv)
+  let mBody = firstMaybes [M.lookup f eAs, M.lookup (dropModuleUnique f) eAs]
+  case mBody of
+    Just re -> expandApp re   <$> mapM expandExpr es
+    Nothing -> eApps (EVar f) <$> mapM expandExpr es
+expandEApp (f, es) =
+  return $ eApps f es
 
 --------------------------------------------------------------------------------
--- Expand Alias Application ----------------------------------------------------
+-- | Expand Alias Application --------------------------------------------------
 --------------------------------------------------------------------------------
-
-expandApp re es
-  = subst su $ rtBody re
-  where su  = mkSubst $ safeZipWithError msg (rtVArgs re) es
-        msg = "Malformed alias application" ++ "\n\t"
+expandApp :: Subable ty => RTAlias Symbol ty -> [Expr] -> ty
+expandApp re es = subst su $ rtBody re
+  where
+    su          = mkSubst $ safeZipWithError msg (rtVArgs re) es
+    msg         = "Malformed alias application" ++ "\n\t"
                ++ show (rtName re)
                ++ " defined at " ++ show (rtPos re)
                ++ "\n\texpects " ++ show (length $ rtVArgs re)
diff --git a/src/Language/Haskell/Liquid/Bare/GhcSpec.hs b/src/Language/Haskell/Liquid/Bare/GhcSpec.hs
--- a/src/Language/Haskell/Liquid/Bare/GhcSpec.hs
+++ b/src/Language/Haskell/Liquid/Bare/GhcSpec.hs
@@ -9,167 +9,187 @@
   ) where
 
 -- import Debug.Trace (trace)
-import Prelude hiding (error)
-import CoreSyn hiding (Expr)
-import HscTypes
-import Id
-import NameSet
-import Name
-import TyCon
-import Var
-import TysWiredIn
-
-import DataCon (DataCon)
+import           Prelude                                    hiding (error)
+import           CoreSyn                                    hiding (Expr)
+import qualified CoreSyn
+import           HscTypes
+import           Id
+import           NameSet
+import           Name
+import           TyCon
+import           Var
+import           TysWiredIn
+import           DataCon                                    (DataCon)
+import           InstEnv
 
-import Control.Monad.Reader
-import Control.Monad.State
-import Data.Bifunctor
-import Data.Maybe
+import           Control.Monad.Reader
+import           Control.Monad.State
+import           Data.Bifunctor
+import           Data.Maybe
 
 
-import Control.Monad.Except (catchError)
-import TypeRep (Type(TyConApp))
-
-import qualified Control.Exception   as Ex
-import qualified Data.List           as L
-import qualified Data.HashMap.Strict as M
-import qualified Data.HashSet        as S
-
-import Language.Fixpoint.Misc (thd3)
+import           Control.Monad.Except                       (catchError)
+import           TypeRep                                    (Type(TyConApp))
 
-import Language.Fixpoint.Types hiding (Error)
+import           Text.PrettyPrint.HughesPJ (text)
 
-import Language.Haskell.Liquid.Types.Dictionaries
-import Language.Haskell.Liquid.GHC.Misc (showPpr, getSourcePosE, getSourcePos, sourcePosSrcSpan, isDataConId)
-import Language.Haskell.Liquid.Types.PredType (makeTyConInfo)
-import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Misc (mapSnd)
-import Language.Haskell.Liquid.WiredIn
+import qualified Control.Exception                          as Ex
+import qualified Data.List                                  as L
+import qualified Data.HashMap.Strict                        as M
+import qualified Data.HashSet                               as S
 
+import           Language.Fixpoint.Misc                     (thd3, mapSnd)
+import           Language.Fixpoint.Types                    hiding (Error)
 
+import           Language.Haskell.Liquid.Types.Dictionaries
+import           Language.Haskell.Liquid.Misc               (concatMapM)
+import           Language.Haskell.Liquid.GHC.Misc           (dropModuleUnique, dropModuleNames, showPpr, getSourcePosE, getSourcePos, sourcePosSrcSpan, isDataConId)
+import           Language.Haskell.Liquid.Types.PredType     (makeTyConInfo)
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.WiredIn
 
-import qualified Language.Haskell.Liquid.Measure as Ms
+import qualified Language.Haskell.Liquid.Measure            as Ms
 
-import Language.Haskell.Liquid.Bare.Check
-import Language.Haskell.Liquid.Bare.DataType
-import Language.Haskell.Liquid.Bare.Env
-import Language.Haskell.Liquid.Bare.Existential
-import Language.Haskell.Liquid.Bare.Measure
-import Language.Haskell.Liquid.Bare.Axiom
-import Language.Haskell.Liquid.Bare.Misc (makeSymbols, mkVarExpr)
-import Language.Haskell.Liquid.Bare.Plugged
-import Language.Haskell.Liquid.Bare.RTEnv
-import Language.Haskell.Liquid.Bare.Spec
-import Language.Haskell.Liquid.Bare.SymSort
-import Language.Haskell.Liquid.Bare.RefToLogic
-import Language.Haskell.Liquid.Bare.Lookup (lookupGhcTyCon)
+import           Language.Haskell.Liquid.Bare.Check
+import           Language.Haskell.Liquid.Bare.DataType
+import           Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.Existential
+import           Language.Haskell.Liquid.Bare.Measure
+import           Language.Haskell.Liquid.Bare.Axiom
+import           Language.Haskell.Liquid.Bare.Misc          (makeSymbols, mkVarExpr)
+import           Language.Haskell.Liquid.Bare.Plugged
+import           Language.Haskell.Liquid.Bare.RTEnv
+import           Language.Haskell.Liquid.Bare.Spec
+import           Language.Haskell.Liquid.Bare.Expand
+import           Language.Haskell.Liquid.Bare.SymSort
+import           Language.Haskell.Liquid.Bare.Lookup        (lookupGhcTyCon)
 
 --------------------------------------------------------------------------------
 makeGhcSpec :: Config
             -> ModName
             -> [CoreBind]
+            -> Maybe [ClsInst]
             -> [Var]
             -> [Var]
             -> NameSet
             -> HscEnv
             -> Either Error LogicMap
-            -> [(ModName,Ms.BareSpec)]
+            -> [(ModName, Ms.BareSpec)]
             -> IO GhcSpec
 --------------------------------------------------------------------------------
-makeGhcSpec cfg name cbs vars defVars exports env lmap specs
-
-  = do sp <- throwLeft =<< execBare act initEnv
-       let renv = ghcSpecEnv sp
-       throwLeft . checkGhcSpec specs renv $ postProcess cbs renv sp
+makeGhcSpec cfg name cbs instenv vars defVars exports env lmap specs = do
+  sp <- throwLeft =<< execBare act initEnv
+  let renv = ghcSpecEnv sp
+  throwLeft . checkGhcSpec specs renv $ postProcess cbs renv sp
   where
-    act       = makeGhcSpec' cfg cbs vars defVars exports specs
+    act       = makeGhcSpec' cfg cbs instenv vars defVars exports specs
     throwLeft = either Ex.throw return
-    initEnv   = BE name mempty mempty mempty env lmap' mempty mempty
-    lmap'     = case lmap of {Left e -> Ex.throw e; Right x -> x `mappend` listLMap}
+    initEnv   = BE name mempty mempty mempty env lmap' mempty mempty axs
+    axs       = initAxSymbols name specs
+    lmap'     = case lmap of { Left e -> Ex.throw e; Right x -> x `mappend` listLMap}
 
-listLMap = toLogicMap [(nilName, [], hNil),
-                       (consName, [x, xs], hCons (EVar <$> [x,xs]))
-                      ]
+initAxSymbols :: ModName -> [(ModName, Ms.BareSpec)] -> M.HashMap Symbol LocSymbol
+initAxSymbols name = locMap . Ms.axioms . fromMaybe mempty . lookup name
   where
-    x  = symbol "x"
-    xs = symbol "xs"
-    hNil    = mkEApp (dummyLoc $ symbol nilDataCon ) []
-    hCons   = mkEApp (dummyLoc $ symbol consDataCon)
+    locMap xs      = M.fromList [ (val x, x) | x <- S.toList xs]
 
+listLMap :: LogicMap
+listLMap  = toLogicMap [ (dummyLoc nilName , []     , hNil)
+                       , (dummyLoc consName, [x, xs], hCons (EVar <$> [x, xs])) ]
+  where
+    x     = symbol "x"
+    xs    = symbol "xs"
+    hNil  = mkEApp (dcSym nilDataCon ) []
+    hCons = mkEApp (dcSym consDataCon)
+    dcSym = dummyLoc . dropModuleUnique . symbol
+
 postProcess :: [CoreBind] -> SEnv SortedReft -> GhcSpec -> GhcSpec
 postProcess cbs specEnv sp@(SP {..})
-  = sp { tySigs = tySigs', texprs = ts, asmSigs = asmSigs', dicts = dicts', invariants = invs', meas = meas', inSigs = inSigs' }
+  = sp { gsTySigs     = mapSnd addTCI <$> sigs
+       , gsInSigs     = mapSnd addTCI <$> insigs
+       , gsAsmSigs    = mapSnd addTCI <$> assms
+       , gsInvariants = mapSnd addTCI <$> gsInvariants
+       , gsLits       = txSort        <$> gsLits
+       , gsMeas       = txSort        <$> gsMeas
+       , gsDicts      = dmapty addTCI'    gsDicts
+       , gsTexprs     = ts
+       }
   where
-    (sigs, ts')   = replaceLocalBinds tcEmbeds tyconEnv tySigs texprs specEnv cbs
-    (assms, ts'') = replaceLocalBinds tcEmbeds tyconEnv asmSigs ts'   specEnv cbs
-    (insigs, ts)  = replaceLocalBinds tcEmbeds tyconEnv inSigs  ts''  specEnv cbs
-    tySigs'     = mapSnd (addTyConInfo tcEmbeds tyconEnv <$>) <$> sigs
-    asmSigs'    = mapSnd (addTyConInfo tcEmbeds tyconEnv <$>) <$> assms
-    inSigs'     = mapSnd (addTyConInfo tcEmbeds tyconEnv <$>) <$> insigs
-    dicts'      = dmapty (addTyConInfo tcEmbeds tyconEnv) dicts
-    invs'       = (addTyConInfo tcEmbeds tyconEnv <$>) <$> invariants
-    meas'       = mapSnd (fmap (addTyConInfo tcEmbeds tyconEnv) . txRefSort tyconEnv tcEmbeds) <$> meas
+    (sigs,   ts')     = replaceLocBinds gsTySigs  gsTexprs
+    (assms,  ts'')    = replaceLocBinds gsAsmSigs ts'
+    (insigs, ts)      = replaceLocBinds gsInSigs  ts''
+    replaceLocBinds   = replaceLocalBinds allowHO gsTcEmbeds gsTyconEnv specEnv cbs
+    txSort            = mapSnd (addTCI . txRefSort gsTyconEnv gsTcEmbeds)
+    addTCI            = (addTCI' <$>)
+    addTCI'           = addTyConInfo gsTcEmbeds gsTyconEnv
+    allowHO           = higherOrderFlag gsConfig
 
 ghcSpecEnv :: GhcSpec -> SEnv SortedReft
 ghcSpecEnv sp        = fromListSEnv binds
   where
-    emb              = tcEmbeds sp
-    binds            =  [(x,        rSort t) | (x, Loc _ _ t) <- meas sp]
-                     ++ [(symbol v, rSort t) | (v, Loc _ _ t) <- ctors sp]
-                     ++ [(x,        vSort v) | (x, v) <- freeSyms sp, isConLikeId v]
-                     -- ++ [(val x   , rSort stringrSort) | Just (ELit x s) <- mkLit <$> lconsts, isString s]
+    emb              = gsTcEmbeds sp
+    binds            =  [(x,        rSort t) | (x, Loc _ _ t) <- gsMeas sp]
+                     ++ [(symbol v, rSort t) | (v, Loc _ _ t) <- gsCtors sp]
+                     ++ [(x,        vSort v) | (x, v) <- gsFreeSyms sp, isConLikeId v]
     rSort            = rTypeSortedReft emb
     vSort            = rSort . varRSort
     varRSort         :: Var -> RSort
     varRSort         = ofType . varType
-    --lconsts          = literals cbs
-    --stringrSort      :: RSort
-    --stringrSort      = ofType stringTy
-    --isString s       = rTypeSort emb stringrSort == s
 
 ------------------------------------------------------------------------------------------------
-makeGhcSpec' :: Config -> [CoreBind] -> [Var] -> [Var] -> NameSet -> [(ModName, Ms.BareSpec)] -> BareM GhcSpec
+makeGhcSpec' :: Config -> [CoreBind] -> Maybe [ClsInst] -> [Var] -> [Var] -> NameSet -> [(ModName, Ms.BareSpec)] -> BareM GhcSpec
 ------------------------------------------------------------------------------------------------
-makeGhcSpec' cfg cbs vars defVars exports specs
+makeGhcSpec' cfg cbs instenv vars defVars exports specs
   = do name          <- modName <$> get
-       makeRTEnv  specs
-       (tycons, datacons, dcSs, recSs, tyi, embs) <- makeGhcSpecCHOP1 specs
+       embs          <- makeNumericInfo instenv <$> (mconcat <$> mapM makeTyConEmbeds specs)
+       xils          <- concatMapM (makeHaskellInlines embs cbs name) specs
+       lmap          <- logic_map . logicEnv <$> get
+       makeRTEnv name xils specs lmap
+       (tycons, datacons, dcSs, recSs, tyi) <- makeGhcSpecCHOP1 cfg specs embs
        makeBounds embs name defVars cbs specs
        modify                                   $ \be -> be { tcEnv = tyi }
        (cls, mts)                              <- second mconcat . unzip . mconcat <$> mapM (makeClasses name cfg vars) specs
        (measures, cms', ms', cs', xs')         <- makeGhcSpecCHOP2 cbs specs dcSs datacons cls embs
-       (invs, ialias, sigs, asms)              <- makeGhcSpecCHOP3 cfg vars defVars specs name mts embs
-       syms                                    <- makeSymbols (varInModule name) (vars ++ map fst cs') xs' (sigs ++ asms ++ cs') ms' (invs ++ (snd <$> ialias))
+       (invs, ntys, ialias, sigs, asms)        <- makeGhcSpecCHOP3 cfg vars defVars specs name mts embs
+       quals   <- mconcat <$> mapM makeQualifiers specs
+       syms                                    <- makeSymbols (varInModule name) (vars ++ map fst cs') xs' (sigs ++ asms ++ cs') ms' (map snd invs ++ (snd <$> ialias))
        let su  = mkSubst [ (x, mkVarExpr v) | (x, v) <- syms]
        makeGhcSpec0 cfg defVars exports name (emptySpec cfg)
          >>= makeGhcSpec1 vars defVars embs tyi exports name sigs (recSs ++ asms) cs' ms' cms' su
-         >>= makeGhcSpec2 invs ialias measures su
+         >>= makeGhcSpec2 invs ntys ialias measures su
          >>= makeGhcSpec3 (datacons ++ cls) tycons embs syms
          >>= makeSpecDictionaries embs vars specs
          >>= makeGhcAxioms embs cbs name specs
          >>= makeExactDataCons name (exactDC cfg) (snd <$> syms)
-         -- This step need the updated logic map, ie should happen after makeGhcAxioms
-         >>= makeGhcSpec4 defVars specs name su
+         -- This step need the updated logic map, ie should happen AFTER makeGhcAxioms
+         >>= makeGhcSpec4 quals defVars specs name su
          >>= addProofType
-
+         >>= addRTEnv
 
 addProofType :: GhcSpec -> BareM GhcSpec
-addProofType spec
-  = do tycon <- (Just <$> (lookupGhcTyCon $ dummyLoc proofTyConName)) `catchError` (\_ -> return Nothing)
-       return $ spec {proofType = (`TyConApp` []) <$> tycon}
+addProofType spec = do
+  tycon <- (Just <$> lookupGhcTyCon (dummyLoc proofTyConName)) `catchError` (\_ -> return Nothing)
+  return $ spec { gsProofType = (`TyConApp` []) <$> tycon }
 
+addRTEnv :: GhcSpec -> BareM GhcSpec
+addRTEnv spec = do
+  rt <- rtEnv <$> get
+  return $ spec { gsRTAliases = rt }
 
+
 makeExactDataCons :: ModName -> Bool -> [Var] -> GhcSpec -> BareM GhcSpec
 makeExactDataCons n flag vs spec
-  | flag      = return $ spec {tySigs = (tySigs spec) ++ xts}
+  | flag      = return $ spec { gsTySigs = gsTySigs spec ++ xts}
   | otherwise = return spec
   where
-    xts = makeExact <$> (filter isDataConId $ filter (varInModule n) vs)
+    xts       = makeExact <$> filter f vs
+    f v       = isDataConId v && varInModule n v
 
+varInModule :: (Show a, Show a1) => a -> a1 -> Bool
 varInModule n v = L.isPrefixOf (show n) $ show v
 
-makeExact :: Var -> (Var, Located SpecType)
+makeExact :: Var -> (Var, LocSpecType)
 makeExact x = (x, dummyLoc . fromRTypeRep $ trep{ty_res = res, ty_binds = xs})
   where
     t    :: SpecType
@@ -191,118 +211,284 @@
     spec = fromMaybe mempty $ lookup name bspecs
 
 makeAxioms :: TCEmb TyCon -> [CoreBind] -> GhcSpec -> Ms.BareSpec -> BareM GhcSpec
-makeAxioms tce cbs spec sp
-  = do lmap          <- logicEnv <$> get
-       (ms, tys, as) <- unzip3 <$> mapM (makeAxiom tce lmap cbs spec sp) (S.toList $ Ms.axioms sp)
-       lmap'         <- logicEnv <$> get
-       return $ spec { meas     = ms         ++  meas   spec
-                     , asmSigs  = concat tys ++ asmSigs spec
-                     , axioms   = concat as  ++ axioms spec
-                     , logicMap = lmap' }
+makeAxioms tce cbs spec sp = do
+  lmap             <- logicEnv <$> get
+  (msA, tysA, asA, smtA) <- L.unzip4 <$> mapM (makeAxiom tce lmap cbs spec sp) (S.toList $ Ms.axioms   sp)
+  (msR, tysR, asR, _   ) <- L.unzip4 <$> mapM (makeAxiom tce lmap cbs spec sp) (S.toList $ Ms.reflects sp)
+  lmap'            <- logicEnv <$> get
+  return $ spec { gsMeas     = msA ++ msR ++ gsMeas     spec
+                , gsAsmSigs  = concat tysA ++ concat tysR ++ gsAsmSigs  spec
+                , gsReflects = concat asA  ++ concat asR  ++ gsReflects spec
+                , gsAxioms   = smtA ++ gsAxioms spec 
+                , gsLogicMap = lmap' }
 
 emptySpec     :: Config -> GhcSpec
-emptySpec cfg = SP [] [] [] [] [] [] [] [] [] [] mempty [] [] [] [] mempty mempty mempty cfg mempty [] mempty mempty [] mempty Nothing
+emptySpec cfg = SP
+  { gsTySigs     = mempty
+  , gsAsmSigs    = mempty
+  , gsInSigs     = mempty
+  , gsCtors      = mempty
+  , gsLits       = mempty
+  , gsMeas       = mempty
+  , gsInvariants = mempty
+  , gsIaliases   = mempty
+  , gsDconsP     = mempty
+  , gsTconsP     = mempty
+  , gsFreeSyms   = mempty
+  , gsTcEmbeds   = mempty
+  , gsQualifiers = mempty
+  , gsTgtVars    = mempty
+  , gsDecr       = mempty
+  , gsTexprs     = mempty
+  , gsNewTypes   = mempty
+  , gsLvars      = mempty
+  , gsLazy       = mempty
+  , gsAutoInst   = mempty
+  , gsAutosize   = mempty
+  , gsConfig     = cfg
+  , gsExports    = mempty
+  , gsMeasures   = mempty
+  , gsTyconEnv   = mempty
+  , gsDicts      = mempty
+  , gsAxioms     = mempty
+  , gsReflects   = mempty 
+  , gsLogicMap   = mempty
+  , gsProofType  = Nothing
+  , gsRTAliases  = mempty
+  }
 
 
+
+
+
+
+makeGhcSpec0 :: Config
+             -> [Var]
+             -> NameSet
+             -> ModName
+             -> GhcSpec
+             -> BareM GhcSpec
 makeGhcSpec0 cfg defVars exports name sp
-  = do targetVars <- makeTargetVars name defVars $ binders cfg
-       return      $ sp { config = cfg
-                        , exports = exports
-                        , tgtVars = targetVars }
+  = do targetVars <- makeTargetVars name defVars $ checks cfg
+       return      $ sp { gsConfig  = cfg
+                        , gsExports = exports
+                        , gsTgtVars = targetVars }
 
+makeGhcSpec1 :: [Var]
+             -> [Var]
+             -> TCEmb TyCon
+             -> M.HashMap TyCon RTyCon
+             -> NameSet
+             -> ModName
+             -> [(Var,    LocSpecType)]
+             -> [(Var,    LocSpecType)]
+             -> [(Var,    LocSpecType)]
+             -> [(Symbol, Located (RRType Reft))]
+             -> [(Symbol, Located (RRType Reft))]
+             -> Subst
+             -> GhcSpec
+             -> BareM GhcSpec
 makeGhcSpec1 vars defVars embs tyi exports name sigs asms cs' ms' cms' su sp
   = do tySigs      <- makePluggedSigs name embs tyi exports $ tx sigs
        asmSigs     <- makePluggedAsmSigs embs tyi $ tx asms
        ctors       <- makePluggedAsmSigs embs tyi $ tx cs'
-       lmap        <- logicEnv <$> get
-       inlmap      <- inlines  <$> get
-       let ctors'   = [ (x, txRefToLogic lmap inlmap <$> t) | (x, t) <- ctors ]
-       return $ sp { tySigs     = filter (\(v,_) -> v `elem` vs) tySigs
-                   , asmSigs    = filter (\(v,_) -> v `elem` vs) asmSigs
-                   , ctors      = filter (\(v,_) -> v `elem` vs) ctors'
-                   , meas       = tx' $ tx $ ms' ++ varMeasures vars ++ cms' }
+       return $ sp { gsTySigs   = filter (\(v,_) -> v `elem` vs) tySigs
+                   , gsAsmSigs  = filter (\(v,_) -> v `elem` vs) asmSigs
+                   , gsCtors    = filter (\(v,_) -> v `elem` vs) ctors
+                   , gsMeas     = measSyms
+                   , gsLits     = measSyms -- RJ: we will be adding *more* things to `meas` but not `lits`
+                   }
     where
-      tx   = fmap . mapSnd . subst $ su
-      tx'  = fmap (mapSnd $ fmap uRType)
-      vs   = vars ++ defVars
+      tx       = fmap . mapSnd . subst $ su
+      tx'      = fmap (mapSnd $ fmap uRType)
+      vs       = vars ++ defVars
+      measSyms = tx' $ tx $ ms' ++ varMeasures vars ++ cms'
 
-makeGhcSpec2 invs ialias measures su sp
-  = return $ sp { invariants = subst su invs
-                , ialiases   = subst su ialias
-                , measures   = subst su
+makeGhcSpec2 :: Monad m
+             => [(Maybe Var  , LocSpecType)]
+             -> [(TyCon      , LocSpecType)]
+             -> [(LocSpecType, LocSpecType)]
+             -> MSpec SpecType DataCon
+             -> Subst
+             -> GhcSpec
+             -> m GhcSpec
+makeGhcSpec2 invs ntys ialias measures su sp
+  = return $ sp { gsInvariants = mapSnd (subst su) <$> invs
+                , gsNewTypes   = mapSnd (subst su) <$> ntys
+                , gsIaliases   = subst su ialias
+                , gsMeasures   = subst su
                                  <$> M.elems (Ms.measMap measures)
                                   ++ Ms.imeas measures
                 }
 
 makeGhcSpec3 :: [(DataCon, DataConP)] -> [(TyCon, TyConP)] -> TCEmb TyCon -> [(t, Var)] -> GhcSpec -> BareM GhcSpec
-makeGhcSpec3 datacons tycons embs syms sp
-  = do tcEnv       <- tcEnv    <$> get 
-       lmap        <- logicEnv <$> get
-       inlmap      <- inlines  <$> get
-       let dcons'   = mapSnd (txRefToLogic lmap inlmap) <$> datacons
-       return  $ sp { tyconEnv   = tcEnv
-                    , dconsP     = dcons'
-                    , tconsP     = tycons
-                    , tcEmbeds   = embs
-                    , freeSyms   = [(symbol v, v) | (_, v) <- syms] }
+makeGhcSpec3 datacons tycons embs syms sp = do
+  tcEnv  <- tcEnv    <$> get
+  return  $ sp { gsTyconEnv = tcEnv
+               , gsDconsP   = datacons -- dcons'
+               , gsTconsP   = tycons
+               , gsTcEmbeds = embs
+               , gsFreeSyms = [(symbol v, v) | (_, v) <- syms]
+               }
 
-makeGhcSpec4 defVars specs name su sp
+makeGhcSpec4 :: [Qualifier]
+             -> [Var]
+             -> [(ModName, Ms.Spec ty bndr)]
+             -> ModName
+             -> Subst
+             -> GhcSpec
+             -> BareM GhcSpec
+makeGhcSpec4 quals defVars specs name su sp
   = do decr'   <- mconcat <$> mapM (makeHints defVars . snd) specs
-       texprs' <- mconcat <$> mapM (makeTExpr defVars . snd) specs
+       gsTexprs' <- mconcat <$> mapM (makeTExpr defVars . snd) specs
        lazies  <- mkThing makeLazy
+       autois  <- mkThing makeAutoInsts
        lvars'  <- mkThing makeLVar
+       defs'   <- mkThing makeDefs
+       addDefs defs'
        asize'  <- S.fromList <$> makeASize
-       hmeas   <- mkThing makeHIMeas
-       quals   <- mconcat <$> mapM makeQualifiers specs
-       let msgs = strengthenHaskellMeasures hmeas
-       lmap    <- logicEnv <$> get
-       inlmap  <- inlines  <$> get
-       let tx   = mapSnd (fmap $ txRefToLogic lmap inlmap)
-       let mtx  = txRefToLogic lmap inlmap
-       return   $ sp { qualifiers = subst su quals
-                     , decr       = decr'
-                     , texprs     = texprs'
-                     , lvars      = lvars'
-                     , autosize   = asize'
-                     , lazy       = lazies
-                     , tySigs     = tx  <$> tySigs  sp 
-                     , asmSigs    = tx  <$> asmSigs sp
-                     , measures   = mtx <$> measures sp
-                     , inSigs     = tx  <$> msgs 
+       hmeas   <- mkThing makeHMeas
+       hinls   <- mkThing makeHInlines
+       mapM_ (\(v, s) -> insertAxiom (val v) (val s)) $ S.toList hmeas
+       mapM_ (\(v, s) -> insertAxiom (val v) (val s)) $ S.toList hinls
+       mapM_ insertHMeasLogicEnv $ S.toList hmeas
+       mapM_ insertHMeasLogicEnv $ S.toList hinls
+       lmap'       <- logicEnv <$> get
+       isgs        <- expand $ strengthenHaskellInlines  (S.map fst hinls) (gsTySigs sp)
+       gsTySigs'   <- expand $ strengthenHaskellMeasures (S.map fst hmeas) isgs
+       gsMeasures' <- expand $ gsMeasures   sp
+       gsAsmSigs'  <- expand $ gsAsmSigs    sp
+       gsInSigs'   <- expand $ gsInSigs     sp
+       gsInvarnts' <- expand $ gsInvariants sp
+       gsCtors'    <- expand $ gsCtors      sp
+       gsIaliases' <- expand $ gsIaliases   sp
+       gsDconsP'   <- expand $ gsDconsP     sp
+       return   $ sp { gsQualifiers = subst su quals
+                     , gsDecr       = decr'
+                     , gsLvars      = lvars'
+                     , gsAutoInst   = M.fromList $ S.toList autois
+                     , gsAutosize   = asize'
+                     , gsLazy       = S.insert dictionaryVar lazies
+                     , gsLogicMap   = lmap'
+                     , gsTySigs     = gsTySigs'
+                     , gsTexprs     = gsTexprs'
+                     , gsMeasures   = gsMeasures'
+                     , gsAsmSigs    = gsAsmSigs'
+                     , gsInSigs     = gsInSigs'
+                     , gsInvariants = gsInvarnts'
+                     , gsCtors      = gsCtors'
+                     , gsIaliases   = gsIaliases'
+                     , gsDconsP     = gsDconsP'
                      }
     where
        mkThing mk = S.fromList . mconcat <$> sequence [ mk defVars s | (m, s) <- specs, m == name ]
        makeASize  = mapM lookupGhcTyCon [v | (m, s) <- specs, m == name, v <- S.toList (Ms.autosize s)]
 
-makeGhcSpecCHOP1 specs
-  = do (tcs, dcs)      <- mconcat <$> mapM makeConTypes specs
-       let tycons       = tcs        ++ wiredTyCons
-       let tyi          = makeTyConInfo tycons
-       embs            <- mconcat <$> mapM makeTyConEmbeds specs
-       datacons        <- makePluggedDataCons embs tyi (concat dcs ++ wiredDataCons)
-       let dcSelectors  = concatMap makeMeasureSelectors datacons
-       recSels         <- makeRecordSelectorSigs datacons
-       return             (tycons, second val <$> datacons, dcSelectors, recSels, tyi, embs)
+insertHMeasLogicEnv :: (Located Var, LocSymbol) -> BareM ()
+insertHMeasLogicEnv (x, s)
+  | isBool res
+  = insertLogicEnv "insertHMeasLogicENV" s (fst <$> vxs) $ mkProp $ mkEApp s ((EVar . fst) <$> vxs)
+  where
+    rep = toRTypeRep  t
+    res = ty_res rep
+    xs  = intSymbol (symbol ("x" :: String)) <$> [1..length $ ty_binds rep]
+    vxs = dropWhile (isClassType.snd) $ zip xs (ty_args rep)
+    t   = (ofType $ varType $ val x) :: SpecType
+insertHMeasLogicEnv _
+  = return ()
 
+makeGhcSpecCHOP1
+  :: Config -> [(ModName,Ms.Spec ty bndr)] -> TCEmb TyCon
+  -> BareM ( [(TyCon,TyConP)]
+           , [(DataCon,DataConP)]
+           , [Measure SpecType DataCon]
+           , [(Var, Located SpecType)]
+           , M.HashMap TyCon RTyCon     )
+makeGhcSpecCHOP1 cfg specs embs = do
+  (tcs, dcs)      <- mconcat <$> mapM makeConTypes specs
+  let tycons       = tcs        ++ wiredTyCons
+  let tyi          = makeTyConInfo tycons
+  datacons        <- makePluggedDataCons embs tyi (concat dcs ++ wiredDataCons)
+  let dcSelectors  = concatMap (makeMeasureSelectors (exactDC cfg) (not $ noMeasureFields cfg)) datacons
+  recSels         <- makeRecordSelectorSigs datacons
+  return             (tycons, second val <$> datacons, dcSelectors, recSels, tyi)
+
+makeGhcSpecCHOP3 :: Config -> [Var] -> [Var] -> [(ModName, Ms.BareSpec)]
+                 -> ModName -> [(ModName, Var, LocSpecType)]
+                 -> TCEmb TyCon
+                 -> BareM ( [(Maybe Var, LocSpecType)]
+                          , [(TyCon, LocSpecType)]
+                          , [(LocSpecType, LocSpecType)]
+                          , [(Var, LocSpecType)]
+                          , [(Var, LocSpecType)] )
 makeGhcSpecCHOP3 cfg vars defVars specs name mts embs
-  = do sigs'   <- mconcat <$> mapM (makeAssertSpec name cfg vars defVars) specs
-       asms'   <- mconcat <$> mapM (makeAssumeSpec name cfg vars defVars) specs
-       invs    <- mconcat <$> mapM makeInvariants specs
-       ialias  <- mconcat <$> mapM makeIAliases   specs
-       let dms  = makeDefaultMethods vars mts
-       tyi     <- gets tcEnv
-       let sigs = [ (x, txRefSort tyi embs $ fmap txExpToBind t) | (_, x, t) <- sigs' ++ mts ++ dms ]
-       let asms = [ (x, txRefSort tyi embs $ fmap txExpToBind t) | (_, x, t) <- asms' ]
-       return     (invs, ialias, sigs, asms)
+  = do sigs'    <- mconcat <$> mapM (makeAssertSpec name cfg vars defVars) specs
+       asms'    <- mconcat <$> mapM (makeAssumeSpec name cfg vars defVars) specs
+       invs     <- mconcat <$> mapM makeInvariants specs
+       ialias   <- mconcat <$> mapM makeIAliases   specs
+       ntys     <- mconcat <$> mapM makeNewTypes   specs
+       let dms   = makeDefaultMethods vars mts
+       tyi      <- gets tcEnv
+       let sigs  = [ (x, txRefSort tyi embs $ fmap txExpToBind t) | (_, x, t) <- sigs' ++ mts ++ dms ]
+       let asms  = [ (x, txRefSort tyi embs $ fmap txExpToBind t) | (_, x, t) <- asms' ]
+       let hms   = concatMap (S.toList . Ms.hmeas . snd) (filter ((==name) . fst) specs)
+       let minvs = makeMeasureInvariants sigs hms
+       return     (invs ++ minvs, ntys, ialias, sigs, asms)
 
 
+symbol' :: Var -> Symbol
+symbol' = dropModuleNames . symbol . getName
+
+makeMeasureInvariants :: [(Var, LocSpecType)] -> [LocSymbol] -> [(Maybe Var, LocSpecType)]
+makeMeasureInvariants sigs xs = measureTypeToInv <$> [(x, (y, ty)) | x <- xs, (y, ty) <- sigs, val x == symbol' y]
+
+measureTypeToInv :: (LocSymbol, (Var, LocSpecType)) -> (Maybe Var, LocSpecType)
+measureTypeToInv (x, (v, t)) = (Just v, t {val = mtype})
+  where
+    trep = toRTypeRep $ val t
+    ts   = ty_args trep
+    mtype
+      | isBool $ ty_res trep
+      = uError $ ErrHMeas (sourcePosSrcSpan $ loc t) (pprint x)
+                          (text "Specification of boolean measures is not allowed")
+{-
+      | [tx] <- ts, not (isTauto tx)
+      = uError $ ErrHMeas (sourcePosSrcSpan $ loc t) (pprint x)
+                          (text "Measures' types cannot have preconditions")
+-}
+      | [tx] <- ts
+      = mkInvariant (head $ ty_binds trep) tx $ ty_res trep
+      | otherwise
+      = uError $ ErrHMeas (sourcePosSrcSpan $ loc t) (pprint x)
+                          (text "Measures has more than one arguments")
+
+
+    mkInvariant :: Symbol -> SpecType -> SpecType -> SpecType
+    mkInvariant z t tr = strengthen (top <$> t) (MkUReft reft mempty mempty)
+      where
+        Reft (v, p) = toReft $ fromMaybe mempty $ stripRTypeBase tr
+        su    = mkSubst [(v, mkEApp x [EVar v])]
+        reft  = Reft (v, subst su p')
+
+        p'    = pAnd $ filter (\e -> z `notElem` syms e) $ conjuncts p
+
+makeGhcSpecCHOP2 :: [CoreBind]
+                 -> [(ModName, Ms.BareSpec)]
+                 -> [Measure SpecType DataCon]
+                 -> [(DataCon, DataConP)]
+                 -> [(DataCon, DataConP)]
+                 -> TCEmb TyCon
+                 -> BareM ( MSpec SpecType DataCon
+                          , [(Symbol, Located (RRType Reft))]
+                          , [(Symbol, Located (RRType Reft))]
+                          , [(Var,    LocSpecType)]
+                          , [Symbol] )
 makeGhcSpecCHOP2 cbs specs dcSelectors datacons cls embs
   = do measures'   <- mconcat <$> mapM makeMeasureSpec specs
        tyi         <- gets tcEnv
        name        <- gets modName
-       mapM_ (makeHaskellInlines embs cbs name) specs
        hmeans      <- mapM (makeHaskellMeasures embs cbs name) specs
-       let measures = mconcat (Ms.wiredInMeasures:measures':Ms.mkMSpec' dcSelectors:hmeans)
+       let measures = mconcat (measures':Ms.mkMSpec' dcSelectors:hmeans)
        let (cs, ms) = makeMeasureSpec' measures
        let cms      = makeClassMeasureSpec measures
        let cms'     = [ (x, Loc l l' $ cSort t) | (Loc l l' x, t) <- cms ]
@@ -311,8 +497,10 @@
        let xs'      = val . fst <$> ms
        return (measures, cms', ms', cs', xs')
 
+txRefSort' :: NamedThing a => a -> TCEnv -> TCEmb TyCon -> SpecType -> LocSpecType
 txRefSort' v tyi embs t = txRefSort tyi embs (atLoc' v t)
 
+atLoc' :: NamedThing a1 => a1 -> a -> Located a
 atLoc' v = Loc (getSourcePos v) (getSourcePosE v)
 
 data ReplaceEnv = RE { _re_env  :: M.HashMap Symbol Symbol
@@ -321,60 +509,65 @@
                      , _re_tyi  :: M.HashMap TyCon RTyCon
                      }
 
-type ReplaceState = ( M.HashMap Var (Located SpecType)
-                    , M.HashMap Var [Expr]
+type ReplaceState = ( M.HashMap Var LocSpecType
+                    , M.HashMap Var [Located Expr]
                     )
 
 type ReplaceM = ReaderT ReplaceEnv (State ReplaceState)
 
-replaceLocalBinds :: TCEmb TyCon
+-- RJ: WHAT DOES THIS FUNCTION DO?!!!!
+replaceLocalBinds :: Bool
+                  -> TCEmb TyCon
                   -> M.HashMap TyCon RTyCon
-                  -> [(Var, Located SpecType)]
-                  -> [(Var, [Expr])]
                   -> SEnv SortedReft
                   -> CoreProgram
-                  -> ([(Var, Located SpecType)], [(Var, [Expr])])
-replaceLocalBinds emb tyi sigs texprs senv cbs
+                  -> [(Var, LocSpecType)]
+                  -> [(Var, [Located Expr])]
+                  -> ([(Var, LocSpecType)], [(Var, [Located Expr])])
+replaceLocalBinds allowHO emb tyi senv cbs sigs texprs
   = (M.toList s, M.toList t)
   where
-    (s,t) = execState (runReaderT (mapM_ (`traverseBinds` return ()) cbs)
-                                  (RE M.empty senv emb tyi))
-                      (M.fromList sigs, M.fromList texprs)
+    (s, t) = execState (runReaderT (mapM_ (\x -> traverseBinds allowHO x (return ())) cbs)
+                                   (RE M.empty senv emb tyi))
+                       (M.fromList sigs, M.fromList texprs)
 
-traverseExprs (Let b e)
-  = traverseBinds b (traverseExprs e)
-traverseExprs (Lam b e)
-  = withExtendedEnv [b] (traverseExprs e)
-traverseExprs (App x y)
-  = traverseExprs x >> traverseExprs y
-traverseExprs (Case e _ _ as)
-  = traverseExprs e >> mapM_ (traverseExprs . thd3) as
-traverseExprs (Cast e _)
-  = traverseExprs e
-traverseExprs (Tick _ e)
-  = traverseExprs e
-traverseExprs _
+traverseExprs :: Bool -> CoreSyn.Expr Var -> ReplaceM ()
+traverseExprs allowHO (Let b e)
+  = traverseBinds allowHO b (traverseExprs allowHO e)
+traverseExprs allowHO (Lam b e)
+  = withExtendedEnv allowHO [b] (traverseExprs allowHO e)
+traverseExprs allowHO (App x y)
+  = traverseExprs allowHO x >> traverseExprs allowHO y
+traverseExprs allowHO (Case e _ _ as)
+  = traverseExprs allowHO e >> mapM_ (traverseExprs allowHO . thd3) as
+traverseExprs allowHO (Cast e _)
+  = traverseExprs allowHO e
+traverseExprs allowHO (Tick _ e)
+  = traverseExprs allowHO e
+traverseExprs _ _
   = return ()
 
-traverseBinds b k = withExtendedEnv (bindersOf b) $ do
-  mapM_ traverseExprs (rhssOfBind b)
+traverseBinds :: Bool -> Bind Var -> ReplaceM b -> ReplaceM b
+traverseBinds allowHO b k = withExtendedEnv allowHO (bindersOf b) $ do
+  mapM_ (traverseExprs allowHO) (rhssOfBind b)
   k
 
 -- RJ: this function is incomprehensible, what does it do?!
-withExtendedEnv vs k
-  = do RE env' fenv' emb tyi <- ask
-       let env  = L.foldl' (\m v -> M.insert (varShortSymbol v) (symbol v) m) env' vs
-           fenv = L.foldl' (\m v -> insertSEnv (symbol v) (rTypeSortedReft emb (ofType $ varType v :: RSort)) m) fenv' vs
-       withReaderT (const (RE env fenv emb tyi)) $ do
-         mapM_ replaceLocalBindsOne vs
-         k
+withExtendedEnv :: Bool -> [Var] -> ReplaceM b -> ReplaceM b
+withExtendedEnv allowHO vs k = do
+  RE env' fenv' emb tyi <- ask
+  let env  = L.foldl' (\m v -> M.insert (varShortSymbol v) (symbol v) m) env' vs
+      fenv = L.foldl' (\m v -> insertSEnv (symbol v) (rTypeSortedReft emb (ofType $ varType v :: RSort)) m) fenv' vs
+  withReaderT (const (RE env fenv emb tyi)) $ do
+    mapM_ (replaceLocalBindsOne allowHO) vs
+    k
 
 varShortSymbol :: Var -> Symbol
 varShortSymbol = symbol . takeWhile (/= '#') . showPpr . getName
 
--- RJ: this function is incomprehensible
-replaceLocalBindsOne :: Var -> ReplaceM ()
-replaceLocalBindsOne v
+-- RJ: this function is incomprehensible, what does it do?!
+replaceLocalBindsOne :: Bool -> Var -> ReplaceM ()
+replaceLocalBindsOne allowHO v
   = do mt <- gets (M.lookup v . fst)
        case mt of
          Nothing -> return ()
@@ -386,9 +579,9 @@
            let res  = substa (f env) ty_res
            let t'   = fromRTypeRep $ t { ty_args = args, ty_res = res }
            let msg  = ErrTySpec (sourcePosSrcSpan l) (pprint v) t'
-           case checkTy msg emb tyi fenv (Loc l l' t') of
+           case checkTy allowHO msg emb tyi fenv (Loc l l' t') of
              Just err -> Ex.throw err
-             Nothing -> modify (first $ M.insert v (Loc l l' t'))
+             Nothing  -> modify (first $ M.insert v (Loc l l' t'))
            mes <- gets (M.lookup v . snd)
            case mes of
              Nothing -> return ()
diff --git a/src/Language/Haskell/Liquid/Bare/Lookup.hs b/src/Language/Haskell/Liquid/Bare/Lookup.hs
--- a/src/Language/Haskell/Liquid/Bare/Lookup.hs
+++ b/src/Language/Haskell/Liquid/Bare/Lookup.hs
@@ -1,53 +1,55 @@
-{-# LANGUAGE FlexibleContexts         #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE NoMonomorphismRestriction #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE NoMonomorphismRestriction  #-}
+{-# LANGUAGE OverloadedStrings          #-}
 
 module Language.Haskell.Liquid.Bare.Lookup (
     GhcLookup(..)
-
   , lookupGhcThing
   , lookupGhcVar
   , lookupGhcTyCon
   , lookupGhcDataCon
   ) where
 
-import Prelude hiding (error)
-import BasicTypes
-import ConLike
-import DataCon
-import GHC (HscEnv)
-import HscMain
-import Name
-import PrelInfo                                 (wiredInThings)
-import PrelNames                                (fromIntegerName, smallIntegerName, integerTyConName)
-import RdrName (setRdrNameSpace)
-import SrcLoc (SrcSpan, GenLocated(L))
-import TcEnv
-import TyCon
-import TysWiredIn
-import Var
-
-import Control.Monad.Except (catchError, throwError)
-import Control.Monad.State
-import Data.Maybe
-import Text.PrettyPrint.HughesPJ (text)
-
-import qualified Data.List           as L
-import qualified Data.HashMap.Strict as M
-
-import Language.Fixpoint.Types.Names (hpropConName, isPrefixOfSym, lengthSym, propConName, symbolString)
-import Language.Fixpoint.Types (Symbol, Symbolic(..))
-
-import Language.Haskell.Liquid.GHC.Misc (lookupRdrName, sourcePosSrcSpan, tcRnLookupRdrName)
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.WiredIn
+import           BasicTypes
+import           ConLike
+import           DataCon
+import           GHC                              (HscEnv)
+import           HscMain
+import           Name
+import           PrelInfo                         (wiredInThings)
+import           PrelNames                        (fromIntegerName, smallIntegerName, integerTyConName)
+import           Prelude                          hiding (error)
+import           RdrName                          (setRdrNameSpace)
+import           SrcLoc                           (SrcSpan, GenLocated(L))
+import           TcEnv
+import           TyCon
+import           TysWiredIn
+import           Module
+import           Finder
+import           TcRnMonad
+import           IfaceEnv
+import           Var
 
-import Language.Haskell.Liquid.Bare.Env
+import           Control.Monad.Except             (catchError, throwError)
+import           Control.Monad.State
+import           Data.Maybe
+import           Text.PrettyPrint.HughesPJ        (text)
+import qualified Data.List                        as L
+import qualified Data.HashMap.Strict              as M
+import qualified Data.Text                        as T
+import           Language.Fixpoint.Types.Names    (symbolText, isPrefixOfSym, lengthSym, symbolString)
+import           Language.Fixpoint.Types          (Symbol, Symbolic(..))
+import           Language.Fixpoint.Misc           as F
+import           Language.Haskell.Liquid.GHC.Misc (splitModuleName, lookupRdrName, sourcePosSrcSpan, tcRnLookupRdrName)
+import           Language.Haskell.Liquid.Misc     (firstMaybes)
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Bare.Env
+-- import Debug.Trace (trace)
 
------------------------------------------------------------------
------- Querying GHC for Id, Type, Class, Con etc. ---------------
------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Querying GHC for Id, Type, Class, Con etc. --------------------------------
+--------------------------------------------------------------------------------
 
 class Symbolic a => GhcLookup a where
   lookupName :: HscEnv -> ModName -> a -> IO [Name]
@@ -61,25 +63,27 @@
   lookupName _ _ = return . (:[])
   srcSpan        = nameSrcSpan
 
+lookupGhcThing :: (GhcLookup a) => String -> (TyThing -> Maybe b) -> a -> BareM b
+lookupGhcThing name f x = lookupGhcThing' err f x >>= maybe (throwError err) return
+  where
+    err                 = ErrGhc (srcSpan x) (text msg)
+    msg                 = unwords [ "Not in scope:", name, "`", symbolicString x, "'"]
 
+lookupGhcThing' :: (GhcLookup a) => TError e -> (TyThing -> Maybe b) -> a -> BareM (Maybe b)
+lookupGhcThing' _err f x = do
+  be     <- get
+  let env = hscEnv be
+  -- _      <- liftIO $ putStrLn ("lookupGhcThing: PRE " ++ symbolicString x)
+  ns     <- liftIO $ lookupName env (modName be) x
+  -- _      <- liftIO $ putStrLn ("lookupGhcThing: POST " ++ symbolicString x ++ show ns)
+  mts    <- liftIO $ mapM (fmap (join . fmap f) . hscTcRcLookupName env) ns
+  return  $ firstMaybes mts
 
--- lookupGhcThing :: (GhcLookup a) => String -> (TyThing -> Maybe b) -> a -> BareM b
-lookupGhcThing name f x
-  = do zs <- lookupGhcThing' name f x
-       case zs of
-         Just x' -> return x'
-         Nothing -> throwError $ ErrGhc (srcSpan x) (text msg)
-  where
-    msg = "Not in scope: " ++ name ++ " `" ++ symbolString (symbol x) ++ "'"
+symbolicString :: Symbolic a => a -> String
+symbolicString = symbolString . symbol
 
--- lookupGhcThing' :: (GhcLookup a) => String -> (TyThing -> Maybe b) -> a -> BareM (Maybe b)
-lookupGhcThing' _    f x
-  = do BE {modName = mod, hscEnv = env} <- get
-       ns                 <- liftIO $ lookupName env mod x
-       mts                <- liftIO $ mapM (fmap (join . fmap f) . hscTcRcLookupName env) ns
-       case catMaybes mts of
-         []    -> return Nothing
-         (t:_) -> return $ Just t
+-- liftIOErr :: TError e -> IO a -> BareM a
+-- liftIOErr e act = liftIO (act `catchError` \_ -> throwError e)
 
 symbolLookup :: HscEnv -> ModName -> Symbol -> IO [Name]
 symbolLookup env mod k
@@ -96,23 +100,59 @@
                , ("GHC.Integer.Type.Integer", integerTyConName)
                , ("GHC.Num.fromInteger"     , fromIntegerName ) ]
 
-symbolLookupEnv env mod s
+symbolLookupEnv :: HscEnv -> ModName -> Symbol -> IO [Name]
+symbolLookupEnv env mod k = do
+  ns <- symbolLookupEnvOrig env mod k
+  case ns of
+    [] -> symbolLookupEnvFull env mod k
+    _  -> return ns
+
+symbolLookupEnvOrig :: HscEnv -> ModName -> Symbol -> IO [Name]
+symbolLookupEnvOrig env mod s
   | isSrcImport mod
   = do let modName = getModName mod
-       L _ rn <- hscParseIdentifier env $ symbolString s
+       L _ rn <- hscParseIdentifier env $ ghcSymbolString s
        res    <- lookupRdrName env modName rn
        -- 'hscParseIdentifier' defaults constructors to 'DataCon's, but we also
        -- need to get the 'TyCon's for declarations like @data Foo = Foo Int@.
        res'   <- lookupRdrName env modName (setRdrNameSpace rn tcName)
        return $ catMaybes [res, res']
   | otherwise
-  = do rn             <- hscParseIdentifier env $ symbolString s
+  = do rn             <- hscParseIdentifier env $ ghcSymbolString s
        (_, lookupres) <- tcRnLookupRdrName env rn
        case lookupres of
          Just ns -> return ns
          _       -> return []
 
+symbolLookupEnvFull :: HscEnv -> ModName -> Symbol -> IO [Name]
+symbolLookupEnvFull hsc _m s = do
+  let (modName, occName) =  ghcSplitModuleName s
+  mbMod  <- lookupTheModule hsc modName
+  case mbMod of
+    Just mod -> liftIO $ F.singleton <$> lookupTheName hsc mod occName
+    Nothing  -> return []
 
+lookupTheModule :: HscEnv -> ModuleName -> IO (Maybe Module)
+lookupTheModule hsc modName = do
+  r <- findImportedModule hsc modName Nothing
+  return $ case r of
+    Found _ mod -> Just mod
+    NotFound {fr_mods_hidden=(unitId:_)} -> Just (mkModule unitId modName)
+    _ -> Nothing -- error "i don't know what to do here"
+
+lookupTheName :: HscEnv -> Module -> OccName -> IO Name
+lookupTheName hsc mod name = initTcForLookup hsc (lookupOrig mod name)
+
+
+ghcSplitModuleName :: Symbol -> (ModuleName, OccName)
+ghcSplitModuleName x = (mkModuleName $ ghcSymbolString m, mkTcOcc $ ghcSymbolString s)
+  where
+    (m, s)           = splitModuleName x
+
+ghcSymbolString :: Symbol -> String
+ghcSymbolString = T.unpack . fst . T.breakOn "##" . symbolText
+-- ghcSymbolString = symbolString . dropModuleUnique
+
 -- | It's possible that we have already resolved the 'Name' we are looking for,
 -- but have had to turn it back into a 'String', e.g. to be used in an 'Expr',
 -- as in @{v:Ordering | v = EQ}@. In this case, the fully-qualified 'Name'
@@ -130,37 +170,43 @@
     fv _                          = Nothing
 
 
-lookupGhcTyCon       ::  GhcLookup a => a -> BareM TyCon
-lookupGhcTyCon s     = (lookupGhcThing "type constructor or class" ftc s)
-                       `catchError` (tryPropTyCon s)
+lookupGhcTyCon   ::  GhcLookup a => a -> BareM TyCon
+lookupGhcTyCon s = lookupGhcThing err ftc s `catchError` \_ ->
+                         lookupGhcThing err fdc s
   where
-    ftc (ATyCon x)   = Just x
-    ftc _            = Nothing
+    -- s = trace ("lookupGhcTyCon: " ++ symbolicString _s) _s
+    ftc (ATyCon x)
+      = Just x
+    ftc _
+      = Nothing
 
-tryPropTyCon s e
-  | sx == propConName  = return propTyCon
-  | sx == hpropConName = return hpropTyCon
-  | otherwise          = throwError e
-  where
-    sx                 = symbol s
+    fdc (AConLike (RealDataCon x)) | isJust $ promoteDataCon_maybe x
+      = Just $ promoteDataCon x
+    fdc _
+      = Nothing
 
+    err = "type constructor or class"
+
+lookupGhcDataCon :: Located Symbol -> BareM DataCon
 lookupGhcDataCon dc
- | Just n <- isTupleDC (val dc)
- = return $ tupleCon BoxedTuple n
- | val dc == "[]"
- = return nilDataCon
- | val dc == ":"
- = return consDataCon
- | otherwise
- = lookupGhcDataCon' dc
+  | Just n <- isTupleDC (val dc)
+  = return $ tupleCon BoxedTuple n
+  | val dc == "[]"
+  = return nilDataCon
+  | val dc == ":"
+  = return consDataCon
+  | otherwise
+  = lookupGhcDataCon' dc
 
+isTupleDC :: Symbol -> Maybe Int
 isTupleDC zs
   | "(," `isPrefixOfSym` zs
   = Just $ lengthSym zs - 1
   | otherwise
   = Nothing
 
-lookupGhcDataCon'    = lookupGhcThing "data constructor" fdc
+lookupGhcDataCon' :: (GhcLookup a) => a -> BareM DataCon
+lookupGhcDataCon' = lookupGhcThing "data constructor" fdc
   where
     fdc (AConLike (RealDataCon x)) = Just x
-    fdc _            = Nothing
+    fdc _                          = Nothing
diff --git a/src/Language/Haskell/Liquid/Bare/Measure.hs b/src/Language/Haskell/Liquid/Bare/Measure.hs
--- a/src/Language/Haskell/Liquid/Bare/Measure.hs
+++ b/src/Language/Haskell/Liquid/Bare/Measure.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE RecordWildCards #-}
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE RecordWildCards  #-}
+{-# LANGUAGE TupleSections    #-}
 
 module Language.Haskell.Liquid.Bare.Measure (
     makeHaskellMeasures
@@ -11,6 +11,7 @@
   , makeClassMeasureSpec
   , makeMeasureSelectors
   , strengthenHaskellMeasures
+  , strengthenHaskellInlines
   , varMeasures
   ) where
 
@@ -18,12 +19,13 @@
 import DataCon
 import TyCon
 import Id
-import Name
 import Type hiding (isFunTy)
+import qualified Type
 import Var
 
+import Data.Default
+-- import Data.Either (either)
 import Prelude hiding (mapM, error)
-import Control.Arrow ((&&&))
 import Control.Monad hiding (forM, mapM)
 import Control.Monad.Except hiding (forM, mapM)
 import Control.Monad.State hiding (forM, mapM)
@@ -31,6 +33,8 @@
 import Data.Maybe
 import Data.Char (toUpper)
 
+import TysWiredIn (boolTyCon)
+
 import Data.Traversable (forM, mapM)
 import Text.PrettyPrint.HughesPJ (text)
 import Text.Parsec.Pos (SourcePos)
@@ -40,131 +44,148 @@
 import qualified Data.HashMap.Strict as M
 import qualified Data.HashSet        as S
 
-import Language.Fixpoint.Misc (mlookup, sortNub)
-import Language.Fixpoint.Types (Symbol, dummySymbol, symbolString, symbol, Expr(..))
+import Language.Fixpoint.Misc (mlookup, sortNub, groupList, mapSnd, mapFst)
+import Language.Fixpoint.Types (Symbol, dummySymbol, symbolString, symbol, Expr(..), meet)
 import Language.Fixpoint.SortCheck (isFirstOrder)
 
 import qualified Language.Fixpoint.Types as F
 
-import Language.Haskell.Liquid.Transforms.CoreToLogic
-import Language.Haskell.Liquid.Misc
-import Language.Haskell.Liquid.GHC.Misc (dropModuleNames, getSourcePos, getSourcePosE, sourcePosSrcSpan, isDataConId)
-import Language.Haskell.Liquid.Types.RefType (generalize, ofType, uRType, typeSort)
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Types.Bounds
+import           Language.Haskell.Liquid.Transforms.CoreToLogic
+import           Language.Haskell.Liquid.Misc
+import qualified Language.Haskell.Liquid.GHC.Misc as GM -- (findVarDef, varLocInfo, getSourcePos, getSourcePosE, sourcePosSrcSpan, isDataConId)
+import           Language.Haskell.Liquid.Types.RefType (generalize, ofType, uRType, typeSort)
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Types.Bounds
 
 import qualified Language.Haskell.Liquid.Measure as Ms
 
-import Language.Haskell.Liquid.Bare.Env
-import Language.Haskell.Liquid.Bare.Misc       (simpleSymbolVar, hasBoolResult)
-import Language.Haskell.Liquid.Bare.Expand
-import Language.Haskell.Liquid.Bare.Lookup
-import Language.Haskell.Liquid.Bare.OfType
-import Language.Haskell.Liquid.Bare.Resolve
-import Language.Haskell.Liquid.Bare.RefToLogic
+import           Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.Misc       (simpleSymbolVar, hasBoolResult, makeDataConChecker, makeDataSelector)
+import           Language.Haskell.Liquid.Bare.Expand
+import           Language.Haskell.Liquid.Bare.Lookup
+import           Language.Haskell.Liquid.Bare.OfType
+import           Language.Haskell.Liquid.Bare.Resolve
+import           Language.Haskell.Liquid.Bare.ToBare
 
-makeHaskellMeasures :: F.TCEmb TyCon -> [CoreBind] -> ModName -> (ModName, Ms.BareSpec) -> BareM (Ms.MSpec SpecType DataCon)
-makeHaskellMeasures _   _   name' (name, _   ) | name /= name'
-  = return mempty
-makeHaskellMeasures tce cbs _     (_   , spec)
-  = do lmap <- gets logicEnv
-       Ms.mkMSpec' <$> mapM (makeMeasureDefinition tce lmap cbs') (S.toList $ Ms.hmeas spec)
+makeHaskellMeasures :: F.TCEmb TyCon -> [CoreBind] -> Ms.BareSpec
+                    -> BareM [Measure (Located BareType) LocSymbol]
+makeHaskellMeasures tce cbs spec = do
+    lmap <- gets logicEnv
+    ms   <- mapM (makeMeasureDefinition tce lmap cbs') (S.toList $ Ms.hmeas spec)
+    return (measureToBare <$> ms)
   where
     cbs'                  = concatMap unrec cbs
     unrec cb@(NonRec _ _) = [cb]
     unrec (Rec xes)       = [NonRec x e | (x, e) <- xes]
 
-makeHaskellInlines :: F.TCEmb TyCon -> [CoreBind] -> ModName -> (ModName, Ms.BareSpec) -> BareM ()
-makeHaskellInlines _   _   name' (name, _   ) | name /= name'
-  = return mempty
-makeHaskellInlines tce cbs _     (_   , spec)
-  = do lmap <- gets logicEnv
-       mapM_ (makeMeasureInline tce lmap cbs') (S.toList $ Ms.inlines spec)
+makeHaskellInlines :: F.TCEmb TyCon -> [CoreBind] -> Ms.BareSpec -> BareM [(LocSymbol, LMap)]
+makeHaskellInlines tce cbs spec = do
+  lmap <- gets logicEnv
+  mapM (makeMeasureInline tce lmap cbs') (S.toList $ Ms.inlines spec)
   where
     cbs'                  = concatMap unrec cbs
     unrec cb@(NonRec _ _) = [cb]
     unrec (Rec xes)       = [NonRec x e | (x, e) <- xes]
 
-makeMeasureInline :: F.TCEmb TyCon -> LogicMap -> [CoreBind] ->  LocSymbol -> BareM ()
-makeMeasureInline tce lmap cbs  x
-  = case filter ((val x `elem`) . map (dropModuleNames . simplesymbol) . binders) cbs of
-    (NonRec v def:_)   -> do {e <- coreToFun' tce x v def; updateInlines x e}
-    (Rec [(v, def)]:_) -> do {e <- coreToFun' tce x v def; updateInlines x e}
-    _                  -> throwError $ mkError "Cannot inline haskell function"
+makeMeasureInline :: F.TCEmb TyCon -> LogicMap -> [CoreBind] ->  LocSymbol -> BareM (LocSymbol, LMap)
+makeMeasureInline tce lmap cbs x = maybe err (chomp x) $ GM.findVarDef (val x) cbs
   where
-    binders (NonRec z _) = [z]
-    binders (Rec xes)    = fst <$> xes
-
-    coreToFun' tce x v def = case runToLogic tce lmap mkError $ coreToFun x v def of
-                           Left (xs, e)  -> return (TI (symbol <$> xs) (fromLR e))
-                           Right e -> throwError e
-
-    fromLR (Left l)  = l 
-    fromLR (Right r) = r
+    chomp x (v, def)             = (x, ) <$> coreToFun' tce lmap x v def ok
+    err                          = throwError $ errHMeas x "Cannot inline haskell function"
+    ok (xs, e)                   = return (LMap x (varSymbol <$> xs) (either id id e))
 
-    mkError :: String -> Error
-    mkError str = ErrHMeas (sourcePosSrcSpan $ loc x) (pprint $ val x) (text str)
+makeMeasureDefinition :: F.TCEmb TyCon -> LogicMap -> [CoreBind] -> LocSymbol
+                      -> BareM (Measure LocSpecType DataCon)
+makeMeasureDefinition tce lmap cbs x = maybe err (chomp x) $ GM.findVarDef (val x) cbs
+  where
+    chomp x (v, def)   = Ms.mkM x (GM.varLocInfo logicType v) <$> coreToDef' x v def
+    coreToDef' x v def = case runToLogic tce lmap mkErr (coreToDef x v def) of
+                           Right l -> return     l
+                           Left e  -> throwError e
 
+    mkErr :: String -> Error
+    mkErr str = ErrHMeas (GM.sourcePosSrcSpan $ loc x) (pprint $ val x) (text str)
+    err       = throwError $ mkErr "Cannot extract measure from haskell function"
 
-updateInlines x v = modify $ \s -> let iold  = M.insert (val x) v (inlines s) in
-                                   s{inlines = M.map (f iold) iold }
-  where
-    f             = txRefToLogic mempty
+varSymbol :: Var -> Symbol
+varSymbol v
+  | Type.isFunTy (varType v) = GM.simplesymbol v
+  | otherwise                = symbol v
 
-makeMeasureDefinition :: F.TCEmb TyCon -> LogicMap -> [CoreBind] -> LocSymbol -> BareM (Measure SpecType DataCon)
-makeMeasureDefinition tce lmap cbs x
-  = case filter ((val x `elem`) . map (dropModuleNames . simplesymbol) . binders) cbs of
-    (NonRec v def:_)   -> Ms.mkM x (logicType $ varType v) <$> coreToDef' x v def
-    (Rec [(v, def)]:_) -> Ms.mkM x (logicType $ varType v) <$> coreToDef' x v def
-    _                  -> throwError $ mkError "Cannot extract measure from haskell function"
-  where
-    binders (NonRec x _) = [x]
-    binders (Rec xes)    = fst <$> xes
+errHMeas :: LocSymbol -> String -> Error
+errHMeas x str = ErrHMeas (GM.sourcePosSrcSpan $ loc x) (pprint $ val x) (text str)
 
-    coreToDef' x v def = case runToLogic tce lmap mkError $ coreToDef x v def of
-                           Left l  -> return     l
-                           Right e -> throwError e
+strengthenHaskellInlines  :: S.HashSet (Located Var) -> [(Var, LocSpecType)] -> [(Var, LocSpecType)]
+strengthenHaskellInlines  = strengthenHaskell strengthenResult
 
-    mkError :: String -> Error
-    mkError str = ErrHMeas (sourcePosSrcSpan $ loc x) (pprint $ val x) (text str)
+strengthenHaskellMeasures :: S.HashSet (Located Var) -> [(Var, LocSpecType)] -> [(Var, LocSpecType)]
+strengthenHaskellMeasures = strengthenHaskell strengthenResult'
 
-simplesymbol :: CoreBndr -> Symbol
-simplesymbol = symbol . getName
+strengthenHaskell :: (Var -> SpecType) -> S.HashSet (Located Var) -> [(Var, LocSpecType)] -> [(Var, LocSpecType)]
+strengthenHaskell strengthen hmeas sigs
+  = go <$> groupList (reverse sigs ++ hsigs)
+  where
+    hsigs      = [(val x, x {val = strengthen $ val x}) | x <- S.toList hmeas]
+    go (v, xs) = (v,) $ L.foldl1' (flip meetLoc) xs
 
-strengthenHaskellMeasures :: S.HashSet (Located Var) -> [(Var, Located SpecType)]
-strengthenHaskellMeasures hmeas
-  = (val &&& fmap strengthenResult) <$> S.toList hmeas
+meetLoc :: Located SpecType -> Located SpecType -> LocSpecType
+meetLoc t1 t2 = t1 {val = val t1 `meet` val t2}
 
-makeMeasureSelectors :: (DataCon, Located DataConP) -> [Measure SpecType DataCon]
-makeMeasureSelectors (dc, Loc l l' (DataConP _ vs _ _ _ xts r _))
-  = catMaybes (go <$> zip (reverse xts) [1..])
+makeMeasureSelectors :: Bool -> Bool -> (DataCon, Located DataConP) -> [Measure SpecType DataCon]
+makeMeasureSelectors autoselectors autofields (dc, Loc l l' (DataConP _ vs _ _ _ xts r _))
+  =    (if autoselectors then checker : catMaybes (go' <$> zip (reverse xts) [1..]) else [])
+    ++ (if autofields    then catMaybes (go <$> zip (reverse xts) [1..])            else [])
   where
     go ((x,t), i)
-      | isFunTy t = Nothing
-      | otherwise = Just $ makeMeasureSelector (Loc l l' x) (dty t) dc n i
+      -- do not make selectors for functional fields
+      | isFunTy t
+      = Nothing
+      | otherwise
+      = Just $ makeMeasureSelector (Loc l l' x) (dty t) dc n i
 
-    dty t         = foldr RAllT  (RFun dummySymbol r (fmap mempty t) mempty) vs
+    go' ((_,t), i)
+      = Just $ makeMeasureSelector (Loc l l' (makeDataSelector dc i)) (dty t) dc n i
+
+    dty t         = foldr RAllT  (RFun dummySymbol r (fmap mempty t) mempty) (makeRTVar <$> vs)
+    scheck        = foldr RAllT  (RFun dummySymbol r bareBool mempty) (makeRTVar <$> vs)
     n             = length xts
+    bareBool      = RApp (RTyCon boolTyCon [] def) [] [] mempty :: SpecType
 
+    checker       = makeMeasureChecker (dummyLoc $ makeDataConChecker dc) scheck dc n
+
+makeMeasureSelector :: (Enum a, Num a, Show a, Show a1)
+                    => LocSymbol -> ty -> ctor -> a -> a1 -> Measure ty ctor
 makeMeasureSelector x s dc n i = M {name = x, sort = s, eqns = [eqn]}
   where eqn   = Def x [] dc Nothing (((, Nothing) . mkx) <$> [1 .. n]) (E (EVar $ mkx i))
         mkx j = symbol ("xx" ++ show j)
 
 
-makeMeasureSpec :: (ModName, Ms.Spec BareType LocSymbol) -> BareM (Ms.MSpec SpecType DataCon)
-makeMeasureSpec (mod,spec) = inModule mod mkSpec
+-- tyConDataCons
+makeMeasureChecker :: LocSymbol -> ty -> DataCon -> Int -> Measure ty DataCon
+makeMeasureChecker x s dc n = M {name = x, sort = s, eqns = eqn:(eqns <$> filter (/=dc) dcs)}
   where
-    mkSpec = mkMeasureDCon =<< mkMeasureSort =<< m
+    eqn    = Def x [] dc Nothing (((, Nothing) . mkx) <$> [1 .. n]) (P F.PTrue)
+    eqns d = Def x [] d Nothing (((, Nothing) . mkx) <$> [1 .. (length $ dataConOrigArgTys d)]) (P F.PFalse)
+    mkx j  = symbol ("xx" ++ show j)
+    dcs    = tyConDataCons $ dataConTyCon dc
+
+makeMeasureSpec :: (ModName, Ms.BareSpec) -> BareM (Ms.MSpec SpecType DataCon)
+makeMeasureSpec (mod, spec) = inModule mod mkSpec
+  where
+    mkSpec = mkMeasureDCon =<< mkMeasureSort =<< first val <$> m
     m      = Ms.mkMSpec <$> mapM expandMeasure (Ms.measures spec)
                         <*> return (Ms.cmeasures spec)
                         <*> mapM expandMeasure (Ms.imeasures spec)
 
+makeMeasureSpec' :: MSpec SpecType DataCon
+                 -> ([(Var, SpecType)], [(LocSymbol, RRType F.Reft)])
 makeMeasureSpec' = mapFst (mapSnd uRType <$>) . Ms.dataConTypes . first (mapReft ur_reft)
 
+makeClassMeasureSpec :: MSpec (RType c tv (UReft r2)) t
+                     -> [(LocSymbol, CMeasure (RType c tv r2))]
 makeClassMeasureSpec (Ms.MSpec {..}) = tx <$> M.elems cmeasMap
   where
-    tx (M n s _) = (n, CM n (mapReft ur_reft s) -- [(t,m) | (IM n' t m) <- imeas, n == n']
-                   )
+    tx (M n s _) = (n, CM n (mapReft ur_reft s))
 
 
 mkMeasureDCon :: Ms.MSpec t LocSymbol -> BareM (Ms.MSpec t DataCon)
@@ -175,9 +196,9 @@
 mkMeasureDCon_ :: Ms.MSpec t LocSymbol -> [(Symbol, DataCon)] -> Ms.MSpec t DataCon
 mkMeasureDCon_ m ndcs = m' {Ms.ctorMap = cm'}
   where
-    m'  = fmap (tx.val) m
-    cm' = hashMapMapKeys (symbol . tx) $ Ms.ctorMap m'
-    tx  = mlookup (M.fromList ndcs)
+    m'                = fmap (tx.val) m
+    cm'               = hashMapMapKeys (symbol . tx) $ Ms.ctorMap m'
+    tx                = mlookup (M.fromList ndcs)
 
 measureCtors ::  Ms.MSpec t LocSymbol -> [LocSymbol]
 measureCtors = sortNub . fmap ctor . concat . M.elems . Ms.ctorMap
@@ -198,45 +219,41 @@
 
 varMeasures :: (Monoid r) => [Var] -> [(Symbol, Located (RRType r))]
 varMeasures vars = [ (symbol v, varSpecType v)  | v <- vars
-                                                , isDataConId v
+                                                , GM.isDataConId v
                                                 , isSimpleType $ varType v ]
 
 isSimpleType :: Type -> Bool
 isSimpleType = isFirstOrder . typeSort M.empty
 
--- OLD isSimpleType t   = null tvs && isNothing (splitFunTy_maybe tb)
--- OLD  where
--- OLD    (tvs, tb)    = splitForAllTys t
-
 varSpecType :: (Monoid r) => Var -> Located (RRType r)
-varSpecType v    = Loc l l' (ofType $ varType v)
-  where
-    l            = getSourcePos  v
-    l'           = getSourcePosE v
-
+varSpecType = fmap (ofType . varType) . GM.locNamedThing
 
 makeHaskellBounds :: F.TCEmb TyCon -> CoreProgram -> S.HashSet (Var, LocSymbol) -> BareM RBEnv
-makeHaskellBounds tce cbs xs
-  = do lmap <- gets logicEnv
-       M.fromList <$> mapM (makeHaskellBound tce lmap cbs) (S.toList xs)
-
-
-makeHaskellBound tce lmap  cbs (v, x) = case filter ((v  `elem`) . binders) cbs of
-    (NonRec v def:_)   -> do {e <- coreToFun' tce x v def; return $ toBound v x e}
-    (Rec [(v, def)]:_) -> do {e <- coreToFun' tce x v def; return $ toBound v x e}
-    _                  -> throwError $ mkError "Cannot make bound of haskell function"
-
-  where
-    binders (NonRec x _) = [x]
-    binders (Rec xes)    = fst <$> xes
-
-    coreToFun' tce x v def = case runToLogic tce lmap mkError $ coreToFun x v def of
-                           Left (xs, e) -> return (xs, e)
-                           Right e      -> throwError e
+makeHaskellBounds tce cbs xs = do
+  lmap <- gets logicEnv
+  M.fromList <$> mapM (makeHaskellBound tce lmap cbs) (S.toList xs)
 
-    mkError :: String -> Error
-    mkError str = ErrHMeas (sourcePosSrcSpan $ loc x) (pprint $ val x) (text str)
+makeHaskellBound :: F.TCEmb TyCon
+                 -> LogicMap
+                 -> [Bind Var]
+                 -> (Var, Located Symbol)
+                 -> BareM (LocSymbol, RBound)
+makeHaskellBound tce lmap  cbs (v, x) =
+  case filter ((v  `elem`) . GM.binders) cbs of
+    (NonRec v def:_)   -> toBound v x <$> coreToFun' tce lmap x v def return
+    (Rec [(v, def)]:_) -> toBound v x <$> coreToFun' tce lmap x v def return
+    _                  -> throwError $ errHMeas x "Cannot make bound of haskell function"
 
+coreToFun' :: F.TCEmb TyCon
+           -> LogicMap
+           -> LocSymbol
+           -> Var
+           -> CoreExpr
+           -> (([Var], Either F.Expr F.Expr) -> BareM a)
+           -> BareM a
+coreToFun' tce lmap x v def ok
+  = either throwError ok
+  $ runToLogic tce lmap (errHMeas x) (coreToFun x v def)
 
 toBound :: Var -> LocSymbol -> ([Var], Either F.Expr F.Expr) -> (LocSymbol, RBound)
 toBound v x (vs, Left p) = (x', Bound x' fvs ps xs p)
@@ -250,6 +267,7 @@
 
 toBound v x (vs, Right e) = toBound v x (vs, Left e)
 
+capitalizeBound :: Located Symbol -> Located Symbol
 capitalizeBound = fmap (symbol . toUpperHead . symbolString)
   where
     toUpperHead []     = []
@@ -258,11 +276,13 @@
 --------------------------------------------------------------------------------
 -- | Expand Measures -----------------------------------------------------------
 --------------------------------------------------------------------------------
+type BareMeasure = Measure (Located BareType) LocSymbol
 
-expandMeasure m
-  = do eqns <- sequence $ expandMeasureDef <$> eqns m
-       return $ m { sort = generalize (sort m)
-                  , eqns = eqns }
+expandMeasure :: BareMeasure -> BareM BareMeasure
+expandMeasure m = do
+  eqns <- sequence $ expandMeasureDef <$> eqns m
+  return $ m { sort = generalize <$> sort m
+             , eqns = eqns }
 
 expandMeasureDef :: Def t LocSymbol -> BareM (Def t LocSymbol)
 expandMeasureDef d
@@ -270,6 +290,6 @@
        return $ d { body = body }
 
 expandMeasureBody :: SourcePos -> Body -> BareM Body
-expandMeasureBody l (P p)   = P   <$> (resolve l =<< expandExpr p)
-expandMeasureBody l (R x p) = R x <$> (resolve l =<< expandExpr p)
+expandMeasureBody l (P p)   = P   <$> (resolve l =<< expand p)
+expandMeasureBody l (R x p) = R x <$> (resolve l =<< expand p)
 expandMeasureBody l (E e)   = E   <$> resolve l e
diff --git a/src/Language/Haskell/Liquid/Bare/Misc.hs b/src/Language/Haskell/Liquid/Bare/Misc.hs
--- a/src/Language/Haskell/Liquid/Bare/Misc.hs
+++ b/src/Language/Haskell/Liquid/Bare/Misc.hs
@@ -10,42 +10,72 @@
   , initMapSt
   , runMapTyVars
   , mapTyVars
+  , matchKindArgs
 
   , symbolRTyVar
   , simpleSymbolVar
 
   , hasBoolResult
+
+  , makeDataConChecker, makeDataSelector
   ) where
 
-import Prelude hiding (error)
-import TysWiredIn
-import Name
+import           Name
+import           Prelude                               hiding (error)
+import           TysWiredIn
 
-import Id
-import Type
-import TypeRep
-import Var
+import           Id
+import           Type
+import           Kind                                  (isKind)
+import           TypeRep
+import           Var
 
-import Control.Monad.Except (throwError)
-import Control.Monad.State
-import Data.Maybe (isNothing)
+import           DataCon
+import           Control.Monad.Except                  (MonadError, throwError)
+import           Control.Monad.State
+import           Data.Maybe                            (isNothing)
 
-import qualified Data.List as L
+import qualified Data.List                             as L
 
-import Language.Fixpoint.Misc  (sortNub)
-import Language.Fixpoint.Types (Symbol, Expr(..), Reft(..), Reftable(..), mkEApp, emptySEnv, memberSEnv, symbol, syms, toReft)
+import           Language.Fixpoint.Misc                (sortNub)
+import           Language.Fixpoint.Types               (Symbol, Expr(..), Reft(..), Reftable(..), mkEApp, emptySEnv, memberSEnv, symbol, syms, toReft, symbolString)
 
-import Language.Haskell.Liquid.GHC.Misc
-import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Misc (sortDiff)
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Misc          (sortDiff)
 
-import Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.Env
 
+makeDataConChecker :: DataCon -> Symbol
+makeDataConChecker d
+  | nilDataCon  == d
+  = symbol "isNull"
+  | consDataCon == d
+  = symbol "notIsNull"
+  | otherwise
+  = symbol $ ("is_"++) $ symbolString $ simpleSymbolVar $ dataConWorkId d
+makeDataSelector :: DataCon -> Int -> Symbol
+makeDataSelector d i
+  | consDataCon == d, i == 1
+  = symbol "head"
+  | consDataCon == d, i == 2
+  = symbol "tail"
+  | otherwise
+  = symbol $ (\ds -> ("select_"++ ds ++ "_" ++ show i)) $ symbolString $ simpleSymbolVar $ dataConWorkId d
 
 -- TODO: This is where unsorted stuff is for now. Find proper places for what follows.
 
 -- WTF does this function do?
+makeSymbols :: (Functor t1, Functor t2, Foldable t, Foldable t1, Foldable t2, Reftable r,
+                Reftable r1, Reftable r2, TyConable c, TyConable c1, TyConable c2, MonadState BareEnv m)
+            => (Id -> Bool)
+            -> [Id]
+            -> [Symbol]
+            -> t2 (a1, Located (RType c2 tv2 r2))
+            -> t1 (a, Located (RType c1 tv1 r1))
+            -> t (Located (RType c tv r))
+            -> m [(Symbol, Var)]
 makeSymbols f vs xs' xts yts ivs
   = do svs <- gets varEnv
        return $ L.nub ([ (x,v') | (x,v) <- svs, x `elem` xs, let (v',_,_) = joinVar vs (v,x,x)]
@@ -62,7 +92,8 @@
       hasBasicArgs _              = True
 
 
-freeSymbols ty = sortNub $ concat $ efoldReft (\_ _ -> []) (const ()) f (const id) emptySEnv [] (val ty)
+freeSymbols :: (Reftable r, TyConable c) => Located (RType c tv r) -> [Symbol]
+freeSymbols ty = sortNub $ concat $ efoldReft (\_ _ -> True) (\_ _ -> []) (\_ -> []) (const ()) f (const id) emptySEnv [] (val ty)
   where
     f γ _ r xs = let Reft (v, _) = toReft r in
                  [ x | x <- syms r, x /= v, not (x `memberSEnv` γ)] : xs
@@ -75,6 +106,7 @@
                         , errmsg :: Error
                         }
 
+initMapSt :: Error -> MapTyVarST
 initMapSt = MTVST []
 
 -- TODO: Maybe don't expose this; instead, roll this in with mapTyVar and export a
@@ -82,15 +114,15 @@
 runMapTyVars :: StateT MapTyVarST (Either Error) () -> MapTyVarST -> Either Error MapTyVarST
 runMapTyVars = execStateT
 
-mapTyVars :: (PPrint r, Reftable r) => Type -> RRType r -> StateT MapTyVarST (Either Error) ()
+mapTyVars :: Type -> SpecType -> StateT MapTyVarST (Either Error) ()
 mapTyVars τ (RAllT _ t)
   = mapTyVars τ t
 mapTyVars (ForAllTy _ τ) t
   = mapTyVars τ t
 mapTyVars (FunTy τ τ') (RFun _ t t' _)
-   = mapTyVars τ t  >> mapTyVars τ' t'
+   = mapTyVars τ t >> mapTyVars τ' t'
 mapTyVars (TyConApp _ τs) (RApp _ ts _ _)
-   = zipWithM_ mapTyVars τs ts
+   = zipWithM_ mapTyVars τs (matchKindArgs' τs ts)
 mapTyVars (TyVarTy α) (RVar a _)
    = do s  <- get
         s' <- mapTyRVar α a s
@@ -112,24 +144,44 @@
         mapTyVars τ' t'
 mapTyVars _ (RHole _)
   = return ()
+mapTyVars k _ | isKind k
+  = return ()
 mapTyVars _ _
   = throwError =<< errmsg <$> get
 
+mapTyRVar :: MonadError Error m
+          => Var -> RTyVar -> MapTyVarST -> m MapTyVarST
 mapTyRVar α a s@(MTVST αas err)
   = case lookup α αas of
       Just a' | a == a'   -> return s
               | otherwise -> throwError err
       Nothing             -> return $ MTVST ((α,a):αas) err
 
+matchKindArgs' :: [Type] -> [SpecType] -> [SpecType]
+matchKindArgs' ts1 ts2 = reverse $ go (reverse ts1) (reverse ts2)
+  where
+    go (_:ts1) (t2:ts2) = t2:go ts1 ts2
+    go ts      []       | all isKind ts
+                        = (ofType <$> ts) :: [SpecType]
+    go _       ts       = ts
 
 
+matchKindArgs :: [SpecType] -> [SpecType] -> [SpecType]
+matchKindArgs ts1 ts2 = reverse $ go (reverse ts1) (reverse ts2)
+  where
+    go (_:ts1) (t2:ts2) = t2:go ts1 ts2
+    go ts      []       = ts
+    go _       ts       = ts
 
+mkVarExpr :: Id -> Expr
 mkVarExpr v
   | isFunVar v = mkEApp (varFunSymbol v) []
   | otherwise  = EVar (symbol v)
 
+varFunSymbol :: Id -> Located Symbol
 varFunSymbol = dummyLoc . symbol . idDataCon
 
+isFunVar :: Id -> Bool
 isFunVar v   = isDataConId v && not (null αs) && isNothing tf
   where
     (αs, t)  = splitForAllTys $ varType v
@@ -143,10 +195,10 @@
                        Just v' -> (v',s,t)
                        Nothing -> (v,s,t)
 
-
 simpleSymbolVar :: Var -> Symbol
 simpleSymbolVar  = dropModuleNames . symbol . showPpr . getName
 
+hasBoolResult :: Type -> Bool
 hasBoolResult (ForAllTy _ t) = hasBoolResult t
 hasBoolResult (FunTy _ t)    | eqType boolTy t = True
 hasBoolResult (FunTy _ t)    = hasBoolResult t
diff --git a/src/Language/Haskell/Liquid/Bare/OfType.hs b/src/Language/Haskell/Liquid/Bare/OfType.hs
--- a/src/Language/Haskell/Liquid/Bare/OfType.hs
+++ b/src/Language/Haskell/Liquid/Bare/OfType.hs
@@ -5,16 +5,15 @@
     ofBareType
   , ofMeaSort
   , ofBSort
-
   , ofBPVar
-
-  , mkSpecType
+  , mkLSpecType
   , mkSpecType'
   ) where
 
 import Prelude hiding (error)
 import BasicTypes
 import Name
+import Kind (isKindVar)
 import TyCon hiding (synTyConRhs_maybe)
 import Type (expandTypeSynonyms)
 import TysWiredIn
@@ -28,11 +27,26 @@
 import Text.Parsec.Pos
 import Text.Printf
 
+import Text.PrettyPrint.HughesPJ
+
 import qualified Control.Exception as Ex
 import qualified Data.HashMap.Strict as M
 
-import Language.Fixpoint.Types (Expr(..), Reftable, Symbol, meet, mkSubst, subst, symbol, mkEApp)
+-- import Language.Fixpoint.Misc (traceShow)
+import Language.Fixpoint.Types ( atLoc
+                               , Expr(..)
+                               , Reftable
+                               , Symbol
+                               , meet
+                               , mkSubst
+                               , subst
+                               , symbol
+                               , symbolString
+                               , mkEApp
+                               -- , tracepp
+                               )
 
+
 import Language.Haskell.Liquid.GHC.Misc
 import Language.Haskell.Liquid.Misc (secondM)
 import Language.Haskell.Liquid.Types.RefType
@@ -45,11 +59,12 @@
 import Language.Haskell.Liquid.Bare.Resolve
 -- import Language.Haskell.Liquid.Bare.RefToLogic
 
---------------------------------------------------------------------------------
+-- import Data.Data (toConstr)
 
+--------------------------------------------------------------------------------
 ofBareType :: SourcePos -> BareType -> BareM SpecType
 ofBareType l
-  = ofBRType expandRTAliasApp (resolve l <=< expandReft)
+  = ofBRType expandRTAliasApp (resolve l <=< expand)
 
 ofMeaSort :: BareType -> BareM SpecType
 ofMeaSort
@@ -72,19 +87,20 @@
        return $ PV x t' v txys'
 
 --------------------------------------------------------------------------------
+mkLSpecType :: Located BareType -> BareM (Located SpecType)
+mkLSpecType t = atLoc t <$> mkSpecType (loc t) (val t)
 
 mkSpecType :: SourcePos -> BareType -> BareM SpecType
-mkSpecType l t
-  = mkSpecType' l (ty_preds $ toRTypeRep t) t
+mkSpecType l t = mkSpecType' l (ty_preds $ toRTypeRep t) t
 
 mkSpecType' :: SourcePos -> [PVar BSort] -> BareType -> BareM SpecType
-mkSpecType' l πs t
-  = ofBRType expandRTAliasApp resolveReft t
+mkSpecType' l πs t = ofBRType expandRTAliasApp resolveReft t
   where
-    resolveReft
-      = (resolve l <=< expandReft) . txParam l subvUReft (uPVar <$> πs) t
+    resolveReft    = (resolve l <=< expand) . txParam l subvUReft (uPVar <$> πs) t
 
 
+txParam :: SourcePos
+        -> ((UsedPVar -> UsedPVar) -> t) -> [UsedPVar] -> RType c tv r -> t
 txParam l f πs t = f (txPvar l (predMap πs t))
 
 txPvar :: SourcePos -> M.HashMap Symbol UsedPVar -> UsedPVar -> UsedPVar
@@ -94,13 +110,14 @@
         π'    = fromMaybe (panic (Just $ sourcePosSrcSpan l) err) $ M.lookup (pname π) m
         err   = "Bare.replaceParams Unbound Predicate Variable: " ++ show π
 
+predMap :: [UsedPVar] -> RType c tv r -> M.HashMap Symbol UsedPVar
 predMap πs t = M.fromList [(pname π, π) | π <- πs ++ rtypePredBinds t]
 
+rtypePredBinds :: RType c tv r -> [UsedPVar]
 rtypePredBinds = map uPVar . ty_preds . toRTypeRep
 
 --------------------------------------------------------------------------------
-
-ofBRType :: (PPrint r, UReftable r)
+ofBRType :: (PPrint r, UReftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r, SubsTy BTyVar BSort r)
          => (SourcePos -> RTAlias RTyVar SpecType -> [BRType r] -> r -> BareM (RRType r))
          -> (r -> BareM r)
          -> BRType r
@@ -117,9 +134,9 @@
       =  do env <- get
             goRFun (bounds env) x t1 t2 r
     go (RVar a r)
-      = RVar (symbolRTyVar a) <$> resolveReft r
+      = RVar (bareRTyVar a) <$> resolveReft r
     go (RAllT a t)
-      = RAllT (symbolRTyVar a) <$> go t
+      = RAllT (dropTyVarInfo $ mapTyVarValue bareRTyVar a) <$> go t
     go (RAllP a t)
       = RAllP <$> ofBPVar a <*> go t
     go (RAllS x t)
@@ -134,27 +151,28 @@
       = RHole <$> resolveReft r
     go (RExprArg (Loc l l' e))
       = RExprArg . Loc l l' <$> resolve l e
-
     go_ref (RProp ss (RHole r))
       = rPropP <$> mapM go_syms ss <*> resolveReft r
     go_ref (RProp ss t)
       = RProp <$> mapM go_syms ss <*> go t
-
-
     go_syms
       = secondM ofBSort
 
-    goRFun bounds _ (RApp c ps' _ _) t _ | Just bnd <- M.lookup c bounds
+    goRFun bounds _ (RApp c ps' _ _) t _
+      | Just bnd <- M.lookup (btc_tc c) bounds
       = do let (ts', ps) = splitAt (length $ tyvars bnd) ps'
            ts <- mapM go ts'
-           makeBound bnd ts [x | RVar x _ <- ps] <$> go t
+           makeBound bnd ts [x | RVar (BTV x) _ <- ps] <$> go t
     goRFun _ x t1 t2 r
       = RFun x <$> go t1 <*> go t2 <*> resolveReft r
 
-    goRApp aliases (RApp (Loc l _ c) ts _ r) | Just rta <- M.lookup c aliases
+    goRApp aliases (RApp tc ts _ r)
+      | Loc l _ c <- btc_tc tc
+      , Just rta <- M.lookup c aliases
       = appRTAlias l rta ts =<< resolveReft r
-    goRApp _ (RApp lc ts rs r)
-      =  do let l = loc lc
+    goRApp _ (RApp tc ts rs r)
+      =  do let lc = btc_tc tc
+            let l = loc lc
             r'  <- resolveReft r
             lc' <- Loc l l <$> matchTyCon lc (length ts)
             rs' <- mapM go_ref rs
@@ -184,24 +202,57 @@
 
 expandRTAliasApp :: SourcePos -> RTAlias RTyVar SpecType -> [BareType] -> RReft -> BareM SpecType
 expandRTAliasApp l rta args r
-  | length args == length αs + length εs
-    = do ts <- mapM (ofBareType l)                   $ take (length αs) args
-         es <- mapM (resolve l . exprArg (show err)) $ drop (length αs) args
+  | Just errmsg <- isOK
+    = Ex.throw errmsg
+  | otherwise
+    = do ts <- mapM (ofBareType l) $ take (length αs) args
+         es <- mapM (resolve l . exprArg (symbolString $ rtName rta)) $ drop (length αs) args
          let tsu = zipWith (\α t -> (α, toRSort t, t)) αs ts
          let esu = mkSubst $ zip (symbol <$> εs) es
          return $ subst esu . (`strengthen` r) . subsTyVars_meet tsu $ rtBody rta
-  | otherwise
-    = Ex.throw err
+
   where
     αs        = rtTArgs rta
     εs        = rtVArgs rta
-    err       :: Error
-    err       = ErrAliasApp (sourcePosSrcSpan l) (length args) (pprint $ rtName rta) (sourcePosSrcSpan $ rtPos rta) (length αs + length εs)
+    err       :: Doc -> Error
+    err       = ErrAliasApp (sourcePosSrcSpan l)
+                            (pprint $ rtName rta)
+                            (sourcePosSrcSpan $ rtPos rta)
 
+
+    isOK :: Maybe Error
+    isOK
+      | length args /= length targs + length eargs
+      = Just $ err (text "Expects" <+> (pprint $ length αs) <+> text "type arguments and then" <+> (pprint $ length εs) <+> text "expression arguments, but is given" <+> (pprint $ length args))
+      | length args /= length αs + length εs
+      = Just $ err (text "Expects" <+> (pprint $ length αs) <+> text "type arguments and " <+> (pprint $ length εs) <+> text "expression arguments, but is given" <+> (pprint $ length args))
+      | length αs /= length targs, not (null eargs)
+      = Just $ err (text "Expects" <+> (pprint $ length αs) <+> text "type arguments before expression arguments")
+--  Many expression arguments are parsed like type arguments
+{-
+      | length αs /= length targs
+      = Just $ err (text "Expects" <+> (pprint $ length αs) <+> text "type arguments but is given" <+> (pprint $ length targs))
+      | length εs /= length eargs
+      = Just $ err (text "Expects" <+> (pprint $ length εs) <+> text "expression arguments but is given" <+> (pprint $ length eargs))
+-}
+      | otherwise
+      = Nothing
+
+    notIsRExprArg (RExprArg _) = False
+    notIsRExprArg _            = True
+
+    targs = takeWhile notIsRExprArg args
+    eargs = dropWhile notIsRExprArg args
+
+
+
+
+
 -- | exprArg converts a tyVar to an exprVar because parser cannot tell
 -- HORRIBLE HACK To allow treating upperCase X as value variables X
 -- e.g. type Matrix a Row Col = List (List a Row) Col
 
+exprArg :: (PrintfArg t1)  => t1 -> BareType -> Expr
 exprArg _   (RExprArg e)
   = val e
 exprArg _   (RVar x _)
@@ -209,36 +260,48 @@
 exprArg _   (RApp x [] [] _)
   = EVar (symbol x)
 exprArg msg (RApp f ts [] _)
-  = mkEApp (symbol <$> f) (exprArg msg <$> ts)
+  = mkEApp (symbol <$> btc_tc f) (exprArg msg <$> ts)
 exprArg msg (RAppTy (RVar f _) t _)
   = mkEApp (dummyLoc $ symbol f) [exprArg msg t]
 exprArg msg z
   = panic Nothing $ printf "Unexpected expression parameter: %s in %s" (show z) msg
+  -- = panic Nothing $ printf "Unexpected expression parameter: %s in %s" (show z ++ "[" ++ show (toConstr z) ++ "]") msg
+    -- FIXME: Handle this error much better!
 
 --------------------------------------------------------------------------------
 
+bareTCApp :: (Monad m, PPrint r, Reftable r, SubsTy RTyVar RSort r)
+          => r
+          -> Located TyCon
+          -> [RTProp RTyCon RTyVar r]
+          -> [RType RTyCon RTyVar r]
+          -> m (RType RTyCon RTyVar r)
 bareTCApp r (Loc l _ c) rs ts | Just rhs <- synTyConRhs_maybe c
   = do when (realTcArity c < length ts) (Ex.throw err)
        return $ tyApp (subsTyVars_meet su $ ofType rhs) (drop nts ts) rs r
     where
-       tvs = tyConTyVarsDef c
+       tvs = filter (not . isKindVar) $ tyConTyVarsDef c
        su  = zipWith (\a t -> (rTyVar a, toRSort t, t)) tvs ts
        nts = length tvs
 
        err :: Error
-       err = ErrAliasApp (sourcePosSrcSpan l) (length ts) (pprint c) (getSrcSpan c) (realTcArity c)
+       err = ErrAliasApp (sourcePosSrcSpan l) (pprint c) (getSrcSpan c)
+                         (text "Expects " <+> (pprint $ realTcArity c) <+> text "arguments, but is given" <+> (pprint $ length ts))
 
 -- TODO expandTypeSynonyms here to
 bareTCApp r (Loc _ _ c) rs ts | isFamilyTyCon c && isTrivial t
-  = return $ expandRTypeSynonyms $ t `strengthen` r
+  = return (expandRTypeSynonyms $ t `strengthen` r)
   where t = rApp c ts rs mempty
 
 bareTCApp r (Loc _ _ c) rs ts
   = return $ rApp c ts rs r
 
+tyApp :: Reftable r
+      => RType c tv r
+      -> [RType c tv r] -> [RTProp c tv r] -> r -> RType c tv r
 tyApp (RApp c ts rs r) ts' rs' r' = RApp c (ts ++ ts') (rs ++ rs') (r `meet` r')
 tyApp t                []  []  r  = t `strengthen` r
 tyApp _                 _  _   _  = panic Nothing $ "Bare.Type.tyApp on invalid inputs"
 
-expandRTypeSynonyms :: (PPrint r, Reftable r) => RRType r -> RRType r
+expandRTypeSynonyms :: (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r) => RRType r -> RRType r
 expandRTypeSynonyms = ofType . expandTypeSynonyms . toType
diff --git a/src/Language/Haskell/Liquid/Bare/Plugged.hs b/src/Language/Haskell/Liquid/Bare/Plugged.hs
--- a/src/Language/Haskell/Liquid/Bare/Plugged.hs
+++ b/src/Language/Haskell/Liquid/Bare/Plugged.hs
@@ -13,7 +13,7 @@
 import Name
 import NameSet
 import TyCon
-import Type (expandTypeSynonyms)
+import Type (expandTypeSynonyms, Type)
 import Var
 
 
@@ -29,8 +29,8 @@
 import Language.Fixpoint.Types (mapPredReft, pAnd, conjuncts, TCEmb)
 -- import Language.Fixpoint.Types (traceFix, showFix)
 
-import Language.Haskell.Liquid.GHC.Misc (sourcePos2SrcSpan)
-import Language.Haskell.Liquid.Types.RefType (addTyConInfo, ofType, rVar, rTyVar, subts, toType, uReft)
+import Language.Haskell.Liquid.GHC.Misc      (sourcePos2SrcSpan)
+import Language.Haskell.Liquid.Types.RefType (updateRTVar, addTyConInfo, ofType, rVar, rTyVar, subts, toType, uReft)
 import Language.Haskell.Liquid.Types
 
 import Language.Haskell.Liquid.Misc (zipWithDefM)
@@ -38,18 +38,41 @@
 import Language.Haskell.Liquid.Bare.Env
 import Language.Haskell.Liquid.Bare.Misc
 
+
+-- NOTE: Be *very* careful with the use functions from RType -> GHC.Type,
+-- e.g. toType, in this module as they cannot handle LH type holes. Since
+-- this module is responsible for plugging the holes we obviously cannot
+-- assume, as in e.g. L.H.L.Constraint.* that they do not appear.
+
+makePluggedSigs :: Traversable t
+                => ModName
+                -> TCEmb TyCon
+                -> M.HashMap TyCon RTyCon
+                -> NameSet
+                -> t (Var, Located (RRType RReft))
+                -> BareM (t (Var, Located (RType RTyCon RTyVar RReft)))
 makePluggedSigs name embs tcEnv exports sigs
   = forM sigs $ \(x,t) -> do
       let τ = expandTypeSynonyms $ varType x
       let r = maybeTrue x name exports
       (x,) <$> plugHoles embs tcEnv x r τ t
 
+makePluggedAsmSigs :: Traversable t
+                   => TCEmb TyCon
+                   -> M.HashMap TyCon RTyCon
+                   -> t (Var, Located (RRType RReft))
+                   -> BareM (t (Var, Located (RType RTyCon RTyVar RReft)))
 makePluggedAsmSigs embs tcEnv sigs
   = forM sigs $ \(x,t) -> do
       let τ = expandTypeSynonyms $ varType x
       let r = const killHoles
       (x,) <$> plugHoles embs tcEnv x r τ t
 
+makePluggedDataCons :: Traversable t
+                    => TCEmb TyCon
+                    -> M.HashMap TyCon RTyCon
+                    -> t (DataCon, Located DataConP)
+                    -> BareM (t (DataCon, Located DataConP))
 makePluggedDataCons embs tcEnv dcs
   = forM dcs $ \(dc, Loc l l' dcp) -> do
        let (das, _, dts, dt) = dataConSig dc
@@ -62,7 +85,16 @@
                                 , tyArgs     = reverse tyArgs
                                 , tyRes      = tyRes})
 
+plugHoles :: (NamedThing a, PPrint a, Show a)
+          => TCEmb TyCon
+          -> M.HashMap TyCon RTyCon
+          -> a
+          -> (SpecType -> RReft -> RReft)
+          -> Type
+          -> Located SpecType
+          -> BareM (Located SpecType)
 plugHoles tce tyi x f t (Loc l l' st)
+                                    -- NOTE: this use of toType is safe as rt' is derived from t.
   = do tyvsmap <- case runMapTyVars (mapTyVars (toType rt') st'') initvmap of
                     Left e -> throwError e
                     Right s -> return $ vmap s
@@ -70,15 +102,16 @@
            st''' = subts su st''
            ps'   = fmap (subts su') <$> ps
            su'   = [(y, RVar (rTyVar x) ()) | (x, y) <- tyvsmap] :: [(RTyVar, RSort)]
-       Loc l l' . mkArrow αs ps' (ls1 ++ ls2) [] . makeCls cs' <$> go rt' st'''
+       Loc l l' . mkArrow (updateRTVar <$> αs) ps' (ls1 ++ ls2) [] . makeCls cs' <$> go rt' st'''
   where
-    (αs, _, ls1, rt)  = bkUniv (ofType t :: SpecType)
+    (αs, _, ls1, rt)  = bkUniv (ofType (expandTypeSynonyms t) :: SpecType)
     (cs, rt')         = bkClass rt
 
     (_, ps, ls2, st') = bkUniv st
     (_, st'')         = bkClass st'
     cs'               = [(dummySymbol, RApp c t [] mempty) | (c,t) <- cs]
-    initvmap          = initMapSt $ ErrMismatch lqSp (pprint x) (pprint t) (pprint $ toType st) hsSp
+
+    initvmap          = initMapSt $ ErrMismatch lqSp (pprint x) (pprint $ expandTypeSynonyms t) (pprint $ toRSort st) hsSp
     hsSp              = getSrcSpan x
     lqSp              = sourcePos2SrcSpan l l'
 
@@ -94,22 +127,23 @@
         addHole t                  = t
 
     go (RVar _ _)       v@(RVar _ _)       = return v
-    go (RFun _ i o _)   (RFun x i' o' r)   = RFun x <$> go i i' <*> go o o' <*> return r
-    go (RAllT _ t)      (RAllT a t')       = RAllT a <$> go t t'
-    go (RAllT a t)      t'                 = RAllT a <$> go t t'
-    go t                (RAllP p t')       = RAllP p <$> go t t'
-    go t                (RAllS s t')       = RAllS s <$> go t t'
-    go t                (RAllE b a t')     = RAllE b a <$> go t t'
-    go t                (REx b x t')       = REx b x <$> go t t'
+    go (RFun _ i o _)   (RFun x i' o' r)   = RFun x     <$> go i i' <*> go o o' <*> return r
+    go (RAllT _ t)      (RAllT a t')       = RAllT a    <$> go t t'
+    go (RAllT a t)      t'                 = RAllT a    <$> go t t'
+    go t                (RAllP p t')       = RAllP p    <$> go t t'
+    go t                (RAllS s t')       = RAllS s    <$> go t t'
+    go t                (RAllE b a t')     = RAllE b a  <$> go t t'
+    go t                (REx b x t')       = REx b x    <$> go t t'
     go t                (RRTy e r o t')    = RRTy e r o <$> go t t'
-    go (RAppTy t1 t2 _) (RAppTy t1' t2' r) = RAppTy <$> go t1 t1' <*> go t2 t2' <*> return r
+    go (RAppTy t1 t2 _) (RAppTy t1' t2' r) = RAppTy     <$> go t1 t1' <*> go t2 t2' <*> return r
     -- zipWithDefM: if ts and ts' have different length then the liquid and haskell types are different.
     -- keep different types for now, as a pretty error message will be created at Bare.Check
-    go (RApp _ ts _ _)  (RApp c ts' p r)   = RApp c <$> (zipWithDefM go ts ts') <*> return p <*> return r
+    go (RApp _ ts _ _)  (RApp c ts' p r)   --  length ts == length ts'
+                                           = RApp c <$> (zipWithDefM go ts $ matchKindArgs ts ts') <*> return p <*> return r
     -- If we reach the default case, there's probably an error, but we defer
     -- throwing it as checkGhcSpec does a much better job of reporting the
     -- problem to the user.
-    go _                st                 = return st
+    go st               _                 = return st
 
     makeCls cs t              = foldr (uncurry rFun) t cs
 
@@ -136,6 +170,7 @@
 
 -- killHoles r@(U (Reft (v, rs)) _ _) = r { ur_reft = Reft (v, filter (not . isHole) rs) }
 
+killHoles :: RReft -> RReft
 killHoles ur = ur { ur_reft = tx $ ur_reft ur }
   where
     tx r = {- traceFix ("killholes: r = " ++ showFix r) $ -} mapPredReft dropHoles r
diff --git a/src/Language/Haskell/Liquid/Bare/RTEnv.hs b/src/Language/Haskell/Liquid/Bare/RTEnv.hs
--- a/src/Language/Haskell/Liquid/Bare/RTEnv.hs
+++ b/src/Language/Haskell/Liquid/Bare/RTEnv.hs
@@ -1,8 +1,6 @@
 {-# LANGUAGE TupleSections #-}
 
-module Language.Haskell.Liquid.Bare.RTEnv (
-    makeRTEnv
-  ) where
+module Language.Haskell.Liquid.Bare.RTEnv ( makeRTEnv ) where
 
 import Prelude hiding (error)
 
@@ -13,41 +11,46 @@
 import qualified Data.HashMap.Strict as M
 import qualified Data.List           as L
 
-import Language.Fixpoint.Misc (fst3)
-import Language.Fixpoint.Types (Expr(..), Symbol)
-
-import Language.Haskell.Liquid.GHC.Misc (sourcePosSrcSpan)
-import Language.Haskell.Liquid.Types.RefType (symbolRTyVar)
-import Language.Haskell.Liquid.Types
-
-
+import           Language.Fixpoint.Misc (fst3)
+import           Language.Fixpoint.Types (Expr(..), Symbol, symbol) -- , tracepp)
+import           Language.Haskell.Liquid.GHC.Misc (sourcePosSrcSpan)
+import           Language.Haskell.Liquid.Types.RefType (symbolRTyVar)
+import           Language.Haskell.Liquid.Types
 import qualified Language.Haskell.Liquid.Measure as Ms
-
-import Language.Haskell.Liquid.Bare.Env
-import Language.Haskell.Liquid.Bare.Expand
-import Language.Haskell.Liquid.Bare.OfType
-import Language.Haskell.Liquid.Bare.Resolve
+import           Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.Expand
+import           Language.Haskell.Liquid.Bare.OfType
+import           Language.Haskell.Liquid.Bare.Resolve
 
 --------------------------------------------------------------------------------
-
-makeRTEnv specs
-  = do makeREAliases ets
-       makeRTAliases rts
-    where
-       rts = (concat [(m,) <$> Ms.aliases  s | (m, s) <- specs])
-       ets = (concat [(m,) <$> Ms.ealiases s | (m, s) <- specs])
-
+-- | `makeRTEnv` initializes the env needed to `expand` refinements and types,
+--   that is, the below needs to be called *before* we use `Expand.expand`
+--------------------------------------------------------------------------------
+makeRTEnv :: ModName
+          -> Ms.BareSpec
+          -> [(ModName, Ms.BareSpec)]
+          -> M.HashMap Symbol LMap
+          -> BareM ()
+--------------------------------------------------------------------------------
+makeRTEnv m lfSpec specs lm = do
+  makeREAliases (eAs ++ eAs' ++ eAs'')
+  makeRTAliases tAs
+  where
+    tAs   = [ (m, t) | (m, s)  <- specs,           t <- Ms.aliases   s ]
+    eAs   = [ (m, e) | (m, s)  <- specs,           e <- Ms.ealiases  s ]
+    eAs'  = [ (m, e) | e       <- Ms.ealiases lfSpec                   ]
+    eAs'' = [ (m, e) | (_, xl) <- M.toList lm, let e  = lmapEAlias  xl ]
 
-makeRTAliases
-  = graphExpand buildTypeEdges expBody
+makeRTAliases :: [(ModName, RTAlias Symbol BareType)] -> BareM ()
+makeRTAliases = graphExpand buildTypeEdges expBody
   where
-    expBody (mod, xt)
-      = inModule mod $
-          do let l  = rtPos  xt
-             let l' = rtPosE xt
-             body  <- withVArgs l l' (rtVArgs xt) $ ofBareType l $ rtBody xt
-             setRTAlias (rtName xt) $ mapRTAVars symbolRTyVar $ xt { rtBody = body}
+    expBody (m, xt) = inModule m $ do
+      let l  = rtPos  xt
+      let l' = rtPosE xt
+      body  <- withVArgs l l' (rtVArgs xt) $ ofBareType l $ rtBody xt
+      setRTAlias (rtName xt) $ mapRTAVars symbolRTyVar $ xt { rtBody = body }
 
+makeREAliases :: [(ModName, RTAlias Symbol Expr)] -> BareM ()
 makeREAliases
   = graphExpand buildExprEdges expBody
   where
@@ -55,15 +58,19 @@
       = inModule mod $
           do let l  = rtPos  xt
              let l' = rtPosE xt
-             body  <- withVArgs l l' (rtVArgs xt) $ resolve l =<< (expandExpr $ rtBody xt)
+             body  <- withVArgs l l' (rtVArgs xt) $ resolve l =<< expand (rtBody xt)
              setREAlias (rtName xt) $ xt { rtBody = body }
 
 
+graphExpand :: (PPrint t)
+            => (AliasTable t -> t -> [Symbol])
+            -> ((ModName, RTAlias Symbol t) -> BareM b)
+            -> [(ModName, RTAlias Symbol t)]
+            -> BareM ()
 graphExpand buildEdges expBody xts
   = do let table = buildAliasTable xts
            graph = buildAliasGraph (buildEdges table) (map snd xts)
        checkCyclicAliases table graph
-
        mapM_ expBody $ genExpandOrder table graph
 
 --------------------------------------------------------------------------------
@@ -72,7 +79,7 @@
 
 buildAliasTable :: [(ModName, RTAlias Symbol t)] -> AliasTable t
 buildAliasTable
-  = M.fromList . map (\(mod, rta) -> (rtName rta, (mod, rta)))
+  = M.fromList . map (\(m, rta) -> (rtName rta, (m, rta)))
 
 fromAliasSymbol :: AliasTable t -> Symbol -> (ModName, RTAlias Symbol t)
 fromAliasSymbol table sym
@@ -84,40 +91,30 @@
 type Graph t = [Node t]
 type Node  t = (t, t, [t])
 
-buildAliasGraph :: (t -> [Symbol]) -> [RTAlias Symbol t] -> Graph Symbol
+buildAliasGraph :: (PPrint t) => (t -> [Symbol]) -> [RTAlias Symbol t] -> Graph Symbol
 buildAliasGraph buildEdges
   = map (buildAliasNode buildEdges)
 
-buildAliasNode :: (t -> [Symbol]) -> RTAlias Symbol t -> Node Symbol
+buildAliasNode :: (PPrint t) => (t -> [Symbol]) -> RTAlias Symbol t -> Node Symbol
 buildAliasNode buildEdges alias
   = (rtName alias, rtName alias, buildEdges $ rtBody alias)
 
-
 checkCyclicAliases :: AliasTable t -> Graph Symbol -> BareM ()
 checkCyclicAliases table graph
   = case mapMaybe go $ stronglyConnComp graph of
-      [] ->
-        return ()
-      sccs ->
-        Ex.throw $ map err sccs
-  where
-    go (AcyclicSCC _)
-      = Nothing
-    go (CyclicSCC vs)
-      = Just vs
-
-    err :: [Symbol] -> Error
-    err scc@(rta:_)
-      = ErrAliasCycle { pos    = fst $ locate rta
-                      , acycle = map locate scc
-                      }
-    err []
-      = panic Nothing "Bare.RTEnv.checkCyclicAliases: No type aliases in reported cycle"
+      []   -> return ()
+      sccs -> Ex.throw (cycleAliasErr table <$> sccs)
+    where
+      go (CyclicSCC vs) = Just vs
+      go (AcyclicSCC _) = Nothing
 
-    locate sym
-      = ( sourcePosSrcSpan $ rtPos $ snd $ fromAliasSymbol table sym
-        , pprint sym
-        )
+cycleAliasErr :: AliasTable t -> [Symbol] -> Error
+cycleAliasErr _ []          = panic Nothing "checkCyclicAliases: No type aliases in reported cycle"
+cycleAliasErr t scc@(rta:_) = ErrAliasCycle { pos    = fst (locate rta)
+                                            , acycle = map locate scc }
+  where
+    locate sym = ( sourcePosSrcSpan $ rtPos $ snd $ fromAliasSymbol t sym
+                 , pprint sym )
 
 
 genExpandOrder :: AliasTable t -> Graph Symbol -> [(ModName, RTAlias Symbol t)]
@@ -138,7 +135,7 @@
 buildTypeEdges table = ordNub . go
   where
     go :: BareType -> [Symbol]
-    go (RApp c ts rs _) = go_alias (val c) ++ concatMap go ts ++ concatMap go (mapMaybe go_ref rs)
+    go (RApp c ts rs _) = go_alias (symbol c) ++ concatMap go ts ++ concatMap go (mapMaybe go_ref rs)
     go (RFun _ t1 t2 _) = go t1 ++ go t2
     go (RAppTy t1 t2 _) = go t1 ++ go t2
     go (RAllE _ t1 t2)  = go t1 ++ go t2
@@ -159,6 +156,7 @@
     go_ref (RProp  _ t) = Just t
 
 
+buildExprEdges :: M.HashMap Symbol a -> Expr -> [Symbol]
 buildExprEdges table  = ordNub . go
   where
     go :: Expr -> [Symbol]
@@ -170,7 +168,7 @@
 
     go (ESym _)       = []
     go (ECon _)       = []
-    go (EVar v)       = go_alias v 
+    go (EVar v)       = go_alias v
 
     go (PAnd ps)           = concatMap go ps
     go (POr ps)            = concatMap go ps
@@ -178,14 +176,14 @@
     go (PImp p q)          = go p ++ go q
     go (PIff p q)          = go p ++ go q
     go (PAll _ p)          = go p
-    go (ELam _ e)          = go e 
+    go (ELam _ e)          = go e
 
-    go (PAtom _ e1 e2)     = go e1 ++ go e2 
+    go (PAtom _ e1 e2)     = go e1 ++ go e2
 
-    go (ETApp e _)         = go e 
-    go (ETAbs e _)         = go e 
+    go (ETApp e _)         = go e
+    go (ETAbs e _)         = go e
     go (PKVar _ _)         = []
-    go (PExist _ e)        = go e 
-    go PGrad               = [] 
+    go (PExist _ e)        = go e
+    go (PGrad _ _ e)       = go e
 
     go_alias f           = [f | M.member f table ]
diff --git a/src/Language/Haskell/Liquid/Bare/RefToLogic.hs b/src/Language/Haskell/Liquid/Bare/RefToLogic.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Bare/RefToLogic.hs
+++ /dev/null
@@ -1,157 +0,0 @@
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE FlexibleInstances    #-}
-
-module Language.Haskell.Liquid.Bare.RefToLogic (
-    Transformable
-   , txRefToLogic
-
-  ) where
-
-import Prelude hiding (error)
-
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Misc (mapSnd)
-import Language.Haskell.Liquid.Bare.Env
-
-import Language.Fixpoint.Types hiding (R)
-
-
-import Language.Haskell.Liquid.GHC.Misc (dropModuleUnique)
-
-
-
-import qualified Data.HashMap.Strict as M
-
-
-
-txRefToLogic :: (Transformable r) => LogicMap -> InlnEnv -> r -> r
-txRefToLogic = tx'
-
-class Transformable a where
-  tx  :: Symbol -> Either LMap TInline -> a -> a
-
-  tx' :: LogicMap -> InlnEnv -> a -> a
-  tx' lmap imap x = M.foldrWithKey tx x limap
-    where
-      limap       = M.fromList ((mapSnd Left <$> (M.toList $ logic_map lmap)) ++ (mapSnd Right <$> M.toList imap))
-
-
-instance (Transformable a) => (Transformable [a]) where
-  tx s m xs = tx s m <$> xs
-
-instance Transformable DataConP where
-  tx s m x = x { tyConsts = tx s m (tyConsts x)
-               , tyArgs   = mapSnd (tx s m) <$> tyArgs x
-               , tyRes    = tx s m (tyRes x)
-               }
-
-instance Transformable TInline where
-  tx s m (TI xs e) = TI xs (tx s m e)
-
-instance (Transformable r) => Transformable (RType c v r) where
-  tx s m = fmap (tx s m)
-
-instance Transformable RReft where
-  tx s m = fmap (tx s m)
-
-instance Transformable Reft where
-  tx s m (Reft (v, p)) = if v == s
-                         then impossible Nothing "Transformable: v != s"
-                         else Reft(v, tx s m p)
-
--- OLD instance Transformable Refa where
--- OLD   tx s m (RConc p)     = RConc $ tx s m p
--- OLD   tx _ _ (RKvar x sub) = RKvar x sub
-
-instance (Transformable a, Transformable b) => Transformable (Either a b) where
-  tx s m (Left  x) = Left  (tx s m x)
-  tx s m (Right x) = Right (tx s m x)
-
-
-txQuant xss s m p
-  | s `elem` (fst <$> xss) = impossible Nothing "Transformable.tx on Pred"
-  | otherwise              = tx s m p
-
-
-instance Transformable Expr where
-  tx s m (EVar s')
-    | cmpSymbol s s'    = mexpr s' m
-    | otherwise         = EVar s'
-  tx s m e@(EApp _ _)   = txEApp (s, m) e -- f (tx s m es)
-  tx _ _ (ESym c)       = ESym c
-  tx _ _ (ECon c)       = ECon c
-  --tx _ _ (ELit l s')    = ELit l s'
-  tx s m (ENeg e)       = ENeg (tx s m e)
-  tx s m (EBin o e1 e2) = EBin o (tx s m e1) (tx s m e2)
-  tx s m (EIte p e1 e2) = EIte (tx s m p) (tx s m e1) (tx s m e2)
-  tx s m (ECst e s')    = ECst (tx s m e) s'
-  tx _ _ EBot           = EBot
-  tx _ _ PTrue           = PTrue
-  tx _ _ PFalse          = PFalse
-  tx _ _ PTop            = PTop
-  tx s m (PAnd ps)       = PAnd (tx s m <$> ps)
-  tx s m (POr ps)        = POr (tx s m <$> ps)
-  tx s m (PNot p)        = PNot (tx s m p)
-  tx s m (PImp p1 p2)    = PImp (tx s m p1) (tx s m p2)
-  tx s m (PIff p1 p2)    = PIff (tx s m p1) (tx s m p2)
-  tx s m (PAtom r e1 e2) = PAtom r (tx s m e1) (tx s m e2)
-  tx s m (ELam (x,t) e)  = ELam (x,t) $ txQuant [(x,t)] s m e
-  tx s m (PAll xss p)    = PAll xss   $ txQuant xss s m p
-  tx _ _ (PExist _ _)    = panic Nothing "tx: PExist is for fixpoint internals only"
- --  tx s m (PExist xss p)  = PExist xss $ txQuant xss s m p
-  tx _ _ p@(PKVar _ _)   = p
-  tx _ _ p@(ETApp _ _)   = p
-  tx _ _ p@(ETAbs _ _)   = p
-  tx _ _ p@PGrad         = p
-
-
-instance Transformable (Measure t c) where
-  tx s m x = x{eqns = tx s m <$> (eqns x)}
-
-instance Transformable (Def t c) where
-        tx s m x = x{body = tx s m (body x)}
-
-instance Transformable Body where
-  tx s m (E e)   = E $ tx s m e
-  tx s m (P p)   = P $ tx s m p
-  tx s m (R v p) = R v $ tx s m p
-
-mexpr _ (Left  (LMap _ [] e)) = e
-mexpr s (Left  (LMap _ _  _)) = EVar s
-mexpr _ (Right (TI _ e)) = e
--- mexpr s s' = panic Nothing ("mexpr on " ++ show s ++ "\t" ++ show s')
-
-txEApp (s,m) e = go f
-  where
-    (f, es) = splitEApp e 
-    go (EVar x) = txEApp' (s,m) x  (tx s m <$> es) 
-    go f        = eApps (tx s m f) (tx s m <$> es)
-
-txEApp' (s, (Left (LMap _ xs e))) f es
-  | cmpSymbol s f && length xs == length es   
-  = subst (mkSubst $ zip xs es) e
-  | otherwise
-  = mkEApp (dummyLoc f) es
-
-txEApp' (s, (Right (TI xs e))) f es
-  | cmpSymbol s f && length xs == length es
-  = subst (mkSubst $ zip xs es) e
-  | otherwise
-  = mkEApp (dummyLoc f) es
-
-
-{-
-txPApp (s, (Right (TI xs e))) f es
-  | cmpSymbol s (val f)
-  = subst (mkSubst $ zip xs es) e
-  | otherwise
-  = EApp f es
-
-txPApp (s, m) f es = txEApp (s, m) f es
--}
-
-cmpSymbol s1 {- symbol in Core -} s2 {- logical Symbol-}
-  = dropModuleNamesAndUnique s1 == dropModuleNamesAndUnique s2
-
-
-dropModuleNamesAndUnique = dropModuleUnique {- . dropModuleNames -}
diff --git a/src/Language/Haskell/Liquid/Bare/Resolve.hs b/src/Language/Haskell/Liquid/Bare/Resolve.hs
--- a/src/Language/Haskell/Liquid/Bare/Resolve.hs
+++ b/src/Language/Haskell/Liquid/Bare/Resolve.hs
@@ -8,17 +8,19 @@
   ) where
 
 
-import Prelude hiding (error)
+import           Prelude                             hiding (error)
+import           Var
 
-import Control.Monad.State
-import Data.Char (isUpper)
-import Text.Parsec.Pos
+import           Control.Monad.State
+import           Data.Char                           (isUpper)
+import           Text.Parsec.Pos
 
-import qualified Data.List           as L
+import qualified Data.List                           as L
 
-import qualified Data.HashMap.Strict as M
+import qualified Data.HashMap.Strict                 as M
 
-import Language.Fixpoint.Types.Names (prims, unconsSym)
+-- import           Language.Fixpoint.Misc              (traceShow)
+import           Language.Fixpoint.Types.Names       (prims, unconsSym)
 import Language.Fixpoint.Types (Expr(..),
                                 Qualifier(..),
                                 Reft(..),
@@ -28,12 +30,14 @@
                                 symbol,
                                 symbolFTycon)
 
-import Language.Haskell.Liquid.Misc (secondM, third3M)
-import Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Misc        (secondM, third3M)
+import           Language.Haskell.Liquid.Types
 
-import Language.Haskell.Liquid.Bare.Env
-import Language.Haskell.Liquid.Bare.Lookup
+import           Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.Lookup
 
+import           Data.Maybe                          (fromMaybe)
+
 class Resolvable a where
   resolve :: SourcePos -> a -> BareM a
 
@@ -59,13 +63,13 @@
   resolve l (PAtom r e1 e2) = PAtom r <$> resolve l e1 <*> resolve l e2
   resolve l (ELam (x,t) e)  = ELam    <$> ((,) <$> resolve l x <*> resolve l t) <*> resolve l e
   resolve l (PAll vs p)     = PAll    <$> mapM (secondM (resolve l)) vs <*> resolve l p
-  resolve l (ETApp e s)     = ETApp   <$> resolve l e <*> resolve l s 
-  resolve l (ETAbs e s)     = ETAbs   <$> resolve l e <*> resolve l s 
-  resolve _ (PKVar k s)     = return $ PKVar k s 
+  resolve l (ETApp e s)     = ETApp   <$> resolve l e <*> resolve l s
+  resolve l (ETAbs e s)     = ETAbs   <$> resolve l e <*> resolve l s
+  resolve _ (PKVar k s)     = return $ PKVar k s
   resolve l (PExist ss e)   = PExist ss <$> resolve l e
-  resolve _ (ESym s)        = return $ ESym s 
-  resolve _ (ECon c)        = return $ ECon c 
-  resolve _ PGrad           = return PGrad 
+  resolve _ (ESym s)        = return $ ESym s
+  resolve _ (ECon c)        = return $ ECon c
+  resolve l (PGrad k su e)  = PGrad k su <$> resolve l e 
 
 instance Resolvable LocSymbol where
   resolve _ ls@(Loc l l' s)
@@ -80,8 +84,10 @@
                                    return $ Loc l l' qs
            _                 -> return ls
 
+addSym :: MonadState BareEnv m => (Symbol, Var) -> m ()
 addSym x = modify $ \be -> be { varEnv = varEnv be `L.union` [x] }
 
+isCon :: Symbol -> Bool
 isCon s
   | Just (c,_) <- unconsSym s = isUpper c
   | otherwise                 = False
@@ -100,7 +106,10 @@
   resolve l (FFunc s1 s2) = FFunc <$> (resolve l s1) <*> (resolve l s2)
   resolve _ (FTC c)
     | tcs' `elem` prims   = FTC <$> return c
-    | otherwise           = FTC <$> (symbolFTycon . Loc l l' . symbol <$> lookupGhcTyCon tcs)
+    | otherwise           = do ty     <- lookupGhcTyCon tcs
+                               emb    <- embeds <$> get
+                               let ftc = symbolFTycon $ Loc l l' $ symbol ty
+                               return  $ FTC $ fromMaybe ftc (M.lookup ty emb)
     where
       tcs@(Loc l l' tcs') = fTyconSymbol c
   resolve l (FApp t1 t2) = FApp <$> resolve l t1 <*> resolve l t2
diff --git a/src/Language/Haskell/Liquid/Bare/Spec.hs b/src/Language/Haskell/Liquid/Bare/Spec.hs
--- a/src/Language/Haskell/Liquid/Bare/Spec.hs
+++ b/src/Language/Haskell/Liquid/Bare/Spec.hs
@@ -1,7 +1,7 @@
-{-# LANGUAGE FlexibleContexts         #-}
+{-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ParallelListComp #-}
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE ParallelListComp  #-}
+{-# LANGUAGE TupleSections     #-}
 
 module Language.Haskell.Liquid.Bare.Spec (
     makeClasses
@@ -9,7 +9,9 @@
   , makeHints
   , makeLVar
   , makeLazy
-  , makeHIMeas
+  , makeAutoInsts
+  , makeDefs
+  , makeHMeas, makeHInlines
   , makeTExpr
   , makeTargetVars
   , makeAssertSpec
@@ -17,93 +19,140 @@
   , makeDefaultMethods
   , makeIAliases
   , makeInvariants
+  , makeNewTypes
   , makeSpecDictionaries
   , makeBounds
   , makeHBounds
   ) where
 
-import Prelude hiding (error)
-import MonadUtils (mapMaybeM)
-import TyCon
-import Var
+import           CoreSyn                                    (CoreBind)
+import           DataCon
+import           MonadUtils                                 (mapMaybeM)
+import           Prelude                                    hiding (error)
+import           TyCon
+import           Var
 
 
-import Control.Monad.Except
-import Control.Monad.State
-import Data.Maybe
+import           Control.Monad.Except
+import           Control.Monad.State
+import           Data.Maybe
 
 
-import qualified Data.List           as L
-import qualified Data.HashSet        as S
-import qualified Data.HashMap.Strict as M
+import qualified Data.List                                  as L
+import qualified Data.HashSet                               as S
+import qualified Data.HashMap.Strict                        as M
 
-import Language.Fixpoint.Misc (group, snd3)
-import Language.Fixpoint.Types.Names (dropSym, isPrefixOfSym,  symbolString)
-import Language.Fixpoint.Types (Qualifier(..), symbol, atLoc)
-import Language.Haskell.Liquid.Types.Dictionaries
-import Language.Haskell.Liquid.GHC.Misc ( dropModuleNames, qualifySymbol, takeModuleNames, getSourcePos, showPpr, symbolTyVar)
-import Language.Haskell.Liquid.Misc (addFst3, fourth4, mapFst, concatMapM)
-import Language.Haskell.Liquid.Types.RefType (generalize, rVar, symbolRTyVar)
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Types.Bounds
 
-import qualified Language.Haskell.Liquid.Measure as Ms
 
-import Language.Haskell.Liquid.Bare.Env
-import Language.Haskell.Liquid.Bare.Existential
-import Language.Haskell.Liquid.Bare.Lookup
-import Language.Haskell.Liquid.Bare.Misc (joinVar)
-import Language.Haskell.Liquid.Bare.OfType
-import Language.Haskell.Liquid.Bare.Resolve
-import Language.Haskell.Liquid.Bare.SymSort
-import Language.Haskell.Liquid.Bare.Measure
+import           Language.Fixpoint.Misc                     (group, snd3, groupList)
+-- import           Language.Fixpoint.Misc                     (traceShow)
 
+
+import qualified Language.Fixpoint.Types                    as F
+import           Language.Haskell.Liquid.Types.Dictionaries
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Misc
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Types.Bounds
+
+import qualified Language.Haskell.Liquid.Measure            as Ms
+
+import           Language.Haskell.Liquid.Bare.Env
+import           Language.Haskell.Liquid.Bare.Existential
+import           Language.Haskell.Liquid.Bare.Lookup
+import           Language.Haskell.Liquid.Bare.Misc          (joinVar)
+import           Language.Haskell.Liquid.Bare.OfType
+import           Language.Haskell.Liquid.Bare.Resolve
+import           Language.Haskell.Liquid.Bare.SymSort
+import           Language.Haskell.Liquid.Bare.Measure
+
+makeClasses :: ModName
+            -> Config
+            -> [Var]
+            -> (ModName, Ms.Spec (Located BareType) bndr)
+            -> BareM [((DataCon, DataConP), [(ModName, Var, LocSpecType)])]
 makeClasses cmod cfg vs (mod, spec) = inModule mod $ mapM mkClass $ Ms.classes spec
   where
     --FIXME: cleanup this code
     unClass = snd . bkClass . fourth4 . bkUniv
-    mkClass (RClass c ss as ms)
-            = do let l   = loc  c
-                 let l'  = locE c
-                 tc  <- lookupGhcTyCon c
-                 ss' <- mapM (mkSpecType l) ss
+    mkClass (RClass cc ss as ms)
+            = do let c      = btc_tc cc
+                 let l      = loc  c
+                 let l'     = locE c
+                 tc        <- lookupGhcTyCon c
+                 ss'       <- mapM mkLSpecType ss
                  let (dc:_) = tyConDataCons tc
-                 let αs  = map symbolRTyVar as
-                 let as' = [rVar $ symbolTyVar a | a <- as ]
-                 let ms' = [ (s, rFun "" (RApp c (flip RVar mempty <$> as) [] mempty) t) | (s, t) <- ms]
+                 let αs  = map bareRTyVar as
+                 let as' = [rVar $ symbolTyVar $ F.symbol a | a <- as ]
+                 let ms' = [ (s, rFun "" (RApp cc (flip RVar mempty <$> as) [] mempty) <$> t) | (s, t) <- ms]
                  vts <- makeSpec (noCheckUnknown cfg || cmod /= mod) vs ms'
                  let sts = [(val s, unClass $ val t) | (s, _)    <- ms
                                                      | (_, _, t) <- vts]
                  let t   = rCls tc as'
-                 let dcp = DataConP l αs [] [] ss' (reverse sts) t l'
+                 let dcp = DataConP l αs [] [] (val <$> ss') (reverse sts) t l'
                  return ((dc,dcp),vts)
 
+makeQualifiers :: (ModName, Ms.Spec ty bndr)
+               -> BareM [F.Qualifier]
 makeQualifiers (mod,spec) = inModule mod mkQuals
   where
-    mkQuals = mapM (\q -> resolve (q_pos q) q) $ Ms.qualifiers spec
+    mkQuals = mapM (\q -> resolve (F.qPos q) q) $ Ms.qualifiers spec
 
+makeHints :: [Var] -> Ms.Spec ty bndr -> BareM [(Var, [Int])]
 makeHints   vs spec = varSymbols id vs $ Ms.decr spec
-makeLVar    vs spec = fmap fst <$> (varSymbols id vs $ [(v, ()) | v <- Ms.lvars spec])
-makeLazy    vs spec = fmap fst <$> (varSymbols id vs $ [(v, ()) | v <- S.toList $ Ms.lazy    spec])
-makeHBounds vs spec = varSymbols id vs $ [(v, v ) | v <- S.toList $ Ms.hbounds spec]
+
+makeLVar :: [Var]
+         -> Ms.Spec ty bndr
+         -> BareM [Var]
+makeLVar    vs spec = fmap fst <$> varSymbols id vs [(v, ()) | v <- Ms.lvars spec]
+
+makeLazy :: [Var]
+         -> Ms.Spec ty bndr
+         -> BareM [Var]
+makeLazy    vs spec = fmap fst <$> varSymbols id vs [(v, ()) | v <- S.toList $ Ms.lazy spec]
+
+makeAutoInsts :: [Var]
+              -> Ms.Spec ty bndr
+              -> BareM [(Var, Maybe Int)]
+makeAutoInsts vs spec = varSymbols id vs (M.toList $ Ms.autois spec)
+
+
+makeDefs :: [Var] -> Ms.Spec ty bndr -> BareM [(Var, F.Symbol)]
+makeDefs vs spec = varSymbols id vs (M.toList $ Ms.defs spec)
+
+makeHBounds :: [Var] -> Ms.Spec ty bndr -> BareM [(Var, LocSymbol)]
+makeHBounds vs spec = varSymbols id vs [(v, v ) | v <- S.toList $ Ms.hbounds spec]
+
+makeTExpr :: [Var] -> Ms.Spec ty bndr -> BareM [(Var, [Located F.Expr])]
 makeTExpr   vs spec = varSymbols id vs $ Ms.termexprs spec
--- makeHIMeas  vs spec = fmap (uncurry $ flip Loc) <$> (varSymbols id vs $ [(v, loc v) | v <- (S.toList $ Ms.hmeas spec) ++ (S.toList $ Ms.inlines spec)])
-makeHIMeas  vs spec = fmap tx <$> (varSymbols id vs $ [(v, (loc v, locE v)) | v <- (S.toList $ Ms.hmeas spec) ++ (S.toList $ Ms.inlines spec)])
-  where
-    tx (x,(l, l'))  = Loc l l' x
 
+makeHInlines :: [Var] -> Ms.Spec ty bndr -> BareM [(Located Var, LocSymbol)]
+makeHInlines = makeHIMeas Ms.inlines
 
+makeHMeas :: [Var] -> Ms.Spec ty bndr -> BareM [(Located Var, LocSymbol)]
+makeHMeas = makeHIMeas Ms.hmeas
 
+makeHIMeas :: (Ms.Spec ty bndr -> S.HashSet LocSymbol)
+           -> [Var]
+           -> Ms.Spec ty bndr
+           -> BareM [(Located Var, LocSymbol)]
+makeHIMeas f vs spec
+  = fmap tx <$> varSymbols id vs [(v, (loc v, locE v, v)) | v <- S.toList (f spec)]
+  where
+    tx (x, (l, l', s))  = (Loc l l' x, s)
 
 varSymbols :: ([Var] -> [Var]) -> [Var] -> [(LocSymbol, a)] -> BareM [(Var, a)]
-varSymbols f vs  = concatMapM go
-  where lvs        = M.map L.sort $ group [(sym v, locVar v) | v <- vs]
-        sym        = dropModuleNames . symbol . showPpr
-        locVar v   = (getSourcePos v, v)
-        go (s, ns) = case M.lookup (val s) lvs of
-                     Just lvs -> return ((, ns) <$> varsAfter f s lvs)
-                     Nothing  -> ((:[]).(,ns)) <$> lookupGhcVar s
+varSymbols f vs = concatMapM go
+  where
+    lvs         = M.map L.sort $ group [(sym v, locVar v) | v <- vs]
+    sym         = dropModuleNames . F.symbol . showPpr
+    locVar v    = (getSourcePos v, v)
+    go (s, ns)  = case M.lookup (val s) lvs of
+                    Just lvs -> return  ((, ns) <$> varsAfter f s lvs)
+                    Nothing  -> ((:[]) . (,ns)) <$> lookupGhcVar s
 
+varsAfter :: ([b] -> [b]) -> Located a -> [(F.SourcePos, b)] -> [b]
 varsAfter f s lvs
   | eqList (fst <$> lvs)    = f (snd <$> lvs)
   | otherwise               = map snd $ takeEqLoc $ dropLeLoc lvs
@@ -115,9 +164,9 @@
     eqList (x:xs)           = all (==x) xs
 
 
-------------------------------------------------------------------
--- | API: Bare Refinement Types ----------------------------------
-------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | API: Bare Refinement Types ------------------------------------------------
+--------------------------------------------------------------------------------
 
 makeTargetVars :: ModName -> [Var] -> [String] -> BareM [Var]
 makeTargetVars name vs ss
@@ -125,65 +174,79 @@
        ns    <- liftIO $ concatMapM (lookupName env name . dummyLoc . prefix) ss
        return $ filter ((`elem` ns) . varName) vs
     where
-       prefix s = qualifySymbol (symbol name) (symbol s)
-
+       prefix s = qualifySymbol (F.symbol name) (F.symbol s)
 
-makeAssertSpec cmod cfg vs lvs (mod,spec)
+makeAssertSpec :: ModName -> Config -> [Var] -> [Var] -> (ModName, Ms.BareSpec)
+               -> BareM [(ModName, Var, LocSpecType)]
+makeAssertSpec cmod cfg vs lvs (mod, spec)
   | cmod == mod
   = makeLocalSpec cfg cmod vs lvs (grepClassAsserts (Ms.rinstance spec)) (Ms.sigs spec ++ Ms.localSigs spec)
   | otherwise
   = inModule mod $ makeSpec True vs $ Ms.sigs spec
 
-makeAssumeSpec cmod cfg vs lvs (mod,spec)
+makeAssumeSpec
+  :: ModName -> Config -> [Var] -> [Var] -> (ModName, Ms.BareSpec)
+  -> BareM [(ModName, Var, LocSpecType)]
+makeAssumeSpec cmod cfg vs lvs (mod, spec)
   | cmod == mod
-  = makeLocalSpec cfg cmod vs lvs [] $ Ms.asmSigs spec
+  = makeLocalSpec cfg cmod vs lvs (grepClassAssumes (Ms.rinstance spec)) $ Ms.asmSigs spec
   | otherwise
   = inModule mod $ makeSpec True vs $ Ms.asmSigs spec
 
-grepClassAsserts  = concatMap go
+grepClassAsserts :: [RInstance t] -> [(Located F.Symbol, t)]
+grepClassAsserts           = concatMap go
    where
-    go    = map goOne . risigs
-    goOne = mapFst (fmap (symbol . (".$c" ++ ) . symbolString))
+    go    xts              = mapMaybe goOne (risigs xts)
+    goOne (x, RISig t)     = Just ((F.symbol . (".$c" ++ ) . F.symbolString) <$> x, t)
+    goOne (_, RIAssumed _) = Nothing
 
+grepClassAssumes :: [RInstance t] -> [(Located F.Symbol, t)]
+grepClassAssumes  = concatMap go
+   where
+    go    xts              = catMaybes $ map goOne $ risigs xts
+    goOne (x, RIAssumed t) = Just (fmap (F.symbol . (".$c" ++ ) . F.symbolString) x, t)
+    goOne (_, RISig _)     = Nothing
 
 makeDefaultMethods :: [Var] -> [(ModName,Var,Located SpecType)]
                    -> [(ModName, Var ,Located SpecType)]
 makeDefaultMethods defVs sigs
   = [ (m,dmv,t)
     | dmv <- defVs
-    , let dm = symbol $ showPpr dmv
-    , "$dm" `isPrefixOfSym` dropModuleNames dm
+    , let dm = F.symbol $ showPpr dmv
+    , "$dm" `F.isPrefixOfSym` dropModuleNames dm
     , let mod = takeModuleNames dm
-    , let method = qualifySymbol mod $ dropSym 3 (dropModuleNames dm)
-    , let mb = L.find ((method `isPrefixOfSym`) . symbol . snd3) sigs
+    , let method = qualifySymbol mod $ F.dropSym 3 (dropModuleNames dm)
+    , let mb = L.find ((method `F.isPrefixOfSym`) . F.symbol . snd3) sigs
     , isJust mb
     , let Just (m,_,t) = mb
     ]
 
-makeLocalSpec :: Config -> ModName -> [Var] -> [Var] -> [(LocSymbol, BareType)] -> [(LocSymbol, BareType)]
-                    -> BareM [(ModName, Var, Located SpecType)]
+makeLocalSpec :: Config -> ModName -> [Var] -> [Var]
+              -> [(LocSymbol, Located BareType)]
+              -> [(LocSymbol, Located BareType)]
+              -> BareM [(ModName, Var, Located SpecType)]
 makeLocalSpec cfg mod vs lvs cbs xbs
   = do vbs1  <- fmap expand3 <$> varSymbols fchoose lvs (dupSnd <$> xbs1)
        vts1  <- map (addFst3 mod) <$> mapM mkVarSpec vbs1
        vts2  <- makeSpec (noCheckUnknown cfg) vs xbs2
        return $ vts1 ++ vts2
   where
-    xbs1 = xbs1' ++ cbs
+    xbs1                = xbs1' ++ cbs
     (xbs1', xbs2)       = L.partition (modElem mod . fst) xbs
     dupSnd (x, y)       = (dropMod x, (x, y))
     expand3 (x, (y, w)) = (x, y, w)
-    dropMod             = fmap (dropModuleNames . symbol)
+    dropMod             = fmap (dropModuleNames . F.symbol)
     fchoose ls          = maybe ls (:[]) $ L.find (`elem` vs) ls
-    modElem n x         = (takeModuleNames $ val x) == (symbol n)
-
-makeSpec :: Bool -> [Var] -> [(LocSymbol, BareType)]
-                 -> BareM [(ModName, Var, Located SpecType)]
-makeSpec ignoreUnknown vs xbs
-  = do vbs <- map (joinVar vs) <$> lookupIds ignoreUnknown xbs
-       (BE { modName = mod}) <- get
-       map (addFst3 mod) <$> mapM mkVarSpec vbs
+    modElem n x         = takeModuleNames (val x) == F.symbol n
 
+makeSpec :: Bool -> [Var] -> [(LocSymbol, Located BareType)]
+         -> BareM [(ModName, Var, LocSpecType)]
+makeSpec ignoreUnknown vs xbs = do
+  vbs <- map (joinVar vs) <$> lookupIds ignoreUnknown xbs
+  (BE { modName = mod}) <- get
+  map (addFst3 mod) <$> mapM mkVarSpec vbs
 
+lookupIds :: GhcLookup a => Bool -> [(a, t)] -> BareM [(Var, a, t)]
 lookupIds ignoreUnknown
   = mapMaybeM lookup
   where
@@ -195,65 +258,113 @@
     handleError err
       = throwError err
 
-mkVarSpec :: (Var, LocSymbol, BareType) -> BareM (Var, Located SpecType)
-mkVarSpec (v, Loc l l' _, b) = tx <$> mkSpecType l b
+mkVarSpec :: (Var, LocSymbol, Located BareType) -> BareM (Var, Located SpecType)
+mkVarSpec (v, _, b) = tx <$> mkLSpecType b
   where
-    tx = (v,) . Loc l l' . generalize
-
+    tx              = (v,) . fmap generalize
 
+makeIAliases :: (ModName, Ms.Spec (Located BareType) bndr)
+             -> BareM [(Located SpecType, Located SpecType)]
 makeIAliases (mod, spec)
   = inModule mod $ makeIAliases' $ Ms.ialiases spec
 
 makeIAliases' :: [(Located BareType, Located BareType)] -> BareM [(Located SpecType, Located SpecType)]
-makeIAliases' = mapM mkIA
+makeIAliases'     = mapM mkIA
   where
-    mkIA (t1, t2)      = (,) <$> mkI t1 <*> mkI t2
-    mkI (Loc l l' t)   = Loc l l' . generalize <$> mkSpecType l t
+    mkIA (t1, t2) = (,) <$> mkI t1 <*> mkI t2
+    mkI t         = fmap generalize <$> mkLSpecType t
 
+makeNewTypes :: (ModName, Ms.Spec (Located BareType) bndr)
+               -> BareM [(TyCon, Located SpecType)]
+makeNewTypes (mod,spec)
+  = inModule mod $ makeNewTypes' $ Ms.newtyDecls spec
+
+makeNewTypes' :: [DataDecl] -> BareM [(TyCon, Located SpecType)]
+makeNewTypes' = mapM mkNT
+  where
+    mkNT :: DataDecl -> BareM (TyCon, Located SpecType)
+    mkNT d       = (,) <$> lookupGhcTyCon (tycName d)
+                       <*> (fmap generalize <$> (getTy (tycSrcPos d) (tycDCons d) >>= mkLSpecType))
+    getTy l [(_,[(_,t)])] = return $ withLoc l t
+    getTy l _             = throwError $ ErrOther (sourcePosSrcSpan l) "bad new type declaration"
+
+    withLoc s = Loc s s
+
+
+makeInvariants :: (ModName, Ms.Spec (Located BareType) bndr)
+               -> BareM [(Maybe Var, Located SpecType)]
 makeInvariants (mod,spec)
   = inModule mod $ makeInvariants' $ Ms.invariants spec
 
-makeInvariants' :: [Located BareType] -> BareM [Located SpecType]
+makeInvariants' :: [Located BareType] -> BareM [(Maybe Var, Located SpecType)]
 makeInvariants' = mapM mkI
   where
-    mkI (Loc l l' t)  = Loc l l' . generalize <$> mkSpecType l t
-
+    mkI t       = (Nothing,) . fmap generalize <$> mkLSpecType t
 
+makeSpecDictionaries :: F.TCEmb TyCon -> [Var] -> [(a, Ms.BareSpec)] -> GhcSpec
+                     -> BareM GhcSpec
 makeSpecDictionaries embs vars specs sp
   = do ds <- (dfromList . concat)  <$>  mapM (makeSpecDictionary embs vars) specs
-       return $ sp {dicts = ds}
+       return $ sp { gsDicts = ds }
 
+
+
+makeSpecDictionary :: F.TCEmb TyCon -> [Var] -> (a, Ms.BareSpec)
+                   -> BareM [(Var, M.HashMap F.Symbol (RISig SpecType))]
 makeSpecDictionary embs vars (_, spec)
-  = catMaybes <$> mapM (makeSpecDictionaryOne embs vars) (Ms.rinstance spec)
+  = (catMaybes . resolveDictionaries vars) <$> mapM (makeSpecDictionaryOne embs) (Ms.rinstance spec)
 
-makeSpecDictionaryOne embs vars (RI x t xts)
-  = do t'  <-  mkTy t
+
+makeSpecDictionaryOne :: F.TCEmb TyCon -> RInstance (Located BareType)
+                      -> BareM (F.Symbol, M.HashMap F.Symbol (RISig SpecType))
+makeSpecDictionaryOne embs (RI x t xts)
+  = do t'  <- mapM mkLSpecType t
        tyi <- gets tcEnv
-       ts' <- map (val . txRefSort tyi embs . fmap txExpToBind) <$> mapM mkTy' ts
-       let (d, dts) = makeDictionary $ RI x (val t') $ zip xs ts'
-       let v = lookupName d
-       return ((, dts) <$> v)
+       ts' <- map (tidy tyi) <$> (mapM mkLSpecIType ts)
+       return $ makeDictionary $ RI x (val <$> t') $ zip xs ts'
   where
-    mkTy  t  = atLoc x         <$> mkSpecType (loc x) t
-    mkTy' t  = fmap generalize <$> mkTy t
+    mkTy' :: Located BareType -> BareM (Located SpecType)
+    mkTy' t  = fmap generalize <$> mkLSpecType t
+
     (xs, ts) = unzip xts
+
+    tidy :: TCEnv -> RISig (Located SpecType) -> RISig SpecType
+    tidy tyi = fmap (val . txRefSort tyi embs . fmap txExpToBind)
+
+    mkLSpecIType :: RISig (Located BareType) -> BareM (RISig (Located SpecType))
+    mkLSpecIType (RISig     t) = RISig     <$> mkTy' t
+    mkLSpecIType (RIAssumed t) = RIAssumed <$> mkTy' t
+
+
+resolveDictionaries :: [Var] -> [(F.Symbol, M.HashMap F.Symbol (RISig SpecType))] -> [Maybe (Var, M.HashMap F.Symbol (RISig SpecType))]
+resolveDictionaries vars ds  = lookupVar <$> concat (go <$> groupList ds)
+ where
+    go (x,is)           = addIndex 0 x $ reverse is
+
+    -- GHC internal postfixed same name dictionaries with ints
+    addIndex _ _ []     = []
+    addIndex _ x [i]    = [(x,i)]
+    addIndex j x (i:is) = (F.symbol (F.symbolString x ++ show j),i):addIndex (j+1) x is
+
+    lookupVar (s, i)    = (, i) <$> lookupName s
     lookupName x
-             = case filter ((==x) . fst) ((\x -> (dropModuleNames $ symbol $ show x, x)) <$> vars) of
+             = case filter ((==x) . fst) ((\x -> (dropModuleNames $ F.symbol $ show x, x)) <$> vars) of
                 [(_, x)] -> Just x
                 _        -> Nothing
 
+makeBounds ::  F.TCEmb TyCon -> ModName -> [Var] -> [CoreBind] -> [(ModName, Ms.BareSpec)] -> BareM ()
 makeBounds tce name defVars cbs specs
   = do bnames  <- mkThing makeHBounds
        hbounds <- makeHaskellBounds tce cbs bnames
        bnds    <- M.fromList <$> mapM go (concatMap (M.toList . Ms.bounds . snd ) specs)
-       modify   $ \env -> env{ bounds = hbounds `mappend` bnds }
+       modify   $ \env -> env { bounds = hbounds `mappend` bnds }
   where
     go (x,bound) = (x,) <$> mkBound bound
     mkThing mk   = S.fromList . mconcat <$> sequence [ mk defVars s | (m, s) <- specs, m == name]
 
-
+mkBound :: (Resolvable a) => Bound (Located BareType) a -> BareM (Bound RSort a)
 mkBound (Bound s vs pts xts r)
-  = do ptys' <- mapM (\(x, t) -> ((x,) . toRSort) <$> mkSpecType (loc x) t) pts
-       xtys' <- mapM (\(x, t) -> ((x,) . toRSort) <$> mkSpecType (loc x) t) xts
-       vs'   <- map toRSort <$> mapM (mkSpecType (loc s)) vs
+  = do ptys' <- mapM (\(x, t) -> ((x,) . toRSort . val) <$> mkLSpecType t) pts
+       xtys' <- mapM (\(x, t) -> ((x,) . toRSort . val) <$> mkLSpecType t) xts
+       vs'   <- map (toRSort . val) <$> mapM mkLSpecType vs
        Bound s vs' ptys' xtys' <$> resolve (loc s) r
diff --git a/src/Language/Haskell/Liquid/Bare/SymSort.hs b/src/Language/Haskell/Liquid/Bare/SymSort.hs
--- a/src/Language/Haskell/Liquid/Bare/SymSort.hs
+++ b/src/Language/Haskell/Liquid/Bare/SymSort.hs
@@ -4,19 +4,20 @@
     txRefSort
   ) where
 
-import Prelude hiding (error)
-
-import qualified Data.List as L
-import Data.Maybe              (fromMaybe)
-import TyCon            (TyCon)
-import Language.Fixpoint.Misc  (fst3, snd3)
-import Language.Fixpoint.Types (atLoc, meet, TCEmb)
-
-import Language.Haskell.Liquid.Types.RefType (appRTyCon, strengthen)
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.GHC.Misc (fSrcSpan)
-import Language.Haskell.Liquid.Misc (safeZipWithError)
-import Language.Haskell.Liquid.Bare.Env
+import qualified Data.HashMap.Strict                   as M
+import           Prelude                               hiding (error)
+import qualified GHC
+import qualified Data.List                             as L
+import           Data.Maybe                            (fromMaybe)
+import           TyCon                                 (TyCon)
+import           Language.Fixpoint.Misc                (fst3, snd3)
+import           Language.Fixpoint.Types.Sorts
+import           Language.Fixpoint.Types               (atLoc, meet, Reftable, Symbolic, Symbol)
+import           Language.Haskell.Liquid.Types.RefType (appRTyCon, strengthen)
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.GHC.Misc      (fSrcSpan)
+import           Language.Haskell.Liquid.Misc          (safeZipWithError)
+import           Language.Haskell.Liquid.Bare.Env
 
 
 -- EFFECTS: TODO is this the SAME as addTyConInfo? No. `txRefSort`
@@ -27,7 +28,13 @@
 txRefSort :: TCEnv -> TCEmb TyCon -> Located SpecType -> Located SpecType
 txRefSort tyi tce t = atLoc t $ mapBot (addSymSort (fSrcSpan t) tce tyi) (val t)
 
-addSymSort sp tce tyi (RApp rc@(RTyCon _ _ _) ts rs r)
+addSymSort :: (PPrint t, Reftable t)
+           => GHC.SrcSpan
+           -> M.HashMap TyCon FTycon
+           -> M.HashMap TyCon RTyCon
+           -> RType RTyCon RTyVar (UReft t)
+           -> RType RTyCon RTyVar (UReft t)
+addSymSort sp tce tyi (RApp rc@(RTyCon {}) ts rs r)
   = RApp rc ts (zipWith3 (addSymSortRef sp rc) pvs rargs [1..]) r'
   where
     rc'                = appRTyCon tce tyi rc ts
@@ -40,12 +47,26 @@
 addSymSort _ _ _ t
   = t
 
+addSymSortRef :: (PPrint t, PPrint a, Symbolic tv, Reftable t)
+              => GHC.SrcSpan
+              -> a
+              -> PVar (RType c tv ())
+              -> Ref (RType c tv ()) (RType c tv (UReft t))
+              -> Int
+              -> Ref (RType c tv ()) (RType c tv (UReft t))
 addSymSortRef sp rc p r i
   | isPropPV p
   = addSymSortRef' sp rc i p r
   | otherwise
   = panic Nothing "addSymSortRef: malformed ref application"
 
+addSymSortRef' :: (PPrint t, PPrint a, Symbolic tv, Reftable t)
+               => GHC.SrcSpan
+               -> a
+               -> Int
+               -> PVar (RType c tv ())
+               -> Ref (RType c tv ()) (RType c tv (UReft t))
+               -> Ref (RType c tv ()) (RType c tv (UReft t))
 addSymSortRef' _ _ _ p (RProp s (RVar v r)) | isDummy v
   = RProp xs t
     where
@@ -70,6 +91,7 @@
     where
       xs = spliceArgs "addSymSortRef 2" s p
 
+spliceArgs :: String  -> [(Symbol, b)] -> PVar t -> [(Symbol, t)]
 spliceArgs msg s p = go (fst <$> s) (pargs p)
   where
     go []     []           = []
diff --git a/src/Language/Haskell/Liquid/Bare/ToBare.hs b/src/Language/Haskell/Liquid/Bare/ToBare.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/Bare/ToBare.hs
@@ -0,0 +1,86 @@
+-- | This module contains functions that convert things
+--   to their `Bare` versions, e.g. SpecType -> BareType etc.
+
+module Language.Haskell.Liquid.Bare.ToBare
+  ( -- * Types
+    specToBare
+
+    -- * Measures
+  , measureToBare
+  )
+  where
+
+import           DataCon
+import           Data.Bifunctor
+
+import           Language.Fixpoint.Misc (mapSnd)
+import qualified Language.Fixpoint.Types as F
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Measure
+import           Language.Haskell.Liquid.Types.RefType
+
+--------------------------------------------------------------------------------
+specToBare :: SpecType -> BareType
+--------------------------------------------------------------------------------
+specToBare = txRType specToBareTC specToBareTV
+
+-- specToBare t = F.tracepp ("specToBare t2 = " ++ F.showpp t2)  t1
+  -- where
+    -- t1       = bareOfType . toType $ t
+    -- t2       = _specToBare           t
+
+
+--------------------------------------------------------------------------------
+measureToBare :: SpecMeasure -> BareMeasure
+--------------------------------------------------------------------------------
+measureToBare = bimap (fmap specToBare) dataConToBare
+
+dataConToBare :: DataCon -> LocSymbol
+dataConToBare = namedLocSymbol
+
+specToBareTC :: RTyCon -> BTyCon
+specToBareTC = tyConBTyCon . rtc_tc
+
+specToBareTV :: RTyVar -> BTyVar
+specToBareTV (RTV α) = BTV (F.symbol α)
+
+txRType :: (c1 -> c2) -> (tv1 -> tv2) -> RType c1 tv1 r -> RType c2 tv2 r
+txRType cF vF = go
+  where
+    -- go :: RType c1 tv1 r -> RType c2 tv2 r
+    go (RVar α r)          = RVar  (vF α) r
+    go (RAllT α t)         = RAllT (goRTV α) (go t)
+    go (RAllP π t)         = RAllP (goPV  π) (go t)
+    go (RAllS s t)         = RAllS s         (go t)
+    go (RFun x t t' r)     = RFun  x         (go t) (go t') r
+    go (RAllE x t t')      = RAllE x         (go t) (go t')
+    go (REx x t t')        = REx   x         (go t) (go t')
+    go (RAppTy t t' r)     = RAppTy          (go t) (go t') r
+    go (RApp c ts rs r)    = RApp  (cF c)    (go <$> ts) (goRTP <$> rs) r
+    go (RRTy xts r o t)    = RRTy  (mapSnd go <$> xts) r o (go t)
+    go (RExprArg e)        = RExprArg e
+    go (RHole r)           = RHole r
+
+    -- go' :: RType c1 tv1 () -> RType c2 tv2 ()
+    go' = txRType cF vF
+
+    -- goRTP :: RTProp c1 tv1 r -> RTProp c2 tv2 r
+    goRTP (RProp s (RHole r)) = RProp (mapSnd go' <$> s) (RHole r)
+    goRTP (RProp s t)         = RProp (mapSnd go' <$> s) (go t)
+
+    -- goRTV :: RTVU c1 tv1 -> RTVU c2 tv2
+    goRTV = txRTV cF vF
+
+    -- goPV :: PVU c1 tv1 -> PVU c2 tv2
+    goPV = txPV cF vF
+
+txRTV :: (c1 -> c2) -> (tv1 -> tv2) -> RTVU c1 tv1 -> RTVU c2 tv2
+txRTV cF vF (RTVar α z) = RTVar (vF α) (txRType cF vF <$> z)
+
+txPV :: (c1 -> c2) -> (tv1 -> tv2) -> PVU c1 tv1 -> PVU c2 tv2
+txPV cF vF (PV x k y txes) = PV x k' y txes'
+  where
+    txes'                  = [ (tx t, x, e) | (t, x, e) <- txes]
+    k'                     = tx <$> k
+    tx                     = txRType cF vF
diff --git a/src/Language/Haskell/Liquid/Constraint/Axioms.hs b/src/Language/Haskell/Liquid/Constraint/Axioms.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Constraint/Axioms.hs
+++ /dev/null
@@ -1,569 +0,0 @@
-{-# LANGUAGE DeriveFoldable            #-}
-{-# LANGUAGE DeriveTraversable         #-}
-{-# LANGUAGE StandaloneDeriving        #-}
-{-# LANGUAGE ScopedTypeVariables       #-}
-{-# LANGUAGE NoMonomorphismRestriction #-}
-{-# LANGUAGE TypeSynonymInstances      #-}
-{-# LANGUAGE FlexibleContexts          #-}
-{-# LANGUAGE FlexibleInstances         #-}
-{-# LANGUAGE TupleSections             #-}
-{-# LANGUAGE BangPatterns              #-}
-{-# LANGUAGE PatternGuards             #-}
-{-# LANGUAGE DeriveFunctor             #-}
-{-# LANGUAGE MultiParamTypeClasses     #-}
-{-# LANGUAGE OverloadedStrings         #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-
-module Language.Haskell.Liquid.Constraint.Axioms (
-
-    expandProofs
-
-    -- * Combining proofs
-  , makeCombineType
-  , makeCombineVar
-
-  ) where
-
-
-import Prelude hiding (error)
-
-import Literal
-
-import Coercion
-import DataCon
-import CoreSyn
-import Type
-import TyCon
-import TypeRep
-import Var
-import Name
-import NameSet
-
-import Text.PrettyPrint.HughesPJ hiding (first, sep)
-import Control.Monad.State
-import qualified Data.List           as L
-import qualified Data.HashMap.Strict as M
-import Data.Maybe               (fromJust)
-import Language.Fixpoint.Types.Names
-import Language.Fixpoint.Utils.Files
-
-import qualified Language.Fixpoint.Types            as F
-
-import Language.Haskell.Liquid.UX.Tidy (panicError)
-import Language.Haskell.Liquid.Types.Visitors (freeVars)
-import Language.Haskell.Liquid.Types            hiding (binds, Loc, loc, freeTyVars, Def, HAxiom)
-import qualified Language.Haskell.Liquid.Types as T
-import Language.Haskell.Liquid.WiredIn
-import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.Types.Visitors         hiding (freeVars)
-import Language.Haskell.Liquid.GHC.Misc
-import Language.Haskell.Liquid.GHC.SpanStack                 (showSpan)
-import Language.Fixpoint.Misc                         hiding (errorstar)
-import Language.Haskell.Liquid.Constraint.ProofToCore
-import Language.Haskell.Liquid.Transforms.CoreToLogic
-import Language.Haskell.Liquid.Constraint.Types
-
-import System.IO.Unsafe
-
-import Language.Haskell.Liquid.Prover.Types (Axiom(..), Query(..))
-import qualified Language.Haskell.Liquid.Prover.Types as P
-import Language.Haskell.Liquid.Prover.Solve (solve)
-
-
-import qualified Data.HashSet        as S
-
-
-
-class Provable a where
-
-  expandProofs :: GhcInfo -> [(F.Symbol, SpecType)] -> a -> CG a
-  expandProofs info sigs x =
-    do (x, s) <- runState (expProofs x) <$> initAEEnv info sigs
-       modify $ \st -> st {freshIndex = ae_index s}
-       return x
-
-  expProofs :: a -> Pr a
-  expProofs = return
-
-
-instance Provable CoreBind where
-  -- expProofs (NonRec x e) | returnsProof x =  (\e -> Rec [(traceShow ("\n\nMake it Rec\n\n" ++ show (F.symbol x)) x,e)]) <$> (addRec (x,e) >> expProofs e)
-  expProofs (NonRec x e) =
-     do e' <- addRec (x,e) >> expProofs e
-        if x `elem` freeVars S.empty e'
-          then return $ Rec [(x, e')]
-          else return $ NonRec x e'
-  expProofs (Rec xes)    = Rec      <$> (addRecs xes  >> mapSndM expProofs xes)
-
-
-instance Provable CoreExpr where
-  expProofs ee@(App (App (Tick _ (Var f)) i) e) | isAuto f = grapInt i >>= expandAutoProof ee e
-  expProofs ee@(App (App (Var f) i) e)          | isAuto f = grapInt i >>= expandAutoProof ee e
-  expProofs ee@(App (Tick _ (App (Tick _ (Var f)) i)) e) | isAuto f = grapInt i >>= expandAutoProof ee e
-  expProofs ee@(App (Tick _ (App (Var f) i)) e)          | isAuto f = grapInt i >>= expandAutoProof ee e
-
-
-  expProofs ee@(App (App (Tick _ (Var f)) i) e) | isCases f = grapInt i >>= expandCasesProof ee e
-  expProofs ee@(App (App (Var f) i) e)          | isCases f = grapInt i >>= expandCasesProof ee e
-  expProofs ee@(App (Tick _ (App (Tick _ (Var f)) i)) e) | isCases f = grapInt i >>= expandCasesProof ee e
-  expProofs ee@(App (Tick _ (App (Var f) i)) e)          | isCases f = grapInt i >>= expandCasesProof ee e
-
-  expProofs (App e1 e2) = liftM2 App (expProofs e1) (expProofs e2)
-  expProofs (Lam x e)   = addVar x >> liftM  (Lam x) (expProofs e)
-  expProofs (Let b e)   = do b' <- expProofs b
-                             addBind b'
-                             liftM (Let b') (expProofs e)
-  expProofs (Case e v t alts) = liftM2 (\e -> Case e v t) (expProofs e) (mapM (expProofsCase e) alts)
-  expProofs (Cast e c)   = liftM (`Cast` c) (expProofs e)
-  expProofs (Tick t e)   = liftM (Tick t) (expProofs e)
-
-  expProofs (Var v)      = return $ Var v
-  expProofs (Lit l)      = return $ Lit l
-  expProofs (Type t)     = return $ Type t
-  expProofs (Coercion c) = return $ Coercion c
-
-
-
-expProofsCase :: CoreExpr -> CoreAlt -> Pr CoreAlt
-expProofsCase (Var x) (DataAlt c, xs, e)
-  = do addVars xs
-       t <- L.lookup (symbol c) . ae_sigs <$> get
-       addAssert $ makeRefinement t (x:xs)
-       res <- liftM (DataAlt c,xs,) (expProofs e)
-       rmAssert
-       return res
-
-expProofsCase _ (c, xs, e)
-  = addVars xs >> liftM (c,xs,) (expProofs e)
-
-
-instance Provable CoreAlt where
-  expProofs (c, xs, e) = addVars xs >> liftM (c,xs,) (expProofs e)
-
-expandCasesProof :: CoreExpr -> CoreExpr -> Integer -> Pr CoreExpr
-expandCasesProof inite e it
-  = do vs <-  reverse . ae_vars <$> get
-       case L.find (isAlgType . varType) vs of
-          Nothing -> return inite
-          Just v  -> makeCases v inite e it
-
-makeDataCons v = data_cons $ algTyConRhs tc
-  where
-    t  = varType v
-    tc = fst $ splitTyConApp t
-
-makeCases v inite e it = Case (Var v) v (varType v) <$> (mapM go $ makeDataCons v)
-  where
-    go c = do xs <- makeDataConArgs v c
-              addVars xs
-              t <- L.lookup (symbol c) . ae_sigs <$> get
-              addAssert $ makeRefinement t (v:xs)
-              proof <- expandAutoProof inite (e) it
-              rmAssert
-              return (DataAlt c, xs, proof)
-
-makeDataConArgs v dc = mapM freshVar ts
-  where
-    ts = dataConInstOrigArgTys dc ats
-    ats = snd $ splitTyConApp $ varType v
-
-
-expandAutoProof :: CoreExpr -> CoreExpr -> Integer -> Pr CoreExpr
-expandAutoProof inite e it
-  =  do ams  <- ae_axioms  <$> get
-        vs'  <- ae_vars    <$> get
-        cts  <- ae_consts  <$> get
-        ds   <- ae_assert  <$> get
-        cmb  <- ae_cmb     <$> get
-        lmap <- ae_lmap    <$> get
-        isHO <- ae_isHO    <$> get 
-        e'   <- unANFExpr e
-
-        foldM (\lm x -> (updateLMap lm (dummyLoc $ F.symbol x) x >> (ae_lmap <$> get))) lmap vs'
-
-        let (vs, vlits)  = L.partition (`elem` readVars e') $ nub' vs'
-        let allvs        = nub'  ((fst . aname <$> ams) ++ cts  ++ vs')
-        let (cts', vcts) = L.partition (isFunctionType . varType) allvs
-        let usedVs = nub' (vs++vcts)
-
-        env    <- makeEnvironment ((L.\\) allvs usedVs) ((L.\\) vlits usedVs)
-        ctors  <- mapM makeCtor cts'
-        pvs    <- mapM makeVar usedVs
-        le     <- makeGoalPredicate e'
-        fn     <- freshFilePath
-        axioms <- makeAxioms
-        let sol = unsafePerformIO (solve $ makeQuery fn it isHO le axioms ctors ds env pvs)
-        return $ {-
-          traceShow (
-            "\n\nTo prove\n" ++ show (showpp le) ++
-            "\n\nWe need \n" ++ show sol         ++
-            "\n\nExpr =  \n" ++ show (toCore cmb inite sol)         ++
-            "\n\n"
-           ) $ -}
-          traceShow "\nexpandedExpr\n" $ toCore cmb inite sol
-
-nub' = L.nubBy (\v1 v2 -> F.symbol v1 == F.symbol v2)
-
--- TODO: merge this with the Bare.Axiom.hs
-updateLMap :: LogicMap  -> LocSymbol -> Var -> Pr ()
-updateLMap _ _ v | not (isFun $ varType v)
-  = return ()
-  where
-    isFun (FunTy _ _)    = True
-    isFun (ForAllTy _ t) = isFun t
-    isFun  _             = False
-
-updateLMap _ x vv
-  = insertLogicEnv x' ys (F.eApps (F.EVar $ val x) (F.EVar <$> ys))
-  where
-    nargs = dropWhile isClassType $ ty_args $ toRTypeRep $ ((ofType $ varType vv) :: RRType ())
-
-    ys = zipWith (\i _ -> symbol (("x" ++ show i) :: String)) [1..] nargs
-    x' = simpleSymbolVar vv
-
-insertLogicEnv x ys e
-  = modify $ \be -> be {ae_lmap = (ae_lmap be) {logic_map = M.insert x (LMap x ys e) $ logic_map $ ae_lmap be}}
-
-simpleSymbolVar  x = dropModuleNames $ symbol $ showPpr $ getName x
-
--------------------------------------------------------------------------------
-----------------   From Haskell to Prover  ------------------------------------
--------------------------------------------------------------------------------
-
-
-
-
-
-makeEnvironment :: [Var] -> [Var] -> Pr [P.LVar]
-makeEnvironment avs vs
-  = do lits <- ae_lits <$> get
-       let lts'  = filter (\(x,_) -> not (x `elem` (F.symbol <$> avs))) (normalize lits)
-       let lts1  = [P.Var x s () | (x, s) <- lts']
-       lts2  <- mapM makeLVar vs
-       return (lts1 ++ lts2)
-
-
-
-makeQuery :: FilePath -> Integer -> Bool -> F.Expr -> [HAxiom] -> [HVarCtor] -> [F.Expr] -> [P.LVar] ->  [HVar] -> HQuery
-makeQuery fn i isHO p axioms cts ds env vs 
- = Query   { q_depth  = fromInteger i
-           , q_goal   = P.Pred p
-
-           , q_vars   = checkVar  <$> vs      -- local variables
-           , q_ctors  = cts                   -- constructors: globals with function type
-           , q_env    = checkEnv  <$> env     -- environment: anything else that can appear in the logic
-
-           , q_fname  = fn
-           , q_axioms = axioms
-           , q_decls  = (P.Pred <$> ds)
-           , q_isHO   = isHO 
-           }
-
-checkEnv pv@(P.Var x s _)
-  | isBaseSort s = pv
-  | otherwise    = panic Nothing ("\nEnv:\nNon Basic " ++ show x ++ "  ::  " ++ show s)
-
-checkVar pv@(P.Var x s _)
-  | isBaseSort s = pv
-  | otherwise    = panic Nothing ("\nVar:\nNon Basic " ++ show x ++ "  ::  " ++ show s)
-
-makeAxioms =
-  do recs <- ae_recs    <$> get
-     tce  <- ae_emb     <$> get
-     sigs <- ae_sigs    <$> get
-     gs   <- ae_globals <$> get
-     let (rgs, gs') = L.partition (`elem` (fst <$> recs)) $ filter returnsProof gs
-     let as1 = varToPAxiom tce sigs <$> gs'
-     let as2 = varToPAxiomWithGuard tce sigs recs <$> rgs
-     return (as1 ++ as2)
-
-unANFExpr e = (foldl (flip Let) e . ae_binds) <$> get
-
-makeGoalPredicate e =
-  do lm   <- ae_lmap    <$> get
-     tce  <- ae_emb     <$> get
-     case runToLogic tce lm (ErrOther (showSpan "makeGoalPredicate") . text) (coreToPred e) of
-       Left p    -> return p
-       Right err -> panicError err
-
-makeRefinement :: Maybe SpecType -> [Var] -> F.Expr
-makeRefinement Nothing  _ = F.PTrue
-makeRefinement (Just t) xs = rr
-  where trep = toRTypeRep t
-        ys   = [x | (x, t') <- zip (ty_binds trep) (ty_args trep), not (isClassType t')]
-        rr   = case stripRTypeBase $ ty_res trep of
-                 Nothing  -> F.PTrue
-                 Just ref -> let F.Reft(v, r) = F.toReft ref
-                                 su = F.mkSubst $ zip (v:ys) (F.EVar . F.symbol <$> xs)
-                             in F.subst su r
-
-
-
-makeCtor :: Var -> Pr HVarCtor
-makeCtor c
-  = do tce  <- ae_emb     <$> get
-       sigs <- ae_sigs    <$> get
-       lmap <- ae_lmap    <$> get
-       lvs  <- ae_vars    <$> get
-       return $ makeCtor' tce lmap sigs (c `elem` lvs) c
-
-makeCtor' :: F.TCEmb TyCon -> LogicMap -> [(F.Symbol, SpecType)] -> Bool -> Var -> HVarCtor
-makeCtor' tce _ _ islocal  v | islocal
-  = P.VarCtor (P.Var (F.symbol v) (typeSort tce $ varType v) v) [] (P.Pred F.PTrue)
-
-makeCtor' tce lmap sigs _  v
-  = case M.lookup v (axiom_map lmap) of
-    Nothing -> P.VarCtor (P.Var (F.symbol v) (typeSort tce $ varType v)      v) vs r
-    Just x  -> P.VarCtor (P.Var x            (typeSort tce $ varType v) v) [] (P.Pred F.PTrue)
-
-  where
-    x    = F.symbol v
-    (vs, r) = case L.lookup x sigs of
-                Nothing -> ([], P.Pred F.PTrue)
-                Just t  -> let trep = toRTypeRep t
-                           in case stripRTypeBase $ ty_res trep of
-                               Nothing -> ([], P.Pred F.PTrue)
-                               Just r  -> let (F.Reft(v, p)) = F.toReft r
-                                              xts = [(x,t) | (x, t) <- zip (ty_binds trep) (ty_args trep), not $ isClassType t]
-                                              e  = F.mkEApp (dummyLoc x) (F.EVar . fst  <$> xts)
-                                          in ([P.Var x (rTypeSort tce t) ()  | (x, t) <- xts], P.Pred $ F.subst1 p (v, e))
-
-makeVar :: Var -> Pr HVar
-makeVar v = do {tce <- ae_emb <$> get; return $ makeVar' tce v}
-
-makeVar'  tce v = P.Var (F.symbol v) (typeSort tce $ varType v) v
-
-makeLVar :: Var -> Pr P.LVar
-makeLVar v = do {tce <- ae_emb <$> get; return $ makeLVar' tce v}
-
-makeLVar' tce v = P.Var (F.symbol v) (typeSort tce $ varType v) ()
-
-
-
-varToPAxiomWithGuard :: F.TCEmb TyCon -> [(Symbol, SpecType)] -> [(Var, [Var])] -> Var -> HAxiom
-varToPAxiomWithGuard tce sigs recs v
-  = P.Axiom { axiom_name = makeVar' tce v
-            , axiom_vars = vs
-            , axiom_body = P.Pred $ F.PImp q bd
-            }
-  where
-    q = makeGuard $ zip (symbol <$> args) xts
-    args = fromJust $ L.lookup v recs
-    x = F.symbol v
-    (vs, xts, bd) = case L.lookup x sigs of
-                     Nothing -> panic Nothing ("haxiomToPAxiom: " ++ show x ++ " not found")
-                     Just t -> let trep = toRTypeRep t
-                                   bd'  = case stripRTypeBase $ ty_res trep of
-                                            Nothing -> F.PTrue
-                                            Just r  -> let (F.Reft(_, p)) = F.toReft r in p
-                                   xts   = filter (not . isClassType . snd) $ zip (ty_binds trep) (ty_args trep)
-                                   vs'   = [P.Var x (rTypeSort tce t) () | (x, t) <- xts]
-                               in  (vs', xts, bd')
-
-makeGuard :: [(F.Symbol, (F.Symbol, SpecType))] -> F.Expr
-makeGuard xs = F.POr $ go [] xs
-  where
-    go _ []
-      = []
-    go acc ((x, (x', RApp c _ _ _)):xxs)
-     | Just f <- sizeFunction $ rtc_info c
-     = (F.PAnd (F.PAtom F.Lt (f x') (f x):acc)) : go (F.PAtom F.Le (f x') (f x):acc) xxs
-    go acc (_:xxs)
-     = go acc xxs
-
-
-varToPAxiom :: F.TCEmb TyCon -> [(Symbol, SpecType)] -> Var -> HAxiom
-varToPAxiom tce sigs v
-  = P.Axiom { axiom_name = makeVar' tce v
-            , axiom_vars = vs
-            , axiom_body = P.Pred bd
-            }
-  where
-    x = F.symbol v
-    (vs, bd) = case L.lookup x sigs of
-                Nothing -> panic Nothing ("haxiomToPAxiom: " ++ show x ++ " not found")
-                Just t -> let trep = toRTypeRep t
-                              bd'  = case stripRTypeBase $ ty_res trep of
-                                       Nothing -> F.PTrue
-                                       Just r  -> let (F.Reft(_, p)) = F.toReft r in p
-                              vs'   = [P.Var x (rTypeSort tce t) () | (x, t) <- zip (ty_binds trep) (ty_args trep), not $ isClassType t]
-                          in  (vs', bd')
-
-
--------------------------------------------------------------------------------
--------------  Proof State Environment ----------------------------------------
--------------------------------------------------------------------------------
-
-type Pr = State AEnv
-
-data AEnv = AE { ae_axioms  :: [T.HAxiom]            -- axiomatized functions
-               , ae_binds   :: [CoreBind]            -- local bindings, tracked st they are expanded in logic
-               , ae_lmap    :: LogicMap              -- logical mapping
-               , ae_consts  :: [Var]                 -- Data constructors and imported variables
-               , ae_globals :: [Var]                 -- Global definitions, like axioms
-               , ae_vars    :: [Var]                 -- local variables in scope
-               , ae_emb     :: F.TCEmb TyCon         -- type constructor information
-               , ae_lits    :: [(Symbol, F.Sort)]    -- literals
-               , ae_index   :: Integer               -- unique integer
-               , ae_sigs    :: [(Symbol, SpecType)]  -- Refined type signatures
-               , ae_target  :: FilePath              -- file name of target source coude
-               , ae_recs    :: [(Var, [Var])]        -- axioms that are used recursively:
-                                                     -- these axioms are guarded to used only with "smaller" arguments
-               , ae_assert  :: [F.Expr]              --
-               , ae_cmb     :: CoreExpr -> CoreExpr -> CoreExpr  -- how to combine proofs
-               , ae_isHO    :: Bool                  -- allow higher order binders 
-               }
-
-
-initAEEnv info sigs
-    = do tce    <- tyConEmbed  <$> get
-         lts    <- lits        <$> get
-         i      <- freshIndex  <$> get
-         modify $ \s -> s{freshIndex = i + 1}
-         return $ AE { ae_axioms  = axioms spc
-                     , ae_binds   = []
-                     , ae_lmap    = logicMap spc
-                     , ae_consts  = L.nub vs
-                     , ae_globals = L.nub tp
-                     , ae_vars    = []
-                     , ae_emb     = tce
-                     , ae_lits    = wiredSortedSyms ++ lts
-                     , ae_index   = i
-                     , ae_sigs    = sigs
-                     , ae_target  = target info
-                     , ae_recs    = []
-                     , ae_assert  = []
-                     , ae_cmb     = \x y -> (App (App (Var by) x) y)
-                     , ae_isHO    = higherorder $ config spc 
-                     }
-    where
-      spc        = spec info
-      vs         = filter validVar (snd <$> freeSyms spc)
-      tp         = filter validExp (defVars info)
-
-      isExported = flip elemNameSet (exports $ spec info) . getName
-      validVar   = not . canIgnore
-      validExp x = validVar x && isExported x
-      by         = makeCombineVar $ makeCombineType τProof
-      τProof     = proofType $ spec info
-
-
-
-
-addBind b     = modify $ \ae -> ae{ae_binds = b:ae_binds ae}
-addAssert p   = modify $ \ae -> ae{ae_assert = p:ae_assert  ae}
-rmAssert      = modify $ \ae -> ae{ae_assert = tail $ ae_assert ae}
-addRec  (x,e) = modify $ \ae -> ae{ae_recs  = (x, grapArgs e):ae_recs  ae}
-addRecs xes   = modify $ \ae -> ae{ae_recs  = [(x, grapArgs e) | (x, e) <- xes] ++ ae_recs  ae}
-
-addVar  x | canIgnore x = return ()
-          | otherwise   = modify $ \ae -> ae{ae_vars  = x:ae_vars  ae}
-
-
-addVars x = modify $ \ae -> ae{ae_vars  = x' ++ ae_vars  ae}
-  where
-    x' = filter (not . canIgnore) x
-
-getUniq :: Pr Integer
-getUniq
-  = do modify (\s -> s{ae_index = 1 + (ae_index s)})
-       ae_index <$> get
-
-
-freshVar :: Type -> Pr Var
-freshVar t =
-  do n <- getUniq
-     return $ stringVar ("x" ++ show n) t
-
-freshFilePath :: Pr FilePath
-freshFilePath =
-  do fn <- ae_target <$> get
-     n  <- getUniq
-     return $ (extFileName (Auto $ fromInteger n) fn)
-
-
--------------------------------------------------------------------------------
---------------  Playing with Fixpoint  ----------------------------------------
--------------------------------------------------------------------------------
-
-
-isBaseSort _ = True 
-
-
-
--------------------------------------------------------------------------------
---------------  Playing with GHC Core  ----------------------------------------
--------------------------------------------------------------------------------
-
--- hasBaseType = isBaseTy . varType
-
-isFunctionType (FunTy _ _)    = True
-isFunctionType (ForAllTy _ t) = isFunctionType t
-isFunctionType _              = False
-
-
-resultType (ForAllTy _ t) = resultType t
-resultType (FunTy _ t)    = resultType t
-resultType  t             = t
-
-
-grapArgs (Lam x e) | isTyVar x  = grapArgs e
-grapArgs (Lam x e) | isClassPred $ varType x = grapArgs e
-grapArgs (Lam x e) = x : grapArgs e
-grapArgs (Let _ e) = grapArgs e
-grapArgs _         = []
-
-
-
-grapInt (Var v)
-  = do bs <- ae_binds <$> get
-       let (e:_) = [ex | NonRec x ex <- bs, x == v]
-       return $ go e
-  where
-    go (Tick _ e) = go e
-    go (App _ l)  = go l
-    go (Lit l)    = litToInt l
-    go e          = panic Nothing $ ("grapInt called with wrong argument " ++ showPpr e)
-
-    litToInt (MachInt i) = i
-    litToInt (MachInt64 i) = i
-    litToInt _             = panic Nothing "litToInt: non integer literal"
-
-grapInt (Tick _ e) = grapInt e
-grapInt _          = return 2
-
-
--------------------------------------------------------------------------------
---------------------  Combine Proofs  ----------------------------------------
--------------------------------------------------------------------------------
-
-makeCombineType Nothing
-  = panic Nothing "proofType not found"
-makeCombineType (Just τ)
-  = FunTy τ (FunTy τ τ)
-
-
-makeCombineVar τ =  stringVar combineProofsName τ
--------------------------------------------------------------------------------
--------------------  Helper Functions  ----------------------------------------
--------------------------------------------------------------------------------
-
-canIgnore v = isInternal v || isTyVar v
-isAuto    v = isPrefixOfSym "auto"  $ dropModuleNames $ F.symbol v
-isCases   v = isPrefixOfSym "cases" $ dropModuleNames $ F.symbol v
-isProof   v = isPrefixOfSym "Proof" $ dropModuleNames $ F.symbol v
-
-
-returnsProof :: Var -> Bool
-returnsProof = isProof' . resultType . varType
-  where
-    isProof' (TyConApp tc _) = isProof tc
-    isProof' _               = False
-
-
-normalize xts = filter hasBaseSort $ L.nub xts
-  where
-    hasBaseSort = isBaseSort . snd
-
-
-mapSndM act xys = mapM (\(x, y) -> (x,) <$> act y) xys
diff --git a/src/Language/Haskell/Liquid/Constraint/Constraint.hs b/src/Language/Haskell/Liquid/Constraint/Constraint.hs
--- a/src/Language/Haskell/Liquid/Constraint/Constraint.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Constraint.hs
@@ -41,6 +41,9 @@
    r        = snd $ last binds
    xss      = combinations ((\t -> [(x, t) | x <- localBindsOfType t γ]) <$> ts)
 
+subConstraintToLogicOne :: (Foldable t, Reftable r, Reftable r1)
+                        => t (Symbol, (Symbol, RType t1 t2 r))
+                        -> (Symbol, (Symbol, RType t3 t4 r1)) -> Expr
 subConstraintToLogicOne xts (x', (x, t)) = PImp (pAnd rs) r
   where
         (rs , su) = foldl go ([], []) xts
diff --git a/src/Language/Haskell/Liquid/Constraint/Env.hs b/src/Language/Haskell/Liquid/Constraint/Env.hs
--- a/src/Language/Haskell/Liquid/Constraint/Env.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Env.hs
@@ -1,4 +1,3 @@
-
 {-# LANGUAGE ScopedTypeVariables       #-}
 {-# LANGUAGE NoMonomorphismRestriction #-}
 {-# LANGUAGE TypeSynonymInstances      #-}
@@ -21,7 +20,7 @@
 
   -- * Insert
     (+++=)
-  , (++=)
+  -- , (++=)
   , (+=)
   , extendEnvWithVV
   , addBinders
@@ -33,7 +32,7 @@
   , fromListREnv
   , toListREnv
   , insertREnv -- TODO: remove this ASAP
-    
+
   -- * Query
   , localBindsOfType
   , lookupREnv
@@ -84,18 +83,14 @@
 import qualified Language.Haskell.Liquid.UX.CTags       as Tg
 
 -- import Debug.Trace (trace)
-
-instance Freshable CG Integer where
-  fresh = do s <- get
-             let n = freshIndex s
-             put $ s { freshIndex = n + 1 }
-             return n
-
 --------------------------------------------------------------------------------
 -- | Refinement Type Environments ----------------------------------------------
 --------------------------------------------------------------------------------
 
 -- updREnvLocal :: REnv -> (_ -> _) -> REnv
+updREnvLocal :: REnv
+             -> (M.HashMap F.Symbol SpecType -> M.HashMap F.Symbol SpecType)
+             -> REnv
 updREnvLocal rE f      = rE { reLocal = f (reLocal rE) }
 
 -- RJ: REnv-Split-Bug?
@@ -126,6 +121,7 @@
   where
     gM'  = M.unionWith (\_ t -> t) gM lM
 
+renvMaps :: REnv -> [M.HashMap F.Symbol SpecType]
 renvMaps rE = [reLocal rE, reGlobal rE]
 
 --------------------------------------------------------------------------------
@@ -148,7 +144,7 @@
 --------------------------------------------------------------------------------
 extendEnvWithVV γ t
   | F.isNontrivialVV vv && not (vv `memberREnv` (renv γ))
-  = (γ, "extVV") += (vv, t)
+  = γ += ("extVV", vv, t)
   | otherwise
   = return γ
   where
@@ -162,17 +158,17 @@
   st          <- get
   let (i, bs') = F.insertBindEnv x r (binds st)
   put          $ st { binds = bs' } { bindSpans = M.insert i l (bindSpans st) }
-  return ((x, F.sr_sort r), i) -- traceShow ("addBind: " ++ showpp x) i
+  return ((x, F.sr_sort r), {- traceShow ("addBind: " ++ showpp x) -} i)
 
 addClassBind :: SrcSpan -> SpecType -> CG [((F.Symbol, F.Sort), F.BindId)]
 addClassBind l = mapM (uncurry (addBind l)) . classBinds
 
 {- see tests/pos/polyfun for why you need everything in fixenv -}
 addCGEnv :: (SpecType -> SpecType) -> CGEnv -> (String, F.Symbol, SpecType) -> CG CGEnv
-addCGEnv tx γ (eMsg, x, REx y tyy tyx)
-  = do y' <- fresh
-       γ' <- addCGEnv tx γ (eMsg, y', tyy)
-       addCGEnv tx γ' (eMsg, x, tyx `F.subst1` (y, F.EVar y'))
+addCGEnv tx γ (eMsg, x, REx y tyy tyx) = do
+  y' <- fresh
+  γ' <- addCGEnv tx γ (eMsg, y', tyy)
+  addCGEnv tx γ' (eMsg, x, tyx `F.subst1` (y, F.EVar y'))
 
 addCGEnv tx γ (eMsg, x, RAllE yy tyy tyx)
   = addCGEnv tx γ (eMsg, x, t)
@@ -183,24 +179,28 @@
 
 addCGEnv tx γ (_, x, t') = do
   idx   <- fresh
-  allowHOBinders <- allowHO <$> get 
+  allowHOBinders <- allowHO <$> get
   let t  = tx $ normalize idx t'
   let l  = getLocation γ
   let γ' = γ { renv = insertREnv x t (renv γ) }
   pflag <- pruneRefs <$> get
-  is    <- if allowHOBinders || isBase t 
-            then (:) <$> addBind l x (rTypeSortedReft' pflag γ' t) <*> addClassBind l t    
+  is    <- if allowHOBinders || isBase t
+            then (:) <$> addBind l x (rTypeSortedReft' pflag γ' t) <*> addClassBind l t
             else return []
   return $ γ' { fenv = insertsFEnv (fenv γ) is }
 
+rTypeSortedReft' :: (PPrint r, F.Reftable r, SubsTy RTyVar RSort r)
+                 => Bool -> CGEnv -> RRType r -> F.SortedReft
 rTypeSortedReft' pflag γ
   | pflag     = pruneUnsortedReft (feEnv $ fenv γ) . f
   | otherwise = f
   where
     f         = rTypeSortedReft (emb γ)
 
+normalize :: Integer -> SpecType -> SpecType
 normalize idx = normalizeVV idx . normalizePds
 
+normalizeVV :: Integer -> SpecType -> SpecType
 normalizeVV idx t@(RApp _ _ _ _)
   | not (F.isNontrivialVV (rTypeValueVar t))
   = shiftVV t (F.vv $ Just idx)
@@ -208,35 +208,34 @@
 normalizeVV _ t
   = t
 
-
 --------------------------------------------------------------------------------
-(+=) :: (CGEnv, String) -> (F.Symbol, SpecType) -> CG CGEnv
+(+=) :: CGEnv -> (String, F.Symbol, SpecType) -> CG CGEnv
 --------------------------------------------------------------------------------
-(γ, eMsg) += (x, r)
+γ += (eMsg, x, r)
   | x == F.dummySymbol
   = return γ
-  | x `memberREnv` (renv γ)
-  = err
+  -- // | x `memberREnv` (renv γ)
+  -- // = _dupBindErr x γ
   | otherwise
   =  γ ++= (eMsg, x, r)
-  where err = panic Nothing $ eMsg ++ " Duplicate binding for "
-                                  ++ F.symbolString x
-                                  ++ "\n New: " ++ showpp r
-                                  ++ "\n Old: " ++ showpp (x `lookupREnv` (renv γ))
 
+_dupBindError :: String -> F.Symbol -> CGEnv -> SpecType -> a
+_dupBindError eMsg x γ r = panic Nothing s
+  where
+    s = unlines [ eMsg ++ " Duplicate binding for " ++ F.symbolString x
+                , "   New: " ++ showpp r
+                , "   Old: " ++ showpp (x `lookupREnv` (renv γ)) ]
 
 --------------------------------------------------------------------------------
 globalize :: CGEnv -> CGEnv
 --------------------------------------------------------------------------------
 globalize γ = γ {renv = globalREnv (renv γ)}
 
-
 --------------------------------------------------------------------------------
 (++=) :: CGEnv -> (String, F.Symbol, SpecType) -> CG CGEnv
 --------------------------------------------------------------------------------
 (++=) γ (eMsg, x, t)
-  = -- trace ("++= " ++ show x) $
-    addCGEnv (addRTyConInv (M.unionWith mappend (invs γ) (ial γ))) γ (eMsg, x, t)
+  = addCGEnv (addRTyConInv (M.unionWith mappend (invs γ) (ial γ))) γ (eMsg, x, t)
 
 --------------------------------------------------------------------------------
 addSEnv :: CGEnv -> (String, F.Symbol, SpecType) -> CG CGEnv
@@ -244,9 +243,13 @@
 addSEnv γ = addCGEnv (addRTyConInv (invs γ)) γ
 
 (+++=) :: (CGEnv, String) -> (F.Symbol, CoreExpr, SpecType) -> CG CGEnv
-(γ, _) +++= (x, e, t) = (γ {lcb = M.insert x e (lcb γ) }, "+++=") += (x, t)
+(γ, _) +++= (x, e, t) = (γ {lcb = M.insert x e (lcb γ) }) += ("+++=", x, t)
 
-γ -= x =  γ {renv = deleteREnv x (renv γ), lcb  = M.delete x (lcb γ)}
+(-=) :: CGEnv -> F.Symbol -> CGEnv
+γ -= x =  γ { renv = deleteREnv x (renv γ)
+            , lcb  = M.delete   x (lcb  γ)
+            -- , fenv = removeFEnv x (fenv γ)
+            }
 
 (?=) :: (?callStack :: CallStack) => CGEnv -> F.Symbol -> Maybe SpecType
 γ ?= x  = lookupREnv x (renv γ)
diff --git a/src/Language/Haskell/Liquid/Constraint/Fresh.hs b/src/Language/Haskell/Liquid/Constraint/Fresh.hs
--- a/src/Language/Haskell/Liquid/Constraint/Fresh.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Fresh.hs
@@ -6,40 +6,74 @@
 {-# LANGUAGE TupleSections         #-}
 {-# LANGUAGE TypeSynonymInstances  #-}
 {-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE BangPatterns          #-}
 
-module Language.Haskell.Liquid.Constraint.Fresh (Freshable(..)) where
+module Language.Haskell.Liquid.Constraint.Fresh
+  ( Freshable(..)
+  , refreshTy
+  , refreshVV
+  , refreshArgs
+  , refreshArgsTop
+  , refreshHoles
+  , freshTy_type
+  , freshTy_expr
+  , trueTy
+  , addKuts
+  )
+  where
 
-import           Prelude                hiding (error)
+import           Data.Maybe                    (catMaybes) -- , fromJust, isJust)
+import           Data.Bifunctor
+import qualified Data.List                      as L
+import qualified Data.HashMap.Strict            as M
+import qualified Data.HashSet                   as S
+import           Data.Hashable
+import           Control.Monad.State            (get, put, modify)
+import           Control.Monad                  (when, (>=>))
+import           Prelude                        hiding (error)
 
+import           CoreUtils  (exprType)
+import           Type       (Type)
+import           CoreSyn
+import           Var        (varType, isTyVar, Var)
 
-import           Language.Fixpoint.Types
-import           Language.Haskell.Liquid.Misc  (single)
+import qualified Language.Fixpoint.Types as F
+import           Language.Fixpoint.Types.Visitor (kvars)
+import           Language.Haskell.Liquid.Misc  (single, (=>>))
 import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Constraint.Types
 
 class (Applicative m, Monad m) => Freshable m a where
   fresh   :: m a
   true    :: a -> m a
-  true    = return . id
+  true    = return
   refresh :: a -> m a
-  refresh = return . id
+  refresh = return
 
-instance Freshable m Integer => Freshable m Symbol where
-  fresh = tempSymbol "x" <$> fresh
+instance Freshable CG Integer where
+  fresh = do s <- get
+             let n = freshIndex s
+             put $ s { freshIndex = n + 1 }
+             return n
 
-instance Freshable m Integer => Freshable m Expr where
+instance Freshable m Integer => Freshable m F.Symbol where
+  fresh = F.tempSymbol "x" <$> fresh
+
+instance Freshable m Integer => Freshable m F.Expr where
   fresh  = kv <$> fresh
     where
-      kv = (`PKVar` mempty) . intKvar
+      kv = (`F.PKVar` mempty) . F.intKvar
 
-instance Freshable m Integer => Freshable m [Expr] where
+instance Freshable m Integer => Freshable m [F.Expr] where
   fresh = single <$> fresh
 
-instance Freshable m Integer => Freshable m Reft where
-  fresh                = panic Nothing "fresh Reft"
-  true    (Reft (v,_)) = return $ Reft (v, mempty)
-  refresh (Reft (_,_)) = (Reft .) . (,) <$> freshVV <*> fresh
+instance Freshable m Integer => Freshable m F.Reft where
+  fresh                  = panic Nothing "fresh Reft"
+  true    (F.Reft (v,_)) = return $ F.Reft (v, mempty)
+  refresh (F.Reft (_,_)) = (F.Reft .) . (,) <$> freshVV <*> fresh
     where
-      freshVV          = vv . Just <$> fresh
+      freshVV            = F.vv . Just <$> fresh
 
 instance Freshable m Integer => Freshable m RReft where
   fresh             = panic Nothing "fresh RReft"
@@ -53,13 +87,13 @@
   refresh [] = fresh
   refresh s  = return s
 
-instance (Freshable m Integer, Freshable m r, Reftable r, RefTypable RTyCon RTyVar r) => Freshable m (RRType r) where
+instance (Freshable m Integer, Freshable m r, F.Reftable r ) => Freshable m (RRType r) where
   fresh   = panic Nothing "fresh RefType"
   refresh = refreshRefType
   true    = trueRefType
 
 -----------------------------------------------------------------------------------------------
-trueRefType :: (Freshable m Integer, Freshable m r, Reftable r, RefTypable RTyCon RTyVar r) => RRType r -> m (RRType r)
+trueRefType :: (Freshable m Integer, Freshable m r, F.Reftable r) => RRType r -> m (RRType r)
 -----------------------------------------------------------------------------------------------
 trueRefType (RAllT α t)
   = RAllT α <$> true t
@@ -86,21 +120,31 @@
   = do y'  <- fresh
        ty' <- true ty
        tx' <- true tx
-       return $ RAllE y' ty' (tx' `subst1` (y, EVar y'))
+       return $ RAllE y' ty' (tx' `F.subst1` (y, F.EVar y'))
 
 trueRefType (RRTy e o r t)
   = RRTy e o r <$> trueRefType t
 
-trueRefType t
-  = return t
+trueRefType (REx _ t t')
+  = REx <$> fresh <*> true t <*> true t'
 
+trueRefType t@(RExprArg _)
+  = return t 
+
+trueRefType t@(RHole _)
+  = return t 
+
+trueRefType (RAllS _ t)
+  = RAllS <$> fresh <*> true t  
+
+trueRef :: (F.Reftable r, Freshable f r, Freshable f Integer)
+        => Ref τ (RType RTyCon RTyVar r) -> f (Ref τ (RRType r))
 trueRef (RProp _ (RHole _)) = panic Nothing "trueRef: unexpected RProp _ (RHole _))"
 trueRef (RProp s t) = RProp s <$> trueRefType t
 
 
-
 -----------------------------------------------------------------------------------------------
-refreshRefType :: (Freshable m Integer, Freshable m r, Reftable r, RefTypable RTyCon RTyVar r) => RRType r -> m (RRType r)
+refreshRefType :: (Freshable m Integer, Freshable m r, F.Reftable r) => RRType r -> m (RRType r)
 -----------------------------------------------------------------------------------------------
 refreshRefType (RAllT α t)
   = RAllT α <$> refresh t
@@ -109,8 +153,8 @@
   = RAllP π <$> refresh t
 
 refreshRefType (RFun b t t' _)
-  | b == dummySymbol = rFun <$> fresh <*> refresh t <*> refresh t'
-  | otherwise        = rFun     b     <$> refresh t <*> refresh t'
+  | b == F.dummySymbol = rFun <$> fresh <*> refresh t <*> refresh t'
+  | otherwise          = rFun     b     <$> refresh t <*> refresh t'
 
 refreshRefType (RApp rc ts _ _) | isClass rc
   = return $ rRCls rc ts
@@ -128,7 +172,7 @@
   = do y'  <- fresh
        ty' <- refresh ty
        tx' <- refresh tx
-       return $ RAllE y' ty' (tx' `subst1` (y, EVar y'))
+       return $ RAllE y' ty' (tx' `F.subst1` (y, F.EVar y'))
 
 refreshRefType (RRTy e o r t)
   = RRTy e o r <$> refreshRefType t
@@ -136,7 +180,212 @@
 refreshRefType t
   = return t
 
+refreshRef :: (F.Reftable r, Freshable f r, Freshable f Integer)
+           => Ref τ (RType RTyCon RTyVar r) -> f (Ref τ (RRType r))
 refreshRef (RProp _ (RHole _)) = panic Nothing "refreshRef: unexpected (RProp _ (RHole _))"
 refreshRef (RProp s t) = RProp <$> mapM freshSym s <*> refreshRefType t
 
+freshSym :: Freshable f a => (t, t1) -> f (a, t1)
 freshSym (_, t)        = (, t) <$> fresh
+
+
+--------------------------------------------------------------------------------
+refreshTy :: SpecType -> CG SpecType
+--------------------------------------------------------------------------------
+refreshTy t = refreshVV t >>= refreshArgs
+
+refreshVV :: Freshable m Integer => SpecType -> m SpecType
+refreshVV (RAllT a t) = RAllT a <$> refreshVV t
+refreshVV (RAllP p t) = RAllP p <$> refreshVV t
+
+refreshVV (REx x t1 t2)
+  = do [t1', t2'] <- mapM refreshVV [t1, t2]
+       shiftVV (REx x t1' t2') <$> fresh
+
+refreshVV (RFun x t1 t2 r)
+  = do [t1', t2'] <- mapM refreshVV [t1, t2]
+       shiftVV (RFun x t1' t2' r) <$> fresh
+
+refreshVV (RAppTy t1 t2 r)
+  = do [t1', t2'] <- mapM refreshVV [t1, t2]
+       shiftVV (RAppTy t1' t2' r) <$> fresh
+
+refreshVV (RApp c ts rs r)
+  = do ts' <- mapM refreshVV ts
+       rs' <- mapM refreshVVRef rs
+       shiftVV (RApp c ts' rs' r) <$> fresh
+
+refreshVV t
+  = shiftVV t <$> fresh
+
+refreshVVRef :: Freshable m Integer
+             => Ref b (RType RTyCon RTyVar RReft)
+             -> m (Ref b (RType RTyCon RTyVar RReft))
+refreshVVRef (RProp ss (RHole r))
+  = return $ RProp ss (RHole r)
+
+refreshVVRef (RProp ss t)
+  = do xs    <- mapM (const fresh) (fst <$> ss)
+       let su = F.mkSubst $ zip (fst <$> ss) (F.EVar <$> xs)
+       (RProp (zip xs (snd <$> ss)) . F.subst su) <$> refreshVV t
+
+--------------------------------------------------------------------------------
+refreshArgsTop :: (Var, SpecType) -> CG SpecType
+--------------------------------------------------------------------------------
+refreshArgsTop (x, t)
+  = do (t', su) <- refreshArgsSub t
+       modify $ \s -> s {termExprs = M.adjust (F.subst su <$>) x $ termExprs s}
+       return t'
+
+--------------------------------------------------------------------------------
+refreshArgs :: SpecType -> CG SpecType
+--------------------------------------------------------------------------------
+refreshArgs t = fst <$> refreshArgsSub t
+
+
+-- NV TODO: this does not refresh args if they are wrapped in an RRTy
+refreshArgsSub :: SpecType -> CG (SpecType, F.Subst)
+refreshArgsSub t
+  = do ts     <- mapM refreshArgs ts_u
+       xs'    <- mapM (const fresh) xs
+       let sus = F.mkSubst <$> L.inits (zip xs (F.EVar <$> xs'))
+       let su  = last sus
+       ts'    <- mapM refreshPs $ zipWith F.subst sus ts
+       let rs' = zipWith F.subst sus rs
+       tr     <- refreshPs $ F.subst su tbd
+       let t'  = fromRTypeRep $ trep {ty_binds = xs', ty_args = ts', ty_res = tr, ty_refts = rs'}
+       return (t', su)
+    where
+       trep    = toRTypeRep t
+       xs      = ty_binds trep
+       ts_u    = ty_args  trep
+       tbd     = ty_res   trep
+       rs      = ty_refts trep
+
+refreshPs :: SpecType -> CG SpecType
+refreshPs = mapPropM go
+  where
+    go (RProp s t) = do
+      t'    <- refreshPs t
+      xs    <- mapM (const fresh) s
+      let su = F.mkSubst [(y, F.EVar x) | (x, (y, _)) <- zip xs s]
+      return $ RProp [(x, t) | (x, (_, t)) <- zip xs s] $ F.subst su t'
+
+--------------------------------------------------------------------------------
+refreshHoles :: (F.Symbolic t, F.Reftable r, TyConable c, Freshable f r)
+             => [(t, RType c tv r)] -> f ([F.Symbol], [(t, RType c tv r)])
+refreshHoles vts = first catMaybes . unzip . map extract <$> mapM refreshHoles' vts
+  where
+  --   extract :: (t, t1, t2) -> (t, (t1, t2))
+    extract (a,b,c) = (a,(b,c))
+
+refreshHoles' :: (F.Symbolic a, F.Reftable r, TyConable c, Freshable m r)
+              => (a, RType c tv r) -> m (Maybe F.Symbol, a, RType c tv r)
+refreshHoles' (x,t)
+  | noHoles t = return (Nothing, x, t)
+  | otherwise = (Just $ F.symbol x,x,) <$> mapReftM tx t
+  where
+    tx r | hasHole r = refresh r
+         | otherwise = return r
+
+noHoles :: (F.Reftable r, TyConable c) => RType c tv r -> Bool
+noHoles = and . foldReft (\_ r bs -> not (hasHole r) : bs) []
+
+--------------------------------------------------------------------------------
+-- | Generation: Freshness -----------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- | Right now, we generate NO new pvars. Rather than clutter code
+--   with `uRType` calls, put it in one place where the above
+--   invariant is /obviously/ enforced.
+--   Constraint generation should ONLY use @freshTy_type@ and @freshTy_expr@
+
+freshTy_type        :: KVKind -> CoreExpr -> Type -> CG SpecType
+freshTy_type k _ τ  = freshTy_reftype k $ ofType τ
+
+freshTy_expr        :: KVKind -> CoreExpr -> Type -> CG SpecType
+freshTy_expr k e _  = freshTy_reftype k $ exprRefType e
+
+freshTy_reftype     :: KVKind -> SpecType -> CG SpecType
+freshTy_reftype k _t = (fixTy t >>= refresh) =>> addKVars k
+  where
+    t                = {- F.tracepp ("freshTy_reftype:" ++ show k) -} _t
+
+-- | Used to generate "cut" kvars for fixpoint. Typically, KVars for recursive
+--   definitions, and also to update the KVar profile.
+addKVars        :: KVKind -> SpecType -> CG ()
+addKVars !k !t  = do when (True)    $ modify $ \s -> s { kvProf = updKVProf k ks (kvProf s) }
+                     when (isKut k) $ addKuts k t
+                     -- when (True)    $ addKvPack t
+  where
+     ks         = F.KS $ S.fromList $ specTypeKVars t
+
+isKut              :: KVKind -> Bool
+isKut (RecBindE _) = True
+isKut ProjectE     = True
+isKut _            = False
+
+addKuts :: (PPrint a) => a -> SpecType -> CG ()
+addKuts _x t = modify $ \s -> s { kuts = mappend (F.KS ks) (kuts s)   }
+  where
+     ks'     = S.fromList $ specTypeKVars t
+     ks
+       | S.null ks' = ks'
+       | otherwise  = {- F.tracepp ("addKuts: " ++ showpp _x) -} ks'
+
+-- addKvPack :: SpecType -> CG ()
+-- addKvPack t = modify $ \s -> s { kvPacks = ks : kvPacks s}
+  -- where
+    -- ks      = S.fromList $ specTypeKVars t
+
+specTypeKVars :: SpecType -> [F.KVar]
+specTypeKVars = foldReft (\ _ r ks -> (kvars $ ur_reft r) ++ ks) []
+
+--------------------------------------------------------------------------------
+trueTy  :: Type -> CG SpecType
+--------------------------------------------------------------------------------
+trueTy = ofType' >=> true
+
+ofType' :: Type -> CG SpecType
+ofType' = fixTy . ofType
+
+fixTy :: SpecType -> CG SpecType
+fixTy t = do tyi   <- tyConInfo  <$> get
+             tce   <- tyConEmbed <$> get
+             return $ addTyConInfo tce tyi t
+
+exprRefType :: CoreExpr -> SpecType
+exprRefType = exprRefType_ M.empty
+
+exprRefType_ :: M.HashMap Var SpecType -> CoreExpr -> SpecType
+exprRefType_ γ (Let b e)
+  = exprRefType_ (bindRefType_ γ b) e
+
+exprRefType_ γ (Lam α e) | isTyVar α
+  = RAllT (makeRTVar $ rTyVar α) (exprRefType_ γ e)
+
+exprRefType_ γ (Lam x e)
+  = rFun (F.symbol x) (ofType $ varType x) (exprRefType_ γ e)
+
+exprRefType_ γ (Tick _ e)
+  = exprRefType_ γ e
+
+exprRefType_ γ (Var x)
+  = M.lookupDefault (ofType $ varType x) x γ
+
+exprRefType_ _ e
+  = ofType $ exprType e
+
+bindRefType_ :: M.HashMap Var SpecType -> Bind Var -> M.HashMap Var SpecType
+bindRefType_ γ (Rec xes)
+  = extendγ γ [(x, exprRefType_ γ e) | (x,e) <- xes]
+
+bindRefType_ γ (NonRec x e)
+  = extendγ γ [(x, exprRefType_ γ e)]
+
+extendγ :: (Eq k, Foldable t, Hashable k)
+        => M.HashMap k v
+        -> t (k, v)
+        -> M.HashMap k v
+extendγ γ xts
+  = foldr (\(x,t) m -> M.insert x t m) γ xts
diff --git a/src/Language/Haskell/Liquid/Constraint/Generate.hs b/src/Language/Haskell/Liquid/Constraint/Generate.hs
--- a/src/Language/Haskell/Liquid/Constraint/Generate.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Generate.hs
@@ -15,1391 +15,1354 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE ImplicitParams            #-}
 
--- | This module defines the representation of Subtyping and WF Constraints, and
--- the code for syntax-directed constraint generation.
-
-module Language.Haskell.Liquid.Constraint.Generate ( generateConstraints ) where
-
-import Prelude hiding (error, undefined)
-
-import GHC.Stack
-import CoreUtils     (exprType)
-import MkCore
-import Coercion
-import DataCon
-import Pair
-import CoreSyn
-import SrcLoc
-import Type
-import TyCon
-import PrelNames
-import TypeRep
-import Class            (className)
-import Var
-import Kind
-import Id
-import IdInfo
-import Name
-import NameSet
-import Unify
-import VarSet
--- import Unique
-
-
-import Text.PrettyPrint.HughesPJ hiding (first)
-import Control.Monad.State
--- import Control.Applicative      ((<$>), (<*>), Applicative)
--- import Data.Monoid              (mconcat, mempty, mappend)
-import Data.Maybe               (fromMaybe, catMaybes, fromJust, isJust)
-import qualified Data.HashMap.Strict as M
-import qualified Data.HashSet        as S
-import qualified Data.List           as L
-
-import Data.Bifunctor
-import qualified Data.Foldable    as F
-import qualified Data.Traversable as T
-
-
-
-
-
-import qualified Language.Haskell.Liquid.UX.CTags       as Tg
-
-
-
-import Language.Fixpoint.Types.Visitor
-
-import Language.Haskell.Liquid.Constraint.Fresh
-import Language.Haskell.Liquid.Constraint.Env
-import Language.Haskell.Liquid.Constraint.Monad
-import Language.Haskell.Liquid.Constraint.Split
-
-import qualified Language.Fixpoint.Types            as F
-
-import Language.Haskell.Liquid.WiredIn          (dictionaryVar)
-import Language.Haskell.Liquid.Types.Dictionaries
-
-import qualified Language.Haskell.Liquid.GHC.SpanStack as Sp
-import Language.Haskell.Liquid.Types            hiding (binds, Loc, loc, freeTyVars, Def)
-import Language.Haskell.Liquid.Types.Strata
-import Language.Haskell.Liquid.Types.Names
-
-import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.Types.Visitors         hiding (freeVars)
-import Language.Haskell.Liquid.Types.PredType         hiding (freeTyVars)
-import Language.Haskell.Liquid.Types.Meet
-import Language.Haskell.Liquid.GHC.Misc          ( isInternal, collectArguments, tickSrcSpan
-                                                 , hasBaseTypeVar, showPpr, isDataConId)
-import Language.Haskell.Liquid.Misc
-import Language.Fixpoint.Misc
-import Language.Haskell.Liquid.Types.Literals
-
-import Language.Haskell.Liquid.Constraint.Axioms
-import Language.Haskell.Liquid.Constraint.Types
-import Language.Haskell.Liquid.Constraint.Constraint
-
--- import Debug.Trace (trace)
-
------------------------------------------------------------------------
-------------- Constraint Generation: Toplevel -------------------------
------------------------------------------------------------------------
-
-generateConstraints      :: GhcInfo -> CGInfo
-generateConstraints info = {-# SCC "ConsGen" #-} execState act $ initCGI cfg info
-  where
-    act                  = consAct info
-    cfg                  = config $ spec info
-
-consAct :: GhcInfo -> CG ()
-consAct info
-  = do γ'    <- initEnv      info
-       sflag <- scheck   <$> get
-       tflag <- trustghc <$> get
-       γ     <- if expandProofsMode then addCombine τProof γ' else return γ'
-       cbs'  <- if expandProofsMode then mapM (expandProofs info (mkSigs γ)) $ cbs info else return $ cbs info
-       let trustBinding x = tflag && (x `elem` derVars info || isInternal x)
-       foldM_ (consCBTop trustBinding) γ cbs'
-       hcs   <- hsCs  <$> get
-       hws   <- hsWfs <$> get
-       scss  <- sCs   <$> get
-       annot <- annotMap <$> get
-       scs   <- if sflag then concat <$> mapM splitS (hcs ++ scss)
-                         else return []
-       let smap = if sflag then solveStrata scs else []
-       let hcs' = if sflag then subsS smap hcs else hcs
-       fcs <- concat <$> mapM splitC (subsS smap hcs')
-       fws <- concat <$> mapM splitW hws
-       let annot' = if sflag then subsS smap <$> annot else annot
-       modify $ \st -> st { fEnv = fixEnv γ, fixCs = fcs , fixWfs = fws , annotMap = annot'}
-  where
-    expandProofsMode = autoproofs $ config $ spec info
-    τProof           = proofType $ spec info
-    fixEnv           = feEnv . fenv
-    mkSigs γ         = toListREnv (renv  γ) ++
-                       toListREnv (assms γ) ++
-                       toListREnv (intys γ) ++
-                       toListREnv (grtys γ)
-
-addCombine τ γ
-  = do t <- trueTy combineType
-       γ ++= ("combineProofs", combineSymbol, t)
-  where
-    combineType   = makeCombineType τ
-    combineVar    = makeCombineVar  combineType
-    combineSymbol = F.symbol combineVar
-
-------------------------------------------------------------------------------------
-initEnv :: GhcInfo -> CG CGEnv
-------------------------------------------------------------------------------------
-initEnv info
-  = do let tce   = tcEmbeds sp
-       let fVars = impVars info
-       let dcs   = filter isConLikeId ((snd <$> freeSyms sp))
-       let dcs'  = filter isConLikeId fVars
-       defaults <- forM fVars $ \x -> liftM (x,) (trueTy $ varType x)
-       dcsty    <- forM dcs   $ makeDataConTypes
-       dcsty'   <- forM dcs'  $ makeDataConTypes
-       (hs,f0)  <- refreshHoles $ grty info                  -- asserted refinements     (for defined vars)
-       f0''     <- refreshArgs' =<< grtyTop info             -- default TOP reftype      (for exported vars without spec)
-       let f0'   = if notruetypes $ config sp then [] else f0''
-       f1       <- refreshArgs'   defaults                   -- default TOP reftype      (for all vars)
-       f1'      <- refreshArgs' $ makedcs dcsty
-       f2       <- refreshArgs' $ assm info                  -- assumed refinements      (for imported vars)
-       f3       <- refreshArgs' $ vals asmSigs sp            -- assumed refinedments     (with `assume`)
-       f40      <- refreshArgs' $ vals ctors sp              -- constructor refinements  (for measures)
-       f5       <- refreshArgs' $ vals inSigs sp             -- internal refinements     (from Haskell measures)
-       (invs1, f41) <- mapSndM refreshArgs' $ makeAutoDecrDataCons dcsty  (autosize sp) dcs
-       (invs2, f42) <- mapSndM refreshArgs' $ makeAutoDecrDataCons dcsty' (autosize sp) dcs'
-       let f4    = mergeDataConTypes (mergeDataConTypes f40 (f41 ++ f42)) (filter (isDataConId . fst) f2)
-       sflag    <- scheck <$> get
-       let senv  = if sflag then f2 else []
-       let tx    = mapFst F.symbol . addRInv ialias . strataUnify senv . predsUnify sp
-       let bs    = (tx <$> ) <$> [f0 ++ f0', f1 ++ f1', f2, f3, f4, f5]
-       lts      <- lits <$> get
-       let tcb   = mapSnd (rTypeSort tce) <$> concat bs
-       let γ0    = measEnv sp (head bs) (cbs info) (tcb ++ lts) (bs!!3) (bs!!5) hs (invs1 ++ invs2)
-       globalize <$> foldM (++=) γ0 [("initEnv", x, y) | (x, y) <- concat $ tail bs]
-  where
-    sp           = spec info
-    ialias       = mkRTyConIAl $ ialiases sp
-    vals f       = map (mapSnd val) . f
-    mapSndM f (x,y) = (x,) <$> f y
-    makedcs      = map strengthenDataConType
-
-makeDataConTypes x = (x,) <$> (trueTy $ varType x)
-
-makeAutoDecrDataCons dcts specenv dcs
-  = (simplify invs, tys)
-  where
-    (invs, tys) = unzip $ concatMap go tycons
-    tycons      = L.nub $ catMaybes $ map idTyCon dcs
-
-    go tycon
-      | S.member tycon specenv =  zipWith (makeSizedDataCons dcts) (tyConDataCons tycon) [0..]
-    go _
-      = []
-    idTyCon x = dataConTyCon <$> case idDetails x of {DataConWorkId d -> Just d; DataConWrapId d -> Just d; _ -> Nothing}
-
-    simplify invs = dummyLoc . (`strengthen` invariant) .  fmap (\_ -> mempty) <$> L.nub invs
-    invariant = MkUReft (F.Reft (F.vv_, F.PAtom F.Ge (lenOf F.vv_) (F.ECon $ F.I 0)) ) mempty mempty
-
-lenOf x = F.mkEApp lenLocSymbol [F.EVar x]
-
-makeSizedDataCons dcts x' n = (toRSort $ ty_res trep, (x, fromRTypeRep trep{ty_res = tres}))
-    where
-      x      = dataConWorkId x'
-      t      = fromMaybe (impossible Nothing "makeSizedDataCons: this should never happen") $ L.lookup x dcts
-      trep   = toRTypeRep t
-      tres   = ty_res trep `strengthen` MkUReft (F.Reft (F.vv_, F.PAtom F.Eq (lenOf F.vv_) computelen)) mempty mempty
-
-      recarguments = filter (\(t,_) -> (toRSort t == toRSort tres)) (zip (ty_args trep) (ty_binds trep))
-      computelen   = foldr (F.EBin F.Plus) (F.ECon $ F.I n) (lenOf .  snd <$> recarguments)
-
-mergeDataConTypes ::  [(Var, SpecType)] -> [(Var, SpecType)] -> [(Var, SpecType)]
-mergeDataConTypes xts yts = merge (L.sortBy f xts) (L.sortBy f yts)
-  where
-    f (x,_) (y,_) = compare x y
-    merge [] ys = ys
-    merge xs [] = xs
-    merge (xt@(x, tx):xs) (yt@(y, ty):ys)
-      | x == y    = (x, mXY x tx y ty) : merge xs ys
-      | x <  y    = xt : merge xs (yt : ys)
-      | otherwise = yt : merge (xt : xs) ys
-    mXY x tx y ty = meetVarTypes (pprint x) (getSrcSpan x, tx) (getSrcSpan y, ty)
-
-refreshHoles vts = first catMaybes . unzip . map extract <$> mapM refreshHoles' vts
-refreshHoles' (x,t)
-  | noHoles t = return (Nothing, x, t)
-  | otherwise = (Just $ F.symbol x,x,) <$> mapReftM tx t
-  where
-    tx r | hasHole r = refresh r
-         | otherwise = return r
-extract (a,b,c) = (a,(b,c))
-
-refreshArgs' = mapM (mapSndM refreshArgs)
-
-strataUnify :: [(Var, SpecType)] -> (Var, SpecType) -> (Var, SpecType)
-strataUnify senv (x, t) = (x, maybe t (mappend t) pt)
-  where
-    pt                  = fmap (\(MkUReft _ _ l) -> MkUReft mempty mempty l) <$> L.lookup x senv
-
-
--- | TODO: All this *should* happen inside @Bare@ but appears
---   to happen after certain are signatures are @fresh@-ed,
---   which is why they are here.
-
--- NV : still some sigs do not get TyConInfo
-
-predsUnify :: GhcSpec -> (Var, RRType RReft) -> (Var, RRType RReft)
-predsUnify sp = second (addTyConInfo tce tyi) -- needed to eliminate some @RPropH@
-  where
-    tce            = tcEmbeds sp
-    tyi            = tyconEnv sp
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-
-measEnv sp xts cbs lts asms itys hs autosizes
-  = CGE { cgLoc = Sp.empty
-        , renv  = fromListREnv (second val <$> meas sp) []
-        , syenv = F.fromListSEnv $ freeSyms sp
-        , fenv  = initFEnv $ lts ++ (second (rTypeSort tce . val) <$> meas sp)
-        , denv  = dicts sp
-        , recs  = S.empty
-        , invs  = mkRTyConInv    $ (invariants sp ++ autosizes)
-        , ial   = mkRTyConIAl    $ ialiases   sp
-        , grtys = fromListREnv xts  []
-        , assms = fromListREnv asms []
-        , intys = fromListREnv itys []
-        , emb   = tce
-        , tgEnv = Tg.makeTagEnv cbs
-        , tgKey = Nothing
-        , trec  = Nothing
-        , lcb   = M.empty
-        , holes = fromListHEnv hs
-        , lcs   = mempty
-        , aenv  = axiom_map $ logicMap sp
-        , cerr  = Nothing 
-        }
-    where
-      tce = tcEmbeds sp
-
-assm = assmGrty impVars
-grty = assmGrty defVars
-
-assmGrty f info = [ (x, val t) | (x, t) <- sigs, x `S.member` xs ]
-  where
-    xs          = S.fromList $ f info
-    sigs        = tySigs     $ spec info
-
-grtyTop info     = forM topVs $ \v -> (v,) <$> trueTy (varType v)
-  where
-    topVs        = filter isTop $ defVars info
-    isTop v      = isExportedId v && not (v `S.member` sigVs)
-    isExportedId = flip elemNameSet (exports $ spec info) . getName
-    sigVs        = S.fromList [v | (v,_) <- tySigs (spec info) ++ asmSigs (spec info) ++ inSigs (spec info)]
-
-initCGI cfg info = CGInfo {
-    fEnv       = F.emptySEnv
-  , hsCs       = []
-  , sCs        = []
-  , hsWfs      = []
-  , fixCs      = []
-  , isBind     = []
-  , fixWfs     = []
-  , freshIndex = 0
-  , binds      = F.emptyBindEnv
-  , annotMap   = AI M.empty
-  , tyConInfo  = tyi
-  , tyConEmbed = tce
-  , kuts       = mempty -- F.ksEmpty
-  , lits       = coreBindLits tce info ++  (map (mapSnd F.sr_sort) $ map mkSort $ meas spc)
-  , termExprs  = M.fromList $ texprs spc
-  , specDecr   = decr spc
-  , specLVars  = lvars spc
-  , specLazy   = dictionaryVar `S.insert` lazy spc
-  , tcheck     = not $ notermination cfg
-  , scheck     = strata cfg
-  , trustghc   = trustinternals cfg
-  , pruneRefs  = not $ noPrune cfg
-  , logErrors  = []
-  , kvProf     = emptyKVProf
-  , recCount   = 0
-  , bindSpans  = M.empty
-  , autoSize   = autosize spc
-  , allowHO    = higherorder cfg   
-  }
-  where
-    tce        = tcEmbeds spc
-    spc        = spec info
-    tyi        = tyconEnv spc
-    mkSort = mapSnd (rTypeSortedReft tce . val)
-
-coreBindLits :: F.TCEmb TyCon -> GhcInfo -> [(F.Symbol, F.Sort)]
-coreBindLits tce info
-  = sortNub      $ [ (F.symbol x, F.strSort) | (_, Just (F.ESym x)) <- lconsts ]    -- strings
-                ++ [ (dconToSym dc, dconToSort dc) | dc <- dcons ]                  -- data constructors
-  where
-    lconsts      = literalConst tce <$> literals (cbs info)
-    dcons        = filter isDCon freeVs
-    freeVs       = impVars info ++ (snd <$> freeSyms (spec info))
-    dconToSort   = typeSort tce . expandTypeSynonyms . varType
-    dconToSym    = F.symbol . idDataCon
-    isDCon x     = isDataConId x && not (hasBaseTypeVar x)
-
--------------------------------------------------------------------
--- | Generation: Freshness ---------------------------------------
--------------------------------------------------------------------
-
--- | Right now, we generate NO new pvars. Rather than clutter code
---   with `uRType` calls, put it in one place where the above
---   invariant is /obviously/ enforced.
---   Constraint generation should ONLY use @freshTy_type@ and @freshTy_expr@
-
-freshTy_type        :: KVKind -> CoreExpr -> Type -> CG SpecType
-freshTy_type k _ τ  = freshTy_reftype k $ ofType τ
-
-freshTy_expr        :: KVKind -> CoreExpr -> Type -> CG SpecType
-freshTy_expr k e _  = freshTy_reftype k $ exprRefType e
-
-freshTy_reftype     :: KVKind -> SpecType -> CG SpecType
-freshTy_reftype k t = (fixTy t >>= refresh) =>> addKVars k
-
--- | Used to generate "cut" kvars for fixpoint. Typically, KVars for recursive
---   definitions, and also to update the KVar profile.
-addKVars        :: KVKind -> SpecType -> CG ()
-addKVars !k !t  = do when (True)    $ modify $ \s -> s { kvProf = updKVProf k kvars (kvProf s) }
-                     when (isKut k) $ modify $ \s -> s { kuts   = mappend   kvars   (kuts s)   }
-  where
-     kvars      = F.KS $ S.fromList $ specTypeKVars t
-
-isKut          :: KVKind -> Bool
-isKut RecBindE = True
-isKut _        = False
-
-specTypeKVars :: SpecType -> [F.KVar]
-specTypeKVars = foldReft (\ _ r ks -> (kvars $ ur_reft r) ++ ks) []
-
-trueTy  :: Type -> CG SpecType
-trueTy = ofType' >=> true
-
-ofType' :: Type -> CG SpecType
-ofType' = fixTy . ofType
-
-fixTy :: SpecType -> CG SpecType
-fixTy t = do tyi   <- tyConInfo  <$> get
-             tce   <- tyConEmbed <$> get
-             return $ addTyConInfo tce tyi t
-
-refreshArgsTop :: (Var, SpecType) -> CG SpecType
-refreshArgsTop (x, t)
-  = do (t', su) <- refreshArgsSub t
-       modify $ \s -> s {termExprs = M.adjust (F.subst su <$>) x $ termExprs s}
-       return t'
-
-refreshArgs :: SpecType -> CG SpecType
-refreshArgs t
-  = fst <$> refreshArgsSub t
-
-
--- NV TODO: this does not refresh args if they are wrapped in an RRTy
-refreshArgsSub :: SpecType -> CG (SpecType, F.Subst)
-refreshArgsSub t
-  = do ts     <- mapM refreshArgs ts_u
-       xs'    <- mapM (\_ -> fresh) xs
-       let sus = F.mkSubst <$> (L.inits $ zip xs (F.EVar <$> xs'))
-       let su  = last sus
-       let ts' = zipWith F.subst sus ts
-       let t'  = fromRTypeRep $ trep {ty_binds = xs', ty_args = ts', ty_res = F.subst su tbd}
-       return (t', su)
-    where
-       trep    = toRTypeRep t
-       xs      = ty_binds trep
-       ts_u    = ty_args  trep
-       tbd     = ty_res   trep
-
--------------------------------------------------------------------------------
--- | TERMINATION TYPE --------------------------------------
--------------------------------------------------------------------------------
-
-makeDecrIndex :: (Var, Template SpecType)-> CG [Int]
-makeDecrIndex (x, Assumed t)
-  = do dindex <- makeDecrIndexTy x t
-       case dindex of
-         Left _  -> return []
-         Right i -> return i
-makeDecrIndex (x, Asserted t)
-  = do dindex <- makeDecrIndexTy x t
-       case dindex of
-         Left msg -> addWarning msg >> return []
-         Right i  -> return i
-makeDecrIndex _ = return []
-
-makeDecrIndexTy x t
-  = do spDecr <- specDecr <$> get
-       autosz <- autoSize <$> get
-       hint   <- checkHint' autosz (L.lookup x $ spDecr)
-       case dindex autosz of
-         Nothing -> return $ Left msg
-         Just i  -> return $ Right $ fromMaybe [i] hint
-    where
-       ts         = ty_args trep
-       checkHint' = \autosz -> checkHint x ts (isDecreasing autosz cenv)
-       dindex     = \autosz -> L.findIndex    (isDecreasing autosz cenv) ts
-       msg        = ErrTermin (getSrcSpan x) [pprint x] (text "No decreasing parameter")
-       cenv       = makeNumEnv ts
-       trep       = toRTypeRep $ unOCons t
-
-
-recType _ ((_, []), (_, [], t))
-  = t
-
-recType autoenv ((vs, indexc), (_, index, t))
-  = makeRecType autoenv t v dxt index
-  where v    = (vs !!)  <$> indexc
-        dxt  = (xts !!) <$> index
-        xts  = zip (ty_binds trep) (ty_args trep)
-        trep = toRTypeRep $ unOCons t
-
--- checkIndex :: (Var, _, _ , _) -> _
-checkIndex (x, vs, t, index)
-  = do mapM_ (safeLogIndex msg1 vs) index
-       mapM  (safeLogIndex msg2 ts) index
-    where
-       loc   = getSrcSpan x
-       ts    = ty_args $ toRTypeRep $ unOCons $ unTemplate t
-       msg1  = ErrTermin loc [xd] ("No decreasing" <+>  pprint index <> "-th argument on" <+> xd <+> "with" <+> (pprint vs))
-       msg2  = ErrTermin loc [xd] "No decreasing parameter"
-       xd    = pprint x
-
-makeRecType autoenv t vs dxs is
-  = mergecondition t $ fromRTypeRep $ trep {ty_binds = xs', ty_args = ts'}
-  where
-    (xs', ts') = unzip $ replaceN (last is) (makeDecrType autoenv vdxs) xts
-    vdxs       = zip vs dxs
-    xts        = zip (ty_binds trep) (ty_args trep)
-    trep       = toRTypeRep $ unOCons t
-
-unOCons (RAllT v t)        = RAllT v $ unOCons t
-unOCons (RAllP p t)        = RAllP p $ unOCons t
-unOCons (RFun x tx t r)    = RFun x (unOCons tx) (unOCons t) r
-unOCons (RRTy _ _ OCons t) = unOCons t
-unOCons t                  = t
-
-
-mergecondition (RAllT _ t1) (RAllT v t2)
-  = RAllT v $ mergecondition t1 t2
-mergecondition (RAllP _ t1) (RAllP p t2)
-  = RAllP p $ mergecondition t1 t2
-mergecondition (RRTy xts r OCons t1) t2
-  = RRTy xts r OCons (mergecondition t1 t2)
-mergecondition (RFun _ t11 t12 _) (RFun x2 t21 t22 r2)
-  = RFun x2 (mergecondition t11 t21) (mergecondition t12 t22) r2
-mergecondition _ t
-  = t
-
-safeLogIndex err ls n
-  | n >= length ls = addWarning err >> return Nothing
-  | otherwise      = return $ Just $ ls !! n
-
-checkHint _ _ _ Nothing
-  = return Nothing
-
-checkHint x _ _ (Just ns) | L.sort ns /= ns
-  = addWarning (ErrTermin loc [dx] (text "The hints should be increasing")) >> return Nothing
-  where
-    loc = getSrcSpan x
-    dx  = pprint x
-
-checkHint x ts f (Just ns)
-  = (mapM (checkValidHint x ts f) ns) >>= (return . Just . catMaybes)
-
-checkValidHint x ts f n
-  | n < 0 || n >= length ts = addWarning err >> return Nothing
-  | f (ts L.!! n)           = return $ Just n
-  | otherwise               = addWarning err >> return Nothing
-  where
-    err = ErrTermin loc [xd] (vcat [ "Invalid Hint" <+> pprint (n+1) <+> "for" <+> xd
-                                   , "in"
-                                   , pprint ts ])
-    loc = getSrcSpan x
-    xd  = pprint x
-
---------------------------------------------------------------------------------
-consCBLet :: CGEnv -> CoreBind -> CG CGEnv
---------------------------------------------------------------------------------
-consCBLet γ cb
-  = do oldtcheck <- tcheck <$> get
-       strict    <- specLazy <$> get
-       let tflag  = oldtcheck
-       let isStr  = tcond cb strict
-       -- TODO: yuck.
-       modify $ \s -> s { tcheck = tflag && isStr }
-       γ' <- consCB (tflag && isStr) isStr γ cb
-       modify $ \s -> s{tcheck = oldtcheck}
-       return γ'
-
---------------------------------------------------------------------------------
--- | Constraint Generation: Corebind -------------------------------------------
---------------------------------------------------------------------------------
-consCBTop :: (Var -> Bool) -> CGEnv -> CoreBind -> CG CGEnv
---------------------------------------------------------------------------------
-consCBTop trustBinding γ cb | all trustBinding xs
-  = do ts <- mapM trueTy (varType <$> xs)
-       foldM (\γ xt -> (γ, "derived") += xt) γ (zip xs' ts)
-    where
-       xs  = bindersOf cb
-       xs' = F.symbol <$> xs
-
-consCBTop _ γ cb
-  = do oldtcheck <- tcheck <$> get
-       strict    <- specLazy <$> get
-       let tflag  = oldtcheck
-       let isStr  = tcond cb strict
-       modify $ \s -> s { tcheck = tflag && isStr}
-       γ' <- consCB (tflag && isStr) isStr γ cb
-       modify $ \s -> s { tcheck = oldtcheck}
-       return γ'
-
-tcond cb strict
-  = not $ any (\x -> S.member x strict || isInternal x) (binds cb)
-  where
-    binds (NonRec x _) = [x]
-    binds (Rec xes)    = fst $ unzip xes
-
---------------------------------------------------------------------------------
-consCB :: Bool -> Bool -> CGEnv -> CoreBind -> CG CGEnv
---------------------------------------------------------------------------------
-
--- RJ: AAAAAAARGHHH!!!!!! THIS CODE IS HORRIBLE!!!!!!!!!
-consCBSizedTys γ xes
-  = do xets''    <- forM xes $ \(x, e) -> liftM (x, e,) (varTemplate γ (x, Just e))
-       sflag     <- scheck <$> get
-       autoenv   <- autoSize <$> get
-       let cmakeFinType = if sflag then makeFinType else id
-       let cmakeFinTy   = if sflag then makeFinTy   else snd
-       let xets = mapThd3 (fmap cmakeFinType) <$> xets''
-       ts'      <- mapM (T.mapM refreshArgs) $ (thd3 <$> xets)
-       let vs    = zipWith collectArgs ts' es
-       is       <- mapM makeDecrIndex (zip xs ts') >>= checkSameLens
-       let ts = cmakeFinTy  <$> zip is ts'
-       let xeets = (\vis -> [(vis, x) | x <- zip3 xs is $ map unTemplate ts]) <$> (zip vs is)
-       (L.transpose <$> mapM checkIndex (zip4 xs vs ts is)) >>= checkEqTypes
-       let rts   = (recType autoenv <$>) <$> xeets
-       let xts   = zip xs ts
-       γ'       <- foldM extender γ xts
-       let γs    = [γ' `setTRec` (zip xs rts') | rts' <- rts]
-       let xets' = zip3 xs es ts
-       mapM_ (uncurry $ consBind True) (zip γs xets')
-       return γ'
-  where
-       (xs, es)       = unzip xes
-       dxs            = pprint <$> xs
-       collectArgs    = collectArguments . length . ty_binds . toRTypeRep . unOCons . unTemplate
-       checkEqTypes :: [[Maybe SpecType]] -> CG [[SpecType]]
-       checkEqTypes x = mapM (checkAll err1 toRSort) (catMaybes <$> x)
-       checkSameLens  = checkAll err2 length
-       err1           = ErrTermin loc dxs $ text "The decreasing parameters should be of same type"
-       err2           = ErrTermin loc dxs $ text "All Recursive functions should have the same number of decreasing parameters"
-       loc            = getSrcSpan (head xs)
-
-       checkAll _   _ []            = return []
-       checkAll err f (x:xs)
-         | all (==(f x)) (f <$> xs) = return (x:xs)
-         | otherwise                = addWarning err >> return []
-
-consCBWithExprs γ xes
-  = do xets'     <- forM xes $ \(x, e) -> liftM (x, e,) (varTemplate γ (x, Just e))
-       texprs <- termExprs <$> get
-       let xtes = catMaybes $ (`lookup` texprs) <$> xs
-       sflag     <- scheck <$> get
-       let cmakeFinType = if sflag then makeFinType else id
-       let xets  = mapThd3 (fmap cmakeFinType) <$> xets'
-       let ts    = safeFromAsserted err . thd3 <$> xets
-       ts'      <- mapM refreshArgs ts
-       let xts   = zip xs (Asserted <$> ts')
-       γ'       <- foldM extender γ xts
-       let γs    = makeTermEnvs γ' xtes xes ts ts'
-       let xets' = zip3 xs es (Asserted <$> ts')
-       mapM_ (uncurry $ consBind True) (zip γs xets')
-       return γ'
-  where (xs, es) = unzip xes
-        lookup k m | Just x <- M.lookup k m = Just (k, x)
-                   | otherwise              = Nothing
-        err      = "Constant: consCBWithExprs"
-
-makeFinTy (ns, t) = fmap go t
-  where
-    go t = fromRTypeRep $ trep {ty_args = args'}
-      where
-        trep = toRTypeRep t
-        args' = mapNs ns makeFinType $ ty_args trep
-
-makeTermEnvs γ xtes xes ts ts' = setTRec γ . zip xs <$> rts
-  where
-    vs   = zipWith collectArgs ts es
-    ys   = (fst4 . bkArrowDeep) <$> ts
-    ys'  = (fst4 . bkArrowDeep) <$> ts'
-    sus' = zipWith mkSub ys ys'
-    sus  = zipWith mkSub ys ((F.symbol <$>) <$> vs)
-    ess  = (\x -> (safeFromJust (err x) $ (x `L.lookup` xtes))) <$> xs
-    tes  = zipWith (\su es -> F.subst su <$> es)  sus ess
-    tes' = zipWith (\su es -> F.subst su <$> es)  sus' ess
-    rss  = zipWith makeLexRefa tes' <$> (repeat <$> tes)
-    rts  = zipWith (addObligation OTerm) ts' <$> rss
-    (xs, es)     = unzip xes
-    mkSub ys ys' = F.mkSubst [(x, F.EVar y) | (x, y) <- zip ys ys']
-    collectArgs  = collectArguments . length . ty_binds . toRTypeRep
-    err x        = "Constant: makeTermEnvs: no terminating expression for " ++ showPpr x
-
-addObligation :: Oblig -> SpecType -> RReft -> SpecType
-addObligation o t r  = mkArrow αs πs ls xts $ RRTy [] r o t2
-  where
-    (αs, πs, ls, t1) = bkUniv t
-    (xs, ts, rs, t2) = bkArrow t1
-    xts              = zip3 xs ts rs
-
-
-consCB tflag _ γ (Rec xes) | tflag
-  = do texprs <- termExprs <$> get
-       modify $ \i -> i { recCount = recCount i + length xes }
-       let xxes = catMaybes $ (`lookup` texprs) <$> xs
-       if null xxes
-         then consCBSizedTys γ xes
-         else check xxes <$> consCBWithExprs γ xes
-    where
-      xs = fst $ unzip xes
-      check ys r | length ys == length xs = r
-                 | otherwise              = panic (Just loc) $ msg
-      msg        = "Termination expressions must be provided for all mutually recursive binders"
-      loc        = getSrcSpan (head xs)
-      lookup k m = (k,) <$> M.lookup k m
-
-consCB _ str γ (Rec xes) | not str
-  = do xets'   <- forM xes $ \(x, e) -> liftM (x, e,) (varTemplate γ (x, Just e))
-       sflag     <- scheck <$> get
-       let cmakeDivType = if sflag then makeDivType else id
-       let xets = mapThd3 (fmap cmakeDivType) <$> xets'
-       modify $ \i -> i { recCount = recCount i + length xes }
-       let xts = [(x, to) | (x, _, to) <- xets]
-       γ'     <- foldM extender (γ `setRecs` (fst <$> xts)) xts
-       mapM_ (consBind True γ') xets
-       return γ'
-
-consCB _ _ γ (Rec xes)
-  = do xets   <- forM xes $ \(x, e) -> liftM (x, e,) (varTemplate γ (x, Just e))
-       modify $ \i -> i { recCount = recCount i + length xes }
-       let xts = [(x, to) | (x, _, to) <- xets]
-       γ'     <- foldM extender (γ `setRecs` (fst <$> xts)) xts
-       mapM_ (consBind True γ') xets
-       return γ'
-
--- | NV: Dictionaries are not checked, because
--- | class methods' preconditions are not satisfied
-consCB _ _ γ (NonRec x _) | isDictionary x
-  = do t  <- trueTy (varType x)
-       extender γ (x, Assumed t)
-  where
-    isDictionary = isJust . dlookup (denv γ)
-
-
-consCB _ _ γ (NonRec x (App (Var w) (Type τ)))
-  | Just d <- dlookup (denv γ) w
-  = do t      <- trueTy τ
-       addW    $ WfC γ t
-       let xts = dmap (f t) d
-       let  γ' = γ{denv = dinsert (denv γ) x xts }
-       t      <- trueTy (varType x)
-       extender γ' (x, Assumed t)
-   where
-       f t' (RAllT α te) = subsTyVar_meet' (α, t') te
-       f _ _ = impossible Nothing "consCB on Dictionary: this should not happen"
-
-consCB _ _ γ (NonRec x e)
-  = do to  <- varTemplate γ (x, Nothing)
-       to' <- consBind False γ (x, e, to) >>= (addPostTemplate γ)
-       extender γ (x, to')
-
---------------------------------------------------------------------------------
-consBind :: Bool
-         -> CGEnv
-         -> (Var, CoreExpr ,Template SpecType)
-         -> CG (Template SpecType)
---------------------------------------------------------------------------------
-consBind _ _ (x, _, t)
-  | RecSelId {} <- idDetails x -- don't check record selectors
-  = return t
-
-consBind isRec γ (x, e, Asserted spect)
-  = do let γ'         = γ `setBind` x
-           (_,πs,_,_) = bkUniv spect
-       γπ    <- foldM addPToEnv γ' πs
-       cconsE γπ e spect
-       when (F.symbol x `elemHEnv` holes γ) $
-         -- have to add the wf constraint here for HOLEs so we have the proper env
-         addW $ WfC γπ $ fmap killSubst spect
-       addIdA x (defAnn isRec spect)
-       return $ Asserted spect -- Nothing
-
-consBind isRec γ (x, e, Internal spect)
-  = do let γ'         = γ `setBind` x
-           (_,πs,_,_) = bkUniv spect
-       γπ    <- foldM addPToEnv γ' πs
-       let γπ' = γπ {cerr = Just $ ErrHMeas (getLocation γπ) (pprint x) (text explanation)}
-       cconsE γπ' e spect
-       when (F.symbol x `elemHEnv` holes γ) $
-         -- have to add the wf constraint here for HOLEs so we have the proper env
-         addW $ WfC γπ $ fmap killSubst spect
-       addIdA x (defAnn isRec spect)
-       return $ Internal spect -- Nothing
-  where
-    explanation = "Cannot give singleton type to the function definition."
-
-
-consBind isRec γ (x, e, Assumed spect)
-  = do let γ' = γ `setBind` x
-       γπ    <- foldM addPToEnv γ' πs
-       cconsE γπ e =<< true spect
-       addIdA x (defAnn isRec spect)
-       return $ Asserted spect -- Nothing
-  where πs   = ty_preds $ toRTypeRep spect
-
-consBind isRec γ (x, e, Unknown)
-  = do t     <- consE (γ `setBind` x) e
-       addIdA x (defAnn isRec t)
-       return $ Asserted t
-
-
-noHoles = and . foldReft (\_ r bs -> not (hasHole r) : bs) []
-
-killSubst :: RReft -> RReft
-killSubst = fmap killSubstReft
-
-killSubstReft :: F.Reft -> F.Reft
-killSubstReft = trans kv () ()
-  where
-    kv    = defaultVisitor { txExpr = ks }
-    ks _ (F.PKVar k _) = F.PKVar k mempty
-    ks _ p             = p
-
-    -- tx (F.Reft (s, rs)) = F.Reft (s, map f rs)
-    -- f (F.RKvar k _)     = F.RKvar k mempty
-    -- f (F.RConc p)       = F.RConc p
-
-defAnn True  = AnnRDf
-defAnn False = AnnDef
-
-addPToEnv γ π
-  = do γπ <- γ ++= ("addSpec1", pname π, pvarRType π)
-       foldM (++=) γπ [("addSpec2", x, ofRSort t) | (t, x, _) <- pargs π]
-
-extender γ (x, Asserted t) = γ ++= ("extender", F.symbol x, t)
-extender γ (x, Assumed t)  = γ ++= ("extender", F.symbol x, t)
-extender γ _               = return γ
-
-
-data Template a = Asserted a | Assumed a | Internal a | Unknown deriving (Functor, F.Foldable, T.Traversable)
-
-deriving instance (Show a) => (Show (Template a))
-
-unTemplate (Asserted t) = t
-unTemplate (Assumed t)  = t
-unTemplate (Internal t) = t 
-unTemplate _ = panic Nothing "Constraint.Generate.unTemplate called on `Unknown`"
-
-addPostTemplate γ (Asserted t) = Asserted <$> addPost γ t
-addPostTemplate γ (Assumed  t) = Assumed  <$> addPost γ t
-addPostTemplate γ (Internal t) = Internal  <$> addPost γ t
-addPostTemplate _ Unknown      = return Unknown
-
-safeFromAsserted _ (Asserted t) = t
-safeFromAsserted msg _ = panic Nothing $ "safeFromAsserted:" ++ msg
-
--- | @varTemplate@ is only called with a `Just e` argument when the `e`
--- corresponds to the body of a @Rec@ binder.
-varTemplate :: CGEnv -> (Var, Maybe CoreExpr) -> CG (Template SpecType)
-varTemplate γ (x, eo)
-  = case (eo, lookupREnv (F.symbol x) (grtys γ), lookupREnv (F.symbol x) (assms γ), lookupREnv (F.symbol x) (intys γ)) of
-      (_, Just t, _, _) -> Asserted <$> refreshArgsTop (x, t)
-      (_, _, _, Just t) -> Internal <$> refreshArgsTop (x, t)
-      (_, _, Just t, _) -> Assumed  <$> refreshArgsTop (x, t)
-      (Just e, _, _, _) -> do t  <- freshTy_expr RecBindE e (exprType e)
-                              addW (WfC γ t)
-                              Asserted <$> refreshArgsTop (x, t)
-      (_,      _, _, _) -> return Unknown
-
---------------------------------------------------------------------------------
--- | Constraint Generation: Checking -------------------------------------------
---------------------------------------------------------------------------------
-cconsE :: CGEnv -> Expr Var -> SpecType -> CG ()
---------------------------------------------------------------------------------
-cconsE g e t = do
-  -- Note: tracing goes here
-  -- traceM $ printf "cconsE:\n  expr = %s\n  exprType = %s\n  lqType = %s\n" (showPpr e) (showPpr (exprType e)) (showpp t)
-  cconsE' g e t
-
-cconsE' :: CGEnv -> Expr Var -> SpecType -> CG ()
-cconsE' γ e@(Let b@(NonRec x _) ee) t
-  = do sp <- specLVars <$> get
-       if (x `S.member` sp) || isDefLazyVar x
-        then cconsLazyLet γ e t
-        else do γ'  <- consCBLet γ b
-                cconsE γ' ee t
-  where
-       isDefLazyVar = L.isPrefixOf "fail" . showPpr
-
-cconsE' γ e (RAllP p t)
-  = cconsE γ' e t''
-  where
-    t'         = replacePredsWithRefs su <$> t
-    su         = (uPVar p, pVartoRConc p)
-    (css, t'') = splitConstraints t'
-    γ'         = L.foldl' addConstraints γ css
-
-cconsE' γ (Let b e) t
-  = do γ'  <- consCBLet γ b
-       cconsE γ' e t
-
-cconsE' γ (Case e x _ cases) t
-  = do γ'  <- consCBLet γ (NonRec x e)
-       forM_ cases $ cconsCase γ' x t nonDefAlts
-    where
-       nonDefAlts = [a | (a, _, _) <- cases, a /= DEFAULT]
-
-cconsE' γ (Lam α e) (RAllT _ t) | isKindVar α
-  = cconsE γ e t
-
-cconsE' γ (Lam α e) (RAllT α' t) | isTyVar α
-  = cconsE γ e $ subsTyVar_meet' (α', rVar α) t
-
-cconsE' γ (Lam x e) (RFun y ty t _)
-  | not (isTyVar x)
-  = do γ' <- (γ, "cconsE") += (F.symbol x, ty)
-       cconsE γ' e (t `F.subst1` (y, F.EVar $ F.symbol x))
-       addIdA x (AnnDef ty)
-
-cconsE' γ (Tick tt e) t
-  = cconsE (γ `setLocation` (Sp.Tick tt)) e t
-
-cconsE' γ (Cast e co) t
-  -- See Note [Type classes with a single method]
-  | Just f <- isClassConCo co
-  = cconsE γ (f e) t
-
-cconsE' γ e@(Cast e' _) t
-  = do t' <- castTy γ (exprType e) e'
-       addC (SubC γ t' t) ("cconsE Cast: " ++ showPpr e)
-
-cconsE' γ e t
-  = do te  <- consE γ e
-       te' <- instantiatePreds γ e te >>= addPost γ
-       addC (SubC γ te' t) ("cconsE: " ++ showPpr e)
-
-
-splitConstraints (RRTy cs _ OCons t)
-  = let (css, t') = splitConstraints t in (cs:css, t')
-splitConstraints (RFun x tx@(RApp c _ _ _) t r) | isClass c
-  = let (css, t') = splitConstraints t in (css, RFun x tx t' r)
-splitConstraints t
-  = ([], t)
-
--------------------------------------------------------------------
--- | @instantiatePreds@ peels away the universally quantified @PVars@
---   of a @RType@, generates fresh @Ref@ for them and substitutes them
---   in the body.
--------------------------------------------------------------------
-instantiatePreds γ e (RAllP π t)
-  = do r     <- freshPredRef γ e π
-       instantiatePreds γ e $ replacePreds "consE" t [(π, r)]
-
-instantiatePreds _ _ t0
-  = return t0
-
--------------------------------------------------------------------
--- | @instantiateStrata@ generates fresh @Strata@ vars and substitutes
---   them inside the body of the type.
--------------------------------------------------------------------
-
-instantiateStrata ls t = substStrata t ls <$> mapM (\_ -> fresh) ls
-
-substStrata t ls ls'   = F.substa f t
-  where
-    f x                = fromMaybe x $ L.lookup x su
-    su                 = zip ls ls'
-
--------------------------------------------------------------------
-cconsLazyLet γ (Let (NonRec x ex) e) t
-  = do tx <- trueTy (varType x)
-       γ' <- (γ, "Let NonRec") +++= (x', ex, tx)
-       cconsE γ' e t
-    where
-       x' = F.symbol x
-
-cconsLazyLet _ _ _
-  = panic Nothing "Constraint.Generate.cconsLazyLet called on invalid inputs"
-
---------------------------------------------------------------------------------
--- | Type Synthesis ------------------------------------------------------------
---------------------------------------------------------------------------------
-consE :: CGEnv -> Expr Var -> CG SpecType
---------------------------------------------------------------------------------
-
--- NV this is a hack to type polymorphic axiomatized functions
--- no need to check this code with flag, the axioms environment withh 
--- be empty if there is no axiomatization
-
-consE γ e'@(App e@(Var x) (Type τ)) | (M.member x $ aenv γ)
-  = do RAllT α te <- checkAll ("Non-all TyApp with expr", e) <$> consE γ e
-       t          <- if isGeneric α te then freshTy_type TypeInstE e τ else trueTy τ
-       addW        $ WfC γ t
-       t'         <- refreshVV t
-       tt <- instantiatePreds γ e' $ subsTyVar_meet' (α, t') te
-       return $ strengthenS tt (singletonReft (M.lookup x $ aenv γ) x)
-
-{-
-consE γ (Lam β (e'@(App e@(Var x) (Type τ)))) | (M.member x $ aenv γ) && isTyVar β 
-  = do RAllT α te <- checkAll ("Non-all TyApp with expr", e) <$> consE γ e
-       t          <- if isGeneric α te then freshTy_type TypeInstE e τ else trueTy τ
-       addW        $ WfC γ t
-       t'         <- refreshVV t
-       tt  <- instantiatePreds γ e' $ subsTyVar_meet' (α, t') te
-       return $ RAllT (rTyVar β) 
-                  $ strengthenS tt (singletonReft (M.lookup x $ aenv γ) x)
--}
--- NV END HACK 
-
-consE γ (Var x)
-  = do t <- varRefType γ x
-       addLocA (Just x) (getLocation γ) (varAnn γ x t)
-       return t
-
-consE _ (Lit c)
-  = refreshVV $ uRType $ literalFRefType c
-
-consE γ (App e (Type τ)) | isKind τ
-  = consE γ e
-
-
-consE γ e'@(App e (Type τ))
-  = do RAllT α te <- checkAll ("Non-all TyApp with expr", e) <$> consE γ e
-       t          <- if isGeneric α te then freshTy_type TypeInstE e τ else trueTy τ
-       addW        $ WfC γ t
-       t'         <- refreshVV t
-       instantiatePreds γ e' $ subsTyVar_meet' (α, t') te
-
--- RJ: The snippet below is *too long*. Please pull stuff from the where-clause
--- out to the top-level.
-consE γ e'@(App e a) | isDictionary a
-  = if isJust tt
-      then return $ fromJust tt
-      else do ([], πs, ls, te) <- bkUniv <$> consE γ e
-              te0              <- instantiatePreds γ e' $ foldr RAllP te πs
-              te'              <- instantiateStrata ls te0
-              (γ', te''')      <- dropExists γ te'
-              te''             <- dropConstraints γ te'''
-              updateLocA {- πs -}  (exprLoc e) te''
-              let RFun x tx t _ = checkFun ("Non-fun App with caller ", e') te''
-              pushConsBind      $ cconsE γ' a tx
-              addPost γ'        $ maybe (checkUnbound γ' e' x t a) (F.subst1 t . (x,)) (argExpr γ a)
-  where
-    grepfunname (App x (Type _)) = grepfunname x
-    grepfunname (Var x)          = x
-    grepfunname e                = panic Nothing $ "grepfunname on \t" ++ showPpr e
-    mdict w                      = case w of
-                                     Var x    -> case dlookup (denv γ) x of {Just _ -> Just x; Nothing -> Nothing}
-                                     Tick _ e -> mdict e
-                                     _        -> Nothing
-    isDictionary _               = isJust (mdict a)
-    d = fromJust (mdict a)
-    dinfo = dlookup (denv γ) d
-    tt = dhasinfo dinfo $ grepfunname e
-
-consE γ e'@(App e a)
-  = do ([], πs, ls, te) <- bkUniv <$> consE γ e
-       te0              <- instantiatePreds γ e' $ foldr RAllP te πs
-       te'              <- instantiateStrata ls te0
-       (γ', te''')      <- dropExists γ te'
-       te''             <- dropConstraints γ te'''
-       updateLocA {- πs -}  (exprLoc e) te''
-       let RFun x tx t _ = checkFun ("Non-fun App with caller ", e') te''
-       pushConsBind      $ cconsE γ' a tx
-       addPost γ'        $ maybe (checkUnbound γ' e' x t a) (F.subst1 t . (x,)) (argExpr γ a)
-       {- 
-       tt <- addPost γ'        $ maybe (checkUnbound γ' e' x t a) (F.subst1 t . (x,)) (argExpr γ a)
-       let rr = case (argExpr γ e, argExpr γ a) of 
-                 (Just e', Just a') -> uTop $ F.Reft (F.vv_, F.PAtom F.Eq (F.EVar F.vv_) (F.EApp e' a'))
-                 _                  -> mempty
-       return $ tt `strengthen` rr 
-       -}
-
-
-consE γ (Lam α e) | isTyVar α
-  = liftM (RAllT (rTyVar α)) (consE γ e)
-
-consE γ  e@(Lam x e1)
-  = do tx      <- freshTy_type LamE (Var x) τx
-       γ'      <- ((γ, "consE") += (F.symbol x, tx))
-       t1      <- consE γ' e1
-       addIdA x $ AnnDef tx
-       addW     $ WfC γ tx
-       return   $ rFun (F.symbol x) tx t1
-    where
-      FunTy τx _ = exprType e
-
-consE γ e@(Let _ _)
-  = cconsFreshE LetE γ e
-
-consE γ e@(Case _ _ _ _)
-  = cconsFreshE CaseE γ e
-
-consE γ (Tick tt e)
-  = do t <- consE (setLocation γ (Sp.Tick tt)) e
-       addLocA Nothing (tickSrcSpan tt) (AnnUse t)
-       return t
-
-consE γ (Cast e co)
-  -- See Note [Type classes with a single method]
-  | Just f <- isClassConCo co
-  = consE γ (f e)
-
-consE γ e@(Cast e' _)
-  = castTy γ (exprType e) e'
-
-consE _ e@(Coercion _)
-   = trueTy $ exprType e
-
-consE _ e@(Type t)
-  = panic Nothing $ "consE cannot handle type " ++ showPpr (e, t)
-
-castTy _ τ (Var x)
-  = do t <- trueTy τ
-       return $  t `strengthen` (uTop $ F.uexprReft $ F.expr x)
-
-castTy g t (Tick _ e)
-  = castTy g t e
-
-castTy _ _ e
-  = panic Nothing $ "castTy cannot handle expr " ++ showPpr e
-
-isClassConCo :: Coercion -> Maybe (Expr Var -> Expr Var)
--- See Note [Type classes with a single method]
-isClassConCo co
-  --- | trace ("isClassConCo: " ++ showPpr (coercionKind co)) False
-  --- = undefined
-
-  | Pair t1 t2 <- coercionKind co
-  , isClassPred t2
-  , (tc,ts) <- splitTyConApp t2
-  , [dc]    <- tyConDataCons tc
-  , [tm]    <- dataConOrigArgTys dc
-               -- tcMatchTy because we have to instantiate the class tyvars
-  , Just _  <- tcMatchTy (mkVarSet $ tyConTyVars tc) tm t1
-  = Just (\e -> mkCoreConApps dc $ map Type ts ++ [e])
-
-  | otherwise
-  = Nothing
-
-----------------------------------------------------------------------
--- Note [Type classes with a single method]
-----------------------------------------------------------------------
--- GHC 7.10 encodes type classes with a single method as newtypes and
--- `cast`s between the method and class type instead of applying the
--- class constructor. Just rewrite the core to what we're used to
--- seeing..
---
--- specifically, we want to rewrite
---
---   e `cast` ((a -> b) ~ C)
---
--- to
---
---   D:C e
---
--- but only when
---
---   D:C :: (a -> b) -> C
-
--- | @consElimE@ is used to *synthesize* types by **existential elimination**
---   instead of *checking* via a fresh template. That is, assuming
---      γ |- e1 ~> t1
---   we have
---      γ |- let x = e1 in e2 ~> Ex x t1 t2
---   where
---      γ, x:t1 |- e2 ~> t2
---   instead of the earlier case where we generate a fresh template `t` and check
---      γ, x:t1 |- e <~ t
-
--- consElimE γ xs e
---   = do t     <- consE γ e
---        xts   <- forM xs $ \x -> (x,) <$> (γ ??= x)
---        return $ rEx xts t
-
--- | @consFreshE@ is used to *synthesize* types with a **fresh template** when
---   the above existential elimination is not easy (e.g. at joins, recursive binders)
-
-cconsFreshE kvkind γ e
-  = do t   <- freshTy_type kvkind e $ exprType e
-       addW $ WfC γ t
-       cconsE γ e t
-       return t
-
-checkUnbound γ e x t a
-  | x `notElem` (F.syms t) = t
-  | otherwise              = panic (Just $ getLocation γ) msg
-  where
-    msg = unlines [ "checkUnbound: " ++ show x ++ " is elem of syms of " ++ show t
-                         , "In", showPpr e, "Arg = " , show a ]
-
-
-dropExists γ (REx x tx t) = liftM (, t) $ (γ, "dropExists") += (x, tx)
-dropExists γ t            = return (γ, t)
-
-dropConstraints :: CGEnv -> SpecType -> CG SpecType
-dropConstraints γ (RFun x tx@(RApp c _ _ _) t r) | isClass c
-  = (flip (RFun x tx)) r <$> dropConstraints γ t
-dropConstraints γ (RRTy cts _ OCons t)
-  = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) γ xts
-       addC (SubC  γ' t1 t2)  "dropConstraints"
-       dropConstraints γ t
-  where
-    (xts, t1, t2) = envToSub cts
-
-dropConstraints _ t = return t
-
--------------------------------------------------------------------------------------
-cconsCase :: CGEnv -> Var -> SpecType -> [AltCon] -> (AltCon, [Var], CoreExpr) -> CG ()
--------------------------------------------------------------------------------------
-cconsCase γ x t acs (ac, ys, ce)
-  = do cγ <- caseEnv γ x acs ac ys
-       cconsE cγ ce t
-
---------------------------------------------------------------------------------
-refreshTy :: SpecType -> CG SpecType
---------------------------------------------------------------------------------
-refreshTy t = refreshVV t >>= refreshArgs
-
-refreshVV (RAllT a t) = liftM (RAllT a) (refreshVV t)
-refreshVV (RAllP p t) = liftM (RAllP p) (refreshVV t)
-
-refreshVV (REx x t1 t2)
-  = do [t1', t2'] <- mapM refreshVV [t1, t2]
-       liftM (shiftVV (REx x t1' t2')) fresh
-
-refreshVV (RFun x t1 t2 r)
-  = do [t1', t2'] <- mapM refreshVV [t1, t2]
-       liftM (shiftVV (RFun x t1' t2' r)) fresh
-
-refreshVV (RAppTy t1 t2 r)
-  = do [t1', t2'] <- mapM refreshVV [t1, t2]
-       liftM (shiftVV (RAppTy t1' t2' r)) fresh
-
-refreshVV (RApp c ts rs r)
-  = do ts' <- mapM refreshVV ts
-       rs' <- mapM refreshVVRef rs
-       liftM (shiftVV (RApp c ts' rs' r)) fresh
-
-refreshVV t
-  = return t
-
-refreshVVRef (RProp ss (RHole r))
-  = return $ RProp ss (RHole r)
-
-refreshVVRef (RProp ss t)
-  = do xs    <- mapM (\_ -> fresh) (fst <$> ss)
-       let su = F.mkSubst $ zip (fst <$> ss) (F.EVar <$> xs)
-       liftM (RProp (zip xs (snd <$> ss)) . F.subst su) (refreshVV t)
-
-
-
-
--------------------------------------------------------------------------------------
-caseEnv   :: CGEnv -> Var -> [AltCon] -> AltCon -> [Var] -> CG CGEnv
--------------------------------------------------------------------------------------
-caseEnv γ x _   (DataAlt c) ys
-  = do let (x' : ys')    = F.symbol <$> (x:ys)
-       xt0              <- checkTyCon ("checkTycon cconsCase", x) <$> γ ??= x
-       let xt            = shiftVV xt0 x'
-       tdc              <- γ ??= ({- F.symbol -} dataConWorkId c) >>= refreshVV
-       let (rtd, yts, _) = unfoldR tdc xt ys
-       let r1            = dataConReft   c   ys'
-       let r2            = dataConMsReft rtd ys'
-       let xt            = (xt0 `F.meet` rtd) `strengthen` (uTop (r1 `F.meet` r2))
-       let cbs           = safeZip "cconsCase" (x':ys') (xt0:yts)
-       cγ'              <- addBinders γ x' cbs
-       cγ               <- addBinders cγ' x' [(x', xt)]
-       return cγ
-
-caseEnv γ x acs a _
-  = do let x'  = F.symbol x
-       xt'    <- (`strengthen` uTop (altReft γ acs a)) <$> (γ ??= x)
-       cγ     <- addBinders γ x' [(x', xt')]
-       return cγ
-
-altReft _ _ (LitAlt l)   = literalFReft l
-altReft γ acs DEFAULT    = mconcat [notLiteralReft l | LitAlt l <- acs]
-  where notLiteralReft   = maybe mempty F.notExprReft . snd . literalConst (emb γ)
-altReft _ _ _            = panic Nothing "Constraint : altReft"
-
-unfoldR td (RApp _ ts rs _) ys = (t3, tvys ++ yts, ignoreOblig rt)
-  where
-        tbody              = instantiatePvs (instantiateTys td ts) $ reverse rs
-        (ys0, yts', _, rt) = safeBkArrow $ instantiateTys tbody tvs'
-        yts''              = zipWith F.subst sus (yts'++[rt])
-        (t3,yts)           = (last yts'', init yts'')
-        sus                = F.mkSubst <$> (L.inits [(x, F.EVar y) | (x, y) <- zip ys0 ys'])
-        (αs, ys')          = mapSnd (F.symbol <$>) $ L.partition isTyVar ys
-        tvs'               = rVar <$> αs
-        tvys               = ofType . varType <$> αs
-
-unfoldR _  _                _  = panic Nothing "Constraint.hs : unfoldR"
-
-instantiateTys = L.foldl' go
-  where go (RAllT α tbody) t = subsTyVar_meet' (α, t) tbody
-        go _ _               = panic Nothing "Constraint.instanctiateTy"
-
-instantiatePvs = L.foldl' go
-  where go (RAllP p tbody) r = replacePreds "instantiatePv" tbody [(p, r)]
-        go _ _               = panic Nothing "Constraint.instanctiatePv"
-
-checkTyCon _ t@(RApp _ _ _ _) = t
-checkTyCon x t                = checkErr x t
-
-checkFun _ t@(RFun _ _ _ _)   = t
-checkFun x t                  = checkErr x t
-
-checkAll _ t@(RAllT _ _)      = t
-checkAll x t                  = checkErr x t
-
-checkErr (msg, e) t          = panic Nothing $ msg ++ showPpr e ++ ", type: " ++ showpp t
-
-varAnn γ x t
-  | x `S.member` recs γ      = AnnLoc (getSrcSpan x)
-  | otherwise                = AnnUse t
-
------------------------------------------------------------------------
--- | Helpers: Creating Fresh Refinement -------------------------------
------------------------------------------------------------------------
-
-freshPredRef :: CGEnv -> CoreExpr -> PVar RSort -> CG SpecProp
-freshPredRef γ e (PV _ (PVProp τ) _ as)
-  = do t    <- freshTy_type PredInstE e (toType τ)
-       args <- mapM (\_ -> fresh) as
-       let targs = [(x, s) | (x, (s, y, z)) <- zip args as, (F.EVar y) == z ]
-       γ' <- foldM (++=) γ [("freshPredRef", x, ofRSort τ) | (x, τ) <- targs]
-       addW $ WfC γ' t
-       return $ RProp targs t
-
-freshPredRef _ _ (PV _ PVHProp _ _)
-  = todo Nothing "EFFECTS:freshPredRef"
-
---------------------------------------------------------------------------------
--- | Helpers: Creating Refinement Types For Various Things ---------------------
---------------------------------------------------------------------------------
-
-argExpr :: CGEnv -> CoreExpr -> Maybe F.Expr
-argExpr _ (Var vy)    = Just $ F.eVar vy
-argExpr γ (Lit c)     = snd  $ literalConst (emb γ) c
-argExpr γ (Tick _ e)  = argExpr γ e
-argExpr _ _           = Nothing
-
-
---------------------------------------------------------------------------------
-(??=) :: (?callStack :: CallStack) => CGEnv -> Var -> CG SpecType
---------------------------------------------------------------------------------
-γ ??= x = case M.lookup x' (lcb γ) of
-            Just e  -> consE (γ -= x') e
-            Nothing -> refreshTy tx
-          where
-            x' = F.symbol x
-            tx = fromMaybe tt (γ ?= x')
-            tt = ofType $ varType x
-
-
---------------------------------------------------------------------------------
-varRefType :: (?callStack :: CallStack) => CGEnv -> Var -> CG SpecType
---------------------------------------------------------------------------------
-varRefType γ x = do
-  xt <- varRefType' γ x <$> (γ ??= x)
-  return xt -- F.tracepp (printf "varRefType x = [%s]" (showpp x))
-
-varRefType' :: CGEnv -> Var -> SpecType -> SpecType
-varRefType' γ x t'
-  | Just tys <- trec γ, Just tr  <- M.lookup x' tys
-  = tr `strengthenS` xr
-  | otherwise
-  = t' `strengthenS` xr
-  where
-    xr = singletonReft (M.lookup x $ aenv γ) x
-    x' = F.symbol x
-
-singletonReft (Just x) _ = uTop $ F.symbolReft x
-singletonReft Nothing  v = uTop $ F.symbolReft $ F.symbol v
-
--- | RJ: `nomeet` replaces `strengthenS` for `strengthen` in the definition
---   of `varRefType`. Why does `tests/neg/strata.hs` fail EVEN if I just replace
---   the `otherwise` case? The fq file holds no answers, both are sat.
-strengthenS :: (PPrint r, F.Reftable r) => RType c tv r -> r -> RType c tv r
-strengthenS (RApp c ts rs r) r'  = RApp c ts rs $ topMeet r r'
-strengthenS (RVar a r) r'        = RVar a       $ topMeet r r'
-strengthenS (RFun b t1 t2 r) r'  = RFun b t1 t2 $ topMeet r r'
-strengthenS (RAppTy t1 t2 r) r'  = RAppTy t1 t2 $ topMeet r r'
-strengthenS t _                  = t
-
-topMeet :: (PPrint r, F.Reftable r) => r -> r -> r
-topMeet r r' = {- F.tracepp msg $ -} F.top r `F.meet` r'
-  -- where
-    -- msg = printf "topMeet r = [%s] r' = [%s]" (showpp r) (showpp r')
-
-  -- traceM $ printf "cconsE:\n  expr = %s\n  exprType = %s\n  lqType = %s\n" (showPpr e) (showPpr (exprType e)) (showpp t)
---------------------------------------------------------------------------------
--- | Cleaner Signatures For Rec-bindings ---------------------------------------
---------------------------------------------------------------------------------
-
-exprLoc                         :: CoreExpr -> Maybe SrcSpan
-
-exprLoc (Tick tt _)             = Just $ tickSrcSpan tt
-exprLoc (App e a) | isType a    = exprLoc e
-exprLoc _                       = Nothing
-
-isType (Type _)                 = True
-isType a                        = eqType (exprType a) predType
-
-
-exprRefType :: CoreExpr -> SpecType
-exprRefType = exprRefType_ M.empty
-
-exprRefType_ :: M.HashMap Var SpecType -> CoreExpr -> SpecType
-exprRefType_ γ (Let b e)
-  = exprRefType_ (bindRefType_ γ b) e
-
-exprRefType_ γ (Lam α e) | isTyVar α
-  = RAllT (rTyVar α) (exprRefType_ γ e)
-
-exprRefType_ γ (Lam x e)
-  = rFun (F.symbol x) (ofType $ varType x) (exprRefType_ γ e)
-
-exprRefType_ γ (Tick _ e)
-  = exprRefType_ γ e
-
-exprRefType_ γ (Var x)
-  = M.lookupDefault (ofType $ varType x) x γ
-
-exprRefType_ _ e
-  = ofType $ exprType e
-
-bindRefType_ γ (Rec xes)
-  = extendγ γ [(x, exprRefType_ γ e) | (x,e) <- xes]
-
-bindRefType_ γ (NonRec x e)
-  = extendγ γ [(x, exprRefType_ γ e)]
-
-extendγ γ xts
-  = foldr (\(x,t) m -> M.insert x t m) γ xts
-
-isGeneric :: RTyVar -> SpecType -> Bool
-isGeneric α t =  all (\(c, α') -> (α'/=α) || isOrd c || isEq c ) (classConstrs t)
-  where classConstrs t = [(c, α') | (c, ts) <- tyClasses t
+-- | This module defines the representation of Subtyping and WF Constraints,
+--   and the code for syntax-directed constraint generation.
+
+module Language.Haskell.Liquid.Constraint.Generate ( generateConstraints ) where
+
+import           Outputable                                    (Outputable)
+import           Prelude                                       hiding (error, undefined)
+import           GHC.Stack
+import           CoreUtils                                     (exprType)
+import           MkCore
+import           Coercion
+import           DataCon
+import           Pair
+import           CoreSyn
+import           SrcLoc                                 hiding (Located)
+import           Type
+import           TyCon
+import           CoAxiom
+import           PrelNames
+import           TypeRep
+import           Class                                         (className)
+import           Var
+import           IdInfo
+import           Name        hiding (varName)
+import           FastString (fastStringToByteString)
+import           Unify
+import           VarSet
+import           Text.PrettyPrint.HughesPJ                     hiding (first)
+import           Control.Monad.State
+import           Data.Maybe                                    (fromMaybe, catMaybes, fromJust, isJust)
+import qualified Data.HashMap.Strict                           as M
+import qualified Data.HashSet                                  as S
+import qualified Data.List                                     as L
+import qualified Data.Foldable                                 as F
+import qualified Data.Traversable                              as T
+import           Language.Fixpoint.Misc
+import           Language.Fixpoint.Types.Visitor
+import qualified Language.Fixpoint.Types                       as F
+-- import           Language.Fixpoint.Solver.Instantiate
+import           Language.Haskell.Liquid.Constraint.Fresh
+import           Language.Haskell.Liquid.Constraint.Init
+import           Language.Haskell.Liquid.Constraint.Env
+import           Language.Haskell.Liquid.Constraint.Monad
+import           Language.Haskell.Liquid.Constraint.Split
+import           Language.Haskell.Liquid.Types.Dictionaries
+import qualified Language.Haskell.Liquid.GHC.Resugar           as Rs
+import qualified Language.Haskell.Liquid.GHC.SpanStack         as Sp
+import           Language.Haskell.Liquid.Types                 hiding (binds, Loc, loc, freeTyVars, Def)
+import           Language.Haskell.Liquid.Types.Names       (anyTypeSymbol)
+import           Language.Haskell.Liquid.Types.Strata
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types.PredType        hiding (freeTyVars)
+import           Language.Haskell.Liquid.GHC.Misc          ( isInternal, collectArguments, tickSrcSpan, showPpr )
+import           Language.Haskell.Liquid.Misc
+import           Language.Haskell.Liquid.Types.Literals
+-- NOPROVER import           Language.Haskell.Liquid.Constraint.Axioms
+import           Language.Haskell.Liquid.Constraint.Types
+import           Language.Haskell.Liquid.Constraint.Constraint
+
+-- import Language.Haskell.Liquid.UX.Config (allowLiquidInstationation)
+
+-- import System.IO.Unsafe
+-- import Debug.Trace (trace)
+
+--------------------------------------------------------------------------------
+-- | Constraint Generation: Toplevel -------------------------------------------
+--------------------------------------------------------------------------------
+generateConstraints      :: GhcInfo -> CGInfo
+--------------------------------------------------------------------------------
+generateConstraints info = {-# SCC "ConsGen" #-} execState act $ initCGI cfg info
+  where
+    act                  = consAct cfg info
+    cfg                  = getConfig   info
+
+instance Show (Cinfo) where
+  show = show . ci_var
+
+consAct :: Config -> GhcInfo -> CG ()
+consAct cfg info = do
+  γ'    <- initEnv      info
+  sflag <- scheck   <$> get
+  γ     <- {- NOPROVER if expandProofsMode then addCombine τProof γ' else -}
+           return  γ'
+  cbs'  <- {- NOPROVER if expandProofsMode then mapM (expandProofs info (mkSigs γ)) $ cbs info else -}
+           return $ cbs info
+  foldM_ (consCBTop cfg info) γ cbs'
+  hcs   <- hsCs  <$> get
+  hws   <- hsWfs <$> get
+  scss  <- sCs   <$> get
+  annot <- annotMap <$> get
+  scs   <- if sflag then concat <$> mapM splitS (hcs ++ scss)
+                    else return []
+  let smap = if sflag then solveStrata scs else []
+  let hcs' = if sflag then subsS smap hcs else hcs
+  fcs <- concat <$> mapM splitC (subsS smap hcs')
+  fws <- concat <$> mapM splitW hws
+  -- bds <- binds <$> get
+  -- dcs <- dataConTys <$> get
+  -- let fcs' = F.addIds fcs
+  -- let fcs'' = if allowLiquidInstationation (getConfig info) then unsafePerformIO . instantiateAxioms bds (feEnv (fenv γ)) (makeAxiomEnvironment info dcs fcs') <$> fcs' else fcs
+  let annot' = if sflag then subsS smap <$> annot else annot
+  modify $ \st -> st { fEnv     = feEnv (fenv γ)
+                     , cgLits   = litEnv   γ
+                     , cgConsts = (cgConsts st) `mappend` (constEnv γ)
+                     , fixCs    = fcs
+                     , fixWfs   = fws
+                     , annotMap = annot' }
+  where
+    -- NOPROVER expandProofsMode = autoproofs $ getConfig info
+    -- NOPROVER τProof           = gsProofType $ spec info
+    -- NOPROVER mkSigs γ         = toListREnv (renv  γ) ++
+                       -- NOPROVER toListREnv (assms γ) ++
+                       -- NOPROVER toListREnv (intys γ) ++
+                       -- NOPROVER toListREnv (grtys γ)
+
+-- NOPROVER addCombine :: Maybe Type -> CGEnv -> CG CGEnv
+-- NOPROVER addCombine τ γ
+  -- NOPROVER = do t <- trueTy combineType
+       -- NOPROVER γ += ("combineProofs", combineSymbol, t)
+    -- NOPROVER where
+       -- NOPROVER combineType   = makeCombineType τ
+       -- NOPROVER combineVar    = makeCombineVar  combineType
+       -- NOPROVER combineSymbol = F.symbol combineVar
+
+--------------------------------------------------------------------------------
+-- | TERMINATION TYPE ----------------------------------------------------------
+--------------------------------------------------------------------------------
+makeDecrIndex :: (Var, Template SpecType)-> CG [Int]
+makeDecrIndex (x, Assumed t)
+  = do dindex <- makeDecrIndexTy x t
+       case dindex of
+         Left _  -> return []
+         Right i -> return i
+makeDecrIndex (x, Asserted t)
+  = do dindex <- makeDecrIndexTy x t
+       case dindex of
+         Left msg -> addWarning msg >> return []
+         Right i  -> return i
+makeDecrIndex _ = return []
+
+makeDecrIndexTy :: Var -> SpecType -> CG (Either (TError t) [Int])
+makeDecrIndexTy x t
+  = do spDecr <- specDecr <$> get
+       autosz <- autoSize <$> get
+       hint   <- checkHint' autosz (L.lookup x $ spDecr)
+       case dindex autosz of
+         Nothing -> return $ Left msg
+         Just i  -> return $ Right $ fromMaybe [i] hint
+    where
+       ts         = ty_args trep
+       checkHint' = \autosz -> checkHint x ts (isDecreasing autosz cenv)
+       dindex     = \autosz -> L.findIndex    (isDecreasing autosz cenv) ts
+       msg        = ErrTermin (getSrcSpan x) [F.pprint x] (text "No decreasing parameter")
+       cenv       = makeNumEnv ts
+       trep       = toRTypeRep $ unOCons t
+
+
+recType :: F.Symbolic a
+        => S.HashSet TyCon
+        -> (([a], [Int]), (t, [Int], SpecType))
+        -> SpecType
+recType _ ((_, []), (_, [], t))
+  = t
+
+recType autoenv ((vs, indexc), (_, index, t))
+  = makeRecType autoenv t v dxt index
+  where v    = (vs !!)  <$> indexc
+        dxt  = (xts !!) <$> index
+        xts  = zip (ty_binds trep) (ty_args trep)
+        trep = toRTypeRep $ unOCons t
+
+checkIndex :: (NamedThing t, PPrint t, PPrint [a])
+           => (t, [a], Template (RType c tv r), [Int])
+           -> CG [Maybe (RType c tv r)]
+checkIndex (x, vs, t, index)
+  = do mapM_ (safeLogIndex msg1 vs) index
+       mapM  (safeLogIndex msg2 ts) index
+    where
+       loc   = getSrcSpan x
+       ts    = ty_args $ toRTypeRep $ unOCons $ unTemplate t
+       msg1  = ErrTermin loc [xd] ("No decreasing" <+> F.pprint index <> "-th argument on" <+> xd <+> "with" <+> (F.pprint vs))
+       msg2  = ErrTermin loc [xd] "No decreasing parameter"
+       xd    = F.pprint x
+
+makeRecType :: (Enum a1, Eq a1, Num a1, F.Symbolic a)
+            => S.HashSet TyCon
+            -> SpecType
+            -> [a]
+            -> [(F.Symbol, SpecType)]
+            -> [a1]
+            -> SpecType
+makeRecType autoenv t vs dxs is
+  = mergecondition t $ fromRTypeRep $ trep {ty_binds = xs', ty_args = ts'}
+  where
+    (xs', ts') = unzip $ replaceN (last is) (makeDecrType autoenv vdxs) xts
+    vdxs       = zip vs dxs
+    xts        = zip (ty_binds trep) (ty_args trep)
+    trep       = toRTypeRep $ unOCons t
+
+unOCons :: RType c tv r -> RType c tv r
+unOCons (RAllT v t)        = RAllT v $ unOCons t
+unOCons (RAllP p t)        = RAllP p $ unOCons t
+unOCons (RFun x tx t r)    = RFun x (unOCons tx) (unOCons t) r
+unOCons (RRTy _ _ OCons t) = unOCons t
+unOCons t                  = t
+
+mergecondition :: RType c tv r -> RType c tv r -> RType c tv r
+mergecondition (RAllT _ t1) (RAllT v t2)
+  = RAllT v $ mergecondition t1 t2
+mergecondition (RAllP _ t1) (RAllP p t2)
+  = RAllP p $ mergecondition t1 t2
+mergecondition (RRTy xts r OCons t1) t2
+  = RRTy xts r OCons (mergecondition t1 t2)
+mergecondition (RFun _ t11 t12 _) (RFun x2 t21 t22 r2)
+  = RFun x2 (mergecondition t11 t21) (mergecondition t12 t22) r2
+mergecondition _ t
+  = t
+
+safeLogIndex :: Error -> [a] -> Int -> CG (Maybe a)
+safeLogIndex err ls n
+  | n >= length ls = addWarning err >> return Nothing
+  | otherwise      = return $ Just $ ls !! n
+
+checkHint :: (NamedThing a, PPrint a, PPrint [a1])
+          => a -> [a1] -> (a1 -> Bool) -> Maybe [Int] -> CG (Maybe [Int])
+checkHint _ _ _ Nothing
+  = return Nothing
+
+checkHint x _ _ (Just ns) | L.sort ns /= ns
+  = addWarning (ErrTermin loc [dx] (text "The hints should be increasing")) >> return Nothing
+  where
+    loc = getSrcSpan x
+    dx  = F.pprint x
+
+checkHint x ts f (Just ns)
+  = (mapM (checkValidHint x ts f) ns) >>= (return . Just . catMaybes)
+
+checkValidHint :: (NamedThing a, PPrint a, PPrint [a1])
+               => a -> [a1] -> (a1 -> Bool) -> Int -> CG (Maybe Int)
+checkValidHint x ts f n
+  | n < 0 || n >= length ts = addWarning err >> return Nothing
+  | f (ts L.!! n)           = return $ Just n
+  | otherwise               = addWarning err >> return Nothing
+  where
+    err = ErrTermin loc [xd] (vcat [ "Invalid Hint" <+> F.pprint (n+1) <+> "for" <+> xd
+                                   , "in"
+                                   , F.pprint ts ])
+    loc = getSrcSpan x
+    xd  = F.pprint x
+
+--------------------------------------------------------------------------------
+consCBLet :: CGEnv -> CoreBind -> CG CGEnv
+--------------------------------------------------------------------------------
+consCBLet γ cb = do
+  oldtcheck <- tcheck <$> get
+  lazyVars  <- specLazy <$> get
+  let isStr  = doTermCheck lazyVars cb
+  -- TODO: yuck.
+  modify $ \s -> s { tcheck = oldtcheck && isStr }
+  γ' <- consCB (oldtcheck && isStr) isStr γ cb
+  modify $ \s -> s{tcheck = oldtcheck}
+  return γ'
+
+--------------------------------------------------------------------------------
+-- | Constraint Generation: Corebind -------------------------------------------
+--------------------------------------------------------------------------------
+consCBTop :: Config -> GhcInfo -> CGEnv -> CoreBind -> CG CGEnv
+--------------------------------------------------------------------------------
+consCBTop cfg info γ cb
+  | all (trustVar cfg info) xs
+  = foldM addB γ xs
+    where
+       xs   = bindersOf cb
+       tt   = trueTy . varType
+       addB γ x = tt x >>= (\t -> γ += ("derived", F.symbol x, t))
+
+consCBTop _ _ γ cb
+  = do oldtcheck <- tcheck <$> get
+       lazyVars  <- specLazy <$> get
+       let isStr  = doTermCheck lazyVars cb
+       modify $ \s -> s { tcheck = oldtcheck && isStr}
+       -- remove invariants that came from the cb definition
+       let (γ', i) = removeInvariant γ cb                 --- DIFF
+       γ'' <- consCB (oldtcheck && isStr) isStr (γ'{cgVar = topBind cb}) cb
+       modify $ \s -> s { tcheck = oldtcheck}
+       return $ restoreInvariant γ'' i                    --- DIFF
+    where
+      topBind (NonRec v _)  = Just v 
+      topBind (Rec [(v,_)]) = Just v 
+      topBind _             = Nothing 
+
+
+trustVar :: Config -> GhcInfo -> Var -> Bool
+trustVar cfg info x = trustInternals cfg && derivedVar info x
+
+derivedVar :: GhcInfo -> Var -> Bool
+derivedVar info x = x `elem` derVars info || isInternal x
+
+doTermCheck :: S.HashSet Var -> Bind Var -> Bool
+doTermCheck lazyVs = not . any (\x -> S.member x lazyVs || isInternal x) . bindersOf
+
+-- RJ: AAAAAAARGHHH!!!!!! THIS CODE IS HORRIBLE!!!!!!!!!
+consCBSizedTys :: CGEnv -> [(Var, CoreExpr)] -> CG CGEnv
+consCBSizedTys γ xes
+  = do xets''    <- forM xes $ \(x, e) -> liftM (x, e,) (varTemplate γ (x, Just e))
+       sflag     <- scheck <$> get
+       autoenv   <- autoSize <$> get
+       let cmakeFinType = if sflag then makeFinType else id
+       let cmakeFinTy   = if sflag then makeFinTy   else snd
+       let xets = mapThd3 (fmap cmakeFinType) <$> xets''
+       ts'      <- mapM (T.mapM refreshArgs) $ (thd3 <$> xets)
+       let vs    = zipWith collectArgs ts' es
+       is       <- mapM makeDecrIndex (zip xs ts') >>= checkSameLens
+       let ts = cmakeFinTy  <$> zip is ts'
+       let xeets = (\vis -> [(vis, x) | x <- zip3 xs is $ map unTemplate ts]) <$> (zip vs is)
+       (L.transpose <$> mapM checkIndex (zip4 xs vs ts is)) >>= checkEqTypes
+       let rts   = (recType autoenv <$>) <$> xeets
+       let xts   = zip xs ts
+       γ'       <- foldM extender γ xts
+       let γs    = zipWith makeRecInvariants [γ' `setTRec` zip xs rts' | rts' <- rts] (filter (not . isClassPred . varType) <$> vs)
+       let xets' = zip3 xs es ts
+       mapM_ (uncurry $ consBind True) (zip γs xets')
+       return γ'
+  where
+       (xs, es)       = unzip xes
+       dxs            = F.pprint <$> xs
+       collectArgs    = collectArguments . length . ty_binds . toRTypeRep . unOCons . unTemplate
+       checkEqTypes :: [[Maybe SpecType]] -> CG [[SpecType]]
+       checkEqTypes x = mapM (checkAll err1 toRSort) (catMaybes <$> x)
+       checkSameLens  = checkAll err2 length
+       err1           = ErrTermin loc dxs $ text "The decreasing parameters should be of same type"
+       err2           = ErrTermin loc dxs $ text "All Recursive functions should have the same number of decreasing parameters"
+       loc            = getSrcSpan (head xs)
+
+       checkAll _   _ []            = return []
+       checkAll err f (x:xs)
+         | all (==(f x)) (f <$> xs) = return (x:xs)
+         | otherwise                = addWarning err >> return []
+
+consCBWithExprs :: CGEnv
+                -> [(Var, CoreExpr)]
+                -> CG CGEnv
+consCBWithExprs γ xes
+  = do xets'     <- forM xes $ \(x, e) -> liftM (x, e,) (varTemplate γ (x, Just e))
+       texprs    <- termExprs <$> get
+       let xtes   = catMaybes $ (`lookup` texprs) <$> xs
+       sflag     <- scheck <$> get
+       let cmakeFinType = if sflag then makeFinType else id
+       let xets  = mapThd3 (fmap cmakeFinType) <$> xets'
+       let ts    = safeFromAsserted err . thd3 <$> xets
+       ts'      <- mapM refreshArgs ts
+       let xts   = zip xs (Asserted <$> ts')
+       γ'       <- foldM extender γ xts
+       let γs    = makeTermEnvs γ' xtes xes ts ts'
+       let xets' = zip3 xs es (Asserted <$> ts')
+       mapM_ (uncurry $ consBind True) (zip γs xets')
+       return γ'
+  where (xs, es) = unzip xes
+        lookup k m | Just x <- M.lookup k m = Just (k, x)
+                   | otherwise              = Nothing
+        err      = "Constant: consCBWithExprs"
+
+makeFinTy :: (Eq a, Functor f, Num a, Foldable t)
+          => (t a, f SpecType)
+          -> f SpecType
+makeFinTy (ns, t) = fmap go t
+  where
+    go t = fromRTypeRep $ trep {ty_args = args'}
+      where
+        trep = toRTypeRep t
+        args' = mapNs ns makeFinType $ ty_args trep
+
+makeTermEnvs :: CGEnv -> [(Var, [F.Located F.Expr])] -> [(Var, CoreExpr)]
+             -> [SpecType] -> [SpecType]
+             -> [CGEnv]
+makeTermEnvs γ xtes xes ts ts' = setTRec γ . zip xs <$> rts
+  where
+    vs   = zipWith collectArgs ts es
+    ys   = (fst4 . bkArrowDeep) <$> ts
+    ys'  = (fst4 . bkArrowDeep) <$> ts'
+    sus' = zipWith mkSub ys ys'
+    sus  = zipWith mkSub ys ((F.symbol <$>) <$> vs)
+    ess  = (\x -> (safeFromJust (err x) $ (x `L.lookup` xtes))) <$> xs
+    tes  = zipWith (\su es -> F.subst su <$> es)  sus ess
+    tes' = zipWith (\su es -> F.subst su <$> es)  sus' ess
+    rss  = zipWith makeLexRefa tes' <$> (repeat <$> tes)
+    rts  = zipWith (addObligation OTerm) ts' <$> rss
+    (xs, es)     = unzip xes
+    mkSub ys ys' = F.mkSubst [(x, F.EVar y) | (x, y) <- zip ys ys']
+    collectArgs  = collectArguments . length . ty_binds . toRTypeRep
+    err x        = "Constant: makeTermEnvs: no terminating expression for " ++ showPpr x
+
+addObligation :: Oblig -> SpecType -> RReft -> SpecType
+addObligation o t r  = mkArrow αs πs ls xts $ RRTy [] r o t2
+  where
+    (αs, πs, ls, t1) = bkUniv t
+    (xs, ts, rs, t2) = bkArrow t1
+    xts              = zip3 xs ts rs
+
+--------------------------------------------------------------------------------
+consCB :: Bool -> Bool -> CGEnv -> CoreBind -> CG CGEnv
+--------------------------------------------------------------------------------
+-- do termination checking
+consCB True _ γ (Rec xes)
+  = do texprs <- termExprs <$> get
+       modify $ \i -> i { recCount = recCount i + length xes }
+       let xxes = catMaybes $ (`lookup` texprs) <$> xs
+       if null xxes
+         then consCBSizedTys γ xes
+         else check xxes <$> consCBWithExprs γ xes
+    where
+      xs = fst $ unzip xes
+      check ys r | length ys == length xs = r
+                 | otherwise              = panic (Just loc) $ msg
+      msg        = "Termination expressions must be provided for all mutually recursive binders"
+      loc        = getSrcSpan (head xs)
+      lookup k m = (k,) <$> M.lookup k m
+
+-- don't do termination checking, but some strata checks?
+consCB _ False γ (Rec xes)
+  = do xets'   <- forM xes $ \(x, e) -> (x, e,) <$> varTemplate γ (x, Just e)
+       sflag   <- scheck <$> get
+       let cmakeDivType = if sflag then makeDivType else id
+       let xets = mapThd3 (fmap cmakeDivType) <$> xets'
+       modify $ \i -> i { recCount = recCount i + length xes }
+       let xts = [(x, to) | (x, _, to) <- xets]
+       γ'     <- foldM extender (γ `setRecs` (fst <$> xts)) xts
+       mapM_ (consBind True γ') xets
+       return γ'
+
+-- don't do termination checking, and don't do any strata checks either?
+consCB _ _ γ (Rec xes)
+  = do xets   <- forM xes $ \(x, e) -> liftM (x, e,) (varTemplate γ (x, Just e))
+       modify $ \i -> i { recCount = recCount i + length xes }
+       let xts = [(x, to) | (x, _, to) <- xets]
+       γ'     <- foldM extender (γ `setRecs` (fst <$> xts)) xts
+       mapM_ (consBind True γ') xets
+       return γ'
+
+-- | NV: Dictionaries are not checked, because
+-- | class methods' preconditions are not satisfied
+consCB _ _ γ (NonRec x _) | isDictionary x
+  = do t  <- trueTy (varType x)
+       extender γ (x, Assumed t)
+    where
+       isDictionary = isJust . dlookup (denv γ)
+
+
+consCB _ _ γ (NonRec x def)
+  | Just (w, τ) <- grepDictionary def
+  , Just d      <- dlookup (denv γ) w
+  = do t        <- trueTy τ
+       addW      $ WfC γ t
+       let xts   = dmap (mapRISig (f t)) d
+       let  γ'   = γ { denv = dinsert (denv γ) x xts }
+       t        <- trueTy (varType x)
+       extender γ' (x, Assumed t)
+   where
+    f t' (RAllT α te) = subsTyVar_meet' (ty_var_value α, t') te
+    f _ _ = impossible Nothing "consCB on Dictionary: this should not happen"
+
+consCB _ _ γ (NonRec x e)
+  = do to  <- varTemplate γ (x, Nothing)
+       to' <- consBind False γ (x, e, to) >>= (addPostTemplate γ)
+       extender γ (x, to')
+
+grepDictionary :: CoreExpr -> Maybe (Var, Type)
+grepDictionary (App (Var w) (Type t)) = Just (w, t)
+grepDictionary (App e (Var _))        = grepDictionary e
+grepDictionary _                      = Nothing
+
+--------------------------------------------------------------------------------
+consBind :: Bool
+         -> CGEnv
+         -> (Var, CoreExpr, Template SpecType)
+         -> CG (Template SpecType)
+--------------------------------------------------------------------------------
+consBind _ _ (x, _, t)
+  | RecSelId {} <- idDetails x -- don't check record selectors
+  = return t
+
+consBind isRec γ (x, e, Asserted spect)
+  = do let γ'         = γ `setBind` x
+           (_,πs,_,_) = bkUniv spect
+       γπ    <- foldM addPToEnv γ' πs
+       cconsE γπ e spect
+       when (F.symbol x `elemHEnv` holes γ) $
+         -- have to add the wf constraint here for HOLEs so we have the proper env
+         addW $ WfC γπ $ fmap killSubst spect
+       addIdA x (defAnn isRec spect)
+       return $ Asserted spect
+
+consBind isRec γ (x, e, Internal spect)
+  = do let γ'         = γ `setBind` x
+           (_,πs,_,_) = bkUniv spect
+       γπ    <- foldM addPToEnv γ' πs
+       let γπ' = γπ {cerr = Just $ ErrHMeas (getLocation γπ) (pprint x) (text explanation)}
+       cconsE γπ' e spect
+       when (F.symbol x `elemHEnv` holes γ) $
+         -- have to add the wf constraint here for HOLEs so we have the proper env
+         addW $ WfC γπ $ fmap killSubst spect
+       addIdA x (defAnn isRec spect)
+       return $ Internal spect -- Nothing
+  where
+    explanation = "Cannot give singleton type to the function definition."
+
+consBind isRec γ (x, e, Assumed spect)
+  = do let γ' = γ `setBind` x
+       γπ    <- foldM addPToEnv γ' πs
+       cconsE γπ e =<< true spect
+       addIdA x (defAnn isRec spect)
+       return $ Asserted spect
+    where πs   = ty_preds $ toRTypeRep spect
+
+consBind isRec γ (x, e, Unknown)
+  = do t'    <- consE (γ `setBind` x) e
+       t     <- topSpecType x t'
+       addIdA x (defAnn isRec t)
+       when (isExportedId x) (addKuts x t)
+       return $ Asserted t
+
+killSubst :: RReft -> RReft
+killSubst = fmap killSubstReft
+
+killSubstReft :: F.Reft -> F.Reft
+killSubstReft = trans kv () ()
+  where
+    kv    = defaultVisitor { txExpr = ks }
+    ks _ (F.PKVar k _) = F.PKVar k mempty
+    ks _ p             = p
+
+defAnn :: Bool -> t -> Annot t
+defAnn True  = AnnRDf
+defAnn False = AnnDef
+
+addPToEnv :: CGEnv
+          -> PVar RSort -> CG CGEnv
+addPToEnv γ π
+  = do γπ <- γ += ("addSpec1", pname π, pvarRType π)
+       foldM (+=) γπ [("addSpec2", x, ofRSort t) | (t, x, _) <- pargs π]
+
+extender :: F.Symbolic a => CGEnv -> (a, Template SpecType) -> CG CGEnv
+extender γ (x, Asserted t)
+  = case lookupREnv (F.symbol x) (assms γ) of
+      Just t' -> γ += ("extender", F.symbol x, t')
+      _       -> γ += ("extender", F.symbol x, t)
+extender γ (x, Assumed t)
+  = γ += ("extender", F.symbol x, t)
+extender γ _
+  = return γ
+
+data Template a = Asserted a
+                | Assumed a
+                | Internal a
+                | Unknown
+                deriving (Functor, F.Foldable, T.Traversable)
+
+deriving instance (Show a) => (Show (Template a))
+
+unTemplate :: Template t -> t
+unTemplate (Asserted t) = t
+unTemplate (Assumed t)  = t
+unTemplate (Internal t) = t
+unTemplate _ = panic Nothing "Constraint.Generate.unTemplate called on `Unknown`"
+
+addPostTemplate :: CGEnv
+                -> Template SpecType
+                -> CG (Template SpecType)
+addPostTemplate γ (Asserted t) = Asserted <$> addPost γ t
+addPostTemplate γ (Assumed  t) = Assumed  <$> addPost γ t
+addPostTemplate γ (Internal t) = Internal  <$> addPost γ t
+addPostTemplate _ Unknown      = return Unknown
+
+safeFromAsserted :: [Char] -> Template t -> t
+safeFromAsserted _ (Asserted t) = t
+safeFromAsserted msg _ = panic Nothing $ "safeFromAsserted:" ++ msg
+
+-- | @varTemplate@ is only called with a `Just e` argument when the `e`
+-- corresponds to the body of a @Rec@ binder.
+varTemplate :: CGEnv -> (Var, Maybe CoreExpr) -> CG (Template SpecType)
+varTemplate γ (x, eo) = varTemplate' γ (x, eo) >>= mapM (topSpecType x)
+
+-- | @lazVarTemplate@ is like `varTemplate` but for binders that are *not*
+--   termination checked and hence, the top-level refinement / KVar is
+--   stripped out. e.g. see tests/neg/T743.hs
+-- varTemplate :: CGEnv -> (Var, Maybe CoreExpr) -> CG (Template SpecType)
+-- lazyVarTemplate γ (x, eo) = dbg <$> (topRTypeBase <$>) <$> varTemplate' γ (x, eo)
+--   where
+--    dbg   = traceShow ("LAZYVAR-TEMPLATE: " ++ show x)
+
+varTemplate' :: CGEnv -> (Var, Maybe CoreExpr) -> CG (Template SpecType)
+varTemplate' γ (x, eo)
+  = case (eo, lookupREnv (F.symbol x) (grtys γ), lookupREnv (F.symbol x) (assms γ), lookupREnv (F.symbol x) (intys γ)) of
+      (_, Just t, _, _) -> Asserted <$> refreshArgsTop (x, t)
+      (_, _, _, Just t) -> Internal <$> refreshArgsTop (x, t)
+      (_, _, Just t, _) -> Assumed  <$> refreshArgsTop (x, t)
+      (Just e, _, _, _) -> do t  <- freshTy_expr (RecBindE x) e (exprType e)
+                              addW (WfC γ t)
+                              Asserted <$> refreshArgsTop (x, t)
+      (_,      _, _, _) -> return Unknown
+
+-- | @topSpecType@ strips out the top-level refinement of "derived var"
+topSpecType :: Var -> SpecType -> CG SpecType
+topSpecType x t = do
+  info  <- ghcI <$> get
+  return $ if derivedVar info x then topRTypeBase t else t
+
+--------------------------------------------------------------------------------
+-- | Constraint Generation: Checking -------------------------------------------
+--------------------------------------------------------------------------------
+cconsE :: CGEnv -> CoreExpr -> SpecType -> CG ()
+--------------------------------------------------------------------------------
+cconsE g e t = do
+  -- Note: tracing goes here
+  -- traceM $ printf "cconsE:\n  expr = %s\n  exprType = %s\n  lqType = %s\n" (showPpr e) (showPpr (exprType e)) (showpp t)
+  cconsE' g e t
+
+cconsE' :: CGEnv -> CoreExpr -> SpecType -> CG ()
+cconsE' γ e@(Let b@(NonRec x _) ee) t
+  = do sp <- specLVars <$> get
+       if (x `S.member` sp)
+         then cconsLazyLet γ e t
+         else do γ'  <- consCBLet γ b
+                 cconsE γ' ee t
+
+cconsE' γ e (RAllP p t)
+  = cconsE γ' e t''
+  where
+    t'         = replacePredsWithRefs su <$> t
+    su         = (uPVar p, pVartoRConc p)
+    (css, t'') = splitConstraints t'
+    γ'         = L.foldl' addConstraints γ css
+
+cconsE' γ (Let b e) t
+  = do γ'  <- consCBLet γ b
+       cconsE γ' e t
+
+cconsE' γ (Case e x _ cases) t
+  = do γ'  <- consCBLet γ (NonRec x e)
+       forM_ cases $ cconsCase (addArgument γ' x) x t nonDefAlts
+    where
+       nonDefAlts = [a | (a, _, _) <- cases, a /= DEFAULT]
+       _msg = "cconsE' #nonDefAlts = " ++ show (length (nonDefAlts))
+
+cconsE' γ (Lam α e) (RAllT α' t) | isTyVar α
+  = do γ' <- updateEnvironment γ α
+       cconsE γ' e $ subsTyVar_meet' (ty_var_value α', rVar α) t
+
+cconsE' γ (Lam x e) (RFun y ty t r)
+  | not (isTyVar x)
+  = do γ' <- γ += ("cconsE", x', ty)
+       cconsE (addArgument γ' x) e t'
+       addFunctionConstraint (addArgument γ x) x e (RFun x' ty t' r')
+       addIdA x (AnnDef ty)
+  where
+    x'  = F.symbol x
+    t'  = t `F.subst1` (y, F.EVar x')
+    r'  = r `F.subst1` (y, F.EVar x')
+
+cconsE' γ (Tick tt e) t
+  = cconsE (γ `setLocation` (Sp.Tick tt)) e t
+
+cconsE' γ (Cast e co) t
+  -- See Note [Type classes with a single method]
+  | Just f <- isClassConCo co
+  = cconsE γ (f e) t
+
+cconsE' γ e@(Cast e' c) t
+  = do t' <- castTy γ (exprType e) e' c
+       addC (SubC γ t' t) ("cconsE Cast: " ++ showPpr e)
+
+cconsE' γ e t
+  = do te  <- consE γ e
+       te' <- instantiatePreds γ e te >>= addPost γ
+       addC (SubC γ te' t) ("cconsE: " ++ showPpr e)
+
+lambdaSignleton :: CGEnv -> F.TCEmb TyCon -> Var -> CoreExpr -> UReft F.Reft
+lambdaSignleton γ tce x e
+  | higherOrderFlag γ, Just e' <- lamExpr γ e
+  = uTop $ F.exprReft $ F.ELam (F.symbol x, sx) e'
+  where
+    sx = typeSort tce $ varType x
+lambdaSignleton _ _ _ _
+  = mempty
+
+
+addFunctionConstraint :: CGEnv -> Var -> CoreExpr -> SpecType -> CG ()
+addFunctionConstraint γ x e (RFun y ty t r)
+  = do ty'      <- true ty
+       t'       <- true t
+       let truet = RFun y ty' t'
+       case (lamExpr γ e, higherOrderFlag γ) of
+          (Just e', True) -> do tce    <- tyConEmbed <$> get
+                                let sx  = typeSort tce $ varType x
+                                let ref = uTop $ F.exprReft $ F.ELam (F.symbol x, sx) e'
+                                addC (SubC γ (truet ref) $ truet r)    "function constraint singleton"
+          _ -> addC (SubC γ (truet mempty) $ truet r) "function constraint true"
+addFunctionConstraint γ _ _ _
+  = impossible (Just $ getLocation γ) "addFunctionConstraint: called on non function argument"
+
+splitConstraints :: TyConable c
+                 => RType c tv r -> ([[(F.Symbol, RType c tv r)]], RType c tv r)
+splitConstraints (RRTy cs _ OCons t)
+  = let (css, t') = splitConstraints t in (cs:css, t')
+splitConstraints (RFun x tx@(RApp c _ _ _) t r) | isClass c
+  = let (css, t') = splitConstraints t in (css, RFun x tx t' r)
+splitConstraints t
+  = ([], t)
+
+-------------------------------------------------------------------
+-- | @instantiatePreds@ peels away the universally quantified @PVars@
+--   of a @RType@, generates fresh @Ref@ for them and substitutes them
+--   in the body.
+-------------------------------------------------------------------
+instantiatePreds :: CGEnv
+                 -> CoreExpr
+                 -> SpecType
+                 -> CG SpecType
+instantiatePreds γ e (RAllP π t)
+  = do r     <- freshPredRef γ e π
+       instantiatePreds γ e $ replacePreds "consE" t [(π, r)]
+
+instantiatePreds _ _ t0
+  = return t0
+
+-------------------------------------------------------------------
+-- | @instantiateStrata@ generates fresh @Strata@ vars and substitutes
+--   them inside the body of the type.
+-------------------------------------------------------------------
+
+instantiateStrata :: (F.Subable b, Freshable f Integer) => [F.Symbol] -> b -> f b
+instantiateStrata ls t = substStrata t ls <$> mapM (\_ -> fresh) ls
+
+substStrata :: F.Subable a => a -> [F.Symbol] -> [F.Symbol] -> a
+substStrata t ls ls'   = F.substa f t
+  where
+    f x                = fromMaybe x $ L.lookup x su
+    su                 = zip ls ls'
+
+-------------------------------------------------------------------
+cconsLazyLet :: CGEnv
+             -> CoreExpr
+             -> SpecType
+             -> CG ()
+cconsLazyLet γ (Let (NonRec x ex) e) t
+  = do tx <- trueTy (varType x)
+       γ' <- (γ, "Let NonRec") +++= (x', ex, tx)
+       cconsE γ' e t
+    where
+       x' = F.symbol x
+
+cconsLazyLet _ _ _
+  = panic Nothing "Constraint.Generate.cconsLazyLet called on invalid inputs"
+
+--------------------------------------------------------------------------------
+-- | Type Synthesis ------------------------------------------------------------
+--------------------------------------------------------------------------------
+consE :: CGEnv -> CoreExpr -> CG SpecType
+--------------------------------------------------------------------------------
+consE γ e
+  | patternFlag γ
+  , Just p <- Rs.lift e
+  = consPattern γ p
+
+-- NV (below) is a hack to type polymorphic axiomatized functions
+-- no need to check this code with flag, the axioms environment with
+-- be empty if there is no axiomatization
+
+consE γ e'@(App e@(Var x) (Type τ)) | M.member x (aenv γ)
+  = do RAllT α te <- checkAll ("Non-all TyApp with expr", e) γ <$> consE γ e
+       t          <- if isGeneric (ty_var_value α) te then freshTy_type TypeInstE e τ else trueTy τ
+       addW        $ WfC γ t
+       t'         <- refreshVV t
+       tt <- instantiatePreds γ e' $ subsTyVar_meet' (ty_var_value α, t') te
+       return $ strengthenMeet tt (singletonReft (M.lookup x $ aenv γ) x)
+
+-- NV END HACK
+
+consE γ (Var x)
+  = do t <- varRefType γ x
+       addLocA (Just x) (getLocation γ) (varAnn γ x t)
+       return t
+
+consE _ (Lit c)
+  = refreshVV $ uRType $ literalFRefType c
+
+consE γ e'@(App e a@(Type τ))
+  = do RAllT α te <- checkAll ("Non-all TyApp with expr", e) γ <$> consE γ e
+       t          <- if isGeneric (ty_var_value α) te then freshTy_type TypeInstE e τ else trueTy τ
+       addW        $ WfC γ t
+       t'         <- refreshVV t
+       tt         <- instantiatePreds γ e' (subsTyVar_meet' (ty_var_value α, t') te)
+       -- NV TODO: embed this step with subsTyVar_meet'
+       case rTVarToBind α of
+         Just (x, _) -> return $ maybe (checkUnbound γ e' x tt a) (F.subst1 tt . (x,)) (argType τ)
+         Nothing     -> return tt
+
+-- RJ: The snippet below is *too long*. Please pull stuff from the where-clause
+-- out to the top-level.
+consE γ e'@(App e a) | isDictionary a
+  = if isJust tt
+      then return $ fromRISig $ fromJust tt
+      else do ([], πs, ls, te) <- bkUniv <$> consE γ e
+              te0              <- instantiatePreds γ e' $ foldr RAllP te πs
+              te'              <- instantiateStrata ls te0
+              (γ', te''')      <- dropExists γ te'
+              te''             <- dropConstraints γ te'''
+              updateLocA {- πs -}  (exprLoc e) te''
+              let RFun x tx t _ = checkFun ("Non-fun App with caller ", e') γ te''
+              pushConsBind      $ cconsE γ' a tx
+              addPost γ'        $ maybe (checkUnbound γ' e' x t a) (F.subst1 t . (x,)) (argExpr γ a)
+
+  where
+    tt                           = dhasinfo dinfo $ grepfunname e
+    grepfunname (App x (Type _)) = grepfunname x
+    grepfunname (Var x)          = x
+    grepfunname e                = panic Nothing $ "grepfunname on \t" ++ showPpr e
+    isDictionary _               = isJust (mdict a)
+    mdict w                      = case w of
+                                     Var x          -> case dlookup (denv γ) x of {Just _ -> Just x; Nothing -> Nothing}
+                                     Tick _ e       -> mdict e
+                                     App a (Type _) -> mdict a
+                                     _              -> Nothing
+    dinfo                        = dlookup (denv γ) (fromJust (mdict a))
+
+
+consE γ e'@(App e a)
+  = do ([], πs, ls, te) <- bkUniv <$> consE γ e
+       te0              <- instantiatePreds γ e' $ foldr RAllP te πs
+       te'              <- instantiateStrata ls te0
+       (γ', te''')      <- dropExists γ te'
+       te''             <- dropConstraints γ te'''
+       updateLocA (exprLoc e) te''
+       let RFun x tx t _ = checkFun ("Non-fun App with caller ", e') γ te''
+       pushConsBind      $ cconsE γ' a tx
+       makeSingleton γ e' <$>  (addPost γ' $ maybe (checkUnbound γ' e' x t a) (F.subst1 t . (x,)) (argExpr γ a))
+
+consE γ (Lam α e) | isTyVar α
+  = do γ' <- updateEnvironment γ α
+       liftM (RAllT (makeRTVar $ rTyVar α)) (consE γ' e)
+
+consE γ  e@(Lam x e1)
+  = do tx      <- freshTy_type LamE (Var x) τx
+       γ'      <- γ += ("consE", F.symbol x, tx)
+       t1      <- consE γ' e1
+       addIdA x $ AnnDef tx
+       addW     $ WfC γ tx
+       tce     <- tyConEmbed <$> get
+       return   $ RFun (F.symbol x) tx t1 $ lambdaSignleton (addArgument γ x) tce x e1
+    where
+      FunTy τx _ = exprType e
+
+consE γ e@(Let _ _)
+  = cconsFreshE LetE γ e
+
+consE γ e@(Case _ _ _ [_])
+  | Just p@(Rs.PatProject {}) <- Rs.lift e
+  = consPattern γ p
+
+consE γ e@(Case _ _ _ cs)
+  = cconsFreshE (caseKVKind cs) γ e
+
+consE γ (Tick tt e)
+  = do t <- consE (setLocation γ (Sp.Tick tt)) e
+       addLocA Nothing (tickSrcSpan tt) (AnnUse t)
+       return t
+
+-- See Note [Type classes with a single method]
+consE γ (Cast e co)
+  | Just f <- isClassConCo co
+  = consE γ (f e)
+
+consE γ e@(Cast e' c)
+  = castTy γ (exprType e) e' c
+
+consE _ e@(Coercion _)
+   = trueTy $ exprType e
+
+consE _ e@(Type t)
+  = panic Nothing $ "consE cannot handle type " ++ showPpr (e, t)
+
+caseKVKind ::[Alt Var] -> KVKind
+caseKVKind [(DataAlt _, _, Var _)] = ProjectE
+caseKVKind cs                      = CaseE (length cs)
+
+updateEnvironment :: CGEnv  -> TyVar -> CG CGEnv
+updateEnvironment γ a
+  | isValKind (tyVarKind a)
+  = γ += ("varType", F.symbol $ varName a, kindToRType $ tyVarKind a)
+  | otherwise
+  = return γ
+
+--------------------------------------------------------------------------------
+-- | Type Synthesis for Special @Pattern@s -------------------------------------
+--------------------------------------------------------------------------------
+consPattern :: CGEnv -> Rs.Pattern -> CG SpecType
+
+{- [NOTE] special type rule for monadic-bind application
+
+    G |- e1 ~> m tx     G, x:tx |- e2 ~> m t
+    -----------------------------------------
+          G |- (e1 >>= \x -> e2) ~> m t
+ -}
+
+consPattern γ (Rs.PatBind e1 x e2 _ _ _ _ _) = do
+  tx <- checkMonad (msg, e1) γ <$> consE γ e1
+  γ' <- γ += ("consPattern", F.symbol x, tx)
+  addIdA x (AnnDef tx)
+  mt <- consE γ' e2
+  return mt
+  where
+    msg = "This expression has a refined monadic type; run with --no-pattern-inline: "
+
+{- [NOTE] special type rule for monadic-return
+
+           G |- e ~> t
+    ------------------------
+      G |- return e ~ m t
+ -}
+consPattern γ (Rs.PatReturn e m _ _ _) = do
+  t     <- consE γ e
+  mt    <- trueTy  m
+  return $ RAppTy mt t mempty
+
+{- [NOTE] special type rule for field projection, is
+          t  = G(x)       ti = Proj(t, i)
+    -----------------------------------------
+      G |- case x of C [y1...yn] -> yi : ti
+ -}
+
+consPattern γ (Rs.PatProject xe _ τ c ys i) = do
+  let yi = ys !! i
+  t    <- (addW . WfC γ) <<= freshTy_type ProjectE (Var yi) τ
+  γ'   <- caseEnv γ xe [] (DataAlt c) ys (Just [i])
+  ti   <- {- γ' ??= yi -} varRefType γ' yi
+  addC (SubC γ' ti t) "consPattern:project"
+  return t
+
+checkMonad :: (Outputable a) => (String, a) -> CGEnv -> SpecType -> SpecType
+checkMonad x g = go . unRRTy
+ where
+   go (RApp _ ts [] _)
+     | length ts > 0 = last ts
+   go (RAppTy _ t _) = t
+   go t              = checkErr x g t
+
+unRRTy :: SpecType -> SpecType
+unRRTy (RRTy _ _ _ t) = unRRTy t
+unRRTy t              = t
+
+--------------------------------------------------------------------------------
+castTy  :: CGEnv -> Type -> CoreExpr -> Coercion -> CG SpecType
+castTy' :: CGEnv -> Type -> CoreExpr -> CG SpecType
+--------------------------------------------------------------------------------
+castTy γ t e (AxiomInstCo ca _ _)
+  = fromMaybe <$> castTy' γ t e <*> lookupNewType (coAxiomTyCon ca)
+
+castTy γ t e (SymCo (AxiomInstCo ca _ _))
+  = do mtc <- lookupNewType (coAxiomTyCon ca)
+       case mtc of
+        Just tc -> cconsE γ e tc
+        Nothing -> return ()
+       castTy' γ t e
+
+castTy γ t e _
+  = castTy' γ t e
+
+
+castTy' _ τ (Var x)
+  = do t <- trueTy τ
+       return (t `strengthen` (uTop $ F.uexprReft $ F.expr x))
+
+castTy' γ t (Tick _ e)
+  = castTy' γ t e
+
+castTy' _ _ e
+  = panic Nothing $ "castTy cannot handle expr " ++ showPpr e
+
+{-
+showCoercion :: Coercion -> String
+showCoercion (AxiomInstCo co1 co2 co3)
+  = "AxiomInstCo " ++ showPpr co1 ++ "\t\t " ++ showPpr co2 ++ "\t\t" ++ showPpr co3 ++ "\n\n" ++
+    "COAxiom Tycon = "  ++ showPpr (coAxiomTyCon co1) ++ "\nBRANCHES\n" ++ concatMap showBranch bs
+  where
+    bs = fromBranchList $ co_ax_branches co1
+    showBranch ab = "\nCoAxiom \nLHS = " ++ showPpr (coAxBranchLHS ab) ++
+                    "\nRHS = " ++ showPpr (coAxBranchRHS ab)
+showCoercion (SymCo c)
+  = "Symc :: " ++ showCoercion c
+showCoercion c
+  = "Coercion " ++ showPpr c
+-}
+
+isClassConCo :: Coercion -> Maybe (Expr Var -> Expr Var)
+-- See Note [Type classes with a single method]
+isClassConCo co
+  | Pair t1 t2 <- coercionKind co
+  , isClassPred t2
+  , (tc,ts) <- splitTyConApp t2
+  , [dc]    <- tyConDataCons tc
+  , [tm]    <- dataConOrigArgTys dc
+               -- tcMatchTy because we have to instantiate the class tyvars
+  , Just _  <- tcMatchTy (mkVarSet $ tyConTyVars tc) tm t1
+  = Just (\e -> mkCoreConApps dc $ map Type ts ++ [e])
+
+  | otherwise
+  = Nothing
+
+----------------------------------------------------------------------
+-- Note [Type classes with a single method]
+----------------------------------------------------------------------
+-- GHC 7.10 encodes type classes with a single method as newtypes and
+-- `cast`s between the method and class type instead of applying the
+-- class constructor. Just rewrite the core to what we're used to
+-- seeing..
+--
+-- specifically, we want to rewrite
+--
+--   e `cast` ((a -> b) ~ C)
+--
+-- to
+--
+--   D:C e
+--
+-- but only when
+--
+--   D:C :: (a -> b) -> C
+
+--------------------------------------------------------------------------------
+-- | @consFreshE@ is used to *synthesize* types with a **fresh template**.
+--   e.g. at joins, recursive binders, polymorphic instantiations etc. It is
+--   the "portal" that connects `consE` (synthesis) and `cconsE` (checking)
+--------------------------------------------------------------------------------
+cconsFreshE :: KVKind -> CGEnv -> CoreExpr -> CG SpecType
+cconsFreshE kvkind γ e = do
+  t   <- freshTy_type kvkind e $ exprType e
+  addW $ WfC γ t
+  cconsE γ e t
+  return t
+--------------------------------------------------------------------------------
+
+checkUnbound :: (Show a, Show a2, F.Subable a)
+             => CGEnv -> CoreExpr -> F.Symbol -> a -> a2 -> a
+checkUnbound γ e x t a
+  | x `notElem` (F.syms t) = t
+  | otherwise              = panic (Just $ getLocation γ) msg
+  where
+    msg = unlines [ "checkUnbound: " ++ show x ++ " is elem of syms of " ++ show t
+                  , "In", showPpr e, "Arg = " , show a ]
+
+
+dropExists :: CGEnv -> SpecType -> CG (CGEnv, SpecType)
+dropExists γ (REx x tx t) =         (, t) <$> γ += ("dropExists", x, tx)
+dropExists γ t            = return (γ, t)
+
+dropConstraints :: CGEnv -> SpecType -> CG SpecType
+dropConstraints γ (RFun x tx@(RApp c _ _ _) t r) | isClass c
+  = (flip (RFun x tx)) r <$> dropConstraints γ t
+dropConstraints γ (RRTy cts _ OCons t)
+  = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) γ xts
+       addC (SubC  γ' t1 t2)  "dropConstraints"
+       dropConstraints γ t
+  where
+    (xts, t1, t2) = envToSub cts
+
+dropConstraints _ t = return t
+
+-------------------------------------------------------------------------------------
+cconsCase :: CGEnv -> Var -> SpecType -> [AltCon] -> (AltCon, [Var], CoreExpr) -> CG ()
+-------------------------------------------------------------------------------------
+cconsCase γ x t acs (ac, ys, ce)
+  = do cγ <- caseEnv γ x acs ac ys mempty
+       cconsE cγ ce t
+
+-------------------------------------------------------------------------------------
+caseEnv   :: CGEnv -> Var -> [AltCon] -> AltCon -> [Var] -> Maybe [Int] -> CG CGEnv
+-------------------------------------------------------------------------------------
+caseEnv γ x _   (DataAlt c) ys pIs
+  = do let (x' : ys')    = F.symbol <$> (x:ys)
+       xt0              <- checkTyCon ("checkTycon cconsCase", x) γ <$> γ ??= x
+       let xt            = shiftVV xt0 x'
+       tdc              <- γ ??= ({- F.symbol -} dataConWorkId c) >>= refreshVV
+       let (rtd,yts', _) = unfoldR tdc xt ys
+       yts              <- projectTypes pIs yts'
+       let r1            = dataConReft   c   ys''
+       let r2            = dataConMsReft rtd ys''
+       let xt            = (xt0 `F.meet` rtd) `strengthen` (uTop (r1 `F.meet` r2))
+       let cbs           = safeZip "cconsCase" (x':ys') (xt0 : yts)
+       cγ'              <- addBinders γ   x' cbs
+       cγ               <- addBinders cγ' x' [(x', xt)]
+       return $ addArguments cγ ys
+  where
+    ys'' = F.symbol <$> (filter (not . isClassPred . varType) ys)
+
+caseEnv γ x acs a _ _
+  = do let x'  = F.symbol x
+       xt'    <- (`strengthen` uTop (altReft γ acs a)) <$> (γ ??= x)
+       cγ     <- addBinders γ x' [(x', xt')]
+       return cγ
+
+--------------------------------------------------------------------------------
+-- | `projectTypes` masks (i.e. true's out) all types EXCEPT those
+--   at given indices; it is used to simplify the environment used
+--   when projecting out fields of single-ctor datatypes.
+--------------------------------------------------------------------------------
+projectTypes :: Maybe [Int] -> [SpecType] -> CG [SpecType]
+projectTypes Nothing   ts = return ts
+projectTypes (Just is) ts = mapM (projT is) (zip [0..] ts)
+  where
+    projT is (j, t)
+      | j `elem` is       = return t
+      | otherwise         = true t
+
+
+altReft :: CGEnv -> [AltCon] -> AltCon -> F.Reft
+altReft _ _ (LitAlt l)   = literalFReft l
+altReft γ acs DEFAULT    = mconcat [notLiteralReft l | LitAlt l <- acs]
+  where notLiteralReft   = maybe mempty F.notExprReft . snd . literalConst (emb γ)
+altReft _ _ _            = panic Nothing "Constraint : altReft"
+
+unfoldR :: SpecType
+        -> SpecType
+        -> [Var]
+        -> (SpecType, [SpecType], SpecType)
+unfoldR td (RApp _ ts rs _) ys = (t3, tvys ++ yts, ignoreOblig rt)
+  where
+        tbody              = instantiatePvs (instantiateTys td ts) $ reverse rs
+        (ys0, yts', _, rt) = safeBkArrow $ instantiateTys tbody tvs'
+        yts''              = zipWith F.subst sus (yts'++[rt])
+        (t3,yts)           = (last yts'', init yts'')
+        sus                = F.mkSubst <$> (L.inits [(x, F.EVar y) | (x, y) <- zip ys0 ys'])
+        (αs, ys')          = mapSnd (F.symbol <$>) $ L.partition isTyVar ys
+        tvs'               = rVar <$> αs
+        tvys               = ofType . varType <$> αs
+
+unfoldR _  _                _  = panic Nothing "Constraint.hs : unfoldR"
+
+instantiateTys :: (Foldable t)
+               => SpecType -> t (SpecType) -> SpecType
+instantiateTys = L.foldl' go
+  where go (RAllT α tbody) t = subsTyVar_meet' (ty_var_value α, t) tbody
+        go _ _               = panic Nothing "Constraint.instanctiateTy"
+
+instantiatePvs :: Foldable t => SpecType -> t SpecProp -> SpecType
+instantiatePvs = L.foldl' go
+  where go (RAllP p tbody) r = replacePreds "instantiatePv" tbody [(p, r)]
+        go _ _               = panic Nothing "Constraint.instanctiatePv"
+
+checkTyCon :: (Outputable a) => (String, a) -> CGEnv -> SpecType -> SpecType
+checkTyCon _ _ t@(RApp _ _ _ _) = t
+checkTyCon x g t              = checkErr x g t
+
+checkFun :: (Outputable a) => (String, a) -> CGEnv -> SpecType -> SpecType
+checkFun _ _ t@(RFun _ _ _ _) = t
+checkFun x g t                = checkErr x g t
+
+checkAll :: (Outputable a) => (String, a) -> CGEnv -> SpecType -> SpecType
+checkAll _ _ t@(RAllT _ _)    = t
+checkAll x g t                = checkErr x g t
+
+checkErr :: (Outputable a) => (String, a) -> CGEnv -> SpecType -> SpecType
+checkErr (msg, e) γ t         = panic (Just sp) $ msg ++ showPpr e ++ ", type: " ++ showpp t
+  where
+    sp                        = getLocation γ
+
+varAnn :: CGEnv -> Var -> t -> Annot t
+varAnn γ x t
+  | x `S.member` recs γ      = AnnLoc (getSrcSpan x)
+  | otherwise                = AnnUse t
+
+-----------------------------------------------------------------------
+-- | Helpers: Creating Fresh Refinement -------------------------------
+-----------------------------------------------------------------------
+freshPredRef :: CGEnv -> CoreExpr -> PVar RSort -> CG SpecProp
+freshPredRef γ e (PV _ (PVProp τ) _ as)
+  = do t    <- freshTy_type PredInstE e (toType τ)
+       args <- mapM (\_ -> fresh) as
+       let targs = [(x, s) | (x, (s, y, z)) <- zip args as, (F.EVar y) == z ]
+       γ' <- foldM (+=) γ [("freshPredRef", x, ofRSort τ) | (x, τ) <- targs]
+       addW $ WfC γ' t
+       return $ RProp targs t
+
+freshPredRef _ _ (PV _ PVHProp _ _)
+  = todo Nothing "EFFECTS:freshPredRef"
+
+--------------------------------------------------------------------------------
+-- | Helpers: Creating Refinement Types For Various Things ---------------------
+--------------------------------------------------------------------------------
+argType :: Type -> Maybe F.Expr
+argType (LitTy (NumTyLit i))
+  = mkI i
+argType (LitTy (StrTyLit s))
+  = mkS $ fastStringToByteString s
+argType (TyVarTy x)
+  = Just $ F.EVar $ F.symbol $ varName x
+argType t
+  | F.symbol (showPpr t) == anyTypeSymbol
+  = Just $ F.EVar anyTypeSymbol
+argType _
+  = Nothing
+
+
+argExpr :: CGEnv -> CoreExpr -> Maybe F.Expr
+argExpr γ (Var v)     | M.member v $ aenv γ, higherOrderFlag γ
+                      = F.EVar <$> (M.lookup v $ aenv γ)
+argExpr _ (Var vy)    = Just $ F.eVar vy
+argExpr γ (Lit c)     = snd  $ literalConst (emb γ) c
+argExpr γ (Tick _ e)  = argExpr γ e
+argExpr _ _           = Nothing
+
+
+-- NIKI TODO: merge arg/lam/fun-Expr
+lamExpr :: CGEnv -> CoreExpr -> Maybe F.Expr
+lamExpr γ (Var v)     | M.member v $ aenv γ
+                      = F.EVar <$> (M.lookup v $ aenv γ)
+lamExpr γ (Var v)     | S.member v (fargs γ)
+                      =  Just $ F.eVar v
+lamExpr γ (Lit c)     = snd  $ literalConst (emb γ) c
+lamExpr γ (Tick _ e)  = lamExpr γ e
+lamExpr γ (App e (Type _)) = lamExpr γ e
+lamExpr γ (App e1 e2) = case (lamExpr γ e1, lamExpr γ e2) of
+                              (Just p1, Just p2) | not (isClassPred $ exprType e2)
+                                                 -> Just $ F.EApp p1 p2
+                              (Just p1, Just _ ) -> Just p1
+                              _  -> Nothing
+lamExpr γ (Let (NonRec x ex) e) = case (lamExpr γ ex, lamExpr (addArgument γ x) e) of
+                                       (Just px, Just p) -> Just (p `F.subst1` (F.symbol x, px))
+                                       _  -> Nothing
+lamExpr γ (Lam x e)   = case lamExpr (addArgument γ x) e of
+                            Just p -> Just $ F.ELam (F.symbol x, typeSort (emb γ) $ varType x) p
+                            _ -> Nothing
+lamExpr _ _           = Nothing
+
+
+--------------------------------------------------------------------------------
+(??=) :: (?callStack :: CallStack) => CGEnv -> Var -> CG SpecType
+--------------------------------------------------------------------------------
+γ ??= x = case M.lookup x' (lcb γ) of
+            Just e  -> consE (γ -= x') e
+            Nothing -> refreshTy tx
+          where
+            x' = F.symbol x
+            tx = fromMaybe tt (γ ?= x')
+            tt = ofType $ varType x
+
+
+--------------------------------------------------------------------------------
+varRefType :: (?callStack :: CallStack) => CGEnv -> Var -> CG SpecType
+--------------------------------------------------------------------------------
+varRefType γ x = do
+  xt <- varRefType' γ x <$> (γ ??= x)
+  return xt -- F.tracepp (printf "varRefType x = [%s]" (showpp x))
+
+varRefType' :: CGEnv -> Var -> SpecType -> SpecType
+varRefType' γ x t'
+  | Just tys <- trec γ, Just tr  <- M.lookup x' tys
+  = strengthen tr xr
+  | otherwise
+  = strengthen t' xr
+  where
+    xr = singletonReft (M.lookup x $ aenv γ) x
+    x' = F.symbol x
+    strengthen
+      | higherOrderFlag γ
+      = strengthenMeet
+      | otherwise
+      = strengthenTop
+
+-- | create singleton types for function application
+makeSingleton :: CGEnv -> CoreExpr -> SpecType -> SpecType
+makeSingleton γ e t
+  | higherOrderFlag γ, App f x <- simplify e
+  = case (funExpr γ f, argExpr γ x) of
+      (Just f', Just x')
+                 | not (isClassPred $ exprType x)
+                 -> strengthenMeet t (uTop $ F.exprReft (F.EApp f' x'))
+      (Just f', Just _)
+                 -> strengthenMeet t (uTop $ F.exprReft f' )
+      _ -> t
+  | otherwise
+  = t
+
+funExpr :: CGEnv -> CoreExpr -> Maybe F.Expr
+funExpr γ (Var v) | M.member v $ aenv γ
+  = F.EVar <$> (M.lookup v $ aenv γ)
+funExpr γ (App e1 e2)
+  = case (funExpr γ e1, argExpr γ e2) of
+      (Just e1', Just e2') | not (isClassPred $ exprType e2)
+                           -> Just (F.EApp e1' e2')
+      (Just e1', Just _)
+                           -> Just e1'
+      _                    -> Nothing
+funExpr γ (Var v) | S.member v (fargs γ)
+  = Just $ F.EVar (F.symbol v)
+funExpr _ _
+  = Nothing
+
+simplify :: CoreExpr -> CoreExpr
+simplify (Tick _ e)       = simplify e
+simplify (App e (Type _)) = simplify e
+simplify (App e1 e2)      = App (simplify e1) (simplify e2)
+simplify e                = e
+
+
+singletonReft :: (F.Symbolic a, F.Symbolic a1) => Maybe a -> a1 -> UReft F.Reft
+singletonReft (Just x) _ = uTop $ F.symbolReft x
+singletonReft Nothing  v = uTop $ F.symbolReft $ F.symbol v
+
+-- | RJ: `nomeet` replaces `strengthenS` for `strengthen` in the definition
+--   of `varRefType`. Why does `tests/neg/strata.hs` fail EVEN if I just replace
+--   the `otherwise` case? The fq file holds no answers, both are sat.
+strengthenTop :: (PPrint r, F.Reftable r) => RType c tv r -> r -> RType c tv r
+strengthenTop (RApp c ts rs r) r'  = RApp c ts rs $ topMeet r r'
+strengthenTop (RVar a r) r'        = RVar a       $ topMeet r r'
+strengthenTop (RFun b t1 t2 r) r'  = RFun b t1 t2 $ topMeet r r'
+strengthenTop (RAppTy t1 t2 r) r'  = RAppTy t1 t2 $ topMeet r r'
+strengthenTop t _                  = t
+
+
+strengthenMeet :: (PPrint r, F.Reftable r) => RType c tv r -> r -> RType c tv r
+strengthenMeet (RApp c ts rs r) r'  = RApp c ts rs (r `F.meet` r')
+strengthenMeet (RVar a r) r'        = RVar a       (r `F.meet` r')
+strengthenMeet (RFun b t1 t2 r) r'  = RFun b t1 t2 (r `F.meet` r')
+strengthenMeet (RAppTy t1 t2 r) r'  = RAppTy t1 t2 (r `F.meet` r')
+strengthenMeet (RAllT a t) r'       = RAllT a $ strengthenMeet t r'
+strengthenMeet t _                  = t
+
+topMeet :: (PPrint r, F.Reftable r) => r -> r -> r
+topMeet r r' = {- F.tracepp msg $ -} ({- F.top -} r `F.meet` r')
+
+--------------------------------------------------------------------------------
+-- | Cleaner Signatures For Rec-bindings ---------------------------------------
+--------------------------------------------------------------------------------
+exprLoc                         :: CoreExpr -> Maybe SrcSpan
+exprLoc (Tick tt _)             = Just $ tickSrcSpan tt
+exprLoc (App e a) | isType a    = exprLoc e
+exprLoc _                       = Nothing
+
+isType :: Expr CoreBndr -> Bool
+isType (Type _)                 = True
+isType a                        = eqType (exprType a) predType
+
+
+
+isGeneric :: RTyVar -> SpecType -> Bool
+isGeneric α t =  all (\(c, α') -> (α'/=α) || isOrd c || isEq c ) (classConstrs t)
+  where classConstrs t = [(c, ty_var_value α')
+                                  | (c, ts) <- tyClasses t
                                   , t'      <- ts
                                   , α'      <- freeTyVars t']
         isOrd          = (ordClassName ==) . className
diff --git a/src/Language/Haskell/Liquid/Constraint/Init.hs b/src/Language/Haskell/Liquid/Constraint/Init.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/Constraint/Init.hs
@@ -0,0 +1,298 @@
+{-# LANGUAGE ScopedTypeVariables       #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE TypeSynonymInstances      #-}
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE MultiParamTypeClasses     #-}
+{-# LANGUAGE OverloadedStrings         #-}
+
+-- | This module defines the representation of Subtyping and WF Constraints,
+--   and the code for syntax-directed constraint generation.
+
+module Language.Haskell.Liquid.Constraint.Init (
+    initEnv ,
+    initCGI,
+    ) where
+
+import           Prelude                                       hiding (error, undefined)
+import           Coercion
+import           DataCon
+import           CoreSyn
+import           Type
+import           TyCon
+import           Var
+import           Id                                           -- hiding (isExportedId)
+import           IdInfo
+import           Name        hiding (varName)
+import           Control.Monad.State
+import           Data.Maybe                                    (isNothing, fromMaybe, catMaybes)
+import qualified Data.HashMap.Strict                           as M
+import qualified Data.HashSet                                  as S
+import qualified Data.List                                     as L
+import           Data.Bifunctor
+import qualified Language.Fixpoint.Types                       as F
+-- import           Language.Fixpoint.Solver.Instantiate
+
+import           Language.Haskell.Liquid.UX.Config (terminationCheck)
+                 --, allowLiquidInstationationGlobal, allowLiquidInstationationLocal,
+                 -- allowRewrite, allowArithmetic)
+import qualified Language.Haskell.Liquid.UX.CTags              as Tg
+import           Language.Haskell.Liquid.Constraint.Fresh
+import           Language.Haskell.Liquid.Constraint.Env
+import           Language.Haskell.Liquid.WiredIn               (dictionaryVar)
+import qualified Language.Haskell.Liquid.GHC.SpanStack         as Sp
+import           Language.Haskell.Liquid.GHC.Interface         (isExportedVar)
+import           Language.Haskell.Liquid.Types                 hiding (binds, Loc, loc, freeTyVars, Def)
+import           Language.Haskell.Liquid.Types.Names
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types.Visitors        hiding (freeVars)
+import           Language.Haskell.Liquid.Types.Meet
+import           Language.Haskell.Liquid.GHC.Misc             ( hasBaseTypeVar, isDataConId) -- dropModuleNames, simplesymbol)
+import           Language.Haskell.Liquid.Misc
+import           Language.Fixpoint.Misc
+import           Language.Haskell.Liquid.Types.Literals
+import           Language.Haskell.Liquid.Constraint.Types
+-- import           Language.Haskell.Liquid.Constraint.ToFixpoint (fixConfig)
+-- import           Language.Fixpoint.Smt.Interface (makeSmtContext, smtPush)
+
+-- import System.IO.Unsafe
+
+-- import Debug.Trace (trace)
+
+--------------------------------------------------------------------------------
+initEnv :: GhcInfo -> CG CGEnv
+--------------------------------------------------------------------------------
+initEnv info
+  = do let tce   = gsTcEmbeds sp
+       let fVars = impVars info
+       let dcs   = filter isConLikeId (snd <$> gsFreeSyms sp)
+       let dcs'  = filter isConLikeId fVars
+       defaults <- forM fVars $ \x -> liftM (x,) (trueTy $ varType x)
+       dcsty    <- forM dcs   makeDataConTypes
+       dcsty'   <- forM dcs'  makeDataConTypes
+       (hs,f0)  <- refreshHoles $ grty info                  -- asserted refinements     (for defined vars)
+       f0''     <- refreshArgs' =<< grtyTop info             -- default TOP reftype      (for exported vars without spec)
+       let f0'   = if notruetypes $ getConfig sp then [] else f0''
+       f1       <- refreshArgs'   defaults                   -- default TOP reftype      (for all vars)
+       f1'      <- refreshArgs' $ makedcs dcsty              -- data constructors
+       f2       <- refreshArgs' $ assm info                  -- assumed refinements      (for imported vars)
+       f3       <- refreshArgs' $ vals gsAsmSigs sp            -- assumed refinedments     (with `assume`)
+       f40      <- refreshArgs' $ vals gsCtors sp              -- constructor refinements  (for measures)
+       f5       <- refreshArgs' $ vals gsInSigs sp             -- internal refinements     (from Haskell measures)
+       (invs1, f41) <- mapSndM refreshArgs' $ makeAutoDecrDataCons dcsty  (gsAutosize sp) dcs
+       (invs2, f42) <- mapSndM refreshArgs' $ makeAutoDecrDataCons dcsty' (gsAutosize sp) dcs'
+       let f4    = mergeDataConTypes (mergeDataConTypes f40 (f41 ++ f42)) (filter (isDataConId . fst) f2)
+       sflag    <- scheck <$> get
+       let senv  = if sflag then f2 else []
+       let tx    = mapFst F.symbol . addRInv ialias . strataUnify senv . predsUnify sp
+       let bs    = (tx <$> ) <$> [f0 ++ f0', f1 ++ f1', f2, f3, f4, f5]
+       modify $ \s -> s{dataConTys = f4}
+       lt1s     <- F.toListSEnv . cgLits <$> get
+       let lt2s  = [ (F.symbol x, rTypeSort tce t) | (x, t) <- f1' ]
+       let tcb   = mapSnd (rTypeSort tce) <$> concat bs
+       let γ0    = measEnv sp (head bs) (cbs info) tcb lt1s lt2s (bs!!3) (bs!!5) hs info
+       γ  <- globalize <$> foldM (+=) γ0 [("initEnv", x, y) | (x, y) <- concat $ tail bs]
+       return γ {invs = is (invs1 ++ invs2)}
+  where
+    sp           = spec info
+    ialias       = mkRTyConIAl $ gsIaliases sp
+    vals f       = map (mapSnd val) . f
+    mapSndM f    = \(x,y) -> ((x,) <$> f y)
+    makedcs      = map strengthenDataConType
+    is autoinv   = mkRTyConInv    (gsInvariants sp ++ ((Nothing,) <$> autoinv))
+
+makeDataConTypes :: Var -> CG (Var, SpecType)
+makeDataConTypes x = (x,) <$> (trueTy $ varType x)
+
+makeAutoDecrDataCons :: [(Id, SpecType)] -> S.HashSet TyCon -> [Id] -> ([LocSpecType], [(Id, SpecType)])
+makeAutoDecrDataCons dcts specenv dcs
+  = (simplify invs, tys)
+  where
+    (invs, tys) = unzip $ concatMap go tycons
+    tycons      = L.nub $ catMaybes $ map idTyCon dcs
+
+    go tycon
+      | S.member tycon specenv =  zipWith (makeSizedDataCons dcts) (tyConDataCons tycon) [0..]
+    go _
+      = []
+    idTyCon x = dataConTyCon <$> case idDetails x of {DataConWorkId d -> Just d; DataConWrapId d -> Just d; _ -> Nothing}
+
+    simplify invs = dummyLoc . (`strengthen` invariant) .  fmap (\_ -> mempty) <$> L.nub invs
+    invariant = MkUReft (F.Reft (F.vv_, F.PAtom F.Ge (lenOf F.vv_) (F.ECon $ F.I 0)) ) mempty mempty
+
+lenOf :: F.Symbol -> F.Expr
+lenOf x = F.mkEApp lenLocSymbol [F.EVar x]
+
+makeSizedDataCons :: [(Id, SpecType)] -> DataCon -> Integer -> (RSort, (Id, SpecType))
+makeSizedDataCons dcts x' n = (toRSort $ ty_res trep, (x, fromRTypeRep trep{ty_res = tres}))
+    where
+      x      = dataConWorkId x'
+      t      = fromMaybe (impossible Nothing "makeSizedDataCons: this should never happen") $ L.lookup x dcts
+      trep   = toRTypeRep t
+      tres   = ty_res trep `strengthen` MkUReft (F.Reft (F.vv_, F.PAtom F.Eq (lenOf F.vv_) computelen)) mempty mempty
+
+      recarguments = filter (\(t,_) -> (toRSort t == toRSort tres)) (zip (ty_args trep) (ty_binds trep))
+      computelen   = foldr (F.EBin F.Plus) (F.ECon $ F.I n) (lenOf .  snd <$> recarguments)
+
+mergeDataConTypes ::  [(Var, SpecType)] -> [(Var, SpecType)] -> [(Var, SpecType)]
+mergeDataConTypes xts yts = merge (L.sortBy f xts) (L.sortBy f yts)
+  where
+    f (x,_) (y,_) = compare x y
+    merge [] ys = ys
+    merge xs [] = xs
+    merge (xt@(x, tx):xs) (yt@(y, ty):ys)
+      | x == y    = (x, mXY x tx y ty) : merge xs ys
+      | x <  y    = xt : merge xs (yt : ys)
+      | otherwise = yt : merge (xt : xs) ys
+    mXY x tx y ty = meetVarTypes (F.pprint x) (getSrcSpan x, tx) (getSrcSpan y, ty)
+
+refreshArgs' :: [(a, SpecType)] -> CG [(a, SpecType)]
+refreshArgs' = mapM (mapSndM refreshArgs)
+
+strataUnify :: [(Var, SpecType)] -> (Var, SpecType) -> (Var, SpecType)
+strataUnify senv (x, t) = (x, maybe t (mappend t) pt)
+  where
+    pt                  = fmap (\(MkUReft _ _ l) -> MkUReft mempty mempty l) <$> L.lookup x senv
+
+
+-- | TODO: All this *should* happen inside @Bare@ but appears
+--   to happen after certain are signatures are @fresh@-ed,
+--   which is why they are here.
+
+-- NV : still some sigs do not get TyConInfo
+
+predsUnify :: GhcSpec -> (Var, RRType RReft) -> (Var, RRType RReft)
+predsUnify sp = second (addTyConInfo tce tyi) -- needed to eliminate some @RPropH@
+  where
+    tce            = gsTcEmbeds sp
+    tyi            = gsTyconEnv sp
+
+--------------------------------------------------------------------------------
+measEnv :: GhcSpec
+        -> [(F.Symbol, SpecType)]
+        -> [CoreBind]
+        -> [(F.Symbol, F.Sort)]
+        -> [(F.Symbol, F.Sort)]
+        -> [(F.Symbol, F.Sort)]
+        -> [(F.Symbol, SpecType)]
+        -> [(F.Symbol, SpecType)]
+        -> [F.Symbol]
+        -> GhcInfo
+        -> CGEnv
+--------------------------------------------------------------------------------
+measEnv sp xts cbs _tcb lt1s lt2s asms itys hs info = CGE
+  { cgLoc    = Sp.empty
+  , renv     = fromListREnv (second val <$> gsMeas sp) []
+  , syenv    = F.fromListSEnv $ gsFreeSyms sp
+  , litEnv   = F.fromListSEnv lts
+  , constEnv = F.fromListSEnv lt2s
+  , fenv     = initFEnv $ filterHO (tcb' ++ lts ++ (second (rTypeSort tce . val) <$> gsMeas sp))
+  , denv     = gsDicts sp
+  , recs     = S.empty
+  , fargs    = S.empty
+  , invs     = mempty
+  , rinvs    = mempty
+  , ial      = mkRTyConIAl    $ gsIaliases   sp
+  , grtys    = fromListREnv xts  []
+  , assms    = fromListREnv asms []
+  , intys    = fromListREnv itys []
+  , emb      = tce
+  , tgEnv    = Tg.makeTagEnv cbs
+  , tgKey    = Nothing
+  , trec     = Nothing
+  , lcb      = M.empty
+  , holes    = fromListHEnv hs
+  , lcs      = mempty
+  , aenv     = axiom_map $ gsLogicMap sp
+  , cerr     = Nothing
+  , cgInfo   = info
+  , cgVar    = Nothing
+  }
+  where
+      tce         = gsTcEmbeds sp
+      filterHO xs = if higherOrderFlag sp then xs else filter (F.isFirstOrder . snd) xs
+      lts         = lt1s ++ lt2s
+      tcb'        = []
+
+assm :: GhcInfo -> [(Var, SpecType)]
+assm = assmGrty impVars
+
+grty :: GhcInfo -> [(Var, SpecType)]
+grty = assmGrty defVars
+
+assmGrty :: (GhcInfo -> [Var]) -> GhcInfo -> [(Var, SpecType)]
+assmGrty f info = [ (x, val t) | (x, t) <- sigs, x `S.member` xs ]
+  where
+    xs          = S.fromList $ f info
+    sigs        = gsTySigs     $ spec info
+
+grtyTop :: GhcInfo -> CG [(Var, SpecType)]
+grtyTop info     = forM topVs $ \v -> (v,) <$> trueTy (varType v)
+  where
+    topVs        = filter isTop $ defVars info
+    isTop v      = isExportedVar info v && not (v `S.member` sigVs)
+    sigVs        = S.fromList [v | (v,_) <- gsTySigs (spec info) ++ gsAsmSigs (spec info) ++ gsInSigs (spec info)]
+
+
+infoLits :: (GhcSpec -> [(F.Symbol, LocSpecType)]) -> (F.Sort -> Bool) -> GhcInfo -> F.SEnv F.Sort
+infoLits litF selF info = F.fromListSEnv $ cbLits ++ measLits
+  where
+    cbLits    = filter (selF . snd) $ coreBindLits tce info
+    measLits  = filter (selF . snd) $ mkSort <$> litF spc
+    spc       = spec info
+    tce       = gsTcEmbeds spc
+    mkSort    = mapSnd (F.sr_sort . rTypeSortedReft tce . val)
+
+initCGI :: Config -> GhcInfo -> CGInfo
+initCGI cfg info = CGInfo {
+    fEnv       = F.emptySEnv
+  , hsCs       = []
+  , sCs        = []
+  , hsWfs      = []
+  , fixCs      = []
+  , isBind     = []
+  , fixWfs     = []
+  , freshIndex = 0
+  , dataConTys = []
+  , binds      = F.emptyBindEnv
+  , annotMap   = AI M.empty
+  , newTyEnv   = M.fromList (mapSnd val <$> gsNewTypes spc)
+  , tyConInfo  = tyi
+  , tyConEmbed = tce
+  , kuts       = mempty
+  , kvPacks    = mempty
+  , cgLits     = infoLits gsMeas   (const True) info
+  , cgConsts   = infoLits gsLits notFn info
+  , termExprs  = M.fromList $ gsTexprs spc
+  , specDecr   = gsDecr spc
+  , specLVars  = gsLvars spc
+  , specLazy   = dictionaryVar `S.insert` gsLazy spc
+  , tcheck     = terminationCheck cfg
+  , scheck     = strata cfg
+  , pruneRefs  = pruneUnsorted cfg
+  , logErrors  = []
+  , kvProf     = emptyKVProf
+  , recCount   = 0
+  , bindSpans  = M.empty
+  , autoSize   = gsAutosize spc
+  , allowHO    = higherOrderFlag cfg
+  , ghcI       = info
+  }
+  where
+    tce        = gsTcEmbeds spc
+    spc        = spec info
+    tyi        = gsTyconEnv spc
+    notFn      = isNothing . F.functionSort
+
+coreBindLits :: F.TCEmb TyCon -> GhcInfo -> [(F.Symbol, F.Sort)]
+coreBindLits tce info
+  = sortNub      $ [ (F.symbol x, F.strSort) | (_, Just (F.ESym x)) <- lconsts ]    -- strings
+                ++ [ (dconToSym dc, dconToSort dc) | dc <- dcons ]                  -- data constructors
+  where
+    lconsts      = literalConst tce <$> literals (cbs info)
+    dcons        = filter isDCon freeVs
+    freeVs       = impVars info ++ (snd <$> gsFreeSyms (spec info))
+    dconToSort   = typeSort tce . expandTypeSynonyms . varType
+    dconToSym    = F.symbol . idDataCon
+    isDCon x     = isDataConId x && not (hasBaseTypeVar x)
diff --git a/src/Language/Haskell/Liquid/Constraint/Monad.hs b/src/Language/Haskell/Liquid/Constraint/Monad.hs
--- a/src/Language/Haskell/Liquid/Constraint/Monad.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Monad.hs
@@ -10,43 +10,26 @@
 module Language.Haskell.Liquid.Constraint.Monad  where
 
 
--- import           Text.PrettyPrint.HughesPJ hiding (first)
 import           Prelude hiding (error)
--- import qualified TyCon  as TC
 import           Var
 import           Name (getSrcSpan)
-import           SrcLoc -- (SrcSpan)
-import           Outputable hiding (showPpr, panic) -- (SrcSpan)
-
+import           SrcLoc
+import           Outputable hiding (showPpr, panic)
 
+import qualified TyCon as TC
 
 import qualified Data.HashMap.Strict as M
--- import qualified Data.HashSet        as S
 import qualified Data.Text           as T
--- import qualified Data.List           as L
 
--- import           Data.Maybe          (fromMaybe) -- catMaybes, fromJust, isJust)
 import           Control.Monad
 import           Control.Monad.State (get, modify)
--- import qualified Language.Fixpoint.Types            as F
 import           Language.Haskell.Liquid.Types hiding (loc)
--- import           Language.Haskell.Liquid.Types.Variance
-
--- import           Language.Haskell.Liquid.Types.Strata
+import           Language.Haskell.Liquid.Types.RefType
 import           Language.Haskell.Liquid.Constraint.Types
 import           Language.Haskell.Liquid.Constraint.Env
--- import           Language.Haskell.Liquid.Constraint.Fresh
--- import           Language.Haskell.Liquid.Types.PredType         hiding (freeTyVars)
--- import           Language.Haskell.Liquid.Types.RefType
 import           Language.Fixpoint.Misc hiding (errorstar)
--- import           Language.Haskell.Liquid.Misc -- (concatMapM)
 import           Language.Haskell.Liquid.GHC.Misc -- (concatMapM)
-import           Language.Haskell.Liquid.Types.RefType
 
-
-
-
-
 --------------------------------------------------------------------------------
 -- RJ: What is this `isBind` business?
 --------------------------------------------------------------------------------
@@ -65,7 +48,7 @@
 --------------------------------------------------------------------------------
 addC c@(SubC γ t1 t2) _msg
   | toType t1 /= toType t2
-  = panic Nothing $ "addC: malformed constraint:\n" ++ showpp t1 ++ "\n <: \n" ++ showpp t2
+  = panic (Just $ getLocation γ) $ "addC: malformed constraint:\n" ++ showpp t1 ++ "\n <: \n" ++ showpp t2 ++ showPpr (toType t1, toType t2)
   | otherwise
   = do modify $ \s -> s { hsCs  = c : (hsCs s) }
        bflag <- headDefault True . isBind <$> get
@@ -91,7 +74,7 @@
        addC (SubR γ' OInv r) "precondition" >> return t
 
 addPost γ (RRTy e r OTerm t)
-  = do γ' <- foldM (\γ (x, t) -> γ ++= ("addPost", x,t)) γ e
+  = do γ' <- foldM (\γ (x, t) -> γ += ("addPost", x, t)) γ e
        addC (SubR γ' OTerm r) "precondition" >> return t
 
 addPost _ (RRTy _ _ OCons t)
@@ -152,3 +135,8 @@
   = AI $ inserts l (T.pack . showPpr <$> xo, t) m
 addA _ _ _ !a
   = a
+
+
+lookupNewType :: TC.TyCon -> CG (Maybe SpecType)
+lookupNewType tc
+  = M.lookup tc . newTyEnv <$> get
diff --git a/src/Language/Haskell/Liquid/Constraint/ProofToCore.hs b/src/Language/Haskell/Liquid/Constraint/ProofToCore.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Constraint/ProofToCore.hs
+++ /dev/null
@@ -1,185 +0,0 @@
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE FlexibleContexts     #-}
-
-module Language.Haskell.Liquid.Constraint.ProofToCore where
-
-import Prelude hiding (error)
-import CoreSyn hiding (Expr, Var)
-import qualified CoreSyn as H
-import Language.Haskell.Liquid.Types.Errors
-
-import Var hiding (Var)
-
-import CoreUtils
-
-import Type hiding (Var)
-import TypeRep
-
-import Language.Haskell.Liquid.GHC.Misc
-import Language.Haskell.Liquid.WiredIn
-
-
-
-import Language.Haskell.Liquid.Prover.Types
-import Language.Haskell.Liquid.Transforms.CoreToLogic ()
-import qualified Data.List as L
-import Data.Maybe (fromMaybe)
-
-type HId       = Id
-type HVar      = Var      HId
-type HAxiom    = Axiom    HId
-type HCtor     = Ctor     HId
-type HVarCtor  = VarCtor     HId
-type HQuery    = Query    HId
-type HInstance = Instance HId
-type HProof    = Proof    HId
-type HExpr     = Expr     HId
-
-type CmbExpr = CoreExpr -> CoreExpr -> CoreExpr
-
-class ToCore a where
-  toCore :: CmbExpr -> CoreExpr -> a -> CoreExpr
-
-instance ToCore HInstance where
-  toCore c e i = makeApp (toCore c e $ inst_axiom i) (toCore c e <$> inst_args i)
-
-instance ToCore HProof where
-  toCore _ e Invalid = e
-  toCore c e p       = combineProofs c e $ (toCore c e <$> p_evidence p)
-
-instance ToCore HAxiom where
-  toCore c e a = toCore c e $ axiom_name a
-
-instance ToCore HExpr  where
-  toCore c e (EVar v)    = toCore c e v
-  toCore c' e (EApp c es) = makeApp (toCore c' e c) (toCore c' e <$> es)
-
-instance ToCore HCtor where
-  toCore c' e c =  toCore c' e $ ctor_expr c
-
-instance ToCore HVar where
-  toCore _ _ v = H.Var $ var_info v
-
-
--------------------------------------------------------------------------------
-----------------  Combining Proofs --------------------------------------------
--------------------------------------------------------------------------------
-
--- | combineProofs :: combinator -> default expressions -> list of proofs
--- |               -> combined result
-
-combineProofs :: CmbExpr -> CoreExpr -> [CoreExpr] -> CoreExpr
-combineProofs _ e []  =  e
-combineProofs c _ es = foldl (flip Let) (combine [1..] c (H.Var v) (H.Var <$> vs)) (bs ++ [dictionaryBind])
-    where
-      (v:vs, bs) = unzip [let v = (varANF i (exprType e)) in (v, NonRec v e)
-                              | (e, i) <- zip es [1..] ]
-
-combine _ _ e []             = e
-combine _ c e' [e]           = c e' e
-combine (i:uniq) c e' (e:es) = Let (NonRec v (c e' e)) (combine uniq c (H.Var v) es)
-  where
-     v = varCombine i (exprType $ c e' e)
-combine _ _ _ _              = impossible Nothing err -- TODO: Does this case have a
-   where                                              -- sane implementation?
-     err = "Language.Haskell.Liquid.Constraint.ProofToCore.combine called with"
-           ++ " empty first argument and non-empty fourth argument. This should"
-           ++ " never happen!"
-
-
--------------------------------------------------------------------------------
-----------------  make Application --------------------------------------------
--------------------------------------------------------------------------------
-
-
-
--- | To make application we need to instantiate expressions irrelevant to logic
--- | type application and dictionaries.
--- | Then, ANF the final expression
-
-makeApp :: CoreExpr -> [CoreExpr] -> CoreExpr
-makeApp f es = foldl (flip Let) (foldl App f' (reverse es')) (reverse  bs)
-  where
-   vts      = resolveVs as $ zip (dropWhile isClassPred ts) (exprType <$> es)
-   (as, ts) = bkArrow (exprType f)
-   f'       = instantiateVars vts f
-   ds       = makeDictionaries dictionaryVar f'
-   (bs, es', _) = foldl anf ([], [], [1..]) (ds ++ (instantiateVars vts <$> es))
-
-
-instance Show Type where
-  show (TyVarTy v) = show $ tvId v
-  show t           = showPpr t
-
--- | ANF
-anf :: ([CoreBind], [CoreExpr], [Int]) -> CoreExpr -> ([CoreBind], [CoreExpr], [Int])
-anf (bs, es, i:uniq) (App f e) = ((NonRec v (App f e')):(bs++bs'), H.Var v:es, uniq')
-  where v = varANFPr i (exprType $ App f e)
-        (bs', [e'], uniq') = anf ([], [], uniq) e
-
-anf (bs, es, uniq) e = (bs, e:es, uniq)
-
--- | Filling up dictionaries
-makeDictionaries dname e = go (exprType e)
-  where
-    go (ForAllTy _ t) = go t
-    go (FunTy tx t  ) | isClassPred tx = (makeDictionary dname tx):go t
-    go _              = []
-
-makeDictionary dname t = App (H.Var dname) (Type t)
-
--- | Filling up types
-instantiateVars vts e = go e (exprType e)
-  where
-    go e (ForAllTy a t) = go (App e (Type $ fromMaybe (TyVarTy a) $ L.lookup a vts)) t
-    go e _              = e
-
-resolveVs :: [Id] -> [(Type, Type)] -> [(Id, Type)]
-resolveVs as  ts = go as ts
-  where
-    go _   []                                     = []
-    go fvs ((ForAllTy v t1, t2):ts)               = go (v:fvs) ((t1, t2):ts)
-    go fvs ((t1, ForAllTy v t2):ts)               = go (v:fvs) ((t1, t2):ts)
-    go fvs ((FunTy t1 t2, FunTy t1' t2'):ts)      = go fvs ((t1, t1'):(t2, t2'):ts)
-    go fvs ((AppTy t1 t2, AppTy t1' t2'):ts)      = go fvs ((t1, t1'):(t2, t2'):ts)
-    go fvs ((TyVarTy a, TyVarTy a'):ts) | a == a' = go fvs ts
-    go fvs ((TyVarTy a, t):ts) | a `elem` fvs     = let vts = (go fvs (substTyV (a, t) <$> ts)) in (a, resolveVar a t vts) : vts
-    go fvs ((t, TyVarTy a):ts) | a `elem` fvs     = let vts = (go fvs (substTyV (a, t) <$> ts)) in (a, resolveVar a t vts) : vts
-    go fvs ((TyConApp _ cts,TyConApp _ cts'):ts)  = go fvs (zip cts cts' ++ ts)
-    go fvs ((LitTy _, LitTy _):ts)                = go fvs ts
-    go _   (tt:_)                                 = panic Nothing $ ("cannot resolve " ++ show tt ++ (" for ") ++ show ts)
-
-resolveVar _ t [] = t
-resolveVar a t ((a', t'):ats)
-  | a == a'           = resolveVar a' t' ats
-  | TyVarTy a'' <- t' = resolveVar a'' t' ats
-  | otherwise         = resolveVar a t ats
-
-
-substTyV :: (Id, Type) -> (Type, Type) -> (Type, Type)
-substTyV (a, at) (t1, t2) = (go t1, go t2)
-  where
-    go (ForAllTy a' t) | a == a'   = ForAllTy a' t
-                       | otherwise = ForAllTy a' (go t)
-    go (FunTy t1 t2)   = FunTy (go t1) (go t2)
-    go (AppTy t1 t2)   = AppTy (go t1) (go t2)
-    go (TyConApp c ts) = TyConApp c (go <$> ts)
-    go (LitTy l)       = LitTy l
-    go (TyVarTy v)     | v == a    = at
-                       | otherwise = TyVarTy v
-
-
--------------------------------------------------------------------------------
--------------------------  HELPERS --------------------------------------------
--------------------------------------------------------------------------------
-
-varCombine i = stringVar ("proof_anf_cmb"  ++ show i)
-varANF     i = stringVar ("proof_anf_bind" ++ show i)
-varANFPr   i = stringVar ("proof_anf_bind_pr" ++ show i)
-
-bkArrow = go [] []
-  where
-    go vs ts (ForAllTy v t) = go (v:vs) ts t
-    go vs ts (FunTy tx t)   = go vs (tx:ts) t
-    go vs ts _              = (reverse vs, reverse ts)
diff --git a/src/Language/Haskell/Liquid/Constraint/Qualifier.hs b/src/Language/Haskell/Liquid/Constraint/Qualifier.hs
--- a/src/Language/Haskell/Liquid/Constraint/Qualifier.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Qualifier.hs
@@ -1,52 +1,139 @@
 {-# LANGUAGE OverloadedStrings     #-}
 {-# LANGUAGE ViewPatterns          #-}
 {-# LANGUAGE PartialTypeSignatures #-}
+{-# LANGUAGE FlexibleContexts      #-}
 
-module Language.Haskell.Liquid.Constraint.Qualifier (
-  specificationQualifiers
-  ) where
 
-import TyCon
+module Language.Haskell.Liquid.Constraint.Qualifier
+  ( qualifiers
+  , useSpcQuals
+  )
+  where
 
-import Prelude hiding (error)
+import           Prelude hiding (error)
+import           Data.List                (delete, nub)
+import           Data.Maybe               (isJust, catMaybes, fromMaybe, isNothing)
+import qualified Data.HashSet        as S
+import qualified Data.HashMap.Strict as M
+import           Debug.Trace (trace)
+import           TyCon
+import           Var (Var)
+import           Language.Fixpoint.Types                  hiding (mkQual)
+import qualified Language.Fixpoint.Types.Config as FC
+import           Language.Fixpoint.SortCheck
+import           Language.Haskell.Liquid.Bare
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.GHC.Misc         (getSourcePos)
+import           Language.Haskell.Liquid.Misc             (condNull)
+import           Language.Haskell.Liquid.Types.PredType
+import           Language.Haskell.Liquid.Types
 
-import Language.Haskell.Liquid.Bare
-import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.GHC.Misc  (getSourcePos)
-import Language.Haskell.Liquid.Types.PredType
-import Language.Haskell.Liquid.Types
-import Language.Fixpoint.Types
 
+--------------------------------------------------------------------------------
+qualifiers :: GhcInfo -> SEnv Sort -> [Qualifier]
+--------------------------------------------------------------------------------
+qualifiers info lEnv
+  =  condNull (useSpcQuals info) (gsQualifiers $ spec info)
+  ++ condNull (useSigQuals info) (sigQualifiers  info lEnv)
+  ++ condNull (useAlsQuals info) (alsQualifiers  info lEnv)
 
+-- --------------------------------------------------------------------------------
+-- qualifiers :: GhcInfo -> SEnv Sort -> [Qualifier]
+-- --------------------------------------------------------------------------------
+-- qualifiers info env = spcQs ++ genQs
+  -- where
+    -- spcQs           = gsQualifiers spc
+    -- genQs           = specificationQualifiers info env
+    -- n               = maxParams (getConfig spc)
+    -- spc             = spec info
 
--- import Control.Applicative      ((<$>))
-import Data.List                (delete, nub)
-import Data.Maybe               (catMaybes, fromMaybe)
-import qualified Data.HashSet as S
--- import Data.Bifunctor           (second)
-import Debug.Trace
+maxQualParams :: (HasConfig t) => t -> Int
+maxQualParams = maxParams . getConfig
 
------------------------------------------------------------------------------------
-specificationQualifiers :: Int -> GhcInfo -> SEnv Sort -> [Qualifier]
------------------------------------------------------------------------------------
-specificationQualifiers k info lEnv
-  = [ q | (x, t) <- (tySigs $ spec info) ++ (asmSigs $ spec info) ++ (inSigs $ spec info) ++ (ctors $ spec info)
-        , x `S.member` (S.fromList $ defVars info ++
-                                     -- NOTE: this mines extra, useful qualifiers but causes
-                                     -- a significant increase in running time, so we hide it
-                                     -- behind `--scrape-imports` and `--scrape-used-imports`
-                                     if info `hasOpt` scrapeUsedImports
-                                     then useVars info
-                                     else if info `hasOpt` scrapeImports
-                                     then impVars info
-                                     else [])
-        , q <- refTypeQuals lEnv (getSourcePos x) (tcEmbeds $ spec info) (val t)
+-- | Use explicitly given qualifiers .spec or source (.hs, .lhs) files
+useSpcQuals :: (HasConfig t) => t -> Bool
+useSpcQuals i = useQuals i && not (useAlsQuals i)
+
+-- | Scrape qualifiers from function signatures (incr :: x:Int -> {v:Int | v > x})
+useSigQuals :: (HasConfig t) => t -> Bool
+useSigQuals i = useQuals i && not (useAlsQuals i)
+
+-- | Scrape qualifiers from refinement type aliases (type Nat = {v:Int | 0 <= 0})
+useAlsQuals :: (HasConfig t) => t -> Bool
+useAlsQuals i = useQuals i && i `hasOpt` higherOrderFlag
+
+useQuals :: (HasConfig t) => t -> Bool
+useQuals = not . (FC.All == ) . eliminate . getConfig
+
+
+--------------------------------------------------------------------------------
+alsQualifiers :: GhcInfo -> SEnv Sort -> [Qualifier]
+--------------------------------------------------------------------------------
+alsQualifiers info lEnv
+  = [ q | a <- specAliases info
+        , q <- refTypeQuals lEnv (rtPos a) tce (rtBody a)
+        , length (qParams q) <= k + 1
+        , validQual lEnv q
+    ]
+    where
+      k   = maxQualParams info
+      tce = gsTcEmbeds (spec info)
+
+    -- Symbol (RTAlias RTyVar SpecType)
+
+specAliases :: GhcInfo -> [RTAlias RTyVar SpecType]
+specAliases = M.elems . typeAliases . gsRTAliases . spec
+
+validQual :: SEnv Sort -> Qualifier -> Bool
+validQual lEnv q = isJust $ checkSortExpr env (qBody q)
+  where
+    env          = unionSEnv lEnv qEnv
+    qEnv         = M.fromList (qParams q)
+
+--------------------------------------------------------------------------------
+sigQualifiers :: GhcInfo -> SEnv Sort -> [Qualifier]
+--------------------------------------------------------------------------------
+sigQualifiers info lEnv
+  = [ q | (x, t) <- specBinders info
+        , x `S.member` qbs
+        , q <- refTypeQuals lEnv (getSourcePos x) tce (val t)
         -- NOTE: large qualifiers are VERY expensive, so we only mine
         -- qualifiers up to a given size, controlled with --max-params
-        , length (q_params q) <= k + 1
+        , length (qParams q) <= k + 1
     ]
-    -- where lEnv = trace ("Literals: " ++ show lEnv') lEnv'
+    where
+      k   = maxQualParams info
+      tce = gsTcEmbeds (spec info)
+      qbs = qualifyingBinders info
 
+qualifyingBinders :: GhcInfo -> S.HashSet Var
+qualifyingBinders info = S.difference sTake sDrop
+  where
+    sTake              = S.fromList $ defVars       info ++ scrapeVars info
+    sDrop              = S.fromList $ specAxiomVars info
+
+-- NOTE: this mines extra, useful qualifiers but causes
+-- a significant increase in running time, so we hide it
+-- behind `--scrape-imports` and `--scrape-used-imports`
+scrapeVars :: GhcInfo -> [Var]
+scrapeVars info
+  | info `hasOpt` scrapeUsedImports = useVars info
+  | info `hasOpt` scrapeImports     = impVars info
+  | otherwise                       = []
+
+specBinders :: GhcInfo -> [(Var, LocSpecType)]
+specBinders info = mconcat
+  [ gsTySigs  sp
+  , gsAsmSigs sp
+  , gsCtors   sp
+  , if info `hasOpt` scrapeInternals then gsInSigs sp else []
+  ]
+  where
+    sp  = spec info
+
+specAxiomVars :: GhcInfo -> [Var]
+specAxiomVars =  gsReflects . spec
+
 -- GRAVEYARD: scraping quals from imports kills the system with too much crap
 -- specificationQualifiers info = {- filter okQual -} qs
 --   where
@@ -65,8 +152,9 @@
 
 
 -- TODO: rewrite using foldReft'
--- refTypeQuals :: SpecType -> [Qualifier]
+--------------------------------------------------------------------------------
 refTypeQuals :: SEnv Sort -> SourcePos -> TCEmb TyCon -> SpecType -> [Qualifier]
+--------------------------------------------------------------------------------
 refTypeQuals lEnv l tce t0    = go emptySEnv t0
   where
     scrape                    = refTopQuals lEnv l tce t0
@@ -87,60 +175,62 @@
     goRef g (RProp s t)  _    = go (insertsSEnv g s) t
     insertsSEnv               = foldr (\(x, t) γ -> insertSEnv x (rTypeSort tce t) γ)
 
+
+refTopQuals :: (PPrint t, Reftable t, SubsTy RTyVar RSort t)
+            => SEnv Sort
+            -> SourcePos
+            -> TCEmb TyCon
+            -> RType RTyCon RTyVar r
+            -> SEnv Sort
+            -> RRType (UReft t)
+            -> [Qualifier]
 refTopQuals lEnv l tce t0 γ t
   = [ mkQ v so pa  | let (RR so (Reft (v, ra))) = rTypeSortedReft tce t
-                                  , pa                        <- conjuncts ra
-                                  , not $ isHole pa
+                   , pa                        <- conjuncts ra
+                   , not $ isHole    pa
+                   , not $ isGradual pa 
+                   , isNothing $ checkSorted (insertSEnv v so γ') pa
     ]
     ++
     [ mkP s e | let (MkUReft _ (Pr ps) _) = fromMaybe (msg t) $ stripRTypeBase t
-                             , p <- findPVar (ty_preds $ toRTypeRep t0) <$> ps
-                             , (s, _, e) <- pargs p
+              , p                        <- findPVar (ty_preds $ toRTypeRep t0) <$> ps
+              , (s, _, e)                <- pargs p
     ]
     where
       mkQ   = mkQual  lEnv l     t0 γ
       mkP   = mkPQual lEnv l tce t0 γ
       msg t = panic Nothing $ "Qualifier.refTopQuals: no typebase" ++ showpp t
+      γ'    = unionSEnv' γ lEnv
 
+mkPQual :: (PPrint r, Reftable r, SubsTy RTyVar RSort r)
+        => SEnv Sort
+        -> SourcePos
+        -> TCEmb TyCon
+        -> t
+        -> SEnv Sort
+        -> RRType r
+        -> Expr
+        -> Qualifier
 mkPQual lEnv l tce t0 γ t e = mkQual lEnv l t0 γ' v so pa
   where
-    v                  = "vv"
-    so                 = rTypeSort tce t
-    γ'                 = insertSEnv v so γ
-    pa                 = PAtom Eq (EVar v) e
-
-mkQual = mkQualNEW
+    v                      = "vv"
+    so                     = rTypeSort tce t
+    γ'                     = insertSEnv v so γ
+    pa                     = PAtom Eq (EVar v) e
 
-mkQualNEW lEnv l _ γ v so p   = Q "Auto" ((v, so) : xts) p l
+mkQual :: SEnv Sort
+       -> SourcePos
+       -> t
+       -> SEnv Sort
+       -> Symbol
+       -> Sort
+       -> Expr
+       -> Qualifier
+mkQual lEnv l _ γ v so p   = Q "Auto" ((v, so) : xts) p l
   where
     xs   = delete v $ nub $ syms p
     xts = catMaybes $ zipWith (envSort l lEnv γ) xs [0..]
-    -- xts  = Language.Fixpoint.Misc.traceShow msg $ xts'
-    -- msg  = "Free Vars in: " ++ showFix p ++ " in " ++ show t0
 
--- OLD
-{-
-  TODO: If it's so OLD, do we need to keep it? Never called, etc...
-mkQualOLD lEnv l t0 γ v so p   = Q "Auto" ((v, so) : yts) p' l
-  where
-    yts                = [(y, lookupSort l γ i x) | (x, i, y) <- xys ]
-    p'                 = subst su p
-    su                 = mkSubst [(x, EVar y) | (x, _, y) <- xys]
-    xys                = zipWith (\x i -> (x, i, symbol ("~A" ++ show i))) xs [0..]
-    -- xs                 = delete v $ orderedFreeVars γ p
-    xs                 = {- Language.Fixpoint.Misc.traceShow msg $ -} delete v $ orderedFreeVarsOLD γ p
-    msg                = "Free Vars in: " ++ showFix p ++ " in " ++ show t0
-
-orderedFreeVarsOLD :: SEnv Sort -> Pred -> [Symbol]
-orderedFreeVarsOLD γ = nub . filter (`memberSEnv` γ) . syms
--}
-
-{-
-   TODO: Never used, do I need to exist?
-orderedFreeVars :: SEnv Sort -> Pred -> [Symbol]
-orderedFreeVars lEnv = nub . filter (not . (`memberSEnv` lEnv)) . syms
--}
-
 envSort :: SourcePos -> SEnv Sort -> SEnv Sort -> Symbol -> Integer -> Maybe (Symbol, Sort)
 envSort l lEnv tEnv x i
   | Just t <- lookupSEnv x tEnv = Just (x, t)
@@ -149,11 +239,3 @@
   where
     ai             = trace msg $ fObj $ Loc l l $ tempSymbol "LHTV" i
     msg            = "unknown symbol in qualifier: " ++ show x
-
-{-
-   TODO: Never used, do I need to exist?
-lookupSort l γ i x = fromMaybe ai $ lookupSEnv x γ
-  where
-    ai             = trace msg $ fObj $ Loc l l $ tempSymbol "LHTV" i
-    msg            = "unknown symbol in qualifier: " ++ show x
--}
diff --git a/src/Language/Haskell/Liquid/Constraint/Split.hs b/src/Language/Haskell/Liquid/Constraint/Split.hs
--- a/src/Language/Haskell/Liquid/Constraint/Split.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Split.hs
@@ -60,9 +60,9 @@
 splitW ::  WfC -> CG [FixWfC]
 --------------------------------------------------------------------------------
 splitW (WfC γ t@(RFun x t1 t2 _))
-  =  do ws   <- bsplitW γ t
-        ws'  <- splitW (WfC γ t1)
-        γ'   <- (γ, "splitW") += (x, t1)
+  =  do ws'  <- splitW (WfC γ t1)
+        γ'   <- γ += ("splitW", x, t1)
+        ws   <- bsplitW γ t
         ws'' <- splitW (WfC γ' t2)
         return $ ws ++ ws' ++ ws''
 
@@ -72,12 +72,17 @@
         ws'' <- splitW (WfC γ t2)
         return $ ws ++ ws' ++ ws''
 
-splitW (WfC γ (RAllT _ r))
-  = splitW (WfC γ r)
+splitW (WfC γ (RAllT a r))
+  = do γ' <- updateEnv γ a
+       splitW (WfC γ' r)
 
+
 splitW (WfC γ (RAllP _ r))
   = splitW (WfC γ r)
 
+splitW (WfC γ (RAllS _ r))
+  = splitW (WfC γ r)
+
 splitW (WfC γ t@(RVar _ _))
   = bsplitW γ t
 
@@ -90,31 +95,41 @@
 
 splitW (WfC γ (RAllE x tx t))
   = do  ws  <- splitW (WfC γ tx)
-        γ'  <- (γ, "splitW") += (x, tx)
+        γ'  <- γ += ("splitW1", x, tx)
         ws' <- splitW (WfC γ' t)
         return $ ws ++ ws'
 
 splitW (WfC γ (REx x tx t))
   = do  ws  <- splitW (WfC γ tx)
-        γ'  <- (γ, "splitW") += (x, tx)
+        γ'  <- γ += ("splitW2", x, tx)
         ws' <- splitW (WfC γ' t)
         return $ ws ++ ws'
 
+splitW (WfC γ (RRTy _ _ _ t))
+  = splitW (WfC γ t) 
+
 splitW (WfC _ t)
   = panic Nothing $ "splitW cannot handle: " ++ showpp t
 
-rsplitW _ (RProp _ (RHole _))
-  = panic Nothing "Constrains: rsplitW for RProp _ (RHole _)"
-rsplitW γ (RProp ss t0)
-  = do γ' <- foldM (++=) γ [("rsplitW", x, ofRSort s) | (x, s) <- ss]
-       splitW $ WfC γ' t0
+rsplitW :: CGEnv
+        -> Ref RSort SpecType
+        -> CG [FixWfC]
+rsplitW _ (RProp _ (RHole _)) =
+  panic Nothing "Constrains: rsplitW for RProp _ (RHole _)"
 
+rsplitW γ (RProp ss t0) = do
+  γ' <- foldM (+=) γ [("rsplitW", x, ofRSort s) | (x, s) <- ss]
+  splitW $ WfC γ' t0
+
+
 bsplitW :: CGEnv -> SpecType -> CG [FixWfC]
 bsplitW γ t =
   do pflag <- pruneRefs <$> get
      isHO  <- allowHO   <$> get
      return $ bsplitW' γ t pflag isHO
 
+bsplitW' :: (PPrint r, F.Reftable r, SubsTy RTyVar RSort r)
+         => CGEnv -> RRType r -> Bool -> Bool -> [F.WfC Cinfo]
 bsplitW' γ t pflag isHO
   | isHO || F.isNonTrivial r'
   = F.wfC (feBinds $ fenv γ) r' ci
@@ -122,7 +137,7 @@
   = []
   where
     r'                = rTypeSortedReft' pflag γ t
-    ci                = Ci (getLocation γ) Nothing
+    ci                = Ci (getLocation γ) Nothing (cgVar γ)
 
 --------------------------------------------------------------------------------
 splitS  :: SubC -> CG [([Stratum], [Stratum])]
@@ -155,7 +170,7 @@
 splitS (SubC γ t1@(RFun x1 r1 r1' _) t2@(RFun x2 r2 r2' _))
   =  do cs       <- bsplitS t1 t2
         cs'      <- splitS  (SubC γ r2 r1)
-        γ'       <- (γ, "splitS") += (x2, r2)
+        γ'       <- γ += ("splitS1", x2, r2)
         let r1x2' = r1' `F.subst1` (x1, F.EVar x2)
         cs''     <- splitS  (SubC γ' r1x2' r2')
         return    $ cs ++ cs' ++ cs''
@@ -176,13 +191,21 @@
 splitS (SubC _ t1@(RAllP _ _) t2)
   = panic Nothing $ "Predicate in lhs of constrain:" ++ showpp t1 ++ "\n<:\n" ++ showpp t2
 
+
 splitS (SubC γ (RAllT α1 t1) (RAllT α2 t2))
   |  α1 ==  α2
-  = splitS $ SubC γ t1 t2
+  = do γ' <- updateEnv γ α2
+       splitS $ SubC γ' t1 (F.subst su t2)
   | otherwise
-  = splitS $ SubC γ t1 t2'
-  where t2' = subsTyVar_meet' (α2, RVar α1 mempty) t2
+  = do γ' <- updateEnv γ α2
+       splitS $ SubC γ' t1 (F.subst su t2')
+  where
+    t2' = subsTyVar_meet' (ty_var_value α2, RVar (ty_var_value α1) mempty) t2
+    su = case (rTVarToBind α1, rTVarToBind α2) of
+          (Just (x1, _), Just (x2, _)) -> F.mkSubst [(x1, F.EVar x2)]
+          _                            -> F.mkSubst []
 
+
 splitS (SubC _ (RApp c1 _ _ _) (RApp c2 _ _ _)) | isClass c1 && c1 == c2
   = return []
 
@@ -209,9 +232,20 @@
 splitS (SubR _ _ _)
   = return []
 
+splitsSWithVariance :: CGEnv
+                    -> [SpecType]
+                    -> [SpecType]
+                    -> [Variance]
+                    -> CG [([Stratum], [Stratum])]
 splitsSWithVariance γ t1s t2s variants
   = concatMapM (\(t1, t2, v) -> splitfWithVariance (\s1 s2 -> splitS (SubC γ s1 s2)) t1 t2 v) (zip3 t1s t2s variants)
 
+rsplitsSWithVariance :: Bool
+                     -> CGEnv
+                     -> [Ref t (RType RTyCon RTyVar RReft)]
+                     -> [Ref t (RType RTyCon RTyVar RReft)]
+                     -> [Variance]
+                     -> CG [([Stratum], [Stratum])]
 rsplitsSWithVariance False _ _ _ _
   = return []
 
@@ -222,6 +256,10 @@
   = return $ [(s1, s2)]
   where [s1, s2]   = getStrata <$> [t1, t2]
 
+rsplitS :: CGEnv
+        -> Ref t (RType RTyCon RTyVar RReft)
+        -> Ref t1 (RType RTyCon RTyVar RReft)
+        -> CG [([Stratum], [Stratum])]
 rsplitS _ (RProp _ (RHole _)) _
    = panic Nothing "rsplitS RProp _ (RHole _)"
 
@@ -232,44 +270,52 @@
   = splitS (SubC γ (F.subst su r1) r2)
   where su = F.mkSubst [(x, F.EVar y) | ((x,_), (y,_)) <- zip s1 s2]
 
+splitfWithVariance :: Applicative f
+                   => (t -> t -> f [a]) -> t -> t -> Variance -> f [a]
 splitfWithVariance f t1 t2 Invariant     = (++) <$> f t1 t2 <*> f t2 t1
 splitfWithVariance f t1 t2 Bivariant     = (++) <$> f t1 t2 <*> f t2 t1
 splitfWithVariance f t1 t2 Covariant     = f t1 t2
 splitfWithVariance f t1 t2 Contravariant = f t2 t1
 
+updateEnv :: CGEnv -> RTVar RTyVar (RType RTyCon RTyVar b0) -> CG CGEnv
+updateEnv γ a
+  | Just (x, s) <- rTVarToBind a
+  = γ += ("splitS RAllT", x, fmap (const mempty) s)
+  | otherwise
+  = return γ
 
 ------------------------------------------------------------
 splitC :: SubC -> CG [FixSubC]
 ------------------------------------------------------------
 
 splitC (SubC γ (REx x tx t1) (REx x2 _ t2)) | x == x2
-  = do γ' <- (γ, "addExBind 0") += (x, forallExprRefType γ tx)
+  = do γ' <- γ += ("addExBind 0", x, forallExprRefType γ tx)
        splitC (SubC γ' t1 t2)
 
 splitC (SubC γ t1 (REx x tx t2))
   = do y <- fresh
-       γ' <- (γ, "addExBind 1") += (y, forallExprRefType γ tx)
+       γ' <- γ += ("addExBind 1", y, forallExprRefType γ tx)
        splitC (SubC γ' t1 (F.subst1 t2 (x, F.EVar y)))
 
 -- existential at the left hand side is treated like forall
 splitC (SubC γ (REx x tx t1) t2)
   = do -- let tx' = traceShow ("splitC: " ++ showpp z) tx
        y <- fresh
-       γ' <- (γ, "addExBind 2") += (y, forallExprRefType γ tx)
+       γ' <- γ += ("addExBind 2", y, forallExprRefType γ tx)
        splitC (SubC γ' (F.subst1 t1 (x, F.EVar y)) t2)
 
 splitC (SubC γ (RAllE x tx t1) (RAllE x2 _ t2)) | x == x2
-  = do γ' <- (γ, "addAllBind 0") += (x, forallExprRefType γ tx)
+  = do γ' <- γ += ("addAllBind 3", x, forallExprRefType γ tx)
        splitC (SubC γ' t1 t2)
 
 splitC (SubC γ (RAllE x tx t1) t2)
   = do y  <- fresh
-       γ' <- (γ, "addAABind 1") += (y, forallExprRefType γ tx)
+       γ' <- γ += ("addAABind 1", y, forallExprRefType γ tx)
        splitC (SubC γ' (t1 `F.subst1` (x, F.EVar y)) t2)
 
 splitC (SubC γ t1 (RAllE x tx t2))
   = do y  <- fresh
-       γ' <- (γ, "addAllBind 2") += (y, forallExprRefType γ tx)
+       γ' <- γ += ("addAllBind 2", y, forallExprRefType γ tx)
        splitC (SubC γ' t1 (F.subst1 t2 (x, F.EVar y)))
 
 splitC (SubC γ (RRTy env _ OCons t1) t2)
@@ -286,12 +332,13 @@
        c2 <- splitC (SubC γ t1 t2)
        return $ c1 ++ c2
 
-splitC (SubC γ t1@(RFun x1 r1 r1' _) t2@(RFun x2 r2 r2' _))
-  =  do cs       <- bsplitC γ t1 t2
-        cs'      <- splitC  (SubC γ r2 r1)
-        γ'       <- (γ, "splitC") += (x2, r2)
-        let r1x2' = r1' `F.subst1` (x1, F.EVar x2)
-        cs''     <- splitC  (SubC γ' r1x2' r2')
+splitC (SubC γ (RFun x1 t1 t1' r1) (RFun x2 t2 t2' r2))
+  =  do cs'      <- splitC  (SubC γ t2 t1)
+        γ'       <- γ+= ("splitC", x2, t2)
+        cs       <- bsplitC γ (RFun x1 t1 t1' (r1 `F.subst1` (x1, F.EVar x2)))
+                              (RFun x2 t2 t2'  r2)
+        let t1x2' = t1' `F.subst1` (x1, F.EVar x2)
+        cs''     <- splitC  (SubC γ' t1x2' t2')
         return    $ cs ++ cs' ++ cs''
 
 splitC (SubC γ t1@(RAppTy r1 r1' _) t2@(RAppTy r2 r2' _))
@@ -312,11 +359,16 @@
 
 splitC (SubC γ (RAllT α1 t1) (RAllT α2 t2))
   |  α1 ==  α2
-  = splitC $ SubC γ t1 t2
+  = do γ' <- updateEnv γ α2
+       splitC $ SubC γ' t1 (F.subst su t2)
   | otherwise
-  = splitC $ SubC γ t1 t2'
-  where t2' = subsTyVar_meet' (α2, RVar α1 mempty) t2
-
+  = do γ' <- updateEnv γ α2
+       splitC $ SubC γ' t1 (F.subst su t2')
+  where
+    t2' = subsTyVar_meet' (ty_var_value α2, RVar (ty_var_value α1) mempty) t2
+    su = case (rTVarToBind α1, rTVarToBind α2) of
+          (Just (x1, _), Just (x2, _)) -> F.mkSubst [(x1, F.EVar x2)]
+          _                            -> F.mkSubst []
 
 splitC (SubC _ (RApp c1 _ _ _) (RApp c2 _ _ _)) | isClass c1 && c1 == c2
   = return []
@@ -337,8 +389,8 @@
   | a1 == a2
   = bsplitC γ t1 t2
 
-splitC (SubC _ t1 t2)
-  = panic Nothing $ "(Another Broken Test!!!) splitc unexpected:\n" ++ showpp t1 ++ "\n  <:\n" ++ showpp t2
+splitC (SubC γ t1 t2)
+  = panic (Just $ getLocation γ) $ "(Another Broken Test!!!) splitc unexpected:\n" ++ showpp t1 ++ "\n  <:\n" ++ showpp t2
 
 splitC (SubR γ o r)
   = do fg     <- pruneRefs <$> get
@@ -350,7 +402,7 @@
     r1  = F.RR F.boolSort rr
     r2  = F.RR F.boolSort $ F.Reft (vv, F.EVar vv)
     vv  = "vvRec"
-    ci  = Ci src err
+    ci  = Ci src err (cgVar γ)
     err = Just $ ErrAssType src o (text $ show o ++ "type error") g (rHole rr)
     rr  = F.toReft r
     tag = getTag γ
@@ -361,20 +413,35 @@
 rHole = RHole . uTop
 
 
+splitsCWithVariance :: CGEnv
+                    -> [SpecType]
+                    -> [SpecType]
+                    -> [Variance]
+                    -> CG [FixSubC]
 splitsCWithVariance γ t1s t2s variants
   = concatMapM (\(t1, t2, v) -> splitfWithVariance (\s1 s2 -> (splitC (SubC γ s1 s2))) t1 t2 v) (zip3 t1s t2s variants)
 
+rsplitsCWithVariance :: Bool
+                     -> CGEnv
+                     -> [SpecProp]
+                     -> [SpecProp]
+                     -> [Variance]
+                     -> CG [FixSubC]
 rsplitsCWithVariance False _ _ _ _
   = return []
 
 rsplitsCWithVariance _ γ t1s t2s variants
   = concatMapM (\(t1, t2, v) -> splitfWithVariance (rsplitC γ) t1 t2 v) (zip3 t1s t2s variants)
 
+bsplitC :: CGEnv
+        -> SpecType
+        -> SpecType
+        -> CG [F.SubC Cinfo]
 bsplitC γ t1 t2 = do
   checkStratum γ t1 t2
   pflag  <- pruneRefs <$> get
   isHO   <- allowHO   <$> get
-  let t1' = addLhsInv γ t1
+  t1'    <- addLhsInv γ <$> refreshVV t1
   return  $ bsplitC' γ t1' t2 pflag isHO
 
 addLhsInv :: CGEnv -> SpecType -> SpecType
@@ -385,11 +452,10 @@
     rE'       = insertREnv v t (renv γ)
     v         = rTypeValueVar t
 
-     -- γ'     <- γ ++= ("bsplitC", v, t1)
-       -- let r   = (mempty :: UReft F.Reft){ur_reft = F.Reft (F.dummySymbol, constraintToLogic γ' (lcs γ'))}
-       -- let t1' = addRTyConInv (invs γ')  t1 `strengthen` r
-       -- let F.Reft(v, _) = ur_reft (fromMaybe mempty (stripRTypeBase t1))
-
+checkStratum :: CGEnv
+             -> RType t t1 (UReft r)
+             -> RType t t1 (UReft r)
+             -> CG ()
 checkStratum γ t1 t2
   | s1 <:= s2 = return ()
   | otherwise = addWarning wrn
@@ -397,6 +463,7 @@
     [s1, s2]  = getStrata <$> [t1, t2]
     wrn       =  ErrOther (getLocation γ) (text $ "Stratum Error : " ++ show s1 ++ " > " ++ show s2)
 
+bsplitC' :: CGEnv -> SpecType -> SpecType -> Bool -> Bool -> [F.SubC Cinfo]
 bsplitC' γ t1 t2 pflag isHO
  | isHO
  = F.subC γ' r1'  r2' Nothing tag ci
@@ -410,8 +477,9 @@
     γ'  = feBinds $ fenv γ
     r1' = rTypeSortedReft' pflag γ t1
     r2' = rTypeSortedReft' pflag γ t2
-    ci  = Ci src err
+    ci  = Ci src err (cgVar γ)
     tag = getTag γ
+    -- err = Just $ ErrSubType src "subtype" g t1 t2
     err = Just $ fromMaybe (ErrSubType src (text "subtype") g t1 t2) (cerr γ)
     src = getLocation γ
     g   = reLocal $ renv γ
@@ -424,6 +492,10 @@
 unifyVV _ _
   = panic Nothing $ "Constraint.Generate.unifyVV called on invalid inputs"
 
+rsplitC :: CGEnv
+        -> SpecProp
+        -> SpecProp
+        -> CG [FixSubC]
 rsplitC _ _ (RProp _ (RHole _))
   = panic Nothing "RefTypes.rsplitC on RProp _ (RHole _)"
 
@@ -431,7 +503,7 @@
   = panic Nothing "RefTypes.rsplitC on RProp _ (RHole _)"
 
 rsplitC γ (RProp s1 r1) (RProp s2 r2)
-  = do γ'  <-  foldM (++=) γ [("rsplitC1", x, ofRSort s) | (x, s) <- s2]
+  = do γ'  <-  foldM (+=) γ [("rsplitC1", x, ofRSort s) | (x, s) <- s2]
        splitC (SubC γ' (F.subst su r1) r2)
   where su = F.mkSubst [(x, F.EVar y) | ((x,_), (y,_)) <- zip s1 s2]
 
@@ -466,6 +538,9 @@
   = Nothing
 
 -- forallExprReftLookup :: CGEnv -> F.Symbol -> Int
+forallExprReftLookup :: CGEnv
+                     -> F.Symbol
+                     -> Maybe ([F.Symbol], [SpecType], [RReft], SpecType)
 forallExprReftLookup γ x = snap <$> F.lookupSEnv x (syenv γ)
   where
     snap     = mapFourth4 ignoreOblig . bkArrow . fourth4 . bkUniv . lookup
@@ -493,4 +568,4 @@
 -- | Constraint Generation Panic -----------------------------------------------
 --------------------------------------------------------------------------------
 panicUnbound :: (PPrint x) => CGEnv -> x -> a
-panicUnbound γ x = Ex.throw $ (ErrUnbound (getLocation γ) (pprint x) :: Error)
+panicUnbound γ x = Ex.throw $ (ErrUnbound (getLocation γ) (F.pprint x) :: Error)
diff --git a/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs b/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs
--- a/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs
+++ b/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs
@@ -1,46 +1,196 @@
+{-# LANGUAGE FlexibleContexts          #-}
 module Language.Haskell.Liquid.Constraint.ToFixpoint (
 
-        cgInfoFInfo
+    cgInfoFInfo
 
-        ) where
-import Prelude hiding (error)
+  , fixConfig
+
+  ) where
+
+import           Prelude hiding (error)
+import           Data.Monoid
+
+import qualified Language.Fixpoint.Types.Config as FC
+import           System.Console.CmdArgs.Default (def)
 import qualified Language.Fixpoint.Types        as F
-import Language.Haskell.Liquid.Constraint.Types
+import           Language.Haskell.Liquid.Constraint.Types
+import           Language.Haskell.Liquid.Types hiding     ( binds )
+import           Language.Fixpoint.Solver                 ( parseFInfo )
+import           Language.Haskell.Liquid.Constraint.Qualifier
+-- import           Language.Fixpoint.Misc (traceShow)
 
-import Language.Haskell.Liquid.Types hiding     ( binds )
+import Language.Haskell.Liquid.UX.Config (allowSMTInstationation)
+import Data.Maybe (fromJust)
 
-import Language.Fixpoint.Solver                 ( parseFInfo )
+-- AT: Move to own module?
+-- imports for AxiomEnv
+import           Language.Haskell.Liquid.UX.Config (allowLiquidInstationationGlobal, allowLiquidInstationationLocal, allowRewrite, allowArithmetic)
+import           Language.Haskell.Liquid.GHC.Misc  (dropModuleNames, simplesymbol)
+import qualified Data.List                         as L
+import qualified Data.HashMap.Strict               as M
+import           Data.Maybe                        (fromMaybe)
+import           Language.Fixpoint.Misc
+import           Var
 
+fixConfig :: FilePath -> Config -> FC.Config
+fixConfig tgt cfg = def
+  { FC.solver           = fromJust (smtsolver cfg)
+  , FC.linear           = linear            cfg
+  , FC.eliminate        = eliminate         cfg
+  , FC.nonLinCuts       = not (higherOrderFlag cfg) -- eliminate cfg /= FC.All
+  , FC.save             = saveQuery         cfg
+  , FC.srcFile          = tgt
+  , FC.cores            = cores             cfg
+  , FC.minPartSize      = minPartSize       cfg
+  , FC.maxPartSize      = maxPartSize       cfg
+  , FC.elimStats        = elimStats         cfg
+  , FC.elimBound        = elimBound         cfg
+  , FC.allowHO          = higherOrderFlag   cfg
+  , FC.allowHOqs        = higherorderqs     cfg
+  , FC.extensionality   = extensionality    cfg || gradual cfg
+  , FC.alphaEquivalence = alphaEquivalence  cfg
+  , FC.betaEquivalence  = betaEquivalence   cfg
+  , FC.normalForm       = normalForm        cfg
+  , FC.stringTheory     = stringTheory      cfg
+  , FC.gradual          = gradual           cfg
+  , FC.noslice          = noslice           cfg
+  , FC.rewriteAxioms    = allowRewrite      cfg
+  , FC.arithmeticAxioms = allowArithmetic   cfg
+  }
 
 
-import           Data.Monoid
+cgInfoFInfo :: GhcInfo -> CGInfo -> IO (F.FInfo Cinfo)
+cgInfoFInfo info cgi = do
+  let tgtFI  = targetFInfo info cgi
+  impFI     <- ignoreQualifiers info <$> parseFInfo (hqFiles info)
+  return       (tgtFI <> impFI)
+  -- let fI    = ignoreQualifiers info (tgtFI <> impFI)
+  -- return fI
 
-import Language.Haskell.Liquid.Constraint.Qualifier
+ignoreQualifiers :: GhcInfo -> F.FInfo a -> F.FInfo a
+ignoreQualifiers info fi
+  | useSpcQuals info = fi
+  | otherwise        = fi { F.quals = [] }
 
+-- NOPROP ignoreQualifiers :: GhcInfo -> F.FInfo a -> F.FInfo a
+-- NOPROP ignoreQualifiers info fi
+  -- NOPROP | noQuals     = fi { F.quals = [] }
+  -- NOPROP | otherwise   = fi
+  -- NOPROP where noQuals = (FC.All == ) . eliminate . getConfig . spec $ info
 
-cgInfoFInfo :: GhcInfo -> CGInfo -> FilePath  -> IO (F.FInfo Cinfo)
-cgInfoFInfo info cgi fi = do
-  let tgtFI = targetFInfo info cgi fi
-  impFI    <- parseFInfo $ hqFiles info
-  return    $ tgtFI <> impFI
+targetFInfo :: GhcInfo -> CGInfo -> F.FInfo Cinfo
+targetFInfo info cgi = mappend (mempty { F.ae = ax }) fi
+  where
+    fi               = F.fi cs ws bs ls consts ks qs bi aHO aHOqs es mempty
+    cs               = fixCs    cgi
+    ws               = fixWfs   cgi
+    bs               = binds    cgi
+    ls               = fEnv     cgi
+    consts           = cgConsts cgi
+    ks               = kuts     cgi
+    qs               = qualifiers info (fEnv cgi)
+    bi               = (\x -> Ci x Nothing Nothing) <$> bindSpans cgi
+    aHO              = allowHO cgi
+    aHOqs            = higherOrderFlag info
+    es               = makeAxioms info
+    ax               = makeAxiomEnvironment info (dataConTys cgi) (F.cm fi)
 
-targetFInfo :: GhcInfo -> CGInfo -> FilePath -> F.FInfo Cinfo
-targetFInfo info cgi fn = F.fi cs ws bs ls ks qs bi fn aHO 
+makeAxiomEnvironment :: GhcInfo -> [(Var, SpecType)] -> M.HashMap F.SubcId (F.SubC Cinfo) -> F.AxiomEnv
+makeAxiomEnvironment info xts fcs
+  = F.AEnv ((axiomName <$> gsAxioms (spec info)) ++ (F.symbol . fst <$> xts))
+           (makeEquations info ++ (specTypToEq  <$> xts))
+           (concatMap makeSimplify xts)
+           fuelMap
+           doExpand
   where
-   cs     = fixCs  cgi
-   ws     = fixWfs cgi
-   bs     = binds  cgi
-   ls     = fEnv cgi
-   ks     = kuts cgi
-   qs     = targetQuals info cgi
-   bi     = (`Ci` Nothing) <$> bindSpans cgi
-   aHO    = allowHO cgi 
+    cfg = getConfig info
+    doExpand = (\sub -> allowLiquidInstationationGlobal cfg
+                || allowLiquidInstationationLocal cfg
+                && maybe False (`M.member` gsAutoInst (spec info)) (subVar sub))
+                                    <$> fcs
+    fuelNumber sub = do {v <- subVar sub; lp <- M.lookup v (gsAutoInst (spec info)); lp}
+    fuelMap =  fromMaybe (fuel cfg) . fuelNumber <$> fcs
+    specTypToEq (x, t)
+      = F.Equ (F.symbol x) (ty_binds $ toRTypeRep t)
+           (specTypeToResultRef (F.eApps (F.EVar $ F.symbol x) (F.EVar <$> ty_binds (toRTypeRep t))) t)
 
-targetQuals :: GhcInfo -> CGInfo -> [F.Qualifier]
-targetQuals info cgi = spcQs ++ genQs
+makeSimplify :: (Var, SpecType) -> [F.Rewrite]
+makeSimplify (x, t) = go $ specTypeToResultRef (F.eApps (F.EVar $ F.symbol x) (F.EVar <$> ty_binds (toRTypeRep t))) t
   where
-    spcQs     = qualifiers spc
-    genQs     = specificationQualifiers n info (fEnv cgi)
-    n         = maxParams $ config spc
-    spc       = spec info
-    -- lEnv      = F.fromListSEnv $ lits cgi
+    go (F.PAnd es) = concatMap go es
+
+    go (F.PAtom eq (F.EApp (F.EVar f) dc) bd)
+      | eq `elem` [F.Eq, F.Ueq]
+      , (F.EVar dc, xs) <- F.splitEApp dc
+      , all isEVar xs
+      = [F.SMeasure f dc (fromEVar <$> xs) bd]
+
+    go (F.PIff (F.EApp (F.EVar f) dc) bd)
+      | (F.EVar dc, xs) <- F.splitEApp dc
+      , all isEVar xs
+      = [F.SMeasure f dc (fromEVar <$> xs) bd]
+
+    go _ = []
+
+    isEVar (F.EVar _) = True
+    isEVar _ = False
+
+    fromEVar (F.EVar x) = x
+    fromEVar _ = impossible Nothing "makeSimplify.fromEVar"
+
+makeEquations :: GhcInfo -> [F.Equation]
+makeEquations info
+  = [ F.Equ x xs (F.pAnd [makeEqBody x xs e, makeRefBody x xs (lookupSpecType x (gsTySigs $ spec info))]) | AxiomEq x xs e _ <- gsAxioms (spec info)]
+  where
+    makeEqBody x xs e = F.PAtom F.Eq (F.eApps (F.EVar x) (F.EVar <$> xs)) e
+    lookupSpecType x xts = L.lookup x ((mapFst (dropModuleNames . simplesymbol)) <$> xts)
+    makeRefBody _ _  Nothing  = F.PTrue
+    makeRefBody x xs (Just t) = specTypeToLogic (F.EVar <$> xs) (F.eApps (F.EVar x) (F.EVar <$> xs)) (val t)
+
+
+-- NV Move this to types?
+-- sound but imprecise approximation of a tyep in the logic
+specTypeToLogic :: [F.Expr] -> F.Expr -> SpecType -> F.Expr
+specTypeToLogic es e t
+  | ok        = F.subst su (F.PImp (F.pAnd args) res)
+  | otherwise = F.PTrue
+  where
+    res     = specTypeToResultRef e t
+
+    args    = zipWith mkExpr (mkReft <$> ts) es
+
+    mkReft t =  F.toReft $ fromMaybe mempty (stripRTypeBase t)
+    mkExpr (F.Reft (v, ev)) e = F.subst1 ev (v, e)
+
+
+    ok      = okLen && okClass && okArgs
+    okLen   = length xs == length xs
+    okClass = all (F.isTauto . snd) cls
+    okArgs  = all okArg ts
+
+    okArg (RVar _ _)       = True
+    okArg t@(RApp _ _ _ _) = F.isTauto (t{rt_reft = mempty})
+    okArg _                = False
+
+
+    su           = F.mkSubst $ zip xs es
+    (cls, nocls) = L.partition (isClassType.snd) $ zip (ty_binds trep) (ty_args trep)
+                 :: ([(F.Symbol, SpecType)], [(F.Symbol, SpecType)])
+    (xs, ts)     = unzip nocls :: ([F.Symbol], [SpecType])
+
+    trep = toRTypeRep t
+
+
+specTypeToResultRef :: F.Expr -> SpecType -> F.Expr
+specTypeToResultRef e t
+  = mkExpr $ F.toReft $ fromMaybe mempty (stripRTypeBase $ ty_res trep)
+  where
+    mkExpr (F.Reft (v, ev)) = F.subst1 ev (v, e)
+    trep                   = toRTypeRep t
+
+makeAxioms :: GhcInfo -> [F.Triggered F.Expr]
+makeAxioms info 
+  | allowSMTInstationation (getConfig info)
+  = F.defaultTrigger . axiomEq <$> gsAxioms (spec info)
+  | otherwise
+  = [] 
diff --git a/src/Language/Haskell/Liquid/Constraint/Types.hs b/src/Language/Haskell/Liquid/Constraint/Types.hs
--- a/src/Language/Haskell/Liquid/Constraint/Types.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Types.hs
@@ -1,6 +1,7 @@
-
-{-# LANGUAGE BangPatterns      #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE TupleSections     #-}
+{-# LANGUAGE EmptyDataDecls    #-}
 
 module Language.Haskell.Liquid.Constraint.Types
   ( -- * Constraint Generation Monad
@@ -19,6 +20,7 @@
   , FEnv (..)
   , initFEnv
   , insertsFEnv
+  -- , removeFEnv
 
    -- * Hole Environment
   , HEnv
@@ -29,6 +31,8 @@
   , SubC (..)
   , FixSubC
 
+  , subVar
+
    -- * Well-formedness Constraints
   , WfC (..)
   , FixWfC
@@ -42,86 +46,84 @@
   -- * Aliases?
   , RTyConIAl
   , mkRTyConIAl
+
+  , removeInvariant, restoreInvariant, makeRecInvariants
+
+  , addArgument, addArguments
   ) where
 
 import Prelude hiding (error)
-import CoreSyn
-import SrcLoc
-
+import           CoreSyn
+import           Var
+import           SrcLoc
+import           Unify (tcUnifyTy)
 import qualified TyCon   as TC
 import qualified DataCon as DC
-
-
-import Text.PrettyPrint.HughesPJ hiding (first)
-
+import           Text.PrettyPrint.HughesPJ hiding (first)
 import qualified Data.HashMap.Strict as M
 import qualified Data.HashSet        as S
 import qualified Data.List           as L
-
-import Control.DeepSeq
--- import Data.Monoid              (mconcat)
-import Data.Maybe               (catMaybes)
-import Control.Monad.State
-
-
-import Var
-
-
-
-
-
-import Language.Haskell.Liquid.GHC.SpanStack
-import Language.Haskell.Liquid.Types hiding   (binds)
-import Language.Haskell.Liquid.Types.Strata
-import Language.Haskell.Liquid.Misc           (fourth4)
-import Language.Haskell.Liquid.Types.RefType  (shiftVV)
-import Language.Haskell.Liquid.WiredIn        (wiredSortedSyms)
+import           Control.DeepSeq
+import           Data.Maybe               (catMaybes, isJust)
+import           Control.Monad.State
+import           Language.Haskell.Liquid.GHC.SpanStack
+import           Language.Haskell.Liquid.Types hiding   (binds)
+import           Language.Haskell.Liquid.Types.Strata
+import           Language.Haskell.Liquid.Misc           (fourth4)
+import           Language.Haskell.Liquid.Types.RefType  (shiftVV, toType)
+import           Language.Haskell.Liquid.WiredIn        (wiredSortedSyms)
 import qualified Language.Fixpoint.Types            as F
-
 import Language.Fixpoint.Misc
 
 import qualified Language.Haskell.Liquid.UX.CTags      as Tg
 
 type CG = State CGInfo
 
-data CGEnv
-  = CGE { cgLoc :: !SpanStack         -- ^ Location in original source file
-        , renv  :: !REnv              -- ^ SpecTypes for Bindings in scope
-        , syenv :: !(F.SEnv Var)      -- ^ Map from free Symbols (e.g. datacons) to Var
-        , denv  :: !RDEnv             -- ^ Dictionary Environment
-        , fenv  :: !FEnv              -- ^ Fixpoint Environment
-        , recs  :: !(S.HashSet Var)   -- ^ recursive defs being processed (for annotations)
-        , invs  :: !RTyConInv         -- ^ Datatype invariants
-        , ial   :: !RTyConIAl         -- ^ Datatype checkable invariants
-        , grtys :: !REnv              -- ^ Top-level variables with (assert)-guarantees to verify
-        , assms :: !REnv              -- ^ Top-level variables with assumed types
-        , intys :: !REnv              -- ^ Top-level variables with auto generated internal types
-        , emb   :: F.TCEmb TC.TyCon   -- ^ How to embed GHC Tycons into fixpoint sorts
-        , tgEnv :: !Tg.TagEnv          -- ^ Map from top-level binders to fixpoint tag
-        , tgKey :: !(Maybe Tg.TagKey)                     -- ^ Current top-level binder
-        , trec  :: !(Maybe (M.HashMap F.Symbol SpecType)) -- ^ Type of recursive function with decreasing constraints
-        , lcb   :: !(M.HashMap F.Symbol CoreExpr)         -- ^ Let binding that have not been checked (c.f. LAZYVARs)
-        , holes :: !HEnv                                  -- ^ Types with holes, will need refreshing
-        , lcs   :: !LConstraint                           -- ^ Logical Constraints
-        , aenv  :: !(M.HashMap Var F.Symbol)              -- ^ axiom environment maps axiomatized Haskell functions to the logical functions
-        , cerr  :: !(Maybe (TError SpecType))             -- ^ error that should be reported at the user 
-        } -- deriving (Data, Typeable)
+data CGEnv = CGE
+  { cgLoc    :: !SpanStack         -- ^ Location in original source file
+  , renv     :: !REnv              -- ^ SpecTypes for Bindings in scope
+  , syenv    :: !(F.SEnv Var)      -- ^ Map from free Symbols (e.g. datacons) to Var
+  , denv     :: !RDEnv             -- ^ Dictionary Environment
+  , litEnv   :: !(F.SEnv F.Sort)   -- ^ Global  literals
+  , constEnv :: !(F.SEnv F.Sort)   -- ^ Distinct literals
+  , fenv   :: !FEnv              -- ^ Fixpoint Environment
+  , recs   :: !(S.HashSet Var)   -- ^ recursive defs being processed (for annotations)
+  , fargs  :: !(S.HashSet Var)   -- ^ recursive defs being processed (for annotations)
+  , invs   :: !RTyConInv         -- ^ Datatype invariants
+  , rinvs  :: !RTyConInv         -- ^ Datatype recursive invariants: ignored in the base case assumed in rec call
+  , ial    :: !RTyConIAl         -- ^ Datatype checkable invariants
+  , grtys  :: !REnv              -- ^ Top-level variables with (assert)-guarantees to verify
+  , assms  :: !REnv              -- ^ Top-level variables with assumed types
+  , intys  :: !REnv              -- ^ Top-level variables with auto generated internal types
+  , emb    :: F.TCEmb TC.TyCon   -- ^ How to embed GHC Tycons into fixpoint sorts
+  , tgEnv  :: !Tg.TagEnv          -- ^ Map from top-level binders to fixpoint tag
+  , tgKey  :: !(Maybe Tg.TagKey)                     -- ^ Current top-level binder
+  , trec   :: !(Maybe (M.HashMap F.Symbol SpecType)) -- ^ Type of recursive function with decreasing constraints
+  , lcb    :: !(M.HashMap F.Symbol CoreExpr)         -- ^ Let binding that have not been checked (c.f. LAZYVARs)
+  , holes  :: !HEnv                                  -- ^ Types with holes, will need refreshing
+  , lcs    :: !LConstraint                           -- ^ Logical Constraints
+  , aenv   :: !(M.HashMap Var F.Symbol)              -- ^ axiom environment maps axiomatized Haskell functions to the logical functions
+  , cerr   :: !(Maybe (TError SpecType))             -- ^ error that should be reported at the user
+  -- , cgCfg  :: !Config                                -- ^ top-level config options
+  , cgInfo :: !GhcInfo                               -- ^ top-level GhcInfo
+  , cgVar  :: !(Maybe Var)                           -- ^ top level function being checked
+  } -- deriving (Data, Typeable)
 
+instance HasConfig CGEnv where
+  getConfig = getConfig . cgInfo
+
 data LConstraint = LC [[(F.Symbol, SpecType)]]
 
 instance Monoid LConstraint where
   mempty  = LC []
   mappend (LC cs1) (LC cs2) = LC (cs1 ++ cs2)
 
-
 instance PPrint CGEnv where
   pprintTidy k = pprintTidy k . renv
 
 instance Show CGEnv where
   show = showpp
 
-
-
 --------------------------------------------------------------------------------
 -- | Subtyping Constraints -----------------------------------------------------
 --------------------------------------------------------------------------------
@@ -143,23 +145,24 @@
 type FixSubC  = F.SubC Cinfo
 type FixWfC   = F.WfC Cinfo
 
+
+subVar :: FixSubC -> Maybe Var 
+subVar = ci_var . F.sinfo
+
 instance PPrint SubC where
-  -- pprint c = pprint (senv c)
-  --           $+$ (text " |- " <+> (pprint (lhs c) $+$
-  --                                 text "<:"      $+$
-  --                                 pprint (rhs c)))
   pprintTidy k c@(SubC {}) = pprintTidy k (senv c)
-                       $+$ ("||-" <+> vcat [ pprintTidy k (lhs c)
-                                           , "<:"
-                                           , pprintTidy k (rhs c) ] )
+                             $+$ ("||-" <+> vcat [ pprintTidy k (lhs c)
+                                                 , "<:"
+                                                 , pprintTidy k (rhs c) ] )
   pprintTidy k c@(SubR {}) = pprintTidy k (senv c)
-                       $+$ ("||-" <+> vcat [ pprintTidy k (ref c)
-                                           , parens (pprintTidy k (oblig c))])
+                             $+$ ("||-" <+> vcat [ pprintTidy k (ref c)
+                                                 , parens (pprintTidy k (oblig c))])
 
 
 instance PPrint WfC where
   pprintTidy k (WfC _ r) = {- pprintTidy k w <> text -} "<...> |-" <+> pprintTidy k r
 
+
 instance SubStratum SubC where
   subS su (SubC γ t1 t2) = SubC γ (subS su t1) (subS su t2)
   subS _  c              = c
@@ -181,29 +184,34 @@
   , annotMap   :: !(AnnInfo (Annot SpecType))  -- ^ source-position annotation map
   , tyConInfo  :: !(M.HashMap TC.TyCon RTyCon) -- ^ information about type-constructors
   , specDecr   :: ![(Var, [Int])]              -- ^ ? FIX THIS
-  , termExprs  :: !(M.HashMap Var [F.Expr])    -- ^ Terminating Metrics for Recursive functions
+  , newTyEnv   :: !(M.HashMap TC.TyCon SpecType)        -- ^ Mapping of new type type constructors with their refined types.
+  , termExprs  :: !(M.HashMap Var [F.Located F.Expr])   -- ^ Terminating Metrics for Recursive functions
   , specLVars  :: !(S.HashSet Var)             -- ^ Set of variables to ignore for termination checking
-  , specLazy   :: !(S.HashSet Var)             -- ^ ? FIX THIS
+  , specLazy   :: !(S.HashSet Var)             -- ^ "Lazy binders", skip termination checking
   , autoSize   :: !(S.HashSet TC.TyCon)        -- ^ ? FIX THIS
   , tyConEmbed :: !(F.TCEmb TC.TyCon)          -- ^ primitive Sorts into which TyCons should be embedded
   , kuts       :: !F.Kuts                      -- ^ Fixpoint Kut variables (denoting "back-edges"/recursive KVars)
-  , lits       :: ![(F.Symbol, F.Sort)]        -- ^ ? FIX THIS
+  , kvPacks    :: ![S.HashSet F.KVar]          -- ^ Fixpoint "packs" of correlated kvars
+  , cgLits     :: !(F.SEnv F.Sort)             -- ^ Global symbols in the refinement logic
+  , cgConsts   :: !(F.SEnv F.Sort)             -- ^ Distinct constant symbols in the refinement logic
   , tcheck     :: !Bool                        -- ^ Check Termination (?)
   , scheck     :: !Bool                        -- ^ Check Strata (?)
-  , trustghc   :: !Bool                        -- ^ Trust ghc auto generated bindings
   , pruneRefs  :: !Bool                        -- ^ prune unsorted refinements
   , logErrors  :: ![Error]                     -- ^ Errors during constraint generation
   , kvProf     :: !KVProf                      -- ^ Profiling distribution of KVars
   , recCount   :: !Int                         -- ^ number of recursive functions seen (for benchmarks)
   , bindSpans  :: M.HashMap F.BindId SrcSpan   -- ^ Source Span associated with Fixpoint Binder
-  , allowHO    :: !Bool  
+  , allowHO    :: !Bool
+  , ghcI       :: !GhcInfo
+  , dataConTys :: ![(Var, SpecType)]           -- ^ Refined Types of Data Constructors
   }
 
 instance PPrint CGInfo where
-  pprintTidy _ cgi =  {-# SCC "ppr_CGI" #-} pprCGInfo cgi
+  pprintTidy = pprCGInfo
 
-pprCGInfo _cgi
-  =  text "*********** Constraint Information ***********"
+pprCGInfo :: F.Tidy -> CGInfo -> Doc
+pprCGInfo _k _cgi
+  =  "*********** Constraint Information (omitted) *************"
   -- -$$ (text "*********** Haskell SubConstraints ***********")
   -- -$$ (pprintLongList $ hsCs  cgi)
   -- -$$ (text "*********** Haskell WFConstraints ************")
@@ -214,8 +222,8 @@
   -- -$$ (F.toFix  $ fixWfs cgi)
   -- -$$ (text "*********** Fixpoint Kut Variables ************")
   -- -$$ (F.toFix  $ kuts cgi)
-  -- -$$ (text "*********** Literals in Source     ************")
-  -- -$$ (pprint $ lits cgi)
+  -- -$$ "*********** Literals in Source     ************"
+  -- -$$ F.pprint (cgLits _cgi)
   -- -$$ (text "*********** KVar Distribution *****************")
   -- -$$ (pprint $ kvProf cgi)
   -- -$$ (text "Recursive binders:" <+> pprint (recCount cgi))
@@ -227,36 +235,84 @@
 
 newtype HEnv = HEnv (S.HashSet F.Symbol)
 
+fromListHEnv :: [F.Symbol] -> HEnv
 fromListHEnv = HEnv . S.fromList
+
+elemHEnv :: F.Symbol -> HEnv -> Bool
 elemHEnv x (HEnv s) = x `S.member` s
 
 --------------------------------------------------------------------------------
 -- | Helper Types: Invariants --------------------------------------------------
 --------------------------------------------------------------------------------
+data RInv = RInv { _rinv_args :: [RSort]   -- empty list means that the invariant is generic
+                                           -- for all type arguments
+                 , _rinv_type :: SpecType
+                 , _rinv_name :: Maybe Var
+                 } deriving Show
 
-type RTyConInv = M.HashMap RTyCon [SpecType]
-type RTyConIAl = M.HashMap RTyCon [SpecType]
+type RTyConInv = M.HashMap RTyCon [RInv]
+type RTyConIAl = M.HashMap RTyCon [RInv]
 
+
+addArgument :: CGEnv -> Var -> CGEnv
+addArgument γ v
+ | higherOrderFlag γ
+ = γ {fargs = S.insert v (fargs γ) }
+ | otherwise
+ = γ
+
+addArguments :: CGEnv -> [Var] -> CGEnv
+addArguments γ vs
+ | higherOrderFlag γ
+ = foldl addArgument γ vs
+ | otherwise
+ = γ
+
 --------------------------------------------------------------------------------
-mkRTyConInv    :: [F.Located SpecType] -> RTyConInv
+mkRTyConInv    :: [(Maybe Var, F.Located SpecType)] -> RTyConInv
 --------------------------------------------------------------------------------
-mkRTyConInv ts = group [ (c, t) | t@(RApp c _ _ _) <- strip <$> ts]
+mkRTyConInv ts = group [ (c, RInv (go ts) t v) | (v, t@(RApp c ts _ _)) <- strip <$> ts]
   where
-    strip      = fourth4 . bkUniv . val
+    strip = mapSnd (fourth4 . bkUniv . val)
+    go ts | generic (toRSort <$> ts) = []
+          | otherwise                = toRSort <$> ts
 
-mkRTyConIAl    = mkRTyConInv . fmap snd
+    generic ts = let ts' = L.nub ts in
+                 all isRVar ts' && length ts' == length ts
 
+mkRTyConIAl :: [(a, F.Located SpecType)] -> RTyConInv
+mkRTyConIAl    = mkRTyConInv . fmap ((Nothing,) . snd)
+
 addRTyConInv :: RTyConInv -> SpecType -> SpecType
-addRTyConInv m t@(RApp c _ _ _)
-  = case M.lookup c m of
+addRTyConInv m t
+  = case lookupRInv t m of
       Nothing -> t
-      Just ts -> L.foldl' conjoinInvariantShift  t ts
-addRTyConInv _ t
-  = t
+      Just ts -> L.foldl' conjoinInvariantShift t ts
 
+lookupRInv :: SpecType -> RTyConInv -> Maybe [SpecType]
+lookupRInv (RApp c ts _ _) m
+  = case M.lookup c m of
+      Nothing   -> Nothing
+      Just invs -> Just (catMaybes $ goodInvs ts <$> invs)
+lookupRInv _ _
+  = Nothing
+
+goodInvs :: [SpecType] -> RInv -> Maybe SpecType
+goodInvs _ (RInv []  t _)
+  = Just t
+goodInvs ts (RInv ts' t _)
+  | and (zipWith unifiable ts' (toRSort <$> ts))
+  = Just t
+  | otherwise
+  = Nothing
+
+
+unifiable :: RSort -> RSort -> Bool
+unifiable t1 t2 = isJust $ tcUnifyTy (toType t1) (toType t2)
+
 addRInv :: RTyConInv -> (Var, SpecType) -> (Var, SpecType)
 addRInv m (x, t)
-  | x `elem` ids , (RApp c _ _ _) <- res t, Just invs <- M.lookup c m
+  | x `elem` ids , Just invs <- lookupRInv (res t) m
   = (x, addInvCond t (mconcat $ catMaybes (stripRTypeBase <$> invs)))
   | otherwise
   = (x, t)
@@ -266,9 +322,11 @@
                , id <- DC.dataConImplicitIds dc]
      res = ty_res . toRTypeRep
 
+conjoinInvariantShift :: SpecType -> SpecType -> SpecType
 conjoinInvariantShift t1 t2
   = conjoinInvariant t1 (shiftVV t2 (rTypeValueVar t1))
 
+conjoinInvariant :: SpecType -> SpecType -> SpecType
 conjoinInvariant (RApp c ts rs r) (RApp ic its _ ir)
   | c == ic && length ts == length its
   = RApp c (zipWith conjoinInvariantShift ts its) rs (r `F.meet` ir)
@@ -282,33 +340,87 @@
 conjoinInvariant t _
   = t
 
+removeInvariant  :: CGEnv -> CoreBind -> (CGEnv, RTyConInv)
+removeInvariant γ cbs
+  = (γ { invs  = M.map (filter f) (invs γ)
+       , rinvs = M.map (filter (not . f)) (invs γ)}
+    , invs γ)
+  where
+    f i | Just v  <- _rinv_name i, v `elem` binds cbs
+        = False
+        | otherwise
+        = True
+    binds (NonRec x _) = [x]
+    binds (Rec xes)    = fst $ unzip xes
+
+restoreInvariant :: CGEnv -> RTyConInv -> CGEnv
+restoreInvariant γ is = γ {invs = is}
+
+makeRecInvariants :: CGEnv -> [Var] -> CGEnv
+makeRecInvariants γ [x] = γ {invs = M.unionWith (++) (invs γ) is}
+  where
+    is  =  M.map (map f . filter (isJust . (varType x `tcUnifyTy`) . toType . _rinv_type)) (rinvs γ)
+    f i = i{_rinv_type = guard $ _rinv_type i}
+
+    guard (RApp c ts rs r)
+      | Just f <- szFun <$> sizeFunction (rtc_info c)
+      = RApp c ts rs (MkUReft (ref f $ F.toReft r) mempty mempty)
+      | otherwise
+      = RApp c ts rs mempty
+    guard t
+      = t
+
+    ref f (F.Reft(v, rr))
+      = F.Reft (v, F.PImp (F.PAtom F.Lt (f v) (f $ F.symbol x)) rr)
+
+makeRecInvariants γ _ = γ
+
 --------------------------------------------------------------------------------
 -- | Fixpoint Environment ------------------------------------------------------
 --------------------------------------------------------------------------------
 
-data FEnv = FE { feBinds :: !F.IBindEnv      -- ^ Integer Keys for Fixpoint Environment
-               , feEnv   :: !(F.SEnv F.Sort) -- ^ Fixpoint Environment
-               }
+data FEnv = FE
+  { feBinds :: !F.IBindEnv        -- ^ Integer Keys for Fixpoint Environment
+  , feEnv   :: !(F.SEnv F.Sort)   -- ^ Fixpoint Environment
+  , feIdEnv :: !(F.SEnv F.BindId) -- ^ Map from Symbol to current BindId
+  }
 
-insertFEnv (FE benv env) ((x, t), i)
-  = FE (F.insertsIBindEnv [i] benv) (F.insertSEnv x t env)
+insertFEnv :: FEnv -> ((F.Symbol, F.Sort), F.BindId) -> FEnv
+insertFEnv (FE benv env ienv) ((x, t), i)
+  = FE (F.insertsIBindEnv [i] benv)
+       (F.insertSEnv x t      env)
+       (F.insertSEnv x i      ienv)
 
 insertsFEnv :: FEnv -> [((F.Symbol, F.Sort), F.BindId)] -> FEnv
 insertsFEnv = L.foldl' insertFEnv
 
-initFEnv xts = FE F.emptyIBindEnv $ F.fromListSEnv (wiredSortedSyms ++ xts)
+initFEnv :: [(F.Symbol, F.Sort)] -> FEnv
+initFEnv xts = FE benv0 env0 ienv0
+  where
+    benv0    = F.emptyIBindEnv
+    env0     = F.fromListSEnv (wiredSortedSyms ++ xts)
+    ienv0    = F.emptySEnv
 
 --------------------------------------------------------------------------------
 -- | Forcing Strictness --------------------------------------------------------
 --------------------------------------------------------------------------------
+instance NFData RInv where
+  rnf (RInv x y z) = rnf x `seq` rnf y `seq` rnf z
 
 instance NFData CGEnv where
-  rnf (CGE x1 _ x3 _ x5 x6 x7 x8 x9 _ _ _ x10 _ _ _ _ _ _ _)
-    = x1 `seq` {- rnf x2 `seq` -} seq x3 `seq` rnf x5 `seq`
-      rnf x6  `seq` x7 `seq` rnf x8 `seq` rnf x9 `seq` rnf x10
+  rnf (CGE x1 _ x3 _ x4 x5 x55 x6 x7 x8 x9 _ _ _ x10 _ _ _ _ _ _ _ _ _ _ _)
+    = x1 `seq` {- rnf x2 `seq` -} seq x3
+         `seq` rnf x5
+         `seq` rnf x55
+         `seq` rnf x6
+         `seq` x7
+         `seq` rnf x8
+         `seq` rnf x9
+         `seq` rnf x10
+         `seq` rnf x4
 
 instance NFData FEnv where
-  rnf (FE x1 _) = rnf x1
+  rnf (FE x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3
 
 instance NFData SubC where
   rnf (SubC x1 x2 x3)
@@ -329,5 +441,7 @@
           ({-# SCC "CGIrnf7" #-}  rnf (binds x))      `seq`
           ({-# SCC "CGIrnf8" #-}  rnf (annotMap x))   `seq`
           ({-# SCC "CGIrnf10" #-} rnf (kuts x))       `seq`
-          ({-# SCC "CGIrnf10" #-} rnf (lits x))       `seq`
+          ({-# SCC "CGIrnf10" #-} rnf (kvPacks x))    `seq`
+          ({-# SCC "CGIrnf10" #-} rnf (cgLits x))     `seq`
+          ({-# SCC "CGIrnf10" #-} rnf (cgConsts x))   `seq`
           ({-# SCC "CGIrnf10" #-} rnf (kvProf x))
diff --git a/src/Language/Haskell/Liquid/Desugar710/Check.hs b/src/Language/Haskell/Liquid/Desugar710/Check.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/Check.hs
+++ /dev/null
@@ -1,774 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1997-1998
-
-Author: Juan J. Quintela    <quintela@krilin.dc.fi.udc.es>
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.Check ( check , ExhaustivePat ) where
-
--- #include "HsVersions.h"
-
-import Prelude hiding (error)
-import HsSyn
-import TcHsSyn
-import Language.Haskell.Liquid.Desugar710.DsUtils
-import Language.Haskell.Liquid.Desugar710.MatchLit
-import Id
-import ConLike
-import DataCon
-import PatSyn
-import Name
-import TysWiredIn
-import PrelNames
-import TyCon
-import SrcLoc
-import UniqSet
-import Util
-import BasicTypes
-import Outputable
-import FastString
-
-{-
-This module performs checks about if one list of equations are:
-\begin{itemize}
-\item Overlapped
-\item Non exhaustive
-\end{itemize}
-To discover that we go through the list of equations in a tree-like fashion.
-
-If you like theory, a similar algorithm is described in:
-\begin{quotation}
-        {\em Two Techniques for Compiling Lazy Pattern Matching},
-        Luc Maranguet,
-        INRIA Rocquencourt (RR-2385, 1994)
-\end{quotation}
-The algorithm is based on the first technique, but there are some differences:
-\begin{itemize}
-\item We don't generate code
-\item We have constructors and literals (not only literals as in the
-          article)
-\item We don't use directions, we must select the columns from
-          left-to-right
-\end{itemize}
-(By the way the second technique is really similar to the one used in
- @Match.lhs@ to generate code)
-
-This function takes the equations of a pattern and returns:
-\begin{itemize}
-\item The patterns that are not recognized
-\item The equations that are not overlapped
-\end{itemize}
-It simplify the patterns and then call @check'@ (the same semantics), and it
-needs to reconstruct the patterns again ....
-
-The problem appear with things like:
-\begin{verbatim}
-  f [x,y]   = ....
-  f (x:xs)  = .....
-\end{verbatim}
-We want to put the two patterns with the same syntax, (prefix form) and
-then all the constructors are equal:
-\begin{verbatim}
-  f (: x (: y []))   = ....
-  f (: x xs)         = .....
-\end{verbatim}
-(more about that in @tidy_eqns@)
-
-We would prefer to have a @WarningPat@ of type @String@, but Strings and the
-Pretty Printer are not friends.
-
-We use @InPat@ in @WarningPat@ instead of @OutPat@
-because we need to print the
-warning messages in the same way they are introduced, i.e. if the user
-wrote:
-\begin{verbatim}
-        f [x,y] = ..
-\end{verbatim}
-He don't want a warning message written:
-\begin{verbatim}
-        f (: x (: y [])) ........
-\end{verbatim}
-Then we need to use InPats.
-\begin{quotation}
-     Juan Quintela 5 JUL 1998\\
-          User-friendliness and compiler writers are no friends.
-\end{quotation}
--}
-
-type WarningPat = InPat Name
-type ExhaustivePat = ([WarningPat], [(Name, [HsLit])])
-type EqnNo  = Int
-type EqnSet = UniqSet EqnNo
-
-
-check :: [EquationInfo] -> ([ExhaustivePat], [EquationInfo])
-  -- Second result is the shadowed equations
-  -- if there are view patterns, just give up - don't know what the function is
-check qs = (untidy_warns, shadowed_eqns)
-      where
-        tidy_qs = map tidy_eqn qs
-        (warns, used_nos) = check' ([1..] `zip` tidy_qs)
-        untidy_warns = map untidy_exhaustive warns
-        shadowed_eqns = [eqn | (eqn,i) <- qs `zip` [1..],
-                                not (i `elementOfUniqSet` used_nos)]
-
-untidy_exhaustive :: ExhaustivePat -> ExhaustivePat
-untidy_exhaustive ([pat], messages) =
-                  ([untidy_no_pars pat], map untidy_message messages)
-untidy_exhaustive (pats, messages) =
-                  (map untidy_pars pats, map untidy_message messages)
-
-untidy_message :: (Name, [HsLit]) -> (Name, [HsLit])
-untidy_message (string, lits) = (string, map untidy_lit lits)
-
--- The function @untidy@ does the reverse work of the @tidy_pat@ function.
-
-type NeedPars = Bool
-
-untidy_no_pars :: WarningPat -> WarningPat
-untidy_no_pars p = untidy False p
-
-untidy_pars :: WarningPat -> WarningPat
-untidy_pars p = untidy True p
-
-untidy :: NeedPars -> WarningPat -> WarningPat
-untidy b (L loc p) = L loc (untidy' b p)
-  where
-    untidy' _ p@(WildPat _)          = p
-    untidy' _ p@(VarPat _)           = p
-    untidy' _ (LitPat lit)           = LitPat (untidy_lit lit)
-    untidy' _ p@(ConPatIn _ (PrefixCon [])) = p
-    untidy' b (ConPatIn name ps)     = pars b (L loc (ConPatIn name (untidy_con ps)))
-    untidy' _ (ListPat pats ty Nothing)     = ListPat (map untidy_no_pars pats) ty Nothing
-    untidy' _ (TuplePat pats box tys) = TuplePat (map untidy_no_pars pats) box tys
-    untidy' _ (ListPat _ _ (Just _)) = panic "Check.untidy: Overloaded ListPat"
-    untidy' _ (PArrPat _ _)          = panic "Check.untidy: Shouldn't get a parallel array here!"
-    untidy' _ (SigPatIn _ _)         = panic "Check.untidy: SigPat"
-    untidy' _ (LazyPat {})           = panic "Check.untidy: LazyPat"
-    untidy' _ (AsPat {})             = panic "Check.untidy: AsPat"
-    untidy' _ (ParPat {})            = panic "Check.untidy: ParPat"
-    untidy' _ (BangPat {})           = panic "Check.untidy: BangPat"
-    untidy' _ (ConPatOut {})         = panic "Check.untidy: ConPatOut"
-    untidy' _ (ViewPat {})           = panic "Check.untidy: ViewPat"
-    untidy' _ (SplicePat {})         = panic "Check.untidy: SplicePat"
-    untidy' _ (QuasiQuotePat {})     = panic "Check.untidy: QuasiQuotePat"
-    untidy' _ (NPat {})              = panic "Check.untidy: NPat"
-    untidy' _ (NPlusKPat {})         = panic "Check.untidy: NPlusKPat"
-    untidy' _ (SigPatOut {})         = panic "Check.untidy: SigPatOut"
-    untidy' _ (CoPat {})             = panic "Check.untidy: CoPat"
-
-untidy_con :: HsConPatDetails Name -> HsConPatDetails Name
-untidy_con (PrefixCon pats) = PrefixCon (map untidy_pars pats)
-untidy_con (InfixCon p1 p2) = InfixCon  (untidy_pars p1) (untidy_pars p2)
-untidy_con (RecCon (HsRecFields flds dd))
-  = RecCon (HsRecFields [ L l (fld { hsRecFieldArg
-                                            = untidy_pars (hsRecFieldArg fld) })
-                        | L l fld <- flds ] dd)
-
-pars :: NeedPars -> WarningPat -> Pat Name
-pars True p = ParPat p
-pars _    p = unLoc p
-
-untidy_lit :: HsLit -> HsLit
-untidy_lit (HsCharPrim src c) = HsChar src c
-untidy_lit lit                = lit
-
-{-
-This equation is the same that check, the only difference is that the
-boring work is done, that work needs to be done only once, this is
-the reason top have two functions, check is the external interface,
-@check'@ is called recursively.
-
-There are several cases:
-
-\begin{itemize}
-\item There are no equations: Everything is OK.
-\item There are only one equation, that can fail, and all the patterns are
-      variables. Then that equation is used and the same equation is
-      non-exhaustive.
-\item All the patterns are variables, and the match can fail, there are
-      more equations then the results is the result of the rest of equations
-      and this equation is used also.
-
-\item The general case, if all the patterns are variables (here the match
-      can't fail) then the result is that this equation is used and this
-      equation doesn't generate non-exhaustive cases.
-
-\item In the general case, there can exist literals ,constructors or only
-      vars in the first column, we actuate in consequence.
-
-\end{itemize}
--}
-
-check' :: [(EqnNo, EquationInfo)]
-        -> ([ExhaustivePat],    -- Pattern scheme that might not be matched at all
-            EqnSet)             -- Eqns that are used (others are overlapped)
-
-check' [] = ([],emptyUniqSet)
-  -- Was    ([([],[])], emptyUniqSet)
-  -- But that (a) seems weird, and (b) triggered Trac #7669
-  -- So now I'm just doing the simple obvious thing
-
-check' ((n, EqnInfo { eqn_pats = ps, eqn_rhs = MatchResult can_fail _ }) : rs)
-   | first_eqn_all_vars && case can_fail of { CantFail -> True; CanFail -> False }
-   = ([], unitUniqSet n)        -- One eqn, which can't fail
-
-   | first_eqn_all_vars && null rs      -- One eqn, but it can fail
-   = ([(takeList ps (repeat nlWildPatName),[])], unitUniqSet n)
-
-   | first_eqn_all_vars         -- Several eqns, first can fail
-   = (pats, addOneToUniqSet indexs n)
-  where
-    first_eqn_all_vars = all_vars ps
-    (pats,indexs) = check' rs
-
-check' qs
-   | some_literals     = split_by_literals qs
-   | some_constructors = split_by_constructor qs
-   | only_vars         = first_column_only_vars qs
-   | otherwise = pprPanic "Check.check': Not implemented :-(" (ppr first_pats)
-                 -- Shouldn't happen
-  where
-     -- Note: RecPats will have been simplified to ConPats
-     --       at this stage.
-    first_pats        = {- ASSERT2( okGroup qs, pprGroup qs ) -} map firstPatN qs
-    some_constructors = any is_con first_pats
-    some_literals     = any is_lit first_pats
-    only_vars         = all is_var first_pats
-
-{-
-Here begins the code to deal with literals, we need to split the matrix
-in different matrix beginning by each literal and a last matrix with the
-rest of values.
--}
-
-split_by_literals :: [(EqnNo, EquationInfo)] -> ([ExhaustivePat], EqnSet)
-split_by_literals qs = process_literals used_lits qs
-           where
-             used_lits = get_used_lits qs
-
-{-
-@process_explicit_literals@ is a function that process each literal that appears
-in the column of the matrix.
--}
-
-process_explicit_literals :: [HsLit] -> [(EqnNo, EquationInfo)] -> ([ExhaustivePat],EqnSet)
-process_explicit_literals lits qs = (concat pats, unionManyUniqSets indexs)
-    where
-      pats_indexs   = map (\x -> construct_literal_matrix x qs) lits
-      (pats,indexs) = unzip pats_indexs
-
-{-
-@process_literals@ calls @process_explicit_literals@ to deal with the literals
-that appears in the matrix and deal also with the rest of the cases. It
-must be one Variable to be complete.
--}
-
-process_literals :: [HsLit] -> [(EqnNo, EquationInfo)] -> ([ExhaustivePat],EqnSet)
-process_literals used_lits qs
-  | null default_eqns  = {- ASSERT( not (null qs) ) -} ([make_row_vars used_lits (head qs)] ++ pats,indexs)
-  | otherwise          = (pats_default,indexs_default)
-     where
-       (pats,indexs)   = process_explicit_literals used_lits qs
-       default_eqns    = -- ASSERT2( okGroup qs, pprGroup qs )
-                         [remove_var q | q <- qs, is_var (firstPatN q)]
-       (pats',indexs') = check' default_eqns
-       pats_default    = [(nlWildPatName:ps,constraints) |
-                                        (ps,constraints) <- (pats')] ++ pats
-       indexs_default  = unionUniqSets indexs' indexs
-
-{-
-Here we have selected the literal and we will select all the equations that
-begins for that literal and create a new matrix.
--}
-
-construct_literal_matrix :: HsLit -> [(EqnNo, EquationInfo)] -> ([ExhaustivePat],EqnSet)
-construct_literal_matrix lit qs =
-    (map (\ (xs,ys) -> (new_lit:xs,ys)) pats,indexs)
-  where
-    (pats,indexs) = (check' (remove_first_column_lit lit qs))
-    new_lit = nlLitPat lit
-
-remove_first_column_lit :: HsLit
-                        -> [(EqnNo, EquationInfo)]
-                        -> [(EqnNo, EquationInfo)]
-remove_first_column_lit lit qs
-  = -- ASSERT2( okGroup qs, pprGroup qs )
-    [(n, shift_pat eqn) | q@(n,eqn) <- qs, is_var_lit lit (firstPatN q)]
-  where
-     shift_pat eqn@(EqnInfo { eqn_pats = _:ps}) = eqn { eqn_pats = ps }
-     shift_pat _                                = panic "Check.shift_var: no patterns"
-
-{-
-This function splits the equations @qs@ in groups that deal with the
-same constructor.
--}
-
-split_by_constructor :: [(EqnNo, EquationInfo)] -> ([ExhaustivePat], EqnSet)
-split_by_constructor qs
-  | null used_cons      = ([], mkUniqSet $ map fst qs)
-  | notNull unused_cons = need_default_case used_cons unused_cons qs
-  | otherwise           = no_need_default_case used_cons qs
-                       where
-                          used_cons   = get_used_cons qs
-                          unused_cons = get_unused_cons used_cons
-
-{-
-The first column of the patterns matrix only have vars, then there is
-nothing to do.
--}
-
-first_column_only_vars :: [(EqnNo, EquationInfo)] -> ([ExhaustivePat],EqnSet)
-first_column_only_vars qs
-  = (map (\ (xs,ys) -> (nlWildPatName:xs,ys)) pats,indexs)
-  where
-    (pats, indexs) = check' (map remove_var qs)
-
-{-
-This equation takes a matrix of patterns and split the equations by
-constructor, using all the constructors that appears in the first column
-of the pattern matching.
-
-We can need a default clause or not ...., it depends if we used all the
-constructors or not explicitly. The reasoning is similar to @process_literals@,
-the difference is that here the default case is not always needed.
--}
-
-no_need_default_case :: [Pat Id] -> [(EqnNo, EquationInfo)] -> ([ExhaustivePat],EqnSet)
-no_need_default_case cons qs = (concat pats, unionManyUniqSets indexs)
-    where
-      pats_indexs   = map (\x -> construct_matrix x qs) cons
-      (pats,indexs) = unzip pats_indexs
-
-need_default_case :: [Pat Id] -> [DataCon] -> [(EqnNo, EquationInfo)] -> ([ExhaustivePat],EqnSet)
-need_default_case used_cons unused_cons qs
-  | null default_eqns  = (pats_default_no_eqns,indexs)
-  | otherwise          = (pats_default,indexs_default)
-     where
-       (pats,indexs)   = no_need_default_case used_cons qs
-       default_eqns    = -- ASSERT2( okGroup qs, pprGroup qs )
-                         [remove_var q | q <- qs, is_var (firstPatN q)]
-       (pats',indexs') = check' default_eqns
-       pats_default    = [(make_whole_con c:ps,constraints) |
-                          c <- unused_cons, (ps,constraints) <- pats'] ++ pats
-       new_wilds       = {- ASSERT( not (null qs) ) -} make_row_vars_for_constructor (head qs)
-       pats_default_no_eqns =  [(make_whole_con c:new_wilds,[]) | c <- unused_cons] ++ pats
-       indexs_default  = unionUniqSets indexs' indexs
-
-construct_matrix :: Pat Id -> [(EqnNo, EquationInfo)] -> ([ExhaustivePat],EqnSet)
-construct_matrix con qs =
-    (map (make_con con) pats,indexs)
-  where
-    (pats,indexs) = (check' (remove_first_column con qs))
-
-{-
-Here remove first column is more difficult that with literals due to the fact
-that constructors can have arguments.
-
-For instance, the matrix
-\begin{verbatim}
- (: x xs) y
- z        y
-\end{verbatim}
-is transformed in:
-\begin{verbatim}
- x xs y
- _ _  y
-\end{verbatim}
--}
-
-remove_first_column :: Pat Id                -- Constructor
-                    -> [(EqnNo, EquationInfo)]
-                    -> [(EqnNo, EquationInfo)]
-remove_first_column (ConPatOut{ pat_con = L _ con, pat_args = PrefixCon con_pats }) qs
-  = --  ASSERT2( okGroup qs, pprGroup qs )
-    [(n, shift_var eqn) | q@(n, eqn) <- qs, is_var_con con (firstPatN q)]
-  where
-     new_wilds = [WildPat (hsLPatType arg_pat) | arg_pat <- con_pats]
-     shift_var eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_args = PrefixCon ps' } : ps})
-        = eqn { eqn_pats = map unLoc ps' ++ ps }
-     shift_var eqn@(EqnInfo { eqn_pats = WildPat _ : ps })
-        = eqn { eqn_pats = new_wilds ++ ps }
-     shift_var _ = panic "Check.Shift_var:No done"
-remove_first_column _ _ = panic "Check.remove_first_column: Not ConPatOut"
-
-make_row_vars :: [HsLit] -> (EqnNo, EquationInfo) -> ExhaustivePat
-make_row_vars used_lits (_, EqnInfo { eqn_pats = pats})
-   = (nlVarPat new_var:takeList (tail pats) (repeat nlWildPatName)
-     ,[(new_var,used_lits)])
-  where
-     new_var = hash_x
-
-hash_x :: Name
-hash_x = mkInternalName unboundKey {- doesn't matter much -}
-                     (mkVarOccFS (fsLit "#x"))
-                     noSrcSpan
-
-make_row_vars_for_constructor :: (EqnNo, EquationInfo) -> [WarningPat]
-make_row_vars_for_constructor (_, EqnInfo { eqn_pats = pats})
-  = takeList (tail pats) (repeat nlWildPatName)
-
-compare_cons :: Pat Id -> Pat Id -> Bool
-compare_cons (ConPatOut{ pat_con = L _ con1 }) (ConPatOut{ pat_con = L _ con2 })
-  = case (con1, con2) of
-    (RealDataCon id1, RealDataCon id2) -> id1 == id2
-    _ -> False
-compare_cons _ _ = panic "Check.compare_cons: Not ConPatOut with RealDataCon"
-
-remove_dups :: [Pat Id] -> [Pat Id]
-remove_dups []     = []
-remove_dups (x:xs) | any (\y -> compare_cons x y) xs = remove_dups  xs
-                   | otherwise                       = x : remove_dups xs
-
-get_used_cons :: [(EqnNo, EquationInfo)] -> [Pat Id]
-get_used_cons qs = remove_dups [pat | q <- qs, let pat = firstPatN q,
-                                      isConPatOut pat]
-
-isConPatOut :: Pat Id -> Bool
-isConPatOut ConPatOut{ pat_con = L _ RealDataCon{} } = True
-isConPatOut _                                        = False
-
-remove_dups' :: [HsLit] -> [HsLit]
-remove_dups' []                   = []
-remove_dups' (x:xs) | x `elem` xs = remove_dups' xs
-                    | otherwise   = x : remove_dups' xs
-
-
-get_used_lits :: [(EqnNo, EquationInfo)] -> [HsLit]
-get_used_lits qs = remove_dups' all_literals
-                 where
-                   all_literals = get_used_lits' qs
-
-get_used_lits' :: [(EqnNo, EquationInfo)] -> [HsLit]
-get_used_lits' [] = []
-get_used_lits' (q:qs)
-  | Just lit <- get_lit (firstPatN q) = lit : get_used_lits' qs
-  | otherwise                         = get_used_lits qs
-
-get_lit :: Pat id -> Maybe HsLit
--- Get a representative HsLit to stand for the OverLit
--- It doesn't matter which one, because they will only be compared
--- with other HsLits gotten in the same way
-get_lit (LitPat lit)                                      = Just lit
-get_lit (NPat (L _ (OverLit { ol_val = HsIntegral src i}))    mb _)
-                        = Just (HsIntPrim src (mb_neg negate              mb i))
-get_lit (NPat (L _ (OverLit { ol_val = HsFractional f })) mb _)
-                        = Just (HsFloatPrim (mb_neg negateFractionalLit mb f))
-get_lit (NPat (L _ (OverLit { ol_val = HsIsString src s }))   _  _)
-                        = Just (HsStringPrim src (fastStringToByteString s))
-get_lit _                                                 = Nothing
-
-mb_neg :: (a -> a) -> Maybe b -> a -> a
-mb_neg _      Nothing  v = v
-mb_neg negate (Just _) v = negate v
-
-get_unused_cons :: [Pat Id] -> [DataCon]
-get_unused_cons used_cons = {- ASSERT( not (null used_cons) ) -} unused_cons
-     where
-       used_set :: UniqSet DataCon
-       used_set = mkUniqSet [d | ConPatOut{ pat_con = L _ (RealDataCon d) } <- used_cons]
-       (ConPatOut { pat_con = L _ (RealDataCon con1), pat_arg_tys = inst_tys }) = head used_cons
-       ty_con      = dataConTyCon con1
-       unused_cons = filterOut is_used (tyConDataCons ty_con)
-       is_used con = con `elementOfUniqSet` used_set
-                     || dataConCannotMatch inst_tys con
-
-all_vars :: [Pat Id] -> Bool
-all_vars []             = True
-all_vars (WildPat _:ps) = all_vars ps
-all_vars _              = False
-
-remove_var :: (EqnNo, EquationInfo) -> (EqnNo, EquationInfo)
-remove_var (n, eqn@(EqnInfo { eqn_pats = WildPat _ : ps})) = (n, eqn { eqn_pats = ps })
-remove_var _  = panic "Check.remove_var: equation does not begin with a variable"
-
------------------------
-{-
-eqnPats :: (EqnNo, EquationInfo) -> [Pat Id]
-eqnPats (_, eqn) = eqn_pats eqn
-okGroup :: [(EqnNo, EquationInfo)] -> Bool
--- True if all equations have at least one pattern, and
--- all have the same number of patterns
-okGroup [] = True
-okGroup (e:es) = n_pats > 0 && and [length (eqnPats e) == n_pats | e <- es]
-               where
-                 n_pats = length (eqnPats e)
--}
--- Half-baked print
--- pprGroup :: [(EqnNo, EquationInfo)] -> SDoc
--- pprEqnInfo :: (EqnNo, EquationInfo) -> SDoc
--- pprGroup es = vcat (map pprEqnInfo es)
--- pprEqnInfo e = ppr (eqnPats e)
-
-
-firstPatN :: (EqnNo, EquationInfo) -> Pat Id
-firstPatN (_, eqn) = firstPat eqn
-
-is_con :: Pat Id -> Bool
-is_con (ConPatOut {}) = True
-is_con _              = False
-
-is_lit :: Pat Id -> Bool
-is_lit (LitPat _)      = True
-is_lit (NPat _ _ _)  = True
-is_lit _               = False
-
-is_var :: Pat Id -> Bool
-is_var (WildPat _) = True
-is_var _           = False
-
-is_var_con :: ConLike -> Pat Id -> Bool
-is_var_con _   (WildPat _)                     = True
-is_var_con con (ConPatOut{ pat_con = L _ id }) = id == con
-is_var_con _   _                               = False
-
-is_var_lit :: HsLit -> Pat Id -> Bool
-is_var_lit _   (WildPat _)   = True
-is_var_lit lit pat
-  | Just lit' <- get_lit pat = lit == lit'
-  | otherwise                = False
-
-{-
-The difference beteewn @make_con@ and @make_whole_con@ is that
-@make_wole_con@ creates a new constructor with all their arguments, and
-@make_con@ takes a list of argumntes, creates the contructor getting their
-arguments from the list. See where \fbox{\ ???\ } are used for details.
-
-We need to reconstruct the patterns (make the constructors infix and
-similar) at the same time that we create the constructors.
-
-You can tell tuple constructors using
-\begin{verbatim}
-        Id.isTupleDataCon
-\end{verbatim}
-You can see if one constructor is infix with this clearer code :-))))))))))
-\begin{verbatim}
-        Lex.isLexConSym (Name.occNameString (Name.getOccName con))
-\end{verbatim}
-
-       Rather clumsy but it works. (Simon Peyton Jones)
-
-
-We don't mind the @nilDataCon@ because it doesn't change the way to
-print the message, we are searching only for things like: @[1,2,3]@,
-not @x:xs@ ....
-
-In @reconstruct_pat@ we want to ``undo'' the work
-that we have done in @tidy_pat@.
-In particular:
-\begin{tabular}{lll}
-        @((,) x y)@   & returns to be & @(x, y)@
-\\      @((:) x xs)@  & returns to be & @(x:xs)@
-\\      @(x:(...:[])@ & returns to be & @[x,...]@
-\end{tabular}
-
-The difficult case is the third one becouse we need to follow all the
-contructors until the @[]@ to know that we need to use the second case,
-not the second. \fbox{\ ???\ }
--}
-
-isInfixCon :: DataCon -> Bool
-isInfixCon con = isDataSymOcc (getOccName con)
-
-is_nil :: Pat Name -> Bool
-is_nil (ConPatIn con (PrefixCon [])) = unLoc con == getName nilDataCon
-is_nil _                             = False
-
-is_list :: Pat Name -> Bool
-is_list (ListPat _ _ Nothing) = True
-is_list _             = False
-
-return_list :: DataCon -> Pat Name -> Bool
-return_list id q = id == consDataCon && (is_nil q || is_list q)
-
-make_list :: LPat Name -> Pat Name -> Pat Name
-make_list p q | is_nil q    = ListPat [p] placeHolderType Nothing
-make_list p (ListPat ps ty Nothing) = ListPat (p:ps) ty Nothing
-make_list _ _               = panic "Check.make_list: Invalid argument"
-
-make_con :: Pat Id -> ExhaustivePat -> ExhaustivePat
-make_con (ConPatOut{ pat_con = L _ (RealDataCon id) }) (lp:lq:ps, constraints)
-     | return_list id q = (noLoc (make_list lp q) : ps, constraints)
-     | isInfixCon id    = (nlInfixConPat (getName id) lp lq : ps, constraints)
-   where q  = unLoc lq
-
-make_con (ConPatOut{ pat_con = L _ (RealDataCon id), pat_args = PrefixCon pats})
-         (ps, constraints)
-      | isTupleTyCon tc  = (noLoc (TuplePat pats_con (tupleTyConBoxity tc) [])
-                                : rest_pats, constraints)
-      | isPArrFakeCon id = (noLoc (PArrPat pats_con placeHolderType)
-                                : rest_pats, constraints)
-      | otherwise        = (nlConPatName name pats_con
-                                : rest_pats, constraints)
-    where
-        name                  = getName id
-        (pats_con, rest_pats) = splitAtList pats ps
-        tc                    = dataConTyCon id
-
-make_con _ _ = panic "Check.make_con: Not ConPatOut"
-
--- reconstruct parallel array pattern
---
---  * don't check for the type only; we need to make sure that we are really
---   dealing with one of the fake constructors and not with the real
---   representation
-
-make_whole_con :: DataCon -> WarningPat
-make_whole_con con | isInfixCon con = nlInfixConPat name
-                                           nlWildPatName nlWildPatName
-                   | otherwise      = nlConPatName name pats
-                where
-                  name   = getName con
-                  pats   = [nlWildPatName | _ <- dataConOrigArgTys con]
-
-{-
-------------------------------------------------------------------------
-                   Tidying equations
-------------------------------------------------------------------------
-
-tidy_eqn does more or less the same thing as @tidy@ in @Match.lhs@;
-that is, it removes syntactic sugar, reducing the number of cases that
-must be handled by the main checking algorithm.  One difference is
-that here we can do *all* the tidying at once (recursively), rather
-than doing it incrementally.
--}
-
-tidy_eqn :: EquationInfo -> EquationInfo
-tidy_eqn eqn = eqn { eqn_pats = map tidy_pat (eqn_pats eqn),
-                     eqn_rhs  = tidy_rhs (eqn_rhs eqn) }
-  where
-        -- Horrible hack.  The tidy_pat stuff converts "might-fail" patterns to
-        -- WildPats which of course loses the info that they can fail to match.
-        -- So we stick in a CanFail as if it were a guard.
-    tidy_rhs (MatchResult can_fail body)
-        | any might_fail_pat (eqn_pats eqn) = MatchResult CanFail body
-        | otherwise                         = MatchResult can_fail body
-
---------------
-might_fail_pat :: Pat Id -> Bool
--- Returns True of patterns that might fail (i.e. fall through) in a way
--- that is not covered by the checking algorithm.  Specifically:
---         NPlusKPat
---         ViewPat (if refutable)
---         ConPatOut of a PatSynCon
-
--- First the two special cases
-might_fail_pat (NPlusKPat {})                = True
-might_fail_pat (ViewPat _ p _)               = not (isIrrefutableHsPat p)
-
--- Now the recursive stuff
-might_fail_pat (ParPat p)                    = might_fail_lpat p
-might_fail_pat (AsPat _ p)                   = might_fail_lpat p
-might_fail_pat (SigPatOut p _ )              = might_fail_lpat p
-might_fail_pat (ListPat ps _ Nothing)        = any might_fail_lpat ps
-might_fail_pat (ListPat _ _ (Just _))      = True
-might_fail_pat (TuplePat ps _ _)             = any might_fail_lpat ps
-might_fail_pat (PArrPat ps _)                = any might_fail_lpat ps
-might_fail_pat (BangPat p)                   = might_fail_lpat p
-might_fail_pat (ConPatOut { pat_con = con, pat_args = ps })
-  = case unLoc con of
-    RealDataCon _dcon -> any might_fail_lpat (hsConPatArgs ps)
-    PatSynCon _psyn -> True
-
--- Finally the ones that are sure to succeed, or which are covered by the checking algorithm
-might_fail_pat (LazyPat _)                   = False -- Always succeeds
-might_fail_pat _                             = False -- VarPat, WildPat, LitPat, NPat
-
---------------
-might_fail_lpat :: LPat Id -> Bool
-might_fail_lpat (L _ p) = might_fail_pat p
-
---------------
-tidy_lpat :: LPat Id -> LPat Id
-tidy_lpat p = fmap tidy_pat p
-
---------------
-tidy_pat :: Pat Id -> Pat Id
-tidy_pat pat@(WildPat _)  = pat
-tidy_pat (VarPat id)      = WildPat (idType id)
-tidy_pat (ParPat p)       = tidy_pat (unLoc p)
-tidy_pat (LazyPat p)      = WildPat (hsLPatType p)      -- For overlap and exhaustiveness checking
-                                                        -- purposes, a ~pat is like a wildcard
-tidy_pat (BangPat p)      = tidy_pat (unLoc p)
-tidy_pat (AsPat _ p)      = tidy_pat (unLoc p)
-tidy_pat (SigPatOut p _)  = tidy_pat (unLoc p)
-tidy_pat (CoPat _ pat _)  = tidy_pat pat
-
--- These two are might_fail patterns, so we map them to
--- WildPats.  The might_fail_pat stuff arranges that the
--- guard says "this equation might fall through".
-tidy_pat (NPlusKPat id _ _ _) = WildPat (idType (unLoc id))
-tidy_pat (ViewPat _ _ ty)     = WildPat ty
-tidy_pat (ListPat _ _ (Just (ty,_))) = WildPat ty
-tidy_pat (ConPatOut { pat_con = L _ (PatSynCon syn), pat_arg_tys = tys })
-  = WildPat (patSynInstResTy syn tys)
-
-tidy_pat pat@(ConPatOut { pat_con = L _ con, pat_args = ps })
-  = pat { pat_args = tidy_con con ps }
-
-tidy_pat (ListPat ps ty Nothing)
-  = unLoc $ foldr (\ x y -> mkPrefixConPat consDataCon [x,y] [ty])
-                                  (mkNilPat ty)
-                                  (map tidy_lpat ps)
-
--- introduce fake parallel array constructors to be able to handle parallel
--- arrays with the existing machinery for constructor pattern
---
-tidy_pat (PArrPat ps ty)
-  = unLoc $ mkPrefixConPat (parrFakeCon (length ps))
-                           (map tidy_lpat ps)
-                           [ty]
-
-tidy_pat (TuplePat ps boxity tys)
-  = unLoc $ mkPrefixConPat (tupleCon (boxityNormalTupleSort boxity) arity)
-                           (map tidy_lpat ps) tys
-  where
-    arity = length ps
-
-tidy_pat (NPat (L _ lit) mb_neg eq) = tidyNPat tidy_lit_pat lit mb_neg eq
-tidy_pat (LitPat lit)         = tidy_lit_pat lit
-
-tidy_pat (ConPatIn {})        = panic "Check.tidy_pat: ConPatIn"
-tidy_pat (SplicePat {})       = panic "Check.tidy_pat: SplicePat"
-tidy_pat (QuasiQuotePat {})   = panic "Check.tidy_pat: QuasiQuotePat"
-tidy_pat (SigPatIn {})        = panic "Check.tidy_pat: SigPatIn"
-
-tidy_lit_pat :: HsLit -> Pat Id
--- Unpack string patterns fully, so we can see when they
--- overlap with each other, or even explicit lists of Chars.
-tidy_lit_pat lit
-  | HsString src s <- lit
-  = unLoc $ foldr (\c pat -> mkPrefixConPat consDataCon
-                                             [mkCharLitPat src c, pat] [charTy])
-                  (mkPrefixConPat nilDataCon [] [charTy]) (unpackFS s)
-  | otherwise
-  = tidyLitPat lit
-
------------------
-tidy_con :: ConLike -> HsConPatDetails Id -> HsConPatDetails Id
-tidy_con _   (PrefixCon ps)   = PrefixCon (map tidy_lpat ps)
-tidy_con _   (InfixCon p1 p2) = PrefixCon [tidy_lpat p1, tidy_lpat p2]
-tidy_con con (RecCon (HsRecFields fs _))
-  | null fs   = PrefixCon (replicate arity nlWildPatId)
-                -- Special case for null patterns; maybe not a record at all
-  | otherwise = PrefixCon (map (tidy_lpat.snd) all_pats)
-  where
-    arity = case con of
-        RealDataCon dcon -> dataConSourceArity dcon
-        PatSynCon psyn -> patSynArity psyn
-
-     -- pad out all the missing fields with WildPats.
-    field_pats = case con of
-        RealDataCon dc -> map (\ f -> (f, nlWildPatId)) (dataConFieldLabels dc)
-        PatSynCon{}    -> panic "Check.tidy_con: pattern synonym with record syntax"
-    all_pats = foldr (\(L _ (HsRecField id p _)) acc
-                                         -> insertNm (getName (unLoc id)) p acc)
-                     field_pats fs
-
-    insertNm nm p [] = [(nm,p)]
-    insertNm nm p (x@(n,_):xs)
-      | nm == n    = (nm,p):xs
-      | otherwise  = x : insertNm nm p xs
diff --git a/src/Language/Haskell/Liquid/Desugar710/Coverage.hs b/src/Language/Haskell/Liquid/Desugar710/Coverage.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/Coverage.hs
+++ /dev/null
@@ -1,1275 +0,0 @@
-{-
-(c) Galois, 2006
-(c) University of Glasgow, 2007
--}
-
-{-# LANGUAGE NondecreasingIndentation #-}
-
-module Language.Haskell.Liquid.Desugar710.Coverage (addTicksToBinds, hpcInitCode) where
-
-import Prelude hiding (error)
-import Type
-import HsSyn
-import Module
-import Outputable
-import DynFlags
-import Control.Monad
-import SrcLoc
-import ErrUtils
-import NameSet hiding (FreeVars)
-import Name
-import Bag
-import CostCentre
-import CoreSyn
-import Id
-import VarSet
-import Data.List
-import FastString
-import HscTypes
-import TyCon
-import UniqSupply
-import BasicTypes
-import MonadUtils
-import Maybes
-import CLabel
-import Util
-
-import Data.Array
-import Data.Time
-import System.Directory
-
-import Trace.Hpc.Mix
-import Trace.Hpc.Util
-
-import BreakArray
-import Data.Map (Map)
-import qualified Data.Map as Map
-
-{-
-************************************************************************
-*                                                                      *
-*              The main function: addTicksToBinds
-*                                                                      *
-************************************************************************
--}
-
-addTicksToBinds
-        :: DynFlags
-        -> Module
-        -> ModLocation          -- ... off the current module
-        -> NameSet              -- Exported Ids.  When we call addTicksToBinds,
-                                -- isExportedId doesn't work yet (the desugarer
-                                -- hasn't set it), so we have to work from this set.
-        -> [TyCon]              -- Type constructor in this module
-        -> LHsBinds Id
-        -> IO (LHsBinds Id, HpcInfo, ModBreaks)
-
-addTicksToBinds dflags mod mod_loc exports tyCons binds
-  | let passes = coveragePasses dflags, not (null passes),
-    Just orig_file <- ml_hs_file mod_loc = do
-
-     if "boot" `isSuffixOf` orig_file
-         then return (binds, emptyHpcInfo False, emptyModBreaks)
-         else do
-
-     us <- mkSplitUniqSupply 'C' -- for cost centres
-     let  orig_file2 = guessSourceFile binds orig_file
-
-          tickPass tickish (binds,st) =
-            let env = TTE
-                      { fileName     = mkFastString orig_file2
-                      , declPath     = []
-                      , tte_dflags   = dflags
-                      , exports      = exports
-                      , inlines      = emptyVarSet
-                      , inScope      = emptyVarSet
-                      , blackList    = Map.fromList
-                                          [ (getSrcSpan (tyConName tyCon),())
-                                          | tyCon <- tyCons ]
-                      , density      = mkDensity tickish dflags
-                      , this_mod     = mod
-                      , tickishType  = tickish
-                      }
-                (binds',_,st') = unTM (addTickLHsBinds binds) env st
-            in (binds', st')
-
-          initState = TT { tickBoxCount = 0
-                         , mixEntries   = []
-                         , breakCount   = 0
-                         , breaks       = []
-                         , uniqSupply   = us
-                         }
-
-          (binds1,st) = foldr tickPass (binds, initState) passes
-
-     let tickCount = tickBoxCount st
-     hashNo <- writeMixEntries dflags mod tickCount (reverse $ mixEntries st)
-                               orig_file2
-     modBreaks <- mkModBreaks dflags (breakCount st) (reverse $ breaks st)
-
-     when (dopt Opt_D_dump_ticked dflags) $
-         log_action dflags dflags SevDump noSrcSpan defaultDumpStyle
-             (pprLHsBinds binds1)
-
-     return (binds1, HpcInfo tickCount hashNo, modBreaks)
-
-  | otherwise = return (binds, emptyHpcInfo False, emptyModBreaks)
-
-guessSourceFile :: LHsBinds Id -> FilePath -> FilePath
-guessSourceFile binds orig_file =
-     -- Try look for a file generated from a .hsc file to a
-     -- .hs file, by peeking ahead.
-     let top_pos = catMaybes $ foldrBag (\ (L pos _) rest ->
-                                 srcSpanFileName_maybe pos : rest) [] binds
-     in
-     case top_pos of
-        (file_name:_) | ".hsc" `isSuffixOf` unpackFS file_name
-                      -> unpackFS file_name
-        _ -> orig_file
-
-
-mkModBreaks :: DynFlags -> Int -> [MixEntry_] -> IO ModBreaks
-mkModBreaks dflags count entries = do
-  breakArray <- newBreakArray dflags $ length entries
-  let
-         locsTicks = listArray (0,count-1) [ span  | (span,_,_,_)  <- entries ]
-         varsTicks = listArray (0,count-1) [ vars  | (_,_,vars,_)  <- entries ]
-         declsTicks= listArray (0,count-1) [ decls | (_,decls,_,_) <- entries ]
-         modBreaks = emptyModBreaks
-                     { modBreaks_flags = breakArray
-                     , modBreaks_locs  = locsTicks
-                     , modBreaks_vars  = varsTicks
-                     , modBreaks_decls = declsTicks
-                     }
-  --
-  return modBreaks
-
-
-writeMixEntries :: DynFlags -> Module -> Int -> [MixEntry_] -> FilePath -> IO Int
-writeMixEntries dflags mod count entries filename
-  | not (gopt Opt_Hpc dflags) = return 0
-  | otherwise   = do
-        let
-            hpc_dir = hpcDir dflags
-            mod_name = moduleNameString (moduleName mod)
-
-            hpc_mod_dir
-              | modulePackageKey mod == mainPackageKey  = hpc_dir
-              | otherwise = hpc_dir ++ "/" ++ packageKeyString (modulePackageKey mod)
-
-            tabStop = 8 -- <tab> counts as a normal char in GHC's location ranges.
-
-        createDirectoryIfMissing True hpc_mod_dir
-        modTime <- getModificationUTCTime filename
-        let entries' = [ (hpcPos, box)
-                       | (span,_,_,box) <- entries, hpcPos <- [mkHpcPos span] ]
-        when (length entries' /= count) $ do
-          panic "the number of .mix entries are inconsistent"
-        let hashNo = mixHash filename modTime tabStop entries'
-        mixCreate hpc_mod_dir mod_name
-                       $ Mix filename modTime (toHash hashNo) tabStop entries'
-        return hashNo
-
-
--- -----------------------------------------------------------------------------
--- TickDensity: where to insert ticks
-
-data TickDensity
-  = TickForCoverage       -- for Hpc
-  | TickForBreakPoints    -- for GHCi
-  | TickAllFunctions      -- for -prof-auto-all
-  | TickTopFunctions      -- for -prof-auto-top
-  | TickExportedFunctions -- for -prof-auto-exported
-  | TickCallSites         -- for stack tracing
-  deriving Eq
-
-mkDensity :: TickishType -> DynFlags -> TickDensity
-mkDensity tickish dflags = case tickish of
-  HpcTicks             -> TickForCoverage
-  SourceNotes          -> TickForCoverage
-  Breakpoints          -> TickForBreakPoints
-  ProfNotes ->
-    case profAuto dflags of
-      ProfAutoAll      -> TickAllFunctions
-      ProfAutoTop      -> TickTopFunctions
-      ProfAutoExports  -> TickExportedFunctions
-      ProfAutoCalls    -> TickCallSites
-      _other           -> panic "mkDensity"
-
--- | Decide whether to add a tick to a binding or not.
-shouldTickBind  :: TickDensity
-                -> Bool         -- top level?
-                -> Bool         -- exported?
-                -> Bool         -- simple pat bind?
-                -> Bool         -- INLINE pragma?
-                -> Bool
-
-shouldTickBind density top_lev exported simple_pat inline
- = case density of
-      TickForBreakPoints    -> not simple_pat
-        -- we never add breakpoints to simple pattern bindings
-        -- (there's always a tick on the rhs anyway).
-      TickAllFunctions      -> not inline
-      TickTopFunctions      -> top_lev && not inline
-      TickExportedFunctions -> exported && not inline
-      TickForCoverage       -> True
-      TickCallSites         -> False
-
-shouldTickPatBind :: TickDensity -> Bool -> Bool
-shouldTickPatBind density top_lev
-  = case density of
-      TickForBreakPoints    -> False
-      TickAllFunctions      -> True
-      TickTopFunctions      -> top_lev
-      TickExportedFunctions -> False
-      TickForCoverage       -> False
-      TickCallSites         -> False
-
--- -----------------------------------------------------------------------------
--- Adding ticks to bindings
-
-addTickLHsBinds :: LHsBinds Id -> TM (LHsBinds Id)
-addTickLHsBinds = mapBagM addTickLHsBind
-
-addTickLHsBind :: LHsBind Id -> TM (LHsBind Id)
-addTickLHsBind (L pos bind@(AbsBinds { abs_binds   = binds,
-                                       abs_exports = abs_exports })) = do
-  withEnv add_exports $ do
-  withEnv add_inlines $ do
-  binds' <- addTickLHsBinds binds
-  return $ L pos $ bind { abs_binds = binds' }
- where
-   -- in AbsBinds, the Id on each binding is not the actual top-level
-   -- Id that we are defining, they are related by the abs_exports
-   -- field of AbsBinds.  So if we're doing TickExportedFunctions we need
-   -- to add the local Ids to the set of exported Names so that we know to
-   -- tick the right bindings.
-   add_exports env =
-     env{ exports = exports env `extendNameSetList`
-                      [ idName mid
-                      | ABE{ abe_poly = pid, abe_mono = mid } <- abs_exports
-                      , idName pid `elemNameSet` (exports env) ] }
-
-   add_inlines env =
-     env{ inlines = inlines env `extendVarSetList`
-                      [ mid
-                      | ABE{ abe_poly = pid, abe_mono = mid } <- abs_exports
-                      , isAnyInlinePragma (idInlinePragma pid) ] }
-
-
-addTickLHsBind (L pos (funBind@(FunBind { fun_id = (L _ id)  }))) = do
-  let name = getOccString id
-  decl_path <- getPathEntry
-  density <- getDensity
-
-  inline_ids <- liftM inlines getEnv
-  let inline   = isAnyInlinePragma (idInlinePragma id)
-                 || id `elemVarSet` inline_ids
-
-  -- See Note [inline sccs]
-  tickish <- tickishType `liftM` getEnv
-  if inline && tickish == ProfNotes then return (L pos funBind) else do
-
-  (fvs, mg@(MG { mg_alts = matches' })) <-
-        getFreeVars $
-        addPathEntry name $
-        addTickMatchGroup False (fun_matches funBind)
-
-  blackListed <- isBlackListed pos
-  exported_names <- liftM exports getEnv
-
-  -- We don't want to generate code for blacklisted positions
-  -- We don't want redundant ticks on simple pattern bindings
-  -- We don't want to tick non-exported bindings in TickExportedFunctions
-  let simple = isSimplePatBind funBind
-      toplev = null decl_path
-      exported = idName id `elemNameSet` exported_names
-
-  tick <- if not blackListed &&
-               shouldTickBind density toplev exported simple inline
-             then
-                bindTick density name pos fvs
-             else
-                return Nothing
-
-  let mbCons = maybe Prelude.id (:)
-  return $ L pos $ funBind { fun_matches = mg { mg_alts = matches' }
-                           , fun_tick = tick `mbCons` fun_tick funBind }
-
-   where
-   -- a binding is a simple pattern binding if it is a funbind with zero patterns
-   isSimplePatBind :: HsBind a -> Bool
-   isSimplePatBind funBind = matchGroupArity (fun_matches funBind) == 0
-
--- TODO: Revisit this
-addTickLHsBind (L pos (pat@(PatBind { pat_lhs = lhs, pat_rhs = rhs }))) = do
-  let name = "(...)"
-  (fvs, rhs') <- getFreeVars $ addPathEntry name $ addTickGRHSs False False rhs
-  let pat' = pat { pat_rhs = rhs'}
-
-  -- Should create ticks here?
-  density <- getDensity
-  decl_path <- getPathEntry
-  let top_lev = null decl_path
-  if not (shouldTickPatBind density top_lev) then return (L pos pat') else do
-
-    -- Allocate the ticks
-    rhs_tick <- bindTick density name pos fvs
-    let patvars = map getOccString (collectPatBinders lhs)
-    patvar_ticks <- mapM (\v -> bindTick density v pos fvs) patvars
-
-    -- Add to pattern
-    let mbCons = maybe id (:)
-        rhs_ticks = rhs_tick `mbCons` fst (pat_ticks pat')
-        patvar_tickss = zipWith mbCons patvar_ticks
-                        (snd (pat_ticks pat') ++ repeat [])
-    return $ L pos $ pat' { pat_ticks = (rhs_ticks, patvar_tickss) }
-
--- Only internal stuff, not from source, uses VarBind, so we ignore it.
-addTickLHsBind var_bind@(L _ (VarBind {})) = return var_bind
-addTickLHsBind patsyn_bind@(L _ (PatSynBind {})) = return patsyn_bind
-
-
-bindTick :: TickDensity -> String -> SrcSpan -> FreeVars -> TM (Maybe (Tickish Id))
-bindTick density name pos fvs = do
-  decl_path <- getPathEntry
-  let
-      toplev        = null decl_path
-      count_entries = toplev || density == TickAllFunctions
-      top_only      = density /= TickAllFunctions
-      box_label     = if toplev then TopLevelBox [name]
-                                else LocalBox (decl_path ++ [name])
-  --
-  allocATickBox box_label count_entries top_only pos fvs
-
-
--- Note [inline sccs]
---
--- It should be reasonable to add ticks to INLINE functions; however
--- currently this tickles a bug later on because the SCCfinal pass
--- does not look inside unfoldings to find CostCentres.  It would be
--- difficult to fix that, because SCCfinal currently works on STG and
--- not Core (and since it also generates CostCentres for CAFs,
--- changing this would be difficult too).
---
--- Another reason not to add ticks to INLINE functions is that this
--- sometimes handy for avoiding adding a tick to a particular function
--- (see #6131)
---
--- So for now we do not add any ticks to INLINE functions at all.
-
--- -----------------------------------------------------------------------------
--- Decorate an LHsExpr with ticks
-
--- selectively add ticks to interesting expressions
-addTickLHsExpr :: LHsExpr Id -> TM (LHsExpr Id)
-addTickLHsExpr e@(L pos e0) = do
-  d <- getDensity
-  case d of
-    TickForBreakPoints | isGoodBreakExpr e0 -> tick_it
-    TickForCoverage    -> tick_it
-    TickCallSites      | isCallSite e0      -> tick_it
-    _other             -> dont_tick_it
- where
-   tick_it      = allocTickBox (ExpBox False) False False pos $ addTickHsExpr e0
-   dont_tick_it = addTickLHsExprNever e
-
--- Add a tick to an expression which is the RHS of an equation or a binding.
--- We always consider these to be breakpoints, unless the expression is a 'let'
--- (because the body will definitely have a tick somewhere).  ToDo: perhaps
--- we should treat 'case' and 'if' the same way?
-addTickLHsExprRHS :: LHsExpr Id -> TM (LHsExpr Id)
-addTickLHsExprRHS e@(L pos e0) = do
-  d <- getDensity
-  case d of
-     TickForBreakPoints | HsLet{} <- e0 -> dont_tick_it
-                        | otherwise     -> tick_it
-     TickForCoverage -> tick_it
-     TickCallSites   | isCallSite e0 -> tick_it
-     _other          -> dont_tick_it
- where
-   tick_it      = allocTickBox (ExpBox False) False False pos $ addTickHsExpr e0
-   dont_tick_it = addTickLHsExprNever e
-
--- The inner expression of an evaluation context:
---    let binds in [], ( [] )
--- we never tick these if we're doing HPC, but otherwise
--- we treat it like an ordinary expression.
-addTickLHsExprEvalInner :: LHsExpr Id -> TM (LHsExpr Id)
-addTickLHsExprEvalInner e = do
-   d <- getDensity
-   case d of
-     TickForCoverage -> addTickLHsExprNever e
-     _otherwise      -> addTickLHsExpr e
-
--- | A let body is treated differently from addTickLHsExprEvalInner
--- above with TickForBreakPoints, because for breakpoints we always
--- want to tick the body, even if it is not a redex.  See test
--- break012.  This gives the user the opportunity to inspect the
--- values of the let-bound variables.
-addTickLHsExprLetBody :: LHsExpr Id -> TM (LHsExpr Id)
-addTickLHsExprLetBody e@(L pos e0) = do
-  d <- getDensity
-  case d of
-     TickForBreakPoints | HsLet{} <- e0 -> dont_tick_it
-                        | otherwise     -> tick_it
-     _other -> addTickLHsExprEvalInner e
- where
-   tick_it      = allocTickBox (ExpBox False) False False pos $ addTickHsExpr e0
-   dont_tick_it = addTickLHsExprNever e
-
--- version of addTick that does not actually add a tick,
--- because the scope of this tick is completely subsumed by
--- another.
-addTickLHsExprNever :: LHsExpr Id -> TM (LHsExpr Id)
-addTickLHsExprNever (L pos e0) = do
-    e1 <- addTickHsExpr e0
-    return $ L pos e1
-
--- general heuristic: expressions which do not denote values are good break points
-isGoodBreakExpr :: HsExpr Id -> Bool
-isGoodBreakExpr (HsApp {})     = True
-isGoodBreakExpr (OpApp {})     = True
-isGoodBreakExpr (NegApp {})    = True
-isGoodBreakExpr (HsIf {})      = True
-isGoodBreakExpr (HsMultiIf {}) = True
-isGoodBreakExpr (HsCase {})    = True
-isGoodBreakExpr (RecordCon {}) = True
-isGoodBreakExpr (RecordUpd {}) = True
-isGoodBreakExpr (ArithSeq {})  = True
-isGoodBreakExpr (PArrSeq {})   = True
-isGoodBreakExpr _other         = False
-
-isCallSite :: HsExpr Id -> Bool
-isCallSite HsApp{}  = True
-isCallSite OpApp{}  = True
-isCallSite _ = False
-
-addTickLHsExprOptAlt :: Bool -> LHsExpr Id -> TM (LHsExpr Id)
-addTickLHsExprOptAlt oneOfMany (L pos e0)
-  = ifDensity TickForCoverage
-        (allocTickBox (ExpBox oneOfMany) False False pos $ addTickHsExpr e0)
-        (addTickLHsExpr (L pos e0))
-
-addBinTickLHsExpr :: (Bool -> BoxLabel) -> LHsExpr Id -> TM (LHsExpr Id)
-addBinTickLHsExpr boxLabel (L pos e0)
-  = ifDensity TickForCoverage
-        (allocBinTickBox boxLabel pos $ addTickHsExpr e0)
-        (addTickLHsExpr (L pos e0))
-
-
--- -----------------------------------------------------------------------------
--- Decoarate an HsExpr with ticks
-
-addTickHsExpr :: HsExpr Id -> TM (HsExpr Id)
-addTickHsExpr e@(HsVar id) = do freeVar id; return e
-addTickHsExpr e@(HsIPVar _) = return e
-addTickHsExpr e@(HsOverLit _) = return e
-addTickHsExpr e@(HsLit _) = return e
-addTickHsExpr (HsLam matchgroup) =
-        liftM HsLam (addTickMatchGroup True matchgroup)
-addTickHsExpr (HsLamCase ty mgs) =
-        liftM (HsLamCase ty) (addTickMatchGroup True mgs)
-addTickHsExpr (HsApp e1 e2) =
-        liftM2 HsApp (addTickLHsExprNever e1) (addTickLHsExpr e2)
-addTickHsExpr (OpApp e1 e2 fix e3) =
-        liftM4 OpApp
-                (addTickLHsExpr e1)
-                (addTickLHsExprNever e2)
-                (return fix)
-                (addTickLHsExpr e3)
-addTickHsExpr (NegApp e neg) =
-        liftM2 NegApp
-                (addTickLHsExpr e)
-                (addTickSyntaxExpr hpcSrcSpan neg)
-addTickHsExpr (HsPar e) =
-        liftM HsPar (addTickLHsExprEvalInner e)
-addTickHsExpr (SectionL e1 e2) =
-        liftM2 SectionL
-                (addTickLHsExpr e1)
-                (addTickLHsExprNever e2)
-addTickHsExpr (SectionR e1 e2) =
-        liftM2 SectionR
-                (addTickLHsExprNever e1)
-                (addTickLHsExpr e2)
-addTickHsExpr (ExplicitTuple es boxity) =
-        liftM2 ExplicitTuple
-                (mapM addTickTupArg es)
-                (return boxity)
-addTickHsExpr (HsCase e mgs) =
-        liftM2 HsCase
-                (addTickLHsExpr e) -- not an EvalInner; e might not necessarily
-                                   -- be evaluated.
-                (addTickMatchGroup False mgs)
-addTickHsExpr (HsIf cnd e1 e2 e3) =
-        liftM3 (HsIf cnd)
-                (addBinTickLHsExpr (BinBox CondBinBox) e1)
-                (addTickLHsExprOptAlt True e2)
-                (addTickLHsExprOptAlt True e3)
-addTickHsExpr (HsMultiIf ty alts)
-  = do { let isOneOfMany = case alts of [_] -> False; _ -> True
-       ; alts' <- mapM (liftL $ addTickGRHS isOneOfMany False) alts
-       ; return $ HsMultiIf ty alts' }
-addTickHsExpr (HsLet binds e) =
-        bindLocals (collectLocalBinders binds) $
-        liftM2 HsLet
-                (addTickHsLocalBinds binds) -- to think about: !patterns.
-                (addTickLHsExprLetBody e)
-addTickHsExpr (HsDo cxt stmts srcloc)
-  = do { (stmts', _) <- addTickLStmts' forQual stmts (return ())
-       ; return (HsDo cxt stmts' srcloc) }
-  where
-        forQual = case cxt of
-                    ListComp -> Just $ BinBox QualBinBox
-                    _        -> Nothing
-addTickHsExpr (ExplicitList ty wit es) =
-        liftM3 ExplicitList
-                (return ty)
-                (addTickWit wit)
-                (mapM (addTickLHsExpr) es)
-             where addTickWit Nothing = return Nothing
-                   addTickWit (Just fln) = do fln' <- addTickHsExpr fln
-                                              return (Just fln')
-addTickHsExpr (ExplicitPArr ty es) =
-        liftM2 ExplicitPArr
-                (return ty)
-                (mapM (addTickLHsExpr) es)
-
-addTickHsExpr (HsStatic e) = HsStatic <$> addTickLHsExpr e
-
-addTickHsExpr (RecordCon id ty rec_binds) =
-        liftM3 RecordCon
-                (return id)
-                (return ty)
-                (addTickHsRecordBinds rec_binds)
-addTickHsExpr (RecordUpd e rec_binds cons tys1 tys2) =
-        liftM5 RecordUpd
-                (addTickLHsExpr e)
-                (addTickHsRecordBinds rec_binds)
-                (return cons) (return tys1) (return tys2)
-
-addTickHsExpr (ExprWithTySigOut e ty) =
-        liftM2 ExprWithTySigOut
-                (addTickLHsExprNever e) -- No need to tick the inner expression
-                                    -- for expressions with signatures
-                (return ty)
-addTickHsExpr (ArithSeq  ty wit arith_seq) =
-        liftM3 ArithSeq
-                (return ty)
-                (addTickWit wit)
-                (addTickArithSeqInfo arith_seq)
-             where addTickWit Nothing = return Nothing
-                   addTickWit (Just fl) = do fl' <- addTickHsExpr fl
-                                             return (Just fl')
-
--- We might encounter existing ticks (multiple Coverage passes)
-addTickHsExpr (HsTick t e) =
-        liftM (HsTick t) (addTickLHsExprNever e)
-addTickHsExpr (HsBinTick t0 t1 e) =
-        liftM (HsBinTick t0 t1) (addTickLHsExprNever e)
-
-addTickHsExpr (HsTickPragma _ _ (L pos e0)) = do
-    e2 <- allocTickBox (ExpBox False) False False pos $
-                addTickHsExpr e0
-    return $ unLoc e2
-addTickHsExpr (PArrSeq   ty arith_seq) =
-        liftM2 PArrSeq
-                (return ty)
-                (addTickArithSeqInfo arith_seq)
-addTickHsExpr (HsSCC src nm e) =
-        liftM3 HsSCC
-                (return src)
-                (return nm)
-                (addTickLHsExpr e)
-addTickHsExpr (HsCoreAnn src nm e) =
-        liftM3 HsCoreAnn
-                (return src)
-                (return nm)
-                (addTickLHsExpr e)
-addTickHsExpr e@(HsBracket     {})   = return e
-addTickHsExpr e@(HsTcBracketOut  {}) = return e
-addTickHsExpr e@(HsRnBracketOut  {}) = return e
-addTickHsExpr e@(HsSpliceE  {})      = return e
-addTickHsExpr (HsProc pat cmdtop) =
-        liftM2 HsProc
-                (addTickLPat pat)
-                (liftL (addTickHsCmdTop) cmdtop)
-addTickHsExpr (HsWrap w e) =
-        liftM2 HsWrap
-                (return w)
-                (addTickHsExpr e)       -- explicitly no tick on inside
-
-addTickHsExpr e@(HsType _) = return e
-addTickHsExpr (HsUnboundVar {}) = panic "addTickHsExpr.HsUnboundVar"
-
--- Others dhould never happen in expression content.
-addTickHsExpr e  = pprPanic "addTickHsExpr" (ppr e)
-
-addTickTupArg :: LHsTupArg Id -> TM (LHsTupArg Id)
-addTickTupArg (L l (Present e))  = do { e' <- addTickLHsExpr e
-                                      ; return (L l (Present e')) }
-addTickTupArg (L l (Missing ty)) = return (L l (Missing ty))
-
-addTickMatchGroup :: Bool{-is lambda-} -> MatchGroup Id (LHsExpr Id) -> TM (MatchGroup Id (LHsExpr Id))
-addTickMatchGroup is_lam mg@(MG { mg_alts = matches }) = do
-  let isOneOfMany = matchesOneOfMany matches
-  matches' <- mapM (liftL (addTickMatch isOneOfMany is_lam)) matches
-  return $ mg { mg_alts = matches' }
-
-addTickMatch :: Bool -> Bool -> Match Id (LHsExpr Id) -> TM (Match Id (LHsExpr Id))
-addTickMatch isOneOfMany isLambda (Match mf pats opSig gRHSs) =
-  bindLocals (collectPatsBinders pats) $ do
-    gRHSs' <- addTickGRHSs isOneOfMany isLambda gRHSs
-    return $ Match mf pats opSig gRHSs'
-
-addTickGRHSs :: Bool -> Bool -> GRHSs Id (LHsExpr Id) -> TM (GRHSs Id (LHsExpr Id))
-addTickGRHSs isOneOfMany isLambda (GRHSs guarded local_binds) = do
-  bindLocals binders $ do
-    local_binds' <- addTickHsLocalBinds local_binds
-    guarded' <- mapM (liftL (addTickGRHS isOneOfMany isLambda)) guarded
-    return $ GRHSs guarded' local_binds'
-  where
-    binders = collectLocalBinders local_binds
-
-addTickGRHS :: Bool -> Bool -> GRHS Id (LHsExpr Id) -> TM (GRHS Id (LHsExpr Id))
-addTickGRHS isOneOfMany isLambda (GRHS stmts expr) = do
-  (stmts',expr') <- addTickLStmts' (Just $ BinBox $ GuardBinBox) stmts
-                        (addTickGRHSBody isOneOfMany isLambda expr)
-  return $ GRHS stmts' expr'
-
-addTickGRHSBody :: Bool -> Bool -> LHsExpr Id -> TM (LHsExpr Id)
-addTickGRHSBody isOneOfMany isLambda expr@(L pos e0) = do
-  d <- getDensity
-  case d of
-    TickForCoverage  -> addTickLHsExprOptAlt isOneOfMany expr
-    TickAllFunctions | isLambda ->
-       addPathEntry "\\" $
-         allocTickBox (ExpBox False) True{-count-} False{-not top-} pos $
-           addTickHsExpr e0
-    _otherwise ->
-       addTickLHsExprRHS expr
-
-addTickLStmts :: (Maybe (Bool -> BoxLabel)) -> [ExprLStmt Id] -> TM [ExprLStmt Id]
-addTickLStmts isGuard stmts = do
-  (stmts, _) <- addTickLStmts' isGuard stmts (return ())
-  return stmts
-
-addTickLStmts' :: (Maybe (Bool -> BoxLabel)) -> [ExprLStmt Id] -> TM a
-               -> TM ([ExprLStmt Id], a)
-addTickLStmts' isGuard lstmts res
-  = bindLocals (collectLStmtsBinders lstmts) $
-    do { lstmts' <- mapM (liftL (addTickStmt isGuard)) lstmts
-       ; a <- res
-       ; return (lstmts', a) }
-
-addTickStmt :: (Maybe (Bool -> BoxLabel)) -> Stmt Id (LHsExpr Id) -> TM (Stmt Id (LHsExpr Id))
-addTickStmt _isGuard (LastStmt e ret) = do
-        liftM2 LastStmt
-                (addTickLHsExpr e)
-                (addTickSyntaxExpr hpcSrcSpan ret)
-addTickStmt _isGuard (BindStmt pat e bind fail) = do
-        liftM4 BindStmt
-                (addTickLPat pat)
-                (addTickLHsExprRHS e)
-                (addTickSyntaxExpr hpcSrcSpan bind)
-                (addTickSyntaxExpr hpcSrcSpan fail)
-addTickStmt isGuard (BodyStmt e bind' guard' ty) = do
-        liftM4 BodyStmt
-                (addTick isGuard e)
-                (addTickSyntaxExpr hpcSrcSpan bind')
-                (addTickSyntaxExpr hpcSrcSpan guard')
-                (return ty)
-addTickStmt _isGuard (LetStmt binds) = do
-        liftM LetStmt
-                (addTickHsLocalBinds binds)
-addTickStmt isGuard (ParStmt pairs mzipExpr bindExpr) = do
-    liftM3 ParStmt
-        (mapM (addTickStmtAndBinders isGuard) pairs)
-        (addTickSyntaxExpr hpcSrcSpan mzipExpr)
-        (addTickSyntaxExpr hpcSrcSpan bindExpr)
-
-addTickStmt isGuard stmt@(TransStmt { trS_stmts = stmts
-                                    , trS_by = by, trS_using = using
-                                    , trS_ret = returnExpr, trS_bind = bindExpr
-                                    , trS_fmap = liftMExpr }) = do
-    t_s <- addTickLStmts isGuard stmts
-    t_y <- fmapMaybeM  addTickLHsExprRHS by
-    t_u <- addTickLHsExprRHS using
-    t_f <- addTickSyntaxExpr hpcSrcSpan returnExpr
-    t_b <- addTickSyntaxExpr hpcSrcSpan bindExpr
-    t_m <- addTickSyntaxExpr hpcSrcSpan liftMExpr
-    return $ stmt { trS_stmts = t_s, trS_by = t_y, trS_using = t_u
-                  , trS_ret = t_f, trS_bind = t_b, trS_fmap = t_m }
-
-addTickStmt isGuard stmt@(RecStmt {})
-  = do { stmts' <- addTickLStmts isGuard (recS_stmts stmt)
-       ; ret'   <- addTickSyntaxExpr hpcSrcSpan (recS_ret_fn stmt)
-       ; mfix'  <- addTickSyntaxExpr hpcSrcSpan (recS_mfix_fn stmt)
-       ; bind'  <- addTickSyntaxExpr hpcSrcSpan (recS_bind_fn stmt)
-       ; return (stmt { recS_stmts = stmts', recS_ret_fn = ret'
-                      , recS_mfix_fn = mfix', recS_bind_fn = bind' }) }
-
-addTick :: Maybe (Bool -> BoxLabel) -> LHsExpr Id -> TM (LHsExpr Id)
-addTick isGuard e | Just fn <- isGuard = addBinTickLHsExpr fn e
-                  | otherwise          = addTickLHsExprRHS e
-
-addTickStmtAndBinders :: Maybe (Bool -> BoxLabel) -> ParStmtBlock Id Id
-                      -> TM (ParStmtBlock Id Id)
-addTickStmtAndBinders isGuard (ParStmtBlock stmts ids returnExpr) =
-    liftM3 ParStmtBlock
-        (addTickLStmts isGuard stmts)
-        (return ids)
-        (addTickSyntaxExpr hpcSrcSpan returnExpr)
-
-addTickHsLocalBinds :: HsLocalBinds Id -> TM (HsLocalBinds Id)
-addTickHsLocalBinds (HsValBinds binds) =
-        liftM HsValBinds
-                (addTickHsValBinds binds)
-addTickHsLocalBinds (HsIPBinds binds)  =
-        liftM HsIPBinds
-                (addTickHsIPBinds binds)
-addTickHsLocalBinds (EmptyLocalBinds)  = return EmptyLocalBinds
-
-addTickHsValBinds :: HsValBindsLR Id a -> TM (HsValBindsLR Id b)
-addTickHsValBinds (ValBindsOut binds sigs) =
-        liftM2 ValBindsOut
-                (mapM (\ (rec,binds') ->
-                                liftM2 (,)
-                                        (return rec)
-                                        (addTickLHsBinds binds'))
-                        binds)
-                (return sigs)
-addTickHsValBinds _ = panic "addTickHsValBinds"
-
-addTickHsIPBinds :: HsIPBinds Id -> TM (HsIPBinds Id)
-addTickHsIPBinds (IPBinds ipbinds dictbinds) =
-        liftM2 IPBinds
-                (mapM (liftL (addTickIPBind)) ipbinds)
-                (return dictbinds)
-
-addTickIPBind :: IPBind Id -> TM (IPBind Id)
-addTickIPBind (IPBind nm e) =
-        liftM2 IPBind
-                (return nm)
-                (addTickLHsExpr e)
-
--- There is no location here, so we might need to use a context location??
-addTickSyntaxExpr :: SrcSpan -> SyntaxExpr Id -> TM (SyntaxExpr Id)
-addTickSyntaxExpr pos x = do
-        L _ x' <- addTickLHsExpr (L pos x)
-        return $ x'
--- we do not walk into patterns.
-addTickLPat :: LPat Id -> TM (LPat Id)
-addTickLPat pat = return pat
-
-addTickHsCmdTop :: HsCmdTop Id -> TM (HsCmdTop Id)
-addTickHsCmdTop (HsCmdTop cmd tys ty syntaxtable) =
-        liftM4 HsCmdTop
-                (addTickLHsCmd cmd)
-                (return tys)
-                (return ty)
-                (return syntaxtable)
-
-addTickLHsCmd ::  LHsCmd Id -> TM (LHsCmd Id)
-addTickLHsCmd (L pos c0) = do
-        c1 <- addTickHsCmd c0
-        return $ L pos c1
-
-addTickHsCmd :: HsCmd Id -> TM (HsCmd Id)
-addTickHsCmd (HsCmdLam matchgroup) =
-        liftM HsCmdLam (addTickCmdMatchGroup matchgroup)
-addTickHsCmd (HsCmdApp c e) =
-        liftM2 HsCmdApp (addTickLHsCmd c) (addTickLHsExpr e)
-{-
-addTickHsCmd (OpApp e1 c2 fix c3) =
-        liftM4 OpApp
-                (addTickLHsExpr e1)
-                (addTickLHsCmd c2)
-                (return fix)
-                (addTickLHsCmd c3)
--}
-addTickHsCmd (HsCmdPar e) = liftM HsCmdPar (addTickLHsCmd e)
-addTickHsCmd (HsCmdCase e mgs) =
-        liftM2 HsCmdCase
-                (addTickLHsExpr e)
-                (addTickCmdMatchGroup mgs)
-addTickHsCmd (HsCmdIf cnd e1 c2 c3) =
-        liftM3 (HsCmdIf cnd)
-                (addBinTickLHsExpr (BinBox CondBinBox) e1)
-                (addTickLHsCmd c2)
-                (addTickLHsCmd c3)
-addTickHsCmd (HsCmdLet binds c) =
-        bindLocals (collectLocalBinders binds) $
-        liftM2 HsCmdLet
-                (addTickHsLocalBinds binds) -- to think about: !patterns.
-                (addTickLHsCmd c)
-addTickHsCmd (HsCmdDo stmts srcloc)
-  = do { (stmts', _) <- addTickLCmdStmts' stmts (return ())
-       ; return (HsCmdDo stmts' srcloc) }
-
-addTickHsCmd (HsCmdArrApp   e1 e2 ty1 arr_ty lr) =
-        liftM5 HsCmdArrApp
-               (addTickLHsExpr e1)
-               (addTickLHsExpr e2)
-               (return ty1)
-               (return arr_ty)
-               (return lr)
-addTickHsCmd (HsCmdArrForm e fix cmdtop) =
-        liftM3 HsCmdArrForm
-               (addTickLHsExpr e)
-               (return fix)
-               (mapM (liftL (addTickHsCmdTop)) cmdtop)
-
-addTickHsCmd (HsCmdCast co cmd)
-  = liftM2 HsCmdCast (return co) (addTickHsCmd cmd)
-
--- Others should never happen in a command context.
---addTickHsCmd e  = pprPanic "addTickHsCmd" (ppr e)
-
-addTickCmdMatchGroup :: MatchGroup Id (LHsCmd Id) -> TM (MatchGroup Id (LHsCmd Id))
-addTickCmdMatchGroup mg@(MG { mg_alts = matches }) = do
-  matches' <- mapM (liftL addTickCmdMatch) matches
-  return $ mg { mg_alts = matches' }
-
-addTickCmdMatch :: Match Id (LHsCmd Id) -> TM (Match Id (LHsCmd Id))
-addTickCmdMatch (Match mf pats opSig gRHSs) =
-  bindLocals (collectPatsBinders pats) $ do
-    gRHSs' <- addTickCmdGRHSs gRHSs
-    return $ Match mf pats opSig gRHSs'
-
-addTickCmdGRHSs :: GRHSs Id (LHsCmd Id) -> TM (GRHSs Id (LHsCmd Id))
-addTickCmdGRHSs (GRHSs guarded local_binds) = do
-  bindLocals binders $ do
-    local_binds' <- addTickHsLocalBinds local_binds
-    guarded' <- mapM (liftL addTickCmdGRHS) guarded
-    return $ GRHSs guarded' local_binds'
-  where
-    binders = collectLocalBinders local_binds
-
-addTickCmdGRHS :: GRHS Id (LHsCmd Id) -> TM (GRHS Id (LHsCmd Id))
--- The *guards* are *not* Cmds, although the body is
--- C.f. addTickGRHS for the BinBox stuff
-addTickCmdGRHS (GRHS stmts cmd)
-  = do { (stmts',expr') <- addTickLStmts' (Just $ BinBox $ GuardBinBox)
-                                   stmts (addTickLHsCmd cmd)
-       ; return $ GRHS stmts' expr' }
-
-addTickLCmdStmts :: [LStmt Id (LHsCmd Id)] -> TM [LStmt Id (LHsCmd Id)]
-addTickLCmdStmts stmts = do
-  (stmts, _) <- addTickLCmdStmts' stmts (return ())
-  return stmts
-
-addTickLCmdStmts' :: [LStmt Id (LHsCmd Id)] -> TM a -> TM ([LStmt Id (LHsCmd Id)], a)
-addTickLCmdStmts' lstmts res
-  = bindLocals binders $ do
-        lstmts' <- mapM (liftL addTickCmdStmt) lstmts
-        a <- res
-        return (lstmts', a)
-  where
-        binders = collectLStmtsBinders lstmts
-
-addTickCmdStmt :: Stmt Id (LHsCmd Id) -> TM (Stmt Id (LHsCmd Id))
-addTickCmdStmt (BindStmt pat c bind fail) = do
-        liftM4 BindStmt
-                (addTickLPat pat)
-                (addTickLHsCmd c)
-                (return bind)
-                (return fail)
-addTickCmdStmt (LastStmt c ret) = do
-        liftM2 LastStmt
-                (addTickLHsCmd c)
-                (addTickSyntaxExpr hpcSrcSpan ret)
-addTickCmdStmt (BodyStmt c bind' guard' ty) = do
-        liftM4 BodyStmt
-                (addTickLHsCmd c)
-                (addTickSyntaxExpr hpcSrcSpan bind')
-                (addTickSyntaxExpr hpcSrcSpan guard')
-                (return ty)
-addTickCmdStmt (LetStmt binds) = do
-        liftM LetStmt
-                (addTickHsLocalBinds binds)
-addTickCmdStmt stmt@(RecStmt {})
-  = do { stmts' <- addTickLCmdStmts (recS_stmts stmt)
-       ; ret'   <- addTickSyntaxExpr hpcSrcSpan (recS_ret_fn stmt)
-       ; mfix'  <- addTickSyntaxExpr hpcSrcSpan (recS_mfix_fn stmt)
-       ; bind'  <- addTickSyntaxExpr hpcSrcSpan (recS_bind_fn stmt)
-       ; return (stmt { recS_stmts = stmts', recS_ret_fn = ret'
-                      , recS_mfix_fn = mfix', recS_bind_fn = bind' }) }
-
--- Others should never happen in a command context.
-addTickCmdStmt stmt  = pprPanic "addTickHsCmd" (ppr stmt)
-
-addTickHsRecordBinds :: HsRecordBinds Id -> TM (HsRecordBinds Id)
-addTickHsRecordBinds (HsRecFields fields dd)
-  = do  { fields' <- mapM process fields
-        ; return (HsRecFields fields' dd) }
-  where
-    process (L l (HsRecField ids expr doc))
-        = do { expr' <- addTickLHsExpr expr
-             ; return (L l (HsRecField ids expr' doc)) }
-
-addTickArithSeqInfo :: ArithSeqInfo Id -> TM (ArithSeqInfo Id)
-addTickArithSeqInfo (From e1) =
-        liftM From
-                (addTickLHsExpr e1)
-addTickArithSeqInfo (FromThen e1 e2) =
-        liftM2 FromThen
-                (addTickLHsExpr e1)
-                (addTickLHsExpr e2)
-addTickArithSeqInfo (FromTo e1 e2) =
-        liftM2 FromTo
-                (addTickLHsExpr e1)
-                (addTickLHsExpr e2)
-addTickArithSeqInfo (FromThenTo e1 e2 e3) =
-        liftM3 FromThenTo
-                (addTickLHsExpr e1)
-                (addTickLHsExpr e2)
-                (addTickLHsExpr e3)
-
-liftL :: (Monad m) => (a -> m a) -> Located a -> m (Located a)
-liftL f (L loc a) = do
-  a' <- f a
-  return $ L loc a'
-
-data TickTransState = TT { tickBoxCount:: Int
-                         , mixEntries  :: [MixEntry_]
-                         , breakCount  :: Int
-                         , breaks      :: [MixEntry_]
-                         , uniqSupply  :: UniqSupply
-                         }
-
-data TickTransEnv = TTE { fileName     :: FastString
-                        , density      :: TickDensity
-                        , tte_dflags   :: DynFlags
-                        , exports      :: NameSet
-                        , inlines      :: VarSet
-                        , declPath     :: [String]
-                        , inScope      :: VarSet
-                        , blackList    :: Map SrcSpan ()
-                        , this_mod     :: Module
-                        , tickishType  :: TickishType
-                        }
-
---      deriving Show
-
-data TickishType = ProfNotes | HpcTicks | Breakpoints | SourceNotes
-                 deriving (Eq)
-
-coveragePasses :: DynFlags -> [TickishType]
-coveragePasses dflags =
-    ifa (hscTarget dflags == HscInterpreted) Breakpoints $
-    ifa (gopt Opt_Hpc dflags)                HpcTicks $
-    ifa (gopt Opt_SccProfilingOn dflags &&
-         profAuto dflags /= NoProfAuto)      ProfNotes $
-    ifa (gopt Opt_Debug dflags)              SourceNotes []
-  where ifa f x xs | f         = x:xs
-                   | otherwise = xs
-
--- | Tickishs that only make sense when their source code location
--- refers to the current file. This might not always be true due to
--- LINE pragmas in the code - which would confuse at least HPC.
-tickSameFileOnly :: TickishType -> Bool
-tickSameFileOnly HpcTicks = True
-tickSameFileOnly _other   = False
-
-type FreeVars = OccEnv Id
-noFVs :: FreeVars
-noFVs = emptyOccEnv
-
--- Note [freevars]
---   For breakpoints we want to collect the free variables of an
---   expression for pinning on the HsTick.  We don't want to collect
---   *all* free variables though: in particular there's no point pinning
---   on free variables that are will otherwise be in scope at the GHCi
---   prompt, which means all top-level bindings.  Unfortunately detecting
---   top-level bindings isn't easy (collectHsBindsBinders on the top-level
---   bindings doesn't do it), so we keep track of a set of "in-scope"
---   variables in addition to the free variables, and the former is used
---   to filter additions to the latter.  This gives us complete control
---   over what free variables we track.
-
-data TM a = TM { unTM :: TickTransEnv -> TickTransState -> (a,FreeVars,TickTransState) }
-        -- a combination of a state monad (TickTransState) and a writer
-        -- monad (FreeVars).
-
-instance Functor TM where
-    fmap = liftM
-
-instance Applicative TM where
-    pure = return
-    (<*>) = ap
-
-instance Monad TM where
-  return a = TM $ \ _env st -> (a,noFVs,st)
-  (TM m) >>= k = TM $ \ env st ->
-                                case m env st of
-                                  (r1,fv1,st1) ->
-                                     case unTM (k r1) env st1 of
-                                       (r2,fv2,st2) ->
-                                          (r2, fv1 `plusOccEnv` fv2, st2)
-
-instance HasDynFlags TM where
-  getDynFlags = TM $ \ env st -> (tte_dflags env, noFVs, st)
-
-instance MonadUnique TM where
-  getUniqueSupplyM = TM $ \_ st -> (uniqSupply st, noFVs, st)
-  getUniqueM = TM $ \_ st -> let (u, us') = takeUniqFromSupply (uniqSupply st)
-                             in (u, noFVs, st { uniqSupply = us' })
-
-getState :: TM TickTransState
-getState = TM $ \ _ st -> (st, noFVs, st)
-
-setState :: (TickTransState -> TickTransState) -> TM ()
-setState f = TM $ \ _ st -> ((), noFVs, f st)
-
-getEnv :: TM TickTransEnv
-getEnv = TM $ \ env st -> (env, noFVs, st)
-
-withEnv :: (TickTransEnv -> TickTransEnv) -> TM a -> TM a
-withEnv f (TM m) = TM $ \ env st ->
-                                 case m (f env) st of
-                                   (a, fvs, st') -> (a, fvs, st')
-
-getDensity :: TM TickDensity
-getDensity = TM $ \env st -> (density env, noFVs, st)
-
-ifDensity :: TickDensity -> TM a -> TM a -> TM a
-ifDensity d th el = do d0 <- getDensity; if d == d0 then th else el
-
-getFreeVars :: TM a -> TM (FreeVars, a)
-getFreeVars (TM m)
-  = TM $ \ env st -> case m env st of (a, fv, st') -> ((fv,a), fv, st')
-
-freeVar :: Id -> TM ()
-freeVar id = TM $ \ env st ->
-                if id `elemVarSet` inScope env
-                   then ((), unitOccEnv (nameOccName (idName id)) id, st)
-                   else ((), noFVs, st)
-
-addPathEntry :: String -> TM a -> TM a
-addPathEntry nm = withEnv (\ env -> env { declPath = declPath env ++ [nm] })
-
-getPathEntry :: TM [String]
-getPathEntry = declPath `liftM` getEnv
-
-getFileName :: TM FastString
-getFileName = fileName `liftM` getEnv
-
-isGoodSrcSpan' :: SrcSpan -> Bool
-isGoodSrcSpan' pos@(RealSrcSpan _) = srcSpanStart pos /= srcSpanEnd pos
-isGoodSrcSpan' (UnhelpfulSpan _) = False
-
-isGoodTickSrcSpan :: SrcSpan -> TM Bool
-isGoodTickSrcSpan pos = do
-  file_name <- getFileName
-  tickish <- tickishType `liftM` getEnv
-  let need_same_file = tickSameFileOnly tickish
-      same_file      = Just file_name == srcSpanFileName_maybe pos
-  return (isGoodSrcSpan' pos && (not need_same_file || same_file))
-
-ifGoodTickSrcSpan :: SrcSpan -> TM a -> TM a -> TM a
-ifGoodTickSrcSpan pos then_code else_code = do
-  good <- isGoodTickSrcSpan pos
-  if good then then_code else else_code
-
-bindLocals :: [Id] -> TM a -> TM a
-bindLocals new_ids (TM m)
-  = TM $ \ env st ->
-                 case m env{ inScope = inScope env `extendVarSetList` new_ids } st of
-                   (r, fv, st') -> (r, fv `delListFromOccEnv` occs, st')
-  where occs = [ nameOccName (idName id) | id <- new_ids ]
-
-isBlackListed :: SrcSpan -> TM Bool
-isBlackListed pos = TM $ \ env st ->
-              case Map.lookup pos (blackList env) of
-                Nothing -> (False,noFVs,st)
-                Just () -> (True,noFVs,st)
-
--- the tick application inherits the source position of its
--- expression argument to support nested box allocations
-allocTickBox :: BoxLabel -> Bool -> Bool -> SrcSpan -> TM (HsExpr Id)
-             -> TM (LHsExpr Id)
-allocTickBox boxLabel countEntries topOnly pos m =
-  ifGoodTickSrcSpan pos (do
-    (fvs, e) <- getFreeVars m
-    env <- getEnv
-    tickish <- mkTickish boxLabel countEntries topOnly pos fvs (declPath env)
-    return (L pos (HsTick tickish (L pos e)))
-  ) (do
-    e <- m
-    return (L pos e)
-  )
-
--- the tick application inherits the source position of its
--- expression argument to support nested box allocations
-allocATickBox :: BoxLabel -> Bool -> Bool -> SrcSpan -> FreeVars
-              -> TM (Maybe (Tickish Id))
-allocATickBox boxLabel countEntries topOnly  pos fvs =
-  ifGoodTickSrcSpan pos (do
-    let
-      mydecl_path = case boxLabel of
-                      TopLevelBox x -> x
-                      LocalBox xs  -> xs
-                      _ -> panic "allocATickBox"
-    tickish <- mkTickish boxLabel countEntries topOnly pos fvs mydecl_path
-    return (Just tickish)
-  ) (return Nothing)
-
-
-mkTickish :: BoxLabel -> Bool -> Bool -> SrcSpan -> OccEnv Id -> [String]
-          -> TM (Tickish Id)
-mkTickish boxLabel countEntries topOnly pos fvs decl_path = do
-
-  let ids = filter (not . isUnLiftedType . idType) $ occEnvElts fvs
-          -- unlifted types cause two problems here:
-          --   * we can't bind them  at the GHCi prompt
-          --     (bindLocalsAtBreakpoint already fliters them out),
-          --   * the simplifier might try to substitute a literal for
-          --     the Id, and we can't handle that.
-
-      me = (pos, decl_path, map (nameOccName.idName) ids, boxLabel)
-
-      cc_name | topOnly   = head decl_path
-              | otherwise = concat (intersperse "." decl_path)
-
-  dflags <- getDynFlags
-  env <- getEnv
-  case tickishType env of
-    HpcTicks -> do
-      c <- liftM tickBoxCount getState
-      setState $ \st -> st { tickBoxCount = c + 1
-                           , mixEntries = me : mixEntries st }
-      return $ HpcTick (this_mod env) c
-
-    ProfNotes -> do
-      ccUnique <- getUniqueM
-      let cc = mkUserCC (mkFastString cc_name) (this_mod env) pos ccUnique
-          count = countEntries && gopt Opt_ProfCountEntries dflags
-      return $ ProfNote cc count True{-scopes-}
-
-    Breakpoints -> do
-      c <- liftM breakCount getState
-      setState $ \st -> st { breakCount = c + 1
-                           , breaks = me:breaks st }
-      return $ Breakpoint c ids
-
-    SourceNotes | RealSrcSpan pos' <- pos ->
-      return $ SourceNote pos' cc_name
-
-    _otherwise -> panic "mkTickish: bad source span!"
-
-
-allocBinTickBox :: (Bool -> BoxLabel) -> SrcSpan -> TM (HsExpr Id)
-                -> TM (LHsExpr Id)
-allocBinTickBox boxLabel pos m = do
-  env <- getEnv
-  case tickishType env of
-    HpcTicks -> do e <- liftM (L pos) m
-                   ifGoodTickSrcSpan pos
-                     (mkBinTickBoxHpc boxLabel pos e)
-                     (return e)
-    _other   -> allocTickBox (ExpBox False) False False pos m
-
-mkBinTickBoxHpc :: (Bool -> BoxLabel) -> SrcSpan -> LHsExpr Id
-                -> TM (LHsExpr Id)
-mkBinTickBoxHpc boxLabel pos e =
- TM $ \ env st ->
-  let meT = (pos,declPath env, [],boxLabel True)
-      meF = (pos,declPath env, [],boxLabel False)
-      meE = (pos,declPath env, [],ExpBox False)
-      c = tickBoxCount st
-      mes = mixEntries st
-  in
-             ( L pos $ HsTick (HpcTick (this_mod env) c) $ L pos $ HsBinTick (c+1) (c+2) e
-           -- notice that F and T are reversed,
-           -- because we are building the list in
-           -- reverse...
-             , noFVs
-             , st {tickBoxCount=c+3 , mixEntries=meF:meT:meE:mes}
-             )
-
-mkHpcPos :: SrcSpan -> HpcPos
-mkHpcPos pos@(RealSrcSpan s)
-   | isGoodSrcSpan' pos = toHpcPos (srcSpanStartLine s,
-                                    srcSpanStartCol s,
-                                    srcSpanEndLine s,
-                                    srcSpanEndCol s - 1)
-                              -- the end column of a SrcSpan is one
-                              -- greater than the last column of the
-                              -- span (see SrcLoc), whereas HPC
-                              -- expects to the column range to be
-                              -- inclusive, hence we subtract one above.
-mkHpcPos _ = panic "bad source span; expected such spans to be filtered out"
-
-hpcSrcSpan :: SrcSpan
-hpcSrcSpan = mkGeneralSrcSpan (fsLit "Haskell Program Coverage internals")
-
-matchesOneOfMany :: [LMatch Id body] -> Bool
-matchesOneOfMany lmatches = sum (map matchCount lmatches) > 1
-  where
-        matchCount (L _ (Match _ _pats _ty (GRHSs grhss _binds))) = length grhss
-
-type MixEntry_ = (SrcSpan, [String], [OccName], BoxLabel)
-
--- For the hash value, we hash everything: the file name,
---  the timestamp of the original source file, the tab stop,
---  and the mix entries. We cheat, and hash the show'd string.
--- This hash only has to be hashed at Mix creation time,
--- and is for sanity checking only.
-
-mixHash :: FilePath -> UTCTime -> Int -> [MixEntry] -> Int
-mixHash file tm tabstop entries = fromIntegral $ hashString
-        (show $ Mix file tm 0 tabstop entries)
-
-{-
-************************************************************************
-*                                                                      *
-*              initialisation
-*                                                                      *
-************************************************************************
-
-Each module compiled with -fhpc declares an initialisation function of
-the form `hpc_init_<module>()`, which is emitted into the _stub.c file
-and annotated with __attribute__((constructor)) so that it gets
-executed at startup time.
-
-The function's purpose is to call hs_hpc_module to register this
-module with the RTS, and it looks something like this:
-
-static void hpc_init_Main(void) __attribute__((constructor));
-static void hpc_init_Main(void)
-{extern StgWord64 _hpc_tickboxes_Main_hpc[];
- hs_hpc_module("Main",8,1150288664,_hpc_tickboxes_Main_hpc);}
--}
-
-hpcInitCode :: Module -> HpcInfo -> SDoc
-hpcInitCode _ (NoHpcInfo {}) = Outputable.empty
-hpcInitCode this_mod (HpcInfo tickCount hashNo)
- = vcat
-    [ text "static void hpc_init_" <> ppr this_mod
-         <> text "(void) __attribute__((constructor));"
-    , text "static void hpc_init_" <> ppr this_mod <> text "(void)"
-    , braces (vcat [
-        ptext (sLit "extern StgWord64 ") <> tickboxes <>
-               ptext (sLit "[]") <> semi,
-        ptext (sLit "hs_hpc_module") <>
-          parens (hcat (punctuate comma [
-              doubleQuotes full_name_str,
-              int tickCount, -- really StgWord32
-              int hashNo,    -- really StgWord32
-              tickboxes
-            ])) <> semi
-       ])
-    ]
-  where
-    tickboxes = ppr (mkHpcTicksLabel $ this_mod)
-
-    module_name  = hcat (map (text.charToC) $
-                         bytesFS (moduleNameFS (Module.moduleName this_mod)))
-    package_name = hcat (map (text.charToC) $
-                         bytesFS (packageKeyFS  (modulePackageKey this_mod)))
-    full_name_str
-       | modulePackageKey this_mod == mainPackageKey
-       = module_name
-       | otherwise
-       = package_name <> char '/' <> module_name
diff --git a/src/Language/Haskell/Liquid/Desugar710/Desugar.hs b/src/Language/Haskell/Liquid/Desugar710/Desugar.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/Desugar.hs
+++ /dev/null
@@ -1,485 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-The Desugarer: turning HsSyn into Core.
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.Desugar ( deSugarWithLoc, deSugar, deSugarExpr ) where
-
-import Prelude hiding (error)
-import DynFlags
-import HscTypes
-import HsSyn
-import TcRnTypes
-import TcRnMonad ( finalSafeMode )
-import MkIface
-import Id
-import Name
-import Type
-import FamInstEnv
-import Coercion
-import InstEnv
-import Class
-import Avail
-import CoreSyn
-import CoreSubst
-import PprCore
-import DsMonad
-import Language.Haskell.Liquid.Desugar710.DsExpr
-import Language.Haskell.Liquid.Desugar710.DsBinds
-import Language.Haskell.Liquid.Desugar710.DsForeign
-import Module
-import NameSet
-import NameEnv
-import Rules
-import TysPrim (eqReprPrimTyCon)
-import TysWiredIn (coercibleTyCon )
-import BasicTypes       ( Activation(.. ) )
-import CoreMonad        ( CoreToDo(..) )
-import CoreLint         ( endPassIO )
-import MkCore
-import FastString
-import ErrUtils
-import Outputable
-import SrcLoc
-import Coverage
-import Util
-import MonadUtils
-import OrdList
-import StaticPtrTable
-import Data.List
-import Data.IORef
-import Control.Monad( when )
-
-{-
-************************************************************************
-*                                                                      *
-*              The main function: deSugar
-*                                                                      *
-************************************************************************
--}
-
--- | Main entry point to the desugarer.
-deSugarWithLoc, deSugar :: HscEnv -> ModLocation -> TcGblEnv -> IO (Messages, Maybe ModGuts)
--- Can modify PCS by faulting in more declarations
-
-deSugarWithLoc = deSugar
-
-deSugar hsc_env
-        mod_loc
-        tcg_env@(TcGblEnv { tcg_mod          = mod,
-                            tcg_src          = hsc_src,
-                            tcg_type_env     = type_env,
-                            tcg_imports      = imports,
-                            tcg_exports      = exports,
-                            tcg_keep         = keep_var,
-                            tcg_th_splice_used = tc_splice_used,
-                            tcg_rdr_env      = rdr_env,
-                            tcg_fix_env      = fix_env,
-                            tcg_inst_env     = inst_env,
-                            tcg_fam_inst_env = fam_inst_env,
-                            tcg_warns        = warns,
-                            tcg_anns         = anns,
-                            tcg_binds        = binds,
-                            tcg_imp_specs    = imp_specs,
-                            tcg_dependent_files = dependent_files,
-                            tcg_ev_binds     = ev_binds,
-                            tcg_fords        = fords,
-                            tcg_rules        = rules,
-                            tcg_vects        = vects,
-                            tcg_patsyns      = patsyns,
-                            tcg_tcs          = tcs,
-                            tcg_insts        = insts,
-                            tcg_fam_insts    = fam_insts,
-                            tcg_hpc          = other_hpc_info})
-
-  = do { let dflags = hsc_dflags hsc_env
-             print_unqual = mkPrintUnqualified dflags rdr_env
-        ; showPass dflags "Desugar"
-
-        -- Desugar the program
-        ; let export_set = availsToNameSet exports
-              target     = hscTarget dflags
-              hpcInfo    = emptyHpcInfo other_hpc_info
-
-        ; (binds_cvr, ds_hpc_info, modBreaks)
-                         <- if not (isHsBootOrSig hsc_src)
-                              then addTicksToBinds dflags mod mod_loc export_set
-                                          (typeEnvTyCons type_env) binds
-                              else return (binds, hpcInfo, emptyModBreaks)
-
-        ; (msgs, mb_res) <- initDs hsc_env mod rdr_env type_env fam_inst_env $
-                       do { ds_ev_binds <- dsEvBinds ev_binds
-                          ; core_prs <- dsTopLHsBinds binds_cvr
-                          ; (spec_prs, spec_rules) <- dsImpSpecs imp_specs
-                          ; (ds_fords, foreign_prs) <- dsForeigns fords
-                          ; ds_rules <- mapMaybeM dsRule rules
-                          ; ds_vects <- mapM dsVect vects
-                          ; stBinds <- dsGetStaticBindsVar >>=
-                                           liftIO . readIORef
-                          ; let hpc_init
-                                  | gopt Opt_Hpc dflags = hpcInitCode mod ds_hpc_info
-                                  | otherwise = empty
-                                -- Stub to insert the static entries of the
-                                -- module into the static pointer table
-                                spt_init = sptInitCode mod stBinds
-                          ; return ( ds_ev_binds
-                                   , foreign_prs `appOL` core_prs `appOL` spec_prs
-                                                 `appOL` toOL (map snd stBinds)
-                                   , spec_rules ++ ds_rules, ds_vects
-                                   , ds_fords `appendStubC` hpc_init
-                                              `appendStubC` spt_init) }
-
-        ; case mb_res of {
-           Nothing -> return (msgs, Nothing) ;
-           Just (ds_ev_binds, all_prs, all_rules, vects0, ds_fords) -> do
-
-     do {       -- Add export flags to bindings
-          keep_alive <- readIORef keep_var
-        ; let (rules_for_locals, rules_for_imps) = partition isLocalRule all_rules
-              final_prs = addExportFlagsAndRules target export_set keep_alive
-                                                 rules_for_locals (fromOL all_prs)
-
-              final_pgm = combineEvBinds ds_ev_binds final_prs
-        -- Notice that we put the whole lot in a big Rec, even the foreign binds
-        -- When compiling PrelFloat, which defines data Float = F# Float#
-        -- we want F# to be in scope in the foreign marshalling code!
-        -- You might think it doesn't matter, but the simplifier brings all top-level
-        -- things into the in-scope set before simplifying; so we get no unfolding for F#!
-
-        ; (ds_binds, ds_rules_for_imps, ds_vects)
-            <- simpleOptPgm dflags mod final_pgm rules_for_imps vects0
-                         -- The simpleOptPgm gets rid of type
-                         -- bindings plus any stupid dead code
-
-        ; endPassIO hsc_env print_unqual CoreDesugarOpt ds_binds ds_rules_for_imps
-
-        ; let used_names = mkUsedNames tcg_env
-        ; deps <- mkDependencies tcg_env
-
-        ; used_th <- readIORef tc_splice_used
-        ; dep_files <- readIORef dependent_files
-        ; safe_mode <- finalSafeMode dflags tcg_env
-
-        ; let mod_guts = ModGuts {
-                mg_module       = mod,
-                mg_boot         = hsc_src == HsBootFile,
-                mg_exports      = exports,
-                mg_deps         = deps,
-                mg_used_names   = used_names,
-                mg_used_th      = used_th,
-                mg_dir_imps     = imp_mods imports,
-                mg_rdr_env      = rdr_env,
-                mg_fix_env      = fix_env,
-                mg_warns        = warns,
-                mg_anns         = anns,
-                mg_tcs          = tcs,
-                mg_insts        = insts,
-                mg_fam_insts    = fam_insts,
-                mg_inst_env     = inst_env,
-                mg_fam_inst_env = fam_inst_env,
-                mg_patsyns      = patsyns,
-                mg_rules        = ds_rules_for_imps,
-                mg_binds        = ds_binds,
-                mg_foreign      = ds_fords,
-                mg_hpc_info     = ds_hpc_info,
-                mg_modBreaks    = modBreaks,
-                mg_vect_decls   = ds_vects,
-                mg_vect_info    = noVectInfo,
-                mg_safe_haskell = safe_mode,
-                mg_trust_pkg    = imp_trust_own_pkg imports,
-                mg_dependent_files = dep_files
-              }
-        ; return (msgs, Just mod_guts)
-        }}}
-
-dsImpSpecs :: [LTcSpecPrag] -> DsM (OrdList (Id,CoreExpr), [CoreRule])
-dsImpSpecs imp_specs
- = do { spec_prs <- mapMaybeM (dsSpec Nothing) imp_specs
-      ; let (spec_binds, spec_rules) = unzip spec_prs
-      ; return (concatOL spec_binds, spec_rules) }
-
-combineEvBinds :: [CoreBind] -> [(Id,CoreExpr)] -> [CoreBind]
--- Top-level bindings can include coercion bindings, but not via superclasses
--- See Note [Top-level evidence]
-combineEvBinds [] val_prs
-  = [Rec val_prs]
-combineEvBinds (NonRec b r : bs) val_prs
-  | isId b    = combineEvBinds bs ((b,r):val_prs)
-  | otherwise = NonRec b r : combineEvBinds bs val_prs
-combineEvBinds (Rec prs : bs) val_prs
-  = combineEvBinds bs (prs ++ val_prs)
-
-{-
-Note [Top-level evidence]
-~~~~~~~~~~~~~~~~~~~~~~~~~
-Top-level evidence bindings may be mutually recursive with the top-level value
-bindings, so we must put those in a Rec.  But we can't put them *all* in a Rec
-because the occurrence analyser doesn't teke account of type/coercion variables
-when computing dependencies.
-
-So we pull out the type/coercion variables (which are in dependency order),
-and Rec the rest.
--}
-
-deSugarExpr :: HscEnv -> LHsExpr Id -> IO (Messages, Maybe CoreExpr)
-
-deSugarExpr hsc_env tc_expr
-  = do { let dflags       = hsc_dflags hsc_env
-             icntxt       = hsc_IC hsc_env
-             rdr_env      = ic_rn_gbl_env icntxt
-             type_env     = mkTypeEnvWithImplicits (ic_tythings icntxt)
-             fam_insts    = snd (ic_instances icntxt)
-             fam_inst_env = extendFamInstEnvList emptyFamInstEnv fam_insts
-             -- This stuff is a half baked version of TcRnDriver.setInteractiveContext
-
-       ; showPass dflags "Desugar"
-
-         -- Do desugaring
-       ; (msgs, mb_core_expr) <- initDs hsc_env (icInteractiveModule icntxt) rdr_env
-                                        type_env fam_inst_env $
-                                 dsLExpr tc_expr
-
-       ; case mb_core_expr of
-            Nothing   -> return ()
-            Just expr -> dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
-
-       ; return (msgs, mb_core_expr) }
-
-{-
-************************************************************************
-*                                                                      *
-*              Add rules and export flags to binders
-*                                                                      *
-************************************************************************
--}
-
-addExportFlagsAndRules
-    :: HscTarget -> NameSet -> NameSet -> [CoreRule]
-    -> [(Id, t)] -> [(Id, t)]
-addExportFlagsAndRules target exports keep_alive rules prs
-  = mapFst add_one prs
-  where
-    add_one bndr = add_rules name (add_export name bndr)
-       where
-         name = idName bndr
-
-    ---------- Rules --------
-        -- See Note [Attach rules to local ids]
-        -- NB: the binder might have some existing rules,
-        -- arising from specialisation pragmas
-    add_rules name bndr
-        | Just rules <- lookupNameEnv rule_base name
-        = bndr `addIdSpecialisations` rules
-        | otherwise
-        = bndr
-    rule_base = extendRuleBaseList emptyRuleBase rules
-
-    ---------- Export flag --------
-    -- See Note [Adding export flags]
-    add_export name bndr
-        | dont_discard name = setIdExported bndr
-        | otherwise         = bndr
-
-    dont_discard :: Name -> Bool
-    dont_discard name = is_exported name
-                     || name `elemNameSet` keep_alive
-
-        -- In interactive mode, we don't want to discard any top-level
-        -- entities at all (eg. do not inline them away during
-        -- simplification), and retain them all in the TypeEnv so they are
-        -- available from the command line.
-        --
-        -- isExternalName separates the user-defined top-level names from those
-        -- introduced by the type checker.
-    is_exported :: Name -> Bool
-    is_exported | targetRetainsAllBindings target = isExternalName
-                | otherwise                       = (`elemNameSet` exports)
-
-{-
-Note [Adding export flags]
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-Set the no-discard flag if either
-        a) the Id is exported
-        b) it's mentioned in the RHS of an orphan rule
-        c) it's in the keep-alive set
-
-It means that the binding won't be discarded EVEN if the binding
-ends up being trivial (v = w) -- the simplifier would usually just
-substitute w for v throughout, but we don't apply the substitution to
-the rules (maybe we should?), so this substitution would make the rule
-bogus.
-
-You might wonder why exported Ids aren't already marked as such;
-it's just because the type checker is rather busy already and
-I didn't want to pass in yet another mapping.
-
-Note [Attach rules to local ids]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Find the rules for locally-defined Ids; then we can attach them
-to the binders in the top-level bindings
-
-Reason
-  - It makes the rules easier to look up
-  - It means that transformation rules and specialisations for
-    locally defined Ids are handled uniformly
-  - It keeps alive things that are referred to only from a rule
-    (the occurrence analyser knows about rules attached to Ids)
-  - It makes sure that, when we apply a rule, the free vars
-    of the RHS are more likely to be in scope
-  - The imported rules are carried in the in-scope set
-    which is extended on each iteration by the new wave of
-    local binders; any rules which aren't on the binding will
-    thereby get dropped
-
-
-************************************************************************
-*                                                                      *
-*              Desugaring transformation rules
-*                                                                      *
-************************************************************************
--}
-
-dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule)
-dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
-  = putSrcSpanDs loc $
-    do  { let bndrs' = [var | L _ (RuleBndr (L _ var)) <- vars]
-
-        ; lhs' <- unsetGOptM Opt_EnableRewriteRules $
-                  unsetWOptM Opt_WarnIdentities $
-                  dsLExpr lhs   -- Note [Desugaring RULE left hand sides]
-
-        ; rhs' <- dsLExpr rhs
-        ; dflags <- getDynFlags
-
-        ; (bndrs'', lhs'', rhs'') <- unfold_coerce bndrs' lhs' rhs'
-
-        -- Substitute the dict bindings eagerly,
-        -- and take the body apart into a (f args) form
-        ; case decomposeRuleLhs bndrs'' lhs'' of {
-                Left msg -> do { warnDs msg; return Nothing } ;
-                Right (final_bndrs, fn_id, args) -> do
-
-        { let is_local = isLocalId fn_id
-                -- NB: isLocalId is False of implicit Ids.  This is good because
-                -- we don't want to attach rules to the bindings of implicit Ids,
-                -- because they don't show up in the bindings until just before code gen
-              fn_name   = idName fn_id
-              final_rhs = simpleOptExpr rhs''    -- De-crap it
-              rule      = mkRule False {- Not auto -} is_local
-                                 (unLoc name) act fn_name final_bndrs args
-                                 final_rhs
-
-              inline_shadows_rule   -- Function can be inlined before rule fires
-                | wopt Opt_WarnInlineRuleShadowing dflags
-                , isLocalId fn_id || hasSomeUnfolding (idUnfolding fn_id)
-                       -- If imported with no unfolding, no worries
-                = case (idInlineActivation fn_id, act) of
-                    (NeverActive, _)    -> False
-                    (AlwaysActive, _)   -> True
-                    (ActiveBefore {}, _) -> True
-                    (ActiveAfter {}, NeverActive)     -> True
-                    (ActiveAfter n, ActiveAfter r)    -> r < n  -- Rule active strictly first
-                    (ActiveAfter {}, AlwaysActive)    -> False
-                    (ActiveAfter {}, ActiveBefore {}) -> False
-                | otherwise = False
-
-        ; when inline_shadows_rule $
-          warnDs (vcat [ hang (ptext (sLit "Rule")
-                               <+> doubleQuotes (ftext $ unLoc name)
-                               <+> ptext (sLit "may never fire"))
-                            2 (ptext (sLit "because") <+> quotes (ppr fn_id)
-                               <+> ptext (sLit "might inline first"))
-                       , ptext (sLit "Probable fix: add an INLINE[n] or NOINLINE[n] pragma on")
-                         <+> quotes (ppr fn_id) ])
-
-        ; return (Just rule)
-        } } }
-
--- See Note [Desugaring coerce as cast]
-unfold_coerce :: [Id] -> CoreExpr -> CoreExpr -> DsM ([Var], CoreExpr, CoreExpr)
-unfold_coerce bndrs lhs rhs = do
-    (bndrs', wrap) <- go bndrs
-    return (bndrs', wrap lhs, wrap rhs)
-  where
-    go :: [Id] -> DsM ([Id], CoreExpr -> CoreExpr)
-    go []     = return ([], id)
-    go (v:vs)
-        | Just (tc, args) <- splitTyConApp_maybe (idType v)
-        , tc == coercibleTyCon = do
-            let ty' = mkTyConApp eqReprPrimTyCon args
-            v' <- mkDerivedLocalM mkRepEqOcc v ty'
-
-            (bndrs, wrap) <- go vs
-            return (v':bndrs, mkCoreLet (NonRec v (mkEqBox (mkCoVarCo v'))) . wrap)
-        | otherwise = do
-            (bndrs,wrap) <- go vs
-            return (v:bndrs, wrap)
-
-{-
-Note [Desugaring RULE left hand sides]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-For the LHS of a RULE we do *not* want to desugar
-    [x]   to    build (\cn. x `c` n)
-We want to leave explicit lists simply as chains
-of cons's. We can achieve that slightly indirectly by
-switching off EnableRewriteRules.  See DsExpr.dsExplicitList.
-
-That keeps the desugaring of list comprehensions simple too.
-
-
-
-Nor do we want to warn of conversion identities on the LHS;
-the rule is precisly to optimise them:
-  {-# RULES "fromRational/id" fromRational = id :: Rational -> Rational #-}
-
-
-Note [Desugaring coerce as cast]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We want the user to express a rule saying roughly “mapping a coercion over a
-list can be replaced by a coercion”. But the cast operator of Core (▷) cannot
-be written in Haskell. So we use `coerce` for that (#2110). The user writes
-    map coerce = coerce
-as a RULE, and this optimizes any kind of mapped' casts aways, including `map
-MkNewtype`.
-
-For that we replace any forall'ed `c :: Coercible a b` value in a RULE by
-corresponding `co :: a ~#R b` and wrap the LHS and the RHS in
-`let c = MkCoercible co in ...`. This is later simplified to the desired form
-by simpleOptExpr (for the LHS) resp. the simplifiers (for the RHS).
-
-************************************************************************
-*                                                                      *
-*              Desugaring vectorisation declarations
-*                                                                      *
-************************************************************************
--}
-
-dsVect :: LVectDecl Id -> DsM CoreVect
-dsVect (L loc (HsVect _ (L _ v) rhs))
-  = putSrcSpanDs loc $
-    do { rhs' <- dsLExpr rhs
-       ; return $ Vect v rhs'
-       }
-dsVect (L _loc (HsNoVect _ (L _ v)))
-  = return $ NoVect v
-dsVect (L _loc (HsVectTypeOut isScalar tycon rhs_tycon))
-  = return $ VectType isScalar tycon' rhs_tycon
-  where
-    tycon' | Just ty <- coreView $ mkTyConTy tycon
-           , (tycon', []) <- splitTyConApp ty      = tycon'
-           | otherwise                             = tycon
-dsVect vd@(L _ (HsVectTypeIn _ _ _ _))
-  = pprPanic "Desugar.dsVect: unexpected 'HsVectTypeIn'" (ppr vd)
-dsVect (L _loc (HsVectClassOut cls))
-  = return $ VectClass (classTyCon cls)
-dsVect vc@(L _ (HsVectClassIn _ _))
-  = pprPanic "Desugar.dsVect: unexpected 'HsVectClassIn'" (ppr vc)
-dsVect (L _loc (HsVectInstOut inst))
-  = return $ VectInst (instanceDFunId inst)
-dsVect vi@(L _ (HsVectInstIn _))
-  = pprPanic "Desugar.dsVect: unexpected 'HsVectInstIn'" (ppr vi)
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsArrows.hs b/src/Language/Haskell/Liquid/Desugar710/DsArrows.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsArrows.hs
+++ /dev/null
@@ -1,1179 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-Desugaring arrow commands
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.DsArrows ( dsProcExpr ) where
-
--- #include "HsVersions.h"
-
-import Language.Haskell.Liquid.Desugar710.Match
-import Language.Haskell.Liquid.Desugar710.DsUtils
-import DsMonad
-
-import HsSyn    hiding (collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectLStmtBinders, collectStmtBinders )
-import TcHsSyn
-
--- NB: The desugarer, which straddles the source and Core worlds, sometimes
---     needs to see source types (newtypes etc), and sometimes not
---     So WATCH OUT; check each use of split*Ty functions.
--- Sigh.  This is a pain.
-
-import {-# SOURCE #-} Language.Haskell.Liquid.Desugar710.DsExpr ( dsExpr, dsLExpr, dsLocalBinds )
-
-import TcType
-import TcEvidence
-import CoreSyn
-import CoreFVs
-import CoreUtils
-import MkCore
-import Language.Haskell.Liquid.Desugar710.DsBinds (dsHsWrapper)
-import qualified Language.Haskell.Liquid.Types.Errors as Err
-
-import Name
-import Var
-import Id
-import DataCon
-import TysWiredIn
-import BasicTypes
-import PrelNames
-import Outputable
-import Bag
-import VarSet
-import SrcLoc
-import ListSetOps( assocDefault )
-import FastString
-import Data.List
-
-data DsCmdEnv = DsCmdEnv {
-        arr_id, compose_id, first_id, app_id, choice_id, loop_id :: CoreExpr
-    }
-
-mkCmdEnv :: CmdSyntaxTable Id -> DsM ([CoreBind], DsCmdEnv)
--- See Note [CmdSyntaxTable] in HsExpr
-mkCmdEnv tc_meths
-  = do { (meth_binds, prs) <- mapAndUnzipM mk_bind tc_meths
-       ; return (meth_binds, DsCmdEnv {
-               arr_id     = Var (find_meth prs arrAName),
-               compose_id = Var (find_meth prs composeAName),
-               first_id   = Var (find_meth prs firstAName),
-               app_id     = Var (find_meth prs appAName),
-               choice_id  = Var (find_meth prs choiceAName),
-               loop_id    = Var (find_meth prs loopAName)
-             }) }
-  where
-    mk_bind (std_name, expr)
-      = do { rhs <- dsExpr expr
-           ; id <- newSysLocalDs (exprType rhs)
-           ; return (NonRec id rhs, (std_name, id)) }
-
-    find_meth prs std_name
-      = assocDefault (mk_panic std_name) prs std_name
-    mk_panic std_name = pprPanic "mkCmdEnv" (ptext (sLit "Not found:") <+> ppr std_name)
-
--- arr :: forall b c. (b -> c) -> a b c
-do_arr :: DsCmdEnv -> Type -> Type -> CoreExpr -> CoreExpr
-do_arr ids b_ty c_ty f = mkApps (arr_id ids) [Type b_ty, Type c_ty, f]
-
--- (>>>) :: forall b c d. a b c -> a c d -> a b d
-do_compose :: DsCmdEnv -> Type -> Type -> Type ->
-                CoreExpr -> CoreExpr -> CoreExpr
-do_compose ids b_ty c_ty d_ty f g
-  = mkApps (compose_id ids) [Type b_ty, Type c_ty, Type d_ty, f, g]
-
--- first :: forall b c d. a b c -> a (b,d) (c,d)
-do_first :: DsCmdEnv -> Type -> Type -> Type -> CoreExpr -> CoreExpr
-do_first ids b_ty c_ty d_ty f
-  = mkApps (first_id ids) [Type b_ty, Type c_ty, Type d_ty, f]
-
--- app :: forall b c. a (a b c, b) c
-do_app :: DsCmdEnv -> Type -> Type -> CoreExpr
-do_app ids b_ty c_ty = mkApps (app_id ids) [Type b_ty, Type c_ty]
-
--- (|||) :: forall b d c. a b d -> a c d -> a (Either b c) d
--- note the swapping of d and c
-do_choice :: DsCmdEnv -> Type -> Type -> Type ->
-                CoreExpr -> CoreExpr -> CoreExpr
-do_choice ids b_ty c_ty d_ty f g
-  = mkApps (choice_id ids) [Type b_ty, Type d_ty, Type c_ty, f, g]
-
--- loop :: forall b d c. a (b,d) (c,d) -> a b c
--- note the swapping of d and c
-do_loop :: DsCmdEnv -> Type -> Type -> Type -> CoreExpr -> CoreExpr
-do_loop ids b_ty c_ty d_ty f
-  = mkApps (loop_id ids) [Type b_ty, Type d_ty, Type c_ty, f]
-
--- premap :: forall b c d. (b -> c) -> a c d -> a b d
--- premap f g = arr f >>> g
-do_premap :: DsCmdEnv -> Type -> Type -> Type ->
-                CoreExpr -> CoreExpr -> CoreExpr
-do_premap ids b_ty c_ty d_ty f g
-   = do_compose ids b_ty c_ty d_ty (do_arr ids b_ty c_ty f) g
-
-mkFailExpr :: HsMatchContext Id -> Type -> DsM CoreExpr
-mkFailExpr ctxt ty
-  = mkErrorAppDs pAT_ERROR_ID ty (matchContextErrString ctxt)
-
--- construct CoreExpr for \ (a :: a_ty, b :: b_ty) -> a
-mkFstExpr :: Type -> Type -> DsM CoreExpr
-mkFstExpr a_ty b_ty = do
-    a_var <- newSysLocalDs a_ty
-    b_var <- newSysLocalDs b_ty
-    pair_var <- newSysLocalDs (mkCorePairTy a_ty b_ty)
-    return (Lam pair_var
-               (coreCasePair pair_var a_var b_var (Var a_var)))
-
--- construct CoreExpr for \ (a :: a_ty, b :: b_ty) -> b
-mkSndExpr :: Type -> Type -> DsM CoreExpr
-mkSndExpr a_ty b_ty = do
-    a_var <- newSysLocalDs a_ty
-    b_var <- newSysLocalDs b_ty
-    pair_var <- newSysLocalDs (mkCorePairTy a_ty b_ty)
-    return (Lam pair_var
-               (coreCasePair pair_var a_var b_var (Var b_var)))
-
-{-
-Build case analysis of a tuple.  This cannot be done in the DsM monad,
-because the list of variables is typically not yet defined.
--}
-
--- coreCaseTuple [u1..] v [x1..xn] body
---      = case v of v { (x1, .., xn) -> body }
--- But the matching may be nested if the tuple is very big
-
-coreCaseTuple :: UniqSupply -> Id -> [Id] -> CoreExpr -> CoreExpr
-coreCaseTuple uniqs scrut_var vars body
-  = mkTupleCase uniqs vars body scrut_var (Var scrut_var)
-
-coreCasePair :: Id -> Id -> Id -> CoreExpr -> CoreExpr
-coreCasePair scrut_var var1 var2 body
-  = Case (Var scrut_var) scrut_var (exprType body)
-         [(DataAlt (tupleCon BoxedTuple 2), [var1, var2], body)]
-
-mkCorePairTy :: Type -> Type -> Type
-mkCorePairTy t1 t2 = mkBoxedTupleTy [t1, t2]
-
-mkCorePairExpr :: CoreExpr -> CoreExpr -> CoreExpr
-mkCorePairExpr e1 e2 = mkCoreTup [e1, e2]
-
-mkCoreUnitExpr :: CoreExpr
-mkCoreUnitExpr = mkCoreTup []
-
-{-
-The input is divided into a local environment, which is a flat tuple
-(unless it's too big), and a stack, which is a right-nested pair.
-In general, the input has the form
-
-        ((x1,...,xn), (s1,...(sk,())...))
-
-where xi are the environment values, and si the ones on the stack,
-with s1 being the "top", the first one to be matched with a lambda.
--}
-
-envStackType :: [Id] -> Type -> Type
-envStackType ids stack_ty = mkCorePairTy (mkBigCoreVarTupTy ids) stack_ty
-
--- splitTypeAt n (t1,... (tn,t)...) = ([t1, ..., tn], t)
-splitTypeAt :: Int -> Type -> ([Type], Type)
-splitTypeAt n ty
-  | n == 0 = ([], ty)
-  | otherwise = case tcTyConAppArgs ty of
-      [t, ty'] -> let (ts, ty_r) = splitTypeAt (n-1) ty' in (t:ts, ty_r)
-      _ -> pprPanic "splitTypeAt" (ppr ty)
-
-----------------------------------------------
---              buildEnvStack
---
---      ((x1,...,xn),stk)
-
-buildEnvStack :: [Id] -> Id -> CoreExpr
-buildEnvStack env_ids stack_id
-  = mkCorePairExpr (mkBigCoreVarTup env_ids) (Var stack_id)
-
-----------------------------------------------
---              matchEnvStack
---
---      \ ((x1,...,xn),stk) -> body
---      =>
---      \ pair ->
---      case pair of (tup,stk) ->
---      case tup of (x1,...,xn) ->
---      body
-
-matchEnvStack   :: [Id]         -- x1..xn
-                -> Id           -- stk
-                -> CoreExpr     -- e
-                -> DsM CoreExpr
-matchEnvStack env_ids stack_id body = do
-    uniqs <- newUniqueSupply
-    tup_var <- newSysLocalDs (mkBigCoreVarTupTy env_ids)
-    let match_env = coreCaseTuple uniqs tup_var env_ids body
-    pair_id <- newSysLocalDs (mkCorePairTy (idType tup_var) (idType stack_id))
-    return (Lam pair_id (coreCasePair pair_id tup_var stack_id match_env))
-
-----------------------------------------------
---              matchEnv
---
---      \ (x1,...,xn) -> body
---      =>
---      \ tup ->
---      case tup of (x1,...,xn) ->
---      body
-
-matchEnv :: [Id]        -- x1..xn
-         -> CoreExpr    -- e
-         -> DsM CoreExpr
-matchEnv env_ids body = do
-    uniqs <- newUniqueSupply
-    tup_id <- newSysLocalDs (mkBigCoreVarTupTy env_ids)
-    return (Lam tup_id (coreCaseTuple uniqs tup_id env_ids body))
-
-----------------------------------------------
---              matchVarStack
---
---      case (x1, ...(xn, s)...) -> e
---      =>
---      case z0 of (x1,z1) ->
---      case zn-1 of (xn,s) ->
---      e
-matchVarStack :: [Id] -> Id -> CoreExpr -> DsM (Id, CoreExpr)
-matchVarStack [] stack_id body = return (stack_id, body)
-matchVarStack (param_id:param_ids) stack_id body = do
-    (tail_id, tail_code) <- matchVarStack param_ids stack_id body
-    pair_id <- newSysLocalDs (mkCorePairTy (idType param_id) (idType tail_id))
-    return (pair_id, coreCasePair pair_id param_id tail_id tail_code)
-
-mkHsEnvStackExpr :: [Id] -> Id -> LHsExpr Id
-mkHsEnvStackExpr env_ids stack_id
-  = mkLHsTupleExpr [mkLHsVarTuple env_ids, nlHsVar stack_id]
-
--- Translation of arrow abstraction
-
--- D; xs |-a c : () --> t'      ---> c'
--- --------------------------
--- D |- proc p -> c :: a t t'   ---> premap (\ p -> ((xs),())) c'
---
---              where (xs) is the tuple of variables bound by p
-
-dsProcExpr
-        :: LPat Id
-        -> LHsCmdTop Id
-        -> DsM CoreExpr
-dsProcExpr pat (L _ (HsCmdTop cmd _unitTy cmd_ty ids)) = do
-    (meth_binds, meth_ids) <- mkCmdEnv ids
-    let locals = mkVarSet (collectPatBinders pat)
-    (core_cmd, _free_vars, env_ids) <- dsfixCmd meth_ids locals unitTy cmd_ty cmd
-    let env_ty = mkBigCoreVarTupTy env_ids
-    let env_stk_ty = mkCorePairTy env_ty unitTy
-    let env_stk_expr = mkCorePairExpr (mkBigCoreVarTup env_ids) mkCoreUnitExpr
-    fail_expr <- mkFailExpr ProcExpr env_stk_ty
-    var <- selectSimpleMatchVarL pat
-    match_code <- matchSimply (Var var) ProcExpr pat env_stk_expr fail_expr
-    let pat_ty = hsLPatType pat
-        proc_code = do_premap meth_ids pat_ty env_stk_ty cmd_ty
-                    (Lam var match_code)
-                    core_cmd
-    return (mkLets meth_binds proc_code)
-
-{-
-Translation of a command judgement of the form
-
-        D; xs |-a c : stk --> t
-
-to an expression e such that
-
-        D |- e :: a (xs, stk) t
--}
-
-dsLCmd :: DsCmdEnv -> IdSet -> Type -> Type -> LHsCmd Id -> [Id]
-       -> DsM (CoreExpr, IdSet)
-dsLCmd ids local_vars stk_ty res_ty cmd env_ids
-  = dsCmd ids local_vars stk_ty res_ty (unLoc cmd) env_ids
-
-dsCmd   :: DsCmdEnv             -- arrow combinators
-        -> IdSet                -- set of local vars available to this command
-        -> Type                 -- type of the stack (right-nested tuple)
-        -> Type                 -- return type of the command
-        -> HsCmd Id             -- command to desugar
-        -> [Id]                 -- list of vars in the input to this command
-                                -- This is typically fed back,
-                                -- so don't pull on it too early
-        -> DsM (CoreExpr,       -- desugared expression
-                IdSet)          -- subset of local vars that occur free
-
--- D |- fun :: a t1 t2
--- D, xs |- arg :: t1
--- -----------------------------
--- D; xs |-a fun -< arg : stk --> t2
---
---              ---> premap (\ ((xs), _stk) -> arg) fun
-
-dsCmd ids local_vars stack_ty res_ty
-        (HsCmdArrApp arrow arg arrow_ty HsFirstOrderApp _)
-        env_ids = do
-    let
-        (a_arg_ty, _res_ty') = tcSplitAppTy arrow_ty
-        (_a_ty, arg_ty) = tcSplitAppTy a_arg_ty
-    core_arrow <- dsLExpr arrow
-    core_arg   <- dsLExpr arg
-    stack_id   <- newSysLocalDs stack_ty
-    core_make_arg <- matchEnvStack env_ids stack_id core_arg
-    return (do_premap ids
-              (envStackType env_ids stack_ty)
-              arg_ty
-              res_ty
-              core_make_arg
-              core_arrow,
-            exprFreeIds core_arg `intersectVarSet` local_vars)
-
--- D, xs |- fun :: a t1 t2
--- D, xs |- arg :: t1
--- ------------------------------
--- D; xs |-a fun -<< arg : stk --> t2
---
---              ---> premap (\ ((xs), _stk) -> (fun, arg)) app
-
-dsCmd ids local_vars stack_ty res_ty
-        (HsCmdArrApp arrow arg arrow_ty HsHigherOrderApp _)
-        env_ids = do
-    let
-        (a_arg_ty, _res_ty') = tcSplitAppTy arrow_ty
-        (_a_ty, arg_ty) = tcSplitAppTy a_arg_ty
-
-    core_arrow <- dsLExpr arrow
-    core_arg   <- dsLExpr arg
-    stack_id   <- newSysLocalDs stack_ty
-    core_make_pair <- matchEnvStack env_ids stack_id
-          (mkCorePairExpr core_arrow core_arg)
-
-    return (do_premap ids
-              (envStackType env_ids stack_ty)
-              (mkCorePairTy arrow_ty arg_ty)
-              res_ty
-              core_make_pair
-              (do_app ids arg_ty res_ty),
-            (exprFreeIds core_arrow `unionVarSet` exprFreeIds core_arg)
-              `intersectVarSet` local_vars)
-
--- D; ys |-a cmd : (t,stk) --> t'
--- D, xs |-  exp :: t
--- ------------------------
--- D; xs |-a cmd exp : stk --> t'
---
---              ---> premap (\ ((xs),stk) -> ((ys),(e,stk))) cmd
-
-dsCmd ids local_vars stack_ty res_ty (HsCmdApp cmd arg) env_ids = do
-    core_arg <- dsLExpr arg
-    let
-        arg_ty = exprType core_arg
-        stack_ty' = mkCorePairTy arg_ty stack_ty
-    (core_cmd, free_vars, env_ids')
-             <- dsfixCmd ids local_vars stack_ty' res_ty cmd
-    stack_id <- newSysLocalDs stack_ty
-    arg_id <- newSysLocalDs arg_ty
-    -- push the argument expression onto the stack
-    let
-        stack' = mkCorePairExpr (Var arg_id) (Var stack_id)
-        core_body = bindNonRec arg_id core_arg
-                        (mkCorePairExpr (mkBigCoreVarTup env_ids') stack')
-
-    -- match the environment and stack against the input
-    core_map <- matchEnvStack env_ids stack_id core_body
-    return (do_premap ids
-                      (envStackType env_ids stack_ty)
-                      (envStackType env_ids' stack_ty')
-                      res_ty
-                      core_map
-                      core_cmd,
-            free_vars `unionVarSet`
-              (exprFreeIds core_arg `intersectVarSet` local_vars))
-
--- D; ys |-a cmd : stk t'
--- -----------------------------------------------
--- D; xs |-a \ p1 ... pk -> cmd : (t1,...(tk,stk)...) t'
---
---              ---> premap (\ ((xs), (p1, ... (pk,stk)...)) -> ((ys),stk)) cmd
-
-dsCmd ids local_vars stack_ty res_ty
-        (HsCmdLam (MG { mg_alts = [L _ (Match _ pats _
-                                       (GRHSs [L _ (GRHS [] body)] _ ))] }))
-        env_ids = do
-    let
-        pat_vars = mkVarSet (collectPatsBinders pats)
-        local_vars' = pat_vars `unionVarSet` local_vars
-        (pat_tys, stack_ty') = splitTypeAt (length pats) stack_ty
-    (core_body, free_vars, env_ids') <- dsfixCmd ids local_vars' stack_ty' res_ty body
-    param_ids <- mapM newSysLocalDs pat_tys
-    stack_id' <- newSysLocalDs stack_ty'
-
-    -- the expression is built from the inside out, so the actions
-    -- are presented in reverse order
-
-    let
-        -- build a new environment, plus what's left of the stack
-        core_expr = buildEnvStack env_ids' stack_id'
-        in_ty = envStackType env_ids stack_ty
-        in_ty' = envStackType env_ids' stack_ty'
-
-    fail_expr <- mkFailExpr LambdaExpr in_ty'
-    -- match the patterns against the parameters
-    match_code <- matchSimplys (map Var param_ids) LambdaExpr pats core_expr fail_expr
-    -- match the parameters against the top of the old stack
-    (stack_id, param_code) <- matchVarStack param_ids stack_id' match_code
-    -- match the old environment and stack against the input
-    select_code <- matchEnvStack env_ids stack_id param_code
-    return (do_premap ids in_ty in_ty' res_ty select_code core_body,
-            free_vars `minusVarSet` pat_vars)
-
-dsCmd ids local_vars stack_ty res_ty (HsCmdPar cmd) env_ids
-  = dsLCmd ids local_vars stack_ty res_ty cmd env_ids
-
--- D, xs |- e :: Bool
--- D; xs1 |-a c1 : stk --> t
--- D; xs2 |-a c2 : stk --> t
--- ----------------------------------------
--- D; xs |-a if e then c1 else c2 : stk --> t
---
---              ---> premap (\ ((xs),stk) ->
---                       if e then Left ((xs1),stk) else Right ((xs2),stk))
---                     (c1 ||| c2)
-
-dsCmd ids local_vars stack_ty res_ty (HsCmdIf mb_fun cond then_cmd else_cmd)
-        env_ids = do
-    core_cond <- dsLExpr cond
-    (core_then, fvs_then, then_ids) <- dsfixCmd ids local_vars stack_ty res_ty then_cmd
-    (core_else, fvs_else, else_ids) <- dsfixCmd ids local_vars stack_ty res_ty else_cmd
-    stack_id   <- newSysLocalDs stack_ty
-    either_con <- dsLookupTyCon eitherTyConName
-    left_con   <- dsLookupDataCon leftDataConName
-    right_con  <- dsLookupDataCon rightDataConName
-
-    let mk_left_expr ty1 ty2 e = mkConApp left_con [Type ty1, Type ty2, e]
-        mk_right_expr ty1 ty2 e = mkConApp right_con [Type ty1, Type ty2, e]
-
-        in_ty = envStackType env_ids stack_ty
-        then_ty = envStackType then_ids stack_ty
-        else_ty = envStackType else_ids stack_ty
-        sum_ty = mkTyConApp either_con [then_ty, else_ty]
-        fvs_cond = exprFreeIds core_cond `intersectVarSet` local_vars
-
-        core_left  = mk_left_expr  then_ty else_ty (buildEnvStack then_ids stack_id)
-        core_right = mk_right_expr then_ty else_ty (buildEnvStack else_ids stack_id)
-
-    core_if <- case mb_fun of
-       Just fun -> do { core_fun <- dsExpr fun
-                      ; matchEnvStack env_ids stack_id $
-                        mkCoreApps core_fun [core_cond, core_left, core_right] }
-       Nothing  -> matchEnvStack env_ids stack_id $
-                   mkIfThenElse core_cond core_left core_right
-
-    return (do_premap ids in_ty sum_ty res_ty
-                core_if
-                (do_choice ids then_ty else_ty res_ty core_then core_else),
-        fvs_cond `unionVarSet` fvs_then `unionVarSet` fvs_else)
-
-{-
-Case commands are treated in much the same way as if commands
-(see above) except that there are more alternatives.  For example
-
-        case e of { p1 -> c1; p2 -> c2; p3 -> c3 }
-
-is translated to
-
-        premap (\ ((xs)*ts) -> case e of
-                p1 -> (Left (Left (xs1)*ts))
-                p2 -> Left ((Right (xs2)*ts))
-                p3 -> Right ((xs3)*ts))
-        ((c1 ||| c2) ||| c3)
-
-The idea is to extract the commands from the case, build a balanced tree
-of choices, and replace the commands with expressions that build tagged
-tuples, obtaining a case expression that can be desugared normally.
-To build all this, we use triples describing segments of the list of
-case bodies, containing the following fields:
- * a list of expressions of the form (Left|Right)* ((xs)*ts), to be put
-   into the case replacing the commands
- * a sum type that is the common type of these expressions, and also the
-   input type of the arrow
- * a CoreExpr for an arrow built by combining the translated command
-   bodies with |||.
--}
-
-dsCmd ids local_vars stack_ty res_ty
-      (HsCmdCase exp (MG { mg_alts = matches, mg_arg_tys = arg_tys, mg_origin = origin }))
-      env_ids = do
-    stack_id <- newSysLocalDs stack_ty
-
-    -- Extract and desugar the leaf commands in the case, building tuple
-    -- expressions that will (after tagging) replace these leaves
-
-    let
-        leaves = concatMap leavesMatch matches
-        make_branch (leaf, bound_vars) = do
-            (core_leaf, _fvs, leaf_ids) <-
-                  dsfixCmd ids (bound_vars `unionVarSet` local_vars) stack_ty res_ty leaf
-            return ([mkHsEnvStackExpr leaf_ids stack_id],
-                    envStackType leaf_ids stack_ty,
-                    core_leaf)
-
-    branches <- mapM make_branch leaves
-    either_con <- dsLookupTyCon eitherTyConName
-    left_con <- dsLookupDataCon leftDataConName
-    right_con <- dsLookupDataCon rightDataConName
-    let
-        left_id  = HsVar (dataConWrapId left_con)
-        right_id = HsVar (dataConWrapId right_con)
-        left_expr  ty1 ty2 e = noLoc $ HsApp (noLoc $ HsWrap (mkWpTyApps [ty1, ty2]) left_id ) e
-        right_expr ty1 ty2 e = noLoc $ HsApp (noLoc $ HsWrap (mkWpTyApps [ty1, ty2]) right_id) e
-
-        -- Prefix each tuple with a distinct series of Left's and Right's,
-        -- in a balanced way, keeping track of the types.
-
-        merge_branches (builds1, in_ty1, core_exp1)
-                       (builds2, in_ty2, core_exp2)
-          = (map (left_expr in_ty1 in_ty2) builds1 ++
-                map (right_expr in_ty1 in_ty2) builds2,
-             mkTyConApp either_con [in_ty1, in_ty2],
-             do_choice ids in_ty1 in_ty2 res_ty core_exp1 core_exp2)
-        (leaves', sum_ty, core_choices) = foldb merge_branches branches
-
-        -- Replace the commands in the case with these tagged tuples,
-        -- yielding a HsExpr Id we can feed to dsExpr.
-
-        (_, matches') = mapAccumL (replaceLeavesMatch res_ty) leaves' matches
-        in_ty = envStackType env_ids stack_ty
-
-    core_body <- dsExpr (HsCase exp (MG { mg_alts = matches', mg_arg_tys = arg_tys
-                                        , mg_res_ty = sum_ty, mg_origin = origin }))
-        -- Note that we replace the HsCase result type by sum_ty,
-        -- which is the type of matches'
-
-    core_matches <- matchEnvStack env_ids stack_id core_body
-    return (do_premap ids in_ty sum_ty res_ty core_matches core_choices,
-            exprFreeIds core_body  `intersectVarSet` local_vars)
-
--- D; ys |-a cmd : stk --> t
--- ----------------------------------
--- D; xs |-a let binds in cmd : stk --> t
---
---              ---> premap (\ ((xs),stk) -> let binds in ((ys),stk)) c
-
-dsCmd ids local_vars stack_ty res_ty (HsCmdLet binds body) env_ids = do
-    let
-        defined_vars = mkVarSet (collectLocalBinders binds)
-        local_vars' = defined_vars `unionVarSet` local_vars
-
-    (core_body, _free_vars, env_ids') <- dsfixCmd ids local_vars' stack_ty res_ty body
-    stack_id <- newSysLocalDs stack_ty
-    -- build a new environment, plus the stack, using the let bindings
-    core_binds <- dsLocalBinds binds (buildEnvStack env_ids' stack_id)
-    -- match the old environment and stack against the input
-    core_map <- matchEnvStack env_ids stack_id core_binds
-    return (do_premap ids
-                        (envStackType env_ids stack_ty)
-                        (envStackType env_ids' stack_ty)
-                        res_ty
-                        core_map
-                        core_body,
-        exprFreeIds core_binds `intersectVarSet` local_vars)
-
--- D; xs |-a ss : t
--- ----------------------------------
--- D; xs |-a do { ss } : () --> t
---
---              ---> premap (\ (env,stk) -> env) c
-
-dsCmd ids local_vars stack_ty res_ty (HsCmdDo stmts _) env_ids = do
-    (core_stmts, env_ids') <- dsCmdDo ids local_vars res_ty stmts env_ids
-    let env_ty = mkBigCoreVarTupTy env_ids
-    core_fst <- mkFstExpr env_ty stack_ty
-    return (do_premap ids
-                (mkCorePairTy env_ty stack_ty)
-                env_ty
-                res_ty
-                core_fst
-                core_stmts,
-        env_ids')
-
--- D |- e :: forall e. a1 (e,stk1) t1 -> ... an (e,stkn) tn -> a (e,stk) t
--- D; xs |-a ci :: stki --> ti
--- -----------------------------------
--- D; xs |-a (|e c1 ... cn|) :: stk --> t       ---> e [t_xs] c1 ... cn
-
-dsCmd _ids local_vars _stack_ty _res_ty (HsCmdArrForm op _ args) env_ids = do
-    let env_ty = mkBigCoreVarTupTy env_ids
-    core_op <- dsLExpr op
-    (core_args, fv_sets) <- mapAndUnzipM (dsTrimCmdArg local_vars env_ids) args
-    return (mkApps (App core_op (Type env_ty)) core_args,
-            unionVarSets fv_sets)
-
-dsCmd ids local_vars stack_ty res_ty (HsCmdCast coercion cmd) env_ids = do
-    (core_cmd, env_ids') <- dsCmd ids local_vars stack_ty res_ty cmd env_ids
-    wrapped_cmd <- dsHsWrapper (mkWpCast coercion) core_cmd
-    return (wrapped_cmd, env_ids')
-
-dsCmd _ _ _ _ _ c = pprPanic "dsCmd" (ppr c)
-
--- D; ys |-a c : stk --> t      (ys <= xs)
--- ---------------------
--- D; xs |-a c : stk --> t      ---> premap (\ ((xs),stk) -> ((ys),stk)) c
-
-dsTrimCmdArg
-        :: IdSet                -- set of local vars available to this command
-        -> [Id]                 -- list of vars in the input to this command
-        -> LHsCmdTop Id         -- command argument to desugar
-        -> DsM (CoreExpr,       -- desugared expression
-                IdSet)          -- subset of local vars that occur free
-dsTrimCmdArg local_vars env_ids (L _ (HsCmdTop cmd stack_ty cmd_ty ids)) = do
-    (meth_binds, meth_ids) <- mkCmdEnv ids
-    (core_cmd, free_vars, env_ids') <- dsfixCmd meth_ids local_vars stack_ty cmd_ty cmd
-    stack_id <- newSysLocalDs stack_ty
-    trim_code <- matchEnvStack env_ids stack_id (buildEnvStack env_ids' stack_id)
-    let
-        in_ty = envStackType env_ids stack_ty
-        in_ty' = envStackType env_ids' stack_ty
-        arg_code = if env_ids' == env_ids then core_cmd else
-                do_premap meth_ids in_ty in_ty' cmd_ty trim_code core_cmd
-    return (mkLets meth_binds arg_code, free_vars)
-
--- Given D; xs |-a c : stk --> t, builds c with xs fed back.
--- Typically needs to be prefixed with arr (\(p, stk) -> ((xs),stk))
-
-dsfixCmd
-        :: DsCmdEnv             -- arrow combinators
-        -> IdSet                -- set of local vars available to this command
-        -> Type                 -- type of the stack (right-nested tuple)
-        -> Type                 -- return type of the command
-        -> LHsCmd Id            -- command to desugar
-        -> DsM (CoreExpr,       -- desugared expression
-                IdSet,          -- subset of local vars that occur free
-                [Id])           -- the same local vars as a list, fed back
-dsfixCmd ids local_vars stk_ty cmd_ty cmd
-  = trimInput (dsLCmd ids local_vars stk_ty cmd_ty cmd)
-
--- Feed back the list of local variables actually used a command,
--- for use as the input tuple of the generated arrow.
-
-trimInput
-        :: ([Id] -> DsM (CoreExpr, IdSet))
-        -> DsM (CoreExpr,       -- desugared expression
-                IdSet,          -- subset of local vars that occur free
-                [Id])           -- same local vars as a list, fed back to
-                                -- the inner function to form the tuple of
-                                -- inputs to the arrow.
-trimInput build_arrow
-  = fixDs (\ ~(_,_,env_ids) -> do
-        (core_cmd, free_vars) <- build_arrow env_ids
-        return (core_cmd, free_vars, varSetElems free_vars))
-
-{-
-Translation of command judgements of the form
-
-        D |-a do { ss } : t
--}
-
-dsCmdDo :: DsCmdEnv             -- arrow combinators
-        -> IdSet                -- set of local vars available to this statement
-        -> Type                 -- return type of the statement
-        -> [CmdLStmt Id]        -- statements to desugar
-        -> [Id]                 -- list of vars in the input to this statement
-                                -- This is typically fed back,
-                                -- so don't pull on it too early
-        -> DsM (CoreExpr,       -- desugared expression
-                IdSet)          -- subset of local vars that occur free
-
-dsCmdDo _ _ _ [] _ = panic "dsCmdDo"
-
--- D; xs |-a c : () --> t
--- --------------------------
--- D; xs |-a do { c } : t
---
---              ---> premap (\ (xs) -> ((xs), ())) c
-
-dsCmdDo ids local_vars res_ty [L _ (LastStmt body _)] env_ids = do
-    (core_body, env_ids') <- dsLCmd ids local_vars unitTy res_ty body env_ids
-    let env_ty = mkBigCoreVarTupTy env_ids
-    env_var <- newSysLocalDs env_ty
-    let core_map = Lam env_var (mkCorePairExpr (Var env_var) mkCoreUnitExpr)
-    return (do_premap ids
-                        env_ty
-                        (mkCorePairTy env_ty unitTy)
-                        res_ty
-                        core_map
-                        core_body,
-        env_ids')
-
-dsCmdDo ids local_vars res_ty (stmt:stmts) env_ids = do
-    let
-        bound_vars = mkVarSet (collectLStmtBinders stmt)
-        local_vars' = bound_vars `unionVarSet` local_vars
-    (core_stmts, _, env_ids') <- trimInput (dsCmdDo ids local_vars' res_ty stmts)
-    (core_stmt, fv_stmt) <- dsCmdLStmt ids local_vars env_ids' stmt env_ids
-    return (do_compose ids
-                (mkBigCoreVarTupTy env_ids)
-                (mkBigCoreVarTupTy env_ids')
-                res_ty
-                core_stmt
-                core_stmts,
-              fv_stmt)
-
-{-
-A statement maps one local environment to another, and is represented
-as an arrow from one tuple type to another.  A statement sequence is
-translated to a composition of such arrows.
--}
-
-dsCmdLStmt :: DsCmdEnv -> IdSet -> [Id] -> CmdLStmt Id -> [Id]
-           -> DsM (CoreExpr, IdSet)
-dsCmdLStmt ids local_vars out_ids cmd env_ids
-  = dsCmdStmt ids local_vars out_ids (unLoc cmd) env_ids
-
-dsCmdStmt
-        :: DsCmdEnv             -- arrow combinators
-        -> IdSet                -- set of local vars available to this statement
-        -> [Id]                 -- list of vars in the output of this statement
-        -> CmdStmt Id           -- statement to desugar
-        -> [Id]                 -- list of vars in the input to this statement
-                                -- This is typically fed back,
-                                -- so don't pull on it too early
-        -> DsM (CoreExpr,       -- desugared expression
-                IdSet)          -- subset of local vars that occur free
-
--- D; xs1 |-a c : () --> t
--- D; xs' |-a do { ss } : t'
--- ------------------------------
--- D; xs  |-a do { c; ss } : t'
---
---              ---> premap (\ ((xs)) -> (((xs1),()),(xs')))
---                      (first c >>> arr snd) >>> ss
-
-dsCmdStmt ids local_vars out_ids (BodyStmt cmd _ _ c_ty) env_ids = do
-    (core_cmd, fv_cmd, env_ids1) <- dsfixCmd ids local_vars unitTy c_ty cmd
-    core_mux <- matchEnv env_ids
-        (mkCorePairExpr
-            (mkCorePairExpr (mkBigCoreVarTup env_ids1) mkCoreUnitExpr)
-            (mkBigCoreVarTup out_ids))
-    let
-        in_ty = mkBigCoreVarTupTy env_ids
-        in_ty1 = mkCorePairTy (mkBigCoreVarTupTy env_ids1) unitTy
-        out_ty = mkBigCoreVarTupTy out_ids
-        before_c_ty = mkCorePairTy in_ty1 out_ty
-        after_c_ty = mkCorePairTy c_ty out_ty
-    snd_fn <- mkSndExpr c_ty out_ty
-    return (do_premap ids in_ty before_c_ty out_ty core_mux $
-                do_compose ids before_c_ty after_c_ty out_ty
-                        (do_first ids in_ty1 c_ty out_ty core_cmd) $
-                do_arr ids after_c_ty out_ty snd_fn,
-              extendVarSetList fv_cmd out_ids)
-
--- D; xs1 |-a c : () --> t
--- D; xs' |-a do { ss } : t'            xs2 = xs' - defs(p)
--- -----------------------------------
--- D; xs  |-a do { p <- c; ss } : t'
---
---              ---> premap (\ (xs) -> (((xs1),()),(xs2)))
---                      (first c >>> arr (\ (p, (xs2)) -> (xs'))) >>> ss
---
--- It would be simpler and more consistent to do this using second,
--- but that's likely to be defined in terms of first.
-
-dsCmdStmt ids local_vars out_ids (BindStmt pat cmd _ _) env_ids = do
-    (core_cmd, fv_cmd, env_ids1) <- dsfixCmd ids local_vars unitTy (hsLPatType pat) cmd
-    let
-        pat_ty = hsLPatType pat
-        pat_vars = mkVarSet (collectPatBinders pat)
-        env_ids2 = varSetElems (mkVarSet out_ids `minusVarSet` pat_vars)
-        env_ty2 = mkBigCoreVarTupTy env_ids2
-
-    -- multiplexing function
-    --          \ (xs) -> (((xs1),()),(xs2))
-
-    core_mux <- matchEnv env_ids
-        (mkCorePairExpr
-            (mkCorePairExpr (mkBigCoreVarTup env_ids1) mkCoreUnitExpr)
-            (mkBigCoreVarTup env_ids2))
-
-    -- projection function
-    --          \ (p, (xs2)) -> (zs)
-
-    env_id <- newSysLocalDs env_ty2
-    uniqs <- newUniqueSupply
-    let
-        after_c_ty = mkCorePairTy pat_ty env_ty2
-        out_ty = mkBigCoreVarTupTy out_ids
-        body_expr = coreCaseTuple uniqs env_id env_ids2 (mkBigCoreVarTup out_ids)
-
-    fail_expr <- mkFailExpr (StmtCtxt DoExpr) out_ty
-    pat_id    <- selectSimpleMatchVarL pat
-    match_code <- matchSimply (Var pat_id) (StmtCtxt DoExpr) pat body_expr fail_expr
-    pair_id   <- newSysLocalDs after_c_ty
-    let
-        proj_expr = Lam pair_id (coreCasePair pair_id pat_id env_id match_code)
-
-    -- put it all together
-    let
-        in_ty = mkBigCoreVarTupTy env_ids
-        in_ty1 = mkCorePairTy (mkBigCoreVarTupTy env_ids1) unitTy
-        in_ty2 = mkBigCoreVarTupTy env_ids2
-        before_c_ty = mkCorePairTy in_ty1 in_ty2
-    return (do_premap ids in_ty before_c_ty out_ty core_mux $
-                do_compose ids before_c_ty after_c_ty out_ty
-                        (do_first ids in_ty1 pat_ty in_ty2 core_cmd) $
-                do_arr ids after_c_ty out_ty proj_expr,
-              fv_cmd `unionVarSet` (mkVarSet out_ids `minusVarSet` pat_vars))
-
--- D; xs' |-a do { ss } : t
--- --------------------------------------
--- D; xs  |-a do { let binds; ss } : t
---
---              ---> arr (\ (xs) -> let binds in (xs')) >>> ss
-
-dsCmdStmt ids local_vars out_ids (LetStmt binds) env_ids = do
-    -- build a new environment using the let bindings
-    core_binds <- dsLocalBinds binds (mkBigCoreVarTup out_ids)
-    -- match the old environment against the input
-    core_map <- matchEnv env_ids core_binds
-    return (do_arr ids
-                        (mkBigCoreVarTupTy env_ids)
-                        (mkBigCoreVarTupTy out_ids)
-                        core_map,
-            exprFreeIds core_binds `intersectVarSet` local_vars)
-
--- D; ys  |-a do { ss; returnA -< ((xs1), (ys2)) } : ...
--- D; xs' |-a do { ss' } : t
--- ------------------------------------
--- D; xs  |-a do { rec ss; ss' } : t
---
---                      xs1 = xs' /\ defs(ss)
---                      xs2 = xs' - defs(ss)
---                      ys1 = ys - defs(ss)
---                      ys2 = ys /\ defs(ss)
---
---              ---> arr (\(xs) -> ((ys1),(xs2))) >>>
---                      first (loop (arr (\((ys1),~(ys2)) -> (ys)) >>> ss)) >>>
---                      arr (\((xs1),(xs2)) -> (xs')) >>> ss'
-
-dsCmdStmt ids local_vars out_ids
-        (RecStmt { recS_stmts = stmts
-                 , recS_later_ids = later_ids, recS_rec_ids = rec_ids
-                 , recS_later_rets = later_rets, recS_rec_rets = rec_rets })
-        env_ids = do
-    let
-        env2_id_set = mkVarSet out_ids `minusVarSet` mkVarSet later_ids
-        env2_ids = varSetElems env2_id_set
-        env2_ty = mkBigCoreVarTupTy env2_ids
-
-    -- post_loop_fn = \((later_ids),(env2_ids)) -> (out_ids)
-
-    uniqs <- newUniqueSupply
-    env2_id <- newSysLocalDs env2_ty
-    let
-        later_ty = mkBigCoreVarTupTy later_ids
-        post_pair_ty = mkCorePairTy later_ty env2_ty
-        post_loop_body = coreCaseTuple uniqs env2_id env2_ids (mkBigCoreVarTup out_ids)
-
-    post_loop_fn <- matchEnvStack later_ids env2_id post_loop_body
-
-    --- loop (...)
-
-    (core_loop, env1_id_set, env1_ids)
-               <- dsRecCmd ids local_vars stmts later_ids later_rets rec_ids rec_rets
-
-    -- pre_loop_fn = \(env_ids) -> ((env1_ids),(env2_ids))
-
-    let
-        env1_ty = mkBigCoreVarTupTy env1_ids
-        pre_pair_ty = mkCorePairTy env1_ty env2_ty
-        pre_loop_body = mkCorePairExpr (mkBigCoreVarTup env1_ids)
-                                        (mkBigCoreVarTup env2_ids)
-
-    pre_loop_fn <- matchEnv env_ids pre_loop_body
-
-    -- arr pre_loop_fn >>> first (loop (...)) >>> arr post_loop_fn
-
-    let
-        env_ty = mkBigCoreVarTupTy env_ids
-        out_ty = mkBigCoreVarTupTy out_ids
-        core_body = do_premap ids env_ty pre_pair_ty out_ty
-                pre_loop_fn
-                (do_compose ids pre_pair_ty post_pair_ty out_ty
-                        (do_first ids env1_ty later_ty env2_ty
-                                core_loop)
-                        (do_arr ids post_pair_ty out_ty
-                                post_loop_fn))
-
-    return (core_body, env1_id_set `unionVarSet` env2_id_set)
-
-dsCmdStmt _ _ _ _ s = pprPanic "dsCmdStmt" (ppr s)
-
---      loop (premap (\ ((env1_ids), ~(rec_ids)) -> (env_ids))
---            (ss >>> arr (\ (out_ids) -> ((later_rets),(rec_rets))))) >>>
-
-dsRecCmd
-        :: DsCmdEnv             -- arrow combinators
-        -> IdSet                -- set of local vars available to this statement
-        -> [CmdLStmt Id]        -- list of statements inside the RecCmd
-        -> [Id]                 -- list of vars defined here and used later
-        -> [HsExpr Id]          -- expressions corresponding to later_ids
-        -> [Id]                 -- list of vars fed back through the loop
-        -> [HsExpr Id]          -- expressions corresponding to rec_ids
-        -> DsM (CoreExpr,       -- desugared statement
-                IdSet,          -- subset of local vars that occur free
-                [Id])           -- same local vars as a list
-
-dsRecCmd ids local_vars stmts later_ids later_rets rec_ids rec_rets = do
-    let
-        later_id_set = mkVarSet later_ids
-        rec_id_set = mkVarSet rec_ids
-        local_vars' = rec_id_set `unionVarSet` later_id_set `unionVarSet` local_vars
-
-    -- mk_pair_fn = \ (out_ids) -> ((later_rets),(rec_rets))
-
-    core_later_rets <- mapM dsExpr later_rets
-    core_rec_rets <- mapM dsExpr rec_rets
-    let
-        -- possibly polymorphic version of vars of later_ids and rec_ids
-        out_ids = varSetElems (unionVarSets (map exprFreeIds (core_later_rets ++ core_rec_rets)))
-        out_ty = mkBigCoreVarTupTy out_ids
-
-        later_tuple = mkBigCoreTup core_later_rets
-        later_ty = mkBigCoreVarTupTy later_ids
-
-        rec_tuple = mkBigCoreTup core_rec_rets
-        rec_ty = mkBigCoreVarTupTy rec_ids
-
-        out_pair = mkCorePairExpr later_tuple rec_tuple
-        out_pair_ty = mkCorePairTy later_ty rec_ty
-
-    mk_pair_fn <- matchEnv out_ids out_pair
-
-    -- ss
-
-    (core_stmts, fv_stmts, env_ids) <- dsfixCmdStmts ids local_vars' out_ids stmts
-
-    -- squash_pair_fn = \ ((env1_ids), ~(rec_ids)) -> (env_ids)
-
-    rec_id <- newSysLocalDs rec_ty
-    let
-        env1_id_set = fv_stmts `minusVarSet` rec_id_set
-        env1_ids = varSetElems env1_id_set
-        env1_ty = mkBigCoreVarTupTy env1_ids
-        in_pair_ty = mkCorePairTy env1_ty rec_ty
-        core_body = mkBigCoreTup (map selectVar env_ids)
-          where
-            selectVar v
-                | v `elemVarSet` rec_id_set
-                  = mkTupleSelector rec_ids v rec_id (Var rec_id)
-                | otherwise = Var v
-
-    squash_pair_fn <- matchEnvStack env1_ids rec_id core_body
-
-    -- loop (premap squash_pair_fn (ss >>> arr mk_pair_fn))
-
-    let
-        env_ty = mkBigCoreVarTupTy env_ids
-        core_loop = do_loop ids env1_ty later_ty rec_ty
-                (do_premap ids in_pair_ty env_ty out_pair_ty
-                        squash_pair_fn
-                        (do_compose ids env_ty out_ty out_pair_ty
-                                core_stmts
-                                (do_arr ids out_ty out_pair_ty mk_pair_fn)))
-
-    return (core_loop, env1_id_set, env1_ids)
-
-{-
-A sequence of statements (as in a rec) is desugared to an arrow between
-two environments (no stack)
--}
-
-dsfixCmdStmts
-        :: DsCmdEnv             -- arrow combinators
-        -> IdSet                -- set of local vars available to this statement
-        -> [Id]                 -- output vars of these statements
-        -> [CmdLStmt Id]        -- statements to desugar
-        -> DsM (CoreExpr,       -- desugared expression
-                IdSet,          -- subset of local vars that occur free
-                [Id])           -- same local vars as a list
-
-dsfixCmdStmts ids local_vars out_ids stmts
-  = trimInput (dsCmdStmts ids local_vars out_ids stmts)
-
-dsCmdStmts
-        :: DsCmdEnv             -- arrow combinators
-        -> IdSet                -- set of local vars available to this statement
-        -> [Id]                 -- output vars of these statements
-        -> [CmdLStmt Id]        -- statements to desugar
-        -> [Id]                 -- list of vars in the input to these statements
-        -> DsM (CoreExpr,       -- desugared expression
-                IdSet)          -- subset of local vars that occur free
-
-dsCmdStmts ids local_vars out_ids [stmt] env_ids
-  = dsCmdLStmt ids local_vars out_ids stmt env_ids
-
-dsCmdStmts ids local_vars out_ids (stmt:stmts) env_ids = do
-    let
-        bound_vars = mkVarSet (collectLStmtBinders stmt)
-        local_vars' = bound_vars `unionVarSet` local_vars
-    (core_stmts, _fv_stmts, env_ids') <- dsfixCmdStmts ids local_vars' out_ids stmts
-    (core_stmt, fv_stmt) <- dsCmdLStmt ids local_vars env_ids' stmt env_ids
-    return (do_compose ids
-                (mkBigCoreVarTupTy env_ids)
-                (mkBigCoreVarTupTy env_ids')
-                (mkBigCoreVarTupTy out_ids)
-                core_stmt
-                core_stmts,
-              fv_stmt)
-
-dsCmdStmts _ _ _ [] _ = panic "dsCmdStmts []"
-
--- Match a list of expressions against a list of patterns, left-to-right.
-
-matchSimplys :: [CoreExpr]              -- Scrutinees
-             -> HsMatchContext Name     -- Match kind
-             -> [LPat Id]               -- Patterns they should match
-             -> CoreExpr                -- Return this if they all match
-             -> CoreExpr                -- Return this if they don't
-             -> DsM CoreExpr
-matchSimplys [] _ctxt [] result_expr _fail_expr = return result_expr
-matchSimplys (exp:exps) ctxt (pat:pats) result_expr fail_expr = do
-    match_code <- matchSimplys exps ctxt pats result_expr fail_expr
-    matchSimply exp ctxt pat match_code fail_expr
-matchSimplys _ _ _ _ _ = panic "matchSimplys"
-
--- List of leaf expressions, with set of variables bound in each
-
-leavesMatch :: LMatch Id (Located (body Id)) -> [(Located (body Id), IdSet)]
-leavesMatch (L _ (Match _ pats _ (GRHSs grhss binds)))
-  = let
-        defined_vars = mkVarSet (collectPatsBinders pats)
-                        `unionVarSet`
-                       mkVarSet (collectLocalBinders binds)
-    in
-    [(body,
-      mkVarSet (collectLStmtsBinders stmts)
-        `unionVarSet` defined_vars)
-    | L _ (GRHS stmts body) <- grhss]
-
--- Replace the leaf commands in a match
-
-replaceLeavesMatch
-        :: Type                                 -- new result type
-        -> [Located (body' Id)]                 -- replacement leaf expressions of that type
-        -> LMatch Id (Located (body Id))        -- the matches of a case command
-        -> ([Located (body' Id)],               -- remaining leaf expressions
-            LMatch Id (Located (body' Id)))     -- updated match
-replaceLeavesMatch _res_ty leaves (L loc (Match mf pat mt (GRHSs grhss binds)))
-  = let
-        (leaves', grhss') = mapAccumL replaceLeavesGRHS leaves grhss
-    in
-    (leaves', L loc (Match mf pat mt (GRHSs grhss' binds)))
-
-replaceLeavesGRHS
-        :: [Located (body' Id)]                 -- replacement leaf expressions of that type
-        -> LGRHS Id (Located (body Id))         -- rhss of a case command
-        -> ([Located (body' Id)],               -- remaining leaf expressions
-            LGRHS Id (Located (body' Id)))      -- updated GRHS
-replaceLeavesGRHS (leaf:leaves) (L loc (GRHS stmts _))
-  = (leaves, L loc (GRHS stmts leaf))
-replaceLeavesGRHS [] _ = panic "replaceLeavesGRHS []"
-
--- Balanced fold of a non-empty list.
-
-foldb :: (a -> a -> a) -> [a] -> a
-foldb _ [] = Err.panic Nothing "foldb of empty list"
-foldb _ [x] = x
-foldb f xs = foldb f (fold_pairs xs)
-  where
-    fold_pairs [] = []
-    fold_pairs [x] = [x]
-    fold_pairs (x1:x2:xs) = f x1 x2:fold_pairs xs
-
-{-
-Note [Dictionary binders in ConPatOut] See also same Note in HsUtils
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The following functions to collect value variables from patterns are
-copied from HsUtils, with one change: we also collect the dictionary
-bindings (pat_binds) from ConPatOut.  We need them for cases like
-
-h :: Arrow a => Int -> a (Int,Int) Int
-h x = proc (y,z) -> case compare x y of
-                GT -> returnA -< z+x
-
-The type checker turns the case into
-
-                case compare x y of
-                  GT { p77 = plusInt } -> returnA -< p77 z x
-
-Here p77 is a local binding for the (+) operation.
-
-See comments in HsUtils for why the other version does not include
-these bindings.
--}
-
-collectPatBinders :: LPat Id -> [Id]
-collectPatBinders pat = collectl pat []
-
-collectPatsBinders :: [LPat Id] -> [Id]
-collectPatsBinders pats = foldr collectl [] pats
-
----------------------
-collectl :: LPat Id -> [Id] -> [Id]
--- See Note [Dictionary binders in ConPatOut]
-collectl (L _ pat) bndrs
-  = go pat
-  where
-    go (VarPat var)               = var : bndrs
-    go (WildPat _)                = bndrs
-    go (LazyPat pat)              = collectl pat bndrs
-    go (BangPat pat)              = collectl pat bndrs
-    go (AsPat (L _ a) pat)        = a : collectl pat bndrs
-    go (ParPat  pat)              = collectl pat bndrs
-
-    go (ListPat pats _ _)         = foldr collectl bndrs pats
-    go (PArrPat pats _)           = foldr collectl bndrs pats
-    go (TuplePat pats _ _)        = foldr collectl bndrs pats
-
-    go (ConPatIn _ ps)            = foldr collectl bndrs (hsConPatArgs ps)
-    go (ConPatOut {pat_args=ps, pat_binds=ds}) =
-                                    collectEvBinders ds
-                                    ++ foldr collectl bndrs (hsConPatArgs ps)
-    go (LitPat _)                 = bndrs
-    go (NPat _ _ _)               = bndrs
-    go (NPlusKPat (L _ n) _ _ _)  = n : bndrs
-
-    go (SigPatIn pat _)           = collectl pat bndrs
-    go (SigPatOut pat _)          = collectl pat bndrs
-    go (CoPat _ pat _)            = collectl (noLoc pat) bndrs
-    go (ViewPat _ pat _)          = collectl pat bndrs
-    go p@(SplicePat {})           = pprPanic "collectl/go" (ppr p)
-    go p@(QuasiQuotePat {})       = pprPanic "collectl/go" (ppr p)
-
-collectEvBinders :: TcEvBinds -> [Id]
-collectEvBinders (EvBinds bs)   = foldrBag add_ev_bndr [] bs
-collectEvBinders (TcEvBinds {}) = panic "ToDo: collectEvBinders"
-
-add_ev_bndr :: EvBind -> [Id] -> [Id]
-add_ev_bndr (EvBind b _) bs | isId b    = b:bs
-                            | otherwise = bs
-  -- A worry: what about coercion variable binders??
-
-collectLStmtsBinders :: [LStmt Id body] -> [Id]
-collectLStmtsBinders = concatMap collectLStmtBinders
-
-collectLStmtBinders :: LStmt Id body -> [Id]
-collectLStmtBinders = collectStmtBinders . unLoc
-
-collectStmtBinders :: Stmt Id body -> [Id]
-collectStmtBinders (BindStmt pat _ _ _) = collectPatBinders pat
-collectStmtBinders (LetStmt binds)      = collectLocalBinders binds
-collectStmtBinders (BodyStmt {})        = []
-collectStmtBinders (LastStmt {})        = []
-collectStmtBinders (ParStmt xs _ _)     = collectLStmtsBinders
-                                        $ [ s | ParStmtBlock ss _ _ <- xs, s <- ss]
-collectStmtBinders (TransStmt { trS_stmts = stmts }) = collectLStmtsBinders stmts
-collectStmtBinders (RecStmt { recS_later_ids = later_ids }) = later_ids
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsBinds.hs b/src/Language/Haskell/Liquid/Desugar710/DsBinds.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsBinds.hs
+++ /dev/null
@@ -1,1197 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-Pattern-matching bindings (HsBinds and MonoBinds)
-
-Handles @HsBinds@; those at the top level require different handling,
-in that the @Rec@/@NonRec@/etc structure is thrown away (whereas at
-lower levels it is preserved with @let@/@letrec@s).
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.DsBinds ( dsTopLHsBinds, dsLHsBinds, decomposeRuleLhs, dsSpec,
-                 dsHsWrapper, dsTcEvBinds, dsEvBinds
-  ) where
-
--- #include "HsVersions.h"
-
-import {-# SOURCE #-}   Language.Haskell.Liquid.Desugar710.DsExpr( dsLExpr )
-import {-# SOURCE #-}   Language.Haskell.Liquid.Desugar710.Match( matchWrapper )
-
-import Prelude hiding (error)
-import DsMonad
-import Language.Haskell.Liquid.Desugar710.DsGRHSs
-import Language.Haskell.Liquid.Desugar710.DsUtils
-
-import HsSyn            -- lots of things
-import CoreSyn          -- lots of things
-import Literal          ( Literal(MachStr) )
-import CoreSubst
-import OccurAnal        ( occurAnalyseExpr )
-import MkCore
-import CoreUtils
-import CoreArity ( etaExpand )
-import CoreUnfold
-import CoreFVs
-import UniqSupply
-import Digraph
-import Module
-import PrelNames
-import TysPrim ( mkProxyPrimTy )
-import TyCon      ( tyConDataCons_maybe
-                  , tyConName, isPromotedTyCon, isPromotedDataCon )
-import TcEvidence
-import TcType
-import Type
-import Coercion hiding (substCo)
-import TysWiredIn ( eqBoxDataCon, coercibleDataCon, mkListTy
-                  , mkBoxedTupleTy, stringTy, tupleCon )
-import Id
-import MkId(proxyHashId)
-import Class
-import DataCon  ( dataConWorkId, dataConTyCon )
-import Name
-import MkId     ( seqId )
-import IdInfo   ( IdDetails(..) )
-import Var
-import VarSet
-import Rules
-import VarEnv
-import Outputable
-import SrcLoc
-import Maybes
-import OrdList
-import Bag
-import BasicTypes hiding ( TopLevel )
-import DynFlags
-import FastString
-import ErrUtils( MsgDoc )
-import ListSetOps( getNth )
-import Util
-import Control.Monad( when )
-import MonadUtils
-import Control.Monad(liftM)
-import Fingerprint(Fingerprint(..), fingerprintString)
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[dsMonoBinds]{Desugaring a @MonoBinds@}
-*                                                                      *
-************************************************************************
--}
-
-dsTopLHsBinds :: LHsBinds Id -> DsM (OrdList (Id,CoreExpr))
-dsTopLHsBinds binds = ds_lhs_binds binds
-
-dsLHsBinds :: LHsBinds Id -> DsM [(Id,CoreExpr)]
-dsLHsBinds binds = do { binds' <- ds_lhs_binds binds
-                      ; return (fromOL binds') }
-
-------------------------
-ds_lhs_binds :: LHsBinds Id -> DsM (OrdList (Id,CoreExpr))
-
-ds_lhs_binds binds = do { ds_bs <- mapBagM dsLHsBind binds
-                        ; return (foldBag appOL id nilOL ds_bs) }
-
-dsLHsBind :: LHsBind Id -> DsM (OrdList (Id,CoreExpr))
-dsLHsBind (L loc bind) = putSrcSpanDs loc $ dsHsBind bind
-
-dsHsBind :: HsBind Id -> DsM (OrdList (Id,CoreExpr))
-
-dsHsBind (VarBind { var_id = var, var_rhs = expr, var_inline = inline_regardless })
-  = do  { dflags <- getDynFlags
-        ; core_expr <- dsLExpr expr
-
-                -- Dictionary bindings are always VarBinds,
-                -- so we only need do this here
-        ; let var' | inline_regardless = var `setIdUnfolding` mkCompulsoryUnfolding core_expr
-                   | otherwise         = var
-
-        ; return (unitOL (makeCorePair dflags var' False 0 core_expr)) }
-
-dsHsBind (FunBind { fun_id = L _ fun, fun_matches = matches
-                  , fun_co_fn = co_fn, fun_tick = tick
-                  , fun_infix = inf })
- = do   { dflags <- getDynFlags
-        ; (args, body) <- matchWrapper (FunRhs (idName fun) inf) matches
-        ; let body' = mkOptTickBox tick body
-        ; rhs <- dsHsWrapper co_fn (mkLams args body')
-        ; {- pprTrace "dsHsBind" (ppr fun <+> ppr (idInlinePragma fun)) $ -}
-           return (unitOL (makeCorePair dflags fun False 0 rhs)) }
-
-dsHsBind (PatBind { pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty
-                  , pat_ticks = (rhs_tick, var_ticks) })
-  = do  { body_expr <- dsGuarded grhss ty
-        ; let body' = mkOptTickBox rhs_tick body_expr
-        ; sel_binds <- mkSelectorBinds var_ticks pat body'
-          -- We silently ignore inline pragmas; no makeCorePair
-          -- Not so cool, but really doesn't matter
-    ; return (toOL sel_binds) }
-
-        -- A common case: one exported variable
-        -- Non-recursive bindings come through this way
-        -- So do self-recursive bindings, and recursive bindings
-        -- that have been chopped up with type signatures
-dsHsBind (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts
-                   , abs_exports = [export]
-                   , abs_ev_binds = ev_binds, abs_binds = binds })
-  | ABE { abe_wrap = wrap, abe_poly = global
-        , abe_mono = local, abe_prags = prags } <- export
-  = do  { dflags <- getDynFlags
-        ; bind_prs    <- ds_lhs_binds binds
-        ; let   core_bind = Rec (fromOL bind_prs)
-        ; ds_binds <- dsTcEvBinds ev_binds
-        ; rhs <- dsHsWrapper wrap $  -- Usually the identity
-                            mkLams tyvars $ mkLams dicts $
-                            mkCoreLets ds_binds $
-                            Let core_bind $
-                            Var local
-
-        ; (spec_binds, rules) <- dsSpecs rhs prags
-
-        ; let   global'   = addIdSpecialisations global rules
-                main_bind = makeCorePair dflags global' (isDefaultMethod prags)
-                                         (dictArity dicts) rhs
-
-        ; return (main_bind `consOL` spec_binds) }
-
-dsHsBind (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts
-                   , abs_exports = exports, abs_ev_binds = ev_binds
-                   , abs_binds = binds })
-         -- See Note [Desugaring AbsBinds]
-  = do  { dflags <- getDynFlags
-        ; bind_prs    <- ds_lhs_binds binds
-        ; let core_bind = Rec [ makeCorePair dflags (add_inline lcl_id) False 0 rhs
-                              | (lcl_id, rhs) <- fromOL bind_prs ]
-                -- Monomorphic recursion possible, hence Rec
-
-              locals       = map abe_mono exports
-              tup_expr     = mkBigCoreVarTup locals
-              tup_ty       = exprType tup_expr
-        ; ds_binds <- dsTcEvBinds ev_binds
-        ; let poly_tup_rhs = mkLams tyvars $ mkLams dicts $
-                             mkCoreLets ds_binds $
-                             Let core_bind $
-                             tup_expr
-
-        ; poly_tup_id <- newSysLocalDs (exprType poly_tup_rhs)
-
-        ; let mk_bind (ABE { abe_wrap = wrap, abe_poly = global
-                           , abe_mono = local, abe_prags = spec_prags })
-                = do { tup_id  <- newSysLocalDs tup_ty
-                     ; rhs <- dsHsWrapper wrap $
-                                 mkLams tyvars $ mkLams dicts $
-                                 mkTupleSelector locals local tup_id $
-                                 mkVarApps (Var poly_tup_id) (tyvars ++ dicts)
-                     ; let rhs_for_spec = Let (NonRec poly_tup_id poly_tup_rhs) rhs
-                     ; (spec_binds, rules) <- dsSpecs rhs_for_spec spec_prags
-                     ; let global' = (global `setInlinePragma` defaultInlinePragma)
-                                             `addIdSpecialisations` rules
-                           -- Kill the INLINE pragma because it applies to
-                           -- the user written (local) function.  The global
-                           -- Id is just the selector.  Hmm.
-                     ; return ((global', rhs) `consOL` spec_binds) }
-
-        ; export_binds_s <- mapM mk_bind exports
-
-        ; return ((poly_tup_id, poly_tup_rhs) `consOL`
-                    concatOL export_binds_s) }
-  where
-    inline_env :: IdEnv Id   -- Maps a monomorphic local Id to one with
-                             -- the inline pragma from the source
-                             -- The type checker put the inline pragma
-                             -- on the *global* Id, so we need to transfer it
-    inline_env = mkVarEnv [ (lcl_id, setInlinePragma lcl_id prag)
-                          | ABE { abe_mono = lcl_id, abe_poly = gbl_id } <- exports
-                          , let prag = idInlinePragma gbl_id ]
-
-    add_inline :: Id -> Id    -- tran
-    add_inline lcl_id = lookupVarEnv inline_env lcl_id `orElse` lcl_id
-
-dsHsBind (PatSynBind{}) = panic "dsHsBind: PatSynBind"
-
-------------------------
-makeCorePair :: DynFlags -> Id -> Bool -> Arity -> CoreExpr -> (Id, CoreExpr)
-makeCorePair dflags gbl_id is_default_method dict_arity rhs
-  | is_default_method                 -- Default methods are *always* inlined
-  = (gbl_id `setIdUnfolding` mkCompulsoryUnfolding rhs, rhs)
-
-  | DFunId _ is_newtype <- idDetails gbl_id
-  = (mk_dfun_w_stuff is_newtype, rhs)
-
-  | otherwise
-  = case inlinePragmaSpec inline_prag of
-          EmptyInlineSpec -> (gbl_id, rhs)
-          NoInline        -> (gbl_id, rhs)
-          Inlinable       -> (gbl_id `setIdUnfolding` inlinable_unf, rhs)
-          Inline          -> inline_pair
-
-  where
-    inline_prag   = idInlinePragma gbl_id
-    inlinable_unf = mkInlinableUnfolding dflags rhs
-    inline_pair
-       | Just arity <- inlinePragmaSat inline_prag
-        -- Add an Unfolding for an INLINE (but not for NOINLINE)
-        -- And eta-expand the RHS; see Note [Eta-expanding INLINE things]
-       , let real_arity = dict_arity + arity
-        -- NB: The arity in the InlineRule takes account of the dictionaries
-       = ( gbl_id `setIdUnfolding` mkInlineUnfolding (Just real_arity) rhs
-         , etaExpand real_arity rhs)
-
-       | otherwise
-       = pprTrace "makeCorePair: arity missing" (ppr gbl_id) $
-         (gbl_id `setIdUnfolding` mkInlineUnfolding Nothing rhs, rhs)
-
-                -- See Note [ClassOp/DFun selection] in TcInstDcls
-                -- See Note [Single-method classes]  in TcInstDcls
-    mk_dfun_w_stuff is_newtype
-       | is_newtype
-       = gbl_id `setIdUnfolding`  mkInlineUnfolding (Just 0) rhs
-                `setInlinePragma` alwaysInlinePragma { inl_sat = Just 0 }
-       | otherwise
-       = gbl_id `setIdUnfolding`  mkDFunUnfolding dfun_bndrs dfun_constr dfun_args
-                `setInlinePragma` dfunInlinePragma
-    (dfun_bndrs, dfun_body) = collectBinders (simpleOptExpr rhs)
-    (dfun_con, dfun_args, _)   = collectArgsTicks (const True) dfun_body
-    dfun_constr | Var id <- dfun_con
-                , DataConWorkId con <- idDetails id
-                = con
-                | otherwise = pprPanic "makeCorePair: dfun" (ppr rhs)
-
-
-dictArity :: [Var] -> Arity
--- Don't count coercion variables in arity
-dictArity dicts = count isId dicts
-
-{-
-[Desugaring AbsBinds]
-~~~~~~~~~~~~~~~~~~~~~
-In the general AbsBinds case we desugar the binding to this:
-
-       tup a (d:Num a) = let fm = ...gm...
-                             gm = ...fm...
-                         in (fm,gm)
-       f a d = case tup a d of { (fm,gm) -> fm }
-       g a d = case tup a d of { (fm,gm) -> fm }
-
-Note [Rules and inlining]
-~~~~~~~~~~~~~~~~~~~~~~~~~
-Common special case: no type or dictionary abstraction
-This is a bit less trivial than you might suppose
-The naive way woudl be to desguar to something like
-        f_lcl = ...f_lcl...     -- The "binds" from AbsBinds
-        M.f = f_lcl             -- Generated from "exports"
-But we don't want that, because if M.f isn't exported,
-it'll be inlined unconditionally at every call site (its rhs is
-trivial).  That would be ok unless it has RULES, which would
-thereby be completely lost.  Bad, bad, bad.
-
-Instead we want to generate
-        M.f = ...f_lcl...
-        f_lcl = M.f
-Now all is cool. The RULES are attached to M.f (by SimplCore),
-and f_lcl is rapidly inlined away.
-
-This does not happen in the same way to polymorphic binds,
-because they desugar to
-        M.f = /\a. let f_lcl = ...f_lcl... in f_lcl
-Although I'm a bit worried about whether full laziness might
-float the f_lcl binding out and then inline M.f at its call site
-
-Note [Specialising in no-dict case]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Even if there are no tyvars or dicts, we may have specialisation pragmas.
-Class methods can generate
-      AbsBinds [] [] [( ... spec-prag]
-         { AbsBinds [tvs] [dicts] ...blah }
-So the overloading is in the nested AbsBinds. A good example is in GHC.Float:
-
-  class  (Real a, Fractional a) => RealFrac a  where
-    round :: (Integral b) => a -> b
-
-  instance  RealFrac Float  where
-    {-# SPECIALIZE round :: Float -> Int #-}
-
-The top-level AbsBinds for $cround has no tyvars or dicts (because the
-instance does not).  But the method is locally overloaded!
-
-Note [Abstracting over tyvars only]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When abstracting over type variable only (not dictionaries), we don't really need to
-built a tuple and select from it, as we do in the general case. Instead we can take
-
-        AbsBinds [a,b] [ ([a,b], fg, fl, _),
-                         ([b],   gg, gl, _) ]
-                { fl = e1
-                  gl = e2
-                   h = e3 }
-
-and desugar it to
-
-        fg = /\ab. let B in e1
-        gg = /\b. let a = () in let B in S(e2)
-        h  = /\ab. let B in e3
-
-where B is the *non-recursive* binding
-        fl = fg a b
-        gl = gg b
-        h  = h a b    -- See (b); note shadowing!
-
-Notice (a) g has a different number of type variables to f, so we must
-             use the mkArbitraryType thing to fill in the gaps.
-             We use a type-let to do that.
-
-         (b) The local variable h isn't in the exports, and rather than
-             clone a fresh copy we simply replace h by (h a b), where
-             the two h's have different types!  Shadowing happens here,
-             which looks confusing but works fine.
-
-         (c) The result is *still* quadratic-sized if there are a lot of
-             small bindings.  So if there are more than some small
-             number (10), we filter the binding set B by the free
-             variables of the particular RHS.  Tiresome.
-
-Why got to this trouble?  It's a common case, and it removes the
-quadratic-sized tuple desugaring.  Less clutter, hopefully faster
-compilation, especially in a case where there are a *lot* of
-bindings.
-
-
-Note [Eta-expanding INLINE things]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
-   foo :: Eq a => a -> a
-   {-# INLINE foo #-}
-   foo x = ...
-
-If (foo d) ever gets floated out as a common sub-expression (which can
-happen as a result of method sharing), there's a danger that we never
-get to do the inlining, which is a Terribly Bad thing given that the
-user said "inline"!
-
-To avoid this we pre-emptively eta-expand the definition, so that foo
-has the arity with which it is declared in the source code.  In this
-example it has arity 2 (one for the Eq and one for x). Doing this
-should mean that (foo d) is a PAP and we don't share it.
-
-Note [Nested arities]
-~~~~~~~~~~~~~~~~~~~~~
-For reasons that are not entirely clear, method bindings come out looking like
-this:
-
-  AbsBinds [] [] [$cfromT <= [] fromT]
-    $cfromT [InlPrag=INLINE] :: T Bool -> Bool
-    { AbsBinds [] [] [fromT <= [] fromT_1]
-        fromT :: T Bool -> Bool
-        { fromT_1 ((TBool b)) = not b } } }
-
-Note the nested AbsBind.  The arity for the InlineRule on $cfromT should be
-gotten from the binding for fromT_1.
-
-It might be better to have just one level of AbsBinds, but that requires more
-thought!
-
-Note [Implementing SPECIALISE pragmas]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Example:
-        f :: (Eq a, Ix b) => a -> b -> Bool
-        {-# SPECIALISE f :: (Ix p, Ix q) => Int -> (p,q) -> Bool #-}
-        f = <poly_rhs>
-
-From this the typechecker generates
-
-    AbsBinds [ab] [d1,d2] [([ab], f, f_mono, prags)] binds
-
-    SpecPrag (wrap_fn :: forall a b. (Eq a, Ix b) => XXX
-                      -> forall p q. (Ix p, Ix q) => XXX[ Int/a, (p,q)/b ])
-
-Note that wrap_fn can transform *any* function with the right type prefix
-    forall ab. (Eq a, Ix b) => XXX
-regardless of XXX.  It's sort of polymorphic in XXX.  This is
-useful: we use the same wrapper to transform each of the class ops, as
-well as the dict.
-
-From these we generate:
-
-    Rule:       forall p, q, (dp:Ix p), (dq:Ix q).
-                    f Int (p,q) dInt ($dfInPair dp dq) = f_spec p q dp dq
-
-    Spec bind:  f_spec = wrap_fn <poly_rhs>
-
-Note that
-
-  * The LHS of the rule may mention dictionary *expressions* (eg
-    $dfIxPair dp dq), and that is essential because the dp, dq are
-    needed on the RHS.
-
-  * The RHS of f_spec, <poly_rhs> has a *copy* of 'binds', so that it
-    can fully specialise it.
--}
-
-------------------------
-dsSpecs :: CoreExpr     -- Its rhs
-        -> TcSpecPrags
-        -> DsM ( OrdList (Id,CoreExpr)  -- Binding for specialised Ids
-               , [CoreRule] )           -- Rules for the Global Ids
--- See Note [Implementing SPECIALISE pragmas]
-dsSpecs _ IsDefaultMethod = return (nilOL, [])
-dsSpecs poly_rhs (SpecPrags sps)
-  = do { pairs <- mapMaybeM (dsSpec (Just poly_rhs)) sps
-       ; let (spec_binds_s, rules) = unzip pairs
-       ; return (concatOL spec_binds_s, rules) }
-
-dsSpec :: Maybe CoreExpr        -- Just rhs => RULE is for a local binding
-                                -- Nothing => RULE is for an imported Id
-                                --            rhs is in the Id's unfolding
-       -> Located TcSpecPrag
-       -> DsM (Maybe (OrdList (Id,CoreExpr), CoreRule))
-dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl))
-  | isJust (isClassOpId_maybe poly_id)
-  = putSrcSpanDs loc $
-    do { warnDs (ptext (sLit "Ignoring useless SPECIALISE pragma for class method selector")
-                 <+> quotes (ppr poly_id))
-       ; return Nothing  }  -- There is no point in trying to specialise a class op
-                            -- Moreover, classops don't (currently) have an inl_sat arity set
-                            -- (it would be Just 0) and that in turn makes makeCorePair bleat
-
-  | no_act_spec && isNeverActive rule_act
-  = putSrcSpanDs loc $
-    do { warnDs (ptext (sLit "Ignoring useless SPECIALISE pragma for NOINLINE function:")
-                 <+> quotes (ppr poly_id))
-       ; return Nothing  }  -- Function is NOINLINE, and the specialiation inherits that
-                            -- See Note [Activation pragmas for SPECIALISE]
-
-  | otherwise
-  = putSrcSpanDs loc $
-    do { uniq <- newUnique
-       ; let poly_name = idName poly_id
-             spec_occ  = mkSpecOcc (getOccName poly_name)
-             spec_name = mkInternalName uniq spec_occ (getSrcSpan poly_name)
-       ; (bndrs, ds_lhs) <- liftM collectBinders
-                                  (dsHsWrapper spec_co (Var poly_id))
-       ; let spec_ty = mkPiTypes bndrs (exprType ds_lhs)
-       ; -- pprTrace "dsRule" (vcat [ ptext (sLit "Id:") <+> ppr poly_id
-         --                         , ptext (sLit "spec_co:") <+> ppr spec_co
-         --                         , ptext (sLit "ds_rhs:") <+> ppr ds_lhs ]) $
-         case decomposeRuleLhs bndrs ds_lhs of {
-           Left msg -> do { warnDs msg; return Nothing } ;
-           Right (rule_bndrs, _fn, args) -> do
-
-       { dflags <- getDynFlags
-       ; let fn_unf    = realIdUnfolding poly_id
-             unf_fvs   = stableUnfoldingVars fn_unf `orElse` emptyVarSet
-             in_scope  = mkInScopeSet (unf_fvs `unionVarSet` exprsFreeVars args)
-             spec_unf  = specUnfolding dflags (mkEmptySubst in_scope) bndrs args fn_unf
-             spec_id   = mkLocalId spec_name spec_ty
-                            `setInlinePragma` inl_prag
-                            `setIdUnfolding`  spec_unf
-             rule =  mkRule False {- Not auto -} is_local_id
-                        (mkFastString ("SPEC " ++ showPpr dflags poly_name))
-                        rule_act poly_name
-                        rule_bndrs args
-                        (mkVarApps (Var spec_id) bndrs)
-
-       ; spec_rhs <- dsHsWrapper spec_co poly_rhs
-
-       ; when (isInlinePragma id_inl && wopt Opt_WarnPointlessPragmas dflags)
-              (warnDs (specOnInline poly_name))
-
-       ; return (Just (unitOL (spec_id, spec_rhs), rule))
-            -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because
-            --     makeCorePair overwrites the unfolding, which we have
-            --     just created using specUnfolding
-       } } }
-  where
-    is_local_id = isJust mb_poly_rhs
-    poly_rhs | Just rhs <-  mb_poly_rhs
-             = rhs          -- Local Id; this is its rhs
-             | Just unfolding <- maybeUnfoldingTemplate (realIdUnfolding poly_id)
-             = unfolding    -- Imported Id; this is its unfolding
-                            -- Use realIdUnfolding so we get the unfolding
-                            -- even when it is a loop breaker.
-                            -- We want to specialise recursive functions!
-             | otherwise = pprPanic "dsImpSpecs" (ppr poly_id)
-                            -- The type checker has checked that it *has* an unfolding
-
-    id_inl = idInlinePragma poly_id
-
-    -- See Note [Activation pragmas for SPECIALISE]
-    inl_prag | not (isDefaultInlinePragma spec_inl)    = spec_inl
-             | not is_local_id  -- See Note [Specialising imported functions]
-                                 -- in OccurAnal
-             , isStrongLoopBreaker (idOccInfo poly_id) = neverInlinePragma
-             | otherwise                               = id_inl
-     -- Get the INLINE pragma from SPECIALISE declaration, or,
-     -- failing that, from the original Id
-
-    spec_prag_act = inlinePragmaActivation spec_inl
-
-    -- See Note [Activation pragmas for SPECIALISE]
-    -- no_act_spec is True if the user didn't write an explicit
-    -- phase specification in the SPECIALISE pragma
-    no_act_spec = case inlinePragmaSpec spec_inl of
-                    NoInline -> isNeverActive  spec_prag_act
-                    _        -> isAlwaysActive spec_prag_act
-    rule_act | no_act_spec = inlinePragmaActivation id_inl   -- Inherit
-             | otherwise   = spec_prag_act                   -- Specified by user
-
-
-specOnInline :: Name -> MsgDoc
-specOnInline f = ptext (sLit "SPECIALISE pragma on INLINE function probably won't fire:")
-                 <+> quotes (ppr f)
-
-{-
-Note [Activation pragmas for SPECIALISE]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-From a user SPECIALISE pragma for f, we generate
-  a) A top-level binding    spec_fn = rhs
-  b) A RULE                 f dOrd = spec_fn
-
-We need two pragma-like things:
-
-* spec_fn's inline pragma: inherited from f's inline pragma (ignoring
-                           activation on SPEC), unless overriden by SPEC INLINE
-
-* Activation of RULE: from SPECIALISE pragma (if activation given)
-                      otherwise from f's inline pragma
-
-This is not obvious (see Trac #5237)!
-
-Examples      Rule activation   Inline prag on spec'd fn
----------------------------------------------------------------------
-SPEC [n] f :: ty            [n]   Always, or NOINLINE [n]
-                                  copy f's prag
-
-NOINLINE f
-SPEC [n] f :: ty            [n]   NOINLINE
-                                  copy f's prag
-
-NOINLINE [k] f
-SPEC [n] f :: ty            [n]   NOINLINE [k]
-                                  copy f's prag
-
-INLINE [k] f
-SPEC [n] f :: ty            [n]   INLINE [k]
-                                  copy f's prag
-
-SPEC INLINE [n] f :: ty     [n]   INLINE [n]
-                                  (ignore INLINE prag on f,
-                                  same activation for rule and spec'd fn)
-
-NOINLINE [k] f
-SPEC f :: ty                [n]   INLINE [k]
-
-
-************************************************************************
-*                                                                      *
-\subsection{Adding inline pragmas}
-*                                                                      *
-************************************************************************
--}
-
-decomposeRuleLhs :: [Var] -> CoreExpr -> Either SDoc ([Var], Id, [CoreExpr])
--- (decomposeRuleLhs bndrs lhs) takes apart the LHS of a RULE,
--- The 'bndrs' are the quantified binders of the rules, but decomposeRuleLhs
--- may add some extra dictionary binders (see Note [Free dictionaries])
---
--- Returns Nothing if the LHS isn't of the expected shape
--- Note [Decomposing the left-hand side of a RULE]
-decomposeRuleLhs orig_bndrs orig_lhs
-  | not (null unbound)    -- Check for things unbound on LHS
-                          -- See Note [Unused spec binders]
-  = Left (vcat (map dead_msg unbound))
-
-  | Var fn_var <- fun
-  , not (fn_var `elemVarSet` orig_bndr_set)
-  = -- pprTrace "decmposeRuleLhs" (vcat [ ptext (sLit "orig_bndrs:") <+> ppr orig_bndrs
-    --                                  , ptext (sLit "orig_lhs:") <+> ppr orig_lhs
-    --                                  , ptext (sLit "lhs1:")     <+> ppr lhs1
-    --                                  , ptext (sLit "bndrs1:") <+> ppr bndrs1
-    --                                  , ptext (sLit "fn_var:") <+> ppr fn_var
-    --                                  , ptext (sLit "args:")   <+> ppr args]) $
-    Right (bndrs1, fn_var, args)
-
-  | Case scrut bndr ty [(DEFAULT, _, body)] <- fun
-  , isDeadBinder bndr   -- Note [Matching seqId]
-  , let args' = [Type (idType bndr), Type ty, scrut, body]
-  = Right (bndrs1, seqId, args' ++ args)
-
-  | otherwise
-  = Left bad_shape_msg
- where
-   lhs1       = drop_dicts orig_lhs
-   lhs2       = simpleOptExpr lhs1  -- See Note [Simplify rule LHS]
-   (fun,args) = collectArgs lhs2
-   lhs_fvs    = exprFreeVars lhs2
-   unbound    = filterOut (`elemVarSet` lhs_fvs) orig_bndrs
-   bndrs1     = orig_bndrs ++ extra_dict_bndrs
-
-   orig_bndr_set = mkVarSet orig_bndrs
-
-        -- Add extra dict binders: Note [Free dictionaries]
-   extra_dict_bndrs = [ mkLocalId (localiseName (idName d)) (idType d)
-                      | d <- varSetElems (lhs_fvs `delVarSetList` orig_bndrs)
-                      , isDictId d ]
-
-   bad_shape_msg = hang (ptext (sLit "RULE left-hand side too complicated to desugar"))
-                      2 (vcat [ text "Optimised lhs:" <+> ppr lhs2
-                              , text "Orig lhs:" <+> ppr orig_lhs])
-   dead_msg bndr = hang (sep [ ptext (sLit "Forall'd") <+> pp_bndr bndr
-                             , ptext (sLit "is not bound in RULE lhs")])
-                      2 (vcat [ text "Orig bndrs:" <+> ppr orig_bndrs
-                              , text "Orig lhs:" <+> ppr orig_lhs
-                              , text "optimised lhs:" <+> ppr lhs2 ])
-   pp_bndr bndr
-    | isTyVar bndr                      = ptext (sLit "type variable") <+> quotes (ppr bndr)
-    | Just pred <- evVarPred_maybe bndr = ptext (sLit "constraint") <+> quotes (ppr pred)
-    | otherwise                         = ptext (sLit "variable") <+> quotes (ppr bndr)
-
-   drop_dicts :: CoreExpr -> CoreExpr
-   drop_dicts e
-       = wrap_lets needed bnds body
-     where
-       needed = orig_bndr_set `minusVarSet` exprFreeVars body
-       (bnds, body) = split_lets (occurAnalyseExpr e)
-           -- The occurAnalyseExpr drops dead bindings which is
-           -- crucial to ensure that every binding is used later;
-           -- which in turn makes wrap_lets work right
-
-   split_lets :: CoreExpr -> ([(DictId,CoreExpr)], CoreExpr)
-   split_lets e
-     | Let (NonRec d r) body <- e
-     , isDictId d
-     , (bs, body') <- split_lets body
-     = ((d,r):bs, body')
-     | otherwise
-     = ([], e)
-
-   wrap_lets :: VarSet -> [(DictId,CoreExpr)] -> CoreExpr -> CoreExpr
-   wrap_lets _ [] body = body
-   wrap_lets needed ((d, r) : bs) body
-     | rhs_fvs `intersectsVarSet` needed = Let (NonRec d r) (wrap_lets needed' bs body)
-     | otherwise                         = wrap_lets needed bs body
-     where
-       rhs_fvs = exprFreeVars r
-       needed' = (needed `minusVarSet` rhs_fvs) `extendVarSet` d
-
-{-
-Note [Decomposing the left-hand side of a RULE]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-There are several things going on here.
-* drop_dicts: see Note [Drop dictionary bindings on rule LHS]
-* simpleOptExpr: see Note [Simplify rule LHS]
-* extra_dict_bndrs: see Note [Free dictionaries]
-
-Note [Drop dictionary bindings on rule LHS]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-drop_dicts drops dictionary bindings on the LHS where possible.
-   E.g.  let d:Eq [Int] = $fEqList $fEqInt in f d
-     --> f d
-   Reasoning here is that there is only one d:Eq [Int], and so we can
-   quantify over it. That makes 'd' free in the LHS, but that is later
-   picked up by extra_dict_bndrs (Note [Dead spec binders]).
-
-   NB 1: We can only drop the binding if the RHS doesn't bind
-         one of the orig_bndrs, which we assume occur on RHS.
-         Example
-            f :: (Eq a) => b -> a -> a
-            {-# SPECIALISE f :: Eq a => b -> [a] -> [a] #-}
-         Here we want to end up with
-            RULE forall d:Eq a.  f ($dfEqList d) = f_spec d
-         Of course, the ($dfEqlist d) in the pattern makes it less likely
-         to match, but ther is no other way to get d:Eq a
-
-   NB 2: We do drop_dicts *before* simplOptEpxr, so that we expect all
-         the evidence bindings to be wrapped around the outside of the
-         LHS.  (After simplOptExpr they'll usually have been inlined.)
-         dsHsWrapper does dependency analysis, so that civilised ones
-         will be simple NonRec bindings.  We don't handle recursive
-         dictionaries!
-
-    NB3: In the common case of a non-overloaded, but perhaps-polymorphic
-         specialisation, we don't need to bind *any* dictionaries for use
-         in the RHS. For example (Trac #8331)
-             {-# SPECIALIZE INLINE useAbstractMonad :: ReaderST s Int #-}
-             useAbstractMonad :: MonadAbstractIOST m => m Int
-         Here, deriving (MonadAbstractIOST (ReaderST s)) is a lot of code
-         but the RHS uses no dictionaries, so we want to end up with
-             RULE forall s (d :: MonadBstractIOST (ReaderT s)).
-                useAbstractMonad (ReaderT s) d = $suseAbstractMonad s
-
-   Trac #8848 is a good example of where there are some intersting
-   dictionary bindings to discard.
-
-The drop_dicts algorithm is based on these observations:
-
-  * Given (let d = rhs in e) where d is a DictId,
-    matching 'e' will bind e's free variables.
-
-  * So we want to keep the binding if one of the needed variables (for
-    which we need a binding) is in fv(rhs) but not already in fv(e).
-
-  * The "needed variables" are simply the orig_bndrs.  Consider
-       f :: (Eq a, Show b) => a -> b -> String
-       ... SPECIALISE f :: (Show b) => Int -> b -> String ...
-    Then orig_bndrs includes the *quantified* dictionaries of the type
-    namely (dsb::Show b), but not the one for Eq Int
-
-So we work inside out, applying the above criterion at each step.
-
-
-Note [Simplify rule LHS]
-~~~~~~~~~~~~~~~~~~~~~~~~
-simplOptExpr occurrence-analyses and simplifies the LHS:
-
-   (a) Inline any remaining dictionary bindings (which hopefully
-       occur just once)
-
-   (b) Substitute trivial lets so that they don't get in the way
-       Note that we substitute the function too; we might
-       have this as a LHS:  let f71 = M.f Int in f71
-
-   (c) Do eta reduction.  To see why, consider the fold/build rule,
-       which without simplification looked like:
-          fold k z (build (/\a. g a))  ==>  ...
-       This doesn't match unless you do eta reduction on the build argument.
-       Similarly for a LHS like
-         augment g (build h)
-       we do not want to get
-         augment (\a. g a) (build h)
-       otherwise we don't match when given an argument like
-          augment (\a. h a a) (build h)
-
-Note [Matching seqId]
-~~~~~~~~~~~~~~~~~~~
-The desugarer turns (seq e r) into (case e of _ -> r), via a special-case hack
-and this code turns it back into an application of seq!
-See Note [Rules for seq] in MkId for the details.
-
-Note [Unused spec binders]
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
-        f :: a -> a
-        ... SPECIALISE f :: Eq a => a -> a ...
-It's true that this *is* a more specialised type, but the rule
-we get is something like this:
-        f_spec d = f
-        RULE: f = f_spec d
-Note that the rule is bogus, because it mentions a 'd' that is
-not bound on the LHS!  But it's a silly specialisation anyway, because
-the constraint is unused.  We could bind 'd' to (error "unused")
-but it seems better to reject the program because it's almost certainly
-a mistake.  That's what the isDeadBinder call detects.
-
-Note [Free dictionaries]
-~~~~~~~~~~~~~~~~~~~~~~~~
-When the LHS of a specialisation rule, (/\as\ds. f es) has a free dict,
-which is presumably in scope at the function definition site, we can quantify
-over it too.  *Any* dict with that type will do.
-
-So for example when you have
-        f :: Eq a => a -> a
-        f = <rhs>
-        ... SPECIALISE f :: Int -> Int ...
-
-Then we get the SpecPrag
-        SpecPrag (f Int dInt)
-
-And from that we want the rule
-
-        RULE forall dInt. f Int dInt = f_spec
-        f_spec = let f = <rhs> in f Int dInt
-
-But be careful!  That dInt might be GHC.Base.$fOrdInt, which is an External
-Name, and you can't bind them in a lambda or forall without getting things
-confused.   Likewise it might have an InlineRule or something, which would be
-utterly bogus. So we really make a fresh Id, with the same unique and type
-as the old one, but with an Internal name and no IdInfo.
-
-
-************************************************************************
-*                                                                      *
-                Desugaring evidence
-*                                                                      *
-************************************************************************
-
--}
-
-dsHsWrapper :: HsWrapper -> CoreExpr -> DsM CoreExpr
-dsHsWrapper WpHole            e = return e
-dsHsWrapper (WpTyApp ty)      e = return $ App e (Type ty)
-dsHsWrapper (WpLet ev_binds)  e = do bs <- dsTcEvBinds ev_binds
-                                     return (mkCoreLets bs e)
-dsHsWrapper (WpCompose c1 c2) e = do { e1 <- dsHsWrapper c2 e
-                                     ; dsHsWrapper c1 e1 }
-dsHsWrapper (WpFun c1 c2 t1 _) e = do { x <- newSysLocalDs t1
-                                      ; e1 <- dsHsWrapper c1 (Var x)
-                                      ; e2 <- dsHsWrapper c2 (e `mkCoreAppDs` e1)
-                                      ; return (Lam x e2) }
-dsHsWrapper (WpCast co)       e = -- ASSERT(tcCoercionRole co == Representational)
-                                  dsTcCoercion co (mkCast e)
-dsHsWrapper (WpEvLam ev)      e = return $ Lam ev e
-dsHsWrapper (WpTyLam tv)      e = return $ Lam tv e
-dsHsWrapper (WpEvApp    tm)   e = liftM (App e) (dsEvTerm tm)
-
---------------------------------------
-dsTcEvBinds :: TcEvBinds -> DsM [CoreBind]
-dsTcEvBinds (TcEvBinds {}) = panic "dsEvBinds"    -- Zonker has got rid of this
-dsTcEvBinds (EvBinds bs)   = dsEvBinds bs
-
-dsEvBinds :: Bag EvBind -> DsM [CoreBind]
-dsEvBinds bs = mapM ds_scc (sccEvBinds bs)
-  where
-    ds_scc (AcyclicSCC (EvBind v r)) = liftM (NonRec v) (dsEvTerm r)
-    ds_scc (CyclicSCC bs)            = liftM Rec (mapM ds_pair bs)
-
-    ds_pair (EvBind v r) = liftM ((,) v) (dsEvTerm r)
-
-sccEvBinds :: Bag EvBind -> [SCC EvBind]
-sccEvBinds bs = stronglyConnCompFromEdgedVertices edges
-  where
-    edges :: [(EvBind, EvVar, [EvVar])]
-    edges = foldrBag ((:) . mk_node) [] bs
-
-    mk_node :: EvBind -> (EvBind, EvVar, [EvVar])
-    mk_node b@(EvBind var term) = (b, var, varSetElems (evVarsOfTerm term))
-
-
----------------------------------------
-dsEvTerm :: EvTerm -> DsM CoreExpr
-dsEvTerm (EvId v) = return (Var v)
-
-dsEvTerm (EvCast tm co)
-  = do { tm' <- dsEvTerm tm
-       ; dsTcCoercion co $ mkCast tm' }
-                        -- 'v' is always a lifted evidence variable so it is
-                        -- unnecessary to call varToCoreExpr v here.
-
-dsEvTerm (EvDFunApp df tys tms) = do { tms' <- mapM dsEvTerm tms
-                                     ; return (Var df `mkTyApps` tys `mkApps` tms') }
-
-dsEvTerm (EvCoercion (TcCoVarCo v)) = return (Var v)  -- See Note [Simple coercions]
-dsEvTerm (EvCoercion co)            = dsTcCoercion co mkEqBox
-
-dsEvTerm (EvTupleSel v n)
-   = do { tm' <- dsEvTerm v
-        ; let scrut_ty = exprType tm'
-              (tc, tys) = splitTyConApp scrut_ty
-              Just [dc] = tyConDataCons_maybe tc
-              xs = mkTemplateLocals tys
-              the_x = getNth xs n
-        ; -- ASSERT( isTupleTyCon tc )
-          return $
-          Case tm' (mkWildValBinder scrut_ty) (idType the_x) [(DataAlt dc, xs, Var the_x)] }
-
-dsEvTerm (EvTupleMk tms)
-  = do { tms' <- mapM dsEvTerm tms
-       ; let tys = map exprType tms'
-       ; return $ Var (dataConWorkId dc) `mkTyApps` tys `mkApps` tms' }
-  where
-    dc = tupleCon ConstraintTuple (length tms)
-
-dsEvTerm (EvSuperClass d n)
-  = do { d' <- dsEvTerm d
-       ; let (cls, tys) = getClassPredTys (exprType d')
-             sc_sel_id  = classSCSelId cls n    -- Zero-indexed
-       ; return $ Var sc_sel_id `mkTyApps` tys `App` d' }
-  where
-
-dsEvTerm (EvDelayedError ty msg) = return $ Var errorId `mkTyApps` [ty] `mkApps` [litMsg]
-  where
-    errorId = rUNTIME_ERROR_ID
-    litMsg  = Lit (MachStr (fastStringToByteString msg))
-
-dsEvTerm (EvLit l) =
-  case l of
-    EvNum n -> mkIntegerExpr n
-    EvStr s -> mkStringExprFS s
-
-dsEvTerm (EvCallStack cs) = dsEvCallStack cs
-
-dsEvTerm (EvTypeable ev) = dsEvTypeable ev
-
-dsEvTypeable :: EvTypeable -> DsM CoreExpr
-dsEvTypeable ev =
-  do tyCl      <- dsLookupTyCon typeableClassName
-     typeRepTc <- dsLookupTyCon typeRepTyConName
-     let tyRepType = mkTyConApp typeRepTc []
-
-     (ty, rep) <-
-        case ev of
-
-          EvTypeableTyCon tc ks ->
-            do ctr       <- dsLookupGlobalId mkPolyTyConAppName
-               mkTyCon   <- dsLookupGlobalId mkTyConName
-               dflags    <- getDynFlags
-               let mkRep cRep kReps tReps =
-                     mkApps (Var ctr) [ cRep, mkListExpr tyRepType kReps
-                                            , mkListExpr tyRepType tReps ]
-
-               let kindRep k =
-                     case splitTyConApp_maybe k of
-                       Nothing -> panic "dsEvTypeable: not a kind constructor"
-                       Just (kc,ks) ->
-                         do kcRep <- tyConRep dflags mkTyCon kc
-                            reps  <- mapM kindRep ks
-                            return (mkRep kcRep [] reps)
-
-               tcRep     <- tyConRep dflags mkTyCon tc
-
-               kReps     <- mapM kindRep ks
-
-               return ( mkTyConApp tc ks
-                      , mkRep tcRep kReps []
-                      )
-
-          EvTypeableTyApp t1 t2 ->
-            do e1  <- getRep tyCl t1
-               e2  <- getRep tyCl t2
-               ctr <- dsLookupGlobalId mkAppTyName
-
-               return ( mkAppTy (snd t1) (snd t2)
-                      , mkApps (Var ctr) [ e1, e2 ]
-                      )
-
-          EvTypeableTyLit ty ->
-            do str <- case (isNumLitTy ty, isStrLitTy ty) of
-                        (Just n, _) -> return (show n)
-                        (_, Just n) -> return (show n)
-                        _ -> panic "dsEvTypeable: malformed TyLit evidence"
-               ctr <- dsLookupGlobalId typeLitTypeRepName
-               tag <- mkStringExpr str
-               return (ty, mkApps (Var ctr) [ tag ])
-
-     -- TyRep -> Typeable t
-     -- see also: Note [Memoising typeOf]
-     repName <- newSysLocalDs tyRepType
-     let proxyT = mkProxyPrimTy (typeKind ty) ty
-         method = bindNonRec repName rep
-                $ mkLams [mkWildValBinder proxyT] (Var repName)
-
-     -- package up the method as `Typeable` dictionary
-     return $ mkCast method $ mkSymCo $ getTypeableCo tyCl ty
-
-  where
-  -- co: method -> Typeable k t
-  getTypeableCo tc t =
-    case instNewTyCon_maybe tc [typeKind t, t] of
-      Just (_,co) -> co
-      _           -> panic "Class `Typeable` is not a `newtype`."
-
-  -- Typeable t -> TyRep
-  getRep tc (ev,t) =
-    do typeableExpr <- dsEvTerm ev
-       let co     = getTypeableCo tc t
-           method = mkCast typeableExpr co
-           proxy  = mkTyApps (Var proxyHashId) [typeKind t, t]
-       return (mkApps method [proxy])
-
-  -- This part could be cached
-  tyConRep dflags mkTyCon tc =
-    do pkgStr  <- mkStringExprFS pkg_fs
-       modStr  <- mkStringExprFS modl_fs
-       nameStr <- mkStringExprFS name_fs
-       return (mkApps (Var mkTyCon) [ int64 high, int64 low
-                                    , pkgStr, modStr, nameStr
-                                    ])
-    where
-    tycon_name                = tyConName tc
-    modl                      = nameModule tycon_name
-    pkg                       = modulePackageKey modl
-
-    modl_fs                   = moduleNameFS (moduleName modl)
-    pkg_fs                    = packageKeyFS pkg
-    name_fs                   = occNameFS (nameOccName tycon_name)
-    hash_name_fs
-      | isPromotedTyCon tc    = appendFS (mkFastString "$k") name_fs
-      | isPromotedDataCon tc  = appendFS (mkFastString "$c") name_fs
-      | otherwise             = name_fs
-
-    hashThis = unwords $ map unpackFS [pkg_fs, modl_fs, hash_name_fs]
-    Fingerprint high low = fingerprintString hashThis
-
-    int64
-      | wORD_SIZE dflags == 4 = mkWord64LitWord64
-      | otherwise             = mkWordLit dflags . fromIntegral
-
-
-
-{- Note [Memoising typeOf]
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-See #3245, #9203
-
-IMPORTANT: we don't want to recalculate the TypeRep once per call with
-the proxy argument.  This is what went wrong in #3245 and #9203. So we
-help GHC by manually keeping the 'rep' *outside* the lambda.
--}
-
-
-
-dsEvCallStack :: EvCallStack -> DsM CoreExpr
--- See Note [Overview of implicit CallStacks] in TcEvidence.hs
-dsEvCallStack cs = do
-  df              <- getDynFlags
-  m               <- getModule
-  srcLocDataCon   <- dsLookupDataCon srcLocDataConName
-  let srcLocTyCon  = dataConTyCon srcLocDataCon
-  let srcLocTy     = mkTyConTy srcLocTyCon
-  let mkSrcLoc l =
-        liftM (mkCoreConApps srcLocDataCon)
-              (sequence [ mkStringExprFS (packageKeyFS $ modulePackageKey m)
-                        , mkStringExprFS (moduleNameFS $ moduleName m)
-                        , mkStringExprFS (srcSpanFile l)
-                        , return $ mkIntExprInt df (srcSpanStartLine l)
-                        , return $ mkIntExprInt df (srcSpanStartCol l)
-                        , return $ mkIntExprInt df (srcSpanEndLine l)
-                        , return $ mkIntExprInt df (srcSpanEndCol l)
-                        ])
-
-  let callSiteTy = mkBoxedTupleTy [stringTy, srcLocTy]
-
-  matchId         <- newSysLocalDs $ mkListTy callSiteTy
-
-  callStackDataCon <- dsLookupDataCon callStackDataConName
-  let callStackTyCon = dataConTyCon callStackDataCon
-  let callStackTy    = mkTyConTy callStackTyCon
-  let emptyCS        = mkCoreConApps callStackDataCon [mkNilExpr callSiteTy]
-  let pushCS name loc rest =
-        mkWildCase rest callStackTy callStackTy
-                   [( DataAlt callStackDataCon
-                    , [matchId]
-                    , mkCoreConApps callStackDataCon
-                       [mkConsExpr callSiteTy
-                                   (mkCoreTup [name, loc])
-                                   (Var matchId)]
-                    )]
-  let mkPush name loc tm = do
-        nameExpr <- mkStringExprFS name
-        locExpr <- mkSrcLoc loc
-        case tm of
-          EvCallStack EvCsEmpty -> return (pushCS nameExpr locExpr emptyCS)
-          _ -> do tmExpr  <- dsEvTerm tm
-                  -- at this point tmExpr :: IP sym CallStack
-                  -- but we need the actual CallStack to pass to pushCS,
-                  -- so we use unwrapIP to strip the dictionary wrapper
-                  -- See Note [Overview of implicit CallStacks]
-                  let ip_co = unwrapIP (exprType tmExpr)
-                  return (pushCS nameExpr locExpr (mkCastDs tmExpr ip_co))
-  case cs of
-    EvCsTop name loc tm -> mkPush name loc tm
-    EvCsPushCall name loc tm -> mkPush (occNameFS $ getOccName name) loc tm
-    EvCsEmpty -> panic "Cannot have an empty CallStack"
-
-
----------------------------------------
-dsTcCoercion :: TcCoercion -> (Coercion -> CoreExpr) -> DsM CoreExpr
--- This is the crucial function that moves
--- from TcCoercions to Coercions; see Note [TcCoercions] in Coercion
--- e.g.  dsTcCoercion (trans g1 g2) k
---       = case g1 of EqBox g1# ->
---         case g2 of EqBox g2# ->
---         k (trans g1# g2#)
--- thing_inside will get a coercion at the role requested
-dsTcCoercion co thing_inside
-  = do { us <- newUniqueSupply
-       ; let eqvs_covs :: [(EqVar,CoVar)]
-             eqvs_covs = zipWith mk_co_var (varSetElems (coVarsOfTcCo co))
-                                           (uniqsFromSupply us)
-
-             subst = mkCvSubst emptyInScopeSet [(eqv, mkCoVarCo cov) | (eqv, cov) <- eqvs_covs]
-             result_expr = thing_inside (ds_tc_coercion subst co)
-             result_ty   = exprType result_expr
-
-       ; return (foldr (wrap_in_case result_ty) result_expr eqvs_covs) }
-  where
-    mk_co_var :: Id -> Unique -> (Id, Id)
-    mk_co_var eqv uniq = (eqv, mkUserLocal occ uniq ty loc)
-       where
-         eq_nm = idName eqv
-         occ = nameOccName eq_nm
-         loc = nameSrcSpan eq_nm
-         ty  = mkCoercionType (getEqPredRole (evVarPred eqv)) ty1 ty2
-         (ty1, ty2) = getEqPredTys (evVarPred eqv)
-
-    wrap_in_case result_ty (eqv, cov) body
-      = case getEqPredRole (evVarPred eqv) of
-         Nominal          -> Case (Var eqv) eqv result_ty [(DataAlt eqBoxDataCon, [cov], body)]
-         Representational -> Case (Var eqv) eqv result_ty [(DataAlt coercibleDataCon, [cov], body)]
-         Phantom          -> panic "wrap_in_case/phantom"
-
-ds_tc_coercion :: CvSubst -> TcCoercion -> Coercion
--- If the incoming TcCoercion if of type (a ~ b)   (resp.  Coercible a b)
---                 the result is of type (a ~# b)  (reps.  a ~# b)
--- The VarEnv maps EqVars of type (a ~ b) to Coercions of type (a ~# b) (resp. and so on)
--- No need for InScope set etc because the
-ds_tc_coercion subst tc_co
-  = go tc_co
-  where
-    go (TcRefl r ty)            = Refl r (Coercion.substTy subst ty)
-    go (TcTyConAppCo r tc cos)  = mkTyConAppCo r tc (map go cos)
-    go (TcAppCo co1 co2)        = mkAppCo (go co1) (go co2)
-    go (TcForAllCo tv co)       = mkForAllCo tv' (ds_tc_coercion subst' co)
-                              where
-                                (subst', tv') = Coercion.substTyVarBndr subst tv
-    go (TcAxiomInstCo ax ind cos)
-                                = AxiomInstCo ax ind (map go cos)
-    go (TcPhantomCo ty1 ty2)    = UnivCo (fsLit "ds_tc_coercion") Phantom ty1 ty2
-    go (TcSymCo co)             = mkSymCo (go co)
-    go (TcTransCo co1 co2)      = mkTransCo (go co1) (go co2)
-    go (TcNthCo n co)           = mkNthCo n (go co)
-    go (TcLRCo lr co)           = mkLRCo lr (go co)
-    go (TcSubCo co)             = mkSubCo (go co)
-    go (TcLetCo bs co)          = ds_tc_coercion (ds_co_binds bs) co
-    go (TcCastCo co1 co2)       = mkCoCast (go co1) (go co2)
-    go (TcCoVarCo v)            = ds_ev_id subst v
-    go (TcAxiomRuleCo co ts cs) = AxiomRuleCo co (map (Coercion.substTy subst) ts) (map go cs)
-    go (TcCoercion co)          = co
-
-    ds_co_binds :: TcEvBinds -> CvSubst
-    ds_co_binds (EvBinds bs)      = foldl ds_scc subst (sccEvBinds bs)
-    ds_co_binds eb@(TcEvBinds {}) = pprPanic "ds_co_binds" (ppr eb)
-
-    ds_scc :: CvSubst -> SCC EvBind -> CvSubst
-    ds_scc subst (AcyclicSCC (EvBind v ev_term))
-      = extendCvSubstAndInScope subst v (ds_co_term subst ev_term)
-    ds_scc _ (CyclicSCC other) = pprPanic "ds_scc:cyclic" (ppr other $$ ppr tc_co)
-
-    ds_co_term :: CvSubst -> EvTerm -> Coercion
-    ds_co_term subst (EvCoercion tc_co) = ds_tc_coercion subst tc_co
-    ds_co_term subst (EvId v)           = ds_ev_id subst v
-    ds_co_term subst (EvCast tm co)     = mkCoCast (ds_co_term subst tm) (ds_tc_coercion subst co)
-    ds_co_term _ other = pprPanic "ds_co_term" (ppr other $$ ppr tc_co)
-
-    ds_ev_id :: CvSubst -> EqVar -> Coercion
-    ds_ev_id subst v
-     | Just co <- Coercion.lookupCoVar subst v = co
-     | otherwise  = pprPanic "ds_tc_coercion" (ppr v $$ ppr tc_co)
-
-{-
-Note [Simple coercions]
-~~~~~~~~~~~~~~~~~~~~~~~
-We have a special case for coercions that are simple variables.
-Suppose   cv :: a ~ b   is in scope
-Lacking the special case, if we see
-        f a b cv
-we'd desguar to
-        f a b (case cv of EqBox (cv# :: a ~# b) -> EqBox cv#)
-which is a bit stupid.  The special case does the obvious thing.
-
-This turns out to be important when desugaring the LHS of a RULE
-(see Trac #7837).  Suppose we have
-    normalise        :: (a ~ Scalar a) => a -> a
-    normalise_Double :: Double -> Double
-    {-# RULES "normalise" normalise = normalise_Double #-}
-
-Then the RULE we want looks like
-     forall a, (cv:a~Scalar a).
-       normalise a cv = normalise_Double
-But without the special case we generate the redundant box/unbox,
-which simpleOpt (currently) doesn't remove. So the rule never matches.
-
-Maybe simpleOpt should be smarter.  But it seems like a good plan
-to simply never generate the redundant box/unbox in the first place.
--}
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsCCall.hs b/src/Language/Haskell/Liquid/Desugar710/DsCCall.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsCCall.hs
+++ /dev/null
@@ -1,381 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The AQUA Project, Glasgow University, 1994-1998
-
-
-Desugaring foreign calls
--}
-
-{-# LANGUAGE CPP #-}
-module Language.Haskell.Liquid.Desugar710.DsCCall
-        ( dsCCall
-        , mkFCall
-        , unboxArg
-        , boxResult
-        , resultWrapper
-        ) where
-
--- #include "HsVersions.h"
-
-import Prelude hiding (error)
-import CoreSyn
-
-import DsMonad
-
-import CoreUtils
-import MkCore
-import Var
-import MkId
-import ForeignCall
-import DataCon
-
-import TcType
-import Type
-import Coercion
-import PrimOp
-import TysPrim
-import TyCon
-import TysWiredIn
-import BasicTypes
-import Literal
-import PrelNames
-import VarSet
-import DynFlags
-import Outputable
-
-import Data.Maybe
-
-{-
-Desugaring of @ccall@s consists of adding some state manipulation,
-unboxing any boxed primitive arguments and boxing the result if
-desired.
-
-The state stuff just consists of adding in
-@PrimIO (\ s -> case s of { S# s# -> ... })@ in an appropriate place.
-
-The unboxing is straightforward, as all information needed to unbox is
-available from the type.  For each boxed-primitive argument, we
-transform:
-\begin{verbatim}
-   _ccall_ foo [ r, t1, ... tm ] e1 ... em
-   |
-   |
-   V
-   case e1 of { T1# x1# ->
-   ...
-   case em of { Tm# xm# -> xm#
-   ccall# foo [ r, t1#, ... tm# ] x1# ... xm#
-   } ... }
-\end{verbatim}
-
-The reboxing of a @_ccall_@ result is a bit tricker: the types don't
-contain information about the state-pairing functions so we have to
-keep a list of \tr{(type, s-p-function)} pairs.  We transform as
-follows:
-\begin{verbatim}
-   ccall# foo [ r, t1#, ... tm# ] e1# ... em#
-   |
-   |
-   V
-   \ s# -> case (ccall# foo [ r, t1#, ... tm# ] s# e1# ... em#) of
-          (StateAnd<r># result# state#) -> (R# result#, realWorld#)
-\end{verbatim}
--}
-
-dsCCall :: CLabelString -- C routine to invoke
-        -> [CoreExpr]   -- Arguments (desugared)
-        -> Safety       -- Safety of the call
-        -> Type         -- Type of the result: IO t
-        -> DsM CoreExpr -- Result, of type ???
-
-dsCCall lbl args may_gc result_ty
-  = do (unboxed_args, arg_wrappers) <- mapAndUnzipM unboxArg args
-       (ccall_result_ty, res_wrapper) <- boxResult result_ty
-       uniq <- newUnique
-       dflags <- getDynFlags
-       let
-           target = StaticTarget lbl Nothing True
-           the_fcall    = CCall (CCallSpec target CCallConv may_gc)
-           the_prim_app = mkFCall dflags uniq the_fcall unboxed_args ccall_result_ty
-       return (foldr ($) (res_wrapper the_prim_app) arg_wrappers)
-
-mkFCall :: DynFlags -> Unique -> ForeignCall
-        -> [CoreExpr]   -- Args
-        -> Type         -- Result type
-        -> CoreExpr
--- Construct the ccall.  The only tricky bit is that the ccall Id should have
--- no free vars, so if any of the arg tys do we must give it a polymorphic type.
---      [I forget *why* it should have no free vars!]
--- For example:
---      mkCCall ... [s::StablePtr (a->b), x::Addr, c::Char]
---
--- Here we build a ccall thus
---      (ccallid::(forall a b.  StablePtr (a -> b) -> Addr -> Char -> IO Addr))
---                      a b s x c
-mkFCall dflags uniq the_fcall val_args res_ty
-  = mkApps (mkVarApps (Var the_fcall_id) tyvars) val_args
-  where
-    arg_tys = map exprType val_args
-    body_ty = (mkFunTys arg_tys res_ty)
-    tyvars  = varSetElems (tyVarsOfType body_ty)
-    ty      = mkForAllTys tyvars body_ty
-    the_fcall_id = mkFCallId dflags uniq the_fcall ty
-
-unboxArg :: CoreExpr                    -- The supplied argument
-         -> DsM (CoreExpr,              -- To pass as the actual argument
-                 CoreExpr -> CoreExpr   -- Wrapper to unbox the arg
-                )
--- Example: if the arg is e::Int, unboxArg will return
---      (x#::Int#, \W. case x of I# x# -> W)
--- where W is a CoreExpr that probably mentions x#
-
-unboxArg arg
-  -- Primtive types: nothing to unbox
-  | isPrimitiveType arg_ty
-  = return (arg, \body -> body)
-
-  -- Recursive newtypes
-  | Just(co, _rep_ty) <- topNormaliseNewType_maybe arg_ty
-  = unboxArg (mkCast arg co)
-
-  -- Booleans
-  | Just tc <- tyConAppTyCon_maybe arg_ty,
-    tc `hasKey` boolTyConKey
-  = do dflags <- getDynFlags
-       prim_arg <- newSysLocalDs intPrimTy
-       return (Var prim_arg,
-              \ body -> Case (mkWildCase arg arg_ty intPrimTy
-                                       [(DataAlt falseDataCon,[],mkIntLit dflags 0),
-                                        (DataAlt trueDataCon, [],mkIntLit dflags 1)])
-                                        -- In increasing tag order!
-                             prim_arg
-                             (exprType body)
-                             [(DEFAULT,[],body)])
-
-  -- Data types with a single constructor, which has a single, primitive-typed arg
-  -- This deals with Int, Float etc; also Ptr, ForeignPtr
-  | is_product_type && data_con_arity == 1
-  = -- ASSERT2(isUnLiftedType data_con_arg_ty1, pprType arg_ty)
-                        -- Typechecker ensures this
-    do case_bndr <- newSysLocalDs arg_ty
-       prim_arg <- newSysLocalDs data_con_arg_ty1
-       return (Var prim_arg,
-               \ body -> Case arg case_bndr (exprType body) [(DataAlt data_con,[prim_arg],body)]
-              )
-
-  -- Byte-arrays, both mutable and otherwise; hack warning
-  -- We're looking for values of type ByteArray, MutableByteArray
-  --    data ByteArray          ix = ByteArray        ix ix ByteArray#
-  --    data MutableByteArray s ix = MutableByteArray ix ix (MutableByteArray# s)
-  | is_product_type &&
-    data_con_arity == 3 &&
-    isJust maybe_arg3_tycon &&
-    (arg3_tycon ==  byteArrayPrimTyCon ||
-     arg3_tycon ==  mutableByteArrayPrimTyCon)
-  = do case_bndr <- newSysLocalDs arg_ty
-       vars@[_l_var, _r_var, arr_cts_var] <- newSysLocalsDs data_con_arg_tys
-       return (Var arr_cts_var,
-               \ body -> Case arg case_bndr (exprType body) [(DataAlt data_con,vars,body)]
-              )
-
-  | otherwise
-  = do l <- getSrcSpanDs
-       pprPanic "unboxArg: " (ppr l <+> ppr arg_ty)
-  where
-    arg_ty                                      = exprType arg
-    maybe_product_type                          = splitDataProductType_maybe arg_ty
-    is_product_type                             = isJust maybe_product_type
-    Just (_, _, data_con, data_con_arg_tys)     = maybe_product_type
-    data_con_arity                              = dataConSourceArity data_con
-    (data_con_arg_ty1 : _)                      = data_con_arg_tys
-
-    (_ : _ : data_con_arg_ty3 : _) = data_con_arg_tys
-    maybe_arg3_tycon               = tyConAppTyCon_maybe data_con_arg_ty3
-    Just arg3_tycon                = maybe_arg3_tycon
-
-boxResult :: Type
-          -> DsM (Type, CoreExpr -> CoreExpr)
-
--- Takes the result of the user-level ccall:
---      either (IO t),
---      or maybe just t for an side-effect-free call
--- Returns a wrapper for the primitive ccall itself, along with the
--- type of the result of the primitive ccall.  This result type
--- will be of the form
---      State# RealWorld -> (# State# RealWorld, t' #)
--- where t' is the unwrapped form of t.  If t is simply (), then
--- the result type will be
---      State# RealWorld -> (# State# RealWorld #)
-
-boxResult result_ty
-  | Just (io_tycon, io_res_ty) <- tcSplitIOType_maybe result_ty
-        -- isIOType_maybe handles the case where the type is a
-        -- simple wrapping of IO.  E.g.
-        --      newtype Wrap a = W (IO a)
-        -- No coercion necessary because its a non-recursive newtype
-        -- (If we wanted to handle a *recursive* newtype too, we'd need
-        -- another case, and a coercion.)
-        -- The result is IO t, so wrap the result in an IO constructor
-  = do  { res <- resultWrapper io_res_ty
-        ; let extra_result_tys
-                = case res of
-                     (Just ty,_)
-                       | isUnboxedTupleType ty
-                       -> let Just ls = tyConAppArgs_maybe ty in tail ls
-                     _ -> []
-
-              return_result state anss
-                = mkCoreConApps (tupleCon UnboxedTuple (2 + length extra_result_tys))
-                                (map Type (realWorldStatePrimTy : io_res_ty : extra_result_tys)
-                                 ++ (state : anss))
-
-        ; (ccall_res_ty, the_alt) <- mk_alt return_result res
-
-        ; state_id <- newSysLocalDs realWorldStatePrimTy
-        ; let io_data_con = head (tyConDataCons io_tycon)
-              toIOCon     = dataConWrapId io_data_con
-
-              wrap the_call =
-                              mkApps (Var toIOCon)
-                                     [ Type io_res_ty,
-                                       Lam state_id $
-                                       mkWildCase (App the_call (Var state_id))
-                                             ccall_res_ty
-                                             (coreAltType the_alt)
-                                             [the_alt]
-                                     ]
-
-        ; return (realWorldStatePrimTy `mkFunTy` ccall_res_ty, wrap) }
-
-boxResult result_ty
-  = do -- It isn't IO, so do unsafePerformIO
-       -- It's not conveniently available, so we inline it
-       res <- resultWrapper result_ty
-       (ccall_res_ty, the_alt) <- mk_alt return_result res
-       let
-           wrap = \ the_call -> mkWildCase (App the_call (Var realWorldPrimId))
-                                           ccall_res_ty
-                                           (coreAltType the_alt)
-                                           [the_alt]
-       return (realWorldStatePrimTy `mkFunTy` ccall_res_ty, wrap)
-  where
-    return_result _ [ans] = ans
-    return_result _ _     = panic "return_result: expected single result"
-
-
-mk_alt :: (Expr Var -> [Expr Var] -> Expr Var)
-       -> (Maybe Type, Expr Var -> Expr Var)
-       -> DsM (Type, (AltCon, [Id], Expr Var))
-mk_alt return_result (Nothing, wrap_result)
-  = do -- The ccall returns ()
-       state_id <- newSysLocalDs realWorldStatePrimTy
-       let
-             the_rhs = return_result (Var state_id)
-                                     [wrap_result (panic "boxResult")]
-
-             ccall_res_ty = mkTyConApp unboxedSingletonTyCon [realWorldStatePrimTy]
-             the_alt      = (DataAlt unboxedSingletonDataCon, [state_id], the_rhs)
-
-       return (ccall_res_ty, the_alt)
-
-mk_alt return_result (Just prim_res_ty, wrap_result)
-                -- The ccall returns a non-() value
-  | isUnboxedTupleType prim_res_ty= do
-    let
-        Just ls = tyConAppArgs_maybe prim_res_ty
-        arity = 1 + length ls
-    args_ids@(result_id:as) <- mapM newSysLocalDs ls
-    state_id <- newSysLocalDs realWorldStatePrimTy
-    let
-        the_rhs = return_result (Var state_id)
-                                (wrap_result (Var result_id) : map Var as)
-        ccall_res_ty = mkTyConApp (tupleTyCon UnboxedTuple arity)
-                                  (realWorldStatePrimTy : ls)
-        the_alt      = ( DataAlt (tupleCon UnboxedTuple arity)
-                       , (state_id : args_ids)
-                       , the_rhs
-                       )
-    return (ccall_res_ty, the_alt)
-
-  | otherwise = do
-    result_id <- newSysLocalDs prim_res_ty
-    state_id <- newSysLocalDs realWorldStatePrimTy
-    let
-        the_rhs = return_result (Var state_id)
-                                [wrap_result (Var result_id)]
-        ccall_res_ty = mkTyConApp unboxedPairTyCon [realWorldStatePrimTy, prim_res_ty]
-        the_alt      = (DataAlt unboxedPairDataCon, [state_id, result_id], the_rhs)
-    return (ccall_res_ty, the_alt)
-
-
-resultWrapper :: Type
-              -> DsM (Maybe Type,               -- Type of the expected result, if any
-                      CoreExpr -> CoreExpr)     -- Wrapper for the result
--- resultWrapper deals with the result *value*
--- E.g. foreign import foo :: Int -> IO T
--- Then resultWrapper deals with marshalling the 'T' part
-resultWrapper result_ty
-  -- Base case 1: primitive types
-  | isPrimitiveType result_ty
-  = return (Just result_ty, \e -> e)
-
-  -- Base case 2: the unit type ()
-  | Just (tc,_) <- maybe_tc_app, tc `hasKey` unitTyConKey
-  = return (Nothing, \_ -> Var unitDataConId)
-
-  -- Base case 3: the boolean type
-  | Just (tc,_) <- maybe_tc_app, tc `hasKey` boolTyConKey
-  = do
-    dflags <- getDynFlags
-    return
-     (Just intPrimTy, \e -> mkWildCase e intPrimTy
-                                   boolTy
-                                   [(DEFAULT                    ,[],Var trueDataConId ),
-                                    (LitAlt (mkMachInt dflags 0),[],Var falseDataConId)])
-
-  -- Newtypes
-  | Just (co, rep_ty) <- topNormaliseNewType_maybe result_ty
-  = do (maybe_ty, wrapper) <- resultWrapper rep_ty
-       return (maybe_ty, \e -> mkCast (wrapper e) (mkSymCo co))
-
-  -- The type might contain foralls (eg. for dummy type arguments,
-  -- referring to 'Ptr a' is legal).
-  | Just (tyvar, rest) <- splitForAllTy_maybe result_ty
-  = do (maybe_ty, wrapper) <- resultWrapper rest
-       return (maybe_ty, \e -> Lam tyvar (wrapper e))
-
-  -- Data types with a single constructor, which has a single arg
-  -- This includes types like Ptr and ForeignPtr
-  | Just (tycon, tycon_arg_tys, data_con, data_con_arg_tys) <- splitDataProductType_maybe result_ty,
-    dataConSourceArity data_con == 1
-  = do dflags <- getDynFlags
-       let
-           (unwrapped_res_ty : _) = data_con_arg_tys
-           narrow_wrapper         = maybeNarrow dflags tycon
-       (maybe_ty, wrapper) <- resultWrapper unwrapped_res_ty
-       return
-         (maybe_ty, \e -> mkApps (Var (dataConWrapId data_con))
-                                 (map Type tycon_arg_tys ++ [wrapper (narrow_wrapper e)]))
-
-  | otherwise
-  = pprPanic "resultWrapper" (ppr result_ty)
-  where
-    maybe_tc_app = splitTyConApp_maybe result_ty
-
--- When the result of a foreign call is smaller than the word size, we
--- need to sign- or zero-extend the result up to the word size.  The C
--- standard appears to say that this is the responsibility of the
--- caller, not the callee.
-
-maybeNarrow :: DynFlags -> TyCon -> (CoreExpr -> CoreExpr)
-maybeNarrow dflags tycon
-  | tycon `hasKey` int8TyConKey   = \e -> App (Var (mkPrimOpId Narrow8IntOp)) e
-  | tycon `hasKey` int16TyConKey  = \e -> App (Var (mkPrimOpId Narrow16IntOp)) e
-  | tycon `hasKey` int32TyConKey
-         && wORD_SIZE dflags > 4         = \e -> App (Var (mkPrimOpId Narrow32IntOp)) e
-
-  | tycon `hasKey` word8TyConKey  = \e -> App (Var (mkPrimOpId Narrow8WordOp)) e
-  | tycon `hasKey` word16TyConKey = \e -> App (Var (mkPrimOpId Narrow16WordOp)) e
-  | tycon `hasKey` word32TyConKey
-         && wORD_SIZE dflags > 4         = \e -> App (Var (mkPrimOpId Narrow32WordOp)) e
-  | otherwise                     = id
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsExpr.hs b/src/Language/Haskell/Liquid/Desugar710/DsExpr.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsExpr.hs
+++ /dev/null
@@ -1,983 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-Desugaring exporessions.
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.DsExpr ( dsExpr, dsLExpr, dsLocalBinds, dsValBinds, dsLit ) where
-
--- #include "HsVersions.h"
-
-import Prelude hiding (error)
-import Language.Haskell.Liquid.Desugar710.Match
-import Language.Haskell.Liquid.Desugar710.MatchLit
-import Language.Haskell.Liquid.Desugar710.DsBinds
-import Language.Haskell.Liquid.Desugar710.DsGRHSs
-import Language.Haskell.Liquid.Desugar710.DsListComp
-import Language.Haskell.Liquid.Desugar710.DsUtils
-import Language.Haskell.Liquid.Desugar710.DsArrows
-import DsMonad
-import Name
-import NameEnv
-import FamInstEnv( topNormaliseType )
-import Language.Haskell.Liquid.Types.Errors (impossible)
-
-import HsSyn
-
-import Platform
--- NB: The desugarer, which straddles the source and Core worlds, sometimes
---     needs to see source types
-import TcType
-import Coercion ( Role(..) )
-import TcEvidence
-import TcRnMonad
-import Type
-import CoreSyn
-import CoreUtils
-import CoreFVs
-import MkCore
-
-import DynFlags
-import CostCentre
-import Id
-import Module
-import VarSet
-import VarEnv
-import ConLike
-import DataCon
-import TysWiredIn
-import PrelNames
-import BasicTypes
-import Maybes
-import SrcLoc
-import Util
-import Bag
-import Outputable
-import FastString
-
-import IdInfo
-import Data.IORef       ( atomicModifyIORef, modifyIORef )
-
-import Control.Monad
-import GHC.Fingerprint
-
-srcSpanTick :: Module -> SrcSpan -> Tickish a
-srcSpanTick m loc
-  = ProfNote (AllCafsCC m loc) False True
-
-{-
-************************************************************************
-*                                                                      *
-                dsLocalBinds, dsValBinds
-*                                                                      *
-************************************************************************
--}
-
-dsLocalBinds :: HsLocalBinds Id -> CoreExpr -> DsM CoreExpr
-dsLocalBinds EmptyLocalBinds    body = return body
-dsLocalBinds (HsValBinds binds) body = dsValBinds binds body
-dsLocalBinds (HsIPBinds binds)  body = dsIPBinds  binds body
-
--------------------------
-dsValBinds :: HsValBinds Id -> CoreExpr -> DsM CoreExpr
-dsValBinds (ValBindsOut binds _) body = foldrM ds_val_bind body binds
-dsValBinds (ValBindsIn  _     _) _    = panic "dsValBinds ValBindsIn"
-
--------------------------
-dsIPBinds :: HsIPBinds Id -> CoreExpr -> DsM CoreExpr
-dsIPBinds (IPBinds ip_binds ev_binds) body
-  = do  { ds_binds <- dsTcEvBinds ev_binds
-        ; let inner = mkCoreLets ds_binds body
-                -- The dict bindings may not be in
-                -- dependency order; hence Rec
-        ; foldrM ds_ip_bind inner ip_binds }
-  where
-    ds_ip_bind (L _ (IPBind ~(Right n) e)) body
-      = do e' <- dsLExpr e
-           return (Let (NonRec n e') body)
-
--------------------------
-ds_val_bind :: (RecFlag, LHsBinds Id) -> CoreExpr -> DsM CoreExpr
--- Special case for bindings which bind unlifted variables
--- We need to do a case right away, rather than building
--- a tuple and doing selections.
--- Silently ignore INLINE and SPECIALISE pragmas...
-ds_val_bind (NonRecursive, hsbinds) body
-  | [L loc bind] <- bagToList hsbinds,
-        -- Non-recursive, non-overloaded bindings only come in ones
-        -- ToDo: in some bizarre case it's conceivable that there
-        --       could be dict binds in the 'binds'.  (See the notes
-        --       below.  Then pattern-match would fail.  Urk.)
-    strictMatchOnly bind
-  = putSrcSpanDs loc (dsStrictBind bind body)
-
--- Ordinary case for bindings; none should be unlifted
-ds_val_bind (_is_rec, binds) body
-  = do  { prs <- dsLHsBinds binds
-        ; -- ASSERT2( not (any (isUnLiftedType . idType . fst) prs), ppr _is_rec $$ ppr binds )
-          case prs of
-            [] -> return body
-            _  -> return (Let (Rec prs) body) }
-        -- Use a Rec regardless of is_rec.
-        -- Why? Because it allows the binds to be all
-        -- mixed up, which is what happens in one rare case
-        -- Namely, for an AbsBind with no tyvars and no dicts,
-        --         but which does have dictionary bindings.
-        -- See notes with TcSimplify.inferLoop [NO TYVARS]
-        -- It turned out that wrapping a Rec here was the easiest solution
-        --
-        -- NB The previous case dealt with unlifted bindings, so we
-        --    only have to deal with lifted ones now; so Rec is ok
-
-------------------
-dsStrictBind :: HsBind Id -> CoreExpr -> DsM CoreExpr
-dsStrictBind (AbsBinds { abs_tvs = [], abs_ev_vars = []
-               , abs_exports = exports
-               , abs_ev_binds = ev_binds
-               , abs_binds = lbinds }) body
-  = do { let body1 = foldr bind_export body exports
-             bind_export export b = bindNonRec (abe_poly export) (Var (abe_mono export)) b
-       ; body2 <- foldlBagM (\body lbind -> dsStrictBind (unLoc lbind) body)
-                            body1 lbinds
-       ; ds_binds <- dsTcEvBinds ev_binds
-       ; return (mkCoreLets ds_binds body2) }
-
-dsStrictBind (FunBind { fun_id = L _ fun, fun_matches = matches --, fun_co_fn = co_fn
-                      , fun_tick = tick, fun_infix = inf }) body
-                -- Can't be a bang pattern (that looks like a PatBind)
-                -- so must be simply unboxed
-  = do { (_args, rhs) <- matchWrapper (FunRhs (idName fun ) inf) matches
-       -- ; MASSERT( null args ) -- Functions aren't lifted
-       -- ; MASSERT( isIdHsWrapper co_fn )
-       ; let rhs' = mkOptTickBox tick rhs
-       ; return (bindNonRec fun rhs' body) }
-
-dsStrictBind (PatBind {pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty }) body
-  =     -- let C x# y# = rhs in body
-        -- ==> case rhs of C x# y# -> body
-    do { rhs <- dsGuarded grhss ty
-       ; let upat = unLoc pat
-             eqn = EqnInfo { eqn_pats = [upat],
-                             eqn_rhs = cantFailMatchResult body }
-       ; var    <- selectMatchVar upat
-       ; result <- matchEquations PatBindRhs [var] [eqn] (exprType body)
-       ; return (bindNonRec var rhs result) }
-
-dsStrictBind bind body = pprPanic "dsLet: unlifted" (ppr bind $$ ppr body)
-
-----------------------
-strictMatchOnly :: HsBind Id -> Bool
-strictMatchOnly (AbsBinds { abs_binds = lbinds })
-  = anyBag (strictMatchOnly . unLoc) lbinds
-strictMatchOnly (PatBind { pat_lhs = lpat, pat_rhs_ty = rhs_ty })
-  =  isUnLiftedType rhs_ty
-  || isStrictLPat lpat
-  || any (isUnLiftedType . idType) (collectPatBinders lpat)
-strictMatchOnly (FunBind { fun_id = L _ id })
-  = isUnLiftedType (idType id)
-strictMatchOnly _ = False -- I hope!  Checked immediately by caller in fact
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[DsExpr-vars-and-cons]{Variables, constructors, literals}
-*                                                                      *
-************************************************************************
--}
-
-dsLExpr :: LHsExpr Id -> DsM CoreExpr
-
-dsLExpr (L loc e)
-  = do ce <- putSrcSpanDs loc $ dsExpr e
-       m  <- getModule
-       return $ Tick (srcSpanTick m loc) ce
-
-dsExpr :: HsExpr Id -> DsM CoreExpr
-dsExpr (HsPar e)              = dsLExpr e
-dsExpr (ExprWithTySigOut e _) = dsLExpr e
-dsExpr (HsVar var)            = return (varToCoreExpr var)   -- See Note [Desugaring vars]
-dsExpr (HsIPVar _)            = panic "dsExpr: HsIPVar"
-dsExpr (HsLit lit)            = dsLit lit
-dsExpr (HsOverLit lit)        = dsOverLit lit
-
-dsExpr (HsWrap co_fn e)
-  = do { e' <- dsExpr e
-       ; wrapped_e <- dsHsWrapper co_fn e'
-       ; dflags <- getDynFlags
-       ; warnAboutIdentities dflags e' (exprType wrapped_e)
-       ; return wrapped_e }
-
-dsExpr (NegApp expr neg_expr)
-  = App <$> dsExpr neg_expr <*> dsLExpr expr
-
-dsExpr (HsLam a_Match)
-  = uncurry mkLams <$> matchWrapper LambdaExpr a_Match
-
-dsExpr (HsLamCase arg matches)
-  = do { arg_var <- newSysLocalDs arg
-       ; ([discrim_var], matching_code) <- matchWrapper CaseAlt matches
-       ; return $ Lam arg_var $ bindNonRec discrim_var (Var arg_var) matching_code }
-
-dsExpr (HsApp fun arg)
-  = mkCoreAppDs <$> dsLExpr fun <*>  dsLExpr arg
-
-dsExpr (HsUnboundVar _) = panic "dsExpr: HsUnboundVar"
-
-{-
-Note [Desugaring vars]
-~~~~~~~~~~~~~~~~~~~~~~
-In one situation we can get a *coercion* variable in a HsVar, namely
-the support method for an equality superclass:
-   class (a~b) => C a b where ...
-   instance (blah) => C (T a) (T b) where ..
-Then we get
-   $dfCT :: forall ab. blah => C (T a) (T b)
-   $dfCT ab blah = MkC ($c$p1C a blah) ($cop a blah)
-
-   $c$p1C :: forall ab. blah => (T a ~ T b)
-   $c$p1C ab blah = let ...; g :: T a ~ T b = ... } in g
-
-That 'g' in the 'in' part is an evidence variable, and when
-converting to core it must become a CO.
-
-Operator sections.  At first it looks as if we can convert
-\begin{verbatim}
-        (expr op)
-\end{verbatim}
-to
-\begin{verbatim}
-        \x -> op expr x
-\end{verbatim}
-
-But no!  expr might be a redex, and we can lose laziness badly this
-way.  Consider
-\begin{verbatim}
-        map (expr op) xs
-\end{verbatim}
-for example.  So we convert instead to
-\begin{verbatim}
-        let y = expr in \x -> op y x
-\end{verbatim}
-If \tr{expr} is actually just a variable, say, then the simplifier
-will sort it out.
--}
-
-dsExpr (OpApp e1 op _ e2)
-  = -- for the type of y, we need the type of op's 2nd argument
-    mkCoreAppsDs <$> dsLExpr op <*> mapM dsLExpr [e1, e2]
-
-dsExpr (SectionL expr op)       -- Desugar (e !) to ((!) e)
-  = mkCoreAppDs <$> dsLExpr op <*> dsLExpr expr
-
--- dsLExpr (SectionR op expr)   -- \ x -> op x expr
-dsExpr (SectionR op expr) = do
-    core_op <- dsLExpr op
-    -- for the type of x, we need the type of op's 2nd argument
-    let (x_ty:y_ty:_, _) = splitFunTys (exprType core_op)
-        -- See comment with SectionL
-    y_core <- dsLExpr expr
-    x_id <- newSysLocalDs x_ty
-    y_id <- newSysLocalDs y_ty
-    return (bindNonRec y_id y_core $
-            Lam x_id (mkCoreAppsDs core_op [Var x_id, Var y_id]))
-
-dsExpr (ExplicitTuple tup_args boxity)
-  = do { let go (lam_vars, args) (L _ (Missing ty))
-                    -- For every missing expression, we need
-                    -- another lambda in the desugaring.
-               = do { lam_var <- newSysLocalDs ty
-                    ; return (lam_var : lam_vars, Var lam_var : args) }
-             go (lam_vars, args) (L _ (Present expr))
-                    -- Expressions that are present don't generate
-                    -- lambdas, just arguments.
-               = do { core_expr <- dsLExpr expr
-                    ; return (lam_vars, core_expr : args) }
-
-       ; (lam_vars, args) <- foldM go ([], []) (reverse tup_args)
-                -- The reverse is because foldM goes left-to-right
-
-       ; return $ mkCoreLams lam_vars $
-                  mkConApp (tupleCon (boxityNormalTupleSort boxity) (length tup_args))
-                           (map (Type . exprType) args ++ args) }
-
-dsExpr (HsSCC _ cc expr@(L loc _)) = do
-    dflags <- getDynFlags
-    if gopt Opt_SccProfilingOn dflags
-      then do
-        mod_name <- getModule
-        count <- goptM Opt_ProfCountEntries
-        uniq <- newUnique
-        Tick (ProfNote (mkUserCC cc mod_name loc uniq) count True)
-               <$> dsLExpr expr
-      else dsLExpr expr
-
-dsExpr (HsCoreAnn _ _ expr)
-  = dsLExpr expr
-
-dsExpr (HsCase discrim matches)
-  = do { core_discrim <- dsLExpr discrim
-       ; ([discrim_var], matching_code) <- matchWrapper CaseAlt matches
-       ; return (bindNonRec discrim_var core_discrim matching_code) }
-
--- Pepe: The binds are in scope in the body but NOT in the binding group
---       This is to avoid silliness in breakpoints
-dsExpr (HsLet binds body) = do
-    body' <- dsLExpr body
-    dsLocalBinds binds body'
-
--- We need the `ListComp' form to use `deListComp' (rather than the "do" form)
--- because the interpretation of `stmts' depends on what sort of thing it is.
---
-dsExpr (HsDo ListComp     stmts res_ty) = dsListComp stmts res_ty
-dsExpr (HsDo PArrComp     stmts _)      = dsPArrComp (map unLoc stmts)
-dsExpr (HsDo DoExpr       stmts _)      = dsDo stmts
-dsExpr (HsDo GhciStmtCtxt stmts _)      = dsDo stmts
-dsExpr (HsDo MDoExpr      stmts _)      = dsDo stmts
-dsExpr (HsDo MonadComp    stmts _)      = dsMonadComp stmts
-
-dsExpr (HsIf mb_fun guard_expr then_expr else_expr)
-  = do { pred <- dsLExpr guard_expr
-       ; b1 <- dsLExpr then_expr
-       ; b2 <- dsLExpr else_expr
-       ; case mb_fun of
-           Just fun -> do { core_fun <- dsExpr fun
-                          ; return (mkCoreApps core_fun [pred,b1,b2]) }
-           Nothing  -> return $ mkIfThenElse pred b1 b2 }
-
-dsExpr (HsMultiIf res_ty alts)
-  | null alts
-  = mkErrorExpr
-
-  | otherwise
-  = do { match_result <- liftM (foldr1 combineMatchResults)
-                               (mapM (dsGRHS IfAlt res_ty) alts)
-       ; error_expr   <- mkErrorExpr
-       ; extractMatchResult match_result error_expr }
-  where
-    mkErrorExpr = mkErrorAppDs nON_EXHAUSTIVE_GUARDS_ERROR_ID res_ty
-                               (ptext (sLit "multi-way if"))
-
-{-
-\noindent
-\underline{\bf Various data construction things}
-             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--}
-
-dsExpr (ExplicitList elt_ty wit xs)
-  = dsExplicitList elt_ty wit xs
-
--- We desugar [:x1, ..., xn:] as
---   singletonP x1 +:+ ... +:+ singletonP xn
---
-dsExpr (ExplicitPArr ty []) = do
-    emptyP <- dsDPHBuiltin emptyPVar
-    return (Var emptyP `App` Type ty)
-dsExpr (ExplicitPArr ty xs) = do
-    singletonP <- dsDPHBuiltin singletonPVar
-    appP       <- dsDPHBuiltin appPVar
-    xs'        <- mapM dsLExpr xs
-    return . foldr1 (binary appP) $ map (unary singletonP) xs'
-  where
-    unary  fn x   = mkApps (Var fn) [Type ty, x]
-    binary fn x y = mkApps (Var fn) [Type ty, x, y]
-
-dsExpr (ArithSeq expr witness seq)
-  = case witness of
-     Nothing -> dsArithSeq expr seq
-     Just fl -> do {
-       ; fl' <- dsExpr fl
-       ; newArithSeq <- dsArithSeq expr seq
-       ; return (App fl' newArithSeq)}
-
-dsExpr (PArrSeq expr (FromTo from to))
-  = mkApps <$> dsExpr expr <*> mapM dsLExpr [from, to]
-
-dsExpr (PArrSeq expr (FromThenTo from thn to))
-  = mkApps <$> dsExpr expr <*> mapM dsLExpr [from, thn, to]
-
-dsExpr (PArrSeq _ _)
-  = panic "DsExpr.dsExpr: Infinite parallel array!"
-    -- the parser shouldn't have generated it and the renamer and typechecker
-    -- shouldn't have let it through
-
-{-
-\noindent
-\underline{\bf Static Pointers}
-               ~~~~~~~~~~~~~~~
-\begin{verbatim}
-    g = ... static f ...
-==>
-    sptEntry:N = StaticPtr
-        (fingerprintString "pkgKey:module.sptEntry:N")
-        (StaticPtrInfo "current pkg key" "current module" "sptEntry:0")
-        f
-    g = ... sptEntry:N
-\end{verbatim}
--}
-
-dsExpr (HsStatic expr@(L loc _)) = do
-    expr_ds <- dsLExpr expr
-    let ty = exprType expr_ds
-    n' <- mkSptEntryName loc
-    static_binds_var <- dsGetStaticBindsVar
-
-    staticPtrTyCon       <- dsLookupTyCon   staticPtrTyConName
-    staticPtrInfoDataCon <- dsLookupDataCon staticPtrInfoDataConName
-    staticPtrDataCon     <- dsLookupDataCon staticPtrDataConName
-    fingerprintDataCon   <- dsLookupDataCon fingerprintDataConName
-
-    dflags <- getDynFlags
-    let (line, col) = case loc of
-           RealSrcSpan r -> ( srcLocLine $ realSrcSpanStart r
-                            , srcLocCol  $ realSrcSpanStart r
-                            )
-           _             -> (0, 0)
-        srcLoc = mkCoreConApps (tupleCon BoxedTuple 2)
-                     [ Type intTy              , Type intTy
-                     , mkIntExprInt dflags line, mkIntExprInt dflags col
-                     ]
-    info <- mkConApp staticPtrInfoDataCon <$>
-            (++[srcLoc]) <$>
-            mapM mkStringExprFS
-                 [ packageKeyFS $ modulePackageKey $ nameModule n'
-                 , moduleNameFS $ moduleName $ nameModule n'
-                 , occNameFS    $ nameOccName n'
-                 ]
-    let tvars = varSetElems $ tyVarsOfType ty
-        speTy = mkForAllTys tvars $ mkTyConApp staticPtrTyCon [ty]
-        speId = mkExportedLocalId VanillaId n' speTy
-        fp@(Fingerprint w0 w1) = fingerprintName $ idName speId
-        fp_core = mkConApp fingerprintDataCon
-                    [ mkWord64LitWordRep dflags w0
-                    , mkWord64LitWordRep dflags w1
-                    ]
-        sp    = mkConApp staticPtrDataCon [Type ty, fp_core, info, expr_ds]
-    liftIO $ modifyIORef static_binds_var ((fp, (speId, mkLams tvars sp)) :)
-    putSrcSpanDs loc $ return $ mkTyApps (Var speId) (map mkTyVarTy tvars)
-
-  where
-
-    -- | Choose either 'Word64#' or 'Word#' to represent the arguments of the
-    -- 'Fingerprint' data constructor.
-    mkWord64LitWordRep dflags
-      | platformWordSize (targetPlatform dflags) < 8 = mkWord64LitWord64
-      | otherwise = mkWordLit dflags . toInteger
-
-    fingerprintName :: Name -> Fingerprint
-    fingerprintName n = fingerprintString $ unpackFS $ concatFS
-        [ packageKeyFS $ modulePackageKey $ nameModule n
-        , fsLit ":"
-        , moduleNameFS (moduleName $ nameModule n)
-        , fsLit "."
-        , occNameFS $ occName n
-        ]
-
-{-
-\noindent
-\underline{\bf Record construction and update}
-             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-For record construction we do this (assuming T has three arguments)
-\begin{verbatim}
-        T { op2 = e }
-==>
-        let err = /\a -> recConErr a
-        T (recConErr t1 "M.lhs/230/op1")
-          e
-          (recConErr t1 "M.lhs/230/op3")
-\end{verbatim}
-@recConErr@ then converts its arugment string into a proper message
-before printing it as
-\begin{verbatim}
-        M.lhs, line 230: missing field op1 was evaluated
-\end{verbatim}
-
-We also handle @C{}@ as valid construction syntax for an unlabelled
-constructor @C@, setting all of @C@'s fields to bottom.
--}
-
-dsExpr (RecordCon (L _ data_con_id) con_expr rbinds) = do
-    con_expr' <- dsExpr con_expr
-    let
-        (arg_tys, _) = tcSplitFunTys (exprType con_expr')
-        -- A newtype in the corner should be opaque;
-        -- hence TcType.tcSplitFunTys
-
-        mk_arg (arg_ty, lbl)    -- Selector id has the field label as its name
-          = case findField (rec_flds rbinds) lbl of
-              (rhs:_) -> -- ASSERT( null rhss )
-                            dsLExpr rhs
-              []         -> mkErrorAppDs rEC_CON_ERROR_ID arg_ty (ppr lbl)
-        unlabelled_bottom arg_ty = mkErrorAppDs rEC_CON_ERROR_ID arg_ty Outputable.empty
-
-        labels = dataConFieldLabels (idDataCon data_con_id)
-        -- The data_con_id is guaranteed to be the wrapper id of the constructor
-
-    con_args <- if null labels
-                then mapM unlabelled_bottom arg_tys
-                else mapM mk_arg (zipEqual "dsExpr:RecordCon" arg_tys labels)
-
-    return (mkApps con_expr' con_args)
-
-{-
-Record update is a little harder. Suppose we have the decl:
-\begin{verbatim}
-        data T = T1 {op1, op2, op3 :: Int}
-               | T2 {op4, op2 :: Int}
-               | T3
-\end{verbatim}
-Then we translate as follows:
-\begin{verbatim}
-        r { op2 = e }
-===>
-        let op2 = e in
-        case r of
-          T1 op1 _ op3 -> T1 op1 op2 op3
-          T2 op4 _     -> T2 op4 op2
-          other        -> recUpdError "M.lhs/230"
-\end{verbatim}
-It's important that we use the constructor Ids for @T1@, @T2@ etc on the
-RHSs, and do not generate a Core constructor application directly, because the constructor
-might do some argument-evaluation first; and may have to throw away some
-dictionaries.
-
-Note [Update for GADTs]
-~~~~~~~~~~~~~~~~~~~~~~~
-Consider
-   data T a b where
-     T1 { f1 :: a } :: T a Int
-
-Then the wrapper function for T1 has type
-   $WT1 :: a -> T a Int
-But if x::T a b, then
-   x { f1 = v } :: T a b   (not T a Int!)
-So we need to cast (T a Int) to (T a b).  Sigh.
--}
-
-dsExpr (RecordUpd record_expr (HsRecFields { rec_flds = fields })
-                       cons_to_upd in_inst_tys out_inst_tys)
-  | null fields
-  = dsLExpr record_expr
-  | otherwise
-  = -- ASSERT2( notNull cons_to_upd, ppr expr )
-
-    do  { record_expr' <- dsLExpr record_expr
-        ; field_binds' <- mapM ds_field fields
-        ; let upd_fld_env :: NameEnv Id -- Maps field name to the LocalId of the field binding
-              upd_fld_env = mkNameEnv [(f,l) | (f,l,_) <- field_binds']
-
-        -- It's important to generate the match with matchWrapper,
-        -- and the right hand sides with applications of the wrapper Id
-        -- so that everything works when we are doing fancy unboxing on the
-        -- constructor aguments.
-        ; alts <- mapM (mk_alt upd_fld_env) cons_to_upd
-        ; ([discrim_var], matching_code)
-                <- matchWrapper RecUpd (MG { mg_alts = alts, mg_arg_tys = [in_ty]
-                                           , mg_res_ty = out_ty, mg_origin = FromSource })
-                                           -- FromSource is not strictly right, but we
-                                           -- want incomplete pattern-match warnings
-
-        ; return (add_field_binds field_binds' $
-                  bindNonRec discrim_var record_expr' matching_code) }
-  where
-    ds_field :: LHsRecField Id (LHsExpr Id) -> DsM (Name, Id, CoreExpr)
-      -- Clone the Id in the HsRecField, because its Name is that
-      -- of the record selector, and we must not make that a lcoal binder
-      -- else we shadow other uses of the record selector
-      -- Hence 'lcl_id'.  Cf Trac #2735
-    ds_field (L _ rec_field) = do { rhs <- dsLExpr (hsRecFieldArg rec_field)
-                                  ; let fld_id = unLoc (hsRecFieldId rec_field)
-                                  ; lcl_id <- newSysLocalDs (idType fld_id)
-                                  ; return (idName fld_id, lcl_id, rhs) }
-
-    add_field_binds [] expr = expr
-    add_field_binds ((_,b,r):bs) expr = bindNonRec b r (add_field_binds bs expr)
-
-        -- Awkwardly, for families, the match goes
-        -- from instance type to family type
-    tycon     = dataConTyCon (head cons_to_upd)
-    in_ty     = mkTyConApp tycon in_inst_tys
-    out_ty    = mkFamilyTyConApp tycon out_inst_tys
-
-    mk_alt upd_fld_env con
-      = do { let (univ_tvs, ex_tvs, eq_spec,
-                  theta, arg_tys, _) = dataConFullSig con
-                 subst = mkTopTvSubst (univ_tvs `zip` in_inst_tys)
-
-                -- I'm not bothering to clone the ex_tvs
-           ; eqs_vars   <- mapM newPredVarDs (substTheta subst (eqSpecPreds eq_spec))
-           ; theta_vars <- mapM newPredVarDs (substTheta subst theta)
-           ; arg_ids    <- newSysLocalsDs (substTys subst arg_tys)
-           ; let val_args = zipWithEqual "dsExpr:RecordUpd" mk_val_arg
-                                         (dataConFieldLabels con) arg_ids
-                 mk_val_arg field_name pat_arg_id
-                     = nlHsVar (lookupNameEnv upd_fld_env field_name `orElse` pat_arg_id)
-                 inst_con = noLoc $ HsWrap wrap (HsVar (dataConWrapId con))
-                        -- Reconstruct with the WrapId so that unpacking happens
-                 wrap = mkWpEvVarApps theta_vars          <.>
-                        mkWpTyApps    (mkTyVarTys ex_tvs) <.>
-                        mkWpTyApps [ty | (tv, ty) <- univ_tvs `zip` out_inst_tys
-                                       , not (tv `elemVarEnv` wrap_subst) ]
-                 rhs = foldl (\a b -> nlHsApp a b) inst_con val_args
-
-                        -- Tediously wrap the application in a cast
-                        -- Note [Update for GADTs]
-                 wrap_co = mkTcTyConAppCo Nominal tycon
-                                [ lookup tv ty | (tv,ty) <- univ_tvs `zip` out_inst_tys ]
-                 lookup univ_tv ty = case lookupVarEnv wrap_subst univ_tv of
-                                        Just co' -> co'
-                                        Nothing  -> mkTcReflCo Nominal ty
-                 wrap_subst = mkVarEnv [ (tv, mkTcSymCo (mkTcCoVarCo eq_var))
-                                       | ((tv,_),eq_var) <- eq_spec `zip` eqs_vars ]
-
-                 pat = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon con)
-                                         , pat_tvs = ex_tvs
-                                         , pat_dicts = eqs_vars ++ theta_vars
-                                         , pat_binds = emptyTcEvBinds
-                                         , pat_args = PrefixCon $ map nlVarPat arg_ids
-                                         , pat_arg_tys = in_inst_tys
-                                         , pat_wrap = idHsWrapper }
-           ; let wrapped_rhs | null eq_spec = rhs
-                             | otherwise    = mkLHsWrap (mkWpCast (mkTcSubCo wrap_co)) rhs
-           ; return (mkSimpleMatch [pat] wrapped_rhs) }
-
--- Here is where we desugar the Template Haskell brackets and escapes
-
--- Template Haskell stuff
-
-dsExpr (HsRnBracketOut _ _) = panic "dsExpr HsRnBracketOut"
--- #ifdef GHCI
--- dsExpr (HsTcBracketOut x ps) = dsBracket x ps
--- #else
-dsExpr (HsTcBracketOut _ _) = panic "dsExpr HsBracketOut"
--- #endif
-dsExpr (HsSpliceE _ s)      = pprPanic "dsExpr:splice" (ppr s)
-
--- Arrow notation extension
-dsExpr (HsProc pat cmd) = dsProcExpr pat cmd
-
--- Hpc Support
-
-dsExpr (HsTick tickish e) = do
-  e' <- dsLExpr e
-  return (Tick tickish e')
-
--- There is a problem here. The then and else branches
--- have no free variables, so they are open to lifting.
--- We need someway of stopping this.
--- This will make no difference to binary coverage
--- (did you go here: YES or NO), but will effect accurate
--- tick counting.
-
-dsExpr (HsBinTick ixT ixF e) = do
-  e2 <- dsLExpr e
-  do { -- ASSERT(exprType e2 `eqType` boolTy)
-       mkBinaryTickBox ixT ixF e2
-     }
-
-dsExpr (HsTickPragma _ _ expr) = do
-  dflags <- getDynFlags
-  if gopt Opt_Hpc dflags
-    then panic "dsExpr:HsTickPragma"
-    else dsLExpr expr
-
--- HsSyn constructs that just shouldn't be here:
-dsExpr (ExprWithTySig {})  = panic "dsExpr:ExprWithTySig"
-dsExpr (HsBracket     {})  = panic "dsExpr:HsBracket"
-dsExpr (HsQuasiQuoteE {})  = panic "dsExpr:HsQuasiQuoteE"
-dsExpr (HsArrApp      {})  = panic "dsExpr:HsArrApp"
-dsExpr (HsArrForm     {})  = panic "dsExpr:HsArrForm"
-dsExpr (EWildPat      {})  = panic "dsExpr:EWildPat"
-dsExpr (EAsPat        {})  = panic "dsExpr:EAsPat"
-dsExpr (EViewPat      {})  = panic "dsExpr:EViewPat"
-dsExpr (ELazyPat      {})  = panic "dsExpr:ELazyPat"
-dsExpr (HsType        {})  = panic "dsExpr:HsType"
-dsExpr (HsDo          {})  = panic "dsExpr:HsDo"
-
-
-
-findField :: [LHsRecField Id arg] -> Name -> [arg]
-findField rbinds lbl
-  = [rhs | L _ (HsRecField { hsRecFieldId = id, hsRecFieldArg = rhs }) <- rbinds
-         , lbl == idName (unLoc id) ]
-
-{-
-%--------------------------------------------------------------------
-
-Note [Desugaring explicit lists]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Explicit lists are desugared in a cleverer way to prevent some
-fruitless allocations.  Essentially, whenever we see a list literal
-[x_1, ..., x_n] we:
-
-1. Find the tail of the list that can be allocated statically (say
-   [x_k, ..., x_n]) by later stages and ensure we desugar that
-   normally: this makes sure that we don't cause a code size increase
-   by having the cons in that expression fused (see later) and hence
-   being unable to statically allocate any more
-
-2. For the prefix of the list which cannot be allocated statically,
-   say [x_1, ..., x_(k-1)], we turn it into an expression involving
-   build so that if we find any foldrs over it it will fuse away
-   entirely!
-
-   So in this example we will desugar to:
-   build (\c n -> x_1 `c` x_2 `c` .... `c` foldr c n [x_k, ..., x_n]
-
-   If fusion fails to occur then build will get inlined and (since we
-   defined a RULE for foldr (:) []) we will get back exactly the
-   normal desugaring for an explicit list.
-
-This optimisation can be worth a lot: up to 25% of the total
-allocation in some nofib programs. Specifically
-
-        Program           Size    Allocs   Runtime  CompTime
-        rewrite          +0.0%    -26.3%      0.02     -1.8%
-           ansi          -0.3%    -13.8%      0.00     +0.0%
-           lift          +0.0%     -8.7%      0.00     -2.3%
-
-Of course, if rules aren't turned on then there is pretty much no
-point doing this fancy stuff, and it may even be harmful.
-
-=======>  Note by SLPJ Dec 08.
-
-I'm unconvinced that we should *ever* generate a build for an explicit
-list.  See the comments in GHC.Base about the foldr/cons rule, which
-points out that (foldr k z [a,b,c]) may generate *much* less code than
-(a `k` b `k` c `k` z).
-
-Furthermore generating builds messes up the LHS of RULES.
-Example: the foldr/single rule in GHC.Base
-   foldr k z [x] = ...
-We do not want to generate a build invocation on the LHS of this RULE!
-
-We fix this by disabling rules in rule LHSs, and testing that
-flag here; see Note [Desugaring RULE left hand sides] in Desugar
-
-To test this I've added a (static) flag -fsimple-list-literals, which
-makes all list literals be generated via the simple route.
--}
-
-dsExplicitList :: PostTc Id Type -> Maybe (SyntaxExpr Id) -> [LHsExpr Id]
-               -> DsM CoreExpr
--- See Note [Desugaring explicit lists]
-dsExplicitList elt_ty Nothing xs
-  = do { dflags <- getDynFlags
-       ; xs' <- mapM dsLExpr xs
-       ; let (dynamic_prefix, static_suffix) = spanTail is_static xs'
-       ; if gopt Opt_SimpleListLiterals dflags        -- -fsimple-list-literals
-         || not (gopt Opt_EnableRewriteRules dflags)  -- Rewrite rules off
-                -- Don't generate a build if there are no rules to eliminate it!
-                -- See Note [Desugaring RULE left hand sides] in Desugar
-         || null dynamic_prefix   -- Avoid build (\c n. foldr c n xs)!
-         then return $ mkListExpr elt_ty xs'
-         else mkBuildExpr elt_ty (mkSplitExplicitList dynamic_prefix static_suffix) }
-  where
-    is_static :: CoreExpr -> Bool
-    is_static e = all is_static_var (varSetElems (exprFreeVars e))
-
-    is_static_var :: Var -> Bool
-    is_static_var v
-      | isId v = isExternalName (idName v)  -- Top-level things are given external names
-      | otherwise = False                   -- Type variables
-
-    mkSplitExplicitList prefix suffix (c, _) (n, n_ty)
-      = do { let suffix' = mkListExpr elt_ty suffix
-           ; folded_suffix <- mkFoldrExpr elt_ty n_ty (Var c) (Var n) suffix'
-           ; return (foldr (App . App (Var c)) folded_suffix prefix) }
-
-dsExplicitList elt_ty (Just fln) xs
-  = do { fln' <- dsExpr fln
-       ; list <- dsExplicitList elt_ty Nothing xs
-       ; dflags <- getDynFlags
-       ; return (App (App fln' (mkIntExprInt dflags (length xs))) list) }
-
-spanTail :: (a -> Bool) -> [a] -> ([a], [a])
-spanTail f xs = (reverse rejected, reverse satisfying)
-    where (satisfying, rejected) = span f $ reverse xs
-
-dsArithSeq :: PostTcExpr -> (ArithSeqInfo Id) -> DsM CoreExpr
-dsArithSeq expr (From from)
-  = App <$> dsExpr expr <*> dsLExpr from
-dsArithSeq expr (FromTo from to)
-  = do dflags <- getDynFlags
-       warnAboutEmptyEnumerations dflags from Nothing to
-       expr' <- dsExpr expr
-       from' <- dsLExpr from
-       to'   <- dsLExpr to
-       return $ mkApps expr' [from', to']
-dsArithSeq expr (FromThen from thn)
-  = mkApps <$> dsExpr expr <*> mapM dsLExpr [from, thn]
-dsArithSeq expr (FromThenTo from thn to)
-  = do dflags <- getDynFlags
-       warnAboutEmptyEnumerations dflags from (Just thn) to
-       expr' <- dsExpr expr
-       from' <- dsLExpr from
-       thn'  <- dsLExpr thn
-       to'   <- dsLExpr to
-       return $ mkApps expr' [from', thn', to']
-
-{-
-Desugar 'do' and 'mdo' expressions (NOT list comprehensions, they're
-handled in DsListComp).  Basically does the translation given in the
-Haskell 98 report:
--}
-
-dsDo :: [ExprLStmt Id] -> DsM CoreExpr
-dsDo stmts
-  = goL stmts
-  where
-    goL [] = panic "dsDo"
-    goL (L loc stmt:lstmts) = putSrcSpanDs loc (go loc stmt lstmts)
-
-    go _ (LastStmt body _) _stmts
-      = {- ASSERT( null stmts ) -} dsLExpr body
-        -- The 'return' op isn't used for 'do' expressions
-
-    go _ (BodyStmt rhs then_expr _ _) stmts
-      = do { rhs2 <- dsLExpr rhs
-           ; warnDiscardedDoBindings rhs (exprType rhs2)
-           ; then_expr2 <- dsExpr then_expr
-           ; rest <- goL stmts
-           ; return (mkApps then_expr2 [rhs2, rest]) }
-
-    go _ (LetStmt binds) stmts
-      = do { rest <- goL stmts
-           ; dsLocalBinds binds rest }
-
-    go _ (BindStmt pat rhs bind_op fail_op) stmts
-      = do  { body     <- goL stmts
-            ; rhs'     <- dsLExpr rhs
-            ; bind_op' <- dsExpr bind_op
-            ; var   <- selectSimpleMatchVarL pat
-            ; let bind_ty = exprType bind_op'   -- rhs -> (pat -> res1) -> res2
-                  res1_ty = funResultTy (funArgTy (funResultTy bind_ty))
-            ; match <- matchSinglePat (Var var) (StmtCtxt DoExpr) pat
-                                      res1_ty (cantFailMatchResult body)
-            ; match_code <- handle_failure pat match fail_op
-            ; return (mkApps bind_op' [rhs', Lam var match_code]) }
-
-    go loc (RecStmt { recS_stmts = rec_stmts, recS_later_ids = later_ids
-                    , recS_rec_ids = rec_ids, recS_ret_fn = return_op
-                    , recS_mfix_fn = mfix_op, recS_bind_fn = bind_op
-                    , recS_rec_rets = rec_rets, recS_ret_ty = body_ty }) stmts
-      = goL (new_bind_stmt : stmts)  -- rec_ids can be empty; eg  rec { print 'x' }
-      where
-        new_bind_stmt = L loc $ BindStmt (mkBigLHsPatTup later_pats)
-                                         mfix_app bind_op
-                                         noSyntaxExpr  -- Tuple cannot fail
-
-        tup_ids      = rec_ids ++ filterOut (`elem` rec_ids) later_ids
-        tup_ty       = mkBigCoreTupTy (map idType tup_ids) -- Deals with singleton case
-        rec_tup_pats = map nlVarPat tup_ids
-        later_pats   = rec_tup_pats
-        rets         = map noLoc rec_rets
-        mfix_app     = nlHsApp (noLoc mfix_op) mfix_arg
-        mfix_arg     = noLoc $ HsLam (MG { mg_alts = [mkSimpleMatch [mfix_pat] body]
-                                         , mg_arg_tys = [tup_ty], mg_res_ty = body_ty
-                                         , mg_origin = Generated })
-        mfix_pat     = noLoc $ LazyPat $ mkBigLHsPatTup rec_tup_pats
-        body         = noLoc $ HsDo DoExpr (rec_stmts ++ [ret_stmt]) body_ty
-        ret_app      = nlHsApp (noLoc return_op) (mkBigLHsTup rets)
-        ret_stmt     = noLoc $ mkLastStmt ret_app
-                     -- This LastStmt will be desugared with dsDo,
-                     -- which ignores the return_op in the LastStmt,
-                     -- so we must apply the return_op explicitly
-
-    go _ (ParStmt   {}) _ = panic "dsDo ParStmt"
-    go _ (TransStmt {}) _ = panic "dsDo TransStmt"
-
-handle_failure :: LPat Id -> MatchResult -> SyntaxExpr Id -> DsM CoreExpr
-    -- In a do expression, pattern-match failure just calls
-    -- the monadic 'fail' rather than throwing an exception
-handle_failure pat match fail_op
-  | matchCanFail match
-  = do { fail_op' <- dsExpr fail_op
-       ; dflags <- getDynFlags
-       ; fail_msg <- mkStringExpr (mk_fail_msg dflags pat)
-       ; extractMatchResult match (App fail_op' fail_msg) }
-  | otherwise
-  = extractMatchResult match (impossible Nothing "It can't fail")
-
-mk_fail_msg :: DynFlags -> Located e -> String
-mk_fail_msg dflags pat = "Pattern match failure in do expression at " ++
-                         showPpr dflags (getLoc pat)
-
-{-
-************************************************************************
-*                                                                      *
-\subsection{Errors and contexts}
-*                                                                      *
-************************************************************************
--}
-
--- Warn about certain types of values discarded in monadic bindings (#3263)
-warnDiscardedDoBindings :: LHsExpr Id -> Type -> DsM ()
-warnDiscardedDoBindings rhs rhs_ty
-  | Just (m_ty, elt_ty) <- tcSplitAppTy_maybe rhs_ty
-  = do { warn_unused <- woptM Opt_WarnUnusedDoBind
-       ; warn_wrong <- woptM Opt_WarnWrongDoBind
-       ; when (warn_unused || warn_wrong) $
-    do { fam_inst_envs <- dsGetFamInstEnvs
-       ; let norm_elt_ty = topNormaliseType fam_inst_envs elt_ty
-
-           -- Warn about discarding non-() things in 'monadic' binding
-       ; if warn_unused && not (isUnitTy norm_elt_ty)
-         then warnDs (badMonadBind rhs elt_ty
-                           (ptext (sLit "-fno-warn-unused-do-bind")))
-         else
-
-           -- Warn about discarding m a things in 'monadic' binding of the same type,
-           -- but only if we didn't already warn due to Opt_WarnUnusedDoBind
-           when warn_wrong $
-                do { case tcSplitAppTy_maybe norm_elt_ty of
-                         Just (elt_m_ty, _)
-                            | m_ty `eqType` topNormaliseType fam_inst_envs elt_m_ty
-                            -> warnDs (badMonadBind rhs elt_ty
-                                           (ptext (sLit "-fno-warn-wrong-do-bind")))
-                         _ -> return () } } }
-
-  | otherwise   -- RHS does have type of form (m ty), which is weird
-  = return ()   -- but at lesat this warning is irrelevant
-
-badMonadBind :: LHsExpr Id -> Type -> SDoc -> SDoc
-badMonadBind rhs elt_ty flag_doc
-  = vcat [ hang (ptext (sLit "A do-notation statement discarded a result of type"))
-              2 (quotes (ppr elt_ty))
-         , hang (ptext (sLit "Suppress this warning by saying"))
-              2 (quotes $ ptext (sLit "_ <-") <+> ppr rhs)
-         , ptext (sLit "or by using the flag") <+>  flag_doc ]
-
-{-
-************************************************************************
-*                                                                      *
-\subsection{Static pointers}
-*                                                                      *
-************************************************************************
--}
-
--- | Creates an name for an entry in the Static Pointer Table.
---
--- The name has the form @sptEntry:<N>@ where @<N>@ is generated from a
--- per-module counter.
---
-mkSptEntryName :: SrcSpan -> DsM Name
-mkSptEntryName loc = do
-    uniq <- newUnique
-    mod  <- getModule
-    occ  <- mkWrapperName "sptEntry"
-    return $ mkExternalName uniq mod occ loc
-  where
-    mkWrapperName what
-      = do dflags <- getDynFlags
-           thisMod <- getModule
-           let -- Note [Generating fresh names for ccall wrapper]
-               -- in compiler/typecheck/TcEnv.hs
-               wrapperRef = nextWrapperNum dflags
-           wrapperNum <- liftIO $ atomicModifyIORef wrapperRef $ \mod_env ->
-               let num = lookupWithDefaultModuleEnv mod_env 0 thisMod
-                in (extendModuleEnv mod_env thisMod (num+1), num)
-           return $ mkVarOcc $ what ++ ":" ++ show wrapperNum
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsExpr.hs-boot b/src/Language/Haskell/Liquid/Desugar710/DsExpr.hs-boot
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsExpr.hs-boot
+++ /dev/null
@@ -1,9 +0,0 @@
-module Language.Haskell.Liquid.Desugar710.DsExpr where
-import HsSyn    ( HsExpr, LHsExpr, HsLocalBinds )
-import Var      ( Id )
-import DsMonad  ( DsM )
-import CoreSyn  ( CoreExpr )
-
-dsExpr  :: HsExpr  Id -> DsM CoreExpr
-dsLExpr :: LHsExpr Id -> DsM CoreExpr
-dsLocalBinds :: HsLocalBinds Id -> CoreExpr -> DsM CoreExpr
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsForeign.hs b/src/Language/Haskell/Liquid/Desugar710/DsForeign.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsForeign.hs
+++ /dev/null
@@ -1,809 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The AQUA Project, Glasgow University, 1998
-
-
-Desugaring foreign declarations (see also DsCCall).
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.DsForeign ( dsForeigns
-                 , dsForeigns'
-                 , dsFImport, dsCImport, dsFCall, dsPrimCall
-                 , dsFExport, dsFExportDynamic, mkFExportCBits
-                 , toCType
-                 , foreignExportInitialiser
-                 ) where
-
--- #include "HsVersions.h"
-import TcRnMonad        -- temp
-import Prelude hiding (error)
-import TypeRep
-
-import CoreSyn
-
-import DsCCall
-import DsMonad
-
-import HsSyn
-import DataCon
-import CoreUnfold
-import Id
-import Literal
-import Module
-import Name
-import Type
-import TyCon
-import Coercion
-import TcEnv
-import TcType
-
-import CmmExpr
-import CmmUtils
-import HscTypes
-import ForeignCall
-import TysWiredIn
-import TysPrim
-import PrelNames
-import BasicTypes
-import SrcLoc
-import Outputable
-import FastString
-import DynFlags
-import Platform
-import Config
-import OrdList
-import Pair
-import Hooks
-
-import Data.Maybe
-import Data.List
-
-{-
-Desugaring of @foreign@ declarations is naturally split up into
-parts, an @import@ and an @export@  part. A @foreign import@
-declaration
-\begin{verbatim}
-  foreign import cc nm f :: prim_args -> IO prim_res
-\end{verbatim}
-is the same as
-\begin{verbatim}
-  f :: prim_args -> IO prim_res
-  f a1 ... an = _ccall_ nm cc a1 ... an
-\end{verbatim}
-so we reuse the desugaring code in @DsCCall@ to deal with these.
--}
-
-type Binding = (Id, CoreExpr)   -- No rec/nonrec structure;
-                                -- the occurrence analyser will sort it all out
-
-dsForeigns :: [LForeignDecl Id]
-           -> DsM (ForeignStubs, OrdList Binding)
-dsForeigns fos = getHooked dsForeignsHook dsForeigns' >>= ($ fos)
-
-dsForeigns' :: [LForeignDecl Id]
-            -> DsM (ForeignStubs, OrdList Binding)
-dsForeigns' []
-  = return (NoStubs, nilOL)
-dsForeigns' fos = do
-    fives <- mapM do_ldecl fos
-    let
-        (hs, cs, idss, bindss) = unzip4 fives
-        fe_ids = concat idss
-        fe_init_code = map foreignExportInitialiser fe_ids
-    --
-    return (ForeignStubs
-             (vcat hs)
-             (vcat cs $$ vcat fe_init_code),
-            foldr (appOL . toOL) nilOL bindss)
-  where
-   do_ldecl (L loc decl) = putSrcSpanDs loc (do_decl decl)
-
-   do_decl (ForeignImport id _ co spec) = do
-      traceIf (text "fi start" <+> ppr id)
-      (bs, h, c) <- dsFImport (unLoc id) co spec
-      traceIf (text "fi end" <+> ppr id)
-      return (h, c, [], bs)
-
-   do_decl (ForeignExport (L _ id) _ co
-                          (CExport (L _ (CExportStatic ext_nm cconv)) _)) = do
-      (h, c, _, _) <- dsFExport id co ext_nm cconv False
-      return (h, c, [id], [])
-
-{-
-************************************************************************
-*                                                                      *
-\subsection{Foreign import}
-*                                                                      *
-************************************************************************
-
-Desugaring foreign imports is just the matter of creating a binding
-that on its RHS unboxes its arguments, performs the external call
-(using the @CCallOp@ primop), before boxing the result up and returning it.
-
-However, we create a worker/wrapper pair, thus:
-
-        foreign import f :: Int -> IO Int
-==>
-        f x = IO ( \s -> case x of { I# x# ->
-                         case fw s x# of { (# s1, y# #) ->
-                         (# s1, I# y# #)}})
-
-        fw s x# = ccall f s x#
-
-The strictness/CPR analyser won't do this automatically because it doesn't look
-inside returned tuples; but inlining this wrapper is a Really Good Idea
-because it exposes the boxing to the call site.
--}
-
-dsFImport :: Id
-          -> Coercion
-          -> ForeignImport
-          -> DsM ([Binding], SDoc, SDoc)
-dsFImport id co (CImport cconv safety mHeader spec _) = do
-    (ids, h, c) <- dsCImport id co spec (unLoc cconv) (unLoc safety) mHeader
-    return (ids, h, c)
-
-dsCImport :: Id
-          -> Coercion
-          -> CImportSpec
-          -> CCallConv
-          -> Safety
-          -> Maybe Header
-          -> DsM ([Binding], SDoc, SDoc)
-dsCImport id co (CLabel _) _ _ _ = do
-   -- dflags <- getDynFlags
-   -- let ty = pFst $ coercionKind co
-   --     fod = case tyConAppTyCon_maybe (dropForAlls ty) of
-   --           Just tycon
-   --            | tyConUnique tycon == funPtrTyConKey ->
-   --               IsFunction
-   --           _ -> IsData
-   -- (resTy, foRhs) <- resultWrapper ty
-   -- ASSERT(fromJust resTy `eqType` addrPrimTy)    -- typechecker ensures this
-   let rhs = let x = x in x -- foRhs (Lit (MachLabel cid stdcall_info fod))
-   let rhs' = Cast rhs co
-   -- let stdcall_info = fun_type_arg_stdcall_info dflags cconv ty
-   return ([(id, rhs')], empty, empty)
-
-dsCImport id co (CFunction target) cconv@PrimCallConv safety _
-  = dsPrimCall id co (CCall (CCallSpec target cconv safety))
-dsCImport id co (CFunction target) cconv safety mHeader
-  = dsFCall id co (CCall (CCallSpec target cconv safety)) mHeader
-dsCImport id co CWrapper cconv _ _
-  = dsFExportDynamic id co cconv
-
--- For stdcall labels, if the type was a FunPtr or newtype thereof,
--- then we need to calculate the size of the arguments in order to add
--- the @n suffix to the label.
--- fun_type_arg_stdcall_info :: DynFlags -> CCallConv -> Type -> Maybe Int
--- fun_type_arg_stdcall_info dflags StdCallConv ty
---   | Just (tc,[arg_ty]) <- splitTyConApp_maybe ty,
---     tyConUnique tc == funPtrTyConKey
---   = let
---        (_tvs,sans_foralls)        = tcSplitForAllTys arg_ty
---        (fe_arg_tys, _orig_res_ty) = tcSplitFunTys sans_foralls
---     in Just $ sum (map (widthInBytes . typeWidth . typeCmmType dflags . getPrimTyOf) fe_arg_tys)
--- fun_type_arg_stdcall_info _ _other_conv _
---   = Nothing
-
-{-
-************************************************************************
-*                                                                      *
-\subsection{Foreign calls}
-*                                                                      *
-************************************************************************
--}
-
-dsFCall :: Id -> Coercion -> ForeignCall -> Maybe Header
-        -> DsM ([(Id, Expr TyVar)], SDoc, SDoc)
-dsFCall fn_id co fcall mDeclHeader = do
-    let
-        ty                   = pFst $ coercionKind co
-        (tvs, fun_ty)        = tcSplitForAllTys ty
-        (arg_tys, io_res_ty) = tcSplitFunTys fun_ty
-                -- Must use tcSplit* functions because we want to
-                -- see that (IO t) in the corner
-
-    args <- newSysLocalsDs arg_tys
-    (val_args, arg_wrappers) <- mapAndUnzipM unboxArg (map Var args)
-
-    let
-        work_arg_ids  = [v | Var v <- val_args] -- All guaranteed to be vars
-
-    (ccall_result_ty, res_wrapper) <- boxResult io_res_ty
-
-    ccall_uniq <- newUnique
-    work_uniq  <- newUnique
-
-    dflags <- getDynFlags
-    (fcall', cDoc) <-
-              case fcall of
-              CCall (CCallSpec (StaticTarget cName mPackageKey isFun) CApiConv safety) ->
-               do wrapperName <- mkWrapperName "ghc_wrapper" (unpackFS cName)
-                  let fcall' = CCall (CCallSpec (StaticTarget wrapperName mPackageKey True) CApiConv safety)
-                      c = includes
-                       $$ fun_proto <+> braces (cRet <> semi)
-                      includes = vcat [ text "#include <" <> ftext h <> text ">"
-                                      | Header h <- nub headers ]
-                      fun_proto = cResType <+> pprCconv <+> ppr wrapperName <> parens argTypes
-                      cRet
-                       | isVoidRes =                   cCall
-                       | otherwise = text "return" <+> cCall
-                      cCall = if isFun
-                              then ppr cName <> parens argVals
-                              else if null arg_tys
-                                    then ppr cName
-                                    else panic "dsFCall: Unexpected arguments to FFI value import"
-                      raw_res_ty = case tcSplitIOType_maybe io_res_ty of
-                                   Just (_ioTyCon, res_ty) -> res_ty
-                                   Nothing                 -> io_res_ty
-                      isVoidRes = raw_res_ty `eqType` unitTy
-                      (mHeader, cResType)
-                       | isVoidRes = (Nothing, text "void")
-                       | otherwise = toCType raw_res_ty
-                      pprCconv = ccallConvAttribute CApiConv
-                      mHeadersArgTypeList
-                          = [ (header, cType <+> char 'a' <> int n)
-                            | (t, n) <- zip arg_tys [1..]
-                            , let (header, cType) = toCType t ]
-                      (mHeaders, argTypeList) = unzip mHeadersArgTypeList
-                      argTypes = if null argTypeList
-                                 then text "void"
-                                 else hsep $ punctuate comma argTypeList
-                      mHeaders' = mDeclHeader : mHeader : mHeaders
-                      headers = catMaybes mHeaders'
-                      argVals = hsep $ punctuate comma
-                                    [ char 'a' <> int n
-                                    | (_, n) <- zip arg_tys [1..] ]
-                  return (fcall', c)
-              _ ->
-                  return (fcall, empty)
-    let
-        -- Build the worker
-        worker_ty     = mkForAllTys tvs (mkFunTys (map idType work_arg_ids) ccall_result_ty)
-        the_ccall_app = mkFCall dflags ccall_uniq fcall' val_args ccall_result_ty
-        work_rhs      = mkLams tvs (mkLams work_arg_ids the_ccall_app)
-        work_id       = mkSysLocal (fsLit "$wccall") work_uniq worker_ty
-
-        -- Build the wrapper
-        work_app     = mkApps (mkVarApps (Var work_id) tvs) val_args
-        wrapper_body = foldr ($) (res_wrapper work_app) arg_wrappers
-        wrap_rhs     = mkLams (tvs ++ args) wrapper_body
-        wrap_rhs'    = Cast wrap_rhs co
-        fn_id_w_inl  = fn_id `setIdUnfolding` mkInlineUnfolding (Just (length args)) wrap_rhs'
-
-    return ([(work_id, work_rhs), (fn_id_w_inl, wrap_rhs')], empty, cDoc)
-
-{-
-************************************************************************
-*                                                                      *
-\subsection{Primitive calls}
-*                                                                      *
-************************************************************************
-
-This is for `@foreign import prim@' declarations.
-
-Currently, at the core level we pretend that these primitive calls are
-foreign calls. It may make more sense in future to have them as a distinct
-kind of Id, or perhaps to bundle them with PrimOps since semantically and
-for calling convention they are really prim ops.
--}
-
-dsPrimCall :: Id -> Coercion -> ForeignCall
-           -> DsM ([(Id, Expr TyVar)], SDoc, SDoc)
-dsPrimCall fn_id co fcall = do
-    let
-        ty                   = pFst $ coercionKind co
-        (tvs, fun_ty)        = tcSplitForAllTys ty
-        (arg_tys, io_res_ty) = tcSplitFunTys fun_ty
-                -- Must use tcSplit* functions because we want to
-                -- see that (IO t) in the corner
-
-    args <- newSysLocalsDs arg_tys
-
-    ccall_uniq <- newUnique
-    dflags <- getDynFlags
-    let
-        call_app = mkFCall dflags ccall_uniq fcall (map Var args) io_res_ty
-        rhs      = mkLams tvs (mkLams args call_app)
-        rhs'     = Cast rhs co
-    return ([(fn_id, rhs')], empty, empty)
-
-{-
-************************************************************************
-*                                                                      *
-\subsection{Foreign export}
-*                                                                      *
-************************************************************************
-
-The function that does most of the work for `@foreign export@' declarations.
-(see below for the boilerplate code a `@foreign export@' declaration expands
- into.)
-
-For each `@foreign export foo@' in a module M we generate:
-\begin{itemize}
-\item a C function `@foo@', which calls
-\item a Haskell stub `@M.\$ffoo@', which calls
-\end{itemize}
-the user-written Haskell function `@M.foo@'.
--}
-
-dsFExport :: Id                 -- Either the exported Id,
-                                -- or the foreign-export-dynamic constructor
-          -> Coercion           -- Coercion between the Haskell type callable
-                                -- from C, and its representation type
-          -> CLabelString       -- The name to export to C land
-          -> CCallConv
-          -> Bool               -- True => foreign export dynamic
-                                --         so invoke IO action that's hanging off
-                                --         the first argument's stable pointer
-          -> DsM ( SDoc         -- contents of Module_stub.h
-                 , SDoc         -- contents of Module_stub.c
-                 , String       -- string describing type to pass to createAdj.
-                 , Int          -- size of args to stub function
-                 )
-
-dsFExport fn_id co ext_name cconv isDyn = do
-    let
-       ty                              = pSnd $ coercionKind co
-       (_tvs,sans_foralls)             = tcSplitForAllTys ty
-       (fe_arg_tys', orig_res_ty)      = tcSplitFunTys sans_foralls
-       -- We must use tcSplits here, because we want to see
-       -- the (IO t) in the corner of the type!
-       fe_arg_tys | isDyn     = tail fe_arg_tys'
-                  | otherwise = fe_arg_tys'
-
-       -- Look at the result type of the exported function, orig_res_ty
-       -- If it's IO t, return         (t, True)
-       -- If it's plain t, return      (t, False)
-       (res_ty, is_IO_res_ty) = case tcSplitIOType_maybe orig_res_ty of
-                                -- The function already returns IO t
-                                Just (_ioTyCon, res_ty) -> (res_ty, True)
-                                -- The function returns t
-                                Nothing                 -> (orig_res_ty, False)
-
-    dflags <- getDynFlags
-    return $
-      mkFExportCBits dflags ext_name
-                     (if isDyn then Nothing else Just fn_id)
-                     fe_arg_tys res_ty is_IO_res_ty cconv
-
-{-
-@foreign import "wrapper"@ (previously "foreign export dynamic") lets
-you dress up Haskell IO actions of some fixed type behind an
-externally callable interface (i.e., as a C function pointer). Useful
-for callbacks and stuff.
-
-\begin{verbatim}
-type Fun = Bool -> Int -> IO Int
-foreign import "wrapper" f :: Fun -> IO (FunPtr Fun)
-
--- Haskell-visible constructor, which is generated from the above:
--- SUP: No check for NULL from createAdjustor anymore???
-
-f :: Fun -> IO (FunPtr Fun)
-f cback =
-   bindIO (newStablePtr cback)
-          (\StablePtr sp# -> IO (\s1# ->
-              case _ccall_ createAdjustor cconv sp# ``f_helper'' <arg info> s1# of
-                 (# s2#, a# #) -> (# s2#, A# a# #)))
-
-foreign import "&f_helper" f_helper :: FunPtr (StablePtr Fun -> Fun)
-
--- and the helper in C: (approximately; see `mkFExportCBits` below)
-
-f_helper(StablePtr s, HsBool b, HsInt i)
-{
-        Capability *cap;
-        cap = rts_lock();
-        rts_evalIO(&cap,
-                   rts_apply(rts_apply(deRefStablePtr(s),
-                                       rts_mkBool(b)), rts_mkInt(i)));
-        rts_unlock(cap);
-}
-\end{verbatim}
--}
-
-dsFExportDynamic :: Id
-                 -> Coercion
-                 -> CCallConv
-                 -> DsM ([Binding], SDoc, SDoc)
-dsFExportDynamic id co0 cconv = do
-    fe_id <-  newSysLocalDs ty
-    mod <- getModule
-    dflags <- getDynFlags
-    let
-        -- hack: need to get at the name of the C stub we're about to generate.
-        -- TODO: There's no real need to go via String with
-        -- (mkFastString . zString). In fact, is there a reason to convert
-        -- to FastString at all now, rather than sticking with FastZString?
-        fe_nm    = mkFastString (zString (zEncodeFS (moduleNameFS (moduleName mod))) ++ "_" ++ toCName dflags fe_id)
-
-    cback <- newSysLocalDs arg_ty
-    newStablePtrId <- dsLookupGlobalId newStablePtrName
-    stable_ptr_tycon <- dsLookupTyCon stablePtrTyConName
-    let
-        stable_ptr_ty = mkTyConApp stable_ptr_tycon [arg_ty]
-        export_ty     = mkFunTy stable_ptr_ty arg_ty
-    bindIOId <- dsLookupGlobalId bindIOName
-    stbl_value <- newSysLocalDs stable_ptr_ty
-    (h_code, c_code, typestring, args_size) <- dsFExport id (mkReflCo Representational export_ty) fe_nm cconv True
-    let
-         {-
-          The arguments to the external function which will
-          create a little bit of (template) code on the fly
-          for allowing the (stable pointed) Haskell closure
-          to be entered using an external calling convention
-          (stdcall, ccall).
-         -}
-        adj_args      = [ mkIntLitInt dflags (ccallConvToInt cconv)
-                        , Var stbl_value
-                        , Lit (MachLabel fe_nm mb_sz_args IsFunction)
-                        , Lit (mkMachString typestring)
-                        ]
-          -- name of external entry point providing these services.
-          -- (probably in the RTS.)
-        adjustor   = fsLit "createAdjustor"
-
-          -- Determine the number of bytes of arguments to the stub function,
-          -- so that we can attach the '@N' suffix to its label if it is a
-          -- stdcall on Windows.
-        mb_sz_args = case cconv of
-                        StdCallConv -> Just args_size
-                        _           -> Nothing
-
-    ccall_adj <- dsCCall adjustor adj_args PlayRisky (mkTyConApp io_tc [res_ty])
-        -- PlayRisky: the adjustor doesn't allocate in the Haskell heap or do a callback
-
-    let io_app = mkLams tvs                  $
-                 Lam cback                   $
-                 mkApps (Var bindIOId)
-                        [ Type stable_ptr_ty
-                        , Type res_ty
-                        , mkApps (Var newStablePtrId) [ Type arg_ty, Var cback ]
-                        , Lam stbl_value ccall_adj
-                        ]
-
-        fed = (id `setInlineActivation` NeverActive, Cast io_app co0)
-               -- Never inline the f.e.d. function, because the litlit
-               -- might not be in scope in other modules.
-
-    return ([fed], h_code, c_code)
-
- where
-  ty                       = pFst (coercionKind co0)
-  (tvs,sans_foralls)       = tcSplitForAllTys ty
-  ([arg_ty], fn_res_ty)    = tcSplitFunTys sans_foralls
-  Just (io_tc, res_ty)     = tcSplitIOType_maybe fn_res_ty
-        -- Must have an IO type; hence Just
-
-toCName :: DynFlags -> Id -> String
-toCName dflags i = showSDoc dflags (pprCode CStyle (ppr (idName i)))
-
-{-
-*
-
-\subsection{Generating @foreign export@ stubs}
-
-*
-
-For each @foreign export@ function, a C stub function is generated.
-The C stub constructs the application of the exported Haskell function
-using the hugs/ghc rts invocation API.
--}
-
-mkFExportCBits :: DynFlags
-               -> FastString
-               -> Maybe Id      -- Just==static, Nothing==dynamic
-               -> [Type]
-               -> Type
-               -> Bool          -- True <=> returns an IO type
-               -> CCallConv
-               -> (SDoc,
-                   SDoc,
-                   String,      -- the argument reps
-                   Int          -- total size of arguments
-                  )
-mkFExportCBits dflags c_nm maybe_target arg_htys res_hty is_IO_res_ty cc
- = (header_bits, c_bits, type_string,
-    sum [ widthInBytes (typeWidth rep) | (_,_,_,rep) <- aug_arg_info] -- all the args
-         -- NB. the calculation here isn't strictly speaking correct.
-         -- We have a primitive Haskell type (eg. Int#, Double#), and
-         -- we want to know the size, when passed on the C stack, of
-         -- the associated C type (eg. HsInt, HsDouble).  We don't have
-         -- this information to hand, but we know what GHC's conventions
-         -- are for passing around the primitive Haskell types, so we
-         -- use that instead.  I hope the two coincide --SDM
-    )
- where
-  -- list the arguments to the C function
-  arg_info :: [(SDoc,           -- arg name
-                SDoc,           -- C type
-                Type,           -- Haskell type
-                CmmType)]       -- the CmmType
-  arg_info  = [ let stg_type = showStgType ty in
-                (arg_cname n stg_type,
-                 stg_type,
-                 ty,
-                 typeCmmType dflags (getPrimTyOf ty))
-              | (ty,n) <- zip arg_htys [1::Int ..] ]
-
-  arg_cname n stg_ty
-        | libffi    = char '*' <> parens (stg_ty <> char '*') <>
-                      ptext (sLit "args") <> brackets (int (n-1))
-        | otherwise = text ('a':show n)
-
-  -- generate a libffi-style stub if this is a "wrapper" and libffi is enabled
-  libffi = cLibFFI && isNothing maybe_target
-
-  type_string
-      -- libffi needs to know the result type too:
-      | libffi    = primTyDescChar dflags res_hty : arg_type_string
-      | otherwise = arg_type_string
-
-  arg_type_string = [primTyDescChar dflags ty | (_,_,ty,_) <- arg_info]
-                -- just the real args
-
-  -- add some auxiliary args; the stable ptr in the wrapper case, and
-  -- a slot for the dummy return address in the wrapper + ccall case
-  aug_arg_info
-    | isNothing maybe_target = stable_ptr_arg : insertRetAddr dflags cc arg_info
-    | otherwise              = arg_info
-
-  stable_ptr_arg =
-        (text "the_stableptr", text "StgStablePtr", undefined,
-         typeCmmType dflags (mkStablePtrPrimTy alphaTy))
-
-  -- stuff to do with the return type of the C function
-  res_hty_is_unit = res_hty `eqType` unitTy     -- Look through any newtypes
-
-  cResType | res_hty_is_unit = text "void"
-           | otherwise       = showStgType res_hty
-
-  -- when the return type is integral and word-sized or smaller, it
-  -- must be assigned as type ffi_arg (#3516).  To see what type
-  -- libffi is expecting here, take a look in its own testsuite, e.g.
-  -- libffi/testsuite/libffi.call/cls_align_ulonglong.c
-  ffi_cResType
-     | is_ffi_arg_type = text "ffi_arg"
-     | otherwise       = cResType
-     where
-       res_ty_key = getUnique (getName (typeTyCon res_hty))
-       is_ffi_arg_type = res_ty_key `notElem`
-              [floatTyConKey, doubleTyConKey,
-               int64TyConKey, word64TyConKey]
-
-  -- Now we can cook up the prototype for the exported function.
-  pprCconv = ccallConvAttribute cc
-
-  header_bits = ptext (sLit "extern") <+> fun_proto <> semi
-
-  fun_args
-    | null aug_arg_info = text "void"
-    | otherwise         = hsep $ punctuate comma
-                               $ map (\(nm,ty,_,_) -> ty <+> nm) aug_arg_info
-
-  fun_proto
-    | libffi
-      = ptext (sLit "void") <+> ftext c_nm <>
-          parens (ptext (sLit "void *cif STG_UNUSED, void* resp, void** args, void* the_stableptr"))
-    | otherwise
-      = cResType <+> pprCconv <+> ftext c_nm <> parens fun_args
-
-  -- the target which will form the root of what we ask rts_evalIO to run
-  the_cfun
-     = case maybe_target of
-          Nothing    -> text "(StgClosure*)deRefStablePtr(the_stableptr)"
-          Just hs_fn -> char '&' <> ppr hs_fn <> text "_closure"
-
-  cap = text "cap" <> comma
-
-  -- the expression we give to rts_evalIO
-  expr_to_run
-     = foldl appArg the_cfun arg_info -- NOT aug_arg_info
-       where
-          appArg acc (arg_cname, _, arg_hty, _)
-             = text "rts_apply"
-               <> parens (cap <> acc <> comma <> mkHObj arg_hty <> parens (cap <> arg_cname))
-
-  -- various other bits for inside the fn
-  declareResult = text "HaskellObj ret;"
-  declareCResult | res_hty_is_unit = empty
-                 | otherwise       = cResType <+> text "cret;"
-
-  assignCResult | res_hty_is_unit = empty
-                | otherwise       =
-                        text "cret=" <> unpackHObj res_hty <> parens (text "ret") <> semi
-
-  -- an extern decl for the fn being called
-  extern_decl
-     = case maybe_target of
-          Nothing -> empty
-          Just hs_fn -> text "extern StgClosure " <> ppr hs_fn <> text "_closure" <> semi
-
-
-  -- finally, the whole darn thing
-  c_bits =
-    space $$
-    extern_decl $$
-    fun_proto  $$
-    vcat
-     [ lbrace
-     ,   ptext (sLit "Capability *cap;")
-     ,   declareResult
-     ,   declareCResult
-     ,   text "cap = rts_lock();"
-          -- create the application + perform it.
-     ,   ptext (sLit "rts_evalIO") <> parens (
-                char '&' <> cap <>
-                ptext (sLit "rts_apply") <> parens (
-                    cap <>
-                    text "(HaskellObj)"
-                 <> ptext (if is_IO_res_ty
-                                then (sLit "runIO_closure")
-                                else (sLit "runNonIO_closure"))
-                 <> comma
-                 <> expr_to_run
-                ) <+> comma
-               <> text "&ret"
-             ) <> semi
-     ,   ptext (sLit "rts_checkSchedStatus") <> parens (doubleQuotes (ftext c_nm)
-                                                <> comma <> text "cap") <> semi
-     ,   assignCResult
-     ,   ptext (sLit "rts_unlock(cap);")
-     ,   ppUnless res_hty_is_unit $
-         if libffi
-                  then char '*' <> parens (ffi_cResType <> char '*') <>
-                       ptext (sLit "resp = cret;")
-                  else ptext (sLit "return cret;")
-     , rbrace
-     ]
-
-
-foreignExportInitialiser :: Id -> SDoc
-foreignExportInitialiser hs_fn =
-   -- Initialise foreign exports by registering a stable pointer from an
-   -- __attribute__((constructor)) function.
-   -- The alternative is to do this from stginit functions generated in
-   -- codeGen/CodeGen.lhs; however, stginit functions have a negative impact
-   -- on binary sizes and link times because the static linker will think that
-   -- all modules that are imported directly or indirectly are actually used by
-   -- the program.
-   -- (this is bad for big umbrella modules like Graphics.Rendering.OpenGL)
-   vcat
-    [ text "static void stginit_export_" <> ppr hs_fn
-         <> text "() __attribute__((constructor));"
-    , text "static void stginit_export_" <> ppr hs_fn <> text "()"
-    , braces (text "foreignExportStablePtr"
-       <> parens (text "(StgPtr) &" <> ppr hs_fn <> text "_closure")
-       <> semi)
-    ]
-
-
-mkHObj :: Type -> SDoc
-mkHObj t = text "rts_mk" <> text (showFFIType t)
-
-unpackHObj :: Type -> SDoc
-unpackHObj t = text "rts_get" <> text (showFFIType t)
-
-showStgType :: Type -> SDoc
-showStgType t = text "Hs" <> text (showFFIType t)
-
-showFFIType :: Type -> String
-showFFIType t = getOccString (getName (typeTyCon t))
-
-toCType :: Type -> (Maybe Header, SDoc)
-toCType = f False
-    where f voidOK t
-           -- First, if we have (Ptr t) of (FunPtr t), then we need to
-           -- convert t to a C type and put a * after it. If we don't
-           -- know a type for t, then "void" is fine, though.
-           | Just (ptr, [t']) <- splitTyConApp_maybe t
-           , tyConName ptr `elem` [ptrTyConName, funPtrTyConName]
-              = case f True t' of
-                (mh, cType') ->
-                    (mh, cType' <> char '*')
-           -- Otherwise, if we have a type constructor application, then
-           -- see if there is a C type associated with that constructor.
-           -- Note that we aren't looking through type synonyms or
-           -- anything, as it may be the synonym that is annotated.
-           | TyConApp tycon _ <- t
-           , Just (CType _ mHeader cType) <- tyConCType_maybe tycon
-              = (mHeader, ftext cType)
-           -- If we don't know a C type for this type, then try looking
-           -- through one layer of type synonym etc.
-           | Just t' <- coreView t
-              = f voidOK t'
-           -- Otherwise we don't know the C type. If we are allowing
-           -- void then return that; otherwise something has gone wrong.
-           | voidOK = (Nothing, ptext (sLit "void"))
-           | otherwise
-              = pprPanic "toCType" (ppr t)
-
-typeTyCon :: Type -> TyCon
-typeTyCon ty
-  | UnaryRep rep_ty <- repType ty
-  , Just (tc, _) <- tcSplitTyConApp_maybe rep_ty
-  = tc
-  | otherwise
-  = pprPanic "DsForeign.typeTyCon" (ppr ty)
-
-insertRetAddr :: DynFlags -> CCallConv
-              -> [(SDoc, SDoc, Type, CmmType)]
-              -> [(SDoc, SDoc, Type, CmmType)]
-insertRetAddr dflags CCallConv args
-    = case platformArch platform of
-      ArchX86_64
-       | platformOS platform == OSMinGW32 ->
-          -- On other Windows x86_64 we insert the return address
-          -- after the 4th argument, because this is the point
-          -- at which we need to flush a register argument to the stack
-          -- (See rts/Adjustor.c for details).
-          let go :: Int -> [(SDoc, SDoc, Type, CmmType)]
-                        -> [(SDoc, SDoc, Type, CmmType)]
-              go 4 args = ret_addr_arg dflags : args
-              go n (arg:args) = arg : go (n+1) args
-              go _ [] = []
-          in go 0 args
-       | otherwise ->
-          -- On other x86_64 platforms we insert the return address
-          -- after the 6th integer argument, because this is the point
-          -- at which we need to flush a register argument to the stack
-          -- (See rts/Adjustor.c for details).
-          let go :: Int -> [(SDoc, SDoc, Type, CmmType)]
-                        -> [(SDoc, SDoc, Type, CmmType)]
-              go 6 args = ret_addr_arg dflags : args
-              go n (arg@(_,_,_,rep):args)
-               | cmmEqType_ignoring_ptrhood rep b64 = arg : go (n+1) args
-               | otherwise  = arg : go n     args
-              go _ [] = []
-          in go 0 args
-      _ ->
-          ret_addr_arg dflags : args
-    where platform = targetPlatform dflags
-insertRetAddr _ _ args = args
-
-ret_addr_arg :: DynFlags -> (SDoc, SDoc, Type, CmmType)
-ret_addr_arg dflags = (text "original_return_addr", text "void*", undefined,
-                       typeCmmType dflags addrPrimTy)
-
--- This function returns the primitive type associated with the boxed
--- type argument to a foreign export (eg. Int ==> Int#).
-getPrimTyOf :: Type -> UnaryType
-getPrimTyOf ty
-  | isBoolTy rep_ty = intPrimTy
-  -- Except for Bool, the types we are interested in have a single constructor
-  -- with a single primitive-typed argument (see TcType.legalFEArgTyCon).
-  | otherwise =
-  case splitDataProductType_maybe rep_ty of
-     Just (_, _, _, [prim_ty]) ->
-        -- ASSERT(dataConSourceArity data_con == 1)
-        -- ASSERT2(isUnLiftedType prim_ty, ppr prim_ty)
-        prim_ty
-     _other -> pprPanic "DsForeign.getPrimTyOf" (ppr ty)
-  where
-        UnaryRep rep_ty = repType ty
-
--- represent a primitive type as a Char, for building a string that
--- described the foreign function type.  The types are size-dependent,
--- e.g. 'W' is a signed 32-bit integer.
-primTyDescChar :: DynFlags -> Type -> Char
-primTyDescChar dflags ty
- | ty `eqType` unitTy = 'v'
- | otherwise
- = case typePrimRep (getPrimTyOf ty) of
-     IntRep      -> signed_word
-     WordRep     -> unsigned_word
-     Int64Rep    -> 'L'
-     Word64Rep   -> 'l'
-     AddrRep     -> 'p'
-     FloatRep    -> 'f'
-     DoubleRep   -> 'd'
-     _           -> pprPanic "primTyDescChar" (ppr ty)
-  where
-    (signed_word, unsigned_word)
-       | wORD_SIZE dflags == 4  = ('W','w')
-       | wORD_SIZE dflags == 8  = ('L','l')
-       | otherwise              = panic "primTyDescChar"
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsGRHSs.hs b/src/Language/Haskell/Liquid/Desugar710/DsGRHSs.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsGRHSs.hs
+++ /dev/null
@@ -1,158 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-Matching guarded right-hand-sides (GRHSs)
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.DsGRHSs ( dsGuarded, dsGRHSs, dsGRHS ) where
-
--- #include "HsVersions.h"
-
-import {-# SOURCE #-} Language.Haskell.Liquid.Desugar710.DsExpr  ( dsLExpr, dsLocalBinds )
-import {-# SOURCE #-} Language.Haskell.Liquid.Desugar710.Match   ( matchSinglePat )
-import Prelude hiding (error)
-import HsSyn
-import MkCore
-import CoreSyn
-import Var
-import Type
-
-import DsMonad
-import Language.Haskell.Liquid.Desugar710.DsUtils
-import TysWiredIn
-import PrelNames
-import Module
-import Name
-import SrcLoc
-import Outputable
-
-{-
-@dsGuarded@ is used for both @case@ expressions and pattern bindings.
-It desugars:
-\begin{verbatim}
-        | g1 -> e1
-        ...
-        | gn -> en
-        where binds
-\end{verbatim}
-producing an expression with a runtime error in the corner if
-necessary.  The type argument gives the type of the @ei@.
--}
-
-dsGuarded :: GRHSs Id (LHsExpr Id) -> Type -> DsM CoreExpr
-
-dsGuarded grhss rhs_ty = do
-    match_result <- dsGRHSs PatBindRhs [] grhss rhs_ty
-    error_expr <- mkErrorAppDs nON_EXHAUSTIVE_GUARDS_ERROR_ID rhs_ty empty
-    extractMatchResult match_result error_expr
-
--- In contrast, @dsGRHSs@ produces a @MatchResult@.
-
-dsGRHSs :: HsMatchContext Name -> [Pat Id]      -- These are to build a MatchContext from
-        -> GRHSs Id (LHsExpr Id)                -- Guarded RHSs
-        -> Type                                 -- Type of RHS
-        -> DsM MatchResult
-dsGRHSs hs_ctx _ (GRHSs grhss binds) rhs_ty
-  = -- ASSERT( notNull grhss )
-    do { match_results <- mapM (dsGRHS hs_ctx rhs_ty) grhss
-       ; let match_result1 = foldr1 combineMatchResults match_results
-             match_result2 = adjustMatchResultDs (dsLocalBinds binds) match_result1
-                             -- NB: nested dsLet inside matchResult
-       ; return match_result2 }
-
-dsGRHS :: HsMatchContext Name -> Type -> LGRHS Id (LHsExpr Id) -> DsM MatchResult
-dsGRHS hs_ctx rhs_ty (L _ (GRHS guards rhs))
-  = matchGuards (map unLoc guards) (PatGuard hs_ctx) rhs rhs_ty
-
-{-
-************************************************************************
-*                                                                      *
-*  matchGuard : make a MatchResult from a guarded RHS                  *
-*                                                                      *
-************************************************************************
--}
-
-matchGuards :: [GuardStmt Id]       -- Guard
-            -> HsStmtContext Name   -- Context
-            -> LHsExpr Id           -- RHS
-            -> Type                 -- Type of RHS of guard
-            -> DsM MatchResult
-
--- See comments with HsExpr.Stmt re what a BodyStmt means
--- Here we must be in a guard context (not do-expression, nor list-comp)
-
-matchGuards [] _ rhs _
-  = do  { core_rhs <- dsLExpr rhs
-        ; return (cantFailMatchResult core_rhs) }
-
-        -- BodyStmts must be guards
-        -- Turn an "otherwise" guard is a no-op.  This ensures that
-        -- you don't get a "non-exhaustive eqns" message when the guards
-        -- finish in "otherwise".
-        -- NB:  The success of this clause depends on the typechecker not
-        --      wrapping the 'otherwise' in empty HsTyApp or HsWrap constructors
-        --      If it does, you'll get bogus overlap warnings
-matchGuards (BodyStmt e _ _ _ : stmts) ctx rhs rhs_ty
-  | Just addTicks <- isTrueLHsExpr e = do
-    match_result <- matchGuards stmts ctx rhs rhs_ty
-    return (adjustMatchResultDs addTicks match_result)
-matchGuards (BodyStmt expr _ _ _ : stmts) ctx rhs rhs_ty = do
-    match_result <- matchGuards stmts ctx rhs rhs_ty
-    pred_expr <- dsLExpr expr
-    return (mkGuardedMatchResult pred_expr match_result)
-
-matchGuards (LetStmt binds : stmts) ctx rhs rhs_ty = do
-    match_result <- matchGuards stmts ctx rhs rhs_ty
-    return (adjustMatchResultDs (dsLocalBinds binds) match_result)
-        -- NB the dsLet occurs inside the match_result
-        -- Reason: dsLet takes the body expression as its argument
-        --         so we can't desugar the bindings without the
-        --         body expression in hand
-
-matchGuards (BindStmt pat bind_rhs _ _ : stmts) ctx rhs rhs_ty = do
-    match_result <- matchGuards stmts ctx rhs rhs_ty
-    core_rhs <- dsLExpr bind_rhs
-    matchSinglePat core_rhs (StmtCtxt ctx) pat rhs_ty match_result
-
-matchGuards (LastStmt  {} : _) _ _ _ = panic "matchGuards LastStmt"
-matchGuards (ParStmt   {} : _) _ _ _ = panic "matchGuards ParStmt"
-matchGuards (TransStmt {} : _) _ _ _ = panic "matchGuards TransStmt"
-matchGuards (RecStmt   {} : _) _ _ _ = panic "matchGuards RecStmt"
-
-isTrueLHsExpr :: LHsExpr Id -> Maybe (CoreExpr -> DsM CoreExpr)
-
--- Returns Just {..} if we're sure that the expression is True
--- I.e.   * 'True' datacon
---        * 'otherwise' Id
---        * Trivial wappings of these
--- The arguments to Just are any HsTicks that we have found,
--- because we still want to tick then, even it they are aways evaluted.
-isTrueLHsExpr (L _ (HsVar v)) |  v `hasKey` otherwiseIdKey
-                              || v `hasKey` getUnique trueDataConId
-                                      = Just return
-        -- trueDataConId doesn't have the same unique as trueDataCon
-isTrueLHsExpr (L _ (HsTick tickish e))
-    | Just ticks <- isTrueLHsExpr e
-    = Just (\x -> ticks x >>= return .  (Tick tickish))
-   -- This encodes that the result is constant True for Hpc tick purposes;
-   -- which is specifically what isTrueLHsExpr is trying to find out.
-isTrueLHsExpr (L _ (HsBinTick ixT _ e))
-    | Just ticks <- isTrueLHsExpr e
-    = Just (\x -> do e <- ticks x
-                     this_mod <- getModule
-                     return (Tick (HpcTick this_mod ixT) e))
-
-isTrueLHsExpr (L _ (HsPar e))         = isTrueLHsExpr e
-isTrueLHsExpr _                       = Nothing
-
-{-
-Should {\em fail} if @e@ returns @D@
-\begin{verbatim}
-f x | p <- e', let C y# = e, f y# = r1
-    | otherwise          = r2
-\end{verbatim}
--}
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsListComp.hs b/src/Language/Haskell/Liquid/Desugar710/DsListComp.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsListComp.hs
+++ /dev/null
@@ -1,873 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-Desugaring list comprehensions, monad comprehensions and array comprehensions
--}
-
-{-# LANGUAGE CPP, NamedFieldPuns #-}
-
-module Language.Haskell.Liquid.Desugar710.DsListComp ( dsListComp, dsPArrComp, dsMonadComp ) where
-
--- #include "HsVersions.h"
-
-import {-# SOURCE #-} Language.Haskell.Liquid.Desugar710.DsExpr ( dsExpr, dsLExpr, dsLocalBinds )
-
-import Prelude hiding (error)
-import HsSyn
-import TcHsSyn
-import CoreSyn
-import MkCore
-
-import DsMonad          -- the monadery used in the desugarer
-import Language.Haskell.Liquid.Desugar710.DsUtils
-import Language.Haskell.Liquid.Types.Errors (impossible)
-
-import DynFlags
-import CoreUtils
-import Id
-import Type
-import TysWiredIn
-import Language.Haskell.Liquid.Desugar710.Match
-import PrelNames
-import SrcLoc
-import Outputable
-import FastString
-import TcType
-import ListSetOps( getNth )
--- import Util
-
-{-
-List comprehensions may be desugared in one of two ways: ``ordinary''
-(as you would expect if you read SLPJ's book) and ``with foldr/build
-turned on'' (if you read Gill {\em et al.}'s paper on the subject).
-
-There will be at least one ``qualifier'' in the input.
--}
-
-dsListComp :: [ExprLStmt Id]
-           -> Type              -- Type of entire list
-           -> DsM CoreExpr
-dsListComp lquals res_ty = do
-    dflags <- getDynFlags
-    let quals = map unLoc lquals
-        elt_ty = case tcTyConAppArgs res_ty of
-                   [elt_ty] -> elt_ty
-                   _ -> pprPanic "dsListComp" (ppr res_ty $$ ppr lquals)
-
-    if not (gopt Opt_EnableRewriteRules dflags) || gopt Opt_IgnoreInterfacePragmas dflags
-       -- Either rules are switched off, or we are ignoring what there are;
-       -- Either way foldr/build won't happen, so use the more efficient
-       -- Wadler-style desugaring
-       || isParallelComp quals
-       -- Foldr-style desugaring can't handle parallel list comprehensions
-        then deListComp quals (mkNilExpr elt_ty)
-        else mkBuildExpr elt_ty (\(c, _) (n, _) -> dfListComp c n quals)
-             -- Foldr/build should be enabled, so desugar
-             -- into foldrs and builds
-
-  where
-    -- We must test for ParStmt anywhere, not just at the head, because an extension
-    -- to list comprehensions would be to add brackets to specify the associativity
-    -- of qualifier lists. This is really easy to do by adding extra ParStmts into the
-    -- mix of possibly a single element in length, so we do this to leave the possibility open
-    isParallelComp = any isParallelStmt
-
-    isParallelStmt (ParStmt {}) = True
-    isParallelStmt _            = False
-
-
--- This function lets you desugar a inner list comprehension and a list of the binders
--- of that comprehension that we need in the outer comprehension into such an expression
--- and the type of the elements that it outputs (tuples of binders)
-dsInnerListComp :: (ParStmtBlock Id Id) -> DsM (CoreExpr, Type)
-dsInnerListComp (ParStmtBlock stmts bndrs _)
-  = do { expr <- dsListComp (stmts ++ [noLoc $ mkLastStmt (mkBigLHsVarTup bndrs)])
-                            (mkListTy bndrs_tuple_type)
-       ; return (expr, bndrs_tuple_type) }
-  where
-    bndrs_tuple_type = mkBigCoreVarTupTy bndrs
-
--- This function factors out commonality between the desugaring strategies for GroupStmt.
--- Given such a statement it gives you back an expression representing how to compute the transformed
--- list and the tuple that you need to bind from that list in order to proceed with your desugaring
-dsTransStmt :: ExprStmt Id -> DsM (CoreExpr, LPat Id)
-dsTransStmt (TransStmt { trS_form = form, trS_stmts = stmts, trS_bndrs = binderMap
-                       , trS_by = by, trS_using = using }) = do
-    let (from_bndrs, to_bndrs) = unzip binderMap
-        from_bndrs_tys  = map idType from_bndrs
-        to_bndrs_tys    = map idType to_bndrs
-        to_bndrs_tup_ty = mkBigCoreTupTy to_bndrs_tys
-
-    -- Desugar an inner comprehension which outputs a list of tuples of the "from" binders
-    (expr, from_tup_ty) <- dsInnerListComp (ParStmtBlock stmts from_bndrs noSyntaxExpr)
-
-    -- Work out what arguments should be supplied to that expression: i.e. is an extraction
-    -- function required? If so, create that desugared function and add to arguments
-    usingExpr' <- dsLExpr using
-    usingArgs <- case by of
-                   Nothing   -> return [expr]
-                   Just by_e -> do { by_e' <- dsLExpr by_e
-                                   ; lam <- matchTuple from_bndrs by_e'
-                                   ; return [lam, expr] }
-
-    -- Create an unzip function for the appropriate arity and element types and find "map"
-    unzip_stuff <- mkUnzipBind form from_bndrs_tys
-    map_id <- dsLookupGlobalId mapName
-
-    -- Generate the expressions to build the grouped list
-    let -- First we apply the grouping function to the inner list
-        inner_list_expr = mkApps usingExpr' usingArgs
-        -- Then we map our "unzip" across it to turn the lists of tuples into tuples of lists
-        -- We make sure we instantiate the type variable "a" to be a list of "from" tuples and
-        -- the "b" to be a tuple of "to" lists!
-        -- Then finally we bind the unzip function around that expression
-        bound_unzipped_inner_list_expr
-          = case unzip_stuff of
-              Nothing -> inner_list_expr
-              Just (unzip_fn, unzip_rhs) -> Let (Rec [(unzip_fn, unzip_rhs)]) $
-                                            mkApps (Var map_id) $
-                                            [ Type (mkListTy from_tup_ty)
-                                            , Type to_bndrs_tup_ty
-                                            , Var unzip_fn
-                                            , inner_list_expr]
-
-    -- Build a pattern that ensures the consumer binds into the NEW binders,
-    -- which hold lists rather than single values
-    let pat = mkBigLHsVarPatTup to_bndrs
-    return (bound_unzipped_inner_list_expr, pat)
-
-dsTransStmt _ = panic "dsTransStmt: Not given a TransStmt"
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[DsListComp-ordinary]{Ordinary desugaring of list comprehensions}
-*                                                                      *
-************************************************************************
-
-Just as in Phil's chapter~7 in SLPJ, using the rules for
-optimally-compiled list comprehensions.  This is what Kevin followed
-as well, and I quite happily do the same.  The TQ translation scheme
-transforms a list of qualifiers (either boolean expressions or
-generators) into a single expression which implements the list
-comprehension.  Because we are generating 2nd-order polymorphic
-lambda-calculus, calls to NIL and CONS must be applied to a type
-argument, as well as their usual value arguments.
-\begin{verbatim}
-TE << [ e | qs ] >>  =  TQ << [ e | qs ] ++ Nil (typeOf e) >>
-
-(Rule C)
-TQ << [ e | ] ++ L >> = Cons (typeOf e) TE <<e>> TE <<L>>
-
-(Rule B)
-TQ << [ e | b , qs ] ++ L >> =
-    if TE << b >> then TQ << [ e | qs ] ++ L >> else TE << L >>
-
-(Rule A')
-TQ << [ e | p <- L1, qs ]  ++  L2 >> =
-  letrec
-    h = \ u1 ->
-          case u1 of
-            []        ->  TE << L2 >>
-            (u2 : u3) ->
-                  (( \ TE << p >> -> ( TQ << [e | qs]  ++  (h u3) >> )) u2)
-                    [] (h u3)
-  in
-    h ( TE << L1 >> )
-
-"h", "u1", "u2", and "u3" are new variables.
-\end{verbatim}
-
-@deListComp@ is the TQ translation scheme.  Roughly speaking, @dsExpr@
-is the TE translation scheme.  Note that we carry around the @L@ list
-already desugared.  @dsListComp@ does the top TE rule mentioned above.
-
-To the above, we add an additional rule to deal with parallel list
-comprehensions.  The translation goes roughly as follows:
-     [ e | p1 <- e11, let v1 = e12, p2 <- e13
-         | q1 <- e21, let v2 = e22, q2 <- e23]
-     =>
-     [ e | ((x1, .., xn), (y1, ..., ym)) <-
-               zip [(x1,..,xn) | p1 <- e11, let v1 = e12, p2 <- e13]
-                   [(y1,..,ym) | q1 <- e21, let v2 = e22, q2 <- e23]]
-where (x1, .., xn) are the variables bound in p1, v1, p2
-      (y1, .., ym) are the variables bound in q1, v2, q2
-
-In the translation below, the ParStmt branch translates each parallel branch
-into a sub-comprehension, and desugars each independently.  The resulting lists
-are fed to a zip function, we create a binding for all the variables bound in all
-the comprehensions, and then we hand things off the the desugarer for bindings.
-The zip function is generated here a) because it's small, and b) because then we
-don't have to deal with arbitrary limits on the number of zip functions in the
-prelude, nor which library the zip function came from.
-The introduced tuples are Boxed, but only because I couldn't get it to work
-with the Unboxed variety.
--}
-
-deListComp :: [ExprStmt Id] -> CoreExpr -> DsM CoreExpr
-
-deListComp [] _ = panic "deListComp"
-
-deListComp (LastStmt body _ : _) list
-  =     -- Figure 7.4, SLPJ, p 135, rule C above
-    -- ASSERT( null quals )
-    do { core_body <- dsLExpr body
-       ; return (mkConsExpr (exprType core_body) core_body list) }
-
-        -- Non-last: must be a guard
-deListComp (BodyStmt guard _ _ _ : quals) list = do  -- rule B above
-    core_guard <- dsLExpr guard
-    core_rest <- deListComp quals list
-    return (mkIfThenElse core_guard core_rest list)
-
--- [e | let B, qs] = let B in [e | qs]
-deListComp (LetStmt binds : quals) list = do
-    core_rest <- deListComp quals list
-    dsLocalBinds binds core_rest
-
-deListComp (stmt@(TransStmt {}) : quals) list = do
-    (inner_list_expr, pat) <- dsTransStmt stmt
-    deBindComp pat inner_list_expr quals list
-
-deListComp (BindStmt pat list1 _ _ : quals) core_list2 = do -- rule A' above
-    core_list1 <- dsLExpr list1
-    deBindComp pat core_list1 quals core_list2
-
-deListComp (ParStmt stmtss_w_bndrs _ _ : quals) list
-  = do { exps_and_qual_tys <- mapM dsInnerListComp stmtss_w_bndrs
-       ; let (exps, qual_tys) = unzip exps_and_qual_tys
-
-       ; (zip_fn, zip_rhs) <- mkZipBind qual_tys
-
-        -- Deal with [e | pat <- zip l1 .. ln] in example above
-       ; deBindComp pat (Let (Rec [(zip_fn, zip_rhs)]) (mkApps (Var zip_fn) exps))
-                    quals list }
-  where
-        bndrs_s = [bs | ParStmtBlock _ bs _ <- stmtss_w_bndrs]
-
-        -- pat is the pattern ((x1,..,xn), (y1,..,ym)) in the example above
-        pat  = mkBigLHsPatTup pats
-        pats = map mkBigLHsVarPatTup bndrs_s
-
-deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt"
-
-deBindComp :: OutPat Id
-           -> CoreExpr
-           -> [ExprStmt Id]
-           -> CoreExpr
-           -> DsM (Expr Id)
-deBindComp pat core_list1 quals core_list2 = do
-    let
-        u3_ty@u1_ty = exprType core_list1       -- two names, same thing
-
-        -- u1_ty is a [alpha] type, and u2_ty = alpha
-        u2_ty = hsLPatType pat
-
-        res_ty = exprType core_list2
-        h_ty   = u1_ty `mkFunTy` res_ty
-
-    [h, u1, u2, u3] <- newSysLocalsDs [h_ty, u1_ty, u2_ty, u3_ty]
-
-    -- the "fail" value ...
-    let
-        core_fail   = App (Var h) (Var u3)
-        letrec_body = App (Var h) core_list1
-
-    rest_expr <- deListComp quals core_fail
-    core_match <- matchSimply (Var u2) (StmtCtxt ListComp) pat rest_expr core_fail
-
-    let
-        rhs = Lam u1 $
-              Case (Var u1) u1 res_ty
-                   [(DataAlt nilDataCon,  [],       core_list2),
-                    (DataAlt consDataCon, [u2, u3], core_match)]
-                        -- Increasing order of tag
-
-    return (Let (Rec [(h, rhs)]) letrec_body)
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[DsListComp-foldr-build]{Foldr/Build desugaring of list comprehensions}
-*                                                                      *
-************************************************************************
-
-@dfListComp@ are the rules used with foldr/build turned on:
-
-\begin{verbatim}
-TE[ e | ]            c n = c e n
-TE[ e | b , q ]      c n = if b then TE[ e | q ] c n else n
-TE[ e | p <- l , q ] c n = let
-                                f = \ x b -> case x of
-                                                  p -> TE[ e | q ] c b
-                                                  _ -> b
-                           in
-                           foldr f n l
-\end{verbatim}
--}
-
-dfListComp :: Id -> Id      -- 'c' and 'n'
-        -> [ExprStmt Id]    -- the rest of the qual's
-        -> DsM CoreExpr
-
-dfListComp _ _ [] = panic "dfListComp"
-
-dfListComp c_id n_id (LastStmt body _ : _)
-  = -- ASSERT( null quals )
-    do { core_body <- dsLExpr body
-       ; return (mkApps (Var c_id) [core_body, Var n_id]) }
-
-        -- Non-last: must be a guard
-dfListComp c_id n_id (BodyStmt guard _ _ _  : quals) = do
-    core_guard <- dsLExpr guard
-    core_rest <- dfListComp c_id n_id quals
-    return (mkIfThenElse core_guard core_rest (Var n_id))
-
-dfListComp c_id n_id (LetStmt binds : quals) = do
-    -- new in 1.3, local bindings
-    core_rest <- dfListComp c_id n_id quals
-    dsLocalBinds binds core_rest
-
-dfListComp c_id n_id (stmt@(TransStmt {}) : quals) = do
-    (inner_list_expr, pat) <- dsTransStmt stmt
-    -- Anyway, we bind the newly grouped list via the generic binding function
-    dfBindComp c_id n_id (pat, inner_list_expr) quals
-
-dfListComp c_id n_id (BindStmt pat list1 _ _ : quals) = do
-    -- evaluate the two lists
-    core_list1 <- dsLExpr list1
-
-    -- Do the rest of the work in the generic binding builder
-    dfBindComp c_id n_id (pat, core_list1) quals
-
-dfListComp _ _ (ParStmt {} : _) = panic "dfListComp ParStmt"
-dfListComp _ _ (RecStmt {} : _) = panic "dfListComp RecStmt"
-
-dfBindComp :: Id -> Id          -- 'c' and 'n'
-           -> (LPat Id, CoreExpr)
-           -> [ExprStmt Id]     -- the rest of the qual's
-           -> DsM CoreExpr
-dfBindComp c_id n_id (pat, core_list1) quals = do
-    -- find the required type
-    let x_ty   = hsLPatType pat
-        b_ty   = idType n_id
-
-    -- create some new local id's
-    [b, x] <- newSysLocalsDs [b_ty, x_ty]
-
-    -- build rest of the comprehesion
-    core_rest <- dfListComp c_id b quals
-
-    -- build the pattern match
-    core_expr <- matchSimply (Var x) (StmtCtxt ListComp)
-                pat core_rest (Var b)
-
-    -- now build the outermost foldr, and return
-    mkFoldrExpr x_ty b_ty (mkLams [x, b] core_expr) (Var n_id) core_list1
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[DsFunGeneration]{Generation of zip/unzip functions for use in desugaring}
-*                                                                      *
-************************************************************************
--}
-
-mkZipBind :: [Type] -> DsM (Id, CoreExpr)
--- mkZipBind [t1, t2]
--- = (zip, \as1:[t1] as2:[t2]
---         -> case as1 of
---              [] -> []
---              (a1:as'1) -> case as2 of
---                              [] -> []
---                              (a2:as'2) -> (a1, a2) : zip as'1 as'2)]
-
-mkZipBind elt_tys = do
-    ass  <- mapM newSysLocalDs  elt_list_tys
-    as'  <- mapM newSysLocalDs  elt_tys
-    as's <- mapM newSysLocalDs  elt_list_tys
-
-    zip_fn <- newSysLocalDs zip_fn_ty
-
-    let inner_rhs = mkConsExpr elt_tuple_ty
-                        (mkBigCoreVarTup as')
-                        (mkVarApps (Var zip_fn) as's)
-        zip_body  = foldr mk_case inner_rhs (zip3 ass as' as's)
-
-    return (zip_fn, mkLams ass zip_body)
-  where
-    elt_list_tys      = map mkListTy elt_tys
-    elt_tuple_ty      = mkBigCoreTupTy elt_tys
-    elt_tuple_list_ty = mkListTy elt_tuple_ty
-
-    zip_fn_ty         = mkFunTys elt_list_tys elt_tuple_list_ty
-
-    mk_case (as, a', as') rest
-          = Case (Var as) as elt_tuple_list_ty
-                  [(DataAlt nilDataCon,  [],        mkNilExpr elt_tuple_ty),
-                   (DataAlt consDataCon, [a', as'], rest)]
-                        -- Increasing order of tag
-
-
-mkUnzipBind :: TransForm -> [Type] -> DsM (Maybe (Id, CoreExpr))
--- mkUnzipBind [t1, t2]
--- = (unzip, \ys :: [(t1, t2)] -> foldr (\ax :: (t1, t2) axs :: ([t1], [t2])
---     -> case ax of
---      (x1, x2) -> case axs of
---                (xs1, xs2) -> (x1 : xs1, x2 : xs2))
---      ([], [])
---      ys)
---
--- We use foldr here in all cases, even if rules are turned off, because we may as well!
-mkUnzipBind ThenForm _
- = return Nothing    -- No unzipping for ThenForm
-mkUnzipBind _ elt_tys
-  = do { ax  <- newSysLocalDs elt_tuple_ty
-       ; axs <- newSysLocalDs elt_list_tuple_ty
-       ; ys  <- newSysLocalDs elt_tuple_list_ty
-       ; xs  <- mapM newSysLocalDs elt_tys
-       ; xss <- mapM newSysLocalDs elt_list_tys
-
-       ; unzip_fn <- newSysLocalDs unzip_fn_ty
-
-       ; [us1, us2] <- sequence [newUniqueSupply, newUniqueSupply]
-
-       ; let nil_tuple = mkBigCoreTup (map mkNilExpr elt_tys)
-             concat_expressions = map mkConcatExpression (zip3 elt_tys (map Var xs) (map Var xss))
-             tupled_concat_expression = mkBigCoreTup concat_expressions
-
-             folder_body_inner_case = mkTupleCase us1 xss tupled_concat_expression axs (Var axs)
-             folder_body_outer_case = mkTupleCase us2 xs folder_body_inner_case ax (Var ax)
-             folder_body = mkLams [ax, axs] folder_body_outer_case
-
-       ; unzip_body <- mkFoldrExpr elt_tuple_ty elt_list_tuple_ty folder_body nil_tuple (Var ys)
-       ; return (Just (unzip_fn, mkLams [ys] unzip_body)) }
-  where
-    elt_tuple_ty       = mkBigCoreTupTy elt_tys
-    elt_tuple_list_ty  = mkListTy elt_tuple_ty
-    elt_list_tys       = map mkListTy elt_tys
-    elt_list_tuple_ty  = mkBigCoreTupTy elt_list_tys
-
-    unzip_fn_ty        = elt_tuple_list_ty `mkFunTy` elt_list_tuple_ty
-
-    mkConcatExpression (list_element_ty, head, tail) = mkConsExpr list_element_ty head tail
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[DsPArrComp]{Desugaring of array comprehensions}
-*                                                                      *
-************************************************************************
--}
-
--- entry point for desugaring a parallel array comprehension
---
---   [:e | qss:] = <<[:e | qss:]>> () [:():]
---
-dsPArrComp :: [ExprStmt Id]
-            -> DsM CoreExpr
-
--- Special case for parallel comprehension
-dsPArrComp (ParStmt qss _ _ : quals) = dePArrParComp qss quals
-
--- Special case for simple generators:
---
---  <<[:e' | p <- e, qs:]>> = <<[: e' | qs :]>> p e
---
--- if matching again p cannot fail, or else
---
---  <<[:e' | p <- e, qs:]>> =
---    <<[:e' | qs:]>> p (filterP (\x -> case x of {p -> True; _ -> False}) e)
---
-dsPArrComp (BindStmt p e _ _ : qs) = do
-    filterP <- dsDPHBuiltin filterPVar
-    ce <- dsLExpr e
-    let ety'ce  = parrElemType ce
-        false   = Var falseDataConId
-        true    = Var trueDataConId
-    v <- newSysLocalDs ety'ce
-    pred <- matchSimply (Var v) (StmtCtxt PArrComp) p true false
-    let gen | isIrrefutableHsPat p = ce
-            | otherwise            = mkApps (Var filterP) [Type ety'ce, mkLams [v] pred, ce]
-    dePArrComp qs p gen
-
-dsPArrComp qs = do -- no ParStmt in `qs'
-    sglP <- dsDPHBuiltin singletonPVar
-    let unitArray = mkApps (Var sglP) [Type unitTy, mkCoreTup []]
-    dePArrComp qs (noLoc $ WildPat unitTy) unitArray
-
-
-
--- the work horse
---
-dePArrComp :: [ExprStmt Id]
-           -> LPat Id           -- the current generator pattern
-           -> CoreExpr          -- the current generator expression
-           -> DsM CoreExpr
-
-dePArrComp [] _ _ = panic "dePArrComp"
-
---
---  <<[:e' | :]>> pa ea = mapP (\pa -> e') ea
---
-dePArrComp (LastStmt e' _ : _) pa cea
-  = -- ASSERT( null quals )
-    do { mapP <- dsDPHBuiltin mapPVar
-       ; let ty = parrElemType cea
-       ; (clam, ty'e') <- deLambda ty pa e'
-       ; return $ mkApps (Var mapP) [Type ty, Type ty'e', clam, cea] }
---
---  <<[:e' | b, qs:]>> pa ea = <<[:e' | qs:]>> pa (filterP (\pa -> b) ea)
---
-dePArrComp (BodyStmt b _ _ _ : qs) pa cea = do
-    filterP <- dsDPHBuiltin filterPVar
-    let ty = parrElemType cea
-    (clam,_) <- deLambda ty pa b
-    dePArrComp qs pa (mkApps (Var filterP) [Type ty, clam, cea])
-
---
---  <<[:e' | p <- e, qs:]>> pa ea =
---    let ef = \pa -> e
---    in
---    <<[:e' | qs:]>> (pa, p) (crossMap ea ef)
---
--- if matching again p cannot fail, or else
---
---  <<[:e' | p <- e, qs:]>> pa ea =
---    let ef = \pa -> filterP (\x -> case x of {p -> True; _ -> False}) e
---    in
---    <<[:e' | qs:]>> (pa, p) (crossMapP ea ef)
---
-dePArrComp (BindStmt p e _ _ : qs) pa cea = do
-    filterP <- dsDPHBuiltin filterPVar
-    crossMapP <- dsDPHBuiltin crossMapPVar
-    ce <- dsLExpr e
-    let ety'cea = parrElemType cea
-        ety'ce  = parrElemType ce
-        false   = Var falseDataConId
-        true    = Var trueDataConId
-    v <- newSysLocalDs ety'ce
-    pred <- matchSimply (Var v) (StmtCtxt PArrComp) p true false
-    let cef | isIrrefutableHsPat p = ce
-            | otherwise            = mkApps (Var filterP) [Type ety'ce, mkLams [v] pred, ce]
-    (clam, _) <- mkLambda ety'cea pa cef
-    let ety'cef = ety'ce                    -- filter doesn't change the element type
-        pa'     = mkLHsPatTup [pa, p]
-
-    dePArrComp qs pa' (mkApps (Var crossMapP)
-                                 [Type ety'cea, Type ety'cef, cea, clam])
---
---  <<[:e' | let ds, qs:]>> pa ea =
---    <<[:e' | qs:]>> (pa, (x_1, ..., x_n))
---                    (mapP (\v@pa -> let ds in (v, (x_1, ..., x_n))) ea)
---  where
---    {x_1, ..., x_n} = DV (ds)         -- Defined Variables
---
-dePArrComp (LetStmt ds : qs) pa cea = do
-    mapP <- dsDPHBuiltin mapPVar
-    let xs     = collectLocalBinders ds
-        ty'cea = parrElemType cea
-    v <- newSysLocalDs ty'cea
-    clet <- dsLocalBinds ds (mkCoreTup (map Var xs))
-    let'v <- newSysLocalDs (exprType clet)
-    let projBody = mkCoreLet (NonRec let'v clet) $
-                   mkCoreTup [Var v, Var let'v]
-        errTy    = exprType projBody
-        errMsg   = ptext (sLit "DsListComp.dePArrComp: internal error!")
-    cerr <- mkErrorAppDs pAT_ERROR_ID errTy errMsg
-    ccase <- matchSimply (Var v) (StmtCtxt PArrComp) pa projBody cerr
-    let pa'    = mkLHsPatTup [pa, mkLHsPatTup (map nlVarPat xs)]
-        proj   = mkLams [v] ccase
-    dePArrComp qs pa' (mkApps (Var mapP)
-                                   [Type ty'cea, Type errTy, proj, cea])
---
--- The parser guarantees that parallel comprehensions can only appear as
--- singleton qualifier lists, which we already special case in the caller.
--- So, encountering one here is a bug.
---
-dePArrComp (ParStmt {} : _) _ _ =
-  panic "DsListComp.dePArrComp: malformed comprehension AST: ParStmt"
-dePArrComp (TransStmt {} : _) _ _ = panic "DsListComp.dePArrComp: TransStmt"
-dePArrComp (RecStmt   {} : _) _ _ = panic "DsListComp.dePArrComp: RecStmt"
-
---  <<[:e' | qs | qss:]>> pa ea =
---    <<[:e' | qss:]>> (pa, (x_1, ..., x_n))
---                     (zipP ea <<[:(x_1, ..., x_n) | qs:]>>)
---    where
---      {x_1, ..., x_n} = DV (qs)
---
-dePArrParComp :: [ParStmtBlock Id Id] -> [ExprStmt Id] -> DsM CoreExpr
-dePArrParComp qss quals = do
-    (pQss, ceQss) <- deParStmt qss
-    dePArrComp quals pQss ceQss
-  where
-    deParStmt []             =
-      -- empty parallel statement lists have no source representation
-      panic "DsListComp.dePArrComp: Empty parallel list comprehension"
-    deParStmt (ParStmtBlock qs xs _:qss) = do        -- first statement
-      let res_expr = mkLHsVarTuple xs
-      cqs <- dsPArrComp (map unLoc qs ++ [mkLastStmt res_expr])
-      parStmts qss (mkLHsVarPatTup xs) cqs
-    ---
-    parStmts []             pa cea = return (pa, cea)
-    parStmts (ParStmtBlock qs xs _:qss) pa cea = do  -- subsequent statements (zip'ed)
-      zipP <- dsDPHBuiltin zipPVar
-      let pa'      = mkLHsPatTup [pa, mkLHsVarPatTup xs]
-          ty'cea   = parrElemType cea
-          res_expr = mkLHsVarTuple xs
-      cqs <- dsPArrComp (map unLoc qs ++ [mkLastStmt res_expr])
-      let ty'cqs = parrElemType cqs
-          cea'   = mkApps (Var zipP) [Type ty'cea, Type ty'cqs, cea, cqs]
-      parStmts qss pa' cea'
-
--- generate Core corresponding to `\p -> e'
---
-deLambda :: Type                        -- type of the argument
-          -> LPat Id                    -- argument pattern
-          -> LHsExpr Id                 -- body
-          -> DsM (CoreExpr, Type)
-deLambda ty p e =
-    mkLambda ty p =<< dsLExpr e
-
--- generate Core for a lambda pattern match, where the body is already in Core
---
-mkLambda :: Type                        -- type of the argument
-         -> LPat Id                     -- argument pattern
-         -> CoreExpr                    -- desugared body
-         -> DsM (CoreExpr, Type)
-mkLambda ty p ce = do
-    v <- newSysLocalDs ty
-    let errMsg = ptext (sLit "DsListComp.deLambda: internal error!")
-        ce'ty  = exprType ce
-    cerr <- mkErrorAppDs pAT_ERROR_ID ce'ty errMsg
-    res <- matchSimply (Var v) (StmtCtxt PArrComp) p ce cerr
-    return (mkLams [v] res, ce'ty)
-
--- obtain the element type of the parallel array produced by the given Core
--- expression
---
-parrElemType   :: CoreExpr -> Type
-parrElemType e  =
-  case splitTyConApp_maybe (exprType e) of
-    Just (tycon, [ty]) | tycon == parrTyCon -> ty
-    _                                                     -> panic
-      "DsListComp.parrElemType: not a parallel array type"
-
--- Translation for monad comprehensions
-
--- Entry point for monad comprehension desugaring
-dsMonadComp :: [ExprLStmt Id] -> DsM CoreExpr
-dsMonadComp stmts = dsMcStmts stmts
-
-dsMcStmts :: [ExprLStmt Id] -> DsM CoreExpr
-dsMcStmts []                    = panic "dsMcStmts"
-dsMcStmts (L loc stmt : lstmts) = putSrcSpanDs loc (dsMcStmt stmt lstmts)
-
----------------
-dsMcStmt :: ExprStmt Id -> [ExprLStmt Id] -> DsM CoreExpr
-
-dsMcStmt (LastStmt body ret_op) _
-  = -- ASSERT( null stmts )
-    do { body' <- dsLExpr body
-       ; ret_op' <- dsExpr ret_op
-       ; return (App ret_op' body') }
-
---   [ .. | let binds, stmts ]
-dsMcStmt (LetStmt binds) stmts
-  = do { rest <- dsMcStmts stmts
-       ; dsLocalBinds binds rest }
-
---   [ .. | a <- m, stmts ]
-dsMcStmt (BindStmt pat rhs bind_op fail_op) stmts
-  = do { rhs' <- dsLExpr rhs
-       ; dsMcBindStmt pat rhs' bind_op fail_op stmts }
-
--- Apply `guard` to the `exp` expression
---
---   [ .. | exp, stmts ]
---
-dsMcStmt (BodyStmt exp then_exp guard_exp _) stmts
-  = do { exp'       <- dsLExpr exp
-       ; guard_exp' <- dsExpr guard_exp
-       ; then_exp'  <- dsExpr then_exp
-       ; rest       <- dsMcStmts stmts
-       ; return $ mkApps then_exp' [ mkApps guard_exp' [exp']
-                                   , rest ] }
-
--- Group statements desugar like this:
---
---   [| (q, then group by e using f); rest |]
---   --->  f {qt} (\qv -> e) [| q; return qv |] >>= \ n_tup ->
---         case unzip n_tup of qv' -> [| rest |]
---
--- where   variables (v1:t1, ..., vk:tk) are bound by q
---         qv = (v1, ..., vk)
---         qt = (t1, ..., tk)
---         (>>=) :: m2 a -> (a -> m3 b) -> m3 b
---         f :: forall a. (a -> t) -> m1 a -> m2 (n a)
---         n_tup :: n qt
---         unzip :: n qt -> (n t1, ..., n tk)    (needs Functor n)
-
-dsMcStmt (TransStmt { trS_stmts = stmts, trS_bndrs = bndrs
-                    , trS_by = by, trS_using = using
-                    , trS_ret = return_op, trS_bind = bind_op
-                    , trS_fmap = fmap_op, trS_form = form }) stmts_rest
-  = do { let (from_bndrs, to_bndrs) = unzip bndrs
-             from_bndr_tys          = map idType from_bndrs     -- Types ty
-
-       -- Desugar an inner comprehension which outputs a list of tuples of the "from" binders
-       ; expr <- dsInnerMonadComp stmts from_bndrs return_op
-
-       -- Work out what arguments should be supplied to that expression: i.e. is an extraction
-       -- function required? If so, create that desugared function and add to arguments
-       ; usingExpr' <- dsLExpr using
-       ; usingArgs <- case by of
-                        Nothing   -> return [expr]
-                        Just by_e -> do { by_e' <- dsLExpr by_e
-                                        ; lam <- matchTuple from_bndrs by_e'
-                                        ; return [lam, expr] }
-
-       -- Generate the expressions to build the grouped list
-       -- Build a pattern that ensures the consumer binds into the NEW binders,
-       -- which hold monads rather than single values
-       ; bind_op' <- dsExpr bind_op
-       ; let bind_ty  = exprType bind_op'    -- m2 (n (a,b,c)) -> (n (a,b,c) -> r1) -> r2
-             n_tup_ty = funArgTy $ funArgTy $ funResultTy bind_ty   -- n (a,b,c)
-             tup_n_ty = mkBigCoreVarTupTy to_bndrs
-
-       ; body       <- dsMcStmts stmts_rest
-       ; n_tup_var  <- newSysLocalDs n_tup_ty
-       ; tup_n_var  <- newSysLocalDs tup_n_ty
-       ; tup_n_expr <- mkMcUnzipM form fmap_op n_tup_var from_bndr_tys
-       ; us         <- newUniqueSupply
-       ; let rhs'  = mkApps usingExpr' usingArgs
-             body' = mkTupleCase us to_bndrs body tup_n_var tup_n_expr
-
-       ; return (mkApps bind_op' [rhs', Lam n_tup_var body']) }
-
--- Parallel statements. Use `Control.Monad.Zip.mzip` to zip parallel
--- statements, for example:
---
---   [ body | qs1 | qs2 | qs3 ]
---     ->  [ body | (bndrs1, (bndrs2, bndrs3))
---                     <- [bndrs1 | qs1] `mzip` ([bndrs2 | qs2] `mzip` [bndrs3 | qs3]) ]
---
--- where `mzip` has type
---   mzip :: forall a b. m a -> m b -> m (a,b)
--- NB: we need a polymorphic mzip because we call it several times
-
-dsMcStmt (ParStmt blocks mzip_op bind_op) stmts_rest
- = do  { exps_w_tys  <- mapM ds_inner blocks   -- Pairs (exp :: m ty, ty)
-       ; mzip_op'    <- dsExpr mzip_op
-
-       ; let -- The pattern variables
-             pats = [ mkBigLHsVarPatTup bs | ParStmtBlock _ bs _ <- blocks]
-             -- Pattern with tuples of variables
-             -- [v1,v2,v3]  =>  (v1, (v2, v3))
-             pat = foldr1 (\p1 p2 -> mkLHsPatTup [p1, p2]) pats
-             (rhs, _) = foldr1 (\(e1,t1) (e2,t2) ->
-                                 (mkApps mzip_op' [Type t1, Type t2, e1, e2],
-                                  mkBoxedTupleTy [t1,t2]))
-                               exps_w_tys
-
-       ; dsMcBindStmt pat rhs bind_op noSyntaxExpr stmts_rest }
-  where
-    ds_inner (ParStmtBlock stmts bndrs return_op)
-       = do { exp <- dsInnerMonadComp stmts bndrs return_op
-            ; return (exp, mkBigCoreVarTupTy bndrs) }
-
-dsMcStmt stmt _ = pprPanic "dsMcStmt: unexpected stmt" (ppr stmt)
-
-
-matchTuple :: [Id] -> CoreExpr -> DsM CoreExpr
--- (matchTuple [a,b,c] body)
---       returns the Core term
---  \x. case x of (a,b,c) -> body
-matchTuple ids body
-  = do { us <- newUniqueSupply
-       ; tup_id <- newSysLocalDs (mkBigCoreVarTupTy ids)
-       ; return (Lam tup_id $ mkTupleCase us ids body tup_id (Var tup_id)) }
-
--- general `rhs' >>= \pat -> stmts` desugaring where `rhs'` is already a
--- desugared `CoreExpr`
-dsMcBindStmt :: LPat Id
-             -> CoreExpr        -- ^ the desugared rhs of the bind statement
-             -> SyntaxExpr Id
-             -> SyntaxExpr Id
-             -> [ExprLStmt Id]
-             -> DsM CoreExpr
-dsMcBindStmt pat rhs' bind_op fail_op stmts
-  = do  { body     <- dsMcStmts stmts
-        ; bind_op' <- dsExpr bind_op
-        ; var      <- selectSimpleMatchVarL pat
-        ; let bind_ty = exprType bind_op'       -- rhs -> (pat -> res1) -> res2
-              res1_ty = funResultTy (funArgTy (funResultTy bind_ty))
-        ; match <- matchSinglePat (Var var) (StmtCtxt DoExpr) pat
-                                  res1_ty (cantFailMatchResult body)
-        ; match_code <- handle_failure pat match fail_op
-        ; return (mkApps bind_op' [rhs', Lam var match_code]) }
-
-  where
-    -- In a monad comprehension expression, pattern-match failure just calls
-    -- the monadic `fail` rather than throwing an exception
-    handle_failure pat match fail_op
-      | matchCanFail match
-        = do { fail_op' <- dsExpr fail_op
-             ; dflags <- getDynFlags
-             ; fail_msg <- mkStringExpr (mk_fail_msg dflags pat)
-             ; extractMatchResult match (App fail_op' fail_msg) }
-      | otherwise
-        = extractMatchResult match (impossible Nothing "It can't fail")
-
-    mk_fail_msg :: DynFlags -> Located e -> String
-    mk_fail_msg dflags pat
-        = "Pattern match failure in monad comprehension at " ++
-          showPpr dflags (getLoc pat)
-
--- Desugar nested monad comprehensions, for example in `then..` constructs
---    dsInnerMonadComp quals [a,b,c] ret_op
--- returns the desugaring of
---       [ (a,b,c) | quals ]
-
-dsInnerMonadComp :: [ExprLStmt Id]
-                 -> [Id]        -- Return a tuple of these variables
-                 -> HsExpr Id   -- The monomorphic "return" operator
-                 -> DsM CoreExpr
-dsInnerMonadComp stmts bndrs ret_op
-  = dsMcStmts (stmts ++ [noLoc (LastStmt (mkBigLHsVarTup bndrs) ret_op)])
-
--- The `unzip` function for `GroupStmt` in a monad comprehensions
---
---   unzip :: m (a,b,..) -> (m a,m b,..)
---   unzip m_tuple = ( liftM selN1 m_tuple
---                   , liftM selN2 m_tuple
---                   , .. )
---
---   mkMcUnzipM fmap ys [t1, t2]
---     = ( fmap (selN1 :: (t1, t2) -> t1) ys
---       , fmap (selN2 :: (t1, t2) -> t2) ys )
-
-mkMcUnzipM :: TransForm
-           -> SyntaxExpr TcId   -- fmap
-           -> Id                -- Of type n (a,b,c)
-           -> [Type]            -- [a,b,c]
-           -> DsM CoreExpr      -- Of type (n a, n b, n c)
-mkMcUnzipM ThenForm _ ys _
-  = return (Var ys) -- No unzipping to do
-
-mkMcUnzipM _ fmap_op ys elt_tys
-  = do { fmap_op' <- dsExpr fmap_op
-       ; xs       <- mapM newSysLocalDs elt_tys
-       ; let tup_ty = mkBigCoreTupTy elt_tys
-       ; tup_xs   <- newSysLocalDs tup_ty
-
-       ; let mk_elt i = mkApps fmap_op'  -- fmap :: forall a b. (a -> b) -> n a -> n b
-                           [ Type tup_ty, Type (getNth elt_tys i)
-                           , mk_sel i, Var ys]
-
-             mk_sel n = Lam tup_xs $
-                        mkTupleSelector xs (getNth xs n) tup_xs (Var tup_xs)
-
-       ; return (mkBigCoreTup (map mk_elt [0..length elt_tys - 1])) }
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsMeta.hs b/src/Language/Haskell/Liquid/Desugar710/DsMeta.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsMeta.hs
+++ /dev/null
@@ -1,2917 +0,0 @@
-{-# LANGUAGE CPP #-}
-
------------------------------------------------------------------------------
---
--- (c) The University of Glasgow 2006
---
--- The purpose of this module is to transform an HsExpr into a CoreExpr which
--- when evaluated, returns a (Meta.Q Meta.Exp) computation analogous to the
--- input HsExpr. We do this in the DsM monad, which supplies access to
--- CoreExpr's of the "smart constructors" of the Meta.Exp datatype.
---
--- It also defines a bunch of knownKeyNames, in the same way as is done
--- in prelude/PrelNames.  It's much more convenient to do it here, because
--- otherwise we have to recompile PrelNames whenever we add a Name, which is
--- a Royal Pain (triggers other recompilation).
------------------------------------------------------------------------------
-
-module Language.Haskell.Liquid.Desugar710.DsMeta( dsBracket,
-               templateHaskellNames, qTyConName, nameTyConName,
-               liftName, liftStringName, expQTyConName, patQTyConName,
-               decQTyConName, decsQTyConName, typeQTyConName,
-               decTyConName, typeTyConName, mkNameG_dName, mkNameG_vName, mkNameG_tcName,
-               quoteExpName, quotePatName, quoteDecName, quoteTypeName,
-               tExpTyConName, tExpDataConName, unTypeName, unTypeQName,
-               unsafeTExpCoerceName
-                ) where
-
--- #include "HsVersions.h"
-
-import Language.Haskell.Liquid.Desugar710.DsExpr ( dsExpr )
-import Prelude hiding (error)
-import Language.Haskell.Liquid.Desugar710.MatchLit
-import DsMonad
-
-import qualified Language.Haskell.TH as TH
-
-import HsSyn
-import Class
-import PrelNames
--- To avoid clashes with DsMeta.varName we must make a local alias for
--- OccName.varName we do this by removing varName from the import of
--- OccName above, making a qualified instance of OccName and using
--- OccNameAlias.varName where varName ws previously used in this file.
-import qualified OccName( isDataOcc, isVarOcc, isTcOcc, varName, tcName, dataName )
-
-import Module
-import Id
-import Name hiding( isVarOcc, isTcOcc, varName, tcName )
-import NameEnv
-import TcType
-import TyCon
-import TysWiredIn
-import TysPrim ( liftedTypeKindTyConName, constraintKindTyConName )
-import CoreSyn
-import MkCore
-import CoreUtils
-import SrcLoc
-import Unique
-import BasicTypes
-import Outputable
-import Bag
-import DynFlags
-import FastString
-import ForeignCall
-import Util
-import MonadUtils
-
-import Data.Maybe
-import Control.Monad
-import Data.List
-
------------------------------------------------------------------------------
-dsBracket :: HsBracket Name -> [PendingTcSplice] -> DsM CoreExpr
--- Returns a CoreExpr of type TH.ExpQ
--- The quoted thing is parameterised over Name, even though it has
--- been type checked.  We don't want all those type decorations!
-
-dsBracket brack splices
-  = dsExtendMetaEnv new_bit (do_brack brack)
-  where
-    new_bit = mkNameEnv [(n, DsSplice (unLoc e)) | PendSplice n e <- splices]
-
-    do_brack (VarBr _ n) = do { MkC e1  <- lookupOcc n ; return e1 }
-    do_brack (ExpBr e)   = do { MkC e1  <- repLE e     ; return e1 }
-    do_brack (PatBr p)   = do { MkC p1  <- repTopP p   ; return p1 }
-    do_brack (TypBr t)   = do { MkC t1  <- repLTy t    ; return t1 }
-    do_brack (DecBrG gp) = do { MkC ds1 <- repTopDs gp ; return ds1 }
-    do_brack (DecBrL _)  = panic "dsBracket: unexpected DecBrL"
-    do_brack (TExpBr e)  = do { MkC e1  <- repLE e     ; return e1 }
-
-{- -------------- Examples --------------------
-
-  [| \x -> x |]
-====>
-  gensym (unpackString "x"#) `bindQ` \ x1::String ->
-  lam (pvar x1) (var x1)
-
-
-  [| \x -> $(f [| x |]) |]
-====>
-  gensym (unpackString "x"#) `bindQ` \ x1::String ->
-  lam (pvar x1) (f (var x1))
--}
-
-
--------------------------------------------------------
---                      Declarations
--------------------------------------------------------
-
-repTopP :: LPat Name -> DsM (Core TH.PatQ)
-repTopP pat = do { ss <- mkGenSyms (collectPatBinders pat)
-                 ; pat' <- addBinds ss (repLP pat)
-                 ; wrapGenSyms ss pat' }
-
-repTopDs :: HsGroup Name -> DsM (Core (TH.Q [TH.Dec]))
-repTopDs group@(HsGroup { hs_valds   = valds
-                        , hs_splcds  = splcds
-                        , hs_tyclds  = tyclds
-                        , hs_instds  = instds
-                        , hs_derivds = derivds
-                        , hs_fixds   = fixds
-                        , hs_defds   = defds
-                        , hs_fords   = fords
-                        , hs_warnds  = warnds
-                        , hs_annds   = annds
-                        , hs_ruleds  = ruleds
-                        , hs_vects   = vects
-                        , hs_docs    = docs })
- = do { let { tv_bndrs = hsSigTvBinders valds
-            ; bndrs = tv_bndrs ++ hsGroupBinders group } ;
-        ss <- mkGenSyms bndrs ;
-
-        -- Bind all the names mainly to avoid repeated use of explicit strings.
-        -- Thus we get
-        --      do { t :: String <- genSym "T" ;
-        --           return (Data t [] ...more t's... }
-        -- The other important reason is that the output must mention
-        -- only "T", not "Foo:T" where Foo is the current module
-
-        decls <- addBinds ss (
-                  do { val_ds   <- rep_val_binds valds
-                     ; _        <- mapM no_splice splcds
-                     ; tycl_ds  <- mapM repTyClD (tyClGroupConcat tyclds)
-                     ; role_ds  <- mapM repRoleD (concatMap group_roles tyclds)
-                     ; inst_ds  <- mapM repInstD instds
-                     ; deriv_ds <- mapM repStandaloneDerivD derivds
-                     ; fix_ds   <- mapM repFixD fixds
-                     ; _        <- mapM no_default_decl defds
-                     ; for_ds   <- mapM repForD fords
-                     ; _        <- mapM no_warn (concatMap (wd_warnings . unLoc)
-                                                           warnds)
-                     ; ann_ds   <- mapM repAnnD annds
-                     ; rule_ds  <- mapM repRuleD (concatMap (rds_rules . unLoc)
-                                                            ruleds)
-                     ; _        <- mapM no_vect vects
-                     ; _        <- mapM no_doc docs
-
-                        -- more needed
-                     ;  return (de_loc $ sort_by_loc $
-                                val_ds ++ catMaybes tycl_ds ++ role_ds
-                                       ++ (concat fix_ds)
-                                       ++ inst_ds ++ rule_ds ++ for_ds
-                                       ++ ann_ds ++ deriv_ds) }) ;
-
-        decl_ty <- lookupType decQTyConName ;
-        let { core_list = coreList' decl_ty decls } ;
-
-        dec_ty <- lookupType decTyConName ;
-        q_decs  <- repSequenceQ dec_ty core_list ;
-
-        wrapGenSyms ss q_decs
-      }
-  where
-    no_splice (L loc _)
-      = notHandledL loc "Splices within declaration brackets" empty
-    no_default_decl (L loc decl)
-      = notHandledL loc "Default declarations" (ppr decl)
-    no_warn (L loc (Warning thing _))
-      = notHandledL loc "WARNING and DEPRECATION pragmas" $
-                    text "Pragma for declaration of" <+> ppr thing
-    no_vect (L loc decl)
-      = notHandledL loc "Vectorisation pragmas" (ppr decl)
-    no_doc (L loc _)
-      = notHandledL loc "Haddock documentation" empty
-
-hsSigTvBinders :: HsValBinds Name -> [Name]
--- See Note [Scoped type variables in bindings]
-hsSigTvBinders binds
-  = [hsLTyVarName tv | L _ (TypeSig _ (L _ (HsForAllTy Explicit _ qtvs _ _)) _) <- sigs
-                     , tv <- hsQTvBndrs qtvs]
-  where
-    sigs = case binds of
-             ValBindsIn  _ sigs -> sigs
-             ValBindsOut _ sigs -> sigs
-
-
-{- Notes
-
-Note [Scoped type variables in bindings]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
-   f :: forall a. a -> a
-   f x = x::a
-Here the 'forall a' brings 'a' into scope over the binding group.
-To achieve this we
-
-  a) Gensym a binding for 'a' at the same time as we do one for 'f'
-     collecting the relevant binders with hsSigTvBinders
-
-  b) When processing the 'forall', don't gensym
-
-The relevant places are signposted with references to this Note
-
-Note [Binders and occurrences]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When we desugar [d| data T = MkT |]
-we want to get
-        Data "T" [] [Con "MkT" []] []
-and *not*
-        Data "Foo:T" [] [Con "Foo:MkT" []] []
-That is, the new data decl should fit into whatever new module it is
-asked to fit in.   We do *not* clone, though; no need for this:
-        Data "T79" ....
-
-But if we see this:
-        data T = MkT
-        foo = reifyDecl T
-
-then we must desugar to
-        foo = Data "Foo:T" [] [Con "Foo:MkT" []] []
-
-So in repTopDs we bring the binders into scope with mkGenSyms and addBinds.
-And we use lookupOcc, rather than lookupBinder
-in repTyClD and repC.
-
--}
-
--- represent associated family instances
---
-repTyClD :: LTyClDecl Name -> DsM (Maybe (SrcSpan, Core TH.DecQ))
-
-repTyClD (L loc (FamDecl { tcdFam = fam })) = liftM Just $ repFamilyDecl (L loc fam)
-
-repTyClD (L loc (SynDecl { tcdLName = tc, tcdTyVars = tvs, tcdRhs = rhs }))
-  = do { tc1 <- lookupLOcc tc           -- See note [Binders and occurrences]
-       ; dec <- addTyClTyVarBinds tvs $ \bndrs ->
-                repSynDecl tc1 bndrs rhs
-       ; return (Just (loc, dec)) }
-
-repTyClD (L loc (DataDecl { tcdLName = tc, tcdTyVars = tvs, tcdDataDefn = defn }))
-  = do { tc1 <- lookupLOcc tc           -- See note [Binders and occurrences]
-       ; tc_tvs <- mk_extra_tvs tc tvs defn
-       ; dec <- addTyClTyVarBinds tc_tvs $ \bndrs ->
-                repDataDefn tc1 bndrs Nothing (hsLTyVarNames tc_tvs) defn
-       ; return (Just (loc, dec)) }
-
-repTyClD (L loc (ClassDecl { tcdCtxt = cxt, tcdLName = cls,
-                             tcdTyVars = tvs, tcdFDs = fds,
-                             tcdSigs = sigs, tcdMeths = meth_binds,
-                             tcdATs = ats, tcdATDefs = [] }))
-  = do { cls1 <- lookupLOcc cls         -- See note [Binders and occurrences]
-       ; dec  <- addTyVarBinds tvs $ \bndrs ->
-           do { cxt1   <- repLContext cxt
-              ; sigs1  <- rep_sigs sigs
-              ; binds1 <- rep_binds meth_binds
-              ; fds1   <- repLFunDeps fds
-              ; ats1   <- repFamilyDecls ats
-              ; decls1 <- coreList decQTyConName (ats1 ++ sigs1 ++ binds1)
-              ; repClass cxt1 cls1 bndrs fds1 decls1
-              }
-       ; return $ Just (loc, dec)
-       }
-
--- Un-handled cases
-repTyClD (L loc d) = putSrcSpanDs loc $
-                     do { warnDs (hang ds_msg 4 (ppr d))
-                        ; return Nothing }
-
--------------------------
-repRoleD :: LRoleAnnotDecl Name -> DsM (SrcSpan, Core TH.DecQ)
-repRoleD (L loc (RoleAnnotDecl tycon roles))
-  = do { tycon1 <- lookupLOcc tycon
-       ; roles1 <- mapM repRole roles
-       ; roles2 <- coreList roleTyConName roles1
-       ; dec <- repRoleAnnotD tycon1 roles2
-       ; return (loc, dec) }
-
--------------------------
-repDataDefn :: Core TH.Name -> Core [TH.TyVarBndr]
-            -> Maybe (Core [TH.TypeQ])
-            -> [Name] -> HsDataDefn Name
-            -> DsM (Core TH.DecQ)
-repDataDefn tc bndrs opt_tys tv_names
-          (HsDataDefn { dd_ND = new_or_data, dd_ctxt = cxt
-                      , dd_cons = cons, dd_derivs = mb_derivs })
-  = do { cxt1     <- repLContext cxt
-       ; derivs1  <- repDerivs mb_derivs
-       ; case new_or_data of
-           NewType  -> do { con1 <- repC tv_names (head cons)
-                          ; case con1 of
-                             [c] -> repNewtype cxt1 tc bndrs opt_tys c derivs1
-                             _cs -> failWithDs (ptext
-                                     (sLit "Multiple constructors for newtype:")
-                                      <+> pprQuotedList
-                                                (con_names $ unLoc $ head cons))
-                          }
-           DataType -> do { consL <- concatMapM (repC tv_names) cons
-                          ; cons1 <- coreList conQTyConName consL
-                          ; repData cxt1 tc bndrs opt_tys cons1 derivs1 } }
-
-repSynDecl :: Core TH.Name -> Core [TH.TyVarBndr]
-          -> LHsType Name
-          -> DsM (Core TH.DecQ)
-repSynDecl tc bndrs ty
-  = do { ty1 <- repLTy ty
-       ; repTySyn tc bndrs ty1 }
-
-repFamilyDecl :: LFamilyDecl Name -> DsM (SrcSpan, Core TH.DecQ)
-repFamilyDecl (L loc (FamilyDecl { fdInfo    = info,
-                                   fdLName   = tc,
-                                   fdTyVars  = tvs,
-                                   fdKindSig = opt_kind }))
-  = do { tc1 <- lookupLOcc tc           -- See note [Binders and occurrences]
-       ; dec <- addTyClTyVarBinds tvs $ \bndrs ->
-           case (opt_kind, info) of
-                  (Nothing, ClosedTypeFamily eqns) ->
-                    do { eqns1 <- mapM repTyFamEqn eqns
-                       ; eqns2 <- coreList tySynEqnQTyConName eqns1
-                       ; repClosedFamilyNoKind tc1 bndrs eqns2 }
-                  (Just ki, ClosedTypeFamily eqns) ->
-                    do { eqns1 <- mapM repTyFamEqn eqns
-                       ; eqns2 <- coreList tySynEqnQTyConName eqns1
-                       ; ki1 <- repLKind ki
-                       ; repClosedFamilyKind tc1 bndrs ki1 eqns2 }
-                  (Nothing, _) ->
-                    do { info' <- repFamilyInfo info
-                       ; repFamilyNoKind info' tc1 bndrs }
-                  (Just ki, _) ->
-                    do { info' <- repFamilyInfo info
-                       ; ki1 <- repLKind ki
-                       ; repFamilyKind info' tc1 bndrs ki1 }
-       ; return (loc, dec)
-       }
-
-repFamilyDecls :: [LFamilyDecl Name] -> DsM [Core TH.DecQ]
-repFamilyDecls fds = liftM de_loc (mapM repFamilyDecl fds)
-
--------------------------
-mk_extra_tvs :: Located Name -> LHsTyVarBndrs Name
-             -> HsDataDefn Name -> DsM (LHsTyVarBndrs Name)
--- If there is a kind signature it must be of form
---    k1 -> .. -> kn -> *
--- Return type variables [tv1:k1, tv2:k2, .., tvn:kn]
-mk_extra_tvs tc tvs defn
-  | HsDataDefn { dd_kindSig = Just hs_kind } <- defn
-  = do { extra_tvs <- go hs_kind
-       ; return (tvs { hsq_tvs = hsq_tvs tvs ++ extra_tvs }) }
-  | otherwise
-  = return tvs
-  where
-    go :: LHsKind Name -> DsM [LHsTyVarBndr Name]
-    go (L loc (HsFunTy kind rest))
-      = do { uniq <- newUnique
-           ; let { occ = mkTyVarOccFS (fsLit "t")
-                 ; nm = mkInternalName uniq occ loc
-                 ; hs_tv = L loc (KindedTyVar (noLoc nm) kind) }
-           ; hs_tvs <- go rest
-           ; return (hs_tv : hs_tvs) }
-
-    go (L _ (HsTyVar n))
-      | n == liftedTypeKindTyConName
-      = return []
-
-    go _ = failWithDs (ptext (sLit "Malformed kind signature for") <+> ppr tc)
-
--------------------------
--- represent fundeps
---
-repLFunDeps :: [Located (FunDep (Located Name))] -> DsM (Core [TH.FunDep])
-repLFunDeps fds = repList funDepTyConName repLFunDep fds
-
-repLFunDep :: Located (FunDep (Located Name)) -> DsM (Core TH.FunDep)
-repLFunDep (L _ (xs, ys))
-   = do xs' <- repList nameTyConName (lookupBinder . unLoc) xs
-        ys' <- repList nameTyConName (lookupBinder . unLoc) ys
-        repFunDep xs' ys'
-
--- represent family declaration flavours
---
-repFamilyInfo :: FamilyInfo Name -> DsM (Core TH.FamFlavour)
-repFamilyInfo OpenTypeFamily      = rep2 typeFamName []
-repFamilyInfo DataFamily          = rep2 dataFamName []
-repFamilyInfo ClosedTypeFamily {} = panic "repFamilyInfo"
-
--- Represent instance declarations
---
-repInstD :: LInstDecl Name -> DsM (SrcSpan, Core TH.DecQ)
-repInstD (L loc (TyFamInstD { tfid_inst = fi_decl }))
-  = do { dec <- repTyFamInstD fi_decl
-       ; return (loc, dec) }
-repInstD (L loc (DataFamInstD { dfid_inst = fi_decl }))
-  = do { dec <- repDataFamInstD fi_decl
-       ; return (loc, dec) }
-repInstD (L loc (ClsInstD { cid_inst = cls_decl }))
-  = do { dec <- repClsInstD cls_decl
-       ; return (loc, dec) }
-
-repClsInstD :: ClsInstDecl Name -> DsM (Core TH.DecQ)
-repClsInstD (ClsInstDecl { cid_poly_ty = ty, cid_binds = binds
-                         , cid_sigs = prags, cid_tyfam_insts = ats
-                         , cid_datafam_insts = adts })
-  = addTyVarBinds tvs $ \_ ->
-            -- We must bring the type variables into scope, so their
-            -- occurrences don't fail, even though the binders don't
-            -- appear in the resulting data structure
-            --
-            -- But we do NOT bring the binders of 'binds' into scope
-            -- because they are properly regarded as occurrences
-            -- For example, the method names should be bound to
-            -- the selector Ids, not to fresh names (Trac #5410)
-            --
-            do { cxt1 <- repContext cxt
-               ; cls_tcon <- repTy (HsTyVar (unLoc cls))
-               ; cls_tys <- repLTys tys
-               ; inst_ty1 <- repTapps cls_tcon cls_tys
-               ; binds1 <- rep_binds binds
-               ; prags1 <- rep_sigs prags
-               ; ats1 <- mapM (repTyFamInstD . unLoc) ats
-               ; adts1 <- mapM (repDataFamInstD . unLoc) adts
-               ; decls <- coreList decQTyConName (ats1 ++ adts1 ++ binds1 ++ prags1)
-               ; repInst cxt1 inst_ty1 decls }
- where
-   Just (tvs, cxt, cls, tys) = splitLHsInstDeclTy_maybe ty
-
-repStandaloneDerivD :: LDerivDecl Name -> DsM (SrcSpan, Core TH.DecQ)
-repStandaloneDerivD (L loc (DerivDecl { deriv_type = ty }))
-  = do { dec <- addTyVarBinds tvs $ \_ ->
-                do { cxt' <- repContext cxt
-                   ; cls_tcon <- repTy (HsTyVar (unLoc cls))
-                   ; cls_tys <- repLTys tys
-                   ; inst_ty <- repTapps cls_tcon cls_tys
-                   ; repDeriv cxt' inst_ty }
-       ; return (loc, dec) }
-  where
-    Just (tvs, cxt, cls, tys) = splitLHsInstDeclTy_maybe ty
-
-repTyFamInstD :: TyFamInstDecl Name -> DsM (Core TH.DecQ)
-repTyFamInstD decl@(TyFamInstDecl { tfid_eqn = eqn })
-  = do { let tc_name = tyFamInstDeclLName decl
-       ; tc <- lookupLOcc tc_name               -- See note [Binders and occurrences]
-       ; eqn1 <- repTyFamEqn eqn
-       ; repTySynInst tc eqn1 }
-
-repTyFamEqn :: LTyFamInstEqn Name -> DsM (Core TH.TySynEqnQ)
-repTyFamEqn (L loc (TyFamEqn { tfe_pats = HsWB { hswb_cts = tys
-                                               , hswb_kvs = kv_names
-                                               , hswb_tvs = tv_names }
-                                 , tfe_rhs = rhs }))
-  = do { let hs_tvs = HsQTvs { hsq_kvs = kv_names
-                             , hsq_tvs = userHsTyVarBndrs loc tv_names }   -- Yuk
-       ; addTyClTyVarBinds hs_tvs $ \ _ ->
-         do { tys1 <- repLTys tys
-            ; tys2 <- coreList typeQTyConName tys1
-            ; rhs1 <- repLTy rhs
-            ; repTySynEqn tys2 rhs1 } }
-
-repDataFamInstD :: DataFamInstDecl Name -> DsM (Core TH.DecQ)
-repDataFamInstD (DataFamInstDecl { dfid_tycon = tc_name
-                                 , dfid_pats = HsWB { hswb_cts = tys, hswb_kvs = kv_names, hswb_tvs = tv_names }
-                                 , dfid_defn = defn })
-  = do { tc <- lookupLOcc tc_name               -- See note [Binders and occurrences]
-       ; let loc = getLoc tc_name
-             hs_tvs = HsQTvs { hsq_kvs = kv_names, hsq_tvs = userHsTyVarBndrs loc tv_names }   -- Yuk
-       ; addTyClTyVarBinds hs_tvs $ \ bndrs ->
-         do { tys1 <- repList typeQTyConName repLTy tys
-            ; repDataDefn tc bndrs (Just tys1) tv_names defn } }
-
-repForD :: Located (ForeignDecl Name) -> DsM (SrcSpan, Core TH.DecQ)
-repForD (L loc (ForeignImport name typ _ (CImport (L _ cc) (L _ s) mch cis _)))
- = do MkC name' <- lookupLOcc name
-      MkC typ' <- repLTy typ
-      MkC cc' <- repCCallConv cc
-      MkC s' <- repSafety s
-      cis' <- conv_cimportspec cis
-      MkC str <- coreStringLit (static ++ chStr ++ cis')
-      dec <- rep2 forImpDName [cc', s', str, name', typ']
-      return (loc, dec)
- where
-    conv_cimportspec (CLabel cls) = notHandled "Foreign label" (doubleQuotes (ppr cls))
-    conv_cimportspec (CFunction DynamicTarget) = return "dynamic"
-    conv_cimportspec (CFunction (StaticTarget fs _ True)) = return (unpackFS fs)
-    conv_cimportspec (CFunction (StaticTarget _  _ False)) = panic "conv_cimportspec: values not supported yet"
-    conv_cimportspec CWrapper = return "wrapper"
-    static = case cis of
-                 CFunction (StaticTarget _ _ _) -> "static "
-                 _ -> ""
-    chStr = case mch of
-            Nothing -> ""
-            Just (Header h) -> unpackFS h ++ " "
-repForD decl = notHandled "Foreign declaration" (ppr decl)
-
-repCCallConv :: CCallConv -> DsM (Core TH.Callconv)
-repCCallConv CCallConv          = rep2 cCallName []
-repCCallConv StdCallConv        = rep2 stdCallName []
-repCCallConv CApiConv           = rep2 cApiCallName []
-repCCallConv PrimCallConv       = rep2 primCallName []
-repCCallConv JavaScriptCallConv = rep2 javaScriptCallName []
-
-repSafety :: Safety -> DsM (Core TH.Safety)
-repSafety PlayRisky = rep2 unsafeName []
-repSafety PlayInterruptible = rep2 interruptibleName []
-repSafety PlaySafe = rep2 safeName []
-
-repFixD :: LFixitySig Name -> DsM [(SrcSpan, Core TH.DecQ)]
-repFixD (L loc (FixitySig names (Fixity prec dir)))
-  = do { MkC prec' <- coreIntLit prec
-       ; let rep_fn = case dir of
-                        InfixL -> infixLDName
-                        InfixR -> infixRDName
-                        InfixN -> infixNDName
-       ; let do_one name
-              = do { MkC name' <- lookupLOcc name
-                   ; dec <- rep2 rep_fn [prec', name']
-                   ; return (loc,dec) }
-       ; mapM do_one names }
-
-repRuleD :: LRuleDecl Name -> DsM (SrcSpan, Core TH.DecQ)
-repRuleD (L loc (HsRule n act bndrs lhs _ rhs _))
-  = do { let bndr_names = concatMap ruleBndrNames bndrs
-       ; ss <- mkGenSyms bndr_names
-       ; rule1 <- addBinds ss $
-                  do { bndrs' <- repList ruleBndrQTyConName repRuleBndr bndrs
-                     ; n'   <- coreStringLit $ unpackFS $ unLoc n
-                     ; act' <- repPhases act
-                     ; lhs' <- repLE lhs
-                     ; rhs' <- repLE rhs
-                     ; repPragRule n' bndrs' lhs' rhs' act' }
-       ; rule2 <- wrapGenSyms ss rule1
-       ; return (loc, rule2) }
-
-ruleBndrNames :: LRuleBndr Name -> [Name]
-ruleBndrNames (L _ (RuleBndr n))      = [unLoc n]
-ruleBndrNames (L _ (RuleBndrSig n (HsWB { hswb_kvs = kvs, hswb_tvs = tvs })))
-  = unLoc n : kvs ++ tvs
-
-repRuleBndr :: LRuleBndr Name -> DsM (Core TH.RuleBndrQ)
-repRuleBndr (L _ (RuleBndr n))
-  = do { MkC n' <- lookupLBinder n
-       ; rep2 ruleVarName [n'] }
-repRuleBndr (L _ (RuleBndrSig n (HsWB { hswb_cts = ty })))
-  = do { MkC n'  <- lookupLBinder n
-       ; MkC ty' <- repLTy ty
-       ; rep2 typedRuleVarName [n', ty'] }
-
-repAnnD :: LAnnDecl Name -> DsM (SrcSpan, Core TH.DecQ)
-repAnnD (L loc (HsAnnotation _ ann_prov (L _ exp)))
-  = do { target <- repAnnProv ann_prov
-       ; exp'   <- repE exp
-       ; dec    <- repPragAnn target exp'
-       ; return (loc, dec) }
-
-repAnnProv :: AnnProvenance Name -> DsM (Core TH.AnnTarget)
-repAnnProv (ValueAnnProvenance (L _ n))
-  = do { MkC n' <- globalVar n  -- ANNs are allowed only at top-level
-       ; rep2 valueAnnotationName [ n' ] }
-repAnnProv (TypeAnnProvenance (L _ n))
-  = do { MkC n' <- globalVar n
-       ; rep2 typeAnnotationName [ n' ] }
-repAnnProv ModuleAnnProvenance
-  = rep2 moduleAnnotationName []
-
-ds_msg :: SDoc
-ds_msg = ptext (sLit "Cannot desugar this Template Haskell declaration:")
-
--------------------------------------------------------
---                      Constructors
--------------------------------------------------------
-
-repC :: [Name] -> LConDecl Name -> DsM [Core TH.ConQ]
-repC _ (L _ (ConDecl { con_names = con, con_qvars = con_tvs, con_cxt = L _ []
-                     , con_details = details, con_res = ResTyH98 }))
-  | null (hsQTvBndrs con_tvs)
-  = do { con1 <- mapM lookupLOcc con       -- See Note [Binders and occurrences]
-       ; mapM (\c -> repConstr c details) con1  }
-
-repC tvs (L _ (ConDecl { con_names = cons
-                       , con_qvars = con_tvs, con_cxt = L _ ctxt
-                       , con_details = details
-                       , con_res = res_ty }))
-  = do { (eq_ctxt, con_tv_subst) <- mkGadtCtxt tvs res_ty
-       ; let ex_tvs = HsQTvs { hsq_kvs = filterOut (in_subst con_tv_subst) (hsq_kvs con_tvs)
-                             , hsq_tvs = filterOut (in_subst con_tv_subst . hsLTyVarName) (hsq_tvs con_tvs) }
-
-       ; binds <- mapM dupBinder con_tv_subst
-       ; b <- dsExtendMetaEnv (mkNameEnv binds) $ -- Binds some of the con_tvs
-         addTyVarBinds ex_tvs $ \ ex_bndrs ->   -- Binds the remaining con_tvs
-    do { cons1     <- mapM lookupLOcc cons -- See Note [Binders and occurrences]
-       ; c'        <- mapM (\c -> repConstr c details) cons1
-       ; ctxt'     <- repContext (eq_ctxt ++ ctxt)
-       ; rep2 forallCName ([unC ex_bndrs, unC ctxt'] ++ (map unC c')) }
-    ; return [b]
-    }
-
-in_subst :: [(Name,Name)] -> Name -> Bool
-in_subst []          _ = False
-in_subst ((n',_):ns) n = n==n' || in_subst ns n
-
-mkGadtCtxt :: [Name]            -- Tyvars of the data type
-           -> ResType (LHsType Name)
-           -> DsM (HsContext Name, [(Name,Name)])
--- Given a data type in GADT syntax, figure out the equality
--- context, so that we can represent it with an explicit
--- equality context, because that is the only way to express
--- the GADT in TH syntax
---
--- Example:
--- data T a b c where { MkT :: forall d e. d -> e -> T d [e] e
---     mkGadtCtxt [a,b,c] [d,e] (T d [e] e)
---   returns
---     (b~[e], c~e), [d->a]
---
--- This function is fiddly, but not really hard
-mkGadtCtxt _ ResTyH98
-  = return ([], [])
-mkGadtCtxt data_tvs (ResTyGADT _ res_ty)
-  | Just (_, tys) <- hsTyGetAppHead_maybe res_ty
-  , data_tvs `equalLength` tys
-  = return (go [] [] (data_tvs `zip` tys))
-
-  | otherwise
-  = failWithDs (ptext (sLit "Malformed constructor result type:") <+> ppr res_ty)
-  where
-    go cxt subst [] = (cxt, subst)
-    go cxt subst ((data_tv, ty) : rest)
-       | Just con_tv <- is_hs_tyvar ty
-       , isTyVarName con_tv
-       , not (in_subst subst con_tv)
-       = go cxt ((con_tv, data_tv) : subst) rest
-       | otherwise
-       = go (eq_pred : cxt) subst rest
-       where
-         loc = getLoc ty
-         eq_pred = L loc (HsEqTy (L loc (HsTyVar data_tv)) ty)
-
-    is_hs_tyvar (L _ (HsTyVar n))  = Just n   -- Type variables *and* tycons
-    is_hs_tyvar (L _ (HsParTy ty)) = is_hs_tyvar ty
-    is_hs_tyvar _                  = Nothing
-
-
-repBangTy :: LBangType Name -> DsM (Core (TH.StrictTypeQ))
-repBangTy ty= do
-  MkC s <- rep2 str []
-  MkC t <- repLTy ty'
-  rep2 strictTypeName [s, t]
-  where
-    (str, ty') = case ty of
-         L _ (HsBangTy (HsSrcBang _ (Just True) True) ty) -> (unpackedName,  ty)
-         L _ (HsBangTy (HsSrcBang _ _     True) ty)       -> (isStrictName,  ty)
-         _                                                -> (notStrictName, ty)
-
--------------------------------------------------------
---                      Deriving clause
--------------------------------------------------------
-
-repDerivs :: Maybe (Located [LHsType Name]) -> DsM (Core [TH.Name])
-repDerivs Nothing = coreList nameTyConName []
-repDerivs (Just (L _ ctxt))
-  = repList nameTyConName rep_deriv ctxt
-  where
-    rep_deriv :: LHsType Name -> DsM (Core TH.Name)
-        -- Deriving clauses must have the simple H98 form
-    rep_deriv ty
-      | Just (cls, []) <- splitHsClassTy_maybe (unLoc ty)
-      = lookupOcc cls
-      | otherwise
-      = notHandled "Non-H98 deriving clause" (ppr ty)
-
-
--------------------------------------------------------
---   Signatures in a class decl, or a group of bindings
--------------------------------------------------------
-
-rep_sigs :: [LSig Name] -> DsM [Core TH.DecQ]
-rep_sigs sigs = do locs_cores <- rep_sigs' sigs
-                   return $ de_loc $ sort_by_loc locs_cores
-
-rep_sigs' :: [LSig Name] -> DsM [(SrcSpan, Core TH.DecQ)]
-        -- We silently ignore ones we don't recognise
-rep_sigs' sigs = do { sigs1 <- mapM rep_sig sigs ;
-                     return (concat sigs1) }
-
-rep_sig :: LSig Name -> DsM [(SrcSpan, Core TH.DecQ)]
-rep_sig (L loc (TypeSig nms ty _))    = mapM (rep_ty_sig sigDName loc ty) nms
-rep_sig (L _   (PatSynSig {}))        = notHandled "Pattern type signatures" empty
-rep_sig (L loc (GenericSig nms ty))   = mapM (rep_ty_sig defaultSigDName loc ty) nms
-rep_sig d@(L _ (IdSig {}))            = pprPanic "rep_sig IdSig" (ppr d)
-rep_sig (L _   (FixSig {}))           = return [] -- fixity sigs at top level
-rep_sig (L loc (InlineSig nm ispec))  = rep_inline nm ispec loc
-rep_sig (L loc (SpecSig nm tys ispec))
-   = concatMapM (\t -> rep_specialise nm t ispec loc) tys
-rep_sig (L loc (SpecInstSig _ ty))    = rep_specialiseInst ty loc
-rep_sig (L _   (MinimalSig {}))       = notHandled "MINIMAL pragmas" empty
-
-rep_ty_sig :: Name -> SrcSpan -> LHsType Name -> Located Name
-           -> DsM (SrcSpan, Core TH.DecQ)
-rep_ty_sig mk_sig loc (L _ ty) nm
-  = do { nm1 <- lookupLOcc nm
-       ; ty1 <- rep_ty ty
-       ; sig <- repProto mk_sig nm1 ty1
-       ; return (loc, sig) }
-  where
-    -- We must special-case the top-level explicit for-all of a TypeSig
-    -- See Note [Scoped type variables in bindings]
-    rep_ty (HsForAllTy Explicit _ tvs ctxt ty)
-      = do { let rep_in_scope_tv tv = do { name <- lookupBinder (hsLTyVarName tv)
-                                         ; repTyVarBndrWithKind tv name }
-           ; bndrs1 <- repList tyVarBndrTyConName rep_in_scope_tv (hsQTvBndrs tvs)
-           ; ctxt1  <- repLContext ctxt
-           ; ty1    <- repLTy ty
-           ; repTForall bndrs1 ctxt1 ty1 }
-
-    rep_ty ty = repTy ty
-
-rep_inline :: Located Name
-           -> InlinePragma      -- Never defaultInlinePragma
-           -> SrcSpan
-           -> DsM [(SrcSpan, Core TH.DecQ)]
-rep_inline nm ispec loc
-  = do { nm1    <- lookupLOcc nm
-       ; inline <- repInline $ inl_inline ispec
-       ; rm     <- repRuleMatch $ inl_rule ispec
-       ; phases <- repPhases $ inl_act ispec
-       ; pragma <- repPragInl nm1 inline rm phases
-       ; return [(loc, pragma)]
-       }
-
-rep_specialise :: Located Name -> LHsType Name -> InlinePragma -> SrcSpan
-               -> DsM [(SrcSpan, Core TH.DecQ)]
-rep_specialise nm ty ispec loc
-  = do { nm1 <- lookupLOcc nm
-       ; ty1 <- repLTy ty
-       ; phases <- repPhases $ inl_act ispec
-       ; let inline = inl_inline ispec
-       ; pragma <- if isEmptyInlineSpec inline
-                   then -- SPECIALISE
-                     repPragSpec nm1 ty1 phases
-                   else -- SPECIALISE INLINE
-                     do { inline1 <- repInline inline
-                        ; repPragSpecInl nm1 ty1 inline1 phases }
-       ; return [(loc, pragma)]
-       }
-
-rep_specialiseInst :: LHsType Name -> SrcSpan -> DsM [(SrcSpan, Core TH.DecQ)]
-rep_specialiseInst ty loc
-  = do { ty1    <- repLTy ty
-       ; pragma <- repPragSpecInst ty1
-       ; return [(loc, pragma)] }
-
-repInline :: InlineSpec -> DsM (Core TH.Inline)
-repInline NoInline  = dataCon noInlineDataConName
-repInline Inline    = dataCon inlineDataConName
-repInline Inlinable = dataCon inlinableDataConName
-repInline spec      = notHandled "repInline" (ppr spec)
-
-repRuleMatch :: RuleMatchInfo -> DsM (Core TH.RuleMatch)
-repRuleMatch ConLike = dataCon conLikeDataConName
-repRuleMatch FunLike = dataCon funLikeDataConName
-
-repPhases :: Activation -> DsM (Core TH.Phases)
-repPhases (ActiveBefore i) = do { MkC arg <- coreIntLit i
-                                ; dataCon' beforePhaseDataConName [arg] }
-repPhases (ActiveAfter i)  = do { MkC arg <- coreIntLit i
-                                ; dataCon' fromPhaseDataConName [arg] }
-repPhases _                = dataCon allPhasesDataConName
-
--------------------------------------------------------
---                      Types
--------------------------------------------------------
-
-addTyVarBinds :: LHsTyVarBndrs Name                            -- the binders to be added
-              -> (Core [TH.TyVarBndr] -> DsM (Core (TH.Q a)))  -- action in the ext env
-              -> DsM (Core (TH.Q a))
--- gensym a list of type variables and enter them into the meta environment;
--- the computations passed as the second argument is executed in that extended
--- meta environment and gets the *new* names on Core-level as an argument
-
-addTyVarBinds (HsQTvs { hsq_kvs = kvs, hsq_tvs = tvs }) m
-  = do { fresh_kv_names <- mkGenSyms kvs
-       ; fresh_tv_names <- mkGenSyms (map hsLTyVarName tvs)
-       ; let fresh_names = fresh_kv_names ++ fresh_tv_names
-       ; term <- addBinds fresh_names $
-                 do { kbs <- repList tyVarBndrTyConName mk_tv_bndr (tvs `zip` fresh_tv_names)
-                    ; m kbs }
-       ; wrapGenSyms fresh_names term }
-  where
-    mk_tv_bndr (tv, (_,v)) = repTyVarBndrWithKind tv (coreVar v)
-
-addTyClTyVarBinds :: LHsTyVarBndrs Name
-                  -> (Core [TH.TyVarBndr] -> DsM (Core (TH.Q a)))
-                  -> DsM (Core (TH.Q a))
-
--- Used for data/newtype declarations, and family instances,
--- so that the nested type variables work right
---    instance C (T a) where
---      type W (T a) = blah
--- The 'a' in the type instance is the one bound by the instance decl
-addTyClTyVarBinds tvs m
-  = do { let tv_names = hsLKiTyVarNames tvs
-       ; env <- dsGetMetaEnv
-       ; freshNames <- mkGenSyms (filterOut (`elemNameEnv` env) tv_names)
-            -- Make fresh names for the ones that are not already in scope
-            -- This makes things work for family declarations
-
-       ; term <- addBinds freshNames $
-                 do { kbs <- repList tyVarBndrTyConName mk_tv_bndr (hsQTvBndrs tvs)
-                    ; m kbs }
-
-       ; wrapGenSyms freshNames term }
-  where
-    mk_tv_bndr tv = do { v <- lookupBinder (hsLTyVarName tv)
-                       ; repTyVarBndrWithKind tv v }
-
--- Produce kinded binder constructors from the Haskell tyvar binders
---
-repTyVarBndrWithKind :: LHsTyVarBndr Name
-                     -> Core TH.Name -> DsM (Core TH.TyVarBndr)
-repTyVarBndrWithKind (L _ (UserTyVar _)) nm
-  = repPlainTV nm
-repTyVarBndrWithKind (L _ (KindedTyVar _ ki)) nm
-  = repLKind ki >>= repKindedTV nm
-
--- represent a type context
---
-repLContext :: LHsContext Name -> DsM (Core TH.CxtQ)
-repLContext (L _ ctxt) = repContext ctxt
-
-repContext :: HsContext Name -> DsM (Core TH.CxtQ)
-repContext ctxt = do preds <- repList typeQTyConName repLTy ctxt
-                     repCtxt preds
-
--- yield the representation of a list of types
---
-repLTys :: [LHsType Name] -> DsM [Core TH.TypeQ]
-repLTys tys = mapM repLTy tys
-
--- represent a type
---
-repLTy :: LHsType Name -> DsM (Core TH.TypeQ)
-repLTy (L _ ty) = repTy ty
-
-repTy :: HsType Name -> DsM (Core TH.TypeQ)
-repTy (HsForAllTy _ _ tvs ctxt ty)  =
-  addTyVarBinds tvs $ \bndrs -> do
-    ctxt1  <- repLContext ctxt
-    ty1    <- repLTy ty
-    repTForall bndrs ctxt1 ty1
-
-repTy (HsTyVar n)
-  | isTvOcc occ   = do tv1 <- lookupOcc n
-                       repTvar tv1
-  | isDataOcc occ = do tc1 <- lookupOcc n
-                       repPromotedTyCon tc1
-  | otherwise     = do tc1 <- lookupOcc n
-                       repNamedTyCon tc1
-  where
-    occ = nameOccName n
-
-repTy (HsAppTy f a)         = do
-                                f1 <- repLTy f
-                                a1 <- repLTy a
-                                repTapp f1 a1
-repTy (HsFunTy f a)         = do
-                                f1   <- repLTy f
-                                a1   <- repLTy a
-                                tcon <- repArrowTyCon
-                                repTapps tcon [f1, a1]
-repTy (HsListTy t)          = do
-                                t1   <- repLTy t
-                                tcon <- repListTyCon
-                                repTapp tcon t1
-repTy (HsPArrTy t)          = do
-                                t1   <- repLTy t
-                                tcon <- repTy (HsTyVar (tyConName parrTyCon))
-                                repTapp tcon t1
-repTy (HsTupleTy HsUnboxedTuple tys) = do
-                                tys1 <- repLTys tys
-                                tcon <- repUnboxedTupleTyCon (length tys)
-                                repTapps tcon tys1
-repTy (HsTupleTy _ tys)     = do tys1 <- repLTys tys
-                                 tcon <- repTupleTyCon (length tys)
-                                 repTapps tcon tys1
-repTy (HsOpTy ty1 (_, n) ty2) = repLTy ((nlHsTyVar (unLoc n) `nlHsAppTy` ty1)
-                                   `nlHsAppTy` ty2)
-repTy (HsParTy t)           = repLTy t
-repTy (HsEqTy t1 t2) = do
-                         t1' <- repLTy t1
-                         t2' <- repLTy t2
-                         eq  <- repTequality
-                         repTapps eq [t1', t2']
-repTy (HsKindSig t k)       = do
-                                t1 <- repLTy t
-                                k1 <- repLKind k
-                                repTSig t1 k1
-repTy (HsSpliceTy splice _)     = repSplice splice
-repTy (HsExplicitListTy _ tys)  = do
-                                    tys1 <- repLTys tys
-                                    repTPromotedList tys1
-repTy (HsExplicitTupleTy _ tys) = do
-                                    tys1 <- repLTys tys
-                                    tcon <- repPromotedTupleTyCon (length tys)
-                                    repTapps tcon tys1
-repTy (HsTyLit lit) = do
-                        lit' <- repTyLit lit
-                        repTLit lit'
-
-repTy ty                      = notHandled "Exotic form of type" (ppr ty)
-
-repTyLit :: HsTyLit -> DsM (Core TH.TyLitQ)
-repTyLit (HsNumTy _ i) = do iExpr <- mkIntegerExpr i
-                            rep2 numTyLitName [iExpr]
-repTyLit (HsStrTy _ s) = do { s' <- mkStringExprFS s
-                            ; rep2 strTyLitName [s']
-                            }
-
--- represent a kind
---
-repLKind :: LHsKind Name -> DsM (Core TH.Kind)
-repLKind ki
-  = do { let (kis, ki') = splitHsFunType ki
-       ; kis_rep <- mapM repLKind kis
-       ; ki'_rep <- repNonArrowLKind ki'
-       ; kcon <- repKArrow
-       ; let f k1 k2 = repKApp kcon k1 >>= flip repKApp k2
-       ; foldrM f ki'_rep kis_rep
-       }
-
-repNonArrowLKind :: LHsKind Name -> DsM (Core TH.Kind)
-repNonArrowLKind (L _ ki) = repNonArrowKind ki
-
-repNonArrowKind :: HsKind Name -> DsM (Core TH.Kind)
-repNonArrowKind (HsTyVar name)
-  | name == liftedTypeKindTyConName = repKStar
-  | name == constraintKindTyConName = repKConstraint
-  | isTvOcc (nameOccName name)      = lookupOcc name >>= repKVar
-  | otherwise                       = lookupOcc name >>= repKCon
-repNonArrowKind (HsAppTy f a)       = do  { f' <- repLKind f
-                                          ; a' <- repLKind a
-                                          ; repKApp f' a'
-                                          }
-repNonArrowKind (HsListTy k)        = do  { k' <- repLKind k
-                                          ; kcon <- repKList
-                                          ; repKApp kcon k'
-                                          }
-repNonArrowKind (HsTupleTy _ ks)    = do  { ks' <- mapM repLKind ks
-                                          ; kcon <- repKTuple (length ks)
-                                          ; repKApps kcon ks'
-                                          }
-repNonArrowKind k                   = notHandled "Exotic form of kind" (ppr k)
-
-repRole :: Located (Maybe Role) -> DsM (Core TH.Role)
-repRole (L _ (Just Nominal))          = rep2 nominalRName []
-repRole (L _ (Just Representational)) = rep2 representationalRName []
-repRole (L _ (Just Phantom))          = rep2 phantomRName []
-repRole (L _ Nothing)                 = rep2 inferRName []
-
------------------------------------------------------------------------------
---              Splices
------------------------------------------------------------------------------
-
-repSplice :: HsSplice Name -> DsM (Core a)
--- See Note [How brackets and nested splices are handled] in TcSplice
--- We return a CoreExpr of any old type; the context should know
-repSplice (HsSplice n _)
- = do { mb_val <- dsLookupMetaEnv n
-       ; case mb_val of
-           Just (DsSplice e) -> do { e' <- dsExpr e
-                                   ; return (MkC e') }
-           _ -> pprPanic "HsSplice" (ppr n) }
-                        -- Should not happen; statically checked
-
------------------------------------------------------------------------------
---              Expressions
------------------------------------------------------------------------------
-
-repLEs :: [LHsExpr Name] -> DsM (Core [TH.ExpQ])
-repLEs es = repList expQTyConName repLE es
-
--- FIXME: some of these panics should be converted into proper error messages
---        unless we can make sure that constructs, which are plainly not
---        supported in TH already lead to error messages at an earlier stage
-repLE :: LHsExpr Name -> DsM (Core TH.ExpQ)
-repLE (L loc e) = putSrcSpanDs loc (repE e)
-
-repE :: HsExpr Name -> DsM (Core TH.ExpQ)
-repE (HsVar x)            =
-  do { mb_val <- dsLookupMetaEnv x
-     ; case mb_val of
-        Nothing          -> do { str <- globalVar x
-                               ; repVarOrCon x str }
-        Just (DsBound y)   -> repVarOrCon x (coreVar y)
-        Just (DsSplice e)  -> do { e' <- dsExpr e
-                               ; return (MkC e') } }
-repE e@(HsIPVar _) = notHandled "Implicit parameters" (ppr e)
-
-        -- Remember, we're desugaring renamer output here, so
-        -- HsOverlit can definitely occur
-repE (HsOverLit l) = do { a <- repOverloadedLiteral l; repLit a }
-repE (HsLit l)     = do { a <- repLiteral l;           repLit a }
-repE (HsLam (MG { mg_alts = [m] })) = repLambda m
-repE (HsLamCase _ (MG { mg_alts = ms }))
-                   = do { ms' <- mapM repMatchTup ms
-                        ; core_ms <- coreList matchQTyConName ms'
-                        ; repLamCase core_ms }
-repE (HsApp x y)   = do {a <- repLE x; b <- repLE y; repApp a b}
-
-repE (OpApp e1 op _ e2) =
-  do { arg1 <- repLE e1;
-       arg2 <- repLE e2;
-       the_op <- repLE op ;
-       repInfixApp arg1 the_op arg2 }
-repE (NegApp x _)        = do
-                              a         <- repLE x
-                              negateVar <- lookupOcc negateName >>= repVar
-                              negateVar `repApp` a
-repE (HsPar x)            = repLE x
-repE (SectionL x y)       = do { a <- repLE x; b <- repLE y; repSectionL a b }
-repE (SectionR x y)       = do { a <- repLE x; b <- repLE y; repSectionR a b }
-repE (HsCase e (MG { mg_alts = ms }))
-                          = do { arg <- repLE e
-                               ; ms2 <- mapM repMatchTup ms
-                               ; core_ms2 <- coreList matchQTyConName ms2
-                               ; repCaseE arg core_ms2 }
-repE (HsIf _ x y z)         = do
-                              a <- repLE x
-                              b <- repLE y
-                              c <- repLE z
-                              repCond a b c
-repE (HsMultiIf _ alts)
-  = do { (binds, alts') <- liftM unzip $ mapM repLGRHS alts
-       ; expr' <- repMultiIf (nonEmptyCoreList alts')
-       ; wrapGenSyms (concat binds) expr' }
-repE (HsLet bs e)         = do { (ss,ds) <- repBinds bs
-                               ; e2 <- addBinds ss (repLE e)
-                               ; z <- repLetE ds e2
-                               ; wrapGenSyms ss z }
-
--- FIXME: I haven't got the types here right yet
-repE e@(HsDo ctxt sts _)
- | case ctxt of { DoExpr -> True; GhciStmtCtxt -> True; _ -> False }
- = do { (ss,zs) <- repLSts sts;
-        e'      <- repDoE (nonEmptyCoreList zs);
-        wrapGenSyms ss e' }
-
- | ListComp <- ctxt
- = do { (ss,zs) <- repLSts sts;
-        e'      <- repComp (nonEmptyCoreList zs);
-        wrapGenSyms ss e' }
-
-  | otherwise
-  = notHandled "mdo, monad comprehension and [: :]" (ppr e)
-
-repE (ExplicitList _ _ es) = do { xs <- repLEs es; repListExp xs }
-repE e@(ExplicitPArr _ _) = notHandled "Parallel arrays" (ppr e)
-repE e@(ExplicitTuple es boxed)
-  | not (all tupArgPresent es) = notHandled "Tuple sections" (ppr e)
-  | isBoxed boxed  = do { xs <- repLEs [e | L _ (Present e) <- es]; repTup xs }
-  | otherwise      = do { xs <- repLEs [e | L _ (Present e) <- es]
-                        ; repUnboxedTup xs }
-
-repE (RecordCon c _ flds)
- = do { x <- lookupLOcc c;
-        fs <- repFields flds;
-        repRecCon x fs }
-repE (RecordUpd e flds _ _ _)
- = do { x <- repLE e;
-        fs <- repFields flds;
-        repRecUpd x fs }
-
-repE (ExprWithTySig e ty _) = do { e1 <- repLE e; t1 <- repLTy ty; repSigExp e1 t1 }
-repE (ArithSeq _ _ aseq) =
-  case aseq of
-    From e              -> do { ds1 <- repLE e; repFrom ds1 }
-    FromThen e1 e2      -> do
-                             ds1 <- repLE e1
-                             ds2 <- repLE e2
-                             repFromThen ds1 ds2
-    FromTo   e1 e2      -> do
-                             ds1 <- repLE e1
-                             ds2 <- repLE e2
-                             repFromTo ds1 ds2
-    FromThenTo e1 e2 e3 -> do
-                             ds1 <- repLE e1
-                             ds2 <- repLE e2
-                             ds3 <- repLE e3
-                             repFromThenTo ds1 ds2 ds3
-
-repE (HsSpliceE _ splice)  = repSplice splice
-repE (HsStatic e)          = repLE e >>= rep2 staticEName . (:[]) . unC
-repE e@(PArrSeq {})        = notHandled "Parallel arrays" (ppr e)
-repE e@(HsCoreAnn {})      = notHandled "Core annotations" (ppr e)
-repE e@(HsSCC {})          = notHandled "Cost centres" (ppr e)
-repE e@(HsTickPragma {})   = notHandled "Tick Pragma" (ppr e)
-repE e@(HsTcBracketOut {}) = notHandled "TH brackets" (ppr e)
-repE e                     = notHandled "Expression form" (ppr e)
-
------------------------------------------------------------------------------
--- Building representations of auxillary structures like Match, Clause, Stmt,
-
-repMatchTup ::  LMatch Name (LHsExpr Name) -> DsM (Core TH.MatchQ)
-repMatchTup (L _ (Match _ [p] _ (GRHSs guards wheres))) =
-  do { ss1 <- mkGenSyms (collectPatBinders p)
-     ; addBinds ss1 $ do {
-     ; p1 <- repLP p
-     ; (ss2,ds) <- repBinds wheres
-     ; addBinds ss2 $ do {
-     ; gs    <- repGuards guards
-     ; match <- repMatch p1 gs ds
-     ; wrapGenSyms (ss1++ss2) match }}}
-repMatchTup _ = panic "repMatchTup: case alt with more than one arg"
-
-repClauseTup ::  LMatch Name (LHsExpr Name) -> DsM (Core TH.ClauseQ)
-repClauseTup (L _ (Match _ ps _ (GRHSs guards wheres))) =
-  do { ss1 <- mkGenSyms (collectPatsBinders ps)
-     ; addBinds ss1 $ do {
-       ps1 <- repLPs ps
-     ; (ss2,ds) <- repBinds wheres
-     ; addBinds ss2 $ do {
-       gs <- repGuards guards
-     ; clause <- repClause ps1 gs ds
-     ; wrapGenSyms (ss1++ss2) clause }}}
-
-repGuards ::  [LGRHS Name (LHsExpr Name)] ->  DsM (Core TH.BodyQ)
-repGuards [L _ (GRHS [] e)]
-  = do {a <- repLE e; repNormal a }
-repGuards other
-  = do { zs <- mapM repLGRHS other
-       ; let (xs, ys) = unzip zs
-       ; gd <- repGuarded (nonEmptyCoreList ys)
-       ; wrapGenSyms (concat xs) gd }
-
-repLGRHS :: LGRHS Name (LHsExpr Name) -> DsM ([GenSymBind], (Core (TH.Q (TH.Guard, TH.Exp))))
-repLGRHS (L _ (GRHS [L _ (BodyStmt e1 _ _ _)] e2))
-  = do { guarded <- repLNormalGE e1 e2
-       ; return ([], guarded) }
-repLGRHS (L _ (GRHS ss rhs))
-  = do { (gs, ss') <- repLSts ss
-       ; rhs' <- addBinds gs $ repLE rhs
-       ; guarded <- repPatGE (nonEmptyCoreList ss') rhs'
-       ; return (gs, guarded) }
-
-repFields :: HsRecordBinds Name -> DsM (Core [TH.Q TH.FieldExp])
-repFields (HsRecFields { rec_flds = flds })
-  = repList fieldExpQTyConName rep_fld flds
-  where
-    rep_fld (L _ fld) = do { fn <- lookupLOcc (hsRecFieldId fld)
-                           ; e  <- repLE (hsRecFieldArg fld)
-                           ; repFieldExp fn e }
-
-
------------------------------------------------------------------------------
--- Representing Stmt's is tricky, especially if bound variables
--- shadow each other. Consider:  [| do { x <- f 1; x <- f x; g x } |]
--- First gensym new names for every variable in any of the patterns.
--- both static (x'1 and x'2), and dynamic ((gensym "x") and (gensym "y"))
--- if variables didn't shaddow, the static gensym wouldn't be necessary
--- and we could reuse the original names (x and x).
---
--- do { x'1 <- gensym "x"
---    ; x'2 <- gensym "x"
---    ; doE [ BindSt (pvar x'1) [| f 1 |]
---          , BindSt (pvar x'2) [| f x |]
---          , NoBindSt [| g x |]
---          ]
---    }
-
--- The strategy is to translate a whole list of do-bindings by building a
--- bigger environment, and a bigger set of meta bindings
--- (like:  x'1 <- gensym "x" ) and then combining these with the translations
--- of the expressions within the Do
-
------------------------------------------------------------------------------
--- The helper function repSts computes the translation of each sub expression
--- and a bunch of prefix bindings denoting the dynamic renaming.
-
-repLSts :: [LStmt Name (LHsExpr Name)] -> DsM ([GenSymBind], [Core TH.StmtQ])
-repLSts stmts = repSts (map unLoc stmts)
-
-repSts :: [Stmt Name (LHsExpr Name)] -> DsM ([GenSymBind], [Core TH.StmtQ])
-repSts (BindStmt p e _ _ : ss) =
-   do { e2 <- repLE e
-      ; ss1 <- mkGenSyms (collectPatBinders p)
-      ; addBinds ss1 $ do {
-      ; p1 <- repLP p;
-      ; (ss2,zs) <- repSts ss
-      ; z <- repBindSt p1 e2
-      ; return (ss1++ss2, z : zs) }}
-repSts (LetStmt bs : ss) =
-   do { (ss1,ds) <- repBinds bs
-      ; z <- repLetSt ds
-      ; (ss2,zs) <- addBinds ss1 (repSts ss)
-      ; return (ss1++ss2, z : zs) }
-repSts (BodyStmt e _ _ _ : ss) =
-   do { e2 <- repLE e
-      ; z <- repNoBindSt e2
-      ; (ss2,zs) <- repSts ss
-      ; return (ss2, z : zs) }
-repSts (ParStmt stmt_blocks _ _ : ss) =
-   do { (ss_s, stmt_blocks1) <- mapAndUnzipM rep_stmt_block stmt_blocks
-      ; let stmt_blocks2 = nonEmptyCoreList stmt_blocks1
-            ss1 = concat ss_s
-      ; z <- repParSt stmt_blocks2
-      ; (ss2, zs) <- addBinds ss1 (repSts ss)
-      ; return (ss1++ss2, z : zs) }
-   where
-     rep_stmt_block :: ParStmtBlock Name Name -> DsM ([GenSymBind], Core [TH.StmtQ])
-     rep_stmt_block (ParStmtBlock stmts _ _) =
-       do { (ss1, zs) <- repSts (map unLoc stmts)
-          ; zs1 <- coreList stmtQTyConName zs
-          ; return (ss1, zs1) }
-repSts [LastStmt e _]
-  = do { e2 <- repLE e
-       ; z <- repNoBindSt e2
-       ; return ([], [z]) }
-repSts []    = return ([],[])
-repSts other = notHandled "Exotic statement" (ppr other)
-
-
------------------------------------------------------------
---                      Bindings
------------------------------------------------------------
-
-repBinds :: HsLocalBinds Name -> DsM ([GenSymBind], Core [TH.DecQ])
-repBinds EmptyLocalBinds
-  = do  { core_list <- coreList decQTyConName []
-        ; return ([], core_list) }
-
-repBinds b@(HsIPBinds _) = notHandled "Implicit parameters" (ppr b)
-
-repBinds (HsValBinds decs)
- = do   { let { bndrs = hsSigTvBinders decs ++ collectHsValBinders decs }
-                -- No need to worrry about detailed scopes within
-                -- the binding group, because we are talking Names
-                -- here, so we can safely treat it as a mutually
-                -- recursive group
-                -- For hsSigTvBinders see Note [Scoped type variables in bindings]
-        ; ss        <- mkGenSyms bndrs
-        ; prs       <- addBinds ss (rep_val_binds decs)
-        ; core_list <- coreList decQTyConName
-                                (de_loc (sort_by_loc prs))
-        ; return (ss, core_list) }
-
-rep_val_binds :: HsValBinds Name -> DsM [(SrcSpan, Core TH.DecQ)]
--- Assumes: all the binders of the binding are alrady in the meta-env
-rep_val_binds (ValBindsOut binds sigs)
- = do { core1 <- rep_binds' (unionManyBags (map snd binds))
-      ; core2 <- rep_sigs' sigs
-      ; return (core1 ++ core2) }
-rep_val_binds (ValBindsIn _ _)
- = panic "rep_val_binds: ValBindsIn"
-
-rep_binds :: LHsBinds Name -> DsM [Core TH.DecQ]
-rep_binds binds = do { binds_w_locs <- rep_binds' binds
-                     ; return (de_loc (sort_by_loc binds_w_locs)) }
-
-rep_binds' :: LHsBinds Name -> DsM [(SrcSpan, Core TH.DecQ)]
-rep_binds' = mapM rep_bind . bagToList
-
-rep_bind :: LHsBind Name -> DsM (SrcSpan, Core TH.DecQ)
--- Assumes: all the binders of the binding are alrady in the meta-env
-
--- Note GHC treats declarations of a variable (not a pattern)
--- e.g.  x = g 5 as a Fun MonoBinds. This is indicated by a single match
--- with an empty list of patterns
-rep_bind (L loc (FunBind
-                 { fun_id = fn,
-                   fun_matches = MG { mg_alts = [L _ (Match _ [] _
-                                                   (GRHSs guards wheres))] } }))
- = do { (ss,wherecore) <- repBinds wheres
-        ; guardcore <- addBinds ss (repGuards guards)
-        ; fn'  <- lookupLBinder fn
-        ; p    <- repPvar fn'
-        ; ans  <- repVal p guardcore wherecore
-        ; ans' <- wrapGenSyms ss ans
-        ; return (loc, ans') }
-
-rep_bind (L loc (FunBind { fun_id = fn, fun_matches = MG { mg_alts = ms } }))
- =   do { ms1 <- mapM repClauseTup ms
-        ; fn' <- lookupLBinder fn
-        ; ans <- repFun fn' (nonEmptyCoreList ms1)
-        ; return (loc, ans) }
-
-rep_bind (L loc (PatBind { pat_lhs = pat, pat_rhs = GRHSs guards wheres }))
- =   do { patcore <- repLP pat
-        ; (ss,wherecore) <- repBinds wheres
-        ; guardcore <- addBinds ss (repGuards guards)
-        ; ans  <- repVal patcore guardcore wherecore
-        ; ans' <- wrapGenSyms ss ans
-        ; return (loc, ans') }
-
-rep_bind (L _ (VarBind { var_id = v, var_rhs = e}))
- =   do { v' <- lookupBinder v
-        ; e2 <- repLE e
-        ; x <- repNormal e2
-        ; patcore <- repPvar v'
-        ; empty_decls <- coreList decQTyConName []
-        ; ans <- repVal patcore x empty_decls
-        ; return (srcLocSpan (getSrcLoc v), ans) }
-
-rep_bind (L _ (AbsBinds {}))  = panic "rep_bind: AbsBinds"
-rep_bind (L _ dec@(PatSynBind {})) = notHandled "pattern synonyms" (ppr dec)
------------------------------------------------------------------------------
--- Since everything in a Bind is mutually recursive we need rename all
--- all the variables simultaneously. For example:
--- [| AndMonoBinds (f x = x + g 2) (g x = f 1 + 2) |] would translate to
--- do { f'1 <- gensym "f"
---    ; g'2 <- gensym "g"
---    ; [ do { x'3 <- gensym "x"; fun f'1 [pvar x'3] [| x + g2 |]},
---        do { x'4 <- gensym "x"; fun g'2 [pvar x'4] [| f 1 + 2 |]}
---      ]}
--- This requires collecting the bindings (f'1 <- gensym "f"), and the
--- environment ( f |-> f'1 ) from each binding, and then unioning them
--- together. As we do this we collect GenSymBinds's which represent the renamed
--- variables bound by the Bindings. In order not to lose track of these
--- representations we build a shadow datatype MB with the same structure as
--- MonoBinds, but which has slots for the representations
-
-
------------------------------------------------------------------------------
--- GHC allows a more general form of lambda abstraction than specified
--- by Haskell 98. In particular it allows guarded lambda's like :
--- (\  x | even x -> 0 | odd x -> 1) at the moment we can't represent this in
--- Haskell Template's Meta.Exp type so we punt if it isn't a simple thing like
--- (\ p1 .. pn -> exp) by causing an error.
-
-repLambda :: LMatch Name (LHsExpr Name) -> DsM (Core TH.ExpQ)
-repLambda (L _ (Match _ ps _ (GRHSs [L _ (GRHS [] e)] EmptyLocalBinds)))
- = do { let bndrs = collectPatsBinders ps ;
-      ; ss  <- mkGenSyms bndrs
-      ; lam <- addBinds ss (
-                do { xs <- repLPs ps; body <- repLE e; repLam xs body })
-      ; wrapGenSyms ss lam }
-
-repLambda (L _ m) = notHandled "Guarded labmdas" (pprMatch (LambdaExpr :: HsMatchContext Name) m)
-
-
------------------------------------------------------------------------------
---                      Patterns
--- repP deals with patterns.  It assumes that we have already
--- walked over the pattern(s) once to collect the binders, and
--- have extended the environment.  So every pattern-bound
--- variable should already appear in the environment.
-
--- Process a list of patterns
-repLPs :: [LPat Name] -> DsM (Core [TH.PatQ])
-repLPs ps = repList patQTyConName repLP ps
-
-repLP :: LPat Name -> DsM (Core TH.PatQ)
-repLP (L _ p) = repP p
-
-repP :: Pat Name -> DsM (Core TH.PatQ)
-repP (WildPat _)       = repPwild
-repP (LitPat l)        = do { l2 <- repLiteral l; repPlit l2 }
-repP (VarPat x)        = do { x' <- lookupBinder x; repPvar x' }
-repP (LazyPat p)       = do { p1 <- repLP p; repPtilde p1 }
-repP (BangPat p)       = do { p1 <- repLP p; repPbang p1 }
-repP (AsPat x p)       = do { x' <- lookupLBinder x; p1 <- repLP p; repPaspat x' p1 }
-repP (ParPat p)        = repLP p
-repP (ListPat ps _ Nothing)    = do { qs <- repLPs ps; repPlist qs }
-repP (ListPat ps ty1 (Just (_,e))) = do { p <- repP (ListPat ps ty1 Nothing); e' <- repE e; repPview e' p}
-repP (TuplePat ps boxed _)
-  | isBoxed boxed       = do { qs <- repLPs ps; repPtup qs }
-  | otherwise           = do { qs <- repLPs ps; repPunboxedTup qs }
-repP (ConPatIn dc details)
- = do { con_str <- lookupLOcc dc
-      ; case details of
-         PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs }
-         RecCon rec   -> do { fps <- repList fieldPatQTyConName rep_fld (rec_flds rec)
-                            ; repPrec con_str fps }
-         InfixCon p1 p2 -> do { p1' <- repLP p1;
-                                p2' <- repLP p2;
-                                repPinfix p1' con_str p2' }
-   }
- where
-   rep_fld (L _ fld) = do { MkC v <- lookupLOcc (hsRecFieldId fld)
-                          ; MkC p <- repLP (hsRecFieldArg fld)
-                          ; rep2 fieldPatName [v,p] }
-
-repP (NPat (L _ l) Nothing _)  = do { a <- repOverloadedLiteral l; repPlit a }
-repP (ViewPat e p _) = do { e' <- repLE e; p' <- repLP p; repPview e' p' }
-repP p@(NPat _ (Just _) _) = notHandled "Negative overloaded patterns" (ppr p)
-repP p@(SigPatIn {})  = notHandled "Type signatures in patterns" (ppr p)
-        -- The problem is to do with scoped type variables.
-        -- To implement them, we have to implement the scoping rules
-        -- here in DsMeta, and I don't want to do that today!
-        --       do { p' <- repLP p; t' <- repLTy t; repPsig p' t' }
-        --      repPsig :: Core TH.PatQ -> Core TH.TypeQ -> DsM (Core TH.PatQ)
-        --      repPsig (MkC p) (MkC t) = rep2 sigPName [p, t]
-
-repP (SplicePat splice) = repSplice splice
-
-repP other = notHandled "Exotic pattern" (ppr other)
-
-----------------------------------------------------------
--- Declaration ordering helpers
-
-sort_by_loc :: [(SrcSpan, a)] -> [(SrcSpan, a)]
-sort_by_loc xs = sortBy comp xs
-    where comp x y = compare (fst x) (fst y)
-
-de_loc :: [(a, b)] -> [b]
-de_loc = map snd
-
-----------------------------------------------------------
---      The meta-environment
-
--- A name/identifier association for fresh names of locally bound entities
-type GenSymBind = (Name, Id)    -- Gensym the string and bind it to the Id
-                                -- I.e.         (x, x_id) means
-                                --      let x_id = gensym "x" in ...
-
--- Generate a fresh name for a locally bound entity
-
-mkGenSyms :: [Name] -> DsM [GenSymBind]
--- We can use the existing name.  For example:
---      [| \x_77 -> x_77 + x_77 |]
--- desugars to
---      do { x_77 <- genSym "x"; .... }
--- We use the same x_77 in the desugared program, but with the type Bndr
--- instead of Int
---
--- We do make it an Internal name, though (hence localiseName)
---
--- Nevertheless, it's monadic because we have to generate nameTy
-mkGenSyms ns = do { var_ty <- lookupType nameTyConName
-                  ; return [(nm, mkLocalId (localiseName nm) var_ty) | nm <- ns] }
-
-
-addBinds :: [GenSymBind] -> DsM a -> DsM a
--- Add a list of fresh names for locally bound entities to the
--- meta environment (which is part of the state carried around
--- by the desugarer monad)
-addBinds bs m = dsExtendMetaEnv (mkNameEnv [(n,DsBound id) | (n,id) <- bs]) m
-
-dupBinder :: (Name, Name) -> DsM (Name, DsMetaVal)
-dupBinder (new, old)
-  = do { mb_val <- dsLookupMetaEnv old
-       ; case mb_val of
-           Just val -> return (new, val)
-           Nothing  -> pprPanic "dupBinder" (ppr old) }
-
--- Look up a locally bound name
---
-lookupLBinder :: Located Name -> DsM (Core TH.Name)
-lookupLBinder (L _ n) = lookupBinder n
-
-lookupBinder :: Name -> DsM (Core TH.Name)
-lookupBinder = lookupOcc
-  -- Binders are brought into scope before the pattern or what-not is
-  -- desugared.  Moreover, in instance declaration the binder of a method
-  -- will be the selector Id and hence a global; so we need the
-  -- globalVar case of lookupOcc
-
--- Look up a name that is either locally bound or a global name
---
---  * If it is a global name, generate the "original name" representation (ie,
---   the <module>:<name> form) for the associated entity
---
-lookupLOcc :: Located Name -> DsM (Core TH.Name)
--- Lookup an occurrence; it can't be a splice.
--- Use the in-scope bindings if they exist
-lookupLOcc (L _ n) = lookupOcc n
-
-lookupOcc :: Name -> DsM (Core TH.Name)
-lookupOcc n
-  = do {  mb_val <- dsLookupMetaEnv n ;
-          case mb_val of
-                Nothing           -> globalVar n
-                Just (DsBound x)  -> return (coreVar x)
-                Just (DsSplice _) -> pprPanic "repE:lookupOcc" (ppr n)
-    }
-
-globalVar :: Name -> DsM (Core TH.Name)
--- Not bound by the meta-env
--- Could be top-level; or could be local
---      f x = $(g [| x |])
--- Here the x will be local
-globalVar name
-  | isExternalName name
-  = do  { MkC mod <- coreStringLit name_mod
-        ; MkC pkg <- coreStringLit name_pkg
-        ; MkC occ <- occNameLit name
-        ; rep2 mk_varg [pkg,mod,occ] }
-  | otherwise
-  = do  { MkC occ <- occNameLit name
-        ; MkC uni <- coreIntLit (getKey (getUnique name))
-        ; rep2 mkNameLName [occ,uni] }
-  where
-      mod = {- ASSERT( isExternalName name) -} nameModule name
-      name_mod = moduleNameString (moduleName mod)
-      name_pkg = packageKeyString (modulePackageKey mod)
-      name_occ = nameOccName name
-      mk_varg | OccName.isDataOcc name_occ = mkNameG_dName
-              | OccName.isVarOcc  name_occ = mkNameG_vName
-              | OccName.isTcOcc   name_occ = mkNameG_tcName
-              | otherwise                  = pprPanic "DsMeta.globalVar" (ppr name)
-
-lookupType :: Name      -- Name of type constructor (e.g. TH.ExpQ)
-           -> DsM Type  -- The type
-lookupType tc_name = do { tc <- dsLookupTyCon tc_name ;
-                          return (mkTyConApp tc []) }
-
-wrapGenSyms :: [GenSymBind]
-            -> Core (TH.Q a) -> DsM (Core (TH.Q a))
--- wrapGenSyms [(nm1,id1), (nm2,id2)] y
---      --> bindQ (gensym nm1) (\ id1 ->
---          bindQ (gensym nm2 (\ id2 ->
---          y))
-
-wrapGenSyms binds body@(MkC b)
-  = do  { var_ty <- lookupType nameTyConName
-        ; go var_ty binds }
-  where
-    [elt_ty] = tcTyConAppArgs (exprType b)
-        -- b :: Q a, so we can get the type 'a' by looking at the
-        -- argument type. NB: this relies on Q being a data/newtype,
-        -- not a type synonym
-
-    go _ [] = return body
-    go var_ty ((name,id) : binds)
-      = do { MkC body'  <- go var_ty binds
-           ; lit_str    <- occNameLit name
-           ; gensym_app <- repGensym lit_str
-           ; repBindQ var_ty elt_ty
-                      gensym_app (MkC (Lam id body')) }
-
-occNameLit :: Name -> DsM (Core String)
-occNameLit n = coreStringLit (occNameString (nameOccName n))
-
-
--- %*********************************************************************
--- %*                                                                   *
---              Constructing code
--- %*                                                                   *
--- %*********************************************************************
-
------------------------------------------------------------------------------
--- PHANTOM TYPES for consistency. In order to make sure we do this correct
--- we invent a new datatype which uses phantom types.
-
-newtype Core a = MkC CoreExpr
-unC :: Core a -> CoreExpr
-unC (MkC x) = x
-
-rep2 :: Name -> [ CoreExpr ] -> DsM (Core a)
-rep2 n xs = do { id <- dsLookupGlobalId n
-               ; return (MkC (foldl App (Var id) xs)) }
-
-dataCon' :: Name -> [CoreExpr] -> DsM (Core a)
-dataCon' n args = do { id <- dsLookupDataCon n
-                     ; return $ MkC $ mkConApp id args }
-
-dataCon :: Name -> DsM (Core a)
-dataCon n = dataCon' n []
-
--- Then we make "repConstructors" which use the phantom types for each of the
--- smart constructors of the Meta.Meta datatypes.
-
-
--- %*********************************************************************
--- %*                                                                   *
---              The 'smart constructors'
--- %*                                                                   *
--- %*********************************************************************
-
---------------- Patterns -----------------
-repPlit   :: Core TH.Lit -> DsM (Core TH.PatQ)
-repPlit (MkC l) = rep2 litPName [l]
-
-repPvar :: Core TH.Name -> DsM (Core TH.PatQ)
-repPvar (MkC s) = rep2 varPName [s]
-
-repPtup :: Core [TH.PatQ] -> DsM (Core TH.PatQ)
-repPtup (MkC ps) = rep2 tupPName [ps]
-
-repPunboxedTup :: Core [TH.PatQ] -> DsM (Core TH.PatQ)
-repPunboxedTup (MkC ps) = rep2 unboxedTupPName [ps]
-
-repPcon   :: Core TH.Name -> Core [TH.PatQ] -> DsM (Core TH.PatQ)
-repPcon (MkC s) (MkC ps) = rep2 conPName [s, ps]
-
-repPrec   :: Core TH.Name -> Core [(TH.Name,TH.PatQ)] -> DsM (Core TH.PatQ)
-repPrec (MkC c) (MkC rps) = rep2 recPName [c,rps]
-
-repPinfix :: Core TH.PatQ -> Core TH.Name -> Core TH.PatQ -> DsM (Core TH.PatQ)
-repPinfix (MkC p1) (MkC n) (MkC p2) = rep2 infixPName [p1, n, p2]
-
-repPtilde :: Core TH.PatQ -> DsM (Core TH.PatQ)
-repPtilde (MkC p) = rep2 tildePName [p]
-
-repPbang :: Core TH.PatQ -> DsM (Core TH.PatQ)
-repPbang (MkC p) = rep2 bangPName [p]
-
-repPaspat :: Core TH.Name -> Core TH.PatQ -> DsM (Core TH.PatQ)
-repPaspat (MkC s) (MkC p) = rep2 asPName [s, p]
-
-repPwild  :: DsM (Core TH.PatQ)
-repPwild = rep2 wildPName []
-
-repPlist :: Core [TH.PatQ] -> DsM (Core TH.PatQ)
-repPlist (MkC ps) = rep2 listPName [ps]
-
-repPview :: Core TH.ExpQ -> Core TH.PatQ -> DsM (Core TH.PatQ)
-repPview (MkC e) (MkC p) = rep2 viewPName [e,p]
-
---------------- Expressions -----------------
-repVarOrCon :: Name -> Core TH.Name -> DsM (Core TH.ExpQ)
-repVarOrCon vc str | isDataOcc (nameOccName vc) = repCon str
-                   | otherwise                  = repVar str
-
-repVar :: Core TH.Name -> DsM (Core TH.ExpQ)
-repVar (MkC s) = rep2 varEName [s]
-
-repCon :: Core TH.Name -> DsM (Core TH.ExpQ)
-repCon (MkC s) = rep2 conEName [s]
-
-repLit :: Core TH.Lit -> DsM (Core TH.ExpQ)
-repLit (MkC c) = rep2 litEName [c]
-
-repApp :: Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repApp (MkC x) (MkC y) = rep2 appEName [x,y]
-
-repLam :: Core [TH.PatQ] -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repLam (MkC ps) (MkC e) = rep2 lamEName [ps, e]
-
-repLamCase :: Core [TH.MatchQ] -> DsM (Core TH.ExpQ)
-repLamCase (MkC ms) = rep2 lamCaseEName [ms]
-
-repTup :: Core [TH.ExpQ] -> DsM (Core TH.ExpQ)
-repTup (MkC es) = rep2 tupEName [es]
-
-repUnboxedTup :: Core [TH.ExpQ] -> DsM (Core TH.ExpQ)
-repUnboxedTup (MkC es) = rep2 unboxedTupEName [es]
-
-repCond :: Core TH.ExpQ -> Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repCond (MkC x) (MkC y) (MkC z) = rep2 condEName [x,y,z]
-
-repMultiIf :: Core [TH.Q (TH.Guard, TH.Exp)] -> DsM (Core TH.ExpQ)
-repMultiIf (MkC alts) = rep2 multiIfEName [alts]
-
-repLetE :: Core [TH.DecQ] -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repLetE (MkC ds) (MkC e) = rep2 letEName [ds, e]
-
-repCaseE :: Core TH.ExpQ -> Core [TH.MatchQ] -> DsM( Core TH.ExpQ)
-repCaseE (MkC e) (MkC ms) = rep2 caseEName [e, ms]
-
-repDoE :: Core [TH.StmtQ] -> DsM (Core TH.ExpQ)
-repDoE (MkC ss) = rep2 doEName [ss]
-
-repComp :: Core [TH.StmtQ] -> DsM (Core TH.ExpQ)
-repComp (MkC ss) = rep2 compEName [ss]
-
-repListExp :: Core [TH.ExpQ] -> DsM (Core TH.ExpQ)
-repListExp (MkC es) = rep2 listEName [es]
-
-repSigExp :: Core TH.ExpQ -> Core TH.TypeQ -> DsM (Core TH.ExpQ)
-repSigExp (MkC e) (MkC t) = rep2 sigEName [e,t]
-
-repRecCon :: Core TH.Name -> Core [TH.Q TH.FieldExp]-> DsM (Core TH.ExpQ)
-repRecCon (MkC c) (MkC fs) = rep2 recConEName [c,fs]
-
-repRecUpd :: Core TH.ExpQ -> Core [TH.Q TH.FieldExp] -> DsM (Core TH.ExpQ)
-repRecUpd (MkC e) (MkC fs) = rep2 recUpdEName [e,fs]
-
-repFieldExp :: Core TH.Name -> Core TH.ExpQ -> DsM (Core (TH.Q TH.FieldExp))
-repFieldExp (MkC n) (MkC x) = rep2 fieldExpName [n,x]
-
-repInfixApp :: Core TH.ExpQ -> Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repInfixApp (MkC x) (MkC y) (MkC z) = rep2 infixAppName [x,y,z]
-
-repSectionL :: Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repSectionL (MkC x) (MkC y) = rep2 sectionLName [x,y]
-
-repSectionR :: Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repSectionR (MkC x) (MkC y) = rep2 sectionRName [x,y]
-
------------- Right hand sides (guarded expressions) ----
-repGuarded :: Core [TH.Q (TH.Guard, TH.Exp)] -> DsM (Core TH.BodyQ)
-repGuarded (MkC pairs) = rep2 guardedBName [pairs]
-
-repNormal :: Core TH.ExpQ -> DsM (Core TH.BodyQ)
-repNormal (MkC e) = rep2 normalBName [e]
-
------------- Guards ----
-repLNormalGE :: LHsExpr Name -> LHsExpr Name -> DsM (Core (TH.Q (TH.Guard, TH.Exp)))
-repLNormalGE g e = do g' <- repLE g
-                      e' <- repLE e
-                      repNormalGE g' e'
-
-repNormalGE :: Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core (TH.Q (TH.Guard, TH.Exp)))
-repNormalGE (MkC g) (MkC e) = rep2 normalGEName [g, e]
-
-repPatGE :: Core [TH.StmtQ] -> Core TH.ExpQ -> DsM (Core (TH.Q (TH.Guard, TH.Exp)))
-repPatGE (MkC ss) (MkC e) = rep2 patGEName [ss, e]
-
-------------- Stmts -------------------
-repBindSt :: Core TH.PatQ -> Core TH.ExpQ -> DsM (Core TH.StmtQ)
-repBindSt (MkC p) (MkC e) = rep2 bindSName [p,e]
-
-repLetSt :: Core [TH.DecQ] -> DsM (Core TH.StmtQ)
-repLetSt (MkC ds) = rep2 letSName [ds]
-
-repNoBindSt :: Core TH.ExpQ -> DsM (Core TH.StmtQ)
-repNoBindSt (MkC e) = rep2 noBindSName [e]
-
-repParSt :: Core [[TH.StmtQ]] -> DsM (Core TH.StmtQ)
-repParSt (MkC sss) = rep2 parSName [sss]
-
--------------- Range (Arithmetic sequences) -----------
-repFrom :: Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repFrom (MkC x) = rep2 fromEName [x]
-
-repFromThen :: Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repFromThen (MkC x) (MkC y) = rep2 fromThenEName [x,y]
-
-repFromTo :: Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repFromTo (MkC x) (MkC y) = rep2 fromToEName [x,y]
-
-repFromThenTo :: Core TH.ExpQ -> Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
-repFromThenTo (MkC x) (MkC y) (MkC z) = rep2 fromThenToEName [x,y,z]
-
------------- Match and Clause Tuples -----------
-repMatch :: Core TH.PatQ -> Core TH.BodyQ -> Core [TH.DecQ] -> DsM (Core TH.MatchQ)
-repMatch (MkC p) (MkC bod) (MkC ds) = rep2 matchName [p, bod, ds]
-
-repClause :: Core [TH.PatQ] -> Core TH.BodyQ -> Core [TH.DecQ] -> DsM (Core TH.ClauseQ)
-repClause (MkC ps) (MkC bod) (MkC ds) = rep2 clauseName [ps, bod, ds]
-
--------------- Dec -----------------------------
-repVal :: Core TH.PatQ -> Core TH.BodyQ -> Core [TH.DecQ] -> DsM (Core TH.DecQ)
-repVal (MkC p) (MkC b) (MkC ds) = rep2 valDName [p, b, ds]
-
-repFun :: Core TH.Name -> Core [TH.ClauseQ] -> DsM (Core TH.DecQ)
-repFun (MkC nm) (MkC b) = rep2 funDName [nm, b]
-
-repData :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndr]
-        -> Maybe (Core [TH.TypeQ])
-        -> Core [TH.ConQ] -> Core [TH.Name] -> DsM (Core TH.DecQ)
-repData (MkC cxt) (MkC nm) (MkC tvs) Nothing (MkC cons) (MkC derivs)
-  = rep2 dataDName [cxt, nm, tvs, cons, derivs]
-repData (MkC cxt) (MkC nm) (MkC _) (Just (MkC tys)) (MkC cons) (MkC derivs)
-  = rep2 dataInstDName [cxt, nm, tys, cons, derivs]
-
-repNewtype :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndr]
-           -> Maybe (Core [TH.TypeQ])
-           -> Core TH.ConQ -> Core [TH.Name] -> DsM (Core TH.DecQ)
-repNewtype (MkC cxt) (MkC nm) (MkC tvs) Nothing (MkC con) (MkC derivs)
-  = rep2 newtypeDName [cxt, nm, tvs, con, derivs]
-repNewtype (MkC cxt) (MkC nm) (MkC _) (Just (MkC tys)) (MkC con) (MkC derivs)
-  = rep2 newtypeInstDName [cxt, nm, tys, con, derivs]
-
-repTySyn :: Core TH.Name -> Core [TH.TyVarBndr]
-         -> Core TH.TypeQ -> DsM (Core TH.DecQ)
-repTySyn (MkC nm) (MkC tvs) (MkC rhs)
-  = rep2 tySynDName [nm, tvs, rhs]
-
-repInst :: Core TH.CxtQ -> Core TH.TypeQ -> Core [TH.DecQ] -> DsM (Core TH.DecQ)
-repInst (MkC cxt) (MkC ty) (MkC ds) = rep2 instanceDName [cxt, ty, ds]
-
-repClass :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndr]
-         -> Core [TH.FunDep] -> Core [TH.DecQ]
-         -> DsM (Core TH.DecQ)
-repClass (MkC cxt) (MkC cls) (MkC tvs) (MkC fds) (MkC ds)
-  = rep2 classDName [cxt, cls, tvs, fds, ds]
-
-repDeriv :: Core TH.CxtQ -> Core TH.TypeQ -> DsM (Core TH.DecQ)
-repDeriv (MkC cxt) (MkC ty) = rep2 standaloneDerivDName [cxt, ty]
-
-repPragInl :: Core TH.Name -> Core TH.Inline -> Core TH.RuleMatch
-           -> Core TH.Phases -> DsM (Core TH.DecQ)
-repPragInl (MkC nm) (MkC inline) (MkC rm) (MkC phases)
-  = rep2 pragInlDName [nm, inline, rm, phases]
-
-repPragSpec :: Core TH.Name -> Core TH.TypeQ -> Core TH.Phases
-            -> DsM (Core TH.DecQ)
-repPragSpec (MkC nm) (MkC ty) (MkC phases)
-  = rep2 pragSpecDName [nm, ty, phases]
-
-repPragSpecInl :: Core TH.Name -> Core TH.TypeQ -> Core TH.Inline
-               -> Core TH.Phases -> DsM (Core TH.DecQ)
-repPragSpecInl (MkC nm) (MkC ty) (MkC inline) (MkC phases)
-  = rep2 pragSpecInlDName [nm, ty, inline, phases]
-
-repPragSpecInst :: Core TH.TypeQ -> DsM (Core TH.DecQ)
-repPragSpecInst (MkC ty) = rep2 pragSpecInstDName [ty]
-
-repPragRule :: Core String -> Core [TH.RuleBndrQ] -> Core TH.ExpQ
-            -> Core TH.ExpQ -> Core TH.Phases -> DsM (Core TH.DecQ)
-repPragRule (MkC nm) (MkC bndrs) (MkC lhs) (MkC rhs) (MkC phases)
-  = rep2 pragRuleDName [nm, bndrs, lhs, rhs, phases]
-
-repPragAnn :: Core TH.AnnTarget -> Core TH.ExpQ -> DsM (Core TH.DecQ)
-repPragAnn (MkC targ) (MkC e) = rep2 pragAnnDName [targ, e]
-
-repFamilyNoKind :: Core TH.FamFlavour -> Core TH.Name -> Core [TH.TyVarBndr]
-                -> DsM (Core TH.DecQ)
-repFamilyNoKind (MkC flav) (MkC nm) (MkC tvs)
-    = rep2 familyNoKindDName [flav, nm, tvs]
-
-repFamilyKind :: Core TH.FamFlavour -> Core TH.Name -> Core [TH.TyVarBndr]
-              -> Core TH.Kind
-              -> DsM (Core TH.DecQ)
-repFamilyKind (MkC flav) (MkC nm) (MkC tvs) (MkC ki)
-    = rep2 familyKindDName [flav, nm, tvs, ki]
-
-repTySynInst :: Core TH.Name -> Core TH.TySynEqnQ -> DsM (Core TH.DecQ)
-repTySynInst (MkC nm) (MkC eqn)
-    = rep2 tySynInstDName [nm, eqn]
-
-repClosedFamilyNoKind :: Core TH.Name
-                      -> Core [TH.TyVarBndr]
-                      -> Core [TH.TySynEqnQ]
-                      -> DsM (Core TH.DecQ)
-repClosedFamilyNoKind (MkC nm) (MkC tvs) (MkC eqns)
-    = rep2 closedTypeFamilyNoKindDName [nm, tvs, eqns]
-
-repClosedFamilyKind :: Core TH.Name
-                    -> Core [TH.TyVarBndr]
-                    -> Core TH.Kind
-                    -> Core [TH.TySynEqnQ]
-                    -> DsM (Core TH.DecQ)
-repClosedFamilyKind (MkC nm) (MkC tvs) (MkC ki) (MkC eqns)
-    = rep2 closedTypeFamilyKindDName [nm, tvs, ki, eqns]
-
-repTySynEqn :: Core [TH.TypeQ] -> Core TH.TypeQ -> DsM (Core TH.TySynEqnQ)
-repTySynEqn (MkC lhs) (MkC rhs)
-  = rep2 tySynEqnName [lhs, rhs]
-
-repRoleAnnotD :: Core TH.Name -> Core [TH.Role] -> DsM (Core TH.DecQ)
-repRoleAnnotD (MkC n) (MkC roles) = rep2 roleAnnotDName [n, roles]
-
-repFunDep :: Core [TH.Name] -> Core [TH.Name] -> DsM (Core TH.FunDep)
-repFunDep (MkC xs) (MkC ys) = rep2 funDepName [xs, ys]
-
-repProto :: Name -> Core TH.Name -> Core TH.TypeQ -> DsM (Core TH.DecQ)
-repProto mk_sig (MkC s) (MkC ty) = rep2 mk_sig [s, ty]
-
-repCtxt :: Core [TH.PredQ] -> DsM (Core TH.CxtQ)
-repCtxt (MkC tys) = rep2 cxtName [tys]
-
-repConstr :: Core TH.Name -> HsConDeclDetails Name
-          -> DsM (Core TH.ConQ)
-repConstr con (PrefixCon ps)
-    = do arg_tys  <- repList strictTypeQTyConName repBangTy ps
-         rep2 normalCName [unC con, unC arg_tys]
-
-repConstr con (RecCon (L _ ips))
-    = do { args <- concatMapM rep_ip ips
-         ; arg_vtys <- coreList varStrictTypeQTyConName args
-         ; rep2 recCName [unC con, unC arg_vtys] }
-    where
-      rep_ip (L _ ip) = mapM (rep_one_ip (cd_fld_type ip)) (cd_fld_names ip)
-      rep_one_ip t n = do { MkC v  <- lookupLOcc n
-                          ; MkC ty <- repBangTy  t
-                          ; rep2 varStrictTypeName [v,ty] }
-
-repConstr con (InfixCon st1 st2)
-    = do arg1 <- repBangTy st1
-         arg2 <- repBangTy st2
-         rep2 infixCName [unC arg1, unC con, unC arg2]
-
------------- Types -------------------
-
-repTForall :: Core [TH.TyVarBndr] -> Core TH.CxtQ -> Core TH.TypeQ
-           -> DsM (Core TH.TypeQ)
-repTForall (MkC tvars) (MkC ctxt) (MkC ty)
-    = rep2 forallTName [tvars, ctxt, ty]
-
-repTvar :: Core TH.Name -> DsM (Core TH.TypeQ)
-repTvar (MkC s) = rep2 varTName [s]
-
-repTapp :: Core TH.TypeQ -> Core TH.TypeQ -> DsM (Core TH.TypeQ)
-repTapp (MkC t1) (MkC t2) = rep2 appTName [t1, t2]
-
-repTapps :: Core TH.TypeQ -> [Core TH.TypeQ] -> DsM (Core TH.TypeQ)
-repTapps f []     = return f
-repTapps f (t:ts) = do { f1 <- repTapp f t; repTapps f1 ts }
-
-repTSig :: Core TH.TypeQ -> Core TH.Kind -> DsM (Core TH.TypeQ)
-repTSig (MkC ty) (MkC ki) = rep2 sigTName [ty, ki]
-
-repTequality :: DsM (Core TH.TypeQ)
-repTequality = rep2 equalityTName []
-
-repTPromotedList :: [Core TH.TypeQ] -> DsM (Core TH.TypeQ)
-repTPromotedList []     = repPromotedNilTyCon
-repTPromotedList (t:ts) = do  { tcon <- repPromotedConsTyCon
-                              ; f <- repTapp tcon t
-                              ; t' <- repTPromotedList ts
-                              ; repTapp f t'
-                              }
-
-repTLit :: Core TH.TyLitQ -> DsM (Core TH.TypeQ)
-repTLit (MkC lit) = rep2 litTName [lit]
-
---------- Type constructors --------------
-
-repNamedTyCon :: Core TH.Name -> DsM (Core TH.TypeQ)
-repNamedTyCon (MkC s) = rep2 conTName [s]
-
-repTupleTyCon :: Int -> DsM (Core TH.TypeQ)
--- Note: not Core Int; it's easier to be direct here
-repTupleTyCon i = do dflags <- getDynFlags
-                     rep2 tupleTName [mkIntExprInt dflags i]
-
-repUnboxedTupleTyCon :: Int -> DsM (Core TH.TypeQ)
--- Note: not Core Int; it's easier to be direct here
-repUnboxedTupleTyCon i = do dflags <- getDynFlags
-                            rep2 unboxedTupleTName [mkIntExprInt dflags i]
-
-repArrowTyCon :: DsM (Core TH.TypeQ)
-repArrowTyCon = rep2 arrowTName []
-
-repListTyCon :: DsM (Core TH.TypeQ)
-repListTyCon = rep2 listTName []
-
-repPromotedTyCon :: Core TH.Name -> DsM (Core TH.TypeQ)
-repPromotedTyCon (MkC s) = rep2 promotedTName [s]
-
-repPromotedTupleTyCon :: Int -> DsM (Core TH.TypeQ)
-repPromotedTupleTyCon i = do dflags <- getDynFlags
-                             rep2 promotedTupleTName [mkIntExprInt dflags i]
-
-repPromotedNilTyCon :: DsM (Core TH.TypeQ)
-repPromotedNilTyCon = rep2 promotedNilTName []
-
-repPromotedConsTyCon :: DsM (Core TH.TypeQ)
-repPromotedConsTyCon = rep2 promotedConsTName []
-
------------- Kinds -------------------
-
-repPlainTV :: Core TH.Name -> DsM (Core TH.TyVarBndr)
-repPlainTV (MkC nm) = rep2 plainTVName [nm]
-
-repKindedTV :: Core TH.Name -> Core TH.Kind -> DsM (Core TH.TyVarBndr)
-repKindedTV (MkC nm) (MkC ki) = rep2 kindedTVName [nm, ki]
-
-repKVar :: Core TH.Name -> DsM (Core TH.Kind)
-repKVar (MkC s) = rep2 varKName [s]
-
-repKCon :: Core TH.Name -> DsM (Core TH.Kind)
-repKCon (MkC s) = rep2 conKName [s]
-
-repKTuple :: Int -> DsM (Core TH.Kind)
-repKTuple i = do dflags <- getDynFlags
-                 rep2 tupleKName [mkIntExprInt dflags i]
-
-repKArrow :: DsM (Core TH.Kind)
-repKArrow = rep2 arrowKName []
-
-repKList :: DsM (Core TH.Kind)
-repKList = rep2 listKName []
-
-repKApp :: Core TH.Kind -> Core TH.Kind -> DsM (Core TH.Kind)
-repKApp (MkC k1) (MkC k2) = rep2 appKName [k1, k2]
-
-repKApps :: Core TH.Kind -> [Core TH.Kind] -> DsM (Core TH.Kind)
-repKApps f []     = return f
-repKApps f (k:ks) = do { f' <- repKApp f k; repKApps f' ks }
-
-repKStar :: DsM (Core TH.Kind)
-repKStar = rep2 starKName []
-
-repKConstraint :: DsM (Core TH.Kind)
-repKConstraint = rep2 constraintKName []
-
-----------------------------------------------------------
---              Literals
-
-repLiteral :: HsLit -> DsM (Core TH.Lit)
-repLiteral lit
-  = do lit' <- case lit of
-                   HsIntPrim _ i    -> mk_integer i
-                   HsWordPrim _ w   -> mk_integer w
-                   HsInt _ i        -> mk_integer i
-                   HsFloatPrim r    -> mk_rational r
-                   HsDoublePrim r   -> mk_rational r
-                   _ -> return lit
-       lit_expr <- dsLit lit'
-       case mb_lit_name of
-          Just lit_name -> rep2 lit_name [lit_expr]
-          Nothing -> notHandled "Exotic literal" (ppr lit)
-  where
-    mb_lit_name = case lit of
-                 HsInteger _ _ _  -> Just integerLName
-                 HsInt     _ _    -> Just integerLName
-                 HsIntPrim _ _    -> Just intPrimLName
-                 HsWordPrim _ _   -> Just wordPrimLName
-                 HsFloatPrim _    -> Just floatPrimLName
-                 HsDoublePrim _   -> Just doublePrimLName
-                 HsChar _ _       -> Just charLName
-                 HsString _ _     -> Just stringLName
-                 HsRat _ _        -> Just rationalLName
-                 _                -> Nothing
-
-mk_integer :: Integer -> DsM HsLit
-mk_integer  i = do integer_ty <- lookupType integerTyConName
-                   return $ HsInteger "" i integer_ty
-mk_rational :: FractionalLit -> DsM HsLit
-mk_rational r = do rat_ty <- lookupType rationalTyConName
-                   return $ HsRat r rat_ty
-mk_string :: FastString -> DsM HsLit
-mk_string s = return $ HsString "" s
-
-repOverloadedLiteral :: HsOverLit Name -> DsM (Core TH.Lit)
-repOverloadedLiteral (OverLit { ol_val = val})
-  = do { lit <- mk_lit val; repLiteral lit }
-        -- The type Rational will be in the environment, because
-        -- the smart constructor 'TH.Syntax.rationalL' uses it in its type,
-        -- and rationalL is sucked in when any TH stuff is used
-
-mk_lit :: OverLitVal -> DsM HsLit
-mk_lit (HsIntegral _ i)   = mk_integer  i
-mk_lit (HsFractional f)   = mk_rational f
-mk_lit (HsIsString _ s)   = mk_string   s
-
---------------- Miscellaneous -------------------
-
-repGensym :: Core String -> DsM (Core (TH.Q TH.Name))
-repGensym (MkC lit_str) = rep2 newNameName [lit_str]
-
-repBindQ :: Type -> Type        -- a and b
-         -> Core (TH.Q a) -> Core (a -> TH.Q b) -> DsM (Core (TH.Q b))
-repBindQ ty_a ty_b (MkC x) (MkC y)
-  = rep2 bindQName [Type ty_a, Type ty_b, x, y]
-
-repSequenceQ :: Type -> Core [TH.Q a] -> DsM (Core (TH.Q [a]))
-repSequenceQ ty_a (MkC list)
-  = rep2 sequenceQName [Type ty_a, list]
-
------------- Lists and Tuples -------------------
--- turn a list of patterns into a single pattern matching a list
-
-repList :: Name -> (a  -> DsM (Core b))
-                -> [a] -> DsM (Core [b])
-repList tc_name f args
-  = do { args1 <- mapM f args
-       ; coreList tc_name args1 }
-
-coreList :: Name        -- Of the TyCon of the element type
-         -> [Core a] -> DsM (Core [a])
-coreList tc_name es
-  = do { elt_ty <- lookupType tc_name; return (coreList' elt_ty es) }
-
-coreList' :: Type       -- The element type
-          -> [Core a] -> Core [a]
-coreList' elt_ty es = MkC (mkListExpr elt_ty (map unC es ))
-
-nonEmptyCoreList :: [Core a] -> Core [a]
-  -- The list must be non-empty so we can get the element type
-  -- Otherwise use coreList
-nonEmptyCoreList []           = panic "coreList: empty argument"
-nonEmptyCoreList xs@(MkC x:_) = MkC (mkListExpr (exprType x) (map unC xs))
-
-coreStringLit :: String -> DsM (Core String)
-coreStringLit s = do { z <- mkStringExpr s; return(MkC z) }
-
------------- Literals & Variables -------------------
-
-coreIntLit :: Int -> DsM (Core Int)
-coreIntLit i = do dflags <- getDynFlags
-                  return (MkC (mkIntExprInt dflags i))
-
-coreVar :: Id -> Core TH.Name   -- The Id has type Name
-coreVar id = MkC (Var id)
-
------------------ Failure -----------------------
-notHandledL :: SrcSpan -> String -> SDoc -> DsM a
-notHandledL loc what doc
-  | isGoodSrcSpan loc
-  = putSrcSpanDs loc $ notHandled what doc
-  | otherwise
-  = notHandled what doc
-
-notHandled :: String -> SDoc -> DsM a
-notHandled what doc = failWithDs msg
-  where
-    msg = hang (text what <+> ptext (sLit "not (yet) handled by Template Haskell"))
-             2 doc
-
-
--- %************************************************************************
--- %*                                                                   *
---              The known-key names for Template Haskell
--- %*                                                                   *
--- %************************************************************************
-
--- To add a name, do three things
---
---  1) Allocate a key
---  2) Make a "Name"
---  3) Add the name to knownKeyNames
-
-templateHaskellNames :: [Name]
--- The names that are implicitly mentioned by ``bracket''
--- Should stay in sync with the import list of DsMeta
-
-templateHaskellNames = [
-    returnQName, bindQName, sequenceQName, newNameName, liftName,
-    mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, mkNameLName,
-    liftStringName,
-    unTypeName,
-    unTypeQName,
-    unsafeTExpCoerceName,
-
-    -- Lit
-    charLName, stringLName, integerLName, intPrimLName, wordPrimLName,
-    floatPrimLName, doublePrimLName, rationalLName,
-    -- Pat
-    litPName, varPName, tupPName, unboxedTupPName,
-    conPName, tildePName, bangPName, infixPName,
-    asPName, wildPName, recPName, listPName, sigPName, viewPName,
-    -- FieldPat
-    fieldPatName,
-    -- Match
-    matchName,
-    -- Clause
-    clauseName,
-    -- Exp
-    varEName, conEName, litEName, appEName, infixEName,
-    infixAppName, sectionLName, sectionRName, lamEName, lamCaseEName,
-    tupEName, unboxedTupEName,
-    condEName, multiIfEName, letEName, caseEName, doEName, compEName,
-    fromEName, fromThenEName, fromToEName, fromThenToEName,
-    listEName, sigEName, recConEName, recUpdEName, staticEName,
-    -- FieldExp
-    fieldExpName,
-    -- Body
-    guardedBName, normalBName,
-    -- Guard
-    normalGEName, patGEName,
-    -- Stmt
-    bindSName, letSName, noBindSName, parSName,
-    -- Dec
-    funDName, valDName, dataDName, newtypeDName, tySynDName,
-    classDName, instanceDName, standaloneDerivDName, sigDName, forImpDName,
-    pragInlDName, pragSpecDName, pragSpecInlDName, pragSpecInstDName,
-    pragRuleDName, pragAnnDName, defaultSigDName,
-    familyNoKindDName, familyKindDName, dataInstDName, newtypeInstDName,
-    tySynInstDName, closedTypeFamilyKindDName, closedTypeFamilyNoKindDName,
-    infixLDName, infixRDName, infixNDName,
-    roleAnnotDName,
-    -- Cxt
-    cxtName,
-    -- Strict
-    isStrictName, notStrictName, unpackedName,
-    -- Con
-    normalCName, recCName, infixCName, forallCName,
-    -- StrictType
-    strictTypeName,
-    -- VarStrictType
-    varStrictTypeName,
-    -- Type
-    forallTName, varTName, conTName, appTName, equalityTName,
-    tupleTName, unboxedTupleTName, arrowTName, listTName, sigTName, litTName,
-    promotedTName, promotedTupleTName, promotedNilTName, promotedConsTName,
-    -- TyLit
-    numTyLitName, strTyLitName,
-    -- TyVarBndr
-    plainTVName, kindedTVName,
-    -- Role
-    nominalRName, representationalRName, phantomRName, inferRName,
-    -- Kind
-    varKName, conKName, tupleKName, arrowKName, listKName, appKName,
-    starKName, constraintKName,
-    -- Callconv
-    cCallName, stdCallName, cApiCallName, primCallName, javaScriptCallName,
-    -- Safety
-    unsafeName,
-    safeName,
-    interruptibleName,
-    -- Inline
-    noInlineDataConName, inlineDataConName, inlinableDataConName,
-    -- RuleMatch
-    conLikeDataConName, funLikeDataConName,
-    -- Phases
-    allPhasesDataConName, fromPhaseDataConName, beforePhaseDataConName,
-    -- TExp
-    tExpDataConName,
-    -- RuleBndr
-    ruleVarName, typedRuleVarName,
-    -- FunDep
-    funDepName,
-    -- FamFlavour
-    typeFamName, dataFamName,
-    -- TySynEqn
-    tySynEqnName,
-    -- AnnTarget
-    valueAnnotationName, typeAnnotationName, moduleAnnotationName,
-
-    -- And the tycons
-    qTyConName, nameTyConName, patTyConName, fieldPatTyConName, matchQTyConName,
-    clauseQTyConName, expQTyConName, fieldExpTyConName, predTyConName,
-    stmtQTyConName, decQTyConName, conQTyConName, strictTypeQTyConName,
-    varStrictTypeQTyConName, typeQTyConName, expTyConName, decTyConName,
-    typeTyConName, tyVarBndrTyConName, matchTyConName, clauseTyConName,
-    patQTyConName, fieldPatQTyConName, fieldExpQTyConName, funDepTyConName,
-    predQTyConName, decsQTyConName, ruleBndrQTyConName, tySynEqnQTyConName,
-    roleTyConName, tExpTyConName,
-
-    -- Quasiquoting
-    quoteDecName, quoteTypeName, quoteExpName, quotePatName]
-
-thSyn, thLib, qqLib :: Module
-thSyn = mkTHModule (fsLit "Language.Haskell.TH.Syntax")
-thLib = mkTHModule (fsLit "Language.Haskell.TH.Lib")
-qqLib = mkTHModule (fsLit "Language.Haskell.TH.Quote")
-
-mkTHModule :: FastString -> Module
-mkTHModule m = mkModule thPackageKey (mkModuleNameFS m)
-
-libFun, libTc, thFun, thTc, thCon, qqFun :: FastString -> Unique -> Name
-libFun = mk_known_key_name OccName.varName  thLib
-libTc  = mk_known_key_name OccName.tcName   thLib
-thFun  = mk_known_key_name OccName.varName  thSyn
-thTc   = mk_known_key_name OccName.tcName   thSyn
-thCon  = mk_known_key_name OccName.dataName thSyn
-qqFun  = mk_known_key_name OccName.varName  qqLib
-
--------------------- TH.Syntax -----------------------
-qTyConName, nameTyConName, fieldExpTyConName, patTyConName,
-    fieldPatTyConName, expTyConName, decTyConName, typeTyConName,
-    tyVarBndrTyConName, matchTyConName, clauseTyConName, funDepTyConName,
-    predTyConName, tExpTyConName :: Name
-qTyConName        = thTc (fsLit "Q")            qTyConKey
-nameTyConName     = thTc (fsLit "Name")         nameTyConKey
-fieldExpTyConName = thTc (fsLit "FieldExp")     fieldExpTyConKey
-patTyConName      = thTc (fsLit "Pat")          patTyConKey
-fieldPatTyConName = thTc (fsLit "FieldPat")     fieldPatTyConKey
-expTyConName      = thTc (fsLit "Exp")          expTyConKey
-decTyConName      = thTc (fsLit "Dec")          decTyConKey
-typeTyConName     = thTc (fsLit "Type")         typeTyConKey
-tyVarBndrTyConName= thTc (fsLit "TyVarBndr")    tyVarBndrTyConKey
-matchTyConName    = thTc (fsLit "Match")        matchTyConKey
-clauseTyConName   = thTc (fsLit "Clause")       clauseTyConKey
-funDepTyConName   = thTc (fsLit "FunDep")       funDepTyConKey
-predTyConName     = thTc (fsLit "Pred")         predTyConKey
-tExpTyConName     = thTc (fsLit "TExp")         tExpTyConKey
-
-returnQName, bindQName, sequenceQName, newNameName, liftName,
-    mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName,
-    mkNameLName, liftStringName, unTypeName, unTypeQName,
-    unsafeTExpCoerceName :: Name
-returnQName    = thFun (fsLit "returnQ")   returnQIdKey
-bindQName      = thFun (fsLit "bindQ")     bindQIdKey
-sequenceQName  = thFun (fsLit "sequenceQ") sequenceQIdKey
-newNameName    = thFun (fsLit "newName")   newNameIdKey
-liftName       = thFun (fsLit "lift")      liftIdKey
-liftStringName = thFun (fsLit "liftString")  liftStringIdKey
-mkNameName     = thFun (fsLit "mkName")     mkNameIdKey
-mkNameG_vName  = thFun (fsLit "mkNameG_v")  mkNameG_vIdKey
-mkNameG_dName  = thFun (fsLit "mkNameG_d")  mkNameG_dIdKey
-mkNameG_tcName = thFun (fsLit "mkNameG_tc") mkNameG_tcIdKey
-mkNameLName    = thFun (fsLit "mkNameL")    mkNameLIdKey
-unTypeName     = thFun (fsLit "unType")     unTypeIdKey
-unTypeQName    = thFun (fsLit "unTypeQ")    unTypeQIdKey
-unsafeTExpCoerceName = thFun (fsLit "unsafeTExpCoerce") unsafeTExpCoerceIdKey
-
-
--------------------- TH.Lib -----------------------
--- data Lit = ...
-charLName, stringLName, integerLName, intPrimLName, wordPrimLName,
-    floatPrimLName, doublePrimLName, rationalLName :: Name
-charLName       = libFun (fsLit "charL")       charLIdKey
-stringLName     = libFun (fsLit "stringL")     stringLIdKey
-integerLName    = libFun (fsLit "integerL")    integerLIdKey
-intPrimLName    = libFun (fsLit "intPrimL")    intPrimLIdKey
-wordPrimLName   = libFun (fsLit "wordPrimL")   wordPrimLIdKey
-floatPrimLName  = libFun (fsLit "floatPrimL")  floatPrimLIdKey
-doublePrimLName = libFun (fsLit "doublePrimL") doublePrimLIdKey
-rationalLName   = libFun (fsLit "rationalL")     rationalLIdKey
-
--- data Pat = ...
-litPName, varPName, tupPName, unboxedTupPName, conPName, infixPName, tildePName, bangPName,
-    asPName, wildPName, recPName, listPName, sigPName, viewPName :: Name
-litPName   = libFun (fsLit "litP")   litPIdKey
-varPName   = libFun (fsLit "varP")   varPIdKey
-tupPName   = libFun (fsLit "tupP")   tupPIdKey
-unboxedTupPName = libFun (fsLit "unboxedTupP") unboxedTupPIdKey
-conPName   = libFun (fsLit "conP")   conPIdKey
-infixPName = libFun (fsLit "infixP") infixPIdKey
-tildePName = libFun (fsLit "tildeP") tildePIdKey
-bangPName  = libFun (fsLit "bangP")  bangPIdKey
-asPName    = libFun (fsLit "asP")    asPIdKey
-wildPName  = libFun (fsLit "wildP")  wildPIdKey
-recPName   = libFun (fsLit "recP")   recPIdKey
-listPName  = libFun (fsLit "listP")  listPIdKey
-sigPName   = libFun (fsLit "sigP")   sigPIdKey
-viewPName  = libFun (fsLit "viewP")  viewPIdKey
-
--- type FieldPat = ...
-fieldPatName :: Name
-fieldPatName = libFun (fsLit "fieldPat") fieldPatIdKey
-
--- data Match = ...
-matchName :: Name
-matchName = libFun (fsLit "match") matchIdKey
-
--- data Clause = ...
-clauseName :: Name
-clauseName = libFun (fsLit "clause") clauseIdKey
-
--- data Exp = ...
-varEName, conEName, litEName, appEName, infixEName, infixAppName,
-    sectionLName, sectionRName, lamEName, lamCaseEName, tupEName,
-    unboxedTupEName, condEName, multiIfEName, letEName, caseEName,
-    doEName, compEName, staticEName :: Name
-varEName        = libFun (fsLit "varE")        varEIdKey
-conEName        = libFun (fsLit "conE")        conEIdKey
-litEName        = libFun (fsLit "litE")        litEIdKey
-appEName        = libFun (fsLit "appE")        appEIdKey
-infixEName      = libFun (fsLit "infixE")      infixEIdKey
-infixAppName    = libFun (fsLit "infixApp")    infixAppIdKey
-sectionLName    = libFun (fsLit "sectionL")    sectionLIdKey
-sectionRName    = libFun (fsLit "sectionR")    sectionRIdKey
-lamEName        = libFun (fsLit "lamE")        lamEIdKey
-lamCaseEName    = libFun (fsLit "lamCaseE")    lamCaseEIdKey
-tupEName        = libFun (fsLit "tupE")        tupEIdKey
-unboxedTupEName = libFun (fsLit "unboxedTupE") unboxedTupEIdKey
-condEName       = libFun (fsLit "condE")       condEIdKey
-multiIfEName    = libFun (fsLit "multiIfE")    multiIfEIdKey
-letEName        = libFun (fsLit "letE")        letEIdKey
-caseEName       = libFun (fsLit "caseE")       caseEIdKey
-doEName         = libFun (fsLit "doE")         doEIdKey
-compEName       = libFun (fsLit "compE")       compEIdKey
--- ArithSeq skips a level
-fromEName, fromThenEName, fromToEName, fromThenToEName :: Name
-fromEName       = libFun (fsLit "fromE")       fromEIdKey
-fromThenEName   = libFun (fsLit "fromThenE")   fromThenEIdKey
-fromToEName     = libFun (fsLit "fromToE")     fromToEIdKey
-fromThenToEName = libFun (fsLit "fromThenToE") fromThenToEIdKey
--- end ArithSeq
-listEName, sigEName, recConEName, recUpdEName :: Name
-listEName       = libFun (fsLit "listE")       listEIdKey
-sigEName        = libFun (fsLit "sigE")        sigEIdKey
-recConEName     = libFun (fsLit "recConE")     recConEIdKey
-recUpdEName     = libFun (fsLit "recUpdE")     recUpdEIdKey
-staticEName     = libFun (fsLit "staticE")     staticEIdKey
-
--- type FieldExp = ...
-fieldExpName :: Name
-fieldExpName = libFun (fsLit "fieldExp") fieldExpIdKey
-
--- data Body = ...
-guardedBName, normalBName :: Name
-guardedBName = libFun (fsLit "guardedB") guardedBIdKey
-normalBName  = libFun (fsLit "normalB")  normalBIdKey
-
--- data Guard = ...
-normalGEName, patGEName :: Name
-normalGEName = libFun (fsLit "normalGE") normalGEIdKey
-patGEName    = libFun (fsLit "patGE")    patGEIdKey
-
--- data Stmt = ...
-bindSName, letSName, noBindSName, parSName :: Name
-bindSName   = libFun (fsLit "bindS")   bindSIdKey
-letSName    = libFun (fsLit "letS")    letSIdKey
-noBindSName = libFun (fsLit "noBindS") noBindSIdKey
-parSName    = libFun (fsLit "parS")    parSIdKey
-
--- data Dec = ...
-funDName, valDName, dataDName, newtypeDName, tySynDName, classDName,
-    instanceDName, sigDName, forImpDName, pragInlDName, pragSpecDName,
-    pragSpecInlDName, pragSpecInstDName, pragRuleDName, pragAnnDName,
-    familyNoKindDName, standaloneDerivDName, defaultSigDName,
-    familyKindDName, dataInstDName, newtypeInstDName, tySynInstDName,
-    closedTypeFamilyKindDName, closedTypeFamilyNoKindDName,
-    infixLDName, infixRDName, infixNDName, roleAnnotDName :: Name
-funDName          = libFun (fsLit "funD")          funDIdKey
-valDName          = libFun (fsLit "valD")          valDIdKey
-dataDName         = libFun (fsLit "dataD")         dataDIdKey
-newtypeDName      = libFun (fsLit "newtypeD")      newtypeDIdKey
-tySynDName        = libFun (fsLit "tySynD")        tySynDIdKey
-classDName        = libFun (fsLit "classD")        classDIdKey
-instanceDName     = libFun (fsLit "instanceD")     instanceDIdKey
-standaloneDerivDName
-                  = libFun (fsLit "standaloneDerivD") standaloneDerivDIdKey
-sigDName          = libFun (fsLit "sigD")          sigDIdKey
-defaultSigDName   = libFun (fsLit "defaultSigD")   defaultSigDIdKey
-forImpDName       = libFun (fsLit "forImpD")       forImpDIdKey
-pragInlDName      = libFun (fsLit "pragInlD")      pragInlDIdKey
-pragSpecDName     = libFun (fsLit "pragSpecD")     pragSpecDIdKey
-pragSpecInlDName  = libFun (fsLit "pragSpecInlD")  pragSpecInlDIdKey
-pragSpecInstDName = libFun (fsLit "pragSpecInstD") pragSpecInstDIdKey
-pragRuleDName     = libFun (fsLit "pragRuleD")     pragRuleDIdKey
-pragAnnDName      = libFun (fsLit "pragAnnD")      pragAnnDIdKey
-familyNoKindDName = libFun (fsLit "familyNoKindD") familyNoKindDIdKey
-familyKindDName   = libFun (fsLit "familyKindD")   familyKindDIdKey
-dataInstDName     = libFun (fsLit "dataInstD")     dataInstDIdKey
-newtypeInstDName  = libFun (fsLit "newtypeInstD")  newtypeInstDIdKey
-tySynInstDName    = libFun (fsLit "tySynInstD")    tySynInstDIdKey
-closedTypeFamilyKindDName
-                  = libFun (fsLit "closedTypeFamilyKindD") closedTypeFamilyKindDIdKey
-closedTypeFamilyNoKindDName
-                  = libFun (fsLit "closedTypeFamilyNoKindD") closedTypeFamilyNoKindDIdKey
-infixLDName       = libFun (fsLit "infixLD")       infixLDIdKey
-infixRDName       = libFun (fsLit "infixRD")       infixRDIdKey
-infixNDName       = libFun (fsLit "infixND")       infixNDIdKey
-roleAnnotDName    = libFun (fsLit "roleAnnotD")    roleAnnotDIdKey
-
--- type Ctxt = ...
-cxtName :: Name
-cxtName = libFun (fsLit "cxt") cxtIdKey
-
--- data Strict = ...
-isStrictName, notStrictName, unpackedName :: Name
-isStrictName      = libFun  (fsLit "isStrict")      isStrictKey
-notStrictName     = libFun  (fsLit "notStrict")     notStrictKey
-unpackedName      = libFun  (fsLit "unpacked")      unpackedKey
-
--- data Con = ...
-normalCName, recCName, infixCName, forallCName :: Name
-normalCName = libFun (fsLit "normalC") normalCIdKey
-recCName    = libFun (fsLit "recC")    recCIdKey
-infixCName  = libFun (fsLit "infixC")  infixCIdKey
-forallCName  = libFun (fsLit "forallC")  forallCIdKey
-
--- type StrictType = ...
-strictTypeName :: Name
-strictTypeName    = libFun  (fsLit "strictType")    strictTKey
-
--- type VarStrictType = ...
-varStrictTypeName :: Name
-varStrictTypeName = libFun  (fsLit "varStrictType") varStrictTKey
-
--- data Type = ...
-forallTName, varTName, conTName, tupleTName, unboxedTupleTName, arrowTName,
-    listTName, appTName, sigTName, equalityTName, litTName,
-    promotedTName, promotedTupleTName,
-    promotedNilTName, promotedConsTName :: Name
-forallTName         = libFun (fsLit "forallT")        forallTIdKey
-varTName            = libFun (fsLit "varT")           varTIdKey
-conTName            = libFun (fsLit "conT")           conTIdKey
-tupleTName          = libFun (fsLit "tupleT")         tupleTIdKey
-unboxedTupleTName   = libFun (fsLit "unboxedTupleT")  unboxedTupleTIdKey
-arrowTName          = libFun (fsLit "arrowT")         arrowTIdKey
-listTName           = libFun (fsLit "listT")          listTIdKey
-appTName            = libFun (fsLit "appT")           appTIdKey
-sigTName            = libFun (fsLit "sigT")           sigTIdKey
-equalityTName       = libFun (fsLit "equalityT")      equalityTIdKey
-litTName            = libFun (fsLit "litT")           litTIdKey
-promotedTName       = libFun (fsLit "promotedT")      promotedTIdKey
-promotedTupleTName  = libFun (fsLit "promotedTupleT") promotedTupleTIdKey
-promotedNilTName    = libFun (fsLit "promotedNilT")   promotedNilTIdKey
-promotedConsTName   = libFun (fsLit "promotedConsT")  promotedConsTIdKey
-
--- data TyLit = ...
-numTyLitName, strTyLitName :: Name
-numTyLitName = libFun (fsLit "numTyLit") numTyLitIdKey
-strTyLitName = libFun (fsLit "strTyLit") strTyLitIdKey
-
--- data TyVarBndr = ...
-plainTVName, kindedTVName :: Name
-plainTVName       = libFun (fsLit "plainTV")       plainTVIdKey
-kindedTVName      = libFun (fsLit "kindedTV")      kindedTVIdKey
-
--- data Role = ...
-nominalRName, representationalRName, phantomRName, inferRName :: Name
-nominalRName          = libFun (fsLit "nominalR")          nominalRIdKey
-representationalRName = libFun (fsLit "representationalR") representationalRIdKey
-phantomRName          = libFun (fsLit "phantomR")          phantomRIdKey
-inferRName            = libFun (fsLit "inferR")            inferRIdKey
-
--- data Kind = ...
-varKName, conKName, tupleKName, arrowKName, listKName, appKName,
-  starKName, constraintKName :: Name
-varKName        = libFun (fsLit "varK")         varKIdKey
-conKName        = libFun (fsLit "conK")         conKIdKey
-tupleKName      = libFun (fsLit "tupleK")       tupleKIdKey
-arrowKName      = libFun (fsLit "arrowK")       arrowKIdKey
-listKName       = libFun (fsLit "listK")        listKIdKey
-appKName        = libFun (fsLit "appK")         appKIdKey
-starKName       = libFun (fsLit "starK")        starKIdKey
-constraintKName = libFun (fsLit "constraintK")  constraintKIdKey
-
--- data Callconv = ...
-cCallName, stdCallName, cApiCallName, primCallName, javaScriptCallName :: Name
-cCallName = libFun (fsLit "cCall") cCallIdKey
-stdCallName = libFun (fsLit "stdCall") stdCallIdKey
-cApiCallName = libFun (fsLit "cApi") cApiCallIdKey
-primCallName = libFun (fsLit "prim") primCallIdKey
-javaScriptCallName = libFun (fsLit "javaScript") javaScriptCallIdKey
-
--- data Safety = ...
-unsafeName, safeName, interruptibleName :: Name
-unsafeName     = libFun (fsLit "unsafe") unsafeIdKey
-safeName       = libFun (fsLit "safe") safeIdKey
-interruptibleName = libFun (fsLit "interruptible") interruptibleIdKey
-
--- data Inline = ...
-noInlineDataConName, inlineDataConName, inlinableDataConName :: Name
-noInlineDataConName  = thCon (fsLit "NoInline")  noInlineDataConKey
-inlineDataConName    = thCon (fsLit "Inline")    inlineDataConKey
-inlinableDataConName = thCon (fsLit "Inlinable") inlinableDataConKey
-
--- data RuleMatch = ...
-conLikeDataConName, funLikeDataConName :: Name
-conLikeDataConName = thCon (fsLit "ConLike") conLikeDataConKey
-funLikeDataConName = thCon (fsLit "FunLike") funLikeDataConKey
-
--- data Phases = ...
-allPhasesDataConName, fromPhaseDataConName, beforePhaseDataConName :: Name
-allPhasesDataConName   = thCon (fsLit "AllPhases")   allPhasesDataConKey
-fromPhaseDataConName   = thCon (fsLit "FromPhase")   fromPhaseDataConKey
-beforePhaseDataConName = thCon (fsLit "BeforePhase") beforePhaseDataConKey
-
--- newtype TExp a = ...
-tExpDataConName :: Name
-tExpDataConName = thCon (fsLit "TExp") tExpDataConKey
-
--- data RuleBndr = ...
-ruleVarName, typedRuleVarName :: Name
-ruleVarName      = libFun (fsLit ("ruleVar"))      ruleVarIdKey
-typedRuleVarName = libFun (fsLit ("typedRuleVar")) typedRuleVarIdKey
-
--- data FunDep = ...
-funDepName :: Name
-funDepName     = libFun (fsLit "funDep") funDepIdKey
-
--- data FamFlavour = ...
-typeFamName, dataFamName :: Name
-typeFamName = libFun (fsLit "typeFam") typeFamIdKey
-dataFamName = libFun (fsLit "dataFam") dataFamIdKey
-
--- data TySynEqn = ...
-tySynEqnName :: Name
-tySynEqnName = libFun (fsLit "tySynEqn") tySynEqnIdKey
-
--- data AnnTarget = ...
-valueAnnotationName, typeAnnotationName, moduleAnnotationName :: Name
-valueAnnotationName  = libFun (fsLit "valueAnnotation")  valueAnnotationIdKey
-typeAnnotationName   = libFun (fsLit "typeAnnotation")   typeAnnotationIdKey
-moduleAnnotationName = libFun (fsLit "moduleAnnotation") moduleAnnotationIdKey
-
-matchQTyConName, clauseQTyConName, expQTyConName, stmtQTyConName,
-    decQTyConName, conQTyConName, strictTypeQTyConName,
-    varStrictTypeQTyConName, typeQTyConName, fieldExpQTyConName,
-    patQTyConName, fieldPatQTyConName, predQTyConName, decsQTyConName,
-    ruleBndrQTyConName, tySynEqnQTyConName, roleTyConName :: Name
-matchQTyConName         = libTc (fsLit "MatchQ")         matchQTyConKey
-clauseQTyConName        = libTc (fsLit "ClauseQ")        clauseQTyConKey
-expQTyConName           = libTc (fsLit "ExpQ")           expQTyConKey
-stmtQTyConName          = libTc (fsLit "StmtQ")          stmtQTyConKey
-decQTyConName           = libTc (fsLit "DecQ")           decQTyConKey
-decsQTyConName          = libTc (fsLit "DecsQ")          decsQTyConKey  -- Q [Dec]
-conQTyConName           = libTc (fsLit "ConQ")           conQTyConKey
-strictTypeQTyConName    = libTc (fsLit "StrictTypeQ")    strictTypeQTyConKey
-varStrictTypeQTyConName = libTc (fsLit "VarStrictTypeQ") varStrictTypeQTyConKey
-typeQTyConName          = libTc (fsLit "TypeQ")          typeQTyConKey
-fieldExpQTyConName      = libTc (fsLit "FieldExpQ")      fieldExpQTyConKey
-patQTyConName           = libTc (fsLit "PatQ")           patQTyConKey
-fieldPatQTyConName      = libTc (fsLit "FieldPatQ")      fieldPatQTyConKey
-predQTyConName          = libTc (fsLit "PredQ")          predQTyConKey
-ruleBndrQTyConName      = libTc (fsLit "RuleBndrQ")      ruleBndrQTyConKey
-tySynEqnQTyConName      = libTc (fsLit "TySynEqnQ")      tySynEqnQTyConKey
-roleTyConName           = libTc (fsLit "Role")           roleTyConKey
-
--- quasiquoting
-quoteExpName, quotePatName, quoteDecName, quoteTypeName :: Name
-quoteExpName        = qqFun (fsLit "quoteExp")  quoteExpKey
-quotePatName        = qqFun (fsLit "quotePat")  quotePatKey
-quoteDecName        = qqFun (fsLit "quoteDec")  quoteDecKey
-quoteTypeName       = qqFun (fsLit "quoteType") quoteTypeKey
-
--- TyConUniques available: 200-299
--- Check in PrelNames if you want to change this
-
-expTyConKey, matchTyConKey, clauseTyConKey, qTyConKey, expQTyConKey,
-    decQTyConKey, patTyConKey, matchQTyConKey, clauseQTyConKey,
-    stmtQTyConKey, conQTyConKey, typeQTyConKey, typeTyConKey, tyVarBndrTyConKey,
-    decTyConKey, varStrictTypeQTyConKey, strictTypeQTyConKey,
-    fieldExpTyConKey, fieldPatTyConKey, nameTyConKey, patQTyConKey,
-    fieldPatQTyConKey, fieldExpQTyConKey, funDepTyConKey, predTyConKey,
-    predQTyConKey, decsQTyConKey, ruleBndrQTyConKey, tySynEqnQTyConKey,
-    roleTyConKey, tExpTyConKey :: Unique
-expTyConKey             = mkPreludeTyConUnique 200
-matchTyConKey           = mkPreludeTyConUnique 201
-clauseTyConKey          = mkPreludeTyConUnique 202
-qTyConKey               = mkPreludeTyConUnique 203
-expQTyConKey            = mkPreludeTyConUnique 204
-decQTyConKey            = mkPreludeTyConUnique 205
-patTyConKey             = mkPreludeTyConUnique 206
-matchQTyConKey          = mkPreludeTyConUnique 207
-clauseQTyConKey         = mkPreludeTyConUnique 208
-stmtQTyConKey           = mkPreludeTyConUnique 209
-conQTyConKey            = mkPreludeTyConUnique 210
-typeQTyConKey           = mkPreludeTyConUnique 211
-typeTyConKey            = mkPreludeTyConUnique 212
-decTyConKey             = mkPreludeTyConUnique 213
-varStrictTypeQTyConKey  = mkPreludeTyConUnique 214
-strictTypeQTyConKey     = mkPreludeTyConUnique 215
-fieldExpTyConKey        = mkPreludeTyConUnique 216
-fieldPatTyConKey        = mkPreludeTyConUnique 217
-nameTyConKey            = mkPreludeTyConUnique 218
-patQTyConKey            = mkPreludeTyConUnique 219
-fieldPatQTyConKey       = mkPreludeTyConUnique 220
-fieldExpQTyConKey       = mkPreludeTyConUnique 221
-funDepTyConKey          = mkPreludeTyConUnique 222
-predTyConKey            = mkPreludeTyConUnique 223
-predQTyConKey           = mkPreludeTyConUnique 224
-tyVarBndrTyConKey       = mkPreludeTyConUnique 225
-decsQTyConKey           = mkPreludeTyConUnique 226
-ruleBndrQTyConKey       = mkPreludeTyConUnique 227
-tySynEqnQTyConKey       = mkPreludeTyConUnique 228
-roleTyConKey            = mkPreludeTyConUnique 229
-tExpTyConKey            = mkPreludeTyConUnique 230
-
--- IdUniques available: 200-499
--- If you want to change this, make sure you check in PrelNames
-
-returnQIdKey, bindQIdKey, sequenceQIdKey, liftIdKey, newNameIdKey,
-    mkNameIdKey, mkNameG_vIdKey, mkNameG_dIdKey, mkNameG_tcIdKey,
-    mkNameLIdKey, unTypeIdKey, unTypeQIdKey, unsafeTExpCoerceIdKey :: Unique
-returnQIdKey        = mkPreludeMiscIdUnique 200
-bindQIdKey          = mkPreludeMiscIdUnique 201
-sequenceQIdKey      = mkPreludeMiscIdUnique 202
-liftIdKey           = mkPreludeMiscIdUnique 203
-newNameIdKey         = mkPreludeMiscIdUnique 204
-mkNameIdKey          = mkPreludeMiscIdUnique 205
-mkNameG_vIdKey       = mkPreludeMiscIdUnique 206
-mkNameG_dIdKey       = mkPreludeMiscIdUnique 207
-mkNameG_tcIdKey      = mkPreludeMiscIdUnique 208
-mkNameLIdKey         = mkPreludeMiscIdUnique 209
-unTypeIdKey          = mkPreludeMiscIdUnique 210
-unTypeQIdKey         = mkPreludeMiscIdUnique 211
-unsafeTExpCoerceIdKey = mkPreludeMiscIdUnique 212
-
-
--- data Lit = ...
-charLIdKey, stringLIdKey, integerLIdKey, intPrimLIdKey, wordPrimLIdKey,
-    floatPrimLIdKey, doublePrimLIdKey, rationalLIdKey :: Unique
-charLIdKey        = mkPreludeMiscIdUnique 220
-stringLIdKey      = mkPreludeMiscIdUnique 221
-integerLIdKey     = mkPreludeMiscIdUnique 222
-intPrimLIdKey     = mkPreludeMiscIdUnique 223
-wordPrimLIdKey    = mkPreludeMiscIdUnique 224
-floatPrimLIdKey   = mkPreludeMiscIdUnique 225
-doublePrimLIdKey  = mkPreludeMiscIdUnique 226
-rationalLIdKey    = mkPreludeMiscIdUnique 227
-
-liftStringIdKey :: Unique
-liftStringIdKey     = mkPreludeMiscIdUnique 228
-
--- data Pat = ...
-litPIdKey, varPIdKey, tupPIdKey, unboxedTupPIdKey, conPIdKey, infixPIdKey, tildePIdKey, bangPIdKey,
-    asPIdKey, wildPIdKey, recPIdKey, listPIdKey, sigPIdKey, viewPIdKey :: Unique
-litPIdKey         = mkPreludeMiscIdUnique 240
-varPIdKey         = mkPreludeMiscIdUnique 241
-tupPIdKey         = mkPreludeMiscIdUnique 242
-unboxedTupPIdKey  = mkPreludeMiscIdUnique 243
-conPIdKey         = mkPreludeMiscIdUnique 244
-infixPIdKey       = mkPreludeMiscIdUnique 245
-tildePIdKey       = mkPreludeMiscIdUnique 246
-bangPIdKey        = mkPreludeMiscIdUnique 247
-asPIdKey          = mkPreludeMiscIdUnique 248
-wildPIdKey        = mkPreludeMiscIdUnique 249
-recPIdKey         = mkPreludeMiscIdUnique 250
-listPIdKey        = mkPreludeMiscIdUnique 251
-sigPIdKey         = mkPreludeMiscIdUnique 252
-viewPIdKey        = mkPreludeMiscIdUnique 253
-
--- type FieldPat = ...
-fieldPatIdKey :: Unique
-fieldPatIdKey       = mkPreludeMiscIdUnique 260
-
--- data Match = ...
-matchIdKey :: Unique
-matchIdKey          = mkPreludeMiscIdUnique 261
-
--- data Clause = ...
-clauseIdKey :: Unique
-clauseIdKey         = mkPreludeMiscIdUnique 262
-
-
--- data Exp = ...
-varEIdKey, conEIdKey, litEIdKey, appEIdKey, infixEIdKey, infixAppIdKey,
-    sectionLIdKey, sectionRIdKey, lamEIdKey, lamCaseEIdKey, tupEIdKey,
-    unboxedTupEIdKey, condEIdKey, multiIfEIdKey,
-    letEIdKey, caseEIdKey, doEIdKey, compEIdKey,
-    fromEIdKey, fromThenEIdKey, fromToEIdKey, fromThenToEIdKey,
-    listEIdKey, sigEIdKey, recConEIdKey, recUpdEIdKey, staticEIdKey :: Unique
-varEIdKey         = mkPreludeMiscIdUnique 270
-conEIdKey         = mkPreludeMiscIdUnique 271
-litEIdKey         = mkPreludeMiscIdUnique 272
-appEIdKey         = mkPreludeMiscIdUnique 273
-infixEIdKey       = mkPreludeMiscIdUnique 274
-infixAppIdKey     = mkPreludeMiscIdUnique 275
-sectionLIdKey     = mkPreludeMiscIdUnique 276
-sectionRIdKey     = mkPreludeMiscIdUnique 277
-lamEIdKey         = mkPreludeMiscIdUnique 278
-lamCaseEIdKey     = mkPreludeMiscIdUnique 279
-tupEIdKey         = mkPreludeMiscIdUnique 280
-unboxedTupEIdKey  = mkPreludeMiscIdUnique 281
-condEIdKey        = mkPreludeMiscIdUnique 282
-multiIfEIdKey     = mkPreludeMiscIdUnique 283
-letEIdKey         = mkPreludeMiscIdUnique 284
-caseEIdKey        = mkPreludeMiscIdUnique 285
-doEIdKey          = mkPreludeMiscIdUnique 286
-compEIdKey        = mkPreludeMiscIdUnique 287
-fromEIdKey        = mkPreludeMiscIdUnique 288
-fromThenEIdKey    = mkPreludeMiscIdUnique 289
-fromToEIdKey      = mkPreludeMiscIdUnique 290
-fromThenToEIdKey  = mkPreludeMiscIdUnique 291
-listEIdKey        = mkPreludeMiscIdUnique 292
-sigEIdKey         = mkPreludeMiscIdUnique 293
-recConEIdKey      = mkPreludeMiscIdUnique 294
-recUpdEIdKey      = mkPreludeMiscIdUnique 295
-staticEIdKey      = mkPreludeMiscIdUnique 296
-
--- type FieldExp = ...
-fieldExpIdKey :: Unique
-fieldExpIdKey       = mkPreludeMiscIdUnique 310
-
--- data Body = ...
-guardedBIdKey, normalBIdKey :: Unique
-guardedBIdKey     = mkPreludeMiscIdUnique 311
-normalBIdKey      = mkPreludeMiscIdUnique 312
-
--- data Guard = ...
-normalGEIdKey, patGEIdKey :: Unique
-normalGEIdKey     = mkPreludeMiscIdUnique 313
-patGEIdKey        = mkPreludeMiscIdUnique 314
-
--- data Stmt = ...
-bindSIdKey, letSIdKey, noBindSIdKey, parSIdKey :: Unique
-bindSIdKey       = mkPreludeMiscIdUnique 320
-letSIdKey        = mkPreludeMiscIdUnique 321
-noBindSIdKey     = mkPreludeMiscIdUnique 322
-parSIdKey        = mkPreludeMiscIdUnique 323
-
--- data Dec = ...
-funDIdKey, valDIdKey, dataDIdKey, newtypeDIdKey, tySynDIdKey,
-    classDIdKey, instanceDIdKey, sigDIdKey, forImpDIdKey, pragInlDIdKey,
-    pragSpecDIdKey, pragSpecInlDIdKey, pragSpecInstDIdKey, pragRuleDIdKey,
-    pragAnnDIdKey, familyNoKindDIdKey, familyKindDIdKey, defaultSigDIdKey,
-    dataInstDIdKey, newtypeInstDIdKey, tySynInstDIdKey, standaloneDerivDIdKey,
-    closedTypeFamilyKindDIdKey, closedTypeFamilyNoKindDIdKey,
-    infixLDIdKey, infixRDIdKey, infixNDIdKey, roleAnnotDIdKey :: Unique
-funDIdKey                    = mkPreludeMiscIdUnique 330
-valDIdKey                    = mkPreludeMiscIdUnique 331
-dataDIdKey                   = mkPreludeMiscIdUnique 332
-newtypeDIdKey                = mkPreludeMiscIdUnique 333
-tySynDIdKey                  = mkPreludeMiscIdUnique 334
-classDIdKey                  = mkPreludeMiscIdUnique 335
-instanceDIdKey               = mkPreludeMiscIdUnique 336
-sigDIdKey                    = mkPreludeMiscIdUnique 337
-forImpDIdKey                 = mkPreludeMiscIdUnique 338
-pragInlDIdKey                = mkPreludeMiscIdUnique 339
-pragSpecDIdKey               = mkPreludeMiscIdUnique 340
-pragSpecInlDIdKey            = mkPreludeMiscIdUnique 341
-pragSpecInstDIdKey           = mkPreludeMiscIdUnique 342
-pragRuleDIdKey               = mkPreludeMiscIdUnique 343
-pragAnnDIdKey                = mkPreludeMiscIdUnique 344
-familyNoKindDIdKey           = mkPreludeMiscIdUnique 345
-familyKindDIdKey             = mkPreludeMiscIdUnique 346
-dataInstDIdKey               = mkPreludeMiscIdUnique 347
-newtypeInstDIdKey            = mkPreludeMiscIdUnique 348
-tySynInstDIdKey              = mkPreludeMiscIdUnique 349
-closedTypeFamilyKindDIdKey   = mkPreludeMiscIdUnique 350
-closedTypeFamilyNoKindDIdKey = mkPreludeMiscIdUnique 351
-infixLDIdKey                 = mkPreludeMiscIdUnique 352
-infixRDIdKey                 = mkPreludeMiscIdUnique 353
-infixNDIdKey                 = mkPreludeMiscIdUnique 354
-roleAnnotDIdKey              = mkPreludeMiscIdUnique 355
-standaloneDerivDIdKey        = mkPreludeMiscIdUnique 356
-defaultSigDIdKey             = mkPreludeMiscIdUnique 357
-
--- type Cxt = ...
-cxtIdKey :: Unique
-cxtIdKey            = mkPreludeMiscIdUnique 360
-
--- data Strict = ...
-isStrictKey, notStrictKey, unpackedKey :: Unique
-isStrictKey         = mkPreludeMiscIdUnique 363
-notStrictKey        = mkPreludeMiscIdUnique 364
-unpackedKey         = mkPreludeMiscIdUnique 365
-
--- data Con = ...
-normalCIdKey, recCIdKey, infixCIdKey, forallCIdKey :: Unique
-normalCIdKey      = mkPreludeMiscIdUnique 370
-recCIdKey         = mkPreludeMiscIdUnique 371
-infixCIdKey       = mkPreludeMiscIdUnique 372
-forallCIdKey      = mkPreludeMiscIdUnique 373
-
--- type StrictType = ...
-strictTKey :: Unique
-strictTKey        = mkPreludeMiscIdUnique 374
-
--- type VarStrictType = ...
-varStrictTKey :: Unique
-varStrictTKey     = mkPreludeMiscIdUnique 375
-
--- data Type = ...
-forallTIdKey, varTIdKey, conTIdKey, tupleTIdKey, unboxedTupleTIdKey, arrowTIdKey,
-    listTIdKey, appTIdKey, sigTIdKey, equalityTIdKey, litTIdKey,
-    promotedTIdKey, promotedTupleTIdKey,
-    promotedNilTIdKey, promotedConsTIdKey :: Unique
-forallTIdKey        = mkPreludeMiscIdUnique 380
-varTIdKey           = mkPreludeMiscIdUnique 381
-conTIdKey           = mkPreludeMiscIdUnique 382
-tupleTIdKey         = mkPreludeMiscIdUnique 383
-unboxedTupleTIdKey  = mkPreludeMiscIdUnique 384
-arrowTIdKey         = mkPreludeMiscIdUnique 385
-listTIdKey          = mkPreludeMiscIdUnique 386
-appTIdKey           = mkPreludeMiscIdUnique 387
-sigTIdKey           = mkPreludeMiscIdUnique 388
-equalityTIdKey      = mkPreludeMiscIdUnique 389
-litTIdKey           = mkPreludeMiscIdUnique 390
-promotedTIdKey      = mkPreludeMiscIdUnique 391
-promotedTupleTIdKey = mkPreludeMiscIdUnique 392
-promotedNilTIdKey   = mkPreludeMiscIdUnique 393
-promotedConsTIdKey  = mkPreludeMiscIdUnique 394
-
--- data TyLit = ...
-numTyLitIdKey, strTyLitIdKey :: Unique
-numTyLitIdKey = mkPreludeMiscIdUnique 395
-strTyLitIdKey = mkPreludeMiscIdUnique 396
-
--- data TyVarBndr = ...
-plainTVIdKey, kindedTVIdKey :: Unique
-plainTVIdKey       = mkPreludeMiscIdUnique 397
-kindedTVIdKey      = mkPreludeMiscIdUnique 398
-
--- data Role = ...
-nominalRIdKey, representationalRIdKey, phantomRIdKey, inferRIdKey :: Unique
-nominalRIdKey          = mkPreludeMiscIdUnique 400
-representationalRIdKey = mkPreludeMiscIdUnique 401
-phantomRIdKey          = mkPreludeMiscIdUnique 402
-inferRIdKey            = mkPreludeMiscIdUnique 403
-
--- data Kind = ...
-varKIdKey, conKIdKey, tupleKIdKey, arrowKIdKey, listKIdKey, appKIdKey,
-  starKIdKey, constraintKIdKey :: Unique
-varKIdKey         = mkPreludeMiscIdUnique 404
-conKIdKey         = mkPreludeMiscIdUnique 405
-tupleKIdKey       = mkPreludeMiscIdUnique 406
-arrowKIdKey       = mkPreludeMiscIdUnique 407
-listKIdKey        = mkPreludeMiscIdUnique 408
-appKIdKey         = mkPreludeMiscIdUnique 409
-starKIdKey        = mkPreludeMiscIdUnique 410
-constraintKIdKey  = mkPreludeMiscIdUnique 411
-
--- data Callconv = ...
-cCallIdKey, stdCallIdKey, cApiCallIdKey, primCallIdKey,
-  javaScriptCallIdKey :: Unique
-cCallIdKey          = mkPreludeMiscIdUnique 420
-stdCallIdKey        = mkPreludeMiscIdUnique 421
-cApiCallIdKey       = mkPreludeMiscIdUnique 422
-primCallIdKey       = mkPreludeMiscIdUnique 423
-javaScriptCallIdKey = mkPreludeMiscIdUnique 424
-
--- data Safety = ...
-unsafeIdKey, safeIdKey, interruptibleIdKey :: Unique
-unsafeIdKey        = mkPreludeMiscIdUnique 430
-safeIdKey          = mkPreludeMiscIdUnique 431
-interruptibleIdKey = mkPreludeMiscIdUnique 432
-
--- data Inline = ...
-noInlineDataConKey, inlineDataConKey, inlinableDataConKey :: Unique
-noInlineDataConKey  = mkPreludeDataConUnique 40
-inlineDataConKey    = mkPreludeDataConUnique 41
-inlinableDataConKey = mkPreludeDataConUnique 42
-
--- data RuleMatch = ...
-conLikeDataConKey, funLikeDataConKey :: Unique
-conLikeDataConKey = mkPreludeDataConUnique 43
-funLikeDataConKey = mkPreludeDataConUnique 44
-
--- data Phases = ...
-allPhasesDataConKey, fromPhaseDataConKey, beforePhaseDataConKey :: Unique
-allPhasesDataConKey   = mkPreludeDataConUnique 45
-fromPhaseDataConKey   = mkPreludeDataConUnique 46
-beforePhaseDataConKey = mkPreludeDataConUnique 47
-
--- newtype TExp a = ...
-tExpDataConKey :: Unique
-tExpDataConKey = mkPreludeDataConUnique 48
-
--- data FunDep = ...
-funDepIdKey :: Unique
-funDepIdKey = mkPreludeMiscIdUnique 440
-
--- data FamFlavour = ...
-typeFamIdKey, dataFamIdKey :: Unique
-typeFamIdKey = mkPreludeMiscIdUnique 450
-dataFamIdKey = mkPreludeMiscIdUnique 451
-
--- data TySynEqn = ...
-tySynEqnIdKey :: Unique
-tySynEqnIdKey = mkPreludeMiscIdUnique 460
-
--- quasiquoting
-quoteExpKey, quotePatKey, quoteDecKey, quoteTypeKey :: Unique
-quoteExpKey  = mkPreludeMiscIdUnique 470
-quotePatKey  = mkPreludeMiscIdUnique 471
-quoteDecKey  = mkPreludeMiscIdUnique 472
-quoteTypeKey = mkPreludeMiscIdUnique 473
-
--- data RuleBndr = ...
-ruleVarIdKey, typedRuleVarIdKey :: Unique
-ruleVarIdKey      = mkPreludeMiscIdUnique 480
-typedRuleVarIdKey = mkPreludeMiscIdUnique 481
-
--- data AnnTarget = ...
-valueAnnotationIdKey, typeAnnotationIdKey, moduleAnnotationIdKey :: Unique
-valueAnnotationIdKey  = mkPreludeMiscIdUnique 490
-typeAnnotationIdKey   = mkPreludeMiscIdUnique 491
-moduleAnnotationIdKey = mkPreludeMiscIdUnique 492
diff --git a/src/Language/Haskell/Liquid/Desugar710/DsUtils.hs b/src/Language/Haskell/Liquid/Desugar710/DsUtils.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/DsUtils.hs
+++ /dev/null
@@ -1,840 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-Utilities for desugaring
-
-This module exports some utility functions of no great interest.
--}
-
-{-# LANGUAGE CPP #-}
-
--- | Utility functions for constructing Core syntax, principally for desugaring
-module Language.Haskell.Liquid.Desugar710.DsUtils (
-        EquationInfo(..),
-        firstPat, shiftEqns,
-
-        MatchResult(..), CanItFail(..), CaseAlt(..),
-        cantFailMatchResult, alwaysFailMatchResult,
-        extractMatchResult, combineMatchResults,
-        adjustMatchResult,  adjustMatchResultDs,
-        mkCoLetMatchResult, mkViewMatchResult, mkGuardedMatchResult,
-        matchCanFail, mkEvalMatchResult,
-        mkCoPrimCaseMatchResult, mkCoAlgCaseMatchResult, mkCoSynCaseMatchResult,
-        wrapBind, wrapBinds,
-
-        mkErrorAppDs, mkCoreAppDs, mkCoreAppsDs, mkCastDs,
-
-        seqVar,
-
-        -- LHs tuples
-        mkLHsVarPatTup, mkLHsPatTup, mkVanillaTuplePat,
-        mkBigLHsVarTup, mkBigLHsTup, mkBigLHsVarPatTup, mkBigLHsPatTup,
-
-        mkSelectorBinds,
-
-        selectSimpleMatchVarL, selectMatchVars, selectMatchVar,
-        mkOptTickBox, mkBinaryTickBox
-    ) where
-
--- #include "HsVersions.h"
-
-import {-# SOURCE #-}   Language.Haskell.Liquid.Desugar710.Match ( matchSimply )
-
-import Prelude hiding (error)
-import HsSyn
-import TcHsSyn
-import Coercion( Coercion, isReflCo )
-import TcType( tcSplitTyConApp )
-import CoreSyn
-import DsMonad
-import {-# SOURCE #-} Language.Haskell.Liquid.Desugar710.DsExpr ( dsLExpr )
-import Language.Haskell.Liquid.Types.Errors (impossible)
-
-import CoreUtils
-import MkCore
-import MkId
-import Id
-import Literal
-import TyCon
-import ConLike
-import DataCon
-import PatSyn
-import Type
-import TysPrim
-import TysWiredIn
-import BasicTypes
-import UniqSet
-import UniqSupply
-import Module
-import PrelNames
-import Outputable
-import SrcLoc
-import Util
-import DynFlags
-import FastString
-
-import TcEvidence
-
-import Control.Monad    ( zipWithM )
-
-{-
-************************************************************************
-*                                                                      *
-\subsection{ Selecting match variables}
-*                                                                      *
-************************************************************************
-
-We're about to match against some patterns.  We want to make some
-@Ids@ to use as match variables.  If a pattern has an @Id@ readily at
-hand, which should indeed be bound to the pattern as a whole, then use it;
-otherwise, make one up.
--}
-
-selectSimpleMatchVarL :: LPat Id -> DsM Id
-selectSimpleMatchVarL pat = selectMatchVar (unLoc pat)
-
--- (selectMatchVars ps tys) chooses variables of type tys
--- to use for matching ps against.  If the pattern is a variable,
--- we try to use that, to save inventing lots of fresh variables.
---
--- OLD, but interesting note:
---    But even if it is a variable, its type might not match.  Consider
---      data T a where
---        T1 :: Int -> T Int
---        T2 :: a   -> T a
---
---      f :: T a -> a -> Int
---      f (T1 i) (x::Int) = x
---      f (T2 i) (y::a)   = 0
---    Then we must not choose (x::Int) as the matching variable!
--- And nowadays we won't, because the (x::Int) will be wrapped in a CoPat
-
-selectMatchVars :: [Pat Id] -> DsM [Id]
-selectMatchVars ps = mapM selectMatchVar ps
-
-selectMatchVar :: Pat Id -> DsM Id
-selectMatchVar (BangPat pat) = selectMatchVar (unLoc pat)
-selectMatchVar (LazyPat pat) = selectMatchVar (unLoc pat)
-selectMatchVar (ParPat pat)  = selectMatchVar (unLoc pat)
-selectMatchVar (VarPat var)  = return (localiseId var)  -- Note [Localise pattern binders]
-selectMatchVar (AsPat var _) = return (unLoc var)
-selectMatchVar other_pat     = newSysLocalDs (hsPatType other_pat)
-                                  -- OK, better make up one...
-
-{-
-Note [Localise pattern binders]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider     module M where
-               [Just a] = e
-After renaming it looks like
-             module M where
-               [Just M.a] = e
-
-We don't generalise, since it's a pattern binding, monomorphic, etc,
-so after desugaring we may get something like
-             M.a = case e of (v:_) ->
-                   case v of Just M.a -> M.a
-Notice the "M.a" in the pattern; after all, it was in the original
-pattern.  However, after optimisation those pattern binders can become
-let-binders, and then end up floated to top level.  They have a
-different *unique* by then (the simplifier is good about maintaining
-proper scoping), but it's BAD to have two top-level bindings with the
-External Name M.a, because that turns into two linker symbols for M.a.
-It's quite rare for this to actually *happen* -- the only case I know
-of is tc003 compiled with the 'hpc' way -- but that only makes it
-all the more annoying.
-
-To avoid this, we craftily call 'localiseId' in the desugarer, which
-simply turns the External Name for the Id into an Internal one, but
-doesn't change the unique.  So the desugarer produces this:
-             M.a{r8} = case e of (v:_) ->
-                       case v of Just a{r8} -> M.a{r8}
-The unique is still 'r8', but the binding site in the pattern
-is now an Internal Name.  Now the simplifier's usual mechanisms
-will propagate that Name to all the occurrence sites, as well as
-un-shadowing it, so we'll get
-             M.a{r8} = case e of (v:_) ->
-                       case v of Just a{s77} -> a{s77}
-In fact, even CoreSubst.simplOptExpr will do this, and simpleOptExpr
-runs on the output of the desugarer, so all is well by the end of
-the desugaring pass.
-
-
-************************************************************************
-*                                                                      *
-* type synonym EquationInfo and access functions for its pieces        *
-*                                                                      *
-************************************************************************
-\subsection[EquationInfo-synonym]{@EquationInfo@: a useful synonym}
-
-The ``equation info'' used by @match@ is relatively complicated and
-worthy of a type synonym and a few handy functions.
--}
-
-firstPat :: EquationInfo -> Pat Id
-firstPat eqn = {- ASSERT( notNull (eqn_pats eqn) ) -} head (eqn_pats eqn)
-
-shiftEqns :: [EquationInfo] -> [EquationInfo]
--- Drop the first pattern in each equation
-shiftEqns eqns = [ eqn { eqn_pats = tail (eqn_pats eqn) } | eqn <- eqns ]
-
--- Functions on MatchResults
-
-matchCanFail :: MatchResult -> Bool
-matchCanFail (MatchResult CanFail _)  = True
-matchCanFail (MatchResult CantFail _) = False
-
-alwaysFailMatchResult :: MatchResult
-alwaysFailMatchResult = MatchResult CanFail (\fail -> return fail)
-
-cantFailMatchResult :: CoreExpr -> MatchResult
-cantFailMatchResult expr = MatchResult CantFail (\_ -> return expr)
-
-extractMatchResult :: MatchResult -> CoreExpr -> DsM CoreExpr
-extractMatchResult (MatchResult CantFail match_fn) _
-  = match_fn (impossible Nothing "It can't fail!")
-
-extractMatchResult (MatchResult CanFail match_fn) fail_expr = do
-    (fail_bind, if_it_fails) <- mkFailurePair fail_expr
-    body <- match_fn if_it_fails
-    return (mkCoreLet fail_bind body)
-
-
-combineMatchResults :: MatchResult -> MatchResult -> MatchResult
-combineMatchResults (MatchResult CanFail      body_fn1)
-                    (MatchResult can_it_fail2 body_fn2)
-  = MatchResult can_it_fail2 body_fn
-  where
-    body_fn fail = do body2 <- body_fn2 fail
-                      (fail_bind, duplicatable_expr) <- mkFailurePair body2
-                      body1 <- body_fn1 duplicatable_expr
-                      return (Let fail_bind body1)
-
-combineMatchResults match_result1@(MatchResult CantFail _) _
-  = match_result1
-
-adjustMatchResult :: DsWrapper -> MatchResult -> MatchResult
-adjustMatchResult encl_fn (MatchResult can_it_fail body_fn)
-  = MatchResult can_it_fail (\fail -> encl_fn <$> body_fn fail)
-
-adjustMatchResultDs :: (CoreExpr -> DsM CoreExpr) -> MatchResult -> MatchResult
-adjustMatchResultDs encl_fn (MatchResult can_it_fail body_fn)
-  = MatchResult can_it_fail (\fail -> encl_fn =<< body_fn fail)
-
-wrapBinds :: [(Var,Var)] -> CoreExpr -> CoreExpr
-wrapBinds [] e = e
-wrapBinds ((new,old):prs) e = wrapBind new old (wrapBinds prs e)
-
-wrapBind :: Var -> Var -> CoreExpr -> CoreExpr
-wrapBind new old body   -- NB: this function must deal with term
-  | new==old    = body  -- variables, type variables or coercion variables
-  | otherwise   = Let (NonRec new (varToCoreExpr old)) body
-
-seqVar :: Var -> CoreExpr -> CoreExpr
-seqVar var body = Case (Var var) var (exprType body)
-                        [(DEFAULT, [], body)]
-
-mkCoLetMatchResult :: CoreBind -> MatchResult -> MatchResult
-mkCoLetMatchResult bind = adjustMatchResult (mkCoreLet bind)
-
--- (mkViewMatchResult var' viewExpr var mr) makes the expression
--- let var' = viewExpr var in mr
-mkViewMatchResult :: Id -> CoreExpr -> Id -> MatchResult -> MatchResult
-mkViewMatchResult var' viewExpr var =
-    adjustMatchResult (mkCoreLet (NonRec var' (mkCoreAppDs viewExpr (Var var))))
-
-mkEvalMatchResult :: Id -> Type -> MatchResult -> MatchResult
-mkEvalMatchResult var ty
-  = adjustMatchResult (\e -> Case (Var var) var ty [(DEFAULT, [], e)])
-
-mkGuardedMatchResult :: CoreExpr -> MatchResult -> MatchResult
-mkGuardedMatchResult pred_expr (MatchResult _ body_fn)
-  = MatchResult CanFail (\fail -> do body <- body_fn fail
-                                     return (mkIfThenElse pred_expr body fail))
-
-mkCoPrimCaseMatchResult :: Id                           -- Scrutinee
-                    -> Type                             -- Type of the case
-                    -> [(Literal, MatchResult)]         -- Alternatives
-                    -> MatchResult                      -- Literals are all unlifted
-mkCoPrimCaseMatchResult var ty match_alts
-  = MatchResult CanFail mk_case
-  where
-    mk_case fail = do
-        alts <- mapM (mk_alt fail) sorted_alts
-        return (Case (Var var) var ty ((DEFAULT, [], fail) : alts))
-
-    sorted_alts = sortWith fst match_alts       -- Right order for a Case
-    mk_alt fail (lit, MatchResult _ body_fn)
-       = -- ASSERT( not (litIsLifted lit) )
-         do body <- body_fn fail
-            return (LitAlt lit, [], body)
-
-data CaseAlt a = MkCaseAlt{ alt_pat :: a,
-                            alt_bndrs :: [CoreBndr],
-                            alt_wrapper :: HsWrapper,
-                            alt_result :: MatchResult }
-
-mkCoAlgCaseMatchResult
-  :: DynFlags
-  -> Id                 -- Scrutinee
-  -> Type               -- Type of exp
-  -> [CaseAlt DataCon]  -- Alternatives (bndrs *include* tyvars, dicts)
-  -> MatchResult
-mkCoAlgCaseMatchResult dflags var ty match_alts
-  | isNewtype  -- Newtype case; use a let
-  = -- ASSERT( null (tail match_alts) && null (tail arg_ids1) )
-    mkCoLetMatchResult (NonRec arg_id1 newtype_rhs) match_result1
-
-  | isPArrFakeAlts match_alts
-  = MatchResult CanFail $ mkPArrCase dflags var ty (sort_alts match_alts)
-  | otherwise
-  = mkDataConCase var ty match_alts
-  where
-    isNewtype = isNewTyCon (dataConTyCon (alt_pat alt1))
-
-        -- [Interesting: because of GADTs, we can't rely on the type of
-        --  the scrutinised Id to be sufficiently refined to have a TyCon in it]
-
-    alt1@MkCaseAlt{ alt_bndrs = arg_ids1, alt_result = match_result1 }
-      = {- ASSERT( notNull match_alts ) -} head match_alts
-    -- Stuff for newtype
-    arg_id1       = {- ASSERT( notNull arg_ids1 ) -} head arg_ids1
-    var_ty        = idType var
-    (tc, ty_args) = tcSplitTyConApp var_ty      -- Don't look through newtypes
-                                                -- (not that splitTyConApp does, these days)
-    newtype_rhs = unwrapNewTypeBody tc ty_args (Var var)
-
-        --- Stuff for parallel arrays
-        --
-        -- Concerning `isPArrFakeAlts':
-        --
-        --  * it is *not* sufficient to just check the type of the type
-        --   constructor, as we have to be careful not to confuse the real
-        --   representation of parallel arrays with the fake constructors;
-        --   moreover, a list of alternatives must not mix fake and real
-        --   constructors (this is checked earlier on)
-        --
-        -- FIXME: We actually go through the whole list and make sure that
-        --        either all or none of the constructors are fake parallel
-        --        array constructors.  This is to spot equations that mix fake
-        --        constructors with the real representation defined in
-        --        `PrelPArr'.  It would be nicer to spot this situation
-        --        earlier and raise a proper error message, but it can really
-        --        only happen in `PrelPArr' anyway.
-        --
-
-    isPArrFakeAlts :: [CaseAlt DataCon] -> Bool
-    isPArrFakeAlts [alt] = isPArrFakeCon (alt_pat alt)
-    isPArrFakeAlts (alt:alts) =
-      case (isPArrFakeCon (alt_pat alt), isPArrFakeAlts alts) of
-        (True , True ) -> True
-        (False, False) -> False
-        _              -> panic "DsUtils: you may not mix `[:...:]' with `PArr' patterns"
-    isPArrFakeAlts [] = panic "DsUtils: unexpectedly found an empty list of PArr fake alternatives"
-
-mkCoSynCaseMatchResult :: Id -> Type -> CaseAlt PatSyn -> MatchResult
-mkCoSynCaseMatchResult var ty alt = MatchResult CanFail $ mkPatSynCase var ty alt
-
-sort_alts :: [CaseAlt DataCon] -> [CaseAlt DataCon]
-sort_alts = sortWith (dataConTag . alt_pat)
-
-mkPatSynCase :: Id -> Type -> CaseAlt PatSyn -> CoreExpr -> DsM CoreExpr
-mkPatSynCase var ty alt fail = do
-    matcher <- dsLExpr $ mkLHsWrap wrapper $ nlHsTyApp matcher [ty]
-    let MatchResult _ mkCont = match_result
-    cont <- mkCoreLams bndrs <$> mkCont fail
-    return $ mkCoreAppsDs matcher [Var var, ensure_unstrict cont, Lam voidArgId fail]
-  where
-    MkCaseAlt{ alt_pat = psyn,
-               alt_bndrs = bndrs,
-               alt_wrapper = wrapper,
-               alt_result = match_result} = alt
-    (matcher, needs_void_lam) = patSynMatcher psyn
-
-    -- See Note [Matchers and builders for pattern synonyms] in PatSyns
-    -- on these extra Void# arguments
-    ensure_unstrict cont | needs_void_lam = Lam voidArgId cont
-                         | otherwise      = cont
-
-mkDataConCase :: Id -> Type -> [CaseAlt DataCon] -> MatchResult
-mkDataConCase _   _  []            = panic "mkDataConCase: no alternatives"
-mkDataConCase var ty alts@(alt1:_) = MatchResult fail_flag mk_case
-  where
-    con1          = alt_pat alt1
-    tycon         = dataConTyCon con1
-    data_cons     = tyConDataCons tycon
-    match_results = map alt_result alts
-
-    sorted_alts :: [CaseAlt DataCon]
-    sorted_alts  = sort_alts alts
-
-    var_ty       = idType var
-    (_, ty_args) = tcSplitTyConApp var_ty -- Don't look through newtypes
-                                          -- (not that splitTyConApp does, these days)
-
-    mk_case :: CoreExpr -> DsM CoreExpr
-    mk_case fail = do
-        alts <- mapM (mk_alt fail) sorted_alts
-        return $ mkWildCase (Var var) (idType var) ty (mk_default fail ++ alts)
-
-    mk_alt :: CoreExpr -> CaseAlt DataCon -> DsM CoreAlt
-    mk_alt fail MkCaseAlt{ alt_pat = con,
-                           alt_bndrs = args,
-                           alt_result = MatchResult _ body_fn }
-      = do { body <- body_fn fail
-           ; case dataConBoxer con of {
-                Nothing -> return (DataAlt con, args, body) ;
-                Just (DCB boxer) ->
-        do { us <- newUniqueSupply
-           ; let (rep_ids, binds) = initUs_ us (boxer ty_args args)
-           ; return (DataAlt con, rep_ids, mkLets binds body) } } }
-
-    mk_default :: CoreExpr -> [CoreAlt]
-    mk_default fail | exhaustive_case = []
-                    | otherwise       = [(DEFAULT, [], fail)]
-
-    fail_flag :: CanItFail
-    fail_flag | exhaustive_case
-              = foldr orFail CantFail [can_it_fail | MatchResult can_it_fail _ <- match_results]
-              | otherwise
-              = CanFail
-
-    mentioned_constructors = mkUniqSet $ map alt_pat alts
-    un_mentioned_constructors
-        = mkUniqSet data_cons `minusUniqSet` mentioned_constructors
-    exhaustive_case = isEmptyUniqSet un_mentioned_constructors
-
---- Stuff for parallel arrays
---
---  * the following is to desugar cases over fake constructors for
---   parallel arrays, which are introduced by `tidy1' in the `PArrPat'
---   case
---
-mkPArrCase :: DynFlags -> Id -> Type -> [CaseAlt DataCon] -> CoreExpr -> DsM CoreExpr
-mkPArrCase dflags var ty sorted_alts fail = do
-    lengthP <- dsDPHBuiltin lengthPVar
-    alt <- unboxAlt
-    return (mkWildCase (len lengthP) intTy ty [alt])
-  where
-    elemTy      = case splitTyConApp (idType var) of
-        (_, [elemTy]) -> elemTy
-        _             -> panic panicMsg
-    panicMsg    = "DsUtils.mkCoAlgCaseMatchResult: not a parallel array?"
-    len lengthP = mkApps (Var lengthP) [Type elemTy, Var var]
-    --
-    unboxAlt = do
-        l      <- newSysLocalDs intPrimTy
-        indexP <- dsDPHBuiltin indexPVar
-        alts   <- mapM (mkAlt indexP) sorted_alts
-        return (DataAlt intDataCon, [l], mkWildCase (Var l) intPrimTy ty (dft : alts))
-      where
-        dft  = (DEFAULT, [], fail)
-
-    --
-    -- each alternative matches one array length (corresponding to one
-    -- fake array constructor), so the match is on a literal; each
-    -- alternative's body is extended by a local binding for each
-    -- constructor argument, which are bound to array elements starting
-    -- with the first
-    --
-    mkAlt indexP alt@MkCaseAlt{alt_result = MatchResult _ bodyFun} = do
-        body <- bodyFun fail
-        return (LitAlt lit, [], mkCoreLets binds body)
-      where
-        lit   = MachInt $ toInteger (dataConSourceArity (alt_pat alt))
-        binds = [NonRec arg (indexExpr i) | (i, arg) <- zip [1..] (alt_bndrs alt)]
-        --
-        indexExpr i = mkApps (Var indexP) [Type elemTy, Var var, mkIntExpr dflags i]
-
-{-
-************************************************************************
-*                                                                      *
-\subsection{Desugarer's versions of some Core functions}
-*                                                                      *
-************************************************************************
--}
-
-mkErrorAppDs :: Id              -- The error function
-             -> Type            -- Type to which it should be applied
-             -> SDoc            -- The error message string to pass
-             -> DsM CoreExpr
-
-mkErrorAppDs err_id ty msg = do
-    src_loc <- getSrcSpanDs
-    dflags <- getDynFlags
-    let
-        full_msg = showSDoc dflags (hcat [ppr src_loc, text "|", msg])
-        core_msg = Lit (mkMachString full_msg)
-        -- mkMachString returns a result of type String#
-    return (mkApps (Var err_id) [Type ty, core_msg])
-
-{-
-'mkCoreAppDs' and 'mkCoreAppsDs' hand the special-case desugaring of 'seq'.
-
-Note [Desugaring seq (1)]  cf Trac #1031
-~~~~~~~~~~~~~~~~~~~~~~~~~
-   f x y = x `seq` (y `seq` (# x,y #))
-
-The [CoreSyn let/app invariant] means that, other things being equal, because
-the argument to the outer 'seq' has an unlifted type, we'll use call-by-value thus:
-
-   f x y = case (y `seq` (# x,y #)) of v -> x `seq` v
-
-But that is bad for two reasons:
-  (a) we now evaluate y before x, and
-  (b) we can't bind v to an unboxed pair
-
-Seq is very, very special!  So we recognise it right here, and desugar to
-        case x of _ -> case y of _ -> (# x,y #)
-
-Note [Desugaring seq (2)]  cf Trac #2273
-~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
-   let chp = case b of { True -> fst x; False -> 0 }
-   in chp `seq` ...chp...
-Here the seq is designed to plug the space leak of retaining (snd x)
-for too long.
-
-If we rely on the ordinary inlining of seq, we'll get
-   let chp = case b of { True -> fst x; False -> 0 }
-   case chp of _ { I# -> ...chp... }
-
-But since chp is cheap, and the case is an alluring contet, we'll
-inline chp into the case scrutinee.  Now there is only one use of chp,
-so we'll inline a second copy.  Alas, we've now ruined the purpose of
-the seq, by re-introducing the space leak:
-    case (case b of {True -> fst x; False -> 0}) of
-      I# _ -> ...case b of {True -> fst x; False -> 0}...
-
-We can try to avoid doing this by ensuring that the binder-swap in the
-case happens, so we get his at an early stage:
-   case chp of chp2 { I# -> ...chp2... }
-But this is fragile.  The real culprit is the source program.  Perhaps we
-should have said explicitly
-   let !chp2 = chp in ...chp2...
-
-But that's painful.  So the code here does a little hack to make seq
-more robust: a saturated application of 'seq' is turned *directly* into
-the case expression, thus:
-   x  `seq` e2 ==> case x of x -> e2    -- Note shadowing!
-   e1 `seq` e2 ==> case x of _ -> e2
-
-So we desugar our example to:
-   let chp = case b of { True -> fst x; False -> 0 }
-   case chp of chp { I# -> ...chp... }
-And now all is well.
-
-The reason it's a hack is because if you define mySeq=seq, the hack
-won't work on mySeq.
-
-Note [Desugaring seq (3)] cf Trac #2409
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The isLocalId ensures that we don't turn
-        True `seq` e
-into
-        case True of True { ... }
-which stupidly tries to bind the datacon 'True'.
--}
-
-mkCoreAppDs  :: CoreExpr -> CoreExpr -> CoreExpr
-mkCoreAppDs (Var f `App` Type ty1 `App` Type ty2 `App` arg1) arg2
-  | f `hasKey` seqIdKey            -- Note [Desugaring seq (1), (2)]
-  = Case arg1 case_bndr ty2 [(DEFAULT,[],arg2)]
-  where
-    case_bndr = case arg1 of
-                   Var v1 | isLocalId v1 -> v1        -- Note [Desugaring seq (2) and (3)]
-                   _                     -> mkWildValBinder ty1
-
-mkCoreAppDs fun arg = mkCoreApp fun arg  -- The rest is done in MkCore
-
-mkCoreAppsDs :: CoreExpr -> [CoreExpr] -> CoreExpr
-mkCoreAppsDs fun args = foldl mkCoreAppDs fun args
-
-mkCastDs :: CoreExpr -> Coercion -> CoreExpr
--- We define a desugarer-specific verison of CoreUtils.mkCast,
--- because in the immediate output of the desugarer, we can have
--- apparently-mis-matched coercions:  E.g.
---     let a = b
---     in (x :: a) |> (co :: b ~ Int)
--- Lint know about type-bindings for let and does not complain
--- So here we do not make the assertion checks that we make in
--- CoreUtils.mkCast; and we do less peephole optimisation too
-mkCastDs e co | isReflCo co = e
-              | otherwise   = Cast e co
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[mkSelectorBind]{Make a selector bind}
-*                                                                      *
-************************************************************************
-
-This is used in various places to do with lazy patterns.
-For each binder $b$ in the pattern, we create a binding:
-\begin{verbatim}
-    b = case v of pat' -> b'
-\end{verbatim}
-where @pat'@ is @pat@ with each binder @b@ cloned into @b'@.
-
-ToDo: making these bindings should really depend on whether there's
-much work to be done per binding.  If the pattern is complex, it
-should be de-mangled once, into a tuple (and then selected from).
-Otherwise the demangling can be in-line in the bindings (as here).
-
-Boring!  Boring!  One error message per binder.  The above ToDo is
-even more helpful.  Something very similar happens for pattern-bound
-expressions.
-
-Note [mkSelectorBinds]
-~~~~~~~~~~~~~~~~~~~~~~
-Given   p = e, where p binds x,y
-we are going to make EITHER
-
-EITHER (A)   v = e   (where v is fresh)
-             x = case v of p -> x
-             y = case v of p -> y
-
-OR (B)       t = case e of p -> (x,y)
-             x = case t of (x,_) -> x
-             y = case t of (_,y) -> y
-
-We do (A) when
- * Matching the pattern is cheap so we don't mind
-   doing it twice.
- * Or if the pattern binds only one variable (so we'll only
-   match once)
- * AND the pattern can't fail (else we tiresomely get two inexhaustive
-   pattern warning messages)
-
-Otherwise we do (B).  Really (A) is just an optimisation for very common
-cases like
-     Just x = e
-     (p,q) = e
--}
-
-mkSelectorBinds :: [[Tickish Id]] -- ticks to add, possibly
-                -> LPat Id      -- The pattern
-                -> CoreExpr     -- Expression to which the pattern is bound
-                -> DsM [(Id,CoreExpr)]
-
-mkSelectorBinds ticks (L _ (VarPat v)) val_expr
-  = return [(v, case ticks of
-                  [t] -> mkOptTickBox t val_expr
-                  _   -> val_expr)]
-
-mkSelectorBinds ticks pat val_expr
-  | null binders
-  = return []
-
-  | isSingleton binders || is_simple_lpat pat
-    -- See Note [mkSelectorBinds]
-  = do { val_var <- newSysLocalDs (hsLPatType pat)
-        -- Make up 'v' in Note [mkSelectorBinds]
-        -- NB: give it the type of *pattern* p, not the type of the *rhs* e.
-        -- This does not matter after desugaring, but there's a subtle
-        -- issue with implicit parameters. Consider
-        --      (x,y) = ?i
-        -- Then, ?i is given type {?i :: Int}, a PredType, which is opaque
-        -- to the desugarer.  (Why opaque?  Because newtypes have to be.  Why
-        -- does it get that type?  So that when we abstract over it we get the
-        -- right top-level type  (?i::Int) => ...)
-        --
-        -- So to get the type of 'v', use the pattern not the rhs.  Often more
-        -- efficient too.
-
-        -- For the error message we make one error-app, to avoid duplication.
-        -- But we need it at different types, so we make it polymorphic:
-        --     err_var = /\a. iRREFUT_PAT_ERR a "blah blah blah"
-       ; err_app <- mkErrorAppDs iRREFUT_PAT_ERROR_ID alphaTy (ppr pat)
-       ; err_var <- newSysLocalDs (mkForAllTy alphaTyVar alphaTy)
-       ; binds   <- zipWithM (mk_bind val_var err_var) ticks' binders
-       ; return ( (val_var, val_expr) :
-                  (err_var, Lam alphaTyVar err_app) :
-                  binds ) }
-
-  | otherwise
-  = do { error_expr <- mkErrorAppDs iRREFUT_PAT_ERROR_ID   tuple_ty (ppr pat)
-       ; tuple_expr <- matchSimply val_expr PatBindRhs pat local_tuple error_expr
-       ; tuple_var <- newSysLocalDs tuple_ty
-       ; let mk_tup_bind tick binder
-              = (binder, mkOptTickBox tick $
-                            mkTupleSelector local_binders binder
-                                            tuple_var (Var tuple_var))
-       ; return ( (tuple_var, tuple_expr) : zipWith mk_tup_bind ticks' binders ) }
-  where
-    binders       = collectPatBinders pat
-    ticks'        = ticks ++ repeat []
-
-    local_binders = map localiseId binders      -- See Note [Localise pattern binders]
-    local_tuple   = mkBigCoreVarTup binders
-    tuple_ty      = exprType local_tuple
-
-    mk_bind scrut_var err_var tick bndr_var = do
-    -- (mk_bind sv err_var) generates
-    --          bv = case sv of { pat -> bv; other -> err_var @ type-of-bv }
-    -- Remember, pat binds bv
-        rhs_expr <- matchSimply (Var scrut_var) PatBindRhs pat
-                                (Var bndr_var) error_expr
-        return (bndr_var, mkOptTickBox tick rhs_expr)
-      where
-        error_expr = Var err_var `App` Type (idType bndr_var)
-
-    is_simple_lpat p = is_simple_pat (unLoc p)
-
-    is_simple_pat (TuplePat ps Boxed _) = all is_triv_lpat ps
-    is_simple_pat pat@(ConPatOut{})     = case unLoc (pat_con pat) of
-        RealDataCon con -> isProductTyCon (dataConTyCon con)
-                           && all is_triv_lpat (hsConPatArgs (pat_args pat))
-        PatSynCon _     -> False
-    is_simple_pat (VarPat _)                   = True
-    is_simple_pat (ParPat p)                   = is_simple_lpat p
-    is_simple_pat _                                    = False
-
-    is_triv_lpat p = is_triv_pat (unLoc p)
-
-    is_triv_pat (VarPat _)  = True
-    is_triv_pat (WildPat _) = True
-    is_triv_pat (ParPat p)  = is_triv_lpat p
-    is_triv_pat _           = False
-
-{-
-Creating big tuples and their types for full Haskell expressions.
-They work over *Ids*, and create tuples replete with their types,
-which is whey they are not in HsUtils.
--}
-
-mkLHsPatTup :: [LPat Id] -> LPat Id
-mkLHsPatTup []     = noLoc $ mkVanillaTuplePat [] Boxed
-mkLHsPatTup [lpat] = lpat
-mkLHsPatTup lpats  = L (getLoc (head lpats)) $
-                     mkVanillaTuplePat lpats Boxed
-
-mkLHsVarPatTup :: [Id] -> LPat Id
-mkLHsVarPatTup bs  = mkLHsPatTup (map nlVarPat bs)
-
-mkVanillaTuplePat :: [OutPat Id] -> Boxity -> Pat Id
--- A vanilla tuple pattern simply gets its type from its sub-patterns
-mkVanillaTuplePat pats box = TuplePat pats box (map hsLPatType pats)
-
--- The Big equivalents for the source tuple expressions
-mkBigLHsVarTup :: [Id] -> LHsExpr Id
-mkBigLHsVarTup ids = mkBigLHsTup (map nlHsVar ids)
-
-mkBigLHsTup :: [LHsExpr Id] -> LHsExpr Id
-mkBigLHsTup = mkChunkified mkLHsTupleExpr
-
--- The Big equivalents for the source tuple patterns
-mkBigLHsVarPatTup :: [Id] -> LPat Id
-mkBigLHsVarPatTup bs = mkBigLHsPatTup (map nlVarPat bs)
-
-mkBigLHsPatTup :: [LPat Id] -> LPat Id
-mkBigLHsPatTup = mkChunkified mkLHsPatTup
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[mkFailurePair]{Code for pattern-matching and other failures}
-*                                                                      *
-************************************************************************
-
-Generally, we handle pattern matching failure like this: let-bind a
-fail-variable, and use that variable if the thing fails:
-\begin{verbatim}
-        let fail.33 = error "Help"
-        in
-        case x of
-                p1 -> ...
-                p2 -> fail.33
-                p3 -> fail.33
-                p4 -> ...
-\end{verbatim}
-Then
-\begin{itemize}
-\item
-If the case can't fail, then there'll be no mention of @fail.33@, and the
-simplifier will later discard it.
-
-\item
-If it can fail in only one way, then the simplifier will inline it.
-
-\item
-Only if it is used more than once will the let-binding remain.
-\end{itemize}
-
-There's a problem when the result of the case expression is of
-unboxed type.  Then the type of @fail.33@ is unboxed too, and
-there is every chance that someone will change the let into a case:
-\begin{verbatim}
-        case error "Help" of
-          fail.33 -> case ....
-\end{verbatim}
-
-which is of course utterly wrong.  Rather than drop the condition that
-only boxed types can be let-bound, we just turn the fail into a function
-for the primitive case:
-\begin{verbatim}
-        let fail.33 :: Void -> Int#
-            fail.33 = \_ -> error "Help"
-        in
-        case x of
-                p1 -> ...
-                p2 -> fail.33 void
-                p3 -> fail.33 void
-                p4 -> ...
-\end{verbatim}
-
-Now @fail.33@ is a function, so it can be let-bound.
--}
-
-mkFailurePair :: CoreExpr       -- Result type of the whole case expression
-              -> DsM (CoreBind, -- Binds the newly-created fail variable
-                                -- to \ _ -> expression
-                      CoreExpr) -- Fail variable applied to realWorld#
--- See Note [Failure thunks and CPR]
-mkFailurePair expr
-  = do { fail_fun_var <- newFailLocalDs (voidPrimTy `mkFunTy` ty)
-       ; fail_fun_arg <- newSysLocalDs voidPrimTy
-       ; let real_arg = setOneShotLambda fail_fun_arg
-       ; return (NonRec fail_fun_var (Lam real_arg expr),
-                 App (Var fail_fun_var) (Var voidPrimId)) }
-  where
-    ty = exprType expr
-
-{-
-Note [Failure thunks and CPR]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When we make a failure point we ensure that it
-does not look like a thunk. Example:
-
-   let fail = \rw -> error "urk"
-   in case x of
-        [] -> fail realWorld#
-        (y:ys) -> case ys of
-                    [] -> fail realWorld#
-                    (z:zs) -> (y,z)
-
-Reason: we know that a failure point is always a "join point" and is
-entered at most once.  Adding a dummy 'realWorld' token argument makes
-it clear that sharing is not an issue.  And that in turn makes it more
-CPR-friendly.  This matters a lot: if you don't get it right, you lose
-the tail call property.  For example, see Trac #3403.
--}
-
-mkOptTickBox :: [Tickish Id] -> CoreExpr -> CoreExpr
-mkOptTickBox = flip (foldr Tick)
-
-mkBinaryTickBox :: Int -> Int -> CoreExpr -> DsM CoreExpr
-mkBinaryTickBox ixT ixF e = do
-       uq <- newUnique
-       this_mod <- getModule
-       let bndr1 = mkSysLocal (fsLit "t1") uq boolTy
-       let
-           falseBox = Tick (HpcTick this_mod ixF) (Var falseDataConId)
-           trueBox  = Tick (HpcTick this_mod ixT) (Var trueDataConId)
-       --
-       return $ Case e bndr1 boolTy
-                       [ (DataAlt falseDataCon, [], falseBox)
-                       , (DataAlt trueDataCon,  [], trueBox)
-                       ]
diff --git a/src/Language/Haskell/Liquid/Desugar710/HscMain.hs b/src/Language/Haskell/Liquid/Desugar710/HscMain.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/HscMain.hs
+++ /dev/null
@@ -1,95 +0,0 @@
--------------------------------------------------------------------------------
---
--- | Main API for compiling plain Haskell source code.
---
--- This module implements compilation of a Haskell source. It is
--- /not/ concerned with preprocessing of source files; this is handled
--- in "DriverPipeline".
---
--- There are various entry points depending on what mode we're in:
--- "batch" mode (@--make@), "one-shot" mode (@-c@, @-S@ etc.), and
--- "interactive" mode (GHCi). There are also entry points for
--- individual passes: parsing, typechecking/renaming, desugaring, and
--- simplification.
---
--- All the functions here take an 'HscEnv' as a parameter, but none of
--- them return a new one: 'HscEnv' is treated as an immutable value
--- from here on in (although it has mutable components, for the
--- caches).
---
--- Warning messages are dealt with consistently throughout this API:
--- during compilation warnings are collected, and before any function
--- in @HscMain@ returns, the warnings are either printed, or turned
--- into a real compialtion error if the @-Werror@ flag is enabled.
---
--- (c) The GRASP/AQUA Project, Glasgow University, 1993-2000
---
--------------------------------------------------------------------------------
-
-module Language.Haskell.Liquid.Desugar710.HscMain (hscDesugarWithLoc) where
-
-import Language.Haskell.Liquid.Desugar710.Desugar (deSugarWithLoc)
-import Prelude hiding (error)
-import Module
-import Lexer
-import TcRnMonad
-
-import ErrUtils
-
-import HscTypes
-import Bag
-import Exception
-
-
--- -----------------------------------------------------------------------------
-
-getWarnings :: Hsc WarningMessages
-getWarnings = Hsc $ \_ w -> return (w, w)
-
-clearWarnings :: Hsc ()
-clearWarnings = Hsc $ \_ _ -> return ((), emptyBag)
-
-logWarnings :: WarningMessages -> Hsc ()
-logWarnings w = Hsc $ \_ w0 -> return ((), w0 `unionBags` w)
-
-
-
--- | Throw some errors.
-throwErrors :: ErrorMessages -> Hsc a
-throwErrors = liftIO . throwIO . mkSrcErr
-
---
--- | Convert a typechecked module to Core
-hscDesugarWithLoc :: HscEnv -> ModSummary -> TcGblEnv -> IO ModGuts
-hscDesugarWithLoc hsc_env mod_summary tc_result =
-    runHsc hsc_env $ hscDesugar' (ms_location mod_summary) tc_result
-
-hscDesugar' :: ModLocation -> TcGblEnv -> Hsc ModGuts
-hscDesugar' mod_location tc_result = do
-    hsc_env <- getHscEnv
-    r <- ioMsgMaybe $
-      {-# SCC "deSugar" #-}
-      deSugarWithLoc hsc_env mod_location tc_result
-
-    -- always check -Werror after desugaring, this is the last opportunity for
-    -- warnings to arise before the backend.
-    handleWarnings
-    return r
-
-getHscEnv :: Hsc HscEnv
-getHscEnv = Hsc $ \e w -> return (e, w)
-
-handleWarnings :: Hsc ()
-handleWarnings = do
-    dflags <- getDynFlags
-    w <- getWarnings
-    liftIO $ printOrThrowWarnings dflags w
-    clearWarnings
-
-ioMsgMaybe :: IO (Messages, Maybe a) -> Hsc a
-ioMsgMaybe ioA = do
-    ((warns,errs), mb_r) <- liftIO ioA
-    logWarnings warns
-    case mb_r of
-        Nothing -> throwErrors errs
-        Just r  -> return r
diff --git a/src/Language/Haskell/Liquid/Desugar710/Match.hs b/src/Language/Haskell/Liquid/Desugar710/Match.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/Match.hs
+++ /dev/null
@@ -1,1091 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-The @match@ function
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.Match ( match, matchEquations, matchWrapper, matchSimply, matchSinglePat ) where
-
--- #include "HsVersions.h"
-
-import {-#SOURCE#-} Language.Haskell.Liquid.Desugar710.DsExpr (dsLExpr, dsExpr)
-import Prelude hiding (error)
-import DynFlags
-import HsSyn
-import TcHsSyn
-import TcEvidence
-import TcRnMonad
-import Check
-import CoreSyn
-import Literal
-import CoreUtils
-import MkCore
-import DsMonad
-import Language.Haskell.Liquid.Desugar710.DsBinds
-import Language.Haskell.Liquid.Desugar710.DsGRHSs
-import Language.Haskell.Liquid.Desugar710.DsUtils
-import Id
-import ConLike
-import DataCon
-import PatSyn
-import Language.Haskell.Liquid.Desugar710.MatchCon
-import Language.Haskell.Liquid.Desugar710.MatchLit
-import Type
-import TyCon( isNewTyCon )
-import TysWiredIn
-import ListSetOps
-import SrcLoc
-import Maybes
-import Util
-import Name
-import Outputable
-import BasicTypes ( boxityNormalTupleSort, isGenerated )
-import FastString
-
-import Control.Monad( when )
-import qualified Data.Map as Map
-
-{-
-This function is a wrapper of @match@, it must be called from all the parts where
-it was called match, but only substitutes the first call, ....
-if the associated flags are declared, warnings will be issued.
-It can not be called matchWrapper because this name already exists :-(
-
-JJCQ 30-Nov-1997
--}
-
-matchCheck ::  DsMatchContext
-            -> [Id]             -- Vars rep'ing the exprs we're matching with
-            -> Type             -- Type of the case expression
-            -> [EquationInfo]   -- Info about patterns, etc. (type synonym below)
-            -> DsM MatchResult  -- Desugared result!
-
-matchCheck ctx vars ty qs
-  = do { dflags <- getDynFlags
-       ; matchCheck_really dflags ctx vars ty qs }
-
-matchCheck_really :: DynFlags
-                  -> DsMatchContext
-                  -> [Id]
-                  -> Type
-                  -> [EquationInfo]
-                  -> DsM MatchResult
-matchCheck_really dflags ctx@(DsMatchContext hs_ctx _) vars ty qs
-  = do { when shadow (dsShadowWarn ctx eqns_shadow)
-       ; when incomplete (dsIncompleteWarn ctx pats)
-       ; match vars ty qs }
-  where
-    (pats, eqns_shadow) = check qs
-    incomplete = incomplete_flag hs_ctx && notNull pats
-    shadow     = wopt Opt_WarnOverlappingPatterns dflags
-              && notNull eqns_shadow
-
-    incomplete_flag :: HsMatchContext id -> Bool
-    incomplete_flag (FunRhs {})   = wopt Opt_WarnIncompletePatterns dflags
-    incomplete_flag CaseAlt       = wopt Opt_WarnIncompletePatterns dflags
-    incomplete_flag IfAlt         = False
-
-    incomplete_flag LambdaExpr    = wopt Opt_WarnIncompleteUniPatterns dflags
-    incomplete_flag PatBindRhs    = wopt Opt_WarnIncompleteUniPatterns dflags
-    incomplete_flag ProcExpr      = wopt Opt_WarnIncompleteUniPatterns dflags
-
-    incomplete_flag RecUpd        = wopt Opt_WarnIncompletePatternsRecUpd dflags
-
-    incomplete_flag ThPatSplice   = False
-    incomplete_flag PatSyn        = False
-    incomplete_flag ThPatQuote    = False
-    incomplete_flag (StmtCtxt {}) = False  -- Don't warn about incomplete patterns
-                                           -- in list comprehensions, pattern guards
-                                           -- etc.  They are often *supposed* to be
-                                           -- incomplete
-
-{-
-This variable shows the maximum number of lines of output generated for warnings.
-It will limit the number of patterns/equations displayed to@ maximum_output@.
-
-(ToDo: add command-line option?)
--}
-
-maximum_output :: Int
-maximum_output = 4
-
--- The next two functions create the warning message.
-
-dsShadowWarn :: DsMatchContext -> [EquationInfo] -> DsM ()
-dsShadowWarn ctx@(DsMatchContext kind loc) qs
-  = putSrcSpanDs loc (warnDs warn)
-  where
-    warn | qs `lengthExceeds` maximum_output
-         = pp_context ctx (ptext (sLit "are overlapped"))
-                      (\ f -> vcat (map (ppr_eqn f kind) (take maximum_output qs)) $$
-                      ptext (sLit "..."))
-         | otherwise
-         = pp_context ctx (ptext (sLit "are overlapped"))
-                      (\ f -> vcat $ map (ppr_eqn f kind) qs)
-
-
-dsIncompleteWarn :: DsMatchContext -> [ExhaustivePat] -> DsM ()
-dsIncompleteWarn ctx@(DsMatchContext kind loc) pats
-  = putSrcSpanDs loc (warnDs warn)
-        where
-          warn = pp_context ctx (ptext (sLit "are non-exhaustive"))
-                            (\_ -> hang (ptext (sLit "Patterns not matched:"))
-                                   4 ((vcat $ map (ppr_incomplete_pats kind)
-                                                  (take maximum_output pats))
-                                      $$ dots))
-
-          dots | pats `lengthExceeds` maximum_output = ptext (sLit "...")
-               | otherwise                           = empty
-
-pp_context :: DsMatchContext -> SDoc -> ((SDoc -> SDoc) -> SDoc) -> SDoc
-pp_context (DsMatchContext kind _loc) msg rest_of_msg_fun
-  = vcat [ptext (sLit "Pattern match(es)") <+> msg,
-          sep [ptext (sLit "In") <+> ppr_match <> char ':', nest 4 (rest_of_msg_fun pref)]]
-  where
-    (ppr_match, pref)
-        = case kind of
-             FunRhs fun _ -> (pprMatchContext kind, \ pp -> ppr fun <+> pp)
-             _            -> (pprMatchContext kind, \ pp -> pp)
-
-ppr_pats :: Outputable a => [a] -> SDoc
-ppr_pats pats = sep (map ppr pats)
-
-ppr_shadow_pats :: HsMatchContext Name -> [Pat Id] -> SDoc
-ppr_shadow_pats kind pats
-  = sep [ppr_pats pats, matchSeparator kind, ptext (sLit "...")]
-
-ppr_incomplete_pats :: HsMatchContext Name -> ExhaustivePat -> SDoc
-ppr_incomplete_pats _ (pats,[]) = ppr_pats pats
-ppr_incomplete_pats _ (pats,constraints) =
-                         sep [ppr_pats pats, ptext (sLit "with"),
-                              sep (map ppr_constraint constraints)]
-
-ppr_constraint :: (Name,[HsLit]) -> SDoc
-ppr_constraint (var,pats) = sep [ppr var, ptext (sLit "`notElem`"), ppr pats]
-
-ppr_eqn :: (SDoc -> SDoc) -> HsMatchContext Name -> EquationInfo -> SDoc
-ppr_eqn prefixF kind eqn = prefixF (ppr_shadow_pats kind (eqn_pats eqn))
-
-{-
-************************************************************************
-*                                                                      *
-                The main matching function
-*                                                                      *
-************************************************************************
-
-The function @match@ is basically the same as in the Wadler chapter,
-except it is monadised, to carry around the name supply, info about
-annotations, etc.
-
-Notes on @match@'s arguments, assuming $m$ equations and $n$ patterns:
-\begin{enumerate}
-\item
-A list of $n$ variable names, those variables presumably bound to the
-$n$ expressions being matched against the $n$ patterns.  Using the
-list of $n$ expressions as the first argument showed no benefit and
-some inelegance.
-
-\item
-The second argument, a list giving the ``equation info'' for each of
-the $m$ equations:
-\begin{itemize}
-\item
-the $n$ patterns for that equation, and
-\item
-a list of Core bindings [@(Id, CoreExpr)@ pairs] to be ``stuck on
-the front'' of the matching code, as in:
-\begin{verbatim}
-let <binds>
-in  <matching-code>
-\end{verbatim}
-\item
-and finally: (ToDo: fill in)
-
-The right way to think about the ``after-match function'' is that it
-is an embryonic @CoreExpr@ with a ``hole'' at the end for the
-final ``else expression''.
-\end{itemize}
-
-There is a type synonym, @EquationInfo@, defined in module @DsUtils@.
-
-An experiment with re-ordering this information about equations (in
-particular, having the patterns available in column-major order)
-showed no benefit.
-
-\item
-A default expression---what to evaluate if the overall pattern-match
-fails.  This expression will (almost?) always be
-a measly expression @Var@, unless we know it will only be used once
-(as we do in @glue_success_exprs@).
-
-Leaving out this third argument to @match@ (and slamming in lots of
-@Var "fail"@s) is a positively {\em bad} idea, because it makes it
-impossible to share the default expressions.  (Also, it stands no
-chance of working in our post-upheaval world of @Locals@.)
-\end{enumerate}
-
-Note: @match@ is often called via @matchWrapper@ (end of this module),
-a function that does much of the house-keeping that goes with a call
-to @match@.
-
-It is also worth mentioning the {\em typical} way a block of equations
-is desugared with @match@.  At each stage, it is the first column of
-patterns that is examined.  The steps carried out are roughly:
-\begin{enumerate}
-\item
-Tidy the patterns in column~1 with @tidyEqnInfo@ (this may add
-bindings to the second component of the equation-info):
-\begin{itemize}
-\item
-Remove the `as' patterns from column~1.
-\item
-Make all constructor patterns in column~1 into @ConPats@, notably
-@ListPats@ and @TuplePats@.
-\item
-Handle any irrefutable (or ``twiddle'') @LazyPats@.
-\end{itemize}
-\item
-Now {\em unmix} the equations into {\em blocks} [w\/ local function
-@unmix_eqns@], in which the equations in a block all have variable
-patterns in column~1, or they all have constructor patterns in ...
-(see ``the mixture rule'' in SLPJ).
-\item
-Call @matchEqnBlock@ on each block of equations; it will do the
-appropriate thing for each kind of column-1 pattern, usually ending up
-in a recursive call to @match@.
-\end{enumerate}
-
-We are a little more paranoid about the ``empty rule'' (SLPJ, p.~87)
-than the Wadler-chapter code for @match@ (p.~93, first @match@ clause).
-And gluing the ``success expressions'' together isn't quite so pretty.
-
-This (more interesting) clause of @match@ uses @tidy_and_unmix_eqns@
-(a)~to get `as'- and `twiddle'-patterns out of the way (tidying), and
-(b)~to do ``the mixture rule'' (SLPJ, p.~88) [which really {\em
-un}mixes the equations], producing a list of equation-info
-blocks, each block having as its first column of patterns either all
-constructors, or all variables (or similar beasts), etc.
-
-@match_unmixed_eqn_blks@ simply takes the place of the @foldr@ in the
-Wadler-chapter @match@ (p.~93, last clause), and @match_unmixed_blk@
-corresponds roughly to @matchVarCon@.
--}
-
-match :: [Id]             -- Variables rep\'ing the exprs we\'re matching with
-      -> Type             -- Type of the case expression
-      -> [EquationInfo]   -- Info about patterns, etc. (type synonym below)
-      -> DsM MatchResult  -- Desugared result!
-
-match [] _ty eqns
-  = -- ASSERT2( not (null eqns), ppr ty )
-    return (foldr1 combineMatchResults match_results)
-  where
-    match_results = [ -- ASSERT( null (eqn_pats eqn) )
-                      eqn_rhs eqn
-                    | eqn <- eqns ]
-
-match vars@(v:_) ty eqns    -- Eqns *can* be empty
-  = do  { dflags <- getDynFlags
-                -- Tidy the first pattern, generating
-                -- auxiliary bindings if necessary
-        ; (aux_binds, tidy_eqns) <- mapAndUnzipM (tidyEqnInfo v) eqns
-
-                -- Group the equations and match each group in turn
-        ; let grouped = groupEquations dflags tidy_eqns
-
-         -- print the view patterns that are commoned up to help debug
-        ; whenDOptM Opt_D_dump_view_pattern_commoning (debug grouped)
-
-        ; match_results <- match_groups grouped
-        ; return (adjustMatchResult (foldr (.) id aux_binds) $
-                  foldr1 combineMatchResults match_results) }
-  where
-    dropGroup :: [(PatGroup,EquationInfo)] -> [EquationInfo]
-    dropGroup = map snd
-
-    match_groups :: [[(PatGroup,EquationInfo)]] -> DsM [MatchResult]
-    -- Result list of [MatchResult] is always non-empty
-    match_groups [] = matchEmpty v ty
-    match_groups gs = mapM match_group gs
-
-    match_group :: [(PatGroup,EquationInfo)] -> DsM MatchResult
-    match_group [] = panic "match_group"
-    match_group eqns@((group,_) : _)
-        = case group of
-            PgCon _    -> matchConFamily  vars ty (subGroup [(c,e) | (PgCon c, e) <- eqns])
-            PgSyn _    -> matchPatSyn     vars ty (dropGroup eqns)
-            PgLit _    -> matchLiterals   vars ty (subGroup [(l,e) | (PgLit l, e) <- eqns])
-            PgAny      -> matchVariables  vars ty (dropGroup eqns)
-            PgN _      -> matchNPats      vars ty (dropGroup eqns)
-            PgNpK _    -> matchNPlusKPats vars ty (dropGroup eqns)
-            PgBang     -> matchBangs      vars ty (dropGroup eqns)
-            PgCo _     -> matchCoercion   vars ty (dropGroup eqns)
-            PgView _ _ -> matchView       vars ty (dropGroup eqns)
-            PgOverloadedList -> matchOverloadedList vars ty (dropGroup eqns)
-
-    -- FIXME: we should also warn about view patterns that should be
-    -- commoned up but are not
-
-    -- print some stuff to see what's getting grouped
-    -- use -dppr-debug to see the resolution of overloaded literals
-    debug eqns =
-        let gs = map (\group -> foldr (\ (p,_) -> \acc ->
-                                           case p of PgView e _ -> e:acc
-                                                     _ -> acc) [] group) eqns
-            maybeWarn [] = return ()
-            maybeWarn l = warnDs (vcat l)
-        in
-          maybeWarn $ (map (\g -> text "Putting these view expressions into the same case:" <+> (ppr g))
-                       (filter (not . null) gs))
-
-matchEmpty :: Id -> Type -> DsM [MatchResult]
--- See Note [Empty case expressions]
-matchEmpty var res_ty
-  = return [MatchResult CanFail mk_seq]
-  where
-    mk_seq fail = return $ mkWildCase (Var var) (idType var) res_ty
-                                      [(DEFAULT, [], fail)]
-
-matchVariables :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult
--- Real true variables, just like in matchVar, SLPJ p 94
--- No binding to do: they'll all be wildcards by now (done in tidy)
-matchVariables (_:vars) ty eqns = match vars ty (shiftEqns eqns)
-matchVariables [] _ _ = panic "matchVariables"
-
-matchBangs :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult
-matchBangs (var:vars) ty eqns
-  = do  { match_result <- match (var:vars) ty $
-                          map (decomposeFirstPat getBangPat) eqns
-        ; return (mkEvalMatchResult var ty match_result) }
-matchBangs [] _ _ = panic "matchBangs"
-
-matchCoercion :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult
--- Apply the coercion to the match variable and then match that
-matchCoercion (var:vars) ty (eqns@(eqn1:_))
-  = do  { let CoPat co pat _ = firstPat eqn1
-        ; var' <- newUniqueId var (hsPatType pat)
-        ; match_result <- match (var':vars) ty $
-                          map (decomposeFirstPat getCoPat) eqns
-        ; rhs' <- dsHsWrapper co (Var var)
-        ; return (mkCoLetMatchResult (NonRec var' rhs') match_result) }
-matchCoercion _ _ _ = panic "matchCoercion"
-
-matchView :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult
--- Apply the view function to the match variable and then match that
-matchView (var:vars) ty (eqns@(eqn1:_))
-  = do  { -- we could pass in the expr from the PgView,
-         -- but this needs to extract the pat anyway
-         -- to figure out the type of the fresh variable
-         let ViewPat viewExpr (L _ pat) _ = firstPat eqn1
-         -- do the rest of the compilation
-        ; var' <- newUniqueId var (hsPatType pat)
-        ; match_result <- match (var':vars) ty $
-                          map (decomposeFirstPat getViewPat) eqns
-         -- compile the view expressions
-        ; viewExpr' <- dsLExpr viewExpr
-        ; return (mkViewMatchResult var' viewExpr' var match_result) }
-matchView _ _ _ = panic "matchView"
-
-matchOverloadedList :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult
-matchOverloadedList (var:vars) ty (eqns@(eqn1:_))
--- Since overloaded list patterns are treated as view patterns,
--- the code is roughly the same as for matchView
-  = do { let ListPat _ elt_ty (Just (_,e)) = firstPat eqn1
-       ; var' <- newUniqueId var (mkListTy elt_ty)  -- we construct the overall type by hand
-       ; match_result <- match (var':vars) ty $
-                            map (decomposeFirstPat getOLPat) eqns -- getOLPat builds the pattern inside as a non-overloaded version of the overloaded list pattern
-       ; e' <- dsExpr e
-       ; return (mkViewMatchResult var' e' var match_result) }
-matchOverloadedList _ _ _ = panic "matchOverloadedList"
-
--- decompose the first pattern and leave the rest alone
-decomposeFirstPat :: (Pat Id -> Pat Id) -> EquationInfo -> EquationInfo
-decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats }))
-        = eqn { eqn_pats = extractpat pat : pats}
-decomposeFirstPat _ _ = panic "decomposeFirstPat"
-
-getCoPat, getBangPat, getViewPat, getOLPat :: Pat Id -> Pat Id
-getCoPat (CoPat _ pat _)     = pat
-getCoPat _                   = panic "getCoPat"
-getBangPat (BangPat pat  )   = unLoc pat
-getBangPat _                 = panic "getBangPat"
-getViewPat (ViewPat _ pat _) = unLoc pat
-getViewPat _                 = panic "getViewPat"
-getOLPat (ListPat pats ty (Just _)) = ListPat pats ty Nothing
-getOLPat _                   = panic "getOLPat"
-
-{-
-Note [Empty case alternatives]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The list of EquationInfo can be empty, arising from
-    case x of {}   or    \case {}
-In that situation we desugar to
-    case x of { _ -> error "pattern match failure" }
-The *desugarer* isn't certain whether there really should be no
-alternatives, so it adds a default case, as it always does.  A later
-pass may remove it if it's inaccessible.  (See also Note [Empty case
-alternatives] in CoreSyn.)
-
-We do *not* desugar simply to
-   error "empty case"
-or some such, because 'x' might be bound to (error "hello"), in which
-case we want to see that "hello" exception, not (error "empty case").
-See also Note [Case elimination: lifted case] in Simplify.
-
-
-************************************************************************
-*                                                                      *
-                Tidying patterns
-*                                                                      *
-************************************************************************
-
-Tidy up the leftmost pattern in an @EquationInfo@, given the variable @v@
-which will be scrutinised.  This means:
-\begin{itemize}
-\item
-Replace variable patterns @x@ (@x /= v@) with the pattern @_@,
-together with the binding @x = v@.
-\item
-Replace the `as' pattern @x@@p@ with the pattern p and a binding @x = v@.
-\item
-Removing lazy (irrefutable) patterns (you don't want to know...).
-\item
-Converting explicit tuple-, list-, and parallel-array-pats into ordinary
-@ConPats@.
-\item
-Convert the literal pat "" to [].
-\end{itemize}
-
-The result of this tidying is that the column of patterns will include
-{\em only}:
-\begin{description}
-\item[@WildPats@:]
-The @VarPat@ information isn't needed any more after this.
-
-\item[@ConPats@:]
-@ListPats@, @TuplePats@, etc., are all converted into @ConPats@.
-
-\item[@LitPats@ and @NPats@:]
-@LitPats@/@NPats@ of ``known friendly types'' (Int, Char,
-Float,  Double, at least) are converted to unboxed form; e.g.,
-\tr{(NPat (HsInt i) _ _)} is converted to:
-\begin{verbatim}
-(ConPat I# _ _ [LitPat (HsIntPrim i)])
-\end{verbatim}
-\end{description}
--}
-
-tidyEqnInfo :: Id -> EquationInfo
-            -> DsM (DsWrapper, EquationInfo)
-        -- DsM'd because of internal call to dsLHsBinds
-        --      and mkSelectorBinds.
-        -- "tidy1" does the interesting stuff, looking at
-        -- one pattern and fiddling the list of bindings.
-        --
-        -- POST CONDITION: head pattern in the EqnInfo is
-        --      WildPat
-        --      ConPat
-        --      NPat
-        --      LitPat
-        --      NPlusKPat
-        -- but no other
-
-tidyEqnInfo _ (EqnInfo { eqn_pats = [] })
-  = panic "tidyEqnInfo"
-
-tidyEqnInfo v eqn@(EqnInfo { eqn_pats = pat : pats })
-  = do { (wrap, pat') <- tidy1 v pat
-       ; return (wrap, eqn { eqn_pats = do pat' : pats }) }
-
-tidy1 :: Id               -- The Id being scrutinised
-      -> Pat Id           -- The pattern against which it is to be matched
-      -> DsM (DsWrapper,  -- Extra bindings to do before the match
-              Pat Id)     -- Equivalent pattern
-
--------------------------------------------------------
---      (pat', mr') = tidy1 v pat mr
--- tidies the *outer level only* of pat, giving pat'
--- It eliminates many pattern forms (as-patterns, variable patterns,
--- list patterns, etc) yielding one of:
---      WildPat
---      ConPatOut
---      LitPat
---      NPat
---      NPlusKPat
-
-tidy1 v (ParPat pat)      = tidy1 v (unLoc pat)
-tidy1 v (SigPatOut pat _) = tidy1 v (unLoc pat)
-tidy1 _ (WildPat ty)      = return (idDsWrapper, WildPat ty)
-tidy1 v (BangPat (L l p)) = tidy_bang_pat v l p
-
-        -- case v of { x -> mr[] }
-        -- = case v of { _ -> let x=v in mr[] }
-tidy1 v (VarPat var)
-  = return (wrapBind var v, WildPat (idType var))
-
-        -- case v of { x@p -> mr[] }
-        -- = case v of { p -> let x=v in mr[] }
-tidy1 v (AsPat (L _ var) pat)
-  = do  { (wrap, pat') <- tidy1 v (unLoc pat)
-        ; return (wrapBind var v . wrap, pat') }
-
-{- now, here we handle lazy patterns:
-    tidy1 v ~p bs = (v, v1 = case v of p -> v1 :
-                        v2 = case v of p -> v2 : ... : bs )
-
-    where the v_i's are the binders in the pattern.
-
-    ToDo: in "v_i = ... -> v_i", are the v_i's really the same thing?
-
-    The case expr for v_i is just: match [v] [(p, [], \ x -> Var v_i)] any_expr
--}
-
-tidy1 v (LazyPat pat)
-  = do  { sel_prs <- mkSelectorBinds [] pat (Var v)
-        ; let sel_binds =  [NonRec b rhs | (b,rhs) <- sel_prs]
-        ; return (mkCoreLets sel_binds, WildPat (idType v)) }
-
-tidy1 _ (ListPat pats ty Nothing)
-  = return (idDsWrapper, unLoc list_ConPat)
-  where
-    list_ConPat = foldr (\ x y -> mkPrefixConPat consDataCon [x, y] [ty])
-                        (mkNilPat ty)
-                        pats
-
--- Introduce fake parallel array constructors to be able to handle parallel
--- arrays with the existing machinery for constructor pattern
-tidy1 _ (PArrPat pats ty)
-  = return (idDsWrapper, unLoc parrConPat)
-  where
-    arity      = length pats
-    parrConPat = mkPrefixConPat (parrFakeCon arity) pats [ty]
-
-tidy1 _ (TuplePat pats boxity tys)
-  = return (idDsWrapper, unLoc tuple_ConPat)
-  where
-    arity = length pats
-    tuple_ConPat = mkPrefixConPat (tupleCon (boxityNormalTupleSort boxity) arity) pats tys
-
--- LitPats: we *might* be able to replace these w/ a simpler form
-tidy1 _ (LitPat lit)
-  = return (idDsWrapper, tidyLitPat lit)
-
--- NPats: we *might* be able to replace these w/ a simpler form
-tidy1 _ (NPat (L _ lit) mb_neg eq)
-  = return (idDsWrapper, tidyNPat tidyLitPat lit mb_neg eq)
-
--- Everything else goes through unchanged...
-
-tidy1 _ non_interesting_pat
-  = return (idDsWrapper, non_interesting_pat)
-
---------------------
-tidy_bang_pat :: Id -> SrcSpan -> Pat Id -> DsM (DsWrapper, Pat Id)
-
--- Discard par/sig under a bang
-tidy_bang_pat v _ (ParPat (L l p))      = tidy_bang_pat v l p
-tidy_bang_pat v _ (SigPatOut (L l p) _) = tidy_bang_pat v l p
-
--- Push the bang-pattern inwards, in the hope that
--- it may disappear next time
-tidy_bang_pat v l (AsPat v' p)  = tidy1 v (AsPat v' (L l (BangPat p)))
-tidy_bang_pat v l (CoPat w p t) = tidy1 v (CoPat w (BangPat (L l p)) t)
-
--- Discard bang around strict pattern
-tidy_bang_pat v _ p@(LitPat {})    = tidy1 v p
-tidy_bang_pat v _ p@(ListPat {})   = tidy1 v p
-tidy_bang_pat v _ p@(TuplePat {})  = tidy1 v p
-tidy_bang_pat v _ p@(PArrPat {})   = tidy1 v p
-
--- Data/newtype constructors
-tidy_bang_pat v l p@(ConPatOut { pat_con = L _ (RealDataCon dc), pat_args = args })
-  | isNewTyCon (dataConTyCon dc)   -- Newtypes: push bang inwards (Trac #9844)
-  = tidy1 v (p { pat_args = push_bang_into_newtype_arg l args })
-  | otherwise                      -- Data types: discard the bang
-  = tidy1 v p
-
--------------------
--- Default case, leave the bang there:
---    VarPat,
---    LazyPat,
---    WildPat,
---    ViewPat,
---    pattern synonyms (ConPatOut with PatSynCon)
---    NPat,
---    NPlusKPat
---
--- For LazyPat, remember that it's semantically like a VarPat
---  i.e.  !(~p) is not like ~p, or p!  (Trac #8952)
---
--- NB: SigPatIn, ConPatIn should not happen
-
-tidy_bang_pat _ l p = return (idDsWrapper, BangPat (L l p))
-
--------------------
-push_bang_into_newtype_arg :: SrcSpan -> HsConPatDetails Id -> HsConPatDetails Id
--- See Note [Bang patterns and newtypes]
--- We are transforming   !(N p)   into   (N !p)
-push_bang_into_newtype_arg l (PrefixCon (arg:_args))
-  = -- ASSERT( null args)
-    PrefixCon [L l (BangPat arg)]
-push_bang_into_newtype_arg l (RecCon rf)
-  | HsRecFields { rec_flds = L lf fld : _flds } <- rf
-  , HsRecField { hsRecFieldArg = arg } <- fld
-  = -- ASSERT( null flds)
-    RecCon (rf { rec_flds = [L lf (fld { hsRecFieldArg = L l (BangPat arg) })] })
-push_bang_into_newtype_arg _ cd
-  = pprPanic "push_bang_into_newtype_arg" (pprConArgs cd)
-
-{-
-Note [Bang patterns and newtypes]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-For the pattern  !(Just pat)  we can discard the bang, because
-the pattern is strict anyway. But for !(N pat), where
-  newtype NT = N Int
-we definitely can't discard the bang.  Trac #9844.
-
-So what we do is to push the bang inwards, in the hope that it will
-get discarded there.  So we transform
-   !(N pat)   into    (N !pat)
-
-
-\noindent
-{\bf Previous @matchTwiddled@ stuff:}
-
-Now we get to the only interesting part; note: there are choices for
-translation [from Simon's notes]; translation~1:
-\begin{verbatim}
-deTwiddle [s,t] e
-\end{verbatim}
-returns
-\begin{verbatim}
-[ w = e,
-  s = case w of [s,t] -> s
-  t = case w of [s,t] -> t
-]
-\end{verbatim}
-
-Here \tr{w} is a fresh variable, and the \tr{w}-binding prevents multiple
-evaluation of \tr{e}.  An alternative translation (No.~2):
-\begin{verbatim}
-[ w = case e of [s,t] -> (s,t)
-  s = case w of (s,t) -> s
-  t = case w of (s,t) -> t
-]
-\end{verbatim}
-
-************************************************************************
-*                                                                      *
-\subsubsection[improved-unmixing]{UNIMPLEMENTED idea for improved unmixing}
-*                                                                      *
-************************************************************************
-
-We might be able to optimise unmixing when confronted by
-only-one-constructor-possible, of which tuples are the most notable
-examples.  Consider:
-\begin{verbatim}
-f (a,b,c) ... = ...
-f d ... (e:f) = ...
-f (g,h,i) ... = ...
-f j ...       = ...
-\end{verbatim}
-This definition would normally be unmixed into four equation blocks,
-one per equation.  But it could be unmixed into just one equation
-block, because if the one equation matches (on the first column),
-the others certainly will.
-
-You have to be careful, though; the example
-\begin{verbatim}
-f j ...       = ...
--------------------
-f (a,b,c) ... = ...
-f d ... (e:f) = ...
-f (g,h,i) ... = ...
-\end{verbatim}
-{\em must} be broken into two blocks at the line shown; otherwise, you
-are forcing unnecessary evaluation.  In any case, the top-left pattern
-always gives the cue.  You could then unmix blocks into groups of...
-\begin{description}
-\item[all variables:]
-As it is now.
-\item[constructors or variables (mixed):]
-Need to make sure the right names get bound for the variable patterns.
-\item[literals or variables (mixed):]
-Presumably just a variant on the constructor case (as it is now).
-\end{description}
-
-************************************************************************
-*                                                                      *
-*  matchWrapper: a convenient way to call @match@                      *
-*                                                                      *
-************************************************************************
-\subsection[matchWrapper]{@matchWrapper@: a convenient interface to @match@}
-
-Calls to @match@ often involve similar (non-trivial) work; that work
-is collected here, in @matchWrapper@.  This function takes as
-arguments:
-\begin{itemize}
-\item
-Typchecked @Matches@ (of a function definition, or a case or lambda
-expression)---the main input;
-\item
-An error message to be inserted into any (runtime) pattern-matching
-failure messages.
-\end{itemize}
-
-As results, @matchWrapper@ produces:
-\begin{itemize}
-\item
-A list of variables (@Locals@) that the caller must ``promise'' to
-bind to appropriate values; and
-\item
-a @CoreExpr@, the desugared output (main result).
-\end{itemize}
-
-The main actions of @matchWrapper@ include:
-\begin{enumerate}
-\item
-Flatten the @[TypecheckedMatch]@ into a suitable list of
-@EquationInfo@s.
-\item
-Create as many new variables as there are patterns in a pattern-list
-(in any one of the @EquationInfo@s).
-\item
-Create a suitable ``if it fails'' expression---a call to @error@ using
-the error-string input; the {\em type} of this fail value can be found
-by examining one of the RHS expressions in one of the @EquationInfo@s.
-\item
-Call @match@ with all of this information!
-\end{enumerate}
--}
-
-matchWrapper :: HsMatchContext Name         -- For shadowing warning messages
-             -> MatchGroup Id (LHsExpr Id)  -- Matches being desugared
-             -> DsM ([Id], CoreExpr)        -- Results
-
-{-
- There is one small problem with the Lambda Patterns, when somebody
- writes something similar to:
-\begin{verbatim}
-    (\ (x:xs) -> ...)
-\end{verbatim}
- he/she don't want a warning about incomplete patterns, that is done with
- the flag @opt_WarnSimplePatterns@.
- This problem also appears in the:
-\begin{itemize}
-\item @do@ patterns, but if the @do@ can fail
-      it creates another equation if the match can fail
-      (see @DsExpr.doDo@ function)
-\item @let@ patterns, are treated by @matchSimply@
-   List Comprension Patterns, are treated by @matchSimply@ also
-\end{itemize}
-
-We can't call @matchSimply@ with Lambda patterns,
-due to the fact that lambda patterns can have more than
-one pattern, and match simply only accepts one pattern.
-
-JJQC 30-Nov-1997
--}
-
-matchWrapper ctxt (MG { mg_alts = matches
-                      , mg_arg_tys = arg_tys
-                      , mg_res_ty = rhs_ty
-                      , mg_origin = origin })
-  = do  { eqns_info   <- mapM mk_eqn_info matches
-        ; new_vars    <- case matches of
-                           []    -> mapM newSysLocalDs arg_tys
-                           (m:_) -> selectMatchVars (map unLoc (hsLMatchPats m))
-        ; result_expr <- handleWarnings $
-                         matchEquations ctxt new_vars eqns_info rhs_ty
-        ; return (new_vars, result_expr) }
-  where
-    mk_eqn_info (L _ (Match _ pats _ grhss))
-      = do { let upats = map unLoc pats
-           ; match_result <- dsGRHSs ctxt upats grhss rhs_ty
-           ; return (EqnInfo { eqn_pats = upats, eqn_rhs  = match_result}) }
-
-    handleWarnings = if isGenerated origin
-                     then discardWarningsDs
-                     else id
-
-
-matchEquations  :: HsMatchContext Name
-                -> [Id] -> [EquationInfo] -> Type
-                -> DsM CoreExpr
-matchEquations ctxt vars eqns_info rhs_ty
-  = do  { locn <- getSrcSpanDs
-        ; let   ds_ctxt   = DsMatchContext ctxt locn
-                error_doc = matchContextErrString ctxt
-
-        ; match_result <- matchCheck ds_ctxt vars rhs_ty eqns_info
-
-        ; fail_expr <- mkErrorAppDs pAT_ERROR_ID rhs_ty error_doc
-        ; extractMatchResult match_result fail_expr }
-
-{-
-************************************************************************
-*                                                                      *
-\subsection[matchSimply]{@matchSimply@: match a single expression against a single pattern}
-*                                                                      *
-************************************************************************
-
-@mkSimpleMatch@ is a wrapper for @match@ which deals with the
-situation where we want to match a single expression against a single
-pattern. It returns an expression.
--}
-
-matchSimply :: CoreExpr                 -- Scrutinee
-            -> HsMatchContext Name      -- Match kind
-            -> LPat Id                  -- Pattern it should match
-            -> CoreExpr                 -- Return this if it matches
-            -> CoreExpr                 -- Return this if it doesn't
-            -> DsM CoreExpr
--- Do not warn about incomplete patterns; see matchSinglePat comments
-matchSimply scrut hs_ctx pat result_expr fail_expr = do
-    let
-      match_result = cantFailMatchResult result_expr
-      rhs_ty       = exprType fail_expr
-        -- Use exprType of fail_expr, because won't refine in the case of failure!
-    match_result' <- matchSinglePat scrut hs_ctx pat rhs_ty match_result
-    extractMatchResult match_result' fail_expr
-
-matchSinglePat :: CoreExpr -> HsMatchContext Name -> LPat Id
-               -> Type -> MatchResult -> DsM MatchResult
--- Do not warn about incomplete patterns
--- Used for things like [ e | pat <- stuff ], where
--- incomplete patterns are just fine
-matchSinglePat (Var var) ctx (L _ pat) ty match_result
-  = do { locn <- getSrcSpanDs
-       ; matchCheck (DsMatchContext ctx locn)
-                    [var] ty
-                    [EqnInfo { eqn_pats = [pat], eqn_rhs  = match_result }] }
-
-matchSinglePat scrut hs_ctx pat ty match_result
-  = do { var <- selectSimpleMatchVarL pat
-       ; match_result' <- matchSinglePat (Var var) hs_ctx pat ty match_result
-       ; return (adjustMatchResult (bindNonRec var scrut) match_result') }
-
-{-
-************************************************************************
-*                                                                      *
-                Pattern classification
-*                                                                      *
-************************************************************************
--}
-
-data PatGroup
-  = PgAny               -- Immediate match: variables, wildcards,
-                        --                  lazy patterns
-  | PgCon DataCon       -- Constructor patterns (incl list, tuple)
-  | PgSyn PatSyn
-  | PgLit Literal       -- Literal patterns
-  | PgN   Literal       -- Overloaded literals
-  | PgNpK Literal       -- n+k patterns
-  | PgBang              -- Bang patterns
-  | PgCo Type           -- Coercion patterns; the type is the type
-                        --      of the pattern *inside*
-  | PgView (LHsExpr Id) -- view pattern (e -> p):
-                        -- the LHsExpr is the expression e
-           Type         -- the Type is the type of p (equivalently, the result type of e)
-  | PgOverloadedList
-
-groupEquations :: DynFlags -> [EquationInfo] -> [[(PatGroup, EquationInfo)]]
--- If the result is of form [g1, g2, g3],
--- (a) all the (pg,eq) pairs in g1 have the same pg
--- (b) none of the gi are empty
--- The ordering of equations is unchanged
-groupEquations dflags eqns
-  = runs same_gp [(patGroup dflags (firstPat eqn), eqn) | eqn <- eqns]
-  where
-    same_gp :: (PatGroup,EquationInfo) -> (PatGroup,EquationInfo) -> Bool
-    (pg1,_) `same_gp` (pg2,_) = pg1 `sameGroup` pg2
-
-subGroup :: Ord a => [(a, EquationInfo)] -> [[EquationInfo]]
--- Input is a particular group.  The result sub-groups the
--- equations by with particular constructor, literal etc they match.
--- Each sub-list in the result has the same PatGroup
--- See Note [Take care with pattern order]
-subGroup group
-    = map reverse $ Map.elems $ foldl accumulate Map.empty group
-  where
-    accumulate pg_map (pg, eqn)
-      = case Map.lookup pg pg_map of
-          Just eqns -> Map.insert pg (eqn:eqns) pg_map
-          Nothing   -> Map.insert pg [eqn]      pg_map
-
-    -- pg_map :: Map a [EquationInfo]
-    -- Equations seen so far in reverse order of appearance
-
-{-
-Note [Take care with pattern order]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-In the subGroup function we must be very careful about pattern re-ordering,
-Consider the patterns [ (True, Nothing), (False, x), (True, y) ]
-Then in bringing together the patterns for True, we must not
-swap the Nothing and y!
--}
-
-sameGroup :: PatGroup -> PatGroup -> Bool
--- Same group means that a single case expression
--- or test will suffice to match both, *and* the order
--- of testing within the group is insignificant.
-sameGroup PgAny      PgAny      = True
-sameGroup PgBang     PgBang     = True
-sameGroup (PgCon _)  (PgCon _)  = True          -- One case expression
-sameGroup (PgSyn p1) (PgSyn p2) = p1==p2
-sameGroup (PgLit _)  (PgLit _)  = True          -- One case expression
-sameGroup (PgN l1)   (PgN l2)   = l1==l2        -- Order is significant
-sameGroup (PgNpK l1) (PgNpK l2) = l1==l2        -- See Note [Grouping overloaded literal patterns]
-sameGroup (PgCo t1)  (PgCo t2)  = t1 `eqType` t2
-        -- CoPats are in the same goup only if the type of the
-        -- enclosed pattern is the same. The patterns outside the CoPat
-        -- always have the same type, so this boils down to saying that
-        -- the two coercions are identical.
-sameGroup (PgView e1 t1) (PgView e2 t2) = viewLExprEq (e1,t1) (e2,t2)
-       -- ViewPats are in the same group iff the expressions
-       -- are "equal"---conservatively, we use syntactic equality
-sameGroup _          _          = False
-
--- An approximation of syntactic equality used for determining when view
--- exprs are in the same group.
--- This function can always safely return false;
--- but doing so will result in the application of the view function being repeated.
---
--- Currently: compare applications of literals and variables
---            and anything else that we can do without involving other
---            HsSyn types in the recursion
---
--- NB we can't assume that the two view expressions have the same type.  Consider
---   f (e1 -> True) = ...
---   f (e2 -> "hi") = ...
-viewLExprEq :: (LHsExpr Id,Type) -> (LHsExpr Id,Type) -> Bool
-viewLExprEq (e1,_) (e2,_) = lexp e1 e2
-  where
-    lexp :: LHsExpr Id -> LHsExpr Id -> Bool
-    lexp e e' = exp (unLoc e) (unLoc e')
-
-    ---------
-    exp :: HsExpr Id -> HsExpr Id -> Bool
-    -- real comparison is on HsExpr's
-    -- strip parens
-    exp (HsPar (L _ e)) e'   = exp e e'
-    exp e (HsPar (L _ e'))   = exp e e'
-    -- because the expressions do not necessarily have the same type,
-    -- we have to compare the wrappers
-    exp (HsWrap h e) (HsWrap h' e') = wrap h h' && exp e e'
-    exp (HsVar i) (HsVar i') =  i == i'
-    -- the instance for IPName derives using the id, so this works if the
-    -- above does
-    exp (HsIPVar i) (HsIPVar i') = i == i'
-    exp (HsOverLit l) (HsOverLit l') =
-        -- Overloaded lits are equal if they have the same type
-        -- and the data is the same.
-        -- this is coarser than comparing the SyntaxExpr's in l and l',
-        -- which resolve the overloading (e.g., fromInteger 1),
-        -- because these expressions get written as a bunch of different variables
-        -- (presumably to improve sharing)
-        eqType (overLitType l) (overLitType l') && l == l'
-    exp (HsApp e1 e2) (HsApp e1' e2') = lexp e1 e1' && lexp e2 e2'
-    -- the fixities have been straightened out by now, so it's safe
-    -- to ignore them?
-    exp (OpApp l o _ ri) (OpApp l' o' _ ri') =
-        lexp l l' && lexp o o' && lexp ri ri'
-    exp (NegApp e n) (NegApp e' n') = lexp e e' && exp n n'
-    exp (SectionL e1 e2) (SectionL e1' e2') =
-        lexp e1 e1' && lexp e2 e2'
-    exp (SectionR e1 e2) (SectionR e1' e2') =
-        lexp e1 e1' && lexp e2 e2'
-    exp (ExplicitTuple es1 _) (ExplicitTuple es2 _) =
-        eq_list tup_arg es1 es2
-    exp (HsIf _ e e1 e2) (HsIf _ e' e1' e2') =
-        lexp e e' && lexp e1 e1' && lexp e2 e2'
-
-    -- Enhancement: could implement equality for more expressions
-    --   if it seems useful
-    -- But no need for HsLit, ExplicitList, ExplicitTuple,
-    -- because they cannot be functions
-    exp _ _  = False
-
-    ---------
-    tup_arg (L _ (Present e1)) (L _ (Present e2)) = lexp e1 e2
-    tup_arg (L _ (Missing t1)) (L _ (Missing t2)) = eqType t1 t2
-    tup_arg _ _ = False
-
-    ---------
-    wrap :: HsWrapper -> HsWrapper -> Bool
-    -- Conservative, in that it demands that wrappers be
-    -- syntactically identical and doesn't look under binders
-    --
-    -- Coarser notions of equality are possible
-    -- (e.g., reassociating compositions,
-    --        equating different ways of writing a coercion)
-    wrap WpHole WpHole = True
-    wrap (WpCompose w1 w2) (WpCompose w1' w2') = wrap w1 w1' && wrap w2 w2'
-    wrap (WpFun w1 w2 _ _) (WpFun w1' w2' _ _) = wrap w1 w1' && wrap w2 w2'
-    wrap (WpCast co)       (WpCast co')        = co `eq_co` co'
-    wrap (WpEvApp et1)     (WpEvApp et2)       = et1 `ev_term` et2
-    wrap (WpTyApp t)       (WpTyApp t')        = eqType t t'
-    -- Enhancement: could implement equality for more wrappers
-    --   if it seems useful (lams and lets)
-    wrap _ _ = False
-
-    ---------
-    ev_term :: EvTerm -> EvTerm -> Bool
-    ev_term (EvId a)       (EvId b)       = a==b
-    ev_term (EvCoercion a) (EvCoercion b) = a `eq_co` b
-    ev_term _ _ = False
-
-    ---------
-    eq_list :: (a->a->Bool) -> [a] -> [a] -> Bool
-    eq_list _  []     []     = True
-    eq_list _  []     (_:_)  = False
-    eq_list _  (_:_)  []     = False
-    eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys
-
-    ---------
-    eq_co :: TcCoercion -> TcCoercion -> Bool
-    -- Just some simple cases (should the r1 == r2 rather be an ASSERT?)
-    eq_co (TcRefl r1 t1)             (TcRefl r2 t2)             = r1 == r2 && eqType t1 t2
-    eq_co (TcCoVarCo v1)             (TcCoVarCo v2)             = v1==v2
-    eq_co (TcSymCo co1)              (TcSymCo co2)              = co1 `eq_co` co2
-    eq_co (TcTyConAppCo r1 tc1 cos1) (TcTyConAppCo r2 tc2 cos2) = r1 == r2 && tc1==tc2 && eq_list eq_co cos1 cos2
-    eq_co _ _ = False
-
-patGroup :: DynFlags -> Pat Id -> PatGroup
-patGroup _      (WildPat {})                  = PgAny
-patGroup _      (BangPat {})                  = PgBang
-patGroup _      (ConPatOut { pat_con = con }) = case unLoc con of
-    RealDataCon dcon -> PgCon dcon
-    PatSynCon psyn -> PgSyn psyn
-patGroup dflags (LitPat lit)                  = PgLit (hsLitKey dflags lit)
-patGroup _      (NPat (L _ olit) mb_neg _)
-                                     = PgN   (hsOverLitKey olit (isJust mb_neg))
-patGroup _      (NPlusKPat _ (L _ olit) _ _)  = PgNpK (hsOverLitKey olit False)
-patGroup _      (CoPat _ p _)                 = PgCo  (hsPatType p) -- Type of innelexp pattern
-patGroup _      (ViewPat expr p _)            = PgView expr (hsPatType (unLoc p))
-patGroup _      (ListPat _ _ (Just _))        = PgOverloadedList
-patGroup _      pat                           = pprPanic "patGroup" (ppr pat)
-
-{-
-Note [Grouping overloaded literal patterns]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-WATCH OUT!  Consider
-
-        f (n+1) = ...
-        f (n+2) = ...
-        f (n+1) = ...
-
-We can't group the first and third together, because the second may match
-the same thing as the first.  Same goes for *overloaded* literal patterns
-        f 1 True = ...
-        f 2 False = ...
-        f 1 False = ...
-If the first arg matches '1' but the second does not match 'True', we
-cannot jump to the third equation!  Because the same argument might
-match '2'!
-Hence we don't regard 1 and 2, or (n+1) and (n+2), as part of the same group.
--}
diff --git a/src/Language/Haskell/Liquid/Desugar710/Match.hs-boot b/src/Language/Haskell/Liquid/Desugar710/Match.hs-boot
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/Match.hs-boot
+++ /dev/null
@@ -1,33 +0,0 @@
-module Language.Haskell.Liquid.Desugar710.Match where
-import Var      ( Id )
-import TcType   ( Type )
-import DsMonad  ( DsM, EquationInfo, MatchResult )
-import CoreSyn  ( CoreExpr )
-import HsSyn    ( LPat, HsMatchContext, MatchGroup, LHsExpr )
-import Name     ( Name )
-
-match   :: [Id]
-        -> Type
-        -> [EquationInfo]
-        -> DsM MatchResult
-
-matchWrapper
-        :: HsMatchContext Name
-        -> MatchGroup Id (LHsExpr Id)
-        -> DsM ([Id], CoreExpr)
-
-matchSimply
-        :: CoreExpr
-        -> HsMatchContext Name
-        -> LPat Id
-        -> CoreExpr
-        -> CoreExpr
-        -> DsM CoreExpr
-
-matchSinglePat
-        :: CoreExpr
-        -> HsMatchContext Name
-        -> LPat Id
-        -> Type
-        -> MatchResult
-        -> DsM MatchResult
diff --git a/src/Language/Haskell/Liquid/Desugar710/MatchCon.hs b/src/Language/Haskell/Liquid/Desugar710/MatchCon.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/MatchCon.hs
+++ /dev/null
@@ -1,290 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-Pattern-matching constructors
--}
-
-{-# LANGUAGE CPP #-}
-
-module Language.Haskell.Liquid.Desugar710.MatchCon ( matchConFamily, matchPatSyn ) where
-
--- #include "HsVersions.h"
-
-import {-# SOURCE #-} Language.Haskell.Liquid.Desugar710.Match     ( match )
-import Prelude hiding (error)
-import HsSyn
-import DsBinds
-import ConLike
-import DataCon
-import PatSyn
-import TcType
-import DsMonad
-import Language.Haskell.Liquid.Desugar710.DsUtils
-import MkCore   ( mkCoreLets )
-import Util
-import ListSetOps ( runs )
-import Id
-import NameEnv
-import SrcLoc
-import DynFlags
-import Outputable
-import Control.Monad(liftM)
-
-{-
-We are confronted with the first column of patterns in a set of
-equations, all beginning with constructors from one ``family'' (e.g.,
-@[]@ and @:@ make up the @List@ ``family'').  We want to generate the
-alternatives for a @Case@ expression.  There are several choices:
-\begin{enumerate}
-\item
-Generate an alternative for every constructor in the family, whether
-they are used in this set of equations or not; this is what the Wadler
-chapter does.
-\begin{description}
-\item[Advantages:]
-(a)~Simple.  (b)~It may also be that large sparsely-used constructor
-families are mainly handled by the code for literals.
-\item[Disadvantages:]
-(a)~Not practical for large sparsely-used constructor families, e.g.,
-the ASCII character set.  (b)~Have to look up a list of what
-constructors make up the whole family.
-\end{description}
-
-\item
-Generate an alternative for each constructor used, then add a default
-alternative in case some constructors in the family weren't used.
-\begin{description}
-\item[Advantages:]
-(a)~Alternatives aren't generated for unused constructors.  (b)~The
-STG is quite happy with defaults.  (c)~No lookup in an environment needed.
-\item[Disadvantages:]
-(a)~A spurious default alternative may be generated.
-\end{description}
-
-\item
-``Do it right:'' generate an alternative for each constructor used,
-and add a default alternative if all constructors in the family
-weren't used.
-\begin{description}
-\item[Advantages:]
-(a)~You will get cases with only one alternative (and no default),
-which should be amenable to optimisation.  Tuples are a common example.
-\item[Disadvantages:]
-(b)~Have to look up constructor families in TDE (as above).
-\end{description}
-\end{enumerate}
-
-We are implementing the ``do-it-right'' option for now.  The arguments
-to @matchConFamily@ are the same as to @match@; the extra @Int@
-returned is the number of constructors in the family.
-
-The function @matchConFamily@ is concerned with this
-have-we-used-all-the-constructors? question; the local function
-@match_cons_used@ does all the real work.
--}
-
-matchConFamily :: [Id]
-               -> Type
-               -> [[EquationInfo]]
-               -> DsM MatchResult
--- Each group of eqns is for a single constructor
-matchConFamily (var:vars) ty groups
-  = do dflags <- getDynFlags
-       alts <- mapM (fmap toRealAlt . matchOneConLike vars ty) groups
-       return (mkCoAlgCaseMatchResult dflags var ty alts)
-  where
-    toRealAlt alt = case alt_pat alt of
-        RealDataCon dcon -> alt{ alt_pat = dcon }
-        _ -> panic "matchConFamily: not RealDataCon"
-matchConFamily [] _ _ = panic "matchConFamily []"
-
-matchPatSyn :: [Id]
-            -> Type
-            -> [EquationInfo]
-            -> DsM MatchResult
-matchPatSyn (var:vars) ty eqns
-  = do alt <- fmap toSynAlt $ matchOneConLike vars ty eqns
-       return (mkCoSynCaseMatchResult var ty alt)
-  where
-    toSynAlt alt = case alt_pat alt of
-        PatSynCon psyn -> alt{ alt_pat = psyn }
-        _ -> panic "matchPatSyn: not PatSynCon"
-matchPatSyn _ _ _ = panic "matchPatSyn []"
-
-type ConArgPats = HsConDetails (LPat Id) (HsRecFields Id (LPat Id))
-
-matchOneConLike :: [Id]
-                -> Type
-                -> [EquationInfo]
-                -> DsM (CaseAlt ConLike)
-matchOneConLike vars ty (eqn1 : eqns)   -- All eqns for a single constructor
-  = do  { arg_vars <- selectConMatchVars val_arg_tys args1
-                -- Use the first equation as a source of
-                -- suggestions for the new variables
-
-        -- Divide into sub-groups; see Note [Record patterns]
-        ; let groups :: [[(ConArgPats, EquationInfo)]]
-              groups = runs compatible_pats [ (pat_args (firstPat eqn), eqn)
-                                            | eqn <- eqn1:eqns ]
-
-        ; match_results <- mapM (match_group arg_vars) groups
-
-        ; return $ MkCaseAlt{ alt_pat = con1,
-                              alt_bndrs = tvs1 ++ dicts1 ++ arg_vars,
-                              alt_wrapper = wrapper1,
-                              alt_result = foldr1 combineMatchResults match_results } }
-  where
-    ConPatOut { pat_con = L _ con1, pat_arg_tys = arg_tys, pat_wrap = wrapper1,
-                pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 }
-              = firstPat eqn1
-    fields1 = case con1 of
-                RealDataCon dcon1 -> dataConFieldLabels dcon1
-                PatSynCon{}       -> []
-
-    val_arg_tys = case con1 of
-                    RealDataCon dcon1 -> dataConInstOrigArgTys dcon1 inst_tys
-                    PatSynCon psyn1   -> patSynInstArgTys      psyn1 inst_tys
-    inst_tys = -- ASSERT( tvs1 `equalLength` ex_tvs )
-               arg_tys ++ mkTyVarTys tvs1
-        -- dataConInstOrigArgTys takes the univ and existential tyvars
-        -- and returns the types of the *value* args, which is what we want
-
---     ex_tvs = case con1 of
---                RealDataCon dcon1 -> dataConExTyVars dcon1
---                PatSynCon psyn1   -> patSynExTyVars psyn1
-
-    match_group :: [Id] -> [(ConArgPats, EquationInfo)] -> DsM MatchResult
-    -- All members of the group have compatible ConArgPats
-    match_group arg_vars arg_eqn_prs
-      = -- ASSERT( notNull arg_eqn_prs )
-        do { (wraps, eqns') <- liftM unzip (mapM shift arg_eqn_prs)
-           ; let group_arg_vars = select_arg_vars arg_vars arg_eqn_prs
-           ; match_result <- match (group_arg_vars ++ vars) ty eqns'
-           ; return (adjustMatchResult (foldr1 (.) wraps) match_result) }
-
-    shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds,
-                                                   pat_binds = bind, pat_args = args
-                                        } : pats }))
-      = do ds_bind <- dsTcEvBinds bind
-           return ( wrapBinds (tvs `zip` tvs1)
-                  . wrapBinds (ds  `zip` dicts1)
-                  . mkCoreLets ds_bind
-                  , eqn { eqn_pats = conArgPats val_arg_tys args ++ pats }
-                  )
-    shift (_, (EqnInfo { eqn_pats = ps })) = pprPanic "matchOneCon/shift" (ppr ps)
-
-    -- Choose the right arg_vars in the right order for this group
-    -- Note [Record patterns]
-    select_arg_vars arg_vars ((arg_pats, _) : _)
-      | RecCon flds <- arg_pats
-      , let rpats = rec_flds flds
-      , not (null rpats)     -- Treated specially; cf conArgPats
-      = -- ASSERT2( length fields1 == length arg_vars,
-        --          ppr con1 $$ ppr fields1 $$ ppr arg_vars )
-        map lookup_fld rpats
-      | otherwise
-      = arg_vars
-      where
-        fld_var_env = mkNameEnv $ zipEqual "get_arg_vars" fields1 arg_vars
-        lookup_fld (L _ rpat) = lookupNameEnv_NF fld_var_env
-                                            (idName (unLoc (hsRecFieldId rpat)))
-    select_arg_vars _ [] = panic "matchOneCon/select_arg_vars []"
-matchOneConLike _ _ [] = panic "matchOneCon []"
-
------------------
-compatible_pats :: (ConArgPats,a) -> (ConArgPats,a) -> Bool
--- Two constructors have compatible argument patterns if the number
--- and order of sub-matches is the same in both cases
-compatible_pats (RecCon flds1, _) (RecCon flds2, _) = same_fields flds1 flds2
-compatible_pats (RecCon flds1, _) _                 = null (rec_flds flds1)
-compatible_pats _                 (RecCon flds2, _) = null (rec_flds flds2)
-compatible_pats _                 _                 = True -- Prefix or infix con
-
-same_fields :: HsRecFields Id (LPat Id) -> HsRecFields Id (LPat Id) -> Bool
-same_fields flds1 flds2
-  = all2 (\(L _ f1) (L _ f2)
-                          -> unLoc (hsRecFieldId f1) == unLoc (hsRecFieldId f2))
-         (rec_flds flds1) (rec_flds flds2)
-
-
------------------
-selectConMatchVars :: [Type] -> ConArgPats -> DsM [Id]
-selectConMatchVars arg_tys (RecCon {})      = newSysLocalsDs arg_tys
-selectConMatchVars _       (PrefixCon ps)   = selectMatchVars (map unLoc ps)
-selectConMatchVars _       (InfixCon p1 p2) = selectMatchVars [unLoc p1, unLoc p2]
-
-conArgPats :: [Type]    -- Instantiated argument types
-                        -- Used only to fill in the types of WildPats, which
-                        -- are probably never looked at anyway
-           -> ConArgPats
-           -> [Pat Id]
-conArgPats _arg_tys (PrefixCon ps)   = map unLoc ps
-conArgPats _arg_tys (InfixCon p1 p2) = [unLoc p1, unLoc p2]
-conArgPats  arg_tys (RecCon (HsRecFields { rec_flds = rpats }))
-  | null rpats = map WildPat arg_tys
-        -- Important special case for C {}, which can be used for a
-        -- datacon that isn't declared to have fields at all
-  | otherwise  = map (unLoc . hsRecFieldArg . unLoc) rpats
-
-{-
-Note [Record patterns]
-~~~~~~~~~~~~~~~~~~~~~~
-Consider
-         data T = T { x,y,z :: Bool }
-
-         f (T { y=True, x=False }) = ...
-
-We must match the patterns IN THE ORDER GIVEN, thus for the first
-one we match y=True before x=False.  See Trac #246; or imagine
-matching against (T { y=False, x=undefined }): should fail without
-touching the undefined.
-
-Now consider:
-
-         f (T { y=True, x=False }) = ...
-         f (T { x=True, y= False}) = ...
-
-In the first we must test y first; in the second we must test x
-first.  So we must divide even the equations for a single constructor
-T into sub-goups, based on whether they match the same field in the
-same order.  That's what the (runs compatible_pats) grouping.
-
-All non-record patterns are "compatible" in this sense, because the
-positional patterns (T a b) and (a `T` b) all match the arguments
-in order.  Also T {} is special because it's equivalent to (T _ _).
-Hence the (null rpats) checks here and there.
-
-
-Note [Existentials in shift_con_pat]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
-        data T = forall a. Ord a => T a (a->Int)
-
-        f (T x f) True  = ...expr1...
-        f (T y g) False = ...expr2..
-
-When we put in the tyvars etc we get
-
-        f (T a (d::Ord a) (x::a) (f::a->Int)) True =  ...expr1...
-        f (T b (e::Ord b) (y::a) (g::a->Int)) True =  ...expr2...
-
-After desugaring etc we'll get a single case:
-
-        f = \t::T b::Bool ->
-            case t of
-               T a (d::Ord a) (x::a) (f::a->Int)) ->
-            case b of
-                True  -> ...expr1...
-                False -> ...expr2...
-
-*** We have to substitute [a/b, d/e] in expr2! **
-Hence
-                False -> ....((/\b\(e:Ord b).expr2) a d)....
-
-Originally I tried to use
-        (\b -> let e = d in expr2) a
-to do this substitution.  While this is "correct" in a way, it fails
-Lint, because e::Ord b but d::Ord a.
--}
diff --git a/src/Language/Haskell/Liquid/Desugar710/MatchLit.hs b/src/Language/Haskell/Liquid/Desugar710/MatchLit.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Desugar710/MatchLit.hs
+++ /dev/null
@@ -1,395 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-
-Pattern-matching literal patterns
--}
-
-{-# LANGUAGE CPP, ScopedTypeVariables #-}
-{-# LANGUAGE RankNTypes #-}
-
-module Language.Haskell.Liquid.Desugar710.MatchLit ( dsLit, dsOverLit, hsLitKey, hsOverLitKey
-                , tidyLitPat, tidyNPat
-                , matchLiterals, matchNPlusKPats, matchNPats
-                , warnAboutIdentities, warnAboutEmptyEnumerations
-                ) where
-
--- #include "HsVersions.h"
-
-import {-# SOURCE #-} Language.Haskell.Liquid.Desugar710.Match  ( match )
-import {-# SOURCE #-} Language.Haskell.Liquid.Desugar710.DsExpr ( dsExpr )
-import Prelude hiding (error)
-import DsMonad
-import Language.Haskell.Liquid.Desugar710.DsUtils
-
-import HsSyn
-
-import Id
-import CoreSyn
-import MkCore
-import TyCon
-import DataCon
-import TcHsSyn ( shortCutLit )
-import TcType
-import Name
-import Type
-import PrelNames
-import TysWiredIn
-import Literal
-import SrcLoc
-import Data.Ratio
-import Outputable
-import BasicTypes
-import DynFlags
-import Util
-import FastString
-
-{-
-************************************************************************
-*                                                                      *
-                Desugaring literals
-        [used to be in DsExpr, but DsMeta needs it,
-         and it's nice to avoid a loop]
-*                                                                      *
-************************************************************************
-
-We give int/float literals type @Integer@ and @Rational@, respectively.
-The typechecker will (presumably) have put \tr{from{Integer,Rational}s}
-around them.
-
-ToDo: put in range checks for when converting ``@i@''
-(or should that be in the typechecker?)
-
-For numeric literals, we try to detect there use at a standard type
-(@Int@, @Float@, etc.) are directly put in the right constructor.
-[NB: down with the @App@ conversion.]
-
-See also below where we look for @DictApps@ for \tr{plusInt}, etc.
--}
-
-dsLit :: HsLit -> DsM CoreExpr
-dsLit (HsStringPrim _ s) = return (Lit (MachStr s))
-dsLit (HsCharPrim   _ c) = return (Lit (MachChar c))
-dsLit (HsIntPrim    _ i) = return (Lit (MachInt i))
-dsLit (HsWordPrim   _ w) = return (Lit (MachWord w))
-dsLit (HsInt64Prim  _ i) = return (Lit (MachInt64 i))
-dsLit (HsWord64Prim _ w) = return (Lit (MachWord64 w))
-dsLit (HsFloatPrim    f) = return (Lit (MachFloat (fl_value f)))
-dsLit (HsDoublePrim   d) = return (Lit (MachDouble (fl_value d)))
-
-dsLit (HsChar _ c)       = return (mkCharExpr c)
-dsLit (HsString _ str)   = mkStringExprFS str
-dsLit (HsInteger _ i _)  = mkIntegerExpr i
-dsLit (HsInt _ i)        = do dflags <- getDynFlags
-                              return (mkIntExpr dflags i)
-
-dsLit (HsRat r ty) = do
-   num   <- mkIntegerExpr (numerator (fl_value r))
-   denom <- mkIntegerExpr (denominator (fl_value r))
-   return (mkConApp ratio_data_con [Type integer_ty, num, denom])
-  where
-    (ratio_data_con, integer_ty)
-        = case tcSplitTyConApp ty of
-                (tycon, [i_ty]) -> -- ASSERT(isIntegerTy i_ty && tycon `hasKey` ratioTyConKey)
-                                   (head (tyConDataCons tycon), i_ty)
-                x -> pprPanic "dsLit" (ppr x)
-
-dsOverLit :: HsOverLit Id -> DsM CoreExpr
-dsOverLit lit = do { dflags <- getDynFlags
-                   ; warnAboutOverflowedLiterals dflags lit
-                   ; dsOverLit' dflags lit }
-
-dsOverLit' :: DynFlags -> HsOverLit Id -> DsM CoreExpr
--- Post-typechecker, the SyntaxExpr field of an OverLit contains
--- (an expression for) the literal value itself
-dsOverLit' dflags (OverLit { ol_val = val, ol_rebindable = rebindable
-                           , ol_witness = witness, ol_type = ty })
-  | not rebindable
-  , Just expr <- shortCutLit dflags val ty = dsExpr expr        -- Note [Literal short cut]
-  | otherwise                              = dsExpr witness
-
-{-
-Note [Literal short cut]
-~~~~~~~~~~~~~~~~~~~~~~~~
-The type checker tries to do this short-cutting as early as possible, but
-because of unification etc, more information is available to the desugarer.
-And where it's possible to generate the correct literal right away, it's
-much better to do so.
-
-
-************************************************************************
-*                                                                      *
-                 Warnings about overflowed literals
-*                                                                      *
-************************************************************************
-
-Warn about functions like toInteger, fromIntegral, that convert
-between one type and another when the to- and from- types are the
-same.  Then it's probably (albeit not definitely) the identity
--}
-
-warnAboutIdentities :: DynFlags -> CoreExpr -> Type -> DsM ()
-warnAboutIdentities dflags (Var conv_fn) type_of_conv
-  | wopt Opt_WarnIdentities dflags
-  , idName conv_fn `elem` conversionNames
-  , Just (arg_ty, res_ty) <- splitFunTy_maybe type_of_conv
-  , arg_ty `eqType` res_ty  -- So we are converting  ty -> ty
-  = warnDs (vcat [ ptext (sLit "Call of") <+> ppr conv_fn <+> dcolon <+> ppr type_of_conv
-                 , nest 2 $ ptext (sLit "can probably be omitted")
-                 , parens (ptext (sLit "Use -fno-warn-identities to suppress this message"))
-           ])
-warnAboutIdentities _ _ _ = return ()
-
-conversionNames :: [Name]
-conversionNames
-  = [ toIntegerName, toRationalName
-    , fromIntegralName, realToFracName ]
- -- We can't easily add fromIntegerName, fromRationalName,
- -- because they are generated by literals
-
-warnAboutOverflowedLiterals :: DynFlags -> HsOverLit Id -> DsM ()
-warnAboutOverflowedLiterals _dflags _lit
-  | otherwise = return ()
-
-{-
-Note [Suggest NegativeLiterals]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If you write
-  x :: Int8
-  x = -128
-it'll parse as (negate 128), and overflow.  In this case, suggest NegativeLiterals.
-We get an erroneous suggestion for
-  x = 128
-but perhaps that does not matter too much.
--}
-
-warnAboutEmptyEnumerations :: DynFlags -> LHsExpr Id -> Maybe (LHsExpr Id) -> LHsExpr Id -> DsM ()
--- Warns about [2,3 .. 1] which returns the empty list
--- Only works for integral types, not floating point
-warnAboutEmptyEnumerations _dflags _fromExpr _mThnExpr _toExpr
-  | otherwise = return ()
-
-
-{-
-************************************************************************
-*                                                                      *
-        Tidying lit pats
-*                                                                      *
-************************************************************************
--}
-
-tidyLitPat :: HsLit -> Pat Id
--- Result has only the following HsLits:
---      HsIntPrim, HsWordPrim, HsCharPrim, HsFloatPrim
---      HsDoublePrim, HsStringPrim, HsString
---  * HsInteger, HsRat, HsInt can't show up in LitPats
---  * We get rid of HsChar right here
-tidyLitPat (HsChar src c) = unLoc (mkCharLitPat src c)
-tidyLitPat (HsString src s)
-  | lengthFS s <= 1     -- Short string literals only
-  = unLoc $ foldr (\c pat -> mkPrefixConPat consDataCon
-                                             [mkCharLitPat src c, pat] [charTy])
-                  (mkNilPat charTy) (unpackFS s)
-        -- The stringTy is the type of the whole pattern, not
-        -- the type to instantiate (:) or [] with!
-tidyLitPat lit = LitPat lit
-
-----------------
-tidyNPat :: (HsLit -> Pat Id)   -- How to tidy a LitPat
-                 -- We need this argument because tidyNPat is called
-                 -- both by Match and by Check, but they tidy LitPats
-                 -- slightly differently; and we must desugar
-                 -- literals consistently (see Trac #5117)
-         -> HsOverLit Id -> Maybe (SyntaxExpr Id) -> SyntaxExpr Id
-         -> Pat Id
-tidyNPat tidy_lit_pat (OverLit val False _ ty) mb_neg _
-        -- False: Take short cuts only if the literal is not using rebindable syntax
-        --
-        -- Once that is settled, look for cases where the type of the
-        -- entire overloaded literal matches the type of the underlying literal,
-        -- and in that case take the short cut
-        -- NB: Watch out for weird cases like Trac #3382
-        --        f :: Int -> Int
-        --        f "blah" = 4
-        --     which might be ok if we hvae 'instance IsString Int'
-        --
-
-  | isIntTy ty,    Just int_lit <- mb_int_lit
-                            = mk_con_pat intDataCon    (HsIntPrim    "" int_lit)
-  | isWordTy ty,   Just int_lit <- mb_int_lit
-                            = mk_con_pat wordDataCon   (HsWordPrim   "" int_lit)
-  | isFloatTy ty,  Just rat_lit <- mb_rat_lit = mk_con_pat floatDataCon  (HsFloatPrim  rat_lit)
-  | isDoubleTy ty, Just rat_lit <- mb_rat_lit = mk_con_pat doubleDataCon (HsDoublePrim rat_lit)
-  | isStringTy ty, Just str_lit <- mb_str_lit
-                            = tidy_lit_pat (HsString "" str_lit)
-  where
-    mk_con_pat :: DataCon -> HsLit -> Pat Id
-    mk_con_pat con lit = unLoc (mkPrefixConPat con [noLoc $ LitPat lit] [])
-
-    mb_int_lit :: Maybe Integer
-    mb_int_lit = case (mb_neg, val) of
-                   (Nothing, HsIntegral _ i) -> Just i
-                   (Just _,  HsIntegral _ i) -> Just (-i)
-                   _ -> Nothing
-
-    mb_rat_lit :: Maybe FractionalLit
-    mb_rat_lit = case (mb_neg, val) of
-       (Nothing, HsIntegral _ i) -> Just (integralFractionalLit (fromInteger i))
-       (Just _,  HsIntegral _ i) -> Just (integralFractionalLit
-                                                             (fromInteger (-i)))
-       (Nothing, HsFractional f) -> Just f
-       (Just _, HsFractional f)  -> Just (negateFractionalLit f)
-       _ -> Nothing
-
-    mb_str_lit :: Maybe FastString
-    mb_str_lit = case (mb_neg, val) of
-                   (Nothing, HsIsString _ s) -> Just s
-                   _ -> Nothing
-
-tidyNPat _ over_lit mb_neg eq
-  = NPat (noLoc over_lit) mb_neg eq
-
-{-
-************************************************************************
-*                                                                      *
-                Pattern matching on LitPat
-*                                                                      *
-************************************************************************
--}
-
-matchLiterals :: [Id]
-              -> Type                   -- Type of the whole case expression
-              -> [[EquationInfo]]       -- All PgLits
-              -> DsM MatchResult
-
-matchLiterals (var:vars) ty sub_groups
-  = -- ASSERT( notNull sub_groups && all notNull sub_groups )
-    do  {       -- Deal with each group
-        ; alts <- mapM match_group sub_groups
-
-                -- Combine results.  For everything except String
-                -- we can use a case expression; for String we need
-                -- a chain of if-then-else
-        ; if isStringTy (idType var) then
-            do  { eq_str <- dsLookupGlobalId eqStringName
-                ; mrs <- mapM (wrap_str_guard eq_str) alts
-                ; return (foldr1 combineMatchResults mrs) }
-          else
-            return (mkCoPrimCaseMatchResult var ty alts)
-        }
-  where
-    match_group :: [EquationInfo] -> DsM (Literal, MatchResult)
-    match_group eqns
-        = do dflags <- getDynFlags
-             let LitPat hs_lit = firstPat (head eqns)
-             match_result <- match vars ty (shiftEqns eqns)
-             return (hsLitKey dflags hs_lit, match_result)
-
-    wrap_str_guard :: Id -> (Literal,MatchResult) -> DsM MatchResult
-        -- Equality check for string literals
-    wrap_str_guard eq_str (MachStr s, mr)
-        = do { -- We now have to convert back to FastString. Perhaps there
-               -- should be separate MachBytes and MachStr constructors?
-               let s'  = mkFastStringByteString s
-             ; lit    <- mkStringExprFS s'
-             ; let pred = mkApps (Var eq_str) [Var var, lit]
-             ; return (mkGuardedMatchResult pred mr) }
-    wrap_str_guard _ (l, _) = pprPanic "matchLiterals/wrap_str_guard" (ppr l)
-
-matchLiterals [] _ _ = panic "matchLiterals []"
-
----------------------------
-hsLitKey :: DynFlags -> HsLit -> Literal
--- Get a Core literal to use (only) a grouping key
--- Hence its type doesn't need to match the type of the original literal
---      (and doesn't for strings)
--- It only works for primitive types and strings;
--- others have been removed by tidy
-hsLitKey dflags (HsIntPrim    _ i) = mkMachInt  dflags i
-hsLitKey dflags (HsWordPrim   _ w) = mkMachWord dflags w
-hsLitKey _      (HsInt64Prim  _ i) = mkMachInt64  i
-hsLitKey _      (HsWord64Prim _ w) = mkMachWord64 w
-hsLitKey _      (HsCharPrim   _ c) = MachChar   c
-hsLitKey _      (HsStringPrim _ s) = MachStr    s
-hsLitKey _      (HsFloatPrim    f) = MachFloat  (fl_value f)
-hsLitKey _      (HsDoublePrim   d) = MachDouble (fl_value d)
-hsLitKey _      (HsString _ s)     = MachStr    (fastStringToByteString s)
-hsLitKey _      l                  = pprPanic "hsLitKey" (ppr l)
-
----------------------------
-hsOverLitKey :: OutputableBndr a => HsOverLit a -> Bool -> Literal
--- Ditto for HsOverLit; the boolean indicates to negate
-hsOverLitKey (OverLit { ol_val = l }) neg = litValKey l neg
-
----------------------------
-litValKey :: OverLitVal -> Bool -> Literal
-litValKey (HsIntegral _ i) False = MachInt i
-litValKey (HsIntegral _ i) True  = MachInt (-i)
-litValKey (HsFractional r) False = MachFloat (fl_value r)
-litValKey (HsFractional r) True  = MachFloat (negate (fl_value r))
-litValKey (HsIsString _ s) _neg   = {- ASSERT( not neg) -} MachStr
-                                                      (fastStringToByteString s)
-
-{-
-************************************************************************
-*                                                                      *
-                Pattern matching on NPat
-*                                                                      *
-************************************************************************
--}
-
-matchNPats :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult
-matchNPats (var:vars) ty (eqn1:eqns)    -- All for the same literal
-  = do  { let NPat (L _ lit) mb_neg eq_chk = firstPat eqn1
-        ; lit_expr <- dsOverLit lit
-        ; neg_lit <- case mb_neg of
-                            Nothing -> return lit_expr
-                            Just neg -> do { neg_expr <- dsExpr neg
-                                           ; return (App neg_expr lit_expr) }
-        ; eq_expr <- dsExpr eq_chk
-        ; let pred_expr = mkApps eq_expr [Var var, neg_lit]
-        ; match_result <- match vars ty (shiftEqns (eqn1:eqns))
-        ; return (mkGuardedMatchResult pred_expr match_result) }
-matchNPats vars _ eqns = pprPanic "matchOneNPat" (ppr (vars, eqns))
-
-{-
-************************************************************************
-*                                                                      *
-                Pattern matching on n+k patterns
-*                                                                      *
-************************************************************************
-
-For an n+k pattern, we use the various magic expressions we've been given.
-We generate:
-\begin{verbatim}
-    if ge var lit then
-        let n = sub var lit
-        in  <expr-for-a-successful-match>
-    else
-        <try-next-pattern-or-whatever>
-\end{verbatim}
--}
-
-matchNPlusKPats :: [Id] -> Type -> [EquationInfo] -> DsM MatchResult
--- All NPlusKPats, for the *same* literal k
-matchNPlusKPats (var:vars) ty (eqn1:eqns)
-  = do  { let NPlusKPat (L _ n1) (L _ lit) ge minus = firstPat eqn1
-        ; ge_expr     <- dsExpr ge
-        ; minus_expr  <- dsExpr minus
-        ; lit_expr    <- dsOverLit lit
-        ; let pred_expr   = mkApps ge_expr [Var var, lit_expr]
-              minusk_expr = mkApps minus_expr [Var var, lit_expr]
-              (wraps, eqns') = mapAndUnzip (shift n1) (eqn1:eqns)
-        ; match_result <- match vars ty eqns'
-        ; return  (mkGuardedMatchResult pred_expr               $
-                   mkCoLetMatchResult (NonRec n1 minusk_expr)   $
-                   adjustMatchResult (foldr1 (.) wraps)         $
-                   match_result) }
-  where
-    shift n1 eqn@(EqnInfo { eqn_pats = NPlusKPat (L _ n) _ _ _ : pats })
-        = (wrapBind n n1, eqn { eqn_pats = pats })
-        -- The wrapBind is a no-op for the first equation
-    shift _ e = pprPanic "matchNPlusKPats/shift" (ppr e)
-
-matchNPlusKPats vars _ eqns = pprPanic "matchNPlusKPats" (ppr (vars, eqns))
diff --git a/src/Language/Haskell/Liquid/GHC.hs b/src/Language/Haskell/Liquid/GHC.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/GHC.hs
@@ -0,0 +1,6 @@
+-- | This module re-exports the GHC API as a single blob.
+
+module Language.Haskell.Liquid.GHC (module X) where
+
+import Language.Haskell.Liquid.GHC.Interface as X
+import Language.Haskell.Liquid.GHC.Misc      as X
diff --git a/src/Language/Haskell/Liquid/GHC/Interface.hs b/src/Language/Haskell/Liquid/GHC/Interface.hs
--- a/src/Language/Haskell/Liquid/GHC/Interface.hs
+++ b/src/Language/Haskell/Liquid/GHC/Interface.hs
@@ -1,50 +1,75 @@
-{-# LANGUAGE NoMonomorphismRestriction #-}
-{-# LANGUAGE TypeSynonymInstances      #-}
-{-# LANGUAGE FlexibleInstances         #-}
-{-# LANGUAGE TupleSections             #-}
-{-# LANGUAGE ScopedTypeVariables       #-}
+{-# LANGUAGE NoMonomorphismRestriction  #-}
+{-# LANGUAGE TypeSynonymInstances       #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE TupleSections              #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE OverloadedStrings          #-}
 
 module Language.Haskell.Liquid.GHC.Interface (
 
   -- * extract all information needed for verification
-    getGhcInfo
+    getGhcInfos
+  , runLiquidGhc
 
   -- * printer
   , pprintCBs
+
+  -- * predicates
+  , isExportedVar
+  , exportedVars
   ) where
 
 import Prelude hiding (error)
 
-import GHC hiding (Target, desugarModule)
+import qualified Outputable as O
+import GHC hiding (Target, desugarModule, Located)
+import qualified GHC
 import GHC.Paths (libdir)
 
+import Annotations
 import Bag
 import Class
 import CoreMonad
 import CoreSyn
 import DataCon
+import Digraph
 import DriverPhases
 import DriverPipeline
 import DynFlags
 import ErrUtils
+import Finder
 import HscTypes hiding (Target)
 import IdInfo
 import InstEnv
+import Module
+import Panic (throwGhcExceptionIO)
+import Serialized
+import TcRnTypes
 import Var
+import NameSet
 
 import Control.Exception
 import Control.Monad
 
+import Data.Bifunctor
+import Data.Data
 import Data.List hiding (intersperse)
 import Data.Maybe
+
+import Data.Generics.Aliases (mkT)
+import Data.Generics.Schemes (everywhere)
+
 import qualified Data.HashSet as S
+import qualified Data.Map as M
 
 import System.Console.CmdArgs.Verbosity hiding (Loud)
 import System.Directory
 import System.FilePath
 import System.IO.Temp
 
-import Text.PrettyPrint.HughesPJ
+import Text.Parsec.Pos
+import Text.PrettyPrint.HughesPJ hiding (first)
 
 import Language.Fixpoint.Types hiding (Error, Result, Expr)
 import Language.Fixpoint.Misc
@@ -59,51 +84,39 @@
 import Language.Haskell.Liquid.Types.PrettyPrint
 import Language.Haskell.Liquid.Types.Visitors
 import Language.Haskell.Liquid.UX.CmdLine
+import Language.Haskell.Liquid.UX.Config (totalityCheck)
+import Language.Haskell.Liquid.UX.QuasiQuoter
 import Language.Haskell.Liquid.UX.Tidy
 import Language.Fixpoint.Utils.Files
 
 --------------------------------------------------------------------------------
--- GHC Interface Pipeline ------------------------------------------------------
+-- | GHC Interface Pipeline ----------------------------------------------------
 --------------------------------------------------------------------------------
 
-getGhcInfo :: Maybe HscEnv -> Config -> FilePath -> IO (GhcInfo, HscEnv)
-getGhcInfo hscEnv cfg0 target = do
-  tryIgnore "create temp directory" $
-    createDirectoryIfMissing False $ tempDirectory target
-  (cfg, name, tgtSpec) <- parseRootTarget cfg0 target
-  runLiquidGhc hscEnv cfg $ getGhcInfo' cfg target name tgtSpec
-
-getGhcInfo' :: Config -> FilePath -> ModName -> Ms.BareSpec -> Ghc (GhcInfo, HscEnv)
-getGhcInfo' cfg target name tgtSpec = do
-  paths <- importPaths <$> getSessionDynFlags
-  liftIO $ whenLoud $ putStrLn $ "paths = " ++ show paths
-
-  impSpecs <- findAndLoadTargets cfg paths target
-
-  modGuts <- makeMGIModGuts target
-  hscEnv <- getSession
-  coreBinds <- liftIO $ anormalize (not $ nocaseexpand cfg) hscEnv modGuts
-
+getGhcInfos :: Maybe HscEnv -> Config -> [FilePath] -> IO ([GhcInfo], HscEnv)
+getGhcInfos hscEnv cfg tgtFiles' = do
+  tgtFiles <- mapM canonicalizePath tgtFiles'
+  _        <- mapM_ createTempDirectoryIfMissing tgtFiles
   logicMap <- liftIO makeLogicMap
-
-  let dataCons = concatMap (map dataConWorkId . tyConDataCons) (mgi_tcs modGuts)
-
-  let impVs = importVars coreBinds ++ classCons (mgi_cls_inst modGuts)
-  let defVs = definedVars coreBinds
-  let useVs = readVars coreBinds
-  let letVs = letVars coreBinds
-  let derVs = derivedVars coreBinds $ ((is_dfun <$>) <$>) $ mgi_cls_inst modGuts
+  runLiquidGhc hscEnv cfg (getGhcInfos' cfg logicMap tgtFiles)
 
-  (spc, imps, incs) <- moduleSpec cfg coreBinds (impVs ++ defVs) letVs name modGuts tgtSpec logicMap impSpecs
-  liftIO $ whenLoud $ putStrLn $ "Module Imports: " ++ show imps
-  hqualFiles <- moduleHquals modGuts paths target imps incs
+getGhcInfos' :: Config -> Either Error LogicMap
+            -> [FilePath]
+            -> Ghc ([GhcInfo], HscEnv)
+getGhcInfos' cfg logicMap tgtFiles = do
+  _           <- compileCFiles cfg
+  homeModules <- configureGhcTargets tgtFiles
+  depGraph    <- buildDepGraph homeModules
+  ghcInfos    <- processModules cfg logicMap tgtFiles depGraph homeModules
+  hscEnv      <- getSession
+  return (ghcInfos, hscEnv)
 
-  let info = GI target hscEnv coreBinds derVs impVs (letVs ++ dataCons) useVs hqualFiles imps incs spc
-  hscEnv' <- getSession
-  return (info, hscEnv')
+createTempDirectoryIfMissing :: FilePath -> IO ()
+createTempDirectoryIfMissing tgtFile = tryIgnore "create temp directory" $
+  createDirectoryIfMissing False $ tempDirectory tgtFile
 
 --------------------------------------------------------------------------------
--- Configure GHC for Liquid Haskell --------------------------------------------
+-- | GHC Configuration & Setup -------------------------------------------------
 --------------------------------------------------------------------------------
 
 runLiquidGhc :: Maybe HscEnv -> Config -> Ghc a -> IO a
@@ -111,105 +124,123 @@
   withSystemTempDirectory "liquid" $ \tmp ->
     runGhc (Just libdir) $ do
       maybe (return ()) setSession hscEnv
-      df <- getSessionDynFlags
-      (df',_,_) <- parseDynamicFlags df (map noLoc $ ghcOptions cfg)
-      loud <- liftIO isLoud
-      let df'' = df' { importPaths  = nub $ idirs cfg ++ importPaths df'
-                     , libraryPaths = nub $ idirs cfg ++ libraryPaths df'
-                     , includePaths = nub $ idirs cfg ++ includePaths df'
-                     , packageFlags = ExposePackage (PackageArg "ghc-prim") (ModRenaming True []) : packageFlags df'
-                     -- , profAuto     = ProfAutoCalls
-                     , ghcLink      = LinkInMemory
-                     --FIXME: this *should* be HscNothing, but that prevents us from
-                     -- looking up *unexported* names in another source module..
-                     , hscTarget    = HscInterpreted -- HscNothing
-                     , ghcMode      = CompManager
-                     -- prevent GHC from printing anything, unless in Loud mode
-                     , log_action   = if loud
-                                        then defaultLogAction
-                                        else \_ _ _ _ _ -> return ()
-                     -- redirect .hi/.o/etc files to temp directory
-                     , objectDir    = Just tmp
-                     , hiDir        = Just tmp
-                     , stubDir      = Just tmp
-                     } `xopt_set` Opt_MagicHash
-                       `gopt_set` Opt_ImplicitImportQualified
-                       `gopt_set` Opt_PIC
-      setSessionDynFlags df''
-      defaultCleanupHandler df'' act
-
---------------------------------------------------------------------------------
--- Parse, Find, & Load Targets -------------------------------------------------
---------------------------------------------------------------------------------
-
-parseRootTarget :: Config -> FilePath -> IO (Config, ModName, Ms.BareSpec)
-parseRootTarget cfg0 target = do
-  (name, tgtSpec) <- parseSpec target
-  cfg <- withPragmas cfg0 target $ Ms.pragmas tgtSpec
-  return (cfg, ModName Target $ getModName name, tgtSpec)
-
-findAndLoadTargets :: Config -> [FilePath] -> FilePath -> Ghc [(ModName, Ms.BareSpec)]
-findAndLoadTargets cfg paths target = do
-  setTargets . return =<< guessTarget target Nothing
-
-  impNames <- allDepNames <$> depanal [] False
-  impSpecs <- getSpecs cfg paths target impNames [Spec, Hs, LHs]
-  liftIO $ whenNormal $ donePhase Loud "Parsed All Specifications"
-
-  compileCFiles =<< liftIO (foldM (\c (f,_,s) -> withPragmas c f (Ms.pragmas s)) cfg impSpecs)
-
-  impSpecs' <- forM impSpecs $ \(f, n, s) -> do
-                 unless (isSpecImport n) $
-                   addTarget =<< guessTarget f Nothing
-                 return (n, s)
-  load LoadAllTargets
-  liftIO $ whenNormal $ donePhase Loud "Loaded Targets"
+      df <- configureDynFlags cfg tmp
+      defaultCleanupHandler df act
 
-  return impSpecs'
+configureDynFlags :: Config -> FilePath -> Ghc DynFlags
+configureDynFlags cfg tmp = do
+  df <- getSessionDynFlags
+  (df',_,_) <- parseDynamicFlags df $ map noLoc $ ghcOptions cfg
+  loud <- liftIO isLoud
+  let df'' = df' { importPaths  = nub $ idirs cfg ++ importPaths df'
+                 , libraryPaths = nub $ idirs cfg ++ libraryPaths df'
+                 , includePaths = nub $ idirs cfg ++ includePaths df'
+                 , packageFlags = ExposePackage (PackageArg "ghc-prim")
+                                                (ModRenaming True [])
+                                : packageFlags df'
+                 -- , profAuto     = ProfAutoCalls
+                 , ghcLink      = LinkInMemory
+                 , hscTarget    = HscInterpreted
+                 , ghcMode      = CompManager
+                 -- prevent GHC from printing anything, unless in Loud mode
+                 , log_action   = if loud
+                                    then defaultLogAction
+                                    else \_ _ _ _ _ -> return ()
+                 -- redirect .hi/.o/etc files to temp directory
+                 , objectDir    = Just tmp
+                 , hiDir        = Just tmp
+                 , stubDir      = Just tmp
+                 } `xopt_set` Opt_MagicHash
+                   `xopt_set` Opt_DeriveGeneric
+                   `xopt_set` Opt_StandaloneDeriving
+                   `gopt_set` Opt_ImplicitImportQualified
+                   `gopt_set` Opt_PIC
+  _ <- setSessionDynFlags df''
+  return df''
 
-allDepNames :: [ModSummary] -> [String]
-allDepNames = concatMap (map declNameString . ms_textual_imps)
+configureGhcTargets :: [FilePath] -> Ghc ModuleGraph
+configureGhcTargets tgtFiles = do
+  targets         <- mapM (`guessTarget` Nothing) tgtFiles
+  _               <- setTargets targets
+  moduleGraph     <- depanal [] False
+  let homeModules  = flattenSCCs $ topSortModuleGraph False moduleGraph Nothing
+  _               <- setTargetModules $ moduleName . ms_mod <$> homeModules
+  return homeModules
 
-declNameString :: GHC.Located (ImportDecl RdrName) -> String
-declNameString = moduleNameString . unLoc . ideclName . unLoc
+setTargetModules :: [ModuleName] -> Ghc ()
+setTargetModules modNames = setTargets $ mkTarget <$> modNames
+  where
+    mkTarget modName = GHC.Target (TargetModule modName) True Nothing
 
 compileCFiles :: Config -> Ghc ()
 compileCFiles cfg = do
   df  <- getSessionDynFlags
-  setSessionDynFlags $ df { includePaths = nub $ idirs cfg ++ includePaths df
-                          , importPaths  = nub $ idirs cfg ++ importPaths df
-                          , libraryPaths = nub $ idirs cfg ++ libraryPaths df }
+  _   <- setSessionDynFlags $
+           df { includePaths = nub $ idirs cfg ++ includePaths df
+              , importPaths  = nub $ idirs cfg ++ importPaths df
+              , libraryPaths = nub $ idirs cfg ++ libraryPaths df }
   hsc <- getSession
   os  <- mapM (\x -> liftIO $ compileFile hsc StopLn (x,Nothing)) (nub $ cFiles cfg)
   df  <- getSessionDynFlags
-  void $ setSessionDynFlags $ df { ldInputs = map (FileOption "") os ++ ldInputs df }
+  void $ setSessionDynFlags $ df { ldInputs = nub $ map (FileOption "") os ++ ldInputs df }
 
 --------------------------------------------------------------------------------
--- Assemble Information for Spec Extraction ------------------------------------
+-- Home Module Dependency Graph ------------------------------------------------
 --------------------------------------------------------------------------------
 
-makeMGIModGuts :: FilePath -> Ghc MGIModGuts
-makeMGIModGuts f = do
-  modGraph <- getModuleGraph
-  case find (\m -> not (isBootSummary m) && f == msHsFilePath m) modGraph of
-    Just modSummary -> do
-      parsed <- parseModule modSummary
-      modGuts <- coreModule <$> (desugarModule =<< typecheckModule (ignoreInline parsed))
-      let deriv = Just $ instEnvElts $ mg_inst_env modGuts
-      return $! miModGuts deriv modGuts
-    Nothing ->
-      panic Nothing $ "Ghc Interface: Unable to get GhcModGuts"
+type DepGraph = Graph DepGraphNode
+type DepGraphNode = Node Module ()
 
-makeLogicMap :: IO (Either Error LogicMap)
-makeLogicMap = do
-  lg    <- getCoreToLogicPath
-  lspec <- readFile lg
-  return $ parseSymbolToLogic lg lspec
+reachableModules :: DepGraph -> Module -> [Module]
+reachableModules depGraph mod =
+  snd3 <$> tail (reachableG depGraph ((), mod, []))
 
+buildDepGraph :: ModuleGraph -> Ghc DepGraph
+buildDepGraph homeModules =
+  graphFromEdgedVertices <$> mapM mkDepGraphNode homeModules
+
+mkDepGraphNode :: ModSummary -> Ghc DepGraphNode
+mkDepGraphNode modSummary = ((), ms_mod modSummary, ) <$>
+  (filterM isHomeModule =<< modSummaryImports modSummary)
+
+isHomeModule :: Module -> Ghc Bool
+isHomeModule mod = do
+  homePkg <- thisPackage <$> getSessionDynFlags
+  return $ modulePackageKey mod == homePkg
+
+modSummaryImports :: ModSummary -> Ghc [Module]
+modSummaryImports modSummary =
+  mapM (importDeclModule (ms_mod modSummary) . unLoc)
+       (ms_textual_imps modSummary)
+
+importDeclModule :: Module -> ImportDecl a -> Ghc Module
+importDeclModule fromMod decl = do
+  hscEnv <- getSession
+  let modName = unLoc $ ideclName decl
+  let pkgQual = ideclPkgQual decl
+  result <- liftIO $ findImportedModule hscEnv modName pkgQual
+  case result of
+    Finder.Found _ mod -> return mod
+    _ -> do
+      dflags <- getSessionDynFlags
+      liftIO $ throwGhcExceptionIO $ ProgramError $
+        O.showPpr dflags (moduleName fromMod) ++ ": " ++
+        O.showSDoc dflags (cannotFindModule dflags modName result)
+
 --------------------------------------------------------------------------------
--- Extract Ids -----------------------------------------------------------------
+-- | Extract Ids ---------------------------------------------------------------
 --------------------------------------------------------------------------------
 
+exportedVars :: GhcInfo -> [Var]
+exportedVars info = filter (isExportedVar info) (defVars info)
+
+isExportedVar :: GhcInfo -> Var -> Bool
+isExportedVar info v = n `elemNameSet` ns
+  where
+    n                = getName v
+    ns               = gsExports (spec info)
+
+
 classCons :: Maybe [ClsInst] -> [Id]
 classCons Nothing   = []
 classCons (Just cs) = concatMap (dataConImplicitIds . head . tyConDataCons . classTyCon . is_cls) cs
@@ -219,7 +250,7 @@
 derivedVars _   Nothing    = []
 
 derivedVs :: CoreProgram -> DFunId -> [Id]
-derivedVs cbs fd = concatMap bindersOf cbs' ++ deps
+derivedVs cbs fd   = concatMap bindersOf cbs' ++ deps
   where
     cbs'           = filter f cbs
     f (NonRec x _) = eqFd x
@@ -229,9 +260,9 @@
     unfolds        = unfoldingInfo . idInfo <$> concatMap bindersOf cbs'
 
 unfoldDep :: Unfolding -> [Id]
-unfoldDep (DFunUnfolding _ _ e)         = concatMap exprDep e
-unfoldDep (CoreUnfolding {uf_tmpl = e}) = exprDep e
-unfoldDep _                             = []
+unfoldDep (DFunUnfolding _ _ e)       = concatMap exprDep e
+unfoldDep CoreUnfolding {uf_tmpl = e} = exprDep e
+unfoldDep _                           = []
 
 exprDep :: CoreExpr -> [Id]
 exprDep = freeVars S.empty
@@ -246,85 +277,283 @@
     defs (Rec xes)    = map fst xes
 
 --------------------------------------------------------------------------------
--- Find & Parse Specs ----------------------------------------------------------
+-- | Per-Module Pipeline -------------------------------------------------------
 --------------------------------------------------------------------------------
 
-getSpecs cfg paths target names exts = do
-  fs' <- sortNub <$> moduleImports exts paths names
-  patSpec <- getPatSpec paths $ totality cfg
-  rlSpec <- getRealSpec paths $ not $ linear cfg
-  let fs = patSpec ++ rlSpec ++ fs'
-  transParseSpecs exts paths (S.singleton target) mempty (map snd fs \\ [target])
+type SpecEnv = ModuleEnv (ModName, Ms.BareSpec)
 
-getPatSpec paths totalitycheck
- | totalitycheck = (map (patErrorName,)) . maybeToList <$> moduleFile paths patErrorName Spec
- | otherwise     = return []
- where
-  patErrorName = "PatErr"
+processModules :: Config -> Either Error LogicMap -> [FilePath] -> DepGraph
+               -> ModuleGraph
+               -> Ghc [GhcInfo]
+processModules cfg logicMap tgtFiles depGraph homeModules = do
+  -- liftIO $ putStrLn $ "Process Modules: TargetFiles = " ++ show tgtFiles
+  catMaybes . snd <$> mapAccumM go emptyModuleEnv homeModules
+  where
+    go = processModule cfg logicMap (S.fromList tgtFiles) depGraph
 
-getRealSpec paths freal
-  | freal     = (map (realSpecName,))    . maybeToList <$> moduleFile paths realSpecName    Spec
-  | otherwise = (map (notRealSpecName,)) . maybeToList <$> moduleFile paths notRealSpecName Spec
+processModule :: Config -> Either Error LogicMap -> S.HashSet FilePath -> DepGraph
+              -> SpecEnv -> ModSummary
+              -> Ghc (SpecEnv, Maybe GhcInfo)
+processModule cfg logicMap tgtFiles depGraph specEnv modSummary = do
+  let mod              = ms_mod modSummary
+  -- _                <- liftIO $ putStrLn $ "Process Module: " ++ showPpr (moduleName mod)
+  file                <- liftIO $ canonicalizePath $ modSummaryHsFile modSummary
+  let isTarget         = file `S.member` tgtFiles
+  _                   <- loadDependenciesOf $ moduleName mod
+  parsed              <- parseModule $ keepRawTokenStream modSummary
+  let specComments     = extractSpecComments parsed
+  typechecked         <- typecheckModule $ ignoreInline parsed
+  let specQuotes       = extractSpecQuotes typechecked
+  _                   <- loadModule' typechecked
+  (modName, commSpec) <- either throw return $ hsSpecificationP (moduleName mod) specComments specQuotes
+  liftedSpec          <- liftIO $ if isTarget then return mempty else loadLiftedSpec file -- modName
+  let bareSpec         = commSpec `mappend` liftedSpec
+  _                   <- checkFilePragmas $ Ms.pragmas bareSpec
+  let specEnv'         = extendModuleEnv specEnv mod (modName, noTerm bareSpec)
+  (specEnv', ) <$> if isTarget
+                     then Just <$> processTargetModule cfg logicMap depGraph specEnv file typechecked bareSpec
+                     else return Nothing
+
+keepRawTokenStream :: ModSummary -> ModSummary
+keepRawTokenStream modSummary = modSummary
+  { ms_hspp_opts = ms_hspp_opts modSummary `gopt_set` Opt_KeepRawTokenStream }
+
+loadDependenciesOf :: ModuleName -> Ghc ()
+loadDependenciesOf modName = do
+  loadResult <- load $ LoadDependenciesOf modName
+  when (failed loadResult) $ liftIO $ throwGhcExceptionIO $ ProgramError $
+   "Failed to load dependencies of module " ++ showPpr modName
+
+loadModule' :: TypecheckedModule -> Ghc TypecheckedModule
+loadModule' tm = loadModule tm'
   where
-    realSpecName    = "Real"
-    notRealSpecName = "NotReal"
+    pm   = tm_parsed_module tm
+    ms   = pm_mod_summary pm
+    df   = ms_hspp_opts ms
+    df'  = df { hscTarget = HscNothing, ghcLink = NoLink }
+    ms'  = ms { ms_hspp_opts = df' }
+    pm'  = pm { pm_mod_summary = ms' }
+    tm'  = tm { tm_parsed_module = pm' }
 
+processTargetModule :: Config -> Either Error LogicMap -> DepGraph
+                    -> SpecEnv
+                    -> FilePath -> TypecheckedModule -> Ms.BareSpec
+                    -> Ghc GhcInfo
+processTargetModule cfg0 logicMap depGraph specEnv file typechecked bareSpec = do
+  cfg               <- liftIO $ withPragmas cfg0 file $ Ms.pragmas bareSpec
+  let modSummary     = pm_mod_summary $ tm_parsed_module typechecked
+  let mod            = ms_mod modSummary
+  let modName        = ModName Target $ moduleName mod
+  desugared         <- desugarModule typechecked
+  let modGuts        = makeMGIModGuts desugared
+  hscEnv            <- getSession
+  coreBinds         <- liftIO $ anormalize cfg hscEnv modGuts
+  _                 <- liftIO $ whenNormal $ donePhase Loud "A-Normalization"
+  let dataCons       = concatMap (map dataConWorkId . tyConDataCons) (mgi_tcs modGuts)
+  let impVs          = importVars coreBinds ++ classCons (mgi_cls_inst modGuts)
+  let defVs          = definedVars coreBinds
+  let useVs          = readVars coreBinds
+  let letVs          = letVars coreBinds
+  let derVs          = derivedVars coreBinds $ ((is_dfun <$>) <$>) $ mgi_cls_inst modGuts
+  let paths          = nub $ idirs cfg ++ importPaths (ms_hspp_opts modSummary)
+  _                 <- liftIO $ whenLoud $ putStrLn $ "paths = " ++ show paths
+  let reachable      = reachableModules depGraph mod
+  specSpecs         <- findAndParseSpecFiles cfg paths modSummary reachable
+  let homeSpecs      = cachedBareSpecs specEnv reachable
+  let impSpecs       = specSpecs ++ homeSpecs
+  (spc, imps, incs) <- toGhcSpec cfg file coreBinds (impVs ++ defVs) letVs modName modGuts bareSpec logicMap impSpecs
+  _                 <- liftIO $ whenLoud $ putStrLn $ "Module Imports: " ++ show imps
+  hqualsFiles       <- moduleHquals modGuts paths file imps incs
+  return GI { target    = file
+            , targetMod = moduleName mod
+            , env       = hscEnv
+            , cbs       = coreBinds
+            , derVars   = derVs
+            , impVars   = impVs
+            , defVars   = letVs ++ dataCons
+            , useVars   = useVs
+            , hqFiles   = hqualsFiles
+            , imports   = imps
+            , includes  = incs
+            , spec      = spc                }
 
-transParseSpecs _ _ _ specs [] = return specs
-transParseSpecs exts paths seenFiles specs newFiles = do
-  newSpecs <- liftIO $ mapM (\f -> addFst3 f <$> parseSpec f) newFiles
-  impFiles <- moduleImports exts paths $ specsImports newSpecs
-  let seenFiles' = seenFiles `S.union` (S.fromList newFiles)
-  let specs'     = specs ++ map (third3 noTerm) newSpecs
-  let newFiles'  = [f | (_, f) <- impFiles, not (f `S.member` seenFiles')]
-  transParseSpecs exts paths seenFiles' specs' newFiles'
+toGhcSpec :: GhcMonad m
+          => Config
+          -> FilePath
+          -> [CoreBind]
+          -> [Var]
+          -> [Var]
+          -> ModName
+          -> MGIModGuts
+          -> Ms.BareSpec
+          -> Either Error LogicMap
+          -> [(ModName, Ms.BareSpec)]
+          -> m (GhcSpec, [String], [FilePath])
+toGhcSpec cfg file cbs vars letVs tgtMod mgi tgtSpec lm impSpecs = do
+  let tgtCxt    = IIModule $ getModName tgtMod
+  let impCxt    = map (IIDecl . qualImportDecl . getModName . fst) impSpecs
+  _            <- setContext (tgtCxt : impCxt)
+  hsc          <- getSession
+  let impNames  = map (getModString . fst) impSpecs
+  let exports   = mgi_exports mgi
+  let specs     = (tgtMod, tgtSpec) : impSpecs
+  let imps      = sortNub $ impNames ++ [ symbolString x | (_, sp) <- specs, x <- Ms.imports sp ]
+  ghcSpec      <- liftIO $ makeGhcSpec cfg file tgtMod cbs (mgi_cls_inst mgi) vars letVs exports hsc lm specs
+  return (ghcSpec, imps, Ms.includes tgtSpec)
+
+modSummaryHsFile :: ModSummary -> FilePath
+modSummaryHsFile modSummary =
+  fromMaybe
+    (panic Nothing $
+      "modSummaryHsFile: missing .hs file for " ++
+      showPpr (ms_mod modSummary))
+    (ml_hs_file $ ms_location modSummary)
+
+cachedBareSpecs :: SpecEnv -> [Module] -> [(ModName, Ms.BareSpec)]
+cachedBareSpecs specEnv mods = lookupBareSpec <$> mods
   where
-    specsImports ss = nub $ concatMap (map symbolString . Ms.imports . thd3) ss
-    noTerm spec = spec { Ms.decr = mempty, Ms.lazy = mempty, Ms.termexprs = mempty }
+    lookupBareSpec m         = fromMaybe (err m) (lookupModuleEnv specEnv m)
+    err m                    = impossible Nothing ("lookupBareSpec: missing module " ++ showPpr m)
 
-parseSpec :: FilePath -> IO (ModName, Ms.BareSpec)
-parseSpec file = either throw return . specParser file =<< readFile file
+checkFilePragmas :: [Located String] -> Ghc ()
+checkFilePragmas = applyNonNull (return ()) throw . mapMaybe err
+  where
+    err pragma
+      | check (val pragma) = Just (ErrFilePragma $ fSrcSpan pragma :: Error)
+      | otherwise          = Nothing
+    check pragma           = any (`isPrefixOf` pragma) bad
+    bad =
+      [ "-i", "--idirs"
+      , "-g", "--ghc-option"
+      , "--c-files", "--cfiles"
+      ]
 
-specParser f str
-  | isExtFile Spec   f = specSpecificationP f str
-  | isExtFile Hs     f = hsSpecificationP   f str
-  | isExtFile HsBoot f = hsSpecificationP   f str
-  | isExtFile LHs    f = lhsSpecificationP  f str
-  | otherwise          = panic Nothing $ "SpecParser: Cannot Parse File " ++ f
+--------------------------------------------------------------------------------
+-- | Extract Specifications from GHC -------------------------------------------
+--------------------------------------------------------------------------------
 
+extractSpecComments :: ParsedModule -> [(SourcePos, String)]
+extractSpecComments parsed = mapMaybe extractSpecComment comments
+  where
+    comments = concat $ M.elems $ snd $ pm_annotations parsed
 
-moduleSpec cfg cbs vars letVs tgtMod mgi tgtSpec lm impSpecs = do
-  let tgtCxt = IIModule $ getModName tgtMod
-  let impCxt = map (IIDecl . qualImportDecl . getModName . fst) impSpecs
-  setContext (tgtCxt : impCxt)
+extractSpecComment :: GHC.Located AnnotationComment -> Maybe (SourcePos, String)
+extractSpecComment (GHC.L span (AnnBlockComment text))
+  | length text > 2 && isPrefixOf "{-@" text && isSuffixOf "@-}" text =
+    Just (offsetPos, take (length text - 6) $ drop 3 text)
+  where
+    offsetPos = incSourceColumn (srcSpanSourcePos span) 3
+extractSpecComment _ = Nothing
 
-  hsc <-getSession
+extractSpecQuotes :: TypecheckedModule -> [BPspec]
+extractSpecQuotes typechecked = mapMaybe extractSpecQuote anns
+  where
+    anns = map ann_value $
+           filter (isOurModTarget . ann_target) $
+           tcg_anns $ fst $ tm_internals_ typechecked
 
-  let impNames = map (getModString . fst) impSpecs
-  let exports  = mgi_exports mgi
+    isOurModTarget (ModuleTarget mod1) = mod1 == mod
+    isOurModTarget _ = False
 
-  let specs = (tgtMod, tgtSpec) : impSpecs
-  let imps  = sortNub $ impNames ++ [ symbolString x
-                                    | (_, sp) <- specs
-                                    , x <- Ms.imports sp
-                                    ]
+    mod = ms_mod $ pm_mod_summary $ tm_parsed_module typechecked
 
-  ghcSpec <- liftIO $ makeGhcSpec cfg tgtMod cbs vars letVs exports hsc lm specs
-  return (ghcSpec, imps, Ms.includes tgtSpec)
+extractSpecQuote :: AnnPayload -> Maybe BPspec
+extractSpecQuote payload =
+  case fromSerialized deserializeWithData payload of
+    Nothing -> Nothing
+    Just qt -> Just $ refreshSymbols $ liquidQuoteSpec qt
 
+refreshSymbols :: Data a => a -> a
+refreshSymbols = everywhere (mkT refreshSymbol)
+
+refreshSymbol :: Symbol -> Symbol
+refreshSymbol = symbol . symbolText
+
+--------------------------------------------------------------------------------
+-- | Finding & Parsing Files ---------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- | Handle Spec Files ---------------------------------------------------------
+
+findAndParseSpecFiles :: Config
+                      -> [FilePath]
+                      -> ModSummary
+                      -> [Module]
+                      -> Ghc [(ModName, Ms.BareSpec)]
+findAndParseSpecFiles cfg paths modSummary reachable = do
+  impSumms <- mapM getModSummary (moduleName <$> reachable)
+  imps''   <- nub . concat <$> mapM modSummaryImports (modSummary : impSumms)
+  imps'    <- filterM ((not <$>) . isHomeModule) imps''
+  let imps  = m2s <$> imps'
+  fs'      <- moduleFiles Spec paths imps
+  -- liftIO    $ print ("moduleFiles-imps'\n"  ++ show (m2s <$> imps'))
+  -- liftIO    $ print ("moduleFiles-imps\n"   ++ show imps)
+  -- liftIO    $ print ("moduleFiles-Paths\n"  ++ show paths)
+  -- liftIO    $ print ("moduleFiles-Specs\n"  ++ show fs')
+  patSpec  <- getPatSpec paths $ totalityCheck cfg
+  rlSpec   <- getRealSpec paths $ not $ linear cfg
+  let fs    = patSpec ++ rlSpec ++ fs'
+  transParseSpecs paths mempty mempty fs
+  where
+    m2s = moduleNameString . moduleName
+
+getPatSpec :: [FilePath] -> Bool -> Ghc [FilePath]
+getPatSpec paths totalitycheck
+ | totalitycheck = moduleFiles Spec paths [patErrorName]
+ | otherwise     = return []
+ where
+  patErrorName   = "PatErr"
+
+getRealSpec :: [FilePath] -> Bool -> Ghc [FilePath]
+getRealSpec paths freal
+  | freal     = moduleFiles Spec paths [realSpecName]
+  | otherwise = moduleFiles Spec paths [notRealSpecName]
+  where
+    realSpecName    = "Real"
+    notRealSpecName = "NotReal"
+
+transParseSpecs :: [FilePath]
+                -> S.HashSet FilePath -> [(ModName, Ms.BareSpec)]
+                -> [FilePath]
+                -> Ghc [(ModName, Ms.BareSpec)]
+transParseSpecs _ _ specs [] = return specs
+transParseSpecs paths seenFiles specs newFiles = do
+  newSpecs      <- liftIO $ mapM parseSpecFile newFiles
+  impFiles      <- moduleFiles Spec paths $ specsImports newSpecs
+  let seenFiles' = seenFiles `S.union` S.fromList newFiles
+  let specs'     = specs ++ map (second noTerm) newSpecs
+  let newFiles'  = filter (not . (`S.member` seenFiles')) impFiles
+  transParseSpecs paths seenFiles' specs' newFiles'
+  where
+    specsImports ss = nub $ concatMap (map symbolString . Ms.imports . snd) ss
+
+noTerm :: Ms.BareSpec -> Ms.BareSpec
+noTerm spec = spec { Ms.decr = mempty, Ms.lazy = mempty, Ms.termexprs = mempty }
+
+parseSpecFile :: FilePath -> IO (ModName, Ms.BareSpec)
+parseSpecFile file = either throw return . specSpecificationP file =<< readFile file
+
+-- Find Hquals Files -----------------------------------------------------------
+
+moduleHquals :: MGIModGuts
+             -> [FilePath]
+             -> FilePath
+             -> [String]
+             -> [FilePath]
+             -> Ghc [FilePath]
 moduleHquals mgi paths target imps incs = do
   hqs   <- specIncludes Hquals paths incs
-  hqs'  <- moduleImports [Hquals] paths (mgi_namestring mgi : imps)
+  hqs'  <- moduleFiles Hquals paths (mgi_namestring mgi : imps)
   hqs'' <- liftIO $ filterM doesFileExist [extFileName Hquals target]
-  return $ sortNub $ hqs'' ++ hqs ++ (snd <$> hqs')
+  return $ sortNub $ hqs'' ++ hqs ++ hqs'
 
+-- Find Files for Modules ------------------------------------------------------
 
-moduleImports :: [Ext] -> [FilePath] -> [String] -> Ghc [(String, FilePath)]
-moduleImports exts paths names = liftM concat $ forM names $ \name ->
-  map (name,) . catMaybes <$> mapM (moduleFile paths name) exts
+moduleFiles :: Ext -> [FilePath] -> [String] -> Ghc [FilePath]
+moduleFiles ext paths names = catMaybes <$> mapM (moduleFile ext paths) names
 
-moduleFile :: [FilePath] -> String -> Ext -> Ghc (Maybe FilePath)
-moduleFile paths name ext
+moduleFile :: Ext -> [FilePath] -> String -> Ghc (Maybe FilePath)
+moduleFile ext paths name
   | ext `elem` [Hs, LHs] = do
     graph <- getModuleGraph
     case find (\m -> not (isBootSummary m) &&
@@ -349,37 +578,61 @@
   | otherwise = Nothing
 
 --------------------------------------------------------------------------------
--- Pretty Printing -------------------------------------------------------------
+-- Assemble Information for Spec Extraction ------------------------------------
 --------------------------------------------------------------------------------
 
+makeMGIModGuts :: DesugaredModule -> MGIModGuts
+makeMGIModGuts desugared = miModGuts deriv modGuts
+  where
+    modGuts = coreModule desugared
+    deriv = Just $ instEnvElts $ mg_inst_env modGuts
+
+makeLogicMap :: IO (Either Error LogicMap)
+makeLogicMap = do
+  lg    <- getCoreToLogicPath
+  lspec <- readFile lg
+  return $ parseSymbolToLogic lg lspec
+
+--------------------------------------------------------------------------------
+-- | Pretty Printing -----------------------------------------------------------
+--------------------------------------------------------------------------------
+
 instance PPrint GhcSpec where
-  pprintTidy k spec =  (text "******* Target Variables ********************")
-              $$ (pprintTidy k $ tgtVars spec)
-              $$ (text "******* Type Signatures *********************")
-              $$ (pprintLongList $ tySigs spec)
-              $$ (text "******* Assumed Type Signatures *************")
-              $$ (pprintLongList $ asmSigs spec)
-              $$ (text "******* DataCon Specifications (Measure) ****")
-              $$ (pprintLongList $ ctors spec)
-              $$ (text "******* Measure Specifications **************")
-              $$ (pprintLongList $ meas spec)
+  pprintTidy k spec = vcat
+    [ "******* Target Variables ********************"
+    , pprintTidy k $ gsTgtVars spec
+    , "******* Type Signatures *********************"
+    , pprintLongList k (gsTySigs spec)
+    , "******* Assumed Type Signatures *************"
+    , pprintLongList k (gsAsmSigs spec)
+    , "******* DataCon Specifications (Measure) ****"
+    , pprintLongList k (gsCtors spec)
+    , "******* Measure Specifications **************"
+    , pprintLongList k (gsMeas spec)                   ]
 
 instance PPrint GhcInfo where
-  pprintTidy k info =   (text "*************** Imports *********************")
-              $+$ (intersperse comma $ text <$> imports info)
-              $+$ (text "*************** Includes ********************")
-              $+$ (intersperse comma $ text <$> includes info)
-              $+$ (text "*************** Imported Variables **********")
-              $+$ (pprDoc $ impVars info)
-              $+$ (text "*************** Defined Variables ***********")
-              $+$ (pprDoc $ defVars info)
-              $+$ (text "*************** Specification ***************")
-              $+$ (pprintTidy k $ spec info)
-              $+$ (text "*************** Core Bindings ***************")
-              $+$ (pprintCBs $ cbs info)
+  pprintTidy k info = vcat
+    [ "*************** Imports *********************"
+    , intersperse comma $ text <$> imports info
+    , "*************** Includes ********************"
+    , intersperse comma $ text <$> includes info
+    , "*************** Imported Variables **********"
+    , pprDoc $ impVars info
+    , "*************** Defined Variables ***********"
+    , pprDoc $ defVars info
+    , "*************** Specification ***************"
+    , pprintTidy k $ spec info
+    , "*************** Core Bindings ***************"
+    , pprintCBs $ cbs info                          ]
 
+-- RJ: the silly guards below are to silence the unused-var checker
 pprintCBs :: [CoreBind] -> Doc
-pprintCBs = pprDoc . tidyCBs
+pprintCBs
+  | otherwise = pprintCBsTidy
+  | otherwise = pprintCBsVerbose
+  where
+    pprintCBsTidy    = pprDoc . tidyCBs
+    pprintCBsVerbose = text . O.showSDocDebug unsafeGlobalDynFlags . O.ppr . tidyCBs
 
 instance Show GhcInfo where
   show = showpp
@@ -398,5 +651,5 @@
          . bagToList
          . srcErrorMessages
 
+errMsgErrors :: ErrMsg -> [TError t]
 errMsgErrors e = [ ErrGhc (errMsgSpan e) (pprint e)]
-
diff --git a/src/Language/Haskell/Liquid/GHC/Misc.hs b/src/Language/Haskell/Liquid/GHC/Misc.hs
--- a/src/Language/Haskell/Liquid/GHC/Misc.hs
+++ b/src/Language/Haskell/Liquid/GHC/Misc.hs
@@ -15,71 +15,71 @@
 
 module Language.Haskell.Liquid.GHC.Misc where
 
-import PrelNames (fractionalClassKeys)
-import Class     (classKey)
+import           Class                                      (classKey)
+import           Data.String
+import           PrelNames                                  (fractionalClassKeys)
 
 import           Debug.Trace
 
-import           Prelude                      hiding (error)
-import           Avail                        (availsToNameSet)
-import           BasicTypes                   (Arity)
-import           CoreSyn                      hiding (Expr, sourceName)
-import qualified CoreSyn as Core
+import           DataCon                                    (isTupleDataCon)
+import           Prelude                                    hiding (error)
+import           Avail                                      (availsToNameSet)
+import           BasicTypes                                 (Arity)
+import           CoreSyn                                    hiding (Expr, sourceName)
+import qualified CoreSyn                                    as Core
 import           CostCentre
-import           GHC                          hiding (L)
-import           HscTypes                     (Dependencies, ImportedMods, ModGuts(..), HscEnv(..), FindResult(..))
-import           Kind                         (superKind)
-import           NameSet                      (NameSet)
-import           SrcLoc                       hiding (L)
+import           GHC                                        hiding (L)
+import           HscTypes                                   (Dependencies, ImportedMods, ModGuts(..), HscEnv(..), FindResult(..))
+import           Kind                                       (superKind)
+import           NameSet                                    (NameSet)
+import           SrcLoc                                     hiding (L)
 import           Bag
 import           ErrUtils
 import           CoreLint
 import           CoreMonad
 
-import           Text.Parsec.Pos              (sourceName, sourceLine, sourceColumn, newPos)
+import           Text.Parsec.Pos                            (incSourceColumn, sourceName, sourceLine, sourceColumn, newPos)
 
-import           Name                         (mkInternalName, getSrcSpan, nameModule_maybe)
-import           Module                       (moduleNameFS)
-import           OccName                      (mkTyVarOcc, mkVarOcc, mkTcOcc, occNameFS)
+import           Name
+import           Module                                     (moduleNameFS)
 import           Unique
-import           Finder                       (findImportedModule, cannotFindModule)
-import           Panic                        (throwGhcException)
+import           Finder                                     (findImportedModule, cannotFindModule)
+import           Panic                                      (throwGhcException)
 import           FastString
 import           TcRnDriver
 -- import           TcRnTypes
 
 
 import           RdrName
-import           Type                         (liftedTypeKind)
+import           Type                                       (liftedTypeKind)
 import           TypeRep
 import           Var
 import           IdInfo
-import qualified TyCon                        as TC
-import           Data.Char                    (isLower, isSpace)
-import           Data.Maybe                   (fromMaybe)
+import qualified TyCon                                      as TC
+import           Data.Char                                  (isLower, isSpace)
+import           Data.Maybe                                 (isJust, fromMaybe)
 import           Data.Hashable
-import qualified Data.HashSet                 as S
+import qualified Data.HashSet                               as S
 
-import qualified Data.Text.Encoding           as T
-import qualified Data.Text                    as T
-import           Control.Arrow                (second)
-import           Control.Monad                ((>=>))
-import           Outputable                   (Outputable (..), text, ppr)
-import qualified Outputable                   as Out
+import qualified Data.Text.Encoding.Error                   as TE
+import qualified Data.Text.Encoding                         as T
+import qualified Data.Text                                  as T
+import           Control.Arrow                              (second)
+import           Control.Monad                              ((>=>))
+import           Outputable                                 (Outputable (..), text, ppr)
+import qualified Outputable                                 as Out
 import           DynFlags
-import qualified Text.PrettyPrint.HughesPJ    as PJ
-import           Language.Fixpoint.Types      hiding (L, Loc (..), SrcSpan, Constant, SESearch (..))
-import qualified Language.Fixpoint.Types      as F
-import           Language.Fixpoint.Misc       (safeHead, safeLast, safeInit)
-import           Language.Haskell.Liquid.Desugar710.HscMain
+import qualified Text.PrettyPrint.HughesPJ                  as PJ
+import           Language.Fixpoint.Types                    hiding (L, Loc (..), SrcSpan, Constant, SESearch (..))
+import qualified Language.Fixpoint.Types                    as F
+import           Language.Fixpoint.Misc                     (safeHead, safeLast, safeInit)
+import           Language.Haskell.Liquid.Desugar.HscMain
 import           Control.DeepSeq
 import           Language.Haskell.Liquid.Types.Errors
 
-
------------------------------------------------------------------------
---------------- Datatype For Holding GHC ModGuts ----------------------
------------------------------------------------------------------------
-
+--------------------------------------------------------------------------------
+-- | Datatype For Holding GHC ModGuts ------------------------------------------
+--------------------------------------------------------------------------------
 data MGIModGuts = MI {
     mgi_binds     :: !CoreProgram
   , mgi_module    :: !Module
@@ -92,6 +92,7 @@
   , mgi_cls_inst  :: !(Maybe [ClsInst])
   }
 
+miModGuts :: Maybe [ClsInst] -> ModGuts -> MGIModGuts
 miModGuts cls mg  = MI {
     mgi_binds     = mg_binds mg
   , mgi_module    = mg_module mg
@@ -104,6 +105,7 @@
   , mgi_cls_inst  = cls
   }
 
+mgi_namestring :: MGIModGuts -> String
 mgi_namestring = moduleNameString . moduleName . mgi_module
 
 --------------------------------------------------------------------------------
@@ -117,15 +119,17 @@
 tickSrcSpan (SourceNote ss _) = RealSrcSpan ss
 tickSrcSpan _                 = noSrcSpan
 
------------------------------------------------------------------------
---------------- Generic Helpers for Accessing GHC Innards -------------
------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Generic Helpers for Accessing GHC Innards ---------------------------------
+--------------------------------------------------------------------------------
 
+-- FIXME: reusing uniques like this is really dangerous
 stringTyVar :: String -> TyVar
 stringTyVar s = mkTyVar name liftedTypeKind
   where name = mkInternalName (mkUnique 'x' 24)  occ noSrcSpan
         occ  = mkTyVarOcc s
 
+-- FIXME: reusing uniques like this is really dangerous
 stringVar :: String -> Type -> Var
 stringVar s t = mkLocalVar VanillaId name t vanillaIdInfo
    where
@@ -135,15 +139,18 @@
 stringTyCon :: Char -> Int -> String -> TyCon
 stringTyCon = stringTyConWithKind superKind
 
+-- FIXME: reusing uniques like this is really dangerous
 stringTyConWithKind :: Kind -> Char -> Int -> String -> TyCon
 stringTyConWithKind k c n s = TC.mkKindTyCon name k
   where
     name          = mkInternalName (mkUnique c n) occ noSrcSpan
     occ           = mkTcOcc s
 
+hasBaseTypeVar :: Var -> Bool
 hasBaseTypeVar = isBaseType . varType
 
 -- same as Constraint isBase
+isBaseType :: Type -> Bool
 isBaseType (ForAllTy _ t)  = isBaseType t
 isBaseType (TyVarTy _)     = True
 isBaseType (TyConApp _ ts) = all isBaseType ts
@@ -155,18 +162,17 @@
 validTyVar s@(c:_) = isLower c && all (not . isSpace) s
 validTyVar _       = False
 
+tvId :: TyVar -> String
 tvId α = {- traceShow ("tvId: α = " ++ show α) $ -} showPpr α ++ show (varUnique α)
 
-tracePpr s x = trace ("\nTrace: [" ++ s ++ "] : " ++ showPpr x) x
-
-pprShow = text . show
-
-
+tidyCBs :: [CoreBind] -> [CoreBind]
 tidyCBs = map unTick
 
+unTick :: CoreBind -> CoreBind
 unTick (NonRec b e) = NonRec b (unTickExpr e)
 unTick (Rec bs)     = Rec $ map (second unTickExpr) bs
 
+unTickExpr :: CoreExpr -> CoreExpr
 unTickExpr (App e a)          = App (unTickExpr e) (unTickExpr a)
 unTickExpr (Lam b e)          = Lam b (unTickExpr e)
 unTickExpr (Let b e)          = Let (unTick b) (unTickExpr e)
@@ -176,54 +182,67 @@
 unTickExpr (Tick _ e)         = unTickExpr e
 unTickExpr x                  = x
 
+isFractionalClass :: Class -> Bool
 isFractionalClass clas = classKey clas `elem` fractionalClassKeys
 
------------------------------------------------------------------------
------------------- Generic Helpers for DataConstructors ---------------
------------------------------------------------------------------------
 
-isDataConId id = case idDetails id of
-                  DataConWorkId _ -> True
-                  DataConWrapId _ -> True
-                  _               -> False
-
-getDataConVarUnique v
-  | isId v && isDataConId v = getUnique $ idDataCon v
-  | otherwise               = getUnique v
-
-
-newtype Loc    = L (Int, Int) deriving (Eq, Ord, Show)
-
-instance Hashable Loc where
-  hashWithSalt i (L z) = hashWithSalt i z
-
---instance (Uniquable a) => Hashable a where
-
-instance Hashable SrcSpan where
-  hashWithSalt i (UnhelpfulSpan s) = hashWithSalt i (uniq s)
-  hashWithSalt i (RealSrcSpan s)   = hashWithSalt i (srcSpanStartLine s, srcSpanStartCol s, srcSpanEndCol s)
+--------------------------------------------------------------------------------
+-- | Pretty Printers -----------------------------------------------------------
+--------------------------------------------------------------------------------
 
-instance Outputable a => Outputable (S.HashSet a) where
-  ppr = ppr . S.toList
+tracePpr :: Outputable a => String -> a -> a
+tracePpr s x = trace ("\nTrace: [" ++ s ++ "] : " ++ showPpr x) x
 
+pprShow :: Show a => a -> Out.SDoc
+pprShow = text . show
 
 
--------------------------------------------------------
-
+toFixSDoc :: Fixpoint a => a -> PJ.Doc
 toFixSDoc = PJ.text . PJ.render . toFix
+
+sDocDoc :: Out.SDoc -> PJ.Doc
 sDocDoc   = PJ.text . showSDoc
+
+pprDoc :: Outputable a => a -> PJ.Doc
 pprDoc    = sDocDoc . ppr
 
 -- Overriding Outputable functions because they now require DynFlags!
+showPpr :: Outputable a => a -> String
 showPpr       = showSDoc . ppr
 
 -- FIXME: somewhere we depend on this printing out all GHC entities with
 -- fully-qualified names...
-showSDoc sdoc = Out.renderWithStyle unsafeGlobalDynFlags sdoc (Out.mkUserStyle Out.alwaysQualify Out.AllTheWay)
+showSDoc :: Out.SDoc -> String
+showSDoc sdoc = Out.renderWithStyle unsafeGlobalDynFlags sdoc (Out.mkUserStyle myQualify {- Out.alwaysQualify -} Out.AllTheWay)
+
+myQualify :: Out.PrintUnqualified
+myQualify = Out.neverQualify { Out.queryQualifyName = Out.alwaysQualifyNames }
+-- { Out.queryQualifyName = \_ _ -> Out.NameNotInScope1 }
+
+showSDocDump :: Out.SDoc -> String
 showSDocDump  = Out.showSDocDump unsafeGlobalDynFlags
 
+instance Outputable a => Outputable (S.HashSet a) where
+  ppr = ppr . S.toList
+
+typeUniqueString :: Outputable a => a -> String
 typeUniqueString = {- ("sort_" ++) . -} showSDocDump . ppr
 
+
+--------------------------------------------------------------------------------
+-- | Manipulating Source Spans -------------------------------------------------
+--------------------------------------------------------------------------------
+
+newtype Loc    = L (Int, Int) deriving (Eq, Ord, Show)
+
+instance Hashable Loc where
+  hashWithSalt i (L z) = hashWithSalt i z
+
+--instance (Uniquable a) => Hashable a where
+
+instance Hashable SrcSpan where
+  hashWithSalt i (UnhelpfulSpan s) = hashWithSalt i (uniq s)
+  hashWithSalt i (RealSrcSpan s)   = hashWithSalt i (srcSpanStartLine s, srcSpanStartCol s, srcSpanEndCol s)
 fSrcSpan :: (F.Loc a) => a -> SrcSpan
 fSrcSpan = fSrcSpanSrcSpan . F.srcSpan
 
@@ -243,7 +262,8 @@
     (_, l', c')        = F.sourcePosElts p'
 
 sourcePosSrcSpan   :: SourcePos -> SrcSpan
-sourcePosSrcSpan = srcLocSpan . sourcePosSrcLoc
+-- sourcePosSrcSpan = srcLocSpan . sourcePosSrcLoc
+sourcePosSrcSpan p = sourcePos2SrcSpan p (incSourceColumn p 1)
 
 sourcePosSrcLoc    :: SourcePos -> SrcLoc
 sourcePosSrcLoc p = mkSrcLoc (fsLit file) line col
@@ -260,12 +280,19 @@
 srcSpanSourcePosE (UnhelpfulSpan _) = dummyPos "<no source information>"
 srcSpanSourcePosE (RealSrcSpan s)   = realSrcSpanSourcePosE s
 
-
-
+srcSpanFilename :: SrcSpan -> String
 srcSpanFilename    = maybe "" unpackFS . srcSpanFileName_maybe
+
+srcSpanStartLoc :: RealSrcSpan -> Loc
 srcSpanStartLoc l  = L (srcSpanStartLine l, srcSpanStartCol l)
+
+srcSpanEndLoc :: RealSrcSpan -> Loc
 srcSpanEndLoc l    = L (srcSpanEndLine l, srcSpanEndCol l)
+
+oneLine :: RealSrcSpan -> Bool
 oneLine l          = srcSpanStartLine l == srcSpanEndLine l
+
+lineCol :: RealSrcSpan -> (Int, Int)
 lineCol l          = (srcSpanStartLine l, srcSpanStartCol l)
 
 realSrcSpanSourcePos :: RealSrcSpan -> SourcePos
@@ -283,15 +310,36 @@
     line                = srcSpanEndLine       s
     col                 = srcSpanEndCol        s
 
+getSourcePos :: NamedThing a => a -> SourcePos
+getSourcePos = srcSpanSourcePos  . getSrcSpan
 
-getSourcePos           = srcSpanSourcePos  . getSrcSpan
-getSourcePosE          = srcSpanSourcePosE . getSrcSpan
+getSourcePosE :: NamedThing a => a -> SourcePos
+getSourcePosE = srcSpanSourcePosE . getSrcSpan
 
+locNamedThing :: NamedThing a => a -> F.Located a
+locNamedThing x = F.Loc l lE x
+  where
+    l          = getSourcePos  x
+    lE         = getSourcePosE x
+
+namedLocSymbol :: (F.Symbolic a, NamedThing a) => a -> F.Located F.Symbol
+namedLocSymbol d = dropModuleNamesAndUnique . F.symbol <$> locNamedThing d
+
+varLocInfo :: (Type -> a) -> Var -> F.Located a
+varLocInfo f x = f . varType <$> locNamedThing x
+
+--------------------------------------------------------------------------------
+-- | Manipulating CoreExpr -----------------------------------------------------
+--------------------------------------------------------------------------------
+
+collectArguments :: Int -> CoreExpr -> [Var]
 collectArguments n e = if length xs > n then take n xs else xs
-  where (vs', e') = collectValBinders' $ snd $ collectTyBinders e
-        vs        = fst $ collectValBinders $ ignoreLetBinds e'
-        xs        = vs' ++ vs
+  where
+    (vs', e')        = collectValBinders' $ snd $ collectTyBinders e
+    vs               = fst $ collectValBinders $ ignoreLetBinds e'
+    xs               = vs' ++ vs
 
+collectValBinders' :: Core.Expr Var -> ([Var], Core.Expr Var)
 collectValBinders' = go []
   where
     go tvs (Lam b e) | isTyVar b = go tvs     e
@@ -299,17 +347,38 @@
     go tvs (Tick _ e)            = go tvs e
     go tvs e                     = (reverse tvs, e)
 
+ignoreLetBinds :: Core.Expr t -> Core.Expr t
 ignoreLetBinds (Let (NonRec _ _) e')
   = ignoreLetBinds e'
 ignoreLetBinds e
   = e
 
+--------------------------------------------------------------------------------
+-- | Predicates on CoreExpr and DataCons ---------------------------------------
+--------------------------------------------------------------------------------
+
+isTupleId :: Id -> Bool
+isTupleId = maybe False isTupleDataCon . idDataConM
+
+idDataConM :: Id -> Maybe DataCon
+idDataConM x = case idDetails x of
+  DataConWorkId d -> Just d
+  DataConWrapId d -> Just d
+  _               -> Nothing
+
+isDataConId :: Id -> Bool
+isDataConId = isJust . idDataConM
+
+getDataConVarUnique :: Var -> Unique
+getDataConVarUnique v
+  | isId v && isDataConId v = getUnique $ idDataCon v
+  | otherwise               = getUnique v
+
 isDictionaryExpression :: Core.Expr Id -> Maybe Id
 isDictionaryExpression (Tick _ e) = isDictionaryExpression e
 isDictionaryExpression (Var x)    | isDictionary x = Just x
 isDictionaryExpression _          = Nothing
 
-
 realTcArity :: TyCon -> Arity
 realTcArity
   = kindArity . TC.tyConKind
@@ -318,11 +387,11 @@
 kindArity (FunTy _ res)
   = 1 + kindArity res
 kindArity (ForAllTy _ res)
-  = kindArity res
+  = 1 + kindArity res
 kindArity _
   = 0
 
-
+uniqueHash :: Uniquable a => Int -> a -> Int
 uniqueHash i = hashWithSalt i . getKey . getUnique
 
 -- slightly modified version of DynamicLoading.lookupRdrNameInModule
@@ -354,18 +423,27 @@
         throwCmdLineError = throwGhcException . CmdLineError
 
 
+qualImportDecl :: ModuleName -> ImportDecl name
 qualImportDecl mn = (simpleImportDecl mn) { ideclQualified = True }
 
+ignoreInline :: ParsedModule -> ParsedModule
 ignoreInline x = x {pm_parsed_source = go <$> pm_parsed_source x}
   where go  x = x {hsmodDecls = filter go' $ hsmodDecls x}
         go' x | SigD (InlineSig _ _) <-  unLoc x = False
               | otherwise                        = True
 
+--------------------------------------------------------------------------------
+-- | Symbol Conversions --------------------------------------------------------
+--------------------------------------------------------------------------------
+
+symbolTyConWithKind :: Kind -> Char -> Int -> Symbol -> TyCon
 symbolTyConWithKind k x i n = stringTyConWithKind k x i (symbolString n)
-symbolTyCon x i n = stringTyCon x i (symbolString n)
-symbolTyVar n = stringTyVar (symbolString n)
 
+symbolTyCon :: Char -> Int -> Symbol -> TyCon
+symbolTyCon x i n = stringTyCon x i (symbolString n)
 
+symbolTyVar :: Symbol -> TyVar
+symbolTyVar n = stringTyVar (symbolString n)
 
 varSymbol ::  Var -> Symbol
 varSymbol v
@@ -375,30 +453,45 @@
     us                    = symbol $ showPpr $ getDataConVarUnique v
     vs                    = symbol $ getName v
 
-qualifiedNameSymbol n = symbol $
-  case nameModule_maybe n of
-    Nothing -> occNameFS (getOccName n)
-    Just m  -> concatFS [moduleNameFS (moduleName m), fsLit ".", occNameFS (getOccName n)]
+qualifiedNameSymbol :: Name -> Symbol
+qualifiedNameSymbol n = symbol $ concatFS [modFS, occFS, uniqFS]
+  where
+  _msg   = showSDoc (ppr n) -- getOccString n
+  modFS = case nameModule_maybe n of
+            Nothing -> fsLit ""
+            Just m  -> concatFS [moduleNameFS (moduleName m), fsLit "."]
 
+  occFS = occNameFS (getOccName n)
+  uniqFS
+    | isSystemName n
+    = concatFS [fsLit "_",  fsLit (showPpr (getUnique n))]
+    | otherwise
+    = fsLit ""
+
 instance Symbolic FastString where
   symbol = symbol . fastStringText
 
-fastStringText = T.decodeUtf8 . fastStringToByteString
+fastStringText :: FastString -> T.Text
+fastStringText = T.decodeUtf8With TE.lenientDecode . fastStringToByteString
 
+tyConTyVarsDef :: TyCon -> [TyVar]
 tyConTyVarsDef c | TC.isPrimTyCon c || isFunTyCon c = []
-tyConTyVarsDef c | TC.isPromotedTyCon   c = panic Nothing ("TyVars on " ++ show c) -- tyConTyVarsDef $ TC.ty_con c
-tyConTyVarsDef c | TC.isPromotedDataCon c = panic Nothing ("TyVars on " ++ show c) -- DC.dataConUnivTyVars $ TC.datacon c
+tyConTyVarsDef c | TC.isPromotedTyCon   c = []
+tyConTyVarsDef c | TC.isPromotedDataCon c = []
 tyConTyVarsDef c = TC.tyConTyVars c
 
-----------------------------------------------------------------------
--- Myriad Instances
-----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Symbol Instances
+--------------------------------------------------------------------------------
 
 instance Symbolic TyCon where
-  symbol = symbol . qualifiedNameSymbol . getName
+  symbol = symbol . getName
 
+instance Symbolic Class where
+  symbol = symbol . getName
+
 instance Symbolic Name where
-  symbol = symbol . showPpr
+  symbol = symbol . qualifiedNameSymbol
 
 instance Symbolic Var where
   symbol = varSymbol
@@ -419,16 +512,16 @@
   toFix = pprDoc
 
 instance Show Name where
-  show = showPpr
+  show = symbolString . symbol
 
 instance Show Var where
-  show = showPpr
+  show = show . getName
 
 instance Show Class where
-  show = showPpr
+  show = show . getName
 
 instance Show TyCon where
-  show = showPpr
+  show = show . getName
 
 instance NFData Class where
   rnf t = seq t ()
@@ -446,69 +539,42 @@
   rnf t = seq t ()
 
 
-----------------------------------------------------------------------
--- GHC Compatibility Layer
-----------------------------------------------------------------------
-
-gHC_VERSION :: String
-gHC_VERSION = show __GLASGOW_HASKELL__
-
-symbolFastString :: Symbol -> FastString
-symbolFastString = mkFastStringByteString . T.encodeUtf8 . symbolText
-
-desugarModule :: TypecheckedModule -> Ghc DesugaredModule
-desugarModule tcm = do
-  let ms = pm_mod_summary $ tm_parsed_module tcm
-  -- let ms = modSummary tcm
-  let (tcg, _) = tm_internals_ tcm
-  hsc_env <- getSession
-  let hsc_env_tmp = hsc_env { hsc_dflags = ms_hspp_opts ms }
-  guts <- liftIO $ hscDesugarWithLoc hsc_env_tmp ms tcg
-  return DesugaredModule { dm_typechecked_module = tcm, dm_core_module = guts }
-
--- desugarModule = GHC.desugarModule
-
-type Prec = TyPrec
-
-lintCoreBindings :: [Var] -> CoreProgram -> (Bag MsgDoc, Bag MsgDoc)
-lintCoreBindings = CoreLint.lintCoreBindings CoreDoNothing
-
-synTyConRhs_maybe :: TyCon -> Maybe Type
-synTyConRhs_maybe = TC.synTyConRhs_maybe
-
-tcRnLookupRdrName :: HscEnv -> GHC.Located RdrName -> IO (Messages, Maybe [Name])
-tcRnLookupRdrName = TcRnDriver.tcRnLookupRdrName
+--------------------------------------------------------------------------------
+-- | Manipulating Symbols ------------------------------------------------------
+--------------------------------------------------------------------------------
 
+splitModuleName :: Symbol -> (Symbol, Symbol)
+splitModuleName x = (takeModuleNames x, dropModuleNamesAndUnique x)
 
-------------------------------------------------------------------------
--- | Manipulating Symbols ----------------------------------------------
-------------------------------------------------------------------------
+dropModuleNamesAndUnique :: Symbol -> Symbol
+dropModuleNamesAndUnique = dropModuleUnique . dropModuleNames
 
-dropModuleNames, takeModuleNames, dropModuleUnique :: Symbol -> Symbol
+dropModuleNames  :: Symbol -> Symbol
 dropModuleNames  = mungeNames lastName sepModNames "dropModuleNames: "
   where
     lastName msg = symbol . safeLast msg
 
+takeModuleNames  :: Symbol -> Symbol
 takeModuleNames  = mungeNames initName sepModNames "takeModuleNames: "
   where
     initName msg = symbol . T.intercalate "." . safeInit msg
 
+dropModuleUnique :: Symbol -> Symbol
 dropModuleUnique = mungeNames headName sepUnique   "dropModuleUnique: "
   where
     headName msg = symbol . safeHead msg
 
 
-sepModNames = "."
-sepUnique   = "#"
-
+cmpSymbol :: Symbol -> Symbol -> Bool
+cmpSymbol coreSym logicSym
+  =  (dropModuleUnique coreSym == dropModuleNamesAndUnique logicSym)
+  || (dropModuleUnique coreSym == dropModuleUnique         logicSym)
 
--- safeHead :: String -> [T.Text] -> Symbol
--- safeHead msg []  = errorstar $ "safeHead with empty list" ++ msg
--- safeHead _ (x:_) = symbol x
+sepModNames :: T.Text
+sepModNames = "."
 
--- safeInit :: String -> [T.Text] -> Symbol
--- safeInit _ xs@(_:_)      = symbol $ T.intercalate "." $ init xs
--- safeInit msg _           = errorstar $ "safeInit with empty list " ++ msg
+sepUnique :: T.Text
+sepUnique = "#"
 
 mungeNames :: (String -> [T.Text] -> Symbol) -> T.Text -> String -> Symbol -> Symbol
 mungeNames _ _ _ ""  = ""
@@ -522,11 +588,19 @@
   | isParened x    = symbol (wrapParens (m `mappend` "." `mappend` stripParens x))
   | otherwise      = symbol (m `mappend` "." `mappend` x)
 
+isQualified :: T.Text -> Bool
 isQualified y = "." `T.isInfixOf` y
+
+wrapParens :: (IsString a, Monoid a) => a -> a
 wrapParens x  = "(" `mappend` x `mappend` ")"
+
+isParened :: T.Text -> Bool
 isParened xs  = xs /= stripParens xs
 
+isDictionary :: Symbolic a => a -> Bool
 isDictionary = isPrefixOfSym "$f" . dropModuleNames . symbol
+
+isInternal :: Symbolic a => a -> Bool
 isInternal   = isPrefixOfSym "$"  . dropModuleNames . symbol
 
 stripParens :: T.Text -> T.Text
@@ -537,6 +611,65 @@
 stripParensSym :: Symbol -> Symbol
 stripParensSym (symbolText -> t) = symbol $ stripParens t
 
+
+
 --------------------------------------------------------------------------------
--- | Source Info = Stack of most recent binders/spans
+-- | GHC Compatibility Layer ---------------------------------------------------
 --------------------------------------------------------------------------------
+
+gHC_VERSION :: String
+gHC_VERSION = show __GLASGOW_HASKELL__
+
+symbolFastString :: Symbol -> FastString
+symbolFastString = mkFastStringByteString . T.encodeUtf8 . symbolText
+
+desugarModule :: TypecheckedModule -> Ghc DesugaredModule
+desugarModule tcm = do
+  let ms = pm_mod_summary $ tm_parsed_module tcm
+  -- let ms = modSummary tcm
+  let (tcg, _) = tm_internals_ tcm
+  hsc_env <- getSession
+  let hsc_env_tmp = hsc_env { hsc_dflags = ms_hspp_opts ms }
+  guts <- liftIO $ hscDesugarWithLoc hsc_env_tmp ms tcg
+  return DesugaredModule { dm_typechecked_module = tcm, dm_core_module = guts }
+
+-- desugarModule = GHC.desugarModule
+
+type Prec = TyPrec
+
+lintCoreBindings :: [Var] -> CoreProgram -> (Bag MsgDoc, Bag MsgDoc)
+lintCoreBindings = CoreLint.lintCoreBindings CoreDoNothing
+
+synTyConRhs_maybe :: TyCon -> Maybe Type
+synTyConRhs_maybe = TC.synTyConRhs_maybe
+
+tcRnLookupRdrName :: HscEnv -> GHC.Located RdrName -> IO (Messages, Maybe [Name])
+tcRnLookupRdrName = TcRnDriver.tcRnLookupRdrName
+
+showCBs :: Bool -> [CoreBind] -> String
+showCBs untidy
+  | untidy    = Out.showSDocDebug unsafeGlobalDynFlags . ppr . tidyCBs
+  | otherwise = showPpr
+
+
+findVarDef :: Symbol -> [CoreBind] -> Maybe (Var, CoreExpr)
+findVarDef x cbs = case xCbs of
+                     (NonRec v def   : _ ) -> Just (v, def)
+                     (Rec [(v, def)] : _ ) -> Just (v, def)
+                     _                     -> Nothing
+  where
+    xCbs         = [ cb | cb <- cbs, x `elem` coreBindSymbols cb ]
+
+coreBindSymbols :: CoreBind -> [Symbol]
+coreBindSymbols = map (dropModuleNames . simplesymbol) . binders
+
+simplesymbol :: (NamedThing t) => t -> Symbol
+simplesymbol = symbol . getName
+
+
+
+
+
+binders :: Bind a -> [a]
+binders (NonRec z _) = [z]
+binders (Rec xes)    = fst <$> xes
diff --git a/src/Language/Haskell/Liquid/GHC/Play.hs b/src/Language/Haskell/Liquid/GHC/Play.hs
--- a/src/Language/Haskell/Liquid/GHC/Play.hs
+++ b/src/Language/Haskell/Liquid/GHC/Play.hs
@@ -11,6 +11,9 @@
 import Var
 import TypeRep
 
+import TyCon
+import Type      (tyConAppArgs_maybe, tyConAppTyCon_maybe)
+import PrelNames (isStringClassName)
 import Coercion
 
 import           Control.Arrow       ((***))
@@ -64,6 +67,7 @@
            | otherwise    = v
  subTy s v = setVarType v (subTy s (varType v))
 
+subVar :: Expr t -> Id
 subVar (Var x) = x
 subVar  _      = panic Nothing "sub Var"
 
@@ -78,9 +82,30 @@
  sub _ e   = e
  subTy     = substTysWith
 
+substTysWith :: M.HashMap Var Type -> Type -> Type
 substTysWith s tv@(TyVarTy v)  = M.lookupDefault tv v s
 substTysWith s (FunTy t1 t2)   = FunTy (substTysWith s t1) (substTysWith s t2)
 substTysWith s (ForAllTy v t)  = ForAllTy v (substTysWith (M.delete v s) t)
 substTysWith s (TyConApp c ts) = TyConApp c (map (substTysWith s) ts)
 substTysWith s (AppTy t1 t2)   = AppTy (substTysWith s t1) (substTysWith s t2)
 substTysWith _ (LitTy t)       = LitTy t
+
+
+
+mapType :: (Type -> Type) -> Type -> Type
+mapType f = go
+  where
+    go t@(TyVarTy _)   = f t
+    go (AppTy t1 t2)   = f $ AppTy (go t1) (go t2)
+    go (TyConApp c ts) = f $ TyConApp c (go <$> ts)
+    go (FunTy t1 t2)   = f $ FunTy (go t1) (go t2)
+    go (ForAllTy v t)  = f $ ForAllTy v (go t)
+    go t@(LitTy _)     = f t
+
+
+stringClassArg :: Type -> Maybe Type
+stringClassArg t
+  = case (tyConAppTyCon_maybe t, tyConAppArgs_maybe t) of
+      (Just c, Just [t]) | isStringClassName == tyConName c
+           -> Just t
+      _    -> Nothing
diff --git a/src/Language/Haskell/Liquid/GHC/Resugar.hs b/src/Language/Haskell/Liquid/GHC/Resugar.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/GHC/Resugar.hs
@@ -0,0 +1,107 @@
+{-# LANGUAGE CPP                       #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE GADTs                     #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE RankNTypes                #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE TypeSynonymInstances      #-}
+{-# LANGUAGE UndecidableInstances      #-}
+
+-- | This module contains functions for "resugaring" low-level GHC `CoreExpr`
+--   into high-level patterns, that can receive special case handling in
+--   different phases (e.g. ANF, Constraint Generation, etc.)
+
+module Language.Haskell.Liquid.GHC.Resugar (
+  -- * High-level Source Patterns
+    Pattern (..)
+
+  -- * Lift a CoreExpr into a Pattern
+  , lift
+
+  -- * Lower a pattern back into a CoreExpr
+  , lower
+  ) where
+
+import           DataCon      (DataCon)
+import           CoreSyn
+import           Type
+import qualified MkCore
+import qualified PrelNames as PN
+import           Name         (Name, getName)
+import qualified Data.List as L
+
+-- import           Debug.Trace
+
+--------------------------------------------------------------------------------
+-- | Data type for high-level patterns -----------------------------------------
+--------------------------------------------------------------------------------
+
+data Pattern
+  = PatBind
+      { patE1  :: !CoreExpr
+      , patX   :: !Var
+      , patE2  :: !CoreExpr
+      , patM   :: !Type
+      , patDct :: !CoreExpr
+      , patTyA :: !Type
+      , patTyB :: !Type
+      , patFF  :: !Var
+      }                      -- ^ e1 >>= \x -> e2
+
+  | PatReturn                -- return @ m @ t @ $dT @ e
+     { patE    :: !CoreExpr  -- ^ e
+     , patM    :: !Type      -- ^ m
+     , patDct  :: !CoreExpr  -- ^ $dT
+     , patTy   :: !Type      -- ^ t
+     , patRet  :: !Var       -- ^ "return"
+     }
+
+  | PatProject               -- (case xe as x of C [x1,...,xn] -> xi) : ty
+    { patXE    :: !Var       -- ^ xe
+    , patX     :: !Var       -- ^ x
+    , patTy    :: !Type      -- ^ ty
+    , patCtor  :: !DataCon   -- ^ C
+    , patBinds :: ![Var]     -- ^ [x1,...,xn]
+    , patIdx   :: !Int       -- ^ i :: NatLT {len patBinds}
+    }
+
+--------------------------------------------------------------------------------
+-- | Lift expressions into High-level patterns ---------------------------------
+--------------------------------------------------------------------------------
+lift :: CoreExpr -> Maybe Pattern
+--------------------------------------------------------------------------------
+lift e = exprArgs e (collectArgs e)
+
+exprArgs :: CoreExpr -> (CoreExpr, [CoreExpr]) -> Maybe Pattern
+exprArgs _e (Var op, [Type m, d, Type a, Type b, e1, Lam x e2])
+  | op `is` PN.bindMName
+  = Just (PatBind e1 x e2 m d a b op)
+
+exprArgs _e (Var op, [Type m, d, Type t, e])
+  | op `is` PN.returnMName
+  = Just (PatReturn e m d t op)
+
+exprArgs (Case (Var xe) x t [(DataAlt c, ys, Var y)]) _
+  | Just i <- y `L.elemIndex` ys
+  = Just (PatProject xe x t c ys i)
+
+exprArgs _ _
+  = Nothing
+
+is :: Var -> Name -> Bool
+is v n = n == getName v
+
+--------------------------------------------------------------------------------
+-- | Lower patterns back into expressions --------------------------------------
+--------------------------------------------------------------------------------
+lower :: Pattern -> CoreExpr
+--------------------------------------------------------------------------------
+lower (PatBind e1 x e2 m d a b op)
+  = MkCore.mkCoreApps (Var op) [Type m, d, Type a, Type b, e1, Lam x e2]
+
+lower (PatReturn e m d t op)
+  = MkCore.mkCoreApps (Var op) [Type m, d, Type t, e]
+
+lower (PatProject xe x t c ys i)
+  = Case (Var xe) x t [(DataAlt c, ys, Var yi)] where yi = ys !! i
diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs
--- a/src/Language/Haskell/Liquid/Liquid.hs
+++ b/src/Language/Haskell/Liquid/Liquid.hs
@@ -1,6 +1,4 @@
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE NamedFieldPuns      #-}
 {-# LANGUAGE TupleSections       #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
@@ -18,81 +16,78 @@
   ) where
 
 import           Prelude hiding (error)
-import           Data.Maybe
+import           Data.Bifunctor
 import           System.Exit
-import           Control.DeepSeq
 import           Text.PrettyPrint.HughesPJ
+-- import           Var                              (Var)
 import           CoreSyn
-import           Var
 import           HscTypes                         (SourceError)
-import           System.Console.CmdArgs.Verbosity (whenLoud, whenNormal)
-import           System.Console.CmdArgs.Default
 import           GHC (HscEnv)
-
+import           System.Console.CmdArgs.Verbosity (whenLoud, whenNormal)
+import           Control.Monad (when)
 import qualified Control.Exception as Ex
-import qualified Language.Fixpoint.Types.Config as FC
+-- import qualified Language.Fixpoint.Types.Config as FC
 import qualified Language.Haskell.Liquid.UX.DiffCheck as DC
+import           Language.Haskell.Liquid.Misc
 import           Language.Fixpoint.Misc
 import           Language.Fixpoint.Solver
 import qualified Language.Fixpoint.Types as F
 import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Types.RefType (applySolution)
 import           Language.Haskell.Liquid.UX.Errors
 import           Language.Haskell.Liquid.UX.CmdLine
 import           Language.Haskell.Liquid.UX.Tidy
+import           Language.Haskell.Liquid.GHC.Misc (showCBs) -- howPpr)
 import           Language.Haskell.Liquid.GHC.Interface
 import           Language.Haskell.Liquid.Constraint.Generate
 import           Language.Haskell.Liquid.Constraint.ToFixpoint
 import           Language.Haskell.Liquid.Constraint.Types
+import           Language.Haskell.Liquid.Model
 import           Language.Haskell.Liquid.Transforms.Rec
 import           Language.Haskell.Liquid.UX.Annotate (mkOutput)
 
 type MbEnv = Maybe HscEnv
 
-------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 liquid :: [String] -> IO b
-------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 liquid args = getOpts args >>= runLiquid Nothing >>= exitWith . fst
 
-------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 -- | This fellow does the real work
-------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 runLiquid :: MbEnv -> Config -> IO (ExitCode, MbEnv)
-------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 runLiquid mE cfg = do
-  (d, mE') <- checkMany cfg mempty mE (files cfg)
-  return      (ec d, mE')
+  z <- actOrDie $ second Just <$> getGhcInfos mE cfg (files cfg)
+  case z of
+    Left e -> do
+      exitWithResult cfg (files cfg) $ mempty { o_result = e }
+      return (resultExit e, mE)
+    Right (gs, mE') -> do
+      d <- checkMany cfg mempty gs
+      return (ec d, mE')
   where
-    ec     = resultExit . o_result
-
+    ec = resultExit . o_result
 
-------------------------------------------------------------------------------
-checkMany :: Config -> Output Doc -> MbEnv -> [FilePath] -> IO (Output Doc, MbEnv)
-------------------------------------------------------------------------------
-checkMany cfg d mE (f:fs) = do
-  (d', mE') <- checkOne mE cfg f
-  checkMany cfg (d `mappend` d') mE' fs
+--------------------------------------------------------------------------------
+checkMany :: Config -> Output Doc -> [GhcInfo] -> IO (Output Doc)
+--------------------------------------------------------------------------------
+checkMany cfg d (g:gs) = do
+  d' <- checkOne cfg g
+  checkMany cfg (d `mappend` d') gs
 
-checkMany _   d mE [] =
-  return (d, mE)
+checkMany _   d [] =
+  return d
 
-------------------------------------------------------------------------------
-checkOne :: MbEnv -> Config -> FilePath -> IO (Output Doc, Maybe HscEnv)
-------------------------------------------------------------------------------
-checkOne mE cfg t = do
-  z <- actOrDie (checkOne' mE cfg t)
+--------------------------------------------------------------------------------
+checkOne :: Config -> GhcInfo -> IO (Output Doc)
+--------------------------------------------------------------------------------
+checkOne cfg g = do
+  z <- actOrDie $ liquidOne g
   case z of
-    Left e -> do
-      d <- exitWithResult cfg t $ mempty { o_result = e }
-      return (d, Nothing)
-    Right r ->
-      return r
-
-
-checkOne' :: MbEnv -> Config -> FilePath -> IO (Output Doc, Maybe HscEnv)
-checkOne' mE cfg t = do
-  (gInfo, hEnv) <- getGhcInfo mE cfg t
-  d <- liquidOne t gInfo
-  return (d, Just hEnv)
+    Left  e -> exitWithResult cfg [target g] $ mempty { o_result = e }
+    Right r -> return r
 
 
 actOrDie :: IO a -> IO (Either ErrorResult a)
@@ -106,34 +101,66 @@
 handle :: (Result a) => a -> IO (Either ErrorResult b)
 handle = return . Left . result
 
-------------------------------------------------------------------------------
-liquidOne :: FilePath -> GhcInfo -> IO (Output Doc)
-------------------------------------------------------------------------------
-liquidOne tgt info = do
+--------------------------------------------------------------------------------
+liquidOne :: GhcInfo -> IO (Output Doc)
+--------------------------------------------------------------------------------
+liquidOne info = do
   whenNormal $ donePhase Loud "Extracted Core using GHC"
-  let cfg   = config $ spec info
-  whenLoud  $ do putStrLn "**** Config **************************************************"
-                 print cfg
-  whenLoud  $ do putStrLn $ showpp info
-                 putStrLn "*************** Original CoreBinds ***************************"
-                 putStrLn $ render $ pprintCBs (cbs info)
+  let cfg   = getConfig info
+  let tgt   = target info
+  -- whenLoud  $ do putStrLn $ showpp info
+                 -- putStrLn "*************** Original CoreBinds ***************************"
+                 -- putStrLn $ render $ pprintCBs (cbs info)
   let cbs' = transformScope (cbs info)
+  whenNormal $ donePhase Loud "Transformed Core"
   whenLoud  $ do donePhase Loud "transformRecExpr"
                  putStrLn "*************** Transform Rec Expr CoreBinds *****************"
-                 putStrLn $ render $ pprintCBs cbs'
-                 putStrLn "*************** Slicing Out Unchanged CoreBinds *****************"
-  dc <- prune cfg cbs' tgt info
-  let cbs'' = maybe cbs' DC.newBinds dc
-  let info' = maybe info (\z -> info {spec = DC.newSpec z}) dc
-  let cgi   = {-# SCC "generateConstraints" #-} generateConstraints $! info' {cbs = cbs''}
-  cgi `deepseq` donePhase Loud "generateConstraints"
-  whenLoud  $ dumpCs cgi
-  out      <- solveCs cfg tgt cgi info' dc
-  whenNormal $ donePhase Loud "solve"
-  let out'  = mconcat [maybe mempty DC.oldOutput dc, out]
-  DC.saveResult tgt out'
-  exitWithResult cfg tgt out'
+                 putStrLn $ showCBs (untidyCore cfg) cbs'
+                 -- putStrLn $ render $ pprintCBs cbs'
+                 -- putStrLn $ showPpr cbs'
+  edcs <- newPrune      cfg cbs' tgt info
+  out' <- liquidQueries cfg      tgt info edcs
+  DC.saveResult       tgt  out'
+  exitWithResult cfg [tgt] out'
 
+newPrune :: Config -> [CoreBind] -> FilePath -> GhcInfo -> IO (Either [CoreBind] [DC.DiffCheck])
+newPrune cfg cbs tgt info
+  | not (null vs) = return . Right $ [DC.thin cbs sp vs]
+  | timeBinds cfg = return . Right $ [DC.thin cbs sp [v] | v <- exportedVars info ]
+  | diffcheck cfg = maybeEither cbs <$> DC.slice tgt cbs sp
+  | otherwise     = return  (Left cbs)
+  where
+    vs            = gsTgtVars sp
+    sp            = spec    info
+
+-- topLevelBinders :: GhcSpec -> [Var]
+-- topLevelBinders = map fst . tySigs
+
+maybeEither :: a -> Maybe b -> Either a [b]
+maybeEither d Nothing  = Left d
+maybeEither _ (Just x) = Right [x]
+
+liquidQueries :: Config -> FilePath -> GhcInfo -> Either [CoreBind] [DC.DiffCheck] -> IO (Output Doc)
+liquidQueries cfg tgt info (Left cbs')
+  = liquidQuery cfg tgt info (Left cbs')
+liquidQueries cfg tgt info (Right dcs)
+  = mconcat <$> mapM (liquidQuery cfg tgt info . Right) dcs
+
+liquidQuery   :: Config -> FilePath -> GhcInfo -> Either [CoreBind] DC.DiffCheck -> IO (Output Doc)
+liquidQuery cfg tgt info edc = do
+  when False (dumpCs cgi)
+  -- whenLoud $ mapM_ putStrLn [ "****************** CGInfo ********************"
+                            -- , render (pprint cgi)                            ]
+  out   <- timedAction names $ solveCs cfg tgt cgi info' names
+  return $  mconcat [oldOut, out]
+  where
+    cgi    = {-# SCC "generateConstraints" #-} generateConstraints $! info' {cbs = cbs''}
+    cbs''  = either id              DC.newBinds                        edc
+    info'  = either (const info)    (\z -> info {spec = DC.newSpec z}) edc
+    names  = either (const Nothing) (Just . map show . DC.checkedVars) edc
+    oldOut = either (const mempty)  DC.oldOutput                       edc
+
+
 dumpCs :: CGInfo -> IO ()
 dumpCs cgi = do
   putStrLn "***************************** SubCs *******************************"
@@ -144,60 +171,22 @@
   putStrLn $ render $ pprintMany (hsWfs cgi)
 
 pprintMany :: (PPrint a) => [a] -> Doc
-pprintMany xs = vcat [ pprint x $+$ text " " | x <- xs ]
-
-checkedNames ::  Maybe DC.DiffCheck -> Maybe [String]
-checkedNames dc          = concatMap names . DC.newBinds <$> dc
-   where
-     names (NonRec v _ ) = [render . text $ shvar v]
-     names (Rec xs)      = map (shvar . fst) xs
-     shvar               = showpp . varName
-
-prune :: Config -> [CoreBind] -> FilePath -> GhcInfo -> IO (Maybe DC.DiffCheck)
-prune cfg cbinds tgt info
-  | not (null vs) = return . Just $ DC.DC (DC.thin cbinds vs) mempty sp
-  | diffcheck cfg = DC.slice tgt cbinds sp
-  | otherwise     = return Nothing
-  where
-    vs            = tgtVars sp
-    sp            = spec info
-
-
-
-solveCs :: Config -> FilePath -> CGInfo -> GhcInfo -> Maybe DC.DiffCheck -> IO (Output Doc)
-solveCs cfg tgt cgi info dc
-  = do finfo        <- cgInfoFInfo info cgi tgt
-       F.Result r sol <- solve fx finfo
-       let names = checkedNames dc
-       let warns = logErrors cgi
-       let annm  = annotMap cgi
-       let res   = ferr sol r
-       let out0  = mkOutput cfg res sol annm
-       return    $ out0 { o_vars    = names             }
-                        { o_errors  = e2u sol <$> warns }
-                        { o_result  = res               }
-    where
-       fx        = def { FC.solver      = fromJust (smtsolver cfg)
-                       , FC.linear      = linear      cfg
-                       , FC.newcheck    = newcheck    cfg
-                       -- , FC.extSolver   = extSolver   cfg
-                       , FC.eliminate   = eliminate   cfg
-                       , FC.save        = saveQuery cfg
-                       , FC.srcFile     = tgt
-                       , FC.cores       = cores       cfg
-                       , FC.minPartSize = minPartSize cfg
-                       , FC.maxPartSize = maxPartSize cfg
-                       , FC.elimStats   = elimStats   cfg
-                       -- , FC.stats   = True
-                       }
-       ferr s  = fmap (cinfoUserError s . snd)
+pprintMany xs = vcat [ F.pprint x $+$ text " " | x <- xs ]
 
 
-cinfoUserError   :: F.FixSolution -> Cinfo -> UserError
-cinfoUserError s =  e2u s . cinfoError
+solveCs :: Config -> FilePath -> CGInfo -> GhcInfo -> Maybe [String] -> IO (Output Doc)
+solveCs cfg tgt cgi info names = do
+  finfo            <- cgInfoFInfo info cgi
+  F.Result r sol _ <- solve (fixConfig tgt cfg) finfo
+  let resErr        = applySolution sol . cinfoError . snd <$> r
+  resModel_        <- fmap (e2u sol) <$> getModels info cfg resErr
+  let resModel      = resModel_  `addErrors` (e2u sol <$> logErrors cgi)
+  let out0          = mkOutput cfg resModel sol (annotMap cgi)
+  return            $ out0 { o_vars    = names    }
+                           { o_result  = resModel }
 
 e2u :: F.FixSolution -> Error -> UserError
-e2u s = fmap pprint . tidyError s
+e2u s = fmap F.pprint . tidyError s
 
 -- writeCGI tgt cgi = {-# SCC "ConsWrite" #-} writeFile (extFileName Cgi tgt) str
 --   where
diff --git a/src/Language/Haskell/Liquid/Measure.hs b/src/Language/Haskell/Liquid/Measure.hs
--- a/src/Language/Haskell/Liquid/Measure.hs
+++ b/src/Language/Haskell/Liquid/Measure.hs
@@ -2,89 +2,99 @@
 {-# LANGUAGE FlexibleContexts       #-}
 {-# LANGUAGE UndecidableInstances   #-}
 {-# LANGUAGE OverloadedStrings      #-}
+{-# LANGUAGE ConstraintKinds        #-}
+{-# LANGUAGE DeriveGeneric          #-}
 
 module Language.Haskell.Liquid.Measure (
+  -- * Specifications
     Spec (..)
-  , BareSpec
   , MSpec (..)
+
+  -- * Type Aliases
+  , BareSpec
+  , BareMeasure
+  , SpecMeasure
+
+  -- * Constructors
   , mkM, mkMSpec, mkMSpec'
   , qualifySpec
   , dataConTypes
   , defRefType
-  , strLen
-  , wiredInMeasures
   ) where
 
-import Prelude hiding (error)
-import GHC hiding (Located)
-import Var
-import Type
-import TysPrim
-import TysWiredIn
-import Text.PrettyPrint.HughesPJ hiding (first)
-import Text.Printf (printf)
-import DataCon
-import Language.Haskell.Liquid.Types.Errors
-
-import qualified Data.HashMap.Strict as M
-import qualified Data.HashSet        as S
-import Data.List (foldl', partition)
-
-
-
-
-
-import Data.Maybe (fromMaybe, isNothing)
-
-import Language.Fixpoint.Misc
-import Language.Fixpoint.Types hiding (R, SrcSpan)
-import Language.Haskell.Liquid.GHC.Misc
-import Language.Haskell.Liquid.Types    hiding (GhcInfo(..), GhcSpec (..))
+import           DataCon
+import           GHC                                    hiding (Located)
+import           Outputable                             (Outputable)
+import           Prelude                                hiding (error)
+import           Text.PrettyPrint.HughesPJ              hiding (first)
+import           Text.Printf                            (printf)
+import           Type
+import           Var
+-- import           Data.Serialize                         (Serialize)
+import           Data.Binary                            as B
+import           GHC.Generics
+import qualified Data.HashMap.Strict                    as M
+import qualified Data.HashSet                           as S
+import           Data.List                              (foldl', partition)
+import           Data.Maybe                             (fromMaybe, isNothing)
 
-import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.Types.Variance
-import Language.Haskell.Liquid.Types.Bounds
-import Language.Haskell.Liquid.UX.Tidy
+import           Language.Fixpoint.Misc
+import           Language.Fixpoint.Types                hiding (R, SrcSpan)
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types          hiding (GhcInfo(..), GhcSpec (..))
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types.Variance
+import           Language.Haskell.Liquid.Types.Bounds
+import           Language.Haskell.Liquid.UX.Tidy
 
 -- MOVE TO TYPES
-type BareSpec      = Spec BareType LocSymbol
+type BareSpec      = Spec    LocBareType LocSymbol
+type BareMeasure   = Measure LocBareType LocSymbol
+type SpecMeasure   = Measure LocSpecType DataCon
 
+instance B.Binary BareSpec
+
 data Spec ty bndr  = Spec
   { measures   :: ![Measure ty bndr]            -- ^ User-defined properties for ADTs
-  , asmSigs    :: ![(LocSymbol, ty)]            -- ^ Assumed (unchecked) types
+  , asmSigs    :: ![(LocSymbol, ty)]            -- ^ Assumed (unchecked) types; including reflected signatures
   , sigs       :: ![(LocSymbol, ty)]            -- ^ Imported functions and types
   , localSigs  :: ![(LocSymbol, ty)]            -- ^ Local type signatures
-  , invariants :: ![Located ty]                 -- ^ Data type invariants
-  , ialiases   :: ![(Located ty, Located ty)]   -- ^ Data type invariants to be checked
+  , reflSigs   :: ![(LocSymbol, ty)]            -- ^ Reflected type signatures
+  , invariants :: ![ty]                         -- ^ Data type invariants
+  , ialiases   :: ![(ty, ty)]                   -- ^ Data type invariants to be checked
   , imports    :: ![Symbol]                     -- ^ Loaded spec module names
   , dataDecls  :: ![DataDecl]                   -- ^ Predicated data definitions
+  , newtyDecls :: ![DataDecl]                   -- ^ Predicated new type definitions
   , includes   :: ![FilePath]                   -- ^ Included qualifier files
   , aliases    :: ![RTAlias Symbol BareType]    -- ^ RefType aliases
   , ealiases   :: ![RTAlias Symbol Expr]        -- ^ Expression aliases
   , embeds     :: !(TCEmb LocSymbol)            -- ^ GHC-Tycon-to-fixpoint Tycon map
   , qualifiers :: ![Qualifier]                  -- ^ Qualifiers in source/spec files
-  , decr       :: ![(LocSymbol, [Int])]         -- ^ Information on decreasing arguments
-  , lvars      :: ![LocSymbol]                  -- ^ Variables that should be checked in the environment they are used
-  , lazy       :: !(S.HashSet LocSymbol)        -- ^ Ignore Termination Check in these Functions
-  , axioms     :: !(S.HashSet LocSymbol)        -- ^ Binders to turn into axiomatized functions
-  , hmeas      :: !(S.HashSet LocSymbol)        -- ^ Binders to turn into measures using haskell definitions
-  , hbounds    :: !(S.HashSet LocSymbol)        -- ^ Binders to turn into bounds using haskell definitions
-  , inlines    :: !(S.HashSet LocSymbol)        -- ^ Binders to turn into logic inline using haskell definitions
-  , autosize   :: !(S.HashSet LocSymbol)        -- ^ Type Constructors that get automatically sizing info
-  , pragmas    :: ![Located String]             -- ^ Command-line configurations passed in through source
-  , cmeasures  :: ![Measure ty ()]              -- ^ Measures attached to a type-class
-  , imeasures  :: ![Measure ty bndr]            -- ^ Mappings from (measure,type) -> measure
-  , classes    :: ![RClass ty]                  -- ^ Refined Type-Classes
-  , termexprs  :: ![(LocSymbol, [Expr])]        -- ^ Terminating Conditions for functions
+  , decr       :: ![(LocSymbol, [Int])]          -- ^ Information on decreasing arguments
+  , lvars      :: ![LocSymbol]                   -- ^ Variables that should be checked in the environment they are used
+  , lazy       :: !(S.HashSet LocSymbol)         -- ^ Ignore Termination Check in these Functions
+  -- , axioms     :: !(S.HashSet LocSymbol)         -- ^ Binders to turn into SMT axioms
+  , reflects   :: !(S.HashSet LocSymbol)         -- ^ Binders to reflect
+  , autois     :: !(M.HashMap LocSymbol (Maybe Int))  -- ^ Automatically instantiate axioms in these Functions with maybe specified fuel
+  , hmeas      :: !(S.HashSet LocSymbol)         -- ^ Binders to turn into measures using haskell definitions
+  , hbounds    :: !(S.HashSet LocSymbol)         -- ^ Binders to turn into bounds using haskell definitions
+  , inlines    :: !(S.HashSet LocSymbol)         -- ^ Binders to turn into logic inline using haskell definitions
+  , autosize   :: !(S.HashSet LocSymbol)         -- ^ Type Constructors that get automatically sizing info
+  , pragmas    :: ![Located String]              -- ^ Command-line configurations passed in through source
+  , cmeasures  :: ![Measure ty ()]               -- ^ Measures attached to a type-class
+  , imeasures  :: ![Measure ty bndr]             -- ^ Mappings from (measure,type) -> measure
+  , classes    :: ![RClass ty]                   -- ^ Refined Type-Classes
+  , termexprs  :: ![(LocSymbol, [Located Expr])] -- ^ Terminating Conditions for functions
   , rinstance  :: ![RInstance ty]
   , dvariance  :: ![(LocSymbol, [Variance])]
   , bounds     :: !(RRBEnv ty)
-  }
+  , defs       :: !(M.HashMap LocSymbol Symbol)
+  } deriving (Generic)
 
 
+qualifySpec :: Symbol -> Spec ty bndr -> Spec ty bndr
 qualifySpec name sp = sp { sigs      = [ (tx x, t)  | (x, t)  <- sigs sp]
                          , asmSigs   = [ (tx x, t)  | (x, t)  <- asmSigs sp]
---                          , termexprs = [ (tx x, es) | (x, es) <- termexprs sp]
                          }
   where
     tx = fmap (qualifySymbol name)
@@ -96,14 +106,13 @@
   | otherwise
   = panic Nothing $ "invalid measure definition for " ++ show name
 
--- mkMSpec :: [Measure ty LocSymbol] -> [Measure ty ()] -> [Measure ty LocSymbol]
---         -> MSpec ty LocSymbol
-
+mkMSpec' :: Symbolic ctor => [Measure ty ctor] -> MSpec ty ctor
 mkMSpec' ms = MSpec cm mm M.empty []
   where
     cm     = groupMap (symbol . ctor) $ concatMap eqns ms
     mm     = M.fromList [(name m, m) | m <- ms ]
 
+mkMSpec :: [Measure t LocSymbol] -> [Measure t ()] -> [Measure t LocSymbol] -> MSpec t LocSymbol
 mkMSpec ms cms ims = MSpec cm mm cmm ims
   where
     cm     = groupMap (val . ctor) $ concatMap eqns (ms'++ims)
@@ -112,17 +121,8 @@
     ms'    = checkDuplicateMeasure ms
     -- ms'    = checkFail "Duplicate Measure Definition" (distinct . fmap name) ms
 
---checkFail ::  [Char] -> (a -> Bool) -> a -> a
---checkFail msg f x
---  | f x
---  = x
---  | otherwise
---  = errorstar $ "Check-Failure: " ++ msg
 
---distinct ::  Ord a => [a] -> Bool
---distinct xs = length xs == length (sortNub xs)
-
-
+checkDuplicateMeasure :: [Measure ty ctor] -> [Measure ty ctor]
 checkDuplicateMeasure ms
   = case M.toList dups of
       []         -> ms
@@ -138,35 +138,40 @@
 -- MOVE TO TYPES
 instance Monoid (Spec ty bndr) where
   mappend s1 s2
-    = Spec { measures   =           measures s1   ++ measures s2
-           , asmSigs    =           asmSigs s1    ++ asmSigs s2
-           , sigs       =           sigs s1       ++ sigs s2
-           , localSigs  =           localSigs s1  ++ localSigs s2
+    = Spec { measures   =           measures   s1 ++ measures   s2
+           , asmSigs    =           asmSigs    s1 ++ asmSigs    s2
+           , sigs       =           sigs       s1 ++ sigs       s2
+           , localSigs  =           localSigs  s1 ++ localSigs  s2
+           , reflSigs   =           reflSigs   s1 ++ reflSigs   s2
            , invariants =           invariants s1 ++ invariants s2
-           , ialiases   =           ialiases s1   ++ ialiases s2
-           , imports    = sortNub $ imports s1    ++ imports s2
-           , dataDecls  = dataDecls s1            ++ dataDecls s2
-           , includes   = sortNub $ includes s1   ++ includes s2
-           , aliases    =           aliases s1    ++ aliases s2
-           , ealiases   =           ealiases s1   ++ ealiases s2
-           , embeds     = M.union   (embeds s1)      (embeds s2)
+           , ialiases   =           ialiases   s1 ++ ialiases   s2
+           , imports    = sortNub $ imports    s1 ++ imports    s2
+           , dataDecls  =           dataDecls  s1 ++ dataDecls  s2
+           , newtyDecls =           newtyDecls s1 ++ newtyDecls s2
+           , includes   = sortNub $ includes   s1 ++ includes   s2
+           , aliases    =           aliases    s1 ++ aliases    s2
+           , ealiases   =           ealiases   s1 ++ ealiases   s2
            , qualifiers =           qualifiers s1 ++ qualifiers s2
-           , decr       =           decr s1       ++ decr s2
-           , lvars      =           lvars s1      ++ lvars s2
-           , lazy       = S.union   (lazy s1)        (lazy s2)
-           , axioms     = S.union   (axioms s1)      (axioms s2)
-           , hmeas      = S.union   (hmeas s1)       (hmeas s2)
-           , hbounds    = S.union   (hbounds s1)     (hbounds s2)
-           , inlines    = S.union   (inlines s1)     (inlines s2)
-           , autosize   = S.union   (autosize s1)    (autosize s2)
-           , pragmas    =           pragmas s1    ++ pragmas s2
-           , cmeasures  =           cmeasures s1  ++ cmeasures s2
-           , imeasures  =           imeasures s1  ++ imeasures s2
-           , classes    =           classes s1    ++ classes s1
-           , termexprs  =           termexprs s1  ++ termexprs s2
-           , rinstance  =           rinstance s1  ++ rinstance s2
-           , dvariance  =           dvariance s1  ++ dvariance s2
-           , bounds     = M.union   (bounds s1)      (bounds s2)
+           , decr       =           decr       s1 ++ decr       s2
+           , lvars      =           lvars      s1 ++ lvars      s2
+           , pragmas    =           pragmas    s1 ++ pragmas    s2
+           , cmeasures  =           cmeasures  s1 ++ cmeasures  s2
+           , imeasures  =           imeasures  s1 ++ imeasures  s2
+           , classes    =           classes    s1 ++ classes    s2
+           , termexprs  =           termexprs  s1 ++ termexprs  s2
+           , rinstance  =           rinstance  s1 ++ rinstance  s2
+           , dvariance  =           dvariance  s1 ++ dvariance  s2
+           , embeds     = M.union   (embeds   s1)  (embeds   s2)
+           , lazy       = S.union   (lazy     s1)  (lazy     s2)
+        -- , axioms     = S.union   (axioms s1) (axioms s2)
+           , reflects   = S.union   (reflects s1)  (reflects s2)
+           , hmeas      = S.union   (hmeas    s1)  (hmeas    s2)
+           , hbounds    = S.union   (hbounds  s1)  (hbounds  s2)
+           , inlines    = S.union   (inlines  s1)  (inlines  s2)
+           , autosize   = S.union   (autosize s1)  (autosize s2)
+           , bounds     = M.union   (bounds   s1)  (bounds   s2)
+           , defs       = M.union   (defs     s1)  (defs     s2)
+           , autois     = M.union   (autois s1)      (autois s2)
            }
 
   mempty
@@ -174,10 +179,12 @@
            , asmSigs    = []
            , sigs       = []
            , localSigs  = []
+           , reflSigs   = []
            , invariants = []
            , ialiases   = []
            , imports    = []
            , dataDecls  = []
+           , newtyDecls = []
            , includes   = []
            , aliases    = []
            , ealiases   = []
@@ -186,8 +193,10 @@
            , decr       = []
            , lvars      = []
            , lazy       = S.empty
+           , autois     = M.empty
            , hmeas      = S.empty
-           , axioms     = S.empty
+           -- , axioms     = S.empty
+           , reflects   = S.empty
            , hbounds    = S.empty
            , inlines    = S.empty
            , autosize   = S.empty
@@ -199,13 +208,14 @@
            , rinstance  = []
            , dvariance  = []
            , bounds     = M.empty
+           , defs       = M.empty
            }
 
 dataConTypes :: MSpec (RRType Reft) DataCon -> ([(Var, RRType Reft)], [(LocSymbol, RRType Reft)])
 dataConTypes  s = (ctorTys, measTys)
   where
     measTys     = [(name m, sort m) | m <- M.elems (measMap s) ++ imeas s]
-    ctorTys     = concatMap makeDataConType (snd <$> (M.toList $ ctorMap s))
+    ctorTys     = concatMap makeDataConType (snd <$> M.toList (ctorMap s))
 
 
 
@@ -246,22 +256,29 @@
       = length (binds def) == length (fst $ splitFunTys $ snd $ splitForAllTys wot)
 
 
+extend :: SourcePos
+       -> RType RTyCon RTyVar Reft
+       -> RRType Reft
+       -> RType RTyCon RTyVar Reft
 extend lc t1' t2
   | Just su <- mapArgumens lc t1 t2
-  = t1 `strengthenResult` (subst su $ fromMaybe mempty (stripRTypeBase $ resultTy t2))
+  = t1 `strengthenResult` subst su (fromMaybe mempty (stripRTypeBase $ resultTy t2))
   | otherwise
   = t1
   where
     t1 = noDummySyms t1'
 
 
+resultTy :: RType c tv r -> RType c tv r
 resultTy = ty_res . toRTypeRep
 
-strengthenResult t r = fromRTypeRep $ rep{ty_res = ty_res rep `strengthen` r}
+strengthenResult :: Reftable r => RType c tv r -> r -> RType c tv r
+strengthenResult t r = fromRTypeRep $ rep {ty_res = ty_res rep `strengthen` r}
   where
-    rep = toRTypeRep t
+    rep              = toRTypeRep t
 
 
+noDummySyms :: (OkRT c tv r) => RType c tv r -> RType c tv r
 noDummySyms t
   | any isDummy (ty_binds rep)
   = subst su $ fromRTypeRep $ rep{ty_binds = xs'}
@@ -272,6 +289,8 @@
     xs' = zipWith (\_ i -> symbol ("x" ++ show i)) (ty_binds rep) [1..]
     su  = mkSubst $ zip (ty_binds rep) (EVar <$> xs')
 
+combineDCTypes :: (Foldable t, PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r)
+               => Type -> t (RType RTyCon RTyVar r) -> RType RTyCon RTyVar r
 combineDCTypes t = foldl' strengthenRefTypeGen (ofType t)
 
 mapArgumens :: SourcePos -> RRType Reft -> RRType Reft -> Maybe Subst
@@ -305,6 +324,12 @@
     (ts, tr)         = splitFunTys $ snd $ splitForAllTys tdc
 
 
+stitchArgs :: (Monoid t1, Monoid r, PPrint a)
+           => SrcSpan
+           -> a
+           -> [(t, Maybe (RType RTyCon RTyVar r))]
+           -> [Type]
+           -> [(t, RType RTyCon RTyVar r, t1)]
 stitchArgs sp dc xs ts
   | nXs == nTs         = zipWith g xs $ ofType `fmap` ts
   | otherwise          = panicFieldNumMismatch sp dc nXs nTs
@@ -330,6 +355,8 @@
     -- s  = traceShow "sort1" $ toRSort t
     -- s' = traceShow "sort2" $ toRSort (ofType t' :: RRType Reft)
 
+panicFieldNumMismatch :: (PPrint a, PPrint a1, PPrint a3)
+                      => SrcSpan -> a3 -> a1 -> a -> a2
 panicFieldNumMismatch sp dc nXs nTs = panicDataCon sp dc msg
   where
     msg = "Requires" <+> pprint nTs <+> "fields but given" <+> pprint nXs
@@ -338,9 +365,17 @@
   -- where
     -- msg = "Field type mismatch for" <+> pprint x
 
+panicDataCon :: PPrint a1 => SrcSpan -> a1 -> Doc -> a
 panicDataCon sp dc d
   = panicError $ ErrDataCon sp (pprint dc) d
 
+refineWithCtorBody :: Outputable a
+                   => a
+                   -> LocSymbol
+                   -> [Symbol]
+                   -> Body
+                   -> RType c tv Reft
+                   -> RType c tv Reft
 refineWithCtorBody dc f as body t =
   case stripRTypeBase t of
     Just (Reft (v, _)) ->
@@ -353,15 +388,3 @@
 bodyPred fv (E e)    = PAtom Eq fv e
 bodyPred fv (P p)    = PIff  fv p
 bodyPred fv (R v' p) = subst1 p (v', fv)
-
-
--- | A wired-in measure @strLen@ that describes the length of a string
--- literal, with type @Addr#@.
-strLen :: Measure SpecType ctor
-strLen = M { name = dummyLoc "strLen"
-           , sort = ofType (mkFunTy addrPrimTy intTy)
-           , eqns = []
-           }
-
-wiredInMeasures :: MSpec SpecType DataCon
-wiredInMeasures = mkMSpec' [strLen]
diff --git a/src/Language/Haskell/Liquid/Misc.hs b/src/Language/Haskell/Liquid/Misc.hs
--- a/src/Language/Haskell/Liquid/Misc.hs
+++ b/src/Language/Haskell/Liquid/Misc.hs
@@ -3,7 +3,7 @@
 module Language.Haskell.Liquid.Misc where
 
 import Prelude hiding (error)
-import Control.Monad (liftM2)
+import Control.Monad.State
 
 import Control.Arrow (first)
 import System.FilePath
@@ -13,57 +13,103 @@
 import qualified Data.HashMap.Strict   as M
 import qualified Data.List             as L
 import           Data.Maybe
+import           Data.Tuple
 import           Data.Hashable
+import           Data.Time
+import           Data.Function (on)
 import qualified Data.ByteString       as B
 import           Data.ByteString.Char8 (pack, unpack)
-import           Text.PrettyPrint.HughesPJ ((<>), char)
-
+import           Text.PrettyPrint.HughesPJ ((<>), char, Doc)
+import           Text.Printf
 import           Language.Fixpoint.Misc
 import           Paths_liquidhaskell
 
+type Nat = Int
 
+timedAction :: (Show msg) => Maybe msg -> IO a -> IO a
+timedAction label io = do
+  t0 <- getCurrentTime
+  a <- io
+  t1 <- getCurrentTime
+  let time = realToFrac (t1 `diffUTCTime` t0) :: Double
+  case label of
+    Just x  -> printf "Time (%.2fs) for action %s \n" time (show x)
+    Nothing -> return ()
+  return a
+
 (!?) :: [a] -> Int -> Maybe a
 []     !? _ = Nothing
 (x:_)  !? 0 = Just x
 (_:xs) !? n = xs !? (n-1)
 
+safeFromJust :: String -> Maybe t -> t
 safeFromJust _  (Just x) = x
 safeFromJust err _       = errorstar err
 
+fst4 :: (t, t1, t2, t3) -> t
 fst4 (a,_,_,_) = a
+
+snd4 :: (t, t1, t2, t3) -> t1
 snd4 (_,b,_,_) = b
 
+mapFourth4 :: (t -> t4) -> (t1, t2, t3, t) -> (t1, t2, t3, t4)
 mapFourth4 f (x, y, z, w) = (x, y, z, f w)
 
+addFst3 :: t -> (t1, t2) -> (t, t1, t2)
 addFst3   a (b, c) = (a, b, c)
+
+addThd3 :: t2 -> (t, t1) -> (t, t1, t2)
 addThd3   c (a, b) = (a, b, c)
+
+dropFst3 :: (t, t1, t2) -> (t1, t2)
 dropFst3 (_, x, y) = (x, y)
+
+dropThd3 :: (t1, t2, t) -> (t1, t2)
 dropThd3 (x, y, _) = (x, y)
 
+replaceN :: (Enum a, Eq a, Num a) => a -> t -> [t] -> [t]
 replaceN n y ls = [if i == n then y else x | (x, i) <- zip ls [0..]]
 
+fourth4 :: (t, t1, t2, t3) -> t3
 fourth4 (_,_,_,x) = x
+
+third4 :: (t, t1, t2, t3) -> t2
 third4  (_,_,x,_) = x
 
 mapSndM :: (Applicative m) => (b -> m c) -> (a, b) -> m (a, c)
 -- mapSndM f (x, y) = return . (x,) =<< f y
 mapSndM f (x, y) = (x, ) <$> f y
 
+firstM :: Functor f => (t -> f a) -> (t, t1) -> f (a, t1)
 firstM  f (a,b) = (,b) <$> f a
+
+secondM :: Functor f => (t -> f a) -> (t1, t) -> f (t1, a)
 secondM f (a,b) = (a,) <$> f b
 
+first3M :: Functor f => (t -> f a) -> (t, t1, t2) -> f (a, t1, t2)
 first3M  f (a,b,c) = (,b,c) <$> f a
+
+second3M :: Functor f => (t -> f a) -> (t1, t, t2) -> f (t1, a, t2)
 second3M f (a,b,c) = (a,,c) <$> f b
+
+third3M :: Functor f => (t -> f a) -> (t1, t2, t) -> f (t1, t2, a)
 third3M  f (a,b,c) = (a,b,) <$> f c
 
+third3 :: (t -> t3) -> (t1, t2, t) -> (t1, t2, t3)
 third3 f (a,b,c) = (a,b,f c)
 
+zip4 :: [t] -> [t1] -> [t2] -> [t3] -> [(t, t1, t2, t3)]
 zip4 (x1:xs1) (x2:xs2) (x3:xs3) (x4:xs4) = (x1, x2, x3, x4) : zip4 xs1 xs2 xs3 xs4
 zip4 _ _ _ _                             = []
 
 
+getIncludeDir :: IO FilePath
 getIncludeDir      = dropFileName <$> getDataFileName ("include" </> "Prelude.spec")
+
+getCssPath :: IO FilePath
 getCssPath         = getDataFileName $ "syntax" </> "liquid.css"
+
+getCoreToLogicPath :: IO FilePath
 getCoreToLogicPath = fmap (</> "CoreToLogic.lg") getIncludeDir
 
 
@@ -71,16 +117,20 @@
 {-@ type ListL a L = ListN a (len L) @-}
 
 {-@ safeZipWithError :: _ -> xs:[a] -> ListL b xs -> ListL (a,b) xs / [xs] @-}
+safeZipWithError :: String -> [t] -> [t1] -> [(t, t1)]
 safeZipWithError msg (x:xs) (y:ys) = (x,y) : safeZipWithError msg xs ys
 safeZipWithError _   []     []     = []
 safeZipWithError msg _      _      = errorstar msg
 
+safeZip3WithError :: String -> [t] -> [t1] -> [t2] -> [(t, t1, t2)]
 safeZip3WithError msg (x:xs) (y:ys) (z:zs) = (x,y,z) : safeZip3WithError msg xs ys zs
 safeZip3WithError _   []     []     []     = []
 safeZip3WithError msg _      _      _      = errorstar msg
 
+mapNs :: (Eq a, Num a, Foldable t) => t a -> (a1 -> a1) -> [a1] -> [a1]
 mapNs ns f xs = foldl (\xs n -> mapN n f xs) xs ns
 
+mapN :: (Eq a, Num a) => a -> (a1 -> a1) -> [a1] -> [a1]
 mapN 0 f (x:xs) = f x : xs
 mapN n f (x:xs) = x : mapN (n-1) f xs
 mapN _ _ []     = []
@@ -95,15 +145,20 @@
 -- Originally part of Fixpoint's Misc:
 --------------------------------------------------------------------------------
 
+single :: t -> [t]
 single x = [x]
 
-mapFst f (x, y)  = (f x, y)
-mapSnd f (x, y)  = (x, f y)
-
+mapFst3 :: (t -> t1) -> (t, t2, t3) -> (t1, t2, t3)
 mapFst3 f (x, y, z) = (f x, y, z)
+
+mapSnd3 :: (t -> t2) -> (t1, t, t3) -> (t1, t2, t3)
 mapSnd3 f (x, y, z) = (x, f y, z)
+
+mapThd3 :: (t -> t3) -> (t1, t2, t) -> (t1, t2, t3)
 mapThd3 f (x, y, z) = (x, y, f z)
 
+firstMaybes :: [Maybe a] -> Maybe a
+firstMaybes = listToMaybe . catMaybes
 
 hashMapMapWithKey   :: (k -> v1 -> v2) -> M.HashMap k v1 -> M.HashMap k v2
 hashMapMapWithKey f = fromJust . M.traverseWithKey (\k v -> Just (f k v))
@@ -111,14 +166,17 @@
 hashMapMapKeys      :: (Eq k, Hashable k) => (t -> k) -> M.HashMap t v -> M.HashMap k v
 hashMapMapKeys f    = M.fromList . fmap (first f) . M.toList
 
+concatMapM :: (Monad f, Traversable t) => (a1 -> f [a]) -> t a1 -> f [a]
 concatMapM f = fmap concat . mapM f
 
 firstElems ::  [(B.ByteString, B.ByteString)] -> B.ByteString -> Maybe (Int, B.ByteString, (B.ByteString, B.ByteString))
 firstElems seps str
   = case splitters seps str of
       [] -> Nothing
-      is -> Just $ L.minimumBy (\x y -> compare (fst3 x) (fst3 y)) is
+      is -> Just $ L.minimumBy (compare `on` fst3) is
 
+splitters :: [(B.ByteString, t)]
+          -> B.ByteString -> [(Int, t, (B.ByteString, B.ByteString))]
 splitters seps str
   = [(i, c', z) | (c, c') <- seps
                 , let z   = B.breakSubstring c str
@@ -129,11 +187,12 @@
 bchopAlts seps  = go
   where
     go  s               = maybe [s] go' (firstElems seps s)
-    go' (_,c',(s0, s1)) = if (B.length s2 == B.length s1) then [B.concat [s0,s1]] else (s0 : s2' : go s3')
+    go' (_,c',(s0, s1)) = if B.length s2 == B.length s1 then [B.concat [s0,s1]] else s0 : s2' : go s3'
                           where (s2, s3) = B.breakSubstring c' s1
                                 s2'      = B.append s2 c'
                                 s3'      = B.drop (B.length c') s3
 
+chopAlts :: [(String, String)] -> String -> [String]
 chopAlts seps str = unpack <$> bchopAlts [(pack c, pack c') | (c, c') <- seps] (pack str)
 
 sortDiff :: (Ord a) => [a] -> [a] -> [a]
@@ -146,6 +205,7 @@
     go xs []                 = xs
     go [] _                  = []
 
+angleBrackets :: Doc -> Doc
 angleBrackets p    = char '<' <> p <> char '>'
 
 mkGraph :: (Eq a, Eq b, Hashable a, Hashable b) => [(a, b)] -> M.HashMap a (S.HashSet b)
@@ -157,9 +217,15 @@
                    writeLoud ("Warning: Couldn't do " ++ s ++ ": " ++ err)
                    return ()
 
+(=>>) :: Monad m => m b -> (b -> m a) -> m b
 (=>>) m f = m >>= (\x -> f x >> return x)
 
+(<<=) :: Monad m => (b -> m a) -> m b -> m b
+(<<=) = flip (=>>)
 
+condNull :: Bool -> [a] -> [a]
+condNull c xs = if c then xs else []
+
 firstJust :: (a -> Maybe b) -> [a] -> Maybe b
 firstJust f xs = listToMaybe $ mapMaybe f xs
 
@@ -168,3 +234,10 @@
 intToString 2 = "2nd"
 intToString 3 = "3rd"
 intToString n = show n ++ "th"
+
+mapAccumM :: (Monad m, Traversable t) => (a -> b -> m (a, c)) -> a -> t b -> m (a, t c)
+mapAccumM f acc0 xs =
+  swap <$> runStateT (traverse (StateT . (\x acc -> swap <$> f acc x)) xs) acc0
+
+ifM :: (Monad m) => m Bool -> m b -> m b -> m b
+ifM b x y = b >>= \z -> if z then x else y
diff --git a/src/Language/Haskell/Liquid/Model.hs b/src/Language/Haskell/Liquid/Model.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/Model.hs
@@ -0,0 +1,485 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module Language.Haskell.Liquid.Model where
+
+import           Control.Monad
+import           Control.Monad.IO.Class
+import           Control.Monad.Reader
+import           Control.Monad.State
+import           Data.Bifunctor
+import qualified Data.HashMap.Strict                   as HM
+import           Data.List                        (partition)
+import           Data.Maybe
+import           Data.Proxy
+import           GHC.Prim
+import           System.Console.CmdArgs.Verbosity (whenLoud)
+import           Text.PrettyPrint.HughesPJ
+import           Text.Printf
+import           Unsafe.Coerce
+
+import           Language.Fixpoint.Types (FixResult(..), mapPredReft, Symbol, symbol, Expr(..),
+                                          mkSubst, subst)
+import           Language.Fixpoint.Smt.Interface
+import qualified Language.Fixpoint.Types.Config as FC
+import           Language.Haskell.Liquid.GHC.Interface
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types         hiding (var)
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.UX.Tidy
+
+import           Test.Target.Monad
+import           Test.Target.Targetable
+import           Test.Target.Testable
+
+
+import           Bag
+import           GHC hiding (obtainTermFromVal)
+import qualified Outputable as GHC
+import           DynFlags
+import           HscMain
+import           InstEnv
+import           OccName
+import           RdrName
+import           Type
+import           TysWiredIn
+import           UniqSet
+import           Var
+import           VarSet
+import           InteractiveEval
+
+import Id
+import ByteCodeGen      ( byteCodeGen )
+import Linker
+import CoreLint         ( lintInteractiveExpr )
+import Panic
+import ConLike
+import CoreSyn
+import SrcLoc
+import TcRnDriver
+import TcRnMonad
+import Desugar
+import TidyPgm
+import CorePrep
+import TyCon
+import ErrUtils
+import HscTypes
+import FastString
+import Exception
+import Util
+
+-- import           Debug.Trace
+
+getModels :: GhcInfo -> Config -> FixResult Error -> IO (FixResult Error)
+getModels info cfg fi = case fi of
+  Unsafe cs
+    | cfg `hasOpt` counterExamples
+    -> fmap Unsafe . runLiquidGhc mbenv cfg $ do
+    df <- getSessionDynFlags
+    let df' = df { packageFlags = ExposePackage (PackageArg "liquidhaskell")
+                                  (ModRenaming True [])
+                                : packageFlags df
+                 }
+    _ <- setSessionDynFlags df'
+    imps <- getContext
+    setContext ( IIModule (targetMod info)
+               : IIDecl ((simpleImportDecl (mkModuleName "Test.Target.Targetable"))
+                                           { ideclQualified = True })
+               : imps)
+    mapM (getModel info cfg) cs
+  _         -> return fi
+  where
+  mbenv = Just (env info)
+
+getModel :: GhcInfo -> Config -> Error -> Ghc Error
+getModel info cfg err
+  = getModel' info cfg err
+    `gcatch`
+    \(e :: SomeException) -> do
+      liftIO $ whenLoud $
+        printf "WARNING: could not generate counter-example: %s\n" (show e)
+      return err
+
+getModel' :: GhcInfo -> Config -> Error -> Ghc Error
+getModel' info cfg (ErrSubType { pos, msg, ctx, tact, texp }) = do
+  let vv  = (symbol "VV", tact `strengthen` (fmap (mapPredReft PNot) (rt_reft texp)))
+  let vts = vv : HM.toList ctx
+
+  let (preds, vts') = partition (isPredTy . toType . snd) vts
+
+  vtds <- addDicts (map (toType.snd) preds) vts'
+
+  hsc_env <- getSession
+  df <- getDynFlags
+  let opts = defaultOpts
+  model <- liftIO $ withContext (toFixCfg cfg) (solver opts) (target info) $ \smt -> do
+    runTarget opts (initState (target info) (spec info) smt) $ do
+      free <- gets freesyms
+      let dcs = [ (v, tidySymbol v)
+                | iv <- impVars info
+                , isDataConId iv
+                , let v = symbol iv
+                ]
+      let su  = mkSubst $ map (second EVar) (free ++ dcs)
+      n <- asks depth
+      vs <- forM vtds $ \(v, t, md) -> case md of
+        Nothing -> do
+          -- if we don't have a Targetable instance, just encode it as an Int so
+          -- the name is available
+          addVariable (v, getType (Proxy :: Proxy Int))
+          return v
+        Just (TargetDict d@Dict)  -> do
+          addVariable (v, getType (dictProxy d))
+          query (dictProxy d) n v (subst su t)
+      setup
+      _ <- liftIO $ command smt CheckSat
+      forM (zip vs vtds) $ \(sv, (v, t, md)) -> case md of
+        Nothing -> do return (v, NoModel t)
+        Just (TargetDict d@Dict) -> do
+          x <- decode sv t
+          xt <- liftIO $ obtainTermFromVal hsc_env 100 True (toType t) (x `asTypeOfDict` d)
+          return (v, WithModel (text (GHC.showPpr df xt)) t)
+
+  let (_, vv_wm) : ctx_model = model
+  return (ErrSubTypeModel
+          { pos  = pos
+          , msg  = msg
+          , ctxM  = HM.fromList ctx_model --  `HM.union` fmap NoModel ctx
+                   -- HM.union is *left-biased*
+          , tactM = case vv_wm of
+                      WithModel vv_model _ -> WithModel vv_model tact
+                      NoModel _            -> NoModel tact
+          , texp = texp
+          })
+
+getModel' _ _ err = return err
+
+
+withContext :: FC.Config -> FC.SMTSolver -> FilePath -> (Context -> IO a) -> IO a
+withContext cfg s t act = do
+  ctx <- makeContext (cfg{FC.solver = s}) t
+  act ctx `finally` cleanupContext ctx
+
+
+toFixCfg :: Config -> FC.Config
+toFixCfg cfg
+  = FC.defConfig
+     { FC.solver    = fromMaybe FC.Z3 $ smtsolver cfg
+     , FC.allowHO   = higherOrderFlag cfg
+     , FC.allowHOqs = higherorderqs   cfg
+     }
+
+dictProxy :: forall t. Dict (Targetable t) -> Proxy t
+dictProxy Dict = Proxy
+
+asTypeOfDict :: forall t. t -> Dict (Targetable t) -> t
+x `asTypeOfDict` Dict = x
+
+data Dict :: Constraint -> * where
+  Dict :: a => Dict a
+
+data TargetDict = forall t. TargetDict (Dict (Targetable t))
+
+addDicts :: [PredType] -> [(Symbol, SpecType)]
+         -> Ghc [(Symbol, SpecType, Maybe TargetDict)]
+addDicts preds bnds = mapM (addDict preds) bnds
+
+-- TODO: instead of returning Maybe (Symbol, SpecType, TargetDict),
+-- return (Symbol, SpecType, Maybe TargetDict).
+-- if Nothing, generate a binder for the value, but no skeleton / model.
+-- this way we can possibly still generate models for other values in the context
+addDict :: [PredType] -> (Symbol, SpecType)
+        -> Ghc (Symbol, SpecType, Maybe TargetDict)
+addDict preds (v, t) = addDict' preds (v, t) `gcatch`
+                       \(_e :: SomeException) -> return (v, t, Nothing)
+
+addDict' :: [PredType] -> (Symbol, SpecType)
+         -> Ghc (Symbol, SpecType, Maybe TargetDict)
+addDict' _preds (v, t)
+  | Type.isFunTy (toType t)
+  = return (v, t, Nothing)
+addDict' preds (v, t) = do
+  -- liftIO $ putStrLn $ showPpr (toType t, preds)
+  msu <- monomorphize preds (toType t)
+  -- liftIO $ putStrLn $ showPpr msu
+  case msu of
+    Nothing -> return (v, t, Nothing)
+    Just su -> do
+      let (tvs, ts) = unzip su
+      let mt = substTyWith tvs ts (toType t)
+  -- traceShowM (v, t, showPpr mt)
+      case tyConAppTyCon_maybe mt of
+        Nothing -> return (v, t, Nothing)
+        Just tc | isClassTyCon tc || isFunTyCon tc || isPrimTyCon tc
+                  || isPromotedDataCon tc || isPromotedTyCon tc
+                  -- FIXME: shouldn't be necessary..
+                  -- why do we have binders for higher-kinded types??
+                  || Type.isFunTy (Type.typeKind mt)
+                  -- TODO: cannot handle `Targetable (Fix f)`, see higher-kinded classes e.g. Eq1, Ord1, etc...
+                  || any Type.isFunTy (map Var.varType (tyConTyVars tc))
+                  -> return (v, t, Nothing)
+        Just tc -> do
+          getInfo False (getName tc) >>= \case
+            Nothing -> return (v, t, Nothing)
+            Just (ATyCon tc, _, cis, _) -> do
+              genericsMod   <- lookupModule (mkModuleName "GHC.Generics") Nothing
+              targetableMod <- lookupModule (mkModuleName "Test.Target.Targetable") Nothing
+              modelMod      <- lookupModule (mkModuleName "Language.Haskell.Liquid.Model") Nothing
+
+              let genericClsName    = mkOrig genericsMod (mkClsOcc "Generic")
+              let targetableClsName = mkOrig targetableMod (mkClsOcc "Targetable")
+              let dictTcName        = mkOrig modelMod (mkTcOcc "Dict")
+              let dictDataName      = mkOrig modelMod (mkDataOcc "Dict")
+
+              -- let mt = monomorphize (toType t)
+
+              -- liftIO $ putStrLn $ showPpr tc
+              -- maybe add a Targetable instance
+              unless ("Test.Target.Targetable.Targetable"
+                      `elem` map (showpp.is_cls_nm) cis) $ do
+
+                let tvs =  map (getRdrName) (tyConTyVars tc)
+                let tvbnds = userHsTyVarBndrs noSrcSpan tvs
+
+                -- maybe derive a Generic instance
+                unless ("GHC.Generics.Generic"
+                        `elem` map (showpp.is_cls_nm) cis) $ do
+                  let genericInst = nlHsTyConApp genericClsName
+                                   [nlHsTyConApp (getRdrName tc) (map nlHsTyVar tvs)]
+                  let instType = noLoc $ HsForAllTy Implicit Nothing
+                                 (HsQTvs [] tvbnds)
+                                 (noLoc []) -- (noLoc (map (nlHsTyConApp genericClsName . pure . nlHsTyVar) tvs))
+                                 genericInst
+                  let derivDecl = DerivD $ DerivDecl instType Nothing
+                  -- liftIO $ putStrLn $ showPpr derivDecl
+                  hsc_env <- getSession
+                  (_, ic) <- liftIO $ hscParsedDecls hsc_env [noLoc derivDecl]
+                  setSession $ hsc_env { hsc_IC = ic }
+
+                let targetInst = nlHsTyConApp targetableClsName
+                                 [nlHsTyConApp (getRdrName tc) (map nlHsTyVar tvs)]
+                let instType = noLoc $ HsForAllTy Implicit Nothing
+                               (HsQTvs [] tvbnds)
+                               -- (noLoc [])
+                               (noLoc (map (nlHsTyConApp targetableClsName . pure . nlHsTyVar) tvs))
+                               targetInst
+                let instDecl = InstD $ ClsInstD $ ClsInstDecl
+                               instType emptyBag [] [] [] Nothing
+                -- liftIO $ putStrLn $ showPpr instDecl
+                hsc_env <- getSession
+                (_, ic) <- liftIO $ hscParsedDecls hsc_env [noLoc instDecl]
+                setSession $ hsc_env { hsc_IC = ic }
+
+              hsc_env <- getSession
+
+              let targetType = nlHsTyConApp targetableClsName [toHsType mt]
+
+              let dictExpr = ExprWithTySig (nlHsVar dictDataName)
+                                           (nlHsTyConApp dictTcName [targetType])
+                                           PlaceHolder
+              let dictStmt = noLoc $ LetStmt $ HsValBinds $ ValBindsIn
+                             (listToBag [noLoc $
+                                         mkFunBind (noLoc $ mkVarUnqual $ fsLit "_compile")
+                                         [mkSimpleMatch [] (noLoc dictExpr)]])
+                             []
+              -- liftIO $ putStrLn $ showPpr dictStmt
+              x <- liftIO $ hscParsedStmt hsc_env dictStmt
+              case x of
+                Nothing -> return (v, t, Nothing)
+                Just (_, hvals_io, _) -> do
+                  [hv] <- liftIO hvals_io
+                  let d = TargetDict $ unsafeCoerce hv
+                  return (v, subts su t, Just d)
+
+            _ -> return (v, t, Nothing)
+
+type Su = [(TyVar, Type)]
+
+-- FIXME: can't instantiate higher-kinded tvs with 'Int'
+-- | Attempt to monomorphize a 'Type' according to simple defaulting rules.
+monomorphize :: [PredType] -> Type -> Ghc (Maybe Su)
+monomorphize preds t = foldM (\s tv -> monomorphizeOne preds tv s)
+                             (Just [])
+                             (varSetElemsKvsFirst $ tyVarsOfType t)
+
+monomorphizeOne :: [PredType] -> TyVar -> Maybe Su -> Ghc (Maybe Su)
+monomorphizeOne _preds _tv Nothing = return Nothing
+monomorphizeOne preds tv (Just su)
+  | null clss
+  = return (monomorphizeFree tv su)
+
+  | otherwise
+  = do insts <- concatMapM (fmap (thd4 . fromJust)
+                            . getInfo False . getName)
+                           clss
+       if any (\ClsInst {..} -> length is_tys /= 1) insts
+         -- TODO: handle multi-param (/ nullary) classes
+         then return Nothing
+         else do
+         -- liftIO $ putStrLn $ showPpr insts
+         let tcs = map (mkUniqSet . map tyConAppTyCon . is_tys) insts
+         let common_tcs = uniqSetToList $ foldr1 intersectUniqSets tcs
+         -- liftIO $ putStrLn $ showPpr common_tcs
+         case common_tcs of
+           -- hopefully doesn't happen
+           [] -> return Nothing
+
+           tc:_ -> return (Just ((tv, (mkTyConApp tc [])) : su))
+  where
+
+  clss = map (fst.getClassPredTys)
+       . filter (\p -> tv `elemVarSet` tyVarsOfType p)
+       $ preds
+
+  thd4 (_,_,c,_) = c
+
+monomorphizeFree :: TyVar -> Su -> Maybe Su
+monomorphizeFree tv su
+  | tyVarKind tv == liftedTypeKind
+    -- replace (a :: *) with Int
+  = Just ((tv, intTy) : su)
+
+  | Just (_, b) <- splitFunTy_maybe (tyVarKind tv)
+  , b == liftedTypeKind
+    -- replace (a :: * -> *) with []
+  = Just ((tv, (mkTyConApp listTyCon [])) : su)
+
+  | otherwise
+    -- TODO: higher-kinded types
+  = Nothing
+
+----------------------------------------------------------------------
+-- Slightly altered from GHC
+----------------------------------------------------------------------
+
+hscParsedStmt :: HscEnv
+              -> GhciLStmt RdrName  -- ^ The parsed statement
+              -> IO ( Maybe ([Id]
+                    , IO [HValue]
+                    , FixityEnv))
+hscParsedStmt hsc_env parsed_stmt = runInteractiveHsc hsc_env $ do
+
+  -- Rename and typecheck it
+  hsc_env <- getHscEnv
+  (ids, tc_expr, fix_env) <- ioMsgMaybe $ tcRnStmt hsc_env parsed_stmt
+
+  -- Desugar it
+  ds_expr <- ioMsgMaybe $ deSugarExpr hsc_env tc_expr
+  liftIO (lintInteractiveExpr "desugar expression" hsc_env ds_expr)
+  handleWarnings
+
+  -- Then code-gen, and link it
+  -- It's important NOT to have package 'interactive' as thisPackageKey
+  -- for linking, else we try to link 'main' and can't find it.
+  -- Whereas the linker already knows to ignore 'interactive'
+  let  src_span     = srcLocSpan interactiveSrcLoc
+  hval <- liftIO $ hscCompileCoreExpr hsc_env src_span ds_expr
+  let hval_io = unsafeCoerce# hval :: IO [HValue]
+
+  return $ Just (ids, hval_io, fix_env)
+
+handleWarnings :: Hsc ()
+handleWarnings = do
+    dflags <- getDynFlags
+    w <- getWarnings
+    liftIO $ printOrThrowWarnings dflags w
+    clearWarnings
+ioMsgMaybe :: IO (Messages, Maybe a) -> Hsc a
+ioMsgMaybe ioA = do
+    ((warns,errs), mb_r) <- liftIO ioA
+    logWarnings warns
+    case mb_r of
+        Nothing -> throwErrors errs
+        Just r  -> return r
+throwErrors :: ErrorMessages -> Hsc a
+throwErrors = liftIO . throwIO . mkSrcErr
+getWarnings :: Hsc WarningMessages
+getWarnings = Hsc $ \_ w -> return (w, w)
+clearWarnings :: Hsc ()
+clearWarnings = Hsc $ \_ _ -> return ((), emptyBag)
+logWarnings :: WarningMessages -> Hsc ()
+logWarnings w = Hsc $ \_ w0 -> return ((), w0 `unionBags` w)
+
+-- hscDeclsWithLocation :: HscEnv
+--                      -> String -- ^ The statement
+--                      -> String -- ^ The source
+--                      -> Int    -- ^ Starting line
+--                      -> IO ([TyThing], InteractiveContext)
+hscParsedDecls :: HscEnv
+               -> [LHsDecl RdrName] -> IO ([TyThing], InteractiveContext)
+hscParsedDecls hsc_env0 decls =
+ runInteractiveHsc hsc_env0 $ do
+
+    {- Rename and typecheck it -}
+    hsc_env <- getHscEnv
+    tc_gblenv <- ioMsgMaybe $ tcRnDeclsi hsc_env decls
+
+    {- Grab the new instances -}
+    -- We grab the whole environment because of the overlapping that may have
+    -- been done. See the notes at the definition of InteractiveContext
+    -- (ic_instances) for more details.
+    let defaults = tcg_default tc_gblenv
+
+    {- Desugar it -}
+    -- We use a basically null location for iNTERACTIVE
+    let iNTERACTIVELoc = ModLocation{ ml_hs_file   = Nothing,
+                                      ml_hi_file   = Panic.panic "hsDeclsWithLocation:ml_hi_file",
+                                      ml_obj_file  = Panic.panic "hsDeclsWithLocation:ml_hi_file"}
+    ds_result <- hscDesugar' iNTERACTIVELoc tc_gblenv
+
+    {- Simplify -}
+    simpl_mg <- liftIO $ hscSimplify hsc_env ds_result
+
+    {- Tidy -}
+    (tidy_cg, mod_details) <- liftIO $ tidyProgram hsc_env simpl_mg
+
+    let dflags = hsc_dflags hsc_env
+        !CgGuts{ cg_module    = this_mod,
+                 cg_binds     = core_binds,
+                 cg_tycons    = tycons,
+                 cg_modBreaks = mod_breaks } = tidy_cg
+
+        !ModDetails { md_insts     = cls_insts
+                    , md_fam_insts = fam_insts } = mod_details
+            -- Get the *tidied* cls_insts and fam_insts
+
+        data_tycons = filter isDataTyCon tycons
+
+    {- Prepare For Code Generation -}
+    -- Do saturation and convert to A-normal form
+    prepd_binds <- {-# SCC "CorePrep" #-}
+      liftIO $ corePrepPgm hsc_env iNTERACTIVELoc core_binds data_tycons
+
+    {- Generate byte code -}
+    cbc <- liftIO $ byteCodeGen dflags this_mod
+                                prepd_binds data_tycons mod_breaks
+
+    let src_span = srcLocSpan interactiveSrcLoc
+    liftIO $ linkDecls hsc_env src_span cbc
+
+    let tcs = filterOut isImplicitTyCon (mg_tcs simpl_mg)
+        patsyns = mg_patsyns simpl_mg
+
+        ext_ids = [ id | id <- bindersOfBinds core_binds
+                       , isExternalName (idName id)
+                       , not (isDFunId id || isImplicitId id) ]
+            -- We only need to keep around the external bindings
+            -- (as decided by TidyPgm), since those are the only ones
+            -- that might be referenced elsewhere.
+            -- The DFunIds are in 'cls_insts' (see Note [ic_tythings] in HscTypes
+            -- Implicit Ids are implicit in tcs
+
+        tythings =  map AnId ext_ids ++ map ATyCon tcs ++ map (AConLike . PatSynCon) patsyns
+
+    let icontext = hsc_IC hsc_env
+        ictxt    = extendInteractiveContext icontext ext_ids tcs
+                                            cls_insts fam_insts defaults patsyns
+    return (tythings, ictxt)
diff --git a/src/Language/Haskell/Liquid/Parse.hs b/src/Language/Haskell/Liquid/Parse.hs
--- a/src/Language/Haskell/Liquid/Parse.hs
+++ b/src/Language/Haskell/Liquid/Parse.hs
@@ -5,952 +5,1413 @@
 {-# LANGUAGE TypeSynonymInstances      #-}
 {-# LANGUAGE TupleSections             #-}
 {-# LANGUAGE OverloadedStrings         #-}
-
-module Language.Haskell.Liquid.Parse
-  ( hsSpecificationP, lhsSpecificationP, specSpecificationP
-  , parseSymbolToLogic
-  )
-  where
-
-import Prelude hiding (error)
-import Control.Monad
-import Text.Parsec
-import Text.Parsec.Error (newErrorMessage, Message (..))
-import Text.Parsec.Pos   (newPos)
-
-import qualified Text.Parsec.Token   as Token
-import qualified Data.Text           as T
-import qualified Data.HashMap.Strict as M
-import qualified Data.HashSet        as S
-import Data.Monoid
-
-
-import Data.Char (isSpace, isAlpha, isUpper, isAlphaNum)
-import Data.List (foldl', partition)
-
-import GHC (mkModuleName)
-import Text.PrettyPrint.HughesPJ    (text)
-
-import Language.Preprocessor.Unlit (unlit)
-
-import Language.Fixpoint.Types hiding (Error, R)
-
-import Language.Haskell.Liquid.GHC.Misc
-import Language.Haskell.Liquid.Types hiding (Axiom)
-import Language.Haskell.Liquid.Misc (mapSnd)
-import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.Types.Variance
-import Language.Haskell.Liquid.Types.Bounds
-
-import qualified Language.Haskell.Liquid.Measure as Measure
-
-import Language.Fixpoint.Parse hiding (angles, refBindP, refP, refDefP)
-
--- import Debug.Trace
-
-----------------------------------------------------------------------------
--- Top Level Parsing API ---------------------------------------------------
-----------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-hsSpecificationP :: SourceName -> String -> Either Error (ModName, Measure.BareSpec)
--------------------------------------------------------------------------------
-
-hsSpecificationP = parseWithError $ do
-    name <-  try (lookAhead $ skipMany (commentP >> spaces)
-                           >> reserved "module" >> symbolP)
-         <|> return "Main"
-    liftM (mkSpec (ModName SrcImport $ mkModuleName $ symbolString name)) $ specWraps specP
-
--------------------------------------------------------------------------------
-lhsSpecificationP :: SourceName -> String -> Either Error (ModName, Measure.BareSpec)
--------------------------------------------------------------------------------
-
-lhsSpecificationP sn s = hsSpecificationP sn $ unlit sn s
-
-commentP =  simpleComment (string "{-") (string "-}")
-        <|> simpleComment (string "--") newlineP
-        <|> simpleComment (string "\\") newlineP
-        <|> simpleComment (string "#")  newlineP
-
-simpleComment open close = open >> manyTill anyChar (try close)
-
-newlineP = try (string "\r\n") <|> string "\n" <|> string "\r"
-
-
--- | Used to parse .spec files
-
---------------------------------------------------------------------------
-specSpecificationP  :: SourceName -> String -> Either Error (ModName, Measure.BareSpec)
---------------------------------------------------------------------------
-specSpecificationP  = parseWithError specificationP
-
-specificationP :: Parser (ModName, Measure.BareSpec)
-specificationP
-  = do reserved "module"
-       reserved "spec"
-       name   <- symbolP
-       reserved "where"
-       xs     <- grabs (specP <* whiteSpace)
-       return $ mkSpec (ModName SpecImport $ mkModuleName $ symbolString name) xs
-
----------------------------------------------------------------------------
-parseWithError :: Parser a -> SourceName -> String -> Either Error a
----------------------------------------------------------------------------
-parseWithError parser f s
-  = case runParser (remainderP (whiteSpace >> parser)) 0 f s of
-      Left e            -> Left  $ parseErrorError f e
-      Right (r, "", _)  -> Right r
-      Right (_, rem, _) -> Left  $ parseErrorError f $ remParseError f s rem
-
----------------------------------------------------------------------------
-parseErrorError     :: SourceName -> ParseError -> Error
----------------------------------------------------------------------------
-parseErrorError f e = ErrParse sp msg e
-  where
-    pos             = errorPos e
-    sp              = sourcePosSrcSpan pos
-    msg             = text $ "Error Parsing Specification from: " ++ f
-
----------------------------------------------------------------------------
-remParseError       :: SourceName -> String -> String -> ParseError
----------------------------------------------------------------------------
-remParseError f s r = newErrorMessage msg $ newPos f line col
-  where
-    msg             = Message "Leftover while parsing"
-    (line, col)     = remLineCol s r
-
-remLineCol          :: String -> String -> (Int, Int)
-remLineCol src rem = (line, col)
-  where
-    line           = 1 + srcLine - remLine
-    srcLine        = length srcLines
-    remLine        = length remLines
-    col            = srcCol - remCol
-    srcCol         = length $ srcLines !! (line - 1)
-    remCol         = length $ head remLines
-    srcLines       = lines  src
-    remLines       = lines  rem
-
-
-
-
-
-----------------------------------------------------------------------------------
--- Parse to Logic  ---------------------------------------------------------------
-----------------------------------------------------------------------------------
-
-parseSymbolToLogic = parseWithError toLogicP
-
-toLogicP
-  = toLogicMap <$> many toLogicOneP
-
-toLogicOneP
-  = do reserved "define"
-       (x:xs) <- many1 symbolP
-       reserved "="
-       e      <- exprP
-       return (x, xs, e)
-
-
-----------------------------------------------------------------------------------
--- Lexer Tokens ------------------------------------------------------------------
-----------------------------------------------------------------------------------
-
-dot           = Token.dot           lexer
-angles        = Token.angles        lexer
-stringLiteral = Token.stringLiteral lexer
-
-----------------------------------------------------------------------------------
--- BareTypes ---------------------------------------------------------------------
-----------------------------------------------------------------------------------
-
--- | The top-level parser for "bare" refinement types. If refinements are
--- not supplied, then the default "top" refinement is used.
-
-bareTypeP :: Parser BareType
-
-bareTypeP
-  =  try bareAllP
- <|> bareAllS
---  <|> bareAllExprP
---  <|> bareExistsP
- <|> try bareConstraintP
- <|> try bareFunP
- <|> bareAtomP (refBindP bindP)
- <|> try (angles (do t <- parens bareTypeP
-                     p <- monoPredicateP
-                     return $ t `strengthen` MkUReft mempty p mempty))
-
-bareArgP vv
-  =  bareAtomP (refDefP vv)
- <|> parens bareTypeP
-
-bareAtomP ref
-  =  ref refasHoleP bbaseP
- <|> holeP
- <|> try (dummyP (bbaseP <* spaces))
-
-refBindP :: Subable a => Parser Symbol -> Parser Expr -> Parser (Reft -> a) -> Parser a
-refBindP bp rp kindP
-  = braces $ do
-      x  <- bp
-      i  <- freshIntP
-      t  <- kindP
-      reserved "|"
-      ra <- rp <* spaces
-      let xi = intSymbol x i
-      let su v = if v == x then xi else v
-      return $ substa su $ t (Reft (x, ra))
-
-refP       = refBindP bindP refaP
-refDefP x  = refBindP (optBindP x)
-
-optBindP x = try bindP <|> return x
-
-holeP       = reserved "_" >> spaces >> return (RHole $ uTop $ Reft ("VV", hole))
-holeRefP    = reserved "_" >> spaces >> return (RHole . uTop)
-refasHoleP  = try refaP
-           <|> (reserved "_" >> return hole)
-
--- FIXME: the use of `blanks = oneOf " \t"` here is a terrible and fragile hack
--- to avoid parsing:
---
---   foo :: a -> b
---   bar :: a
---
--- as `foo :: a -> b bar`..
-bbaseP :: Parser (Reft -> BareType)
-bbaseP
-  =  holeRefP
- <|> liftM2 bLst (brackets (maybeP bareTypeP)) predicatesP
- <|> liftM2 bTup (parens $ sepBy bareTypeP comma) predicatesP
- <|> try (liftM2 bAppTy lowerIdP (sepBy1 bareTyArgP blanks))
- <|> try (liftM3 bRVar lowerIdP stratumP monoPredicateP)
- <|> liftM5 bCon locUpperIdP stratumP predicatesP (sepBy bareTyArgP blanks) mmonoPredicateP
-
-stratumP :: Parser Strata
-stratumP
-  = do reserved "^"
-       bstratumP
- <|> return mempty
-
-bstratumP
-  = ((:[]) . SVar) <$> symbolP
-
-bbaseNoAppP :: Parser (Reft -> BareType)
-bbaseNoAppP
-  =  holeRefP
- <|> liftM2 bLst (brackets (maybeP bareTypeP)) predicatesP
- <|> liftM2 bTup (parens $ sepBy bareTypeP comma) predicatesP
- <|> try (liftM5 bCon locUpperIdP stratumP predicatesP (return []) (return mempty))
- <|> liftM3 bRVar lowerIdP stratumP monoPredicateP
-
-maybeP p = liftM Just p <|> return Nothing
-
-bareTyArgP
-  =  -- try (RExprArg . expr <$> binderP) <|>
-     try (RExprArg . fmap expr <$> locParserP integer)
- <|> try (braces $ RExprArg <$> locParserP exprP)
- <|> try bareAtomNoAppP
- <|> try (parens bareTypeP)
-
-bareAtomNoAppP
-  =  refP bbaseNoAppP
- <|> try (dummyP (bbaseNoAppP <* spaces))
-
-bareConstraintP
-  = do ct   <- braces constraintP
-       t    <- bareTypeP
-       return $ rrTy ct t
-
-
-constraintP
-  = do xts <- constraintEnvP
-       t1 <- bareTypeP
-       reserved "<:"
-       t2 <- bareTypeP
-       return $ fromRTypeRep $ RTypeRep [] [] [] ((val . fst <$> xts) ++ [dummySymbol]) (replicate (length xts + 1) mempty) ((snd <$> xts) ++ [t1]) t2
-
-
-constraintEnvP
-   =  try (do xts <- sepBy tyBindP comma
-              reserved "|-"
-              return xts)
-  <|> return []
-
-rrTy ct = RRTy (xts ++ [(dummySymbol, tr)]) mempty OCons
-  where
-    tr   = ty_res trep
-    xts  = zip (ty_binds trep) (ty_args trep)
-    trep = toRTypeRep ct
-
-bareAllS
-  = do reserved "forall"
-       ss <- angles $ sepBy1 symbolP comma
-       dot
-       t  <- bareTypeP
-       return $ foldr RAllS t ss
-
-bareAllP
-  = do reserved "forall"
-       as <- many tyVarIdP
-       ps <- predVarDefsP
-       dot
-       t  <- bareTypeP
-       return $ foldr RAllT (foldr RAllP t ps) as
-
-tyVarIdP :: Parser Symbol
-tyVarIdP = symbol <$> condIdP alphanums (isSmall . head)
-           where
-             alphanums = S.fromList $ ['a'..'z'] ++ ['0'..'9']
-
-predVarDefsP
-  =  try (angles $ sepBy1 predVarDefP comma)
- <|> return []
-
-predVarDefP
-  = bPVar <$> predVarIdP <*> dcolon <*> predVarTypeP
-
-predVarIdP
-  = symbol <$> tyVarIdP
-
-bPVar p _ xts  = PV p (PVProp τ) dummySymbol τxs
-  where
-    (_, τ) = safeLast "bPVar last" xts
-    τxs    = [ (τ, x, EVar x) | (x, τ) <- init xts ]
-    safeLast _ xs@(_:_) = last xs
-    safeLast msg _      = panic Nothing $ "safeLast with empty list " ++ msg
-
-predVarTypeP :: Parser [(Symbol, BSort)]
-predVarTypeP = bareTypeP >>= either parserFail return . mkPredVarType
-
-mkPredVarType t
-  | isOk      = Right $ zip xs ts
-  | otherwise = Left err
-  where
-    isOk      = isPropBareType tOut || isHPropBareType tOut
-    tOut      = ty_res trep
-    trep      = toRTypeRep t
-    xs        = ty_binds trep
-    ts        = toRSort <$> ty_args trep
-    err       = "Predicate Variable with non-Prop output sort: " ++ showpp t
-
-xyP lP sepP rP
-  = (\x _ y -> (x, y)) <$> lP <*> (spaces >> sepP) <*> rP
-
-data ArrowSym = ArrowFun | ArrowPred
-
-arrowP
-  =   (reserved "->" >> return ArrowFun)
-  <|> (reserved "=>" >> return ArrowPred)
-
-bareFunP
-  = do b  <- try bindP <|> dummyBindP
-       t1 <- bareArgP b
-       a  <- arrowP
-       t2 <- bareTypeP
-       return $ bareArrow b t1 a t2
-
-dummyBindP = tempSymbol "db" <$> freshIntP
-
-bbindP     = lowerIdP <* dcolon
-
-bareArrow b t1 ArrowFun t2
-  = rFun b t1 t2
-bareArrow _ t1 ArrowPred t2
-  = foldr (rFun dummySymbol) t2 (getClasses t1)
-
-
-isPropBareType  = isPrimBareType propConName
-isHPropBareType = isPrimBareType hpropConName
-isPrimBareType n (RApp tc [] _ _) = val tc == n
-isPrimBareType _ _                = False
-
-
-
-getClasses t@(RApp tc ts _ _)
-  | isTuple tc
-  = ts
-  | otherwise
-  = [t]
-getClasses t
-  = [t]
-
-dummyP ::  Monad m => m (Reft -> b) -> m b
-dummyP fm
-  = fm `ap` return dummyReft
-
-symsP
-  = do reserved "\\"
-       ss <- sepBy symbolP spaces
-       reserved "->"
-       return $ (, dummyRSort) <$> ss
- <|> return []
-
-dummyRSort
-  = RVar "dummy" mempty
-
-predicatesP
-   =  try (angles $ sepBy1 predicate1P comma)
-  <|> return []
-
-predicate1P
-   =  try (RProp <$> symsP <*> refP bbaseP)
-  <|> (rPropP [] . predUReft <$> monoPredicate1P)
-  <|> (braces $ bRProp <$> symsP' <*> refaP)
-   where
-    symsP'       = do ss    <- symsP
-                      fs    <- mapM refreshSym (fst <$> ss)
-                      return $ zip ss fs
-    refreshSym s = intSymbol s <$> freshIntP
-
-mmonoPredicateP
-   = try (angles $ angles monoPredicate1P)
-  <|> return mempty
-
-monoPredicateP
-   = try (angles monoPredicate1P)
-  <|> return mempty
-
-monoPredicate1P
-   =  try (reserved "True" >> return mempty)
-  <|> try (pdVar <$> parens predVarUseP)
-  <|> (pdVar <$> predVarUseP)
-
-predVarUseP
-  = do (p, xs) <- funArgsP
-       return   $ PV p (PVProp dummyTyId) dummySymbol [ (dummyTyId, dummySymbol, x) | x <- xs ]
-
-funArgsP  = try realP <|> empP
-  where
-    empP  = (,[]) <$> predVarIdP
-    realP = do (EVar lp, xs) <- splitEApp <$> funAppP
-               return (lp, xs)
-
-
-
-boundP = do
-  name   <- locParserP upperIdP
-  reservedOp "="
-  vs     <- bvsP
-  params <- many (parens tyBindP)
-  args   <- bargsP
-  body   <- predP
-  return $ Bound name vs params args body
- where
-    bargsP = try ( do reservedOp "\\"
-                      xs <- many (parens tyBindP)
-                      reservedOp  "->"
-                      return xs
-                 )
-           <|> return []
-    bvsP   = try ( do reserved "forall"
-                      xs <- many symbolP
-                      reserved  "."
-                      return ((`RVar` mempty) <$> xs)
-                 )
-           <|> return []
-
-------------------------------------------------------------------------
------------------------ Wrapped Constructors ---------------------------
-------------------------------------------------------------------------
-
-bRProp []    _    = panic Nothing "Parse.bRProp empty list"
-bRProp syms' expr = RProp ss $ bRVar dummyName mempty mempty r
-  where
-    (ss, (v, _))  = (init syms, last syms)
-    syms          = [(y, s) | ((_, s), y) <- syms']
-    su            = mkSubst [(x, EVar y) | ((x, _), y) <- syms']
-    r             = su `subst` Reft (v, expr)
-
-bRVar α s p r             = RVar α (MkUReft r p s)
-bLst (Just t) rs r        = RApp (dummyLoc listConName) [t] rs (reftUReft r)
-bLst (Nothing) rs r       = RApp (dummyLoc listConName) []  rs (reftUReft r)
-
-bTup [t] _ r | isTauto r  = t
-             | otherwise  = t `strengthen` (reftUReft r)
-bTup ts rs r              = RApp (dummyLoc tupConName) ts rs (reftUReft r)
-
-
--- Temporarily restore this hack benchmarks/esop2013-submission/Array.hs fails
--- w/o it
--- TODO RApp Int [] [p] true should be syntactically different than RApp Int [] [] p
--- bCon b s [RProp _ (RHole r1)] [] _ r = RApp b [] [] $ r1 `meet` (MkUReft r mempty s)
-bCon b s rs            ts p r = RApp b ts rs $ MkUReft r p s
-
-bAppTy v ts r  = ts' `strengthen` reftUReft r
-  where
-    ts'        = foldl' (\a b -> RAppTy a b mempty) (RVar v mempty) ts
-
-reftUReft r    = MkUReft r mempty mempty
-
-predUReft p    = MkUReft dummyReft p mempty
-
-dummyReft      = mempty
-
-dummyTyId      = ""
-
-------------------------------------------------------------------
---------------------------- Measures -----------------------------
-------------------------------------------------------------------
-
-data Pspec ty ctor
-  = Meas    (Measure ty ctor)
-  | Assm    (LocSymbol, ty)
-  | Asrt    (LocSymbol, ty)
-  | LAsrt   (LocSymbol, ty)
-  | Asrts   ([LocSymbol], (ty, Maybe [Expr]))
-  | Impt    Symbol
-  | DDecl   DataDecl
-  | Incl    FilePath
-  | Invt    (Located ty)
-  | IAlias  (Located ty, Located ty)
-  | Alias   (RTAlias Symbol BareType)
-  | EAlias  (RTAlias Symbol Expr)
-  | Embed   (LocSymbol, FTycon)
-  | Qualif  Qualifier
-  | Decr    (LocSymbol, [Int])
-  | LVars   LocSymbol
-  | Lazy    LocSymbol
-  | HMeas   LocSymbol
-  | Axiom   LocSymbol
-  | Inline  LocSymbol
-  | ASize   LocSymbol
-  | HBound  LocSymbol
-  | PBound  (Bound ty Expr)
-  | Pragma  (Located String)
-  | CMeas   (Measure ty ())
-  | IMeas   (Measure ty ctor)
-  | Class   (RClass ty)
-  | RInst   (RInstance ty)
-  | Varia   (LocSymbol, [Variance])
-
--- | For debugging
-instance Show (Pspec a b) where
-  show (Meas   _) = "Meas"
-  show (Assm   _) = "Assm"
-  show (Asrt   _) = "Asrt"
-  show (LAsrt  _) = "LAsrt"
-  show (Asrts  _) = "Asrts"
-  show (Impt   _) = "Impt"
-  show (DDecl  _) = "DDecl"
-  show (Incl   _) = "Incl"
-  show (Invt   _) = "Invt"
-  show (IAlias _) = "IAlias"
-  show (Alias  _) = "Alias"
-  show (EAlias _) = "EAlias"
-  show (Embed  _) = "Embed"
-  show (Qualif _) = "Qualif"
-  show (Decr   _) = "Decr"
-  show (LVars  _) = "LVars"
-  show (Lazy   _) = "Lazy"
-  show (Axiom  _) = "Axiom"
-  show (HMeas  _) = "HMeas"
-  show (HBound _) = "HBound"
-  show (Inline _) = "Inline"
-  show (Pragma _) = "Pragma"
-  show (CMeas  _) = "CMeas"
-  show (IMeas  _) = "IMeas"
-  show (Class  _) = "Class"
-  show (Varia  _) = "Varia"
-  show (PBound _) = "Bound"
-  show (RInst  _) = "RInst"
-  show (ASize  _) = "ASize"
-
-
-mkSpec name xs         = (name,)
-                       $ Measure.qualifySpec (symbol name)
-                       $ Measure.Spec
-  { Measure.measures   = [m | Meas   m <- xs]
-  , Measure.asmSigs    = [a | Assm   a <- xs]
-  , Measure.sigs       = [a | Asrt   a <- xs]
-                      ++ [(y, t) | Asrts (ys, (t, _)) <- xs, y <- ys]
-  , Measure.localSigs  = []
-  , Measure.invariants = [t | Invt   t <- xs]
-  , Measure.ialiases   = [t | IAlias t <- xs]
-  , Measure.imports    = [i | Impt   i <- xs]
-  , Measure.dataDecls  = [d | DDecl  d <- xs]
-  , Measure.includes   = [q | Incl   q <- xs]
-  , Measure.aliases    = [a | Alias  a <- xs]
-  , Measure.ealiases   = [e | EAlias e <- xs]
-  , Measure.embeds     = M.fromList [e | Embed e <- xs]
-  , Measure.qualifiers = [q | Qualif q <- xs]
-  , Measure.decr       = [d | Decr d   <- xs]
-  , Measure.lvars      = [d | LVars d  <- xs]
-  , Measure.lazy       = S.fromList [s | Lazy   s <- xs]
-  , Measure.axioms     = S.fromList [s | Axiom  s <- xs]
-  , Measure.hmeas      = S.fromList [s | HMeas  s <- xs]
-  , Measure.inlines    = S.fromList [s | Inline s <- xs]
-  , Measure.autosize   = S.fromList [s | ASize  s <- xs]
-  , Measure.hbounds    = S.fromList [s | HBound s <- xs]
-  , Measure.pragmas    = [s | Pragma s <- xs]
-  , Measure.cmeasures  = [m | CMeas  m <- xs]
-  , Measure.imeasures  = [m | IMeas  m <- xs]
-  , Measure.classes    = [c | Class  c <- xs]
-  , Measure.dvariance  = [v | Varia  v <- xs]
-  , Measure.rinstance  = [i | RInst  i <- xs]
-  , Measure.bounds     = M.fromList [(bname i, i) | PBound i <- xs]
-  , Measure.termexprs  = [(y, es) | Asrts (ys, (_, Just es)) <- xs, y <- ys]
-  }
-
-specP :: Parser (Pspec BareType LocSymbol)
-specP
-  = try (reservedToken "assume"    >> liftM Assm   tyBindP   )
-    <|> (reservedToken "assert"    >> liftM Asrt   tyBindP   )
-    <|> (reservedToken "autosize"  >> liftM ASize  asizeP    )
-    <|> (reservedToken "Local"     >> liftM LAsrt  tyBindP   )
-    <|> (reservedToken "axiomatize" >> liftM Axiom  axiomP )
-    <|> try (reservedToken "measure"  >> liftM Meas   measureP  )
-    <|> (reservedToken "measure"   >> liftM HMeas  hmeasureP )
-    <|> (reservedToken "inline"   >> liftM Inline  inlineP )
-    <|> try (reservedToken "bound" >> liftM PBound  boundP)
-    <|> (reservedToken "bound"    >> liftM HBound  hboundP)
-    <|> try (reservedToken "class"    >> reserved "measure" >> liftM CMeas cMeasureP)
-    <|> try (reservedToken "instance" >> reserved "measure" >> liftM IMeas iMeasureP)
-    <|> (reservedToken "instance"  >> liftM RInst  instanceP )
-    <|> (reservedToken "class"     >> liftM Class  classP    )
-    <|> (reservedToken "import"    >> liftM Impt   symbolP   )
-    <|> try (reservedToken "data" >> reserved "variance " >> liftM Varia datavarianceP)
-    <|> (reservedToken "data"      >> liftM DDecl  dataDeclP )
-    <|> (reservedToken "include"   >> liftM Incl   filePathP )
-    <|> (reservedToken "invariant" >> liftM Invt   invariantP)
-    <|> (reservedToken "using"     >> liftM IAlias invaliasP )
-    <|> (reservedToken "type"      >> liftM Alias  aliasP    )
-    <|> (reservedToken "predicate" >> liftM EAlias ealiasP   )
-    <|> (reservedToken "expression">> liftM EAlias ealiasP   )
-    <|> (reservedToken "embed"     >> liftM Embed  embedP    )
-    <|> (reservedToken "qualif"    >> liftM Qualif (qualifierP sortP))
-    <|> (reservedToken "Decrease"  >> liftM Decr   decreaseP )
-    <|> (reservedToken "LAZYVAR"   >> liftM LVars  lazyVarP  )
-    <|> (reservedToken "Strict"    >> liftM Lazy   lazyVarP  )
-    <|> (reservedToken "Lazy"      >> liftM Lazy   lazyVarP  )
-    <|> (reservedToken "LIQUID"    >> liftM Pragma pragmaP   )
-    <|> ({- DEFAULT -}           liftM Asrts  tyBindsP  )
-
-reservedToken str = try(string str >> spaces1)
-
-spaces1 = satisfy isSpace >> spaces
-
-pragmaP :: Parser (Located String)
-pragmaP = locParserP stringLiteral
-
-lazyVarP :: Parser LocSymbol
-lazyVarP = locParserP binderP
-
-hmeasureP :: Parser LocSymbol
-hmeasureP = locParserP binderP
-
-axiomP :: Parser LocSymbol
-axiomP = locParserP binderP
-
-hboundP :: Parser LocSymbol
-hboundP = locParserP binderP
-
-inlineP :: Parser LocSymbol
-inlineP = locParserP binderP
-
-asizeP :: Parser LocSymbol
-asizeP = locParserP binderP
-
-decreaseP :: Parser (LocSymbol, [Int])
-decreaseP = mapSnd f <$> liftM2 (,) (locParserP binderP) (spaces >> (many integer))
-  where
-    f     = ((\n -> fromInteger n - 1) <$>)
-
-filePathP     :: Parser FilePath
-filePathP     = angles $ many1 pathCharP
-  where
-    pathCharP = choice $ char <$> pathChars
-    pathChars = ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ['.', '/']
-
-datavarianceP = liftM2 (,) locUpperIdP (spaces >> many varianceP)
-
-varianceP = (reserved "bivariant"     >> return Bivariant)
-        <|> (reserved "invariant"     >> return Invariant)
-        <|> (reserved "covariant"     >> return Covariant)
-        <|> (reserved "contravariant" >> return Contravariant)
-        <?> "Invalib variance annotation\t Use one of bivariant, invariant, covariant, contravariant"
-
-tyBindsP    :: Parser ([LocSymbol], (BareType, Maybe [Expr]))
-tyBindsP = xyP (sepBy (locParserP binderP) comma) dcolon termBareTypeP
-
-tyBindP    :: Parser (LocSymbol, BareType)
-tyBindP    = xyP (locParserP binderP) dcolon genBareTypeP
-
-termBareTypeP :: Parser (BareType, Maybe [Expr])
-termBareTypeP
-   = try termTypeP
-  <|> (, Nothing) <$> genBareTypeP
-
-termTypeP
-  = do t <- genBareTypeP
-       reserved "/"
-       es <- brackets $ sepBy exprP comma
-       return (t, Just es)
-
-invariantP   = locParserP genBareTypeP
-
-invaliasP
-  = do t  <- locParserP genBareTypeP
-       reserved "as"
-       ta <- locParserP genBareTypeP
-       return (t, ta)
-
-genBareTypeP
-  = bareTypeP
-
-embedP
-  = xyP locUpperIdP (reserved "as") fTyConP
-
-
-aliasP  = rtAliasP id     bareTypeP
-ealiasP = try (rtAliasP symbol predP)
-      <|> rtAliasP symbol exprP
-
-rtAliasP :: (Symbol -> tv) -> Parser ty -> Parser (RTAlias tv ty)
-rtAliasP f bodyP
-  = do pos  <- getPosition
-       name <- upperIdP
-       spaces
-       args <- sepBy aliasIdP blanks
-       whiteSpace >> reservedOp "=" >> whiteSpace
-       body <- bodyP
-       posE <- getPosition
-       let (tArgs, vArgs) = partition (isSmall . headSym) args
-       return $ RTA name (f <$> tArgs) (f <$> vArgs) body pos posE
-
-aliasIdP :: Parser Symbol
-aliasIdP = condIdP alphaNums (isAlpha . head)
-           where
-             alphaNums = S.fromList $ ['A' .. 'Z'] ++ ['a'..'z'] ++ ['0'..'9']
-
-measureP :: Parser (Measure BareType LocSymbol)
-measureP
-  = do (x, ty) <- tyBindP
-       whiteSpace
-       eqns    <- grabs $ measureDefP $ (rawBodyP <|> tyBodyP ty)
-       return   $ Measure.mkM x ty eqns
-
-cMeasureP :: Parser (Measure BareType ())
-cMeasureP
-  = do (x, ty) <- tyBindP
-       return $ Measure.mkM x ty []
-
-iMeasureP :: Parser (Measure BareType LocSymbol)
-iMeasureP = measureP
-
-instanceP
-  = do c  <- locUpperIdP
-       t  <- locUpperIdP
-       as <- classParams
-       ts <- sepBy tyBindP semi
-       return $ RI c (RApp t ((`RVar` mempty) <$> as) [] mempty) ts
-  where
-    classParams
-       =  (reserved "where" >> return [])
-      <|> (liftM2 (:) lowerIdP classParams)
-
-classP :: Parser (RClass BareType)
-classP
-  = do sups <- supersP
-       c <- locUpperIdP
-       spaces
-       tvs <- manyTill tyVarIdP (try $ reserved "where")
-       ms <- grabs tyBindP
-       spaces
-       return $ RClass (fmap symbol c) sups tvs ms
-  where
-    superP =  toRCls <$> bareAtomP (refBindP bindP)
-      -- c <- locUpperIdP
-      -- spaces
-      -- tvs <- many1 bareAtomNoAppP
-      -- return (RApp c tvs [] mempty)
-
-    supersP = try (((parens (superP `sepBy1` comma)) <|> fmap pure superP)
-                      <* reserved "=>")
-              <|> return []
-    toRCls x = x
---     toRCls (RApp c ts rs r) = RCls c ts
---     toRCls t@(RCls _ _)     = t
---     toRCls t                = errorstar $ "Parse.toRCls called with" ++ show t
-
-rawBodyP
-  = braces $ do
-      v <- symbolP
-      reserved "|"
-      p <- predP <* spaces
-      return $ R v p
-
-tyBodyP :: BareType -> Parser Body
-tyBodyP ty
-  = case outTy ty of
-      Just bt | isPropBareType bt
-                -> P <$> predP
-      _         -> E <$> exprP
-    where outTy (RAllT _ t)    = outTy t
-          outTy (RAllP _ t)    = outTy t
-          outTy (RFun _ _ t _) = Just t
-          outTy _              = Nothing
-
-locUpperIdP' = locParserP upperIdP'
-
-upperIdP' :: Parser Symbol
-upperIdP' = try $ symbol <$> condIdP' (isUpper . head)
-
-condIdP'  :: (String -> Bool) -> Parser Symbol
-condIdP' f
-  = do c  <- letter
-       let isAlphaNumOr' c = (isAlphaNum c) || ('\''== c)
-       cs <- many (satisfy isAlphaNumOr')
-       blanks
-       if f (c:cs) then return (symbol $ T.pack $ c:cs) else parserZero
-
-binderP :: Parser Symbol
-binderP    =  try $ symbol <$> idP badc
-          <|> pwr <$> parens (idP bad)
-  where
-    idP p  = many1 (satisfy (not . p))
-    badc c = (c == ':') || (c == ',') || bad c
-    bad c  = isSpace c || c `elem` ("(,)" :: String)
-    pwr s  = symbol $ "(" `mappend` s `mappend` ")"
-
-grabs p = try (liftM2 (:) p (grabs p))
-       <|> return []
-
-measureDefP :: Parser Body -> Parser (Def BareType LocSymbol)
-measureDefP bodyP
-  = do mname   <- locParserP symbolP
-       (c, xs) <- measurePatP
-       whiteSpace >> reservedOp "=" >> whiteSpace
-       body    <- bodyP
-       whiteSpace
-       let xs'  = (symbol . val) <$> xs
-       return   $ Def mname [] (symbol <$> c) Nothing ((,Nothing) <$> xs') body
-
-measurePatP :: Parser (LocSymbol, [LocSymbol])
-measurePatP
-  =  parens (try conPatP <|> try consPatP <|> nilPatP <|> tupPatP)
- <|> nullaryConPatP
-
-tupPatP  = mkTupPat  <$> sepBy1 locLowerIdP comma
-conPatP  = (,)       <$> locParserP dataConNameP <*> sepBy locLowerIdP whiteSpace
-consPatP = mkConsPat <$> locLowerIdP  <*> colon <*> locLowerIdP
-nilPatP  = mkNilPat  <$> brackets whiteSpace
-
-nullaryConPatP = nilPatP <|> ((,[]) <$> locParserP dataConNameP)
-
-mkTupPat zs     = (tupDataCon (length zs), zs)
-mkNilPat _      = (dummyLoc "[]", []    )
-mkConsPat x _ y = (dummyLoc ":" , [x, y])
-tupDataCon n    = dummyLoc $ symbol $ "(" <> replicate (n - 1) ',' <> ")"
-
-
--------------------------------------------------------------------------------
---------------------------------- Predicates ----------------------------------
--------------------------------------------------------------------------------
-
-dataConFieldsP
-  =   (braces $ sepBy predTypeDDP comma)
-  <|> (sepBy dataConFieldP spaces)
-
-dataConFieldP
-  = parens ( try predTypeDDP
-             <|> do v <- dummyBindP
-                    t <- bareTypeP
-                    return (v,t)
-           )
-    <|> do v <- dummyBindP
-           t <- bareTypeP
-           return (v,t)
-
-predTypeDDP
-  = liftM2 (,) bbindP bareTypeP
-
-dataConP
-  = do x   <- locParserP dataConNameP
-       spaces
-       xts <- dataConFieldsP
-       return (x, xts)
-
-dataConNameP
-  =  try upperIdP
- <|> pwr <$> parens (idP bad)
-  where
-     idP p  = many1 (satisfy (not . p))
-     bad c  = isSpace c || c `elem` ("(,)" :: String)
-     pwr s  = symbol $ "(" <> s <> ")"
-
-dataSizeP
-  = (brackets $ (Just . mkFun) <$> locLowerIdP)
-  <|> return Nothing
-  where
-    mkFun s x = mkEApp (symbol <$> s) [EVar x]
-
-dataDeclP :: Parser DataDecl
-dataDeclP = try dataDeclFullP <|> dataDeclSizeP
-
-
-dataDeclSizeP
-  = do pos <- getPosition
-       x   <- locUpperIdP'
-       spaces
-       fsize <- dataSizeP
-       return $ D x [] [] [] [] pos fsize
-
-dataDeclFullP
-  = do pos <- getPosition
-       x   <- locUpperIdP'
-       spaces
-       fsize <- dataSizeP
-       spaces
-       ts  <- sepBy tyVarIdP blanks
-       ps  <- predVarDefsP
-       whiteSpace >> reservedOp "=" >> whiteSpace
-       dcs <- sepBy dataConP (reserved "|")
-       whiteSpace
-       return $ D x ts ps [] dcs pos fsize
-
----------------------------------------------------------------------
--- | Parsing Qualifiers ---------------------------------------------
----------------------------------------------------------------------
-
-fTyConP :: Parser FTycon
-fTyConP
-  =   (reserved "int"     >> return intFTyCon)
-  <|> (reserved "Integer" >> return intFTyCon)
-  <|> (reserved "Int"     >> return intFTyCon)
-  <|> (reserved "int"     >> return intFTyCon)
-  <|> (reserved "real"    >> return realFTyCon)
-  <|> (reserved "bool"    >> return boolFTyCon)
-  <|> (symbolFTycon      <$> locUpperIdP)
-
-
----------------------------------------------------------------------
------------- Interacting with Fixpoint ------------------------------
----------------------------------------------------------------------
-
-grabUpto p
-  =  try (Just <$> lookAhead p)
- <|> try (eof   >> return Nothing)
- <|> (anyChar   >> grabUpto p)
-
-betweenMany leftP rightP p
-  = do z <- grabUpto leftP
-       case z of
-         Just _  -> liftM2 (:) (between leftP rightP p) (betweenMany leftP rightP p)
-         Nothing -> return []
-
-specWraps = betweenMany (liquidBeginP >> whiteSpace) (whiteSpace >> liquidEndP)
-
-liquidBeginP = string liquidBegin
-liquidEndP   = string liquidEnd
----------------------------------------------------------------
--- | Bundling Parsers into a Typeclass ------------------------
----------------------------------------------------------------
-
-instance Inputable BareType where
-  rr' = doParse' bareTypeP
-
-instance Inputable (Measure BareType LocSymbol) where
-  rr' = doParse' measureP
+{-# LANGUAGE DeriveDataTypeable        #-}
+
+module Language.Haskell.Liquid.Parse
+  ( hsSpecificationP, specSpecificationP
+  , singleSpecP, BPspec, Pspec(..)
+  , parseSymbolToLogic
+  )
+  where
+
+import           Control.Arrow                          (second)
+import           Control.Monad
+import           Data.String
+import           Prelude                                hiding (error)
+import           Text.Parsec
+import           Text.Parsec.Error                      (newErrorMessage, Message (..))
+import           Text.Parsec.Pos
+
+import qualified Text.Parsec.Token                      as Token
+import qualified Data.Text                              as T
+import qualified Data.HashMap.Strict                    as M
+import qualified Data.HashSet                           as S
+import           Data.Monoid
+import           Data.Data
+
+
+import           Data.Char                              (isSpace, isAlpha, isUpper, isAlphaNum, isDigit)
+import           Data.List                              (foldl', partition)
+
+import           GHC                                    (ModuleName, mkModuleName)
+import           Text.PrettyPrint.HughesPJ              (text )
+
+import           Language.Fixpoint.Types                hiding (Error, R, Predicate)
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types          -- hiding (Axiom)
+import           Language.Fixpoint.Misc                 (mapSnd)
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types.Variance
+import           Language.Haskell.Liquid.Types.Bounds
+import qualified Language.Haskell.Liquid.Measure        as Measure
+import           Language.Fixpoint.Parse                hiding (angles, refBindP, refP, refDefP)
+
+import Control.Monad.State
+
+-- import Debug.Trace
+
+--------------------------------------------------------------------------------
+-- | Top Level Parsing API -----------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- | Used to parse .hs and .lhs files (via ApiAnnotations)
+
+-------------------------------------------------------------------------------
+hsSpecificationP :: ModuleName
+                 -> [(SourcePos, String)] -> [BPspec]
+                 -> Either [Error] (ModName, Measure.BareSpec)
+-------------------------------------------------------------------------------
+hsSpecificationP modName specComments specQuotes =
+  case go ([], []) initPState $ reverse specComments of
+    ([], specs) ->
+      Right $ mkSpec (ModName SrcImport modName) (specs ++ specQuotes)
+    (errs, _) ->
+      Left errs
+  where
+    go (errs, specs) _ []
+      = (reverse errs, reverse specs)
+    go (errs, specs) pstate ((pos, specComment):xs)
+      = case parseWithError pstate specP pos specComment of
+          Left err        -> go (err:errs, specs) pstate xs
+          Right (st,spec) -> go (errs,spec:specs) st xs
+
+-- | Used to parse .spec files
+
+--------------------------------------------------------------------------
+specSpecificationP  :: SourceName -> String -> Either Error (ModName, Measure.BareSpec)
+--------------------------------------------------------------------------
+specSpecificationP f s = mapRight snd $  parseWithError initPState specificationP (newPos f 1 1) s
+
+specificationP :: Parser (ModName, Measure.BareSpec)
+specificationP
+  = do reserved "module"
+       reserved "spec"
+       name   <- symbolP
+       reserved "where"
+       xs     <- grabs (specP <* whiteSpace)
+       return $ mkSpec (ModName SpecImport $ mkModuleName $ symbolString name) xs
+
+-------------------------------------------------------------------------------
+singleSpecP :: SourcePos -> String -> Either Error BPspec
+-------------------------------------------------------------------------------
+singleSpecP pos = mapRight snd . parseWithError initPState specP pos
+
+mapRight :: (a -> b) -> Either l a -> Either l b
+mapRight f (Right x) = Right $ f x
+mapRight _ (Left x)  = Left x
+
+---------------------------------------------------------------------------
+parseWithError :: PState -> Parser a -> SourcePos -> String -> Either Error (PState, a)
+---------------------------------------------------------------------------
+parseWithError pstate parser p s =
+  case runState (runParserT doParse 0 (sourceName p) s) pstate of
+    (Left e, _)            -> Left  $ parseErrorError e
+    (Right (r, "", _), st) -> Right (st, r)
+    (Right (_, rem, _), _) -> Left  $ parseErrorError $ remParseError p s rem
+  where
+    -- See http://stackoverflow.com/questions/16209278/parsec-consume-all-input
+    doParse = setPosition p >> remainderP (whiteSpace *> parser <* (whiteSpace >> eof))
+
+
+---------------------------------------------------------------------------
+parseErrorError     :: ParseError -> Error
+---------------------------------------------------------------------------
+parseErrorError e = ErrParse sp msg e
+  where
+    pos             = errorPos e
+    sp              = sourcePosSrcSpan pos
+    msg             = text $ "Error Parsing Specification from: " ++ sourceName pos
+
+---------------------------------------------------------------------------
+remParseError       :: SourcePos -> String -> String -> ParseError
+---------------------------------------------------------------------------
+remParseError p s r = newErrorMessage msg $ newPos (sourceName p) line col
+  where
+    msg             = Message "Leftover while parsing"
+    (line, col)     = remLineCol p s r
+
+remLineCol             :: SourcePos -> String -> String -> (Int, Int)
+remLineCol pos src rem = (line + offLine, col + offCol)
+  where
+    line               = 1 + srcLine - remLine
+    srcLine            = length srcLines
+    remLine            = length remLines
+    offLine            = sourceLine pos - 1
+    col                = 1 + srcCol - remCol
+    srcCol             = length $ srcLines !! (line - 1)
+    remCol             = length $ head remLines
+    offCol             = if line == 1 then sourceColumn pos - 1 else 0
+    srcLines           = lines  src
+    remLines           = lines  rem
+
+
+
+----------------------------------------------------------------------------------
+-- Parse to Logic  ---------------------------------------------------------------
+----------------------------------------------------------------------------------
+
+parseSymbolToLogic :: SourceName -> String -> Either Error LogicMap
+parseSymbolToLogic f = mapRight snd . parseWithError initPState toLogicP (newPos f 1 1)
+
+toLogicP :: Parser LogicMap
+toLogicP
+  = toLogicMap <$> many toLogicOneP
+
+toLogicOneP :: Parser  (LocSymbol, [Symbol], Expr)
+toLogicOneP
+  = do reserved "define"
+       (x:xs) <- many1 (locParserP symbolP)
+       reservedOp "="
+       e      <- exprP
+       return (x, val <$> xs, e)
+
+
+defineP :: Parser (LocSymbol, Symbol)
+defineP = do v <- locParserP binderP
+             spaces
+             reservedOp "="
+             spaces
+             x <- binderP
+             return (v, x)
+
+----------------------------------------------------------------------------------
+-- Lexer Tokens ------------------------------------------------------------------
+----------------------------------------------------------------------------------
+
+dot :: Parser String
+dot           = Token.dot           lexer
+
+angles :: Parser a -> Parser a
+angles        = Token.angles        lexer
+
+stringLiteral :: Parser String
+stringLiteral = Token.stringLiteral lexer
+
+-- identifier :: Parser String
+-- identifier = Token.identifier       lexer
+
+-- operator :: Parser String
+-- operator = Token.operator           lexer
+
+----------------------------------------------------------------------------------
+-- BareTypes ---------------------------------------------------------------------
+----------------------------------------------------------------------------------
+
+-- ---------------------------------------------------------------------
+-- fundamentally, a type is ofthe form
+--   comp -> comp -> .. -> comp
+--
+-- So
+--
+-- bt = comp
+--    | comp '->' bt
+--
+-- comp = circle
+--      | '(' bt ')'
+--
+-- circle = the ground component of a baretype, sans parens or "->" at the top
+--          level
+
+-- Each 'comp' should have a variable to refer to it, either a parser-assigned
+-- one or given explicitly.
+--  e.g.   xs : [Int]
+data ParamComp = PC { _pci :: PcScope
+                    , _pct :: BareType }
+
+data PcScope = PcImplicit Symbol
+             | PcExplicit Symbol
+             | PcNoSymbol
+             deriving (Eq,Show)
+
+nullPC :: BareType -> ParamComp
+nullPC bt = PC PcNoSymbol bt
+
+btP :: Parser ParamComp
+btP = do
+  c@(PC sb _) <- compP
+  case sb of
+    PcNoSymbol   -> return c
+    PcImplicit b -> parseFun c b
+    PcExplicit b -> parseFun c b
+  <?> "btP"
+  where
+    parseFun c@(PC sb t1) b  =
+      ((do
+            reservedOp "->"
+            PC _ t2 <- btP
+            return (PC sb (rFun b t1 t2)))
+        <|>
+         (do
+            reservedOp "=>"
+            PC _ t2 <- btP
+            -- TODO:AZ return an error if s == PcExplicit
+            return $ PC sb $ foldr (rFun dummySymbol) t2 (getClasses t1))
+         <|> return c)
+
+compP :: Parser ParamComp
+compP = circleP <* whiteSpace <|> parens btP <?> "compP"
+
+circleP :: Parser ParamComp
+circleP
+  =  nullPC <$> (reserved "forall" >> bareAllP)
+ <|> holePC -- starts with '_'
+ <|> namedCircleP -- starts with lower
+ <|> bareTypeBracesP -- starts with '{'
+ <|> unnamedCircleP
+ <|> (angles (do PC sb t <- parens btP
+                 p <- monoPredicateP
+                 return $ PC sb (t `strengthen` MkUReft mempty p mempty)))
+             -- starts with '<'
+ <|> nullPC <$> (dummyP (bbaseP <* spaces)) -- starts with '_' or '[' or '(' or lower or "'" or upper
+ <?> "circeP"
+
+holePC :: Parser ParamComp
+holePC = do
+  h <- holeP
+  b <- dummyBindP
+  return (PC (PcImplicit b) h)
+
+namedCircleP :: Parser ParamComp
+namedCircleP = do
+  lb <- locParserP lowerIdP
+  (do
+      _ <- colon
+      let b = val lb
+      t1 <- bareArgP b
+      return $ PC (PcExplicit b) t1
+    <|> do
+      b <- dummyBindP
+      PC (PcImplicit b) <$> dummyP (lowerIdTail (val lb))
+    )
+
+unnamedCircleP :: Parser ParamComp
+unnamedCircleP = do
+  lb <- locParserP dummyBindP
+  let b = val lb
+  t1 <- bareArgP b
+  return $ PC (PcImplicit b) t1
+
+-- ---------------------------------------------------------------------
+
+-- | The top-level parser for "bare" refinement types. If refinements are
+-- not supplied, then the default "top" refinement is used.
+
+bareTypeP :: Parser BareType
+bareTypeP = do
+  PC _ v <- btP
+  return v
+
+bareTypeBracesP :: Parser ParamComp
+bareTypeBracesP = do
+  t <-  braces (
+            (try (do
+               ct <- constraintP
+               return $ Right ct
+                     ))
+           <|>
+            (try(do
+                    x  <- symbolP
+                    _ <- colon
+                    i  <- freshIntP
+                    t  <- bbaseP
+                    reservedOp "|"
+                    ra <- refasHoleP <* spaces
+                    let xi = intSymbol x i
+                    -- xi is a unique var based on the name in x.
+                    -- su replaces any use of x in the balance of the expression with the unique val
+                    let su v = if v == x then xi else v
+                    return $ Left $ PC (PcExplicit x) $ substa su $ t (Reft (x, ra)) ))
+           <|> do t <- ((RHole . uTop . Reft . ("VV",)) <$> (refasHoleP <* spaces))
+                  return (Left $ nullPC t)
+            )
+  case t of
+    Left l -> return l
+    Right ct -> do
+      PC _sb tt <- btP
+      return $ nullPC $ rrTy ct tt
+
+bareArgP :: Symbol -> Parser BareType
+bareArgP vvv
+  =  (refDefP vvv) refasHoleP bbaseP -- starts with '{'
+ <|> holeP                           -- starts with '_'
+ <|> (dummyP (bbaseP <* spaces))
+ <|> parens bareTypeP                -- starts with '('
+        -- starts with '_', '[', '(', lower, upper
+ <?> "bareArgP"
+
+bareAtomP :: (Parser Expr -> Parser (Reft -> BareType) -> Parser BareType)
+          -> Parser BareType
+bareAtomP ref
+  =  ref refasHoleP bbaseP
+ <|> holeP
+ <|> (dummyP (bbaseP <* spaces))
+ <?> "bareAtomP"
+
+bareAtomBindP :: Parser BareType
+bareAtomBindP = bareAtomP refBindBindP
+
+
+-- Either
+--  { x : t | ra }
+-- or
+--  { ra }
+refBindBindP :: Parser Expr
+             -> Parser (Reft -> BareType)
+             -> Parser BareType
+refBindBindP rp kindP'
+  = braces (
+      ((do
+              x  <- symbolP
+              _ <- colon
+              i  <- freshIntP
+              t  <- kindP'
+              reservedOp "|"
+              ra <- rp <* spaces
+              let xi = intSymbol x i
+              -- xi is a unique var based on the name in x.
+              -- su replaces any use of x in the balance of the expression with the unique val
+              let su v = if v == x then xi else v
+              return $ substa su $ t (Reft (x, ra)) ))
+     <|> ((RHole . uTop . Reft . ("VV",)) <$> (rp <* spaces))
+     <?> "refBindBindP"
+   )
+
+
+refBindOptBindP :: Symbol
+         -> Parser Expr
+         -> Parser (Reft -> BareType)
+         -> Parser BareType
+refBindOptBindP vv rp kindP'
+  = braces (
+      (try(do x  <- optBindP vv
+              i  <- freshIntP
+              t  <- kindP'
+              reservedOp "|"
+              ra <- rp <* spaces
+              let xi = intSymbol x i
+              -- xi is a unique var based on the name in x.
+              -- su replaces any use of x in the balance of the expression with the unique val
+              let su v = if v == x then xi else v
+              return $ substa su $ t (Reft (x, ra)) ))
+     <|> ((RHole . uTop . Reft . ("VV",)) <$> (rp <* spaces))
+     <?> "refBindP"
+   )
+
+refP :: Parser (Reft -> BareType) -> Parser BareType
+refP = refBindBindP refaP
+
+refDefP :: Symbol -> Parser Expr -> Parser (Reft -> BareType) -> Parser BareType
+refDefP x  = refBindOptBindP x
+
+
+-- "sym :" or return the devault sym
+optBindP :: Symbol
+         -> Parser Symbol
+optBindP x = try bindP <|> return x
+
+holeP :: Parser BareType
+holeP    = reserved "_" >> spaces >> return (RHole $ uTop $ Reft ("VV", hole))
+
+holeRefP :: Parser (Reft -> BareType)
+holeRefP = reserved "_" >> spaces >> return (RHole . uTop)
+
+-- NOPROP refasHoleP :: Parser Expr
+-- NOPROP refasHoleP  = try refaP
+-- NOPROP          <|> (reserved "_" >> return hole)
+
+refasHoleP :: Parser Expr
+refasHoleP
+  =  (reserved "_" >> return hole)
+ <|> refaP
+ <?> "refasHoleP"
+
+-- FIXME: the use of `blanks = oneOf " \t"` here is a terrible and fragile hack
+-- to avoid parsing:
+--
+--   foo :: a -> b
+--   bar :: a
+--
+-- as `foo :: a -> b bar`..
+bbaseP :: Parser (Reft -> BareType)
+bbaseP
+  =  holeRefP  -- Starts with '_'
+ <|> liftM2 bLst (brackets (maybeP bareTypeP)) predicatesP
+ <|> liftM2 bTup (parens $ sepBy bareTypeP comma) predicatesP
+ <|> parseHelper  -- starts with lower
+ <|> liftM5 bCon bTyConP stratumP predicatesP (sepBy bareTyArgP blanks) mmonoPredicateP
+           -- starts with "'" or upper case char
+ <?> "bbaseP"
+ where
+   parseHelper = do
+     l <- lowerIdP
+     lowerIdTail l
+
+lowerIdTail :: Symbol -> Parser (Reft -> BareType)
+lowerIdTail l =
+     (    (liftM2 bAppTy (return $ bTyVar l) (sepBy1 bareTyArgP blanks))
+      <|> (liftM3 bRVar  (return $ bTyVar l) stratumP monoPredicateP))
+
+bTyConP :: Parser BTyCon
+bTyConP
+  =  (reservedOp "'" >> (mkPromotedBTyCon <$> locUpperIdP))
+ <|> mkBTyCon <$> locUpperIdP
+ <?> "bTyConP"
+
+classBTyConP :: Parser BTyCon
+classBTyConP = mkClassBTyCon <$> locUpperIdP
+
+stratumP :: Parser Strata
+stratumP
+  = do reservedOp "^"
+       bstratumP
+ <|> return mempty
+ <?> "stratumP"
+
+bstratumP :: Parser [Stratum]
+bstratumP
+  = ((:[]) . SVar) <$> symbolP
+
+bbaseNoAppP :: Parser (Reft -> BareType)
+bbaseNoAppP
+  =  holeRefP
+ <|> liftM2 bLst (brackets (maybeP bareTypeP)) predicatesP
+ <|> liftM2 bTup (parens $ sepBy bareTypeP comma) predicatesP
+ <|> try (liftM5 bCon bTyConP stratumP predicatesP (return []) (return mempty))
+ <|> liftM3 bRVar (bTyVar <$> lowerIdP) stratumP monoPredicateP
+ <?> "bbaseNoAppP"
+
+maybeP :: ParsecT s u m a -> ParsecT s u m (Maybe a)
+maybeP p = liftM Just p <|> return Nothing
+
+bareTyArgP :: Parser BareType
+bareTyArgP
+  =  (RExprArg . fmap expr <$> locParserP integer)
+ <|> try (braces $ RExprArg <$> locParserP exprP)
+ <|> try bareAtomNoAppP
+ <|> try (parens bareTypeP)
+ <?> "bareTyArgP"
+
+bareAtomNoAppP :: Parser BareType
+bareAtomNoAppP
+  =  refP bbaseNoAppP
+ <|> (dummyP (bbaseNoAppP <* spaces))
+ <?> "bareAtomNoAppP"
+
+
+constraintP :: Parser BareType
+constraintP
+  = do xts <- constraintEnvP
+       t1  <- bareTypeP
+       reservedOp "<:"
+       t2  <- bareTypeP
+       return $ fromRTypeRep $ RTypeRep [] [] [] ((val . fst <$> xts) ++ [dummySymbol])
+                                                 (replicate (length xts + 1) mempty)
+                                                 ((snd <$> xts) ++ [t1]) t2
+
+constraintEnvP :: Parser [(LocSymbol, BareType)]
+constraintEnvP
+   =  try (do xts <- sepBy tyBindNoLocP comma
+              reservedOp "|-"
+              return xts)
+  <|> return []
+  <?> "constraintEnvP"
+
+rrTy :: Monoid r => RType c tv r -> RType c tv r -> RType c tv r
+rrTy ct = RRTy (xts ++ [(dummySymbol, tr)]) mempty OCons
+  where
+    tr   = ty_res trep
+    xts  = zip (ty_binds trep) (ty_args trep)
+    trep = toRTypeRep ct
+
+--  "forall <z w> . TYPE"
+-- or
+--  "forall x y <z :: Nat, w :: Int> . TYPE"
+bareAllP :: Parser BareType
+bareAllP = do
+  as <- tyVarDefsP
+  vs <- angles inAngles
+        <|> (return $ Right [])
+  dot
+  t <- bareTypeP
+  case vs of
+    Left ss  -> return $ foldr RAllS t ss
+    Right ps -> return $ foldr RAllT (foldr RAllP t ps) (makeRTVar <$> as)
+  where
+    inAngles =
+      (
+       (try  (Right <$> sepBy  predVarDefP comma))
+        <|> ((Left  <$> sepBy1 symbolP     comma))
+       )
+
+tyVarDefsP :: Parser [BTyVar]
+tyVarDefsP
+  = (parens $ many (bTyVar <$> tyKindVarIdP))
+ <|> many (bTyVar <$> tyVarIdP)
+ <?> "tyVarDefsP"
+
+-- TODO:AZ use something from Token instead
+tyVarIdP :: Parser Symbol
+tyVarIdP = symbol <$> condIdP alphanums (isSmall . head)
+  where
+    alphanums = S.fromList $ ['a'..'z'] ++ ['0'..'9']
+
+tyKindVarIdP :: Parser Symbol
+tyKindVarIdP = do
+   tv <- tyVarIdP
+   (  (do reservedOp "::"; _ <- kindP; return tv)
+    <|> return tv)
+
+kindP :: Parser BareType
+kindP = bareAtomBindP
+
+predVarDefsP :: Parser [PVar BSort]
+predVarDefsP
+  =  (angles $ sepBy1 predVarDefP comma)
+ <|> return []
+ <?> "predVarDefP"
+
+predVarDefP :: Parser (PVar BSort)
+predVarDefP
+  = bPVar <$> predVarIdP <*> dcolon <*> predVarTypeP
+
+predVarIdP :: Parser Symbol
+predVarIdP
+  = symbol <$> tyVarIdP
+
+bPVar :: Symbol -> t -> [(Symbol, t1)] -> PVar t1
+bPVar p _ xts  = PV p (PVProp τ) dummySymbol τxs
+  where
+    (_, τ) = safeLast "bPVar last" xts
+    τxs    = [ (τ, x, EVar x) | (x, τ) <- init xts ]
+    safeLast _ xs@(_:_) = last xs
+    safeLast msg _      = panic Nothing $ "safeLast with empty list " ++ msg
+
+predVarTypeP :: Parser [(Symbol, BSort)]
+predVarTypeP = bareTypeP >>= either parserFail return . mkPredVarType
+
+mkPredVarType :: BareType -> Either String [(Symbol, BSort)]
+mkPredVarType t
+  | isOk      = Right $ zip xs ts
+  | otherwise = Left err
+  where
+    isOk      = isPropBareType tOut --  isHPropBareType tOut
+    tOut      = ty_res trep
+    trep      = toRTypeRep t
+    xs        = ty_binds trep
+    ts        = toRSort <$> ty_args trep
+    err       = "Predicate Variable with non-Prop output sort: " ++ showpp t
+
+xyP :: Parser x -> Parser a -> Parser y -> Parser (x, y)
+xyP lP sepP rP = (\x _ y -> (x, y)) <$> lP <*> (spaces >> sepP) <*> rP
+
+
+dummyBindP :: Parser Symbol
+dummyBindP = tempSymbol "db" <$> freshIntP
+
+
+isPropBareType :: RType BTyCon t t1 -> Bool
+isPropBareType  = isPrimBareType boolConName -- propConName
+
+-- isHPropBareType :: RType BTyCon t t1 -> Bool
+-- isHPropBareType = isPrimBareType hpropConName
+
+isPrimBareType :: Symbol -> RType BTyCon t t1 -> Bool
+isPrimBareType n (RApp tc [] _ _) = val (btc_tc tc) == n
+isPrimBareType _ _                = False
+
+getClasses :: RType BTyCon t t1 -> [RType BTyCon t t1]
+getClasses (RApp tc ts ps r)
+  | isTuple tc
+  = concatMap getClasses ts
+  | otherwise
+  = [RApp (tc { btc_class = True }) ts ps r]
+getClasses t
+  = [t]
+
+dummyP ::  Monad m => m (Reft -> b) -> m b
+dummyP fm
+  = fm `ap` return dummyReft
+
+symsP :: (IsString tv, Monoid r)
+      => Parser [(Symbol, RType c tv r)]
+symsP
+  = do reservedOp "\\"
+       ss <- sepBy symbolP spaces
+       reservedOp "->"
+       return $ (, dummyRSort) <$> ss
+ <|> return []
+ <?> "symsP"
+
+dummyRSort :: (IsString tv, Monoid r) => RType c tv r
+dummyRSort
+  = RVar "dummy" mempty
+
+predicatesP :: (IsString tv, Monoid r)
+            => Parser [Ref (RType c tv r) BareType]
+predicatesP
+   =  (angles $ sepBy1 predicate1P comma)
+  <|> return []
+  <?> "predicatesP"
+
+predicate1P :: (IsString tv, Monoid r)
+            => Parser (Ref (RType c tv r) BareType)
+predicate1P
+   =  try (RProp <$> symsP <*> refP bbaseP)
+  <|> (rPropP [] . predUReft <$> monoPredicate1P)
+  <|> (braces $ bRProp <$> symsP' <*> refaP)
+  <?> "predicate1P"
+   where
+    symsP'       = do ss    <- symsP
+                      fs    <- mapM refreshSym (fst <$> ss)
+                      return $ zip ss fs
+    refreshSym s = intSymbol s <$> freshIntP
+
+mmonoPredicateP :: Parser Predicate
+mmonoPredicateP
+   = try (angles $ angles monoPredicate1P)
+  <|> return mempty
+  <?> "mmonoPredicateP"
+
+monoPredicateP :: Parser Predicate
+monoPredicateP
+   = try (angles monoPredicate1P)
+  <|> return mempty
+  <?> "monoPredicateP"
+
+monoPredicate1P :: Parser Predicate
+monoPredicate1P
+   =  (reserved "True" >> return mempty)
+  <|> (pdVar <$> parens predVarUseP)
+  <|> (pdVar <$>        predVarUseP)
+  <?> "monoPredicate1P"
+
+predVarUseP :: IsString t
+            => Parser (PVar t)
+predVarUseP
+  = do (p, xs) <- funArgsP
+       return   $ PV p (PVProp dummyTyId) dummySymbol [ (dummyTyId, dummySymbol, x) | x <- xs ]
+
+funArgsP :: Parser (Symbol, [Expr])
+funArgsP  = try realP <|> empP <?> "funArgsP"
+  where
+    empP  = (,[]) <$> predVarIdP
+    realP = do (EVar lp, xs) <- splitEApp <$> funAppP
+               return (lp, xs)
+
+boundP :: Parser (Bound (Located BareType) Expr)
+boundP = do
+  name   <- locParserP upperIdP
+  reservedOp "="
+  vs     <- bvsP
+  params <- many (parens tyBindP)
+  args   <- bargsP
+  body   <- predP
+  return $ Bound name vs params args body
+ where
+    bargsP =     ( do reservedOp "\\"
+                      xs <- many (parens tyBindP)
+                      reservedOp  "->"
+                      return xs
+                 )
+           <|> return []
+           <?> "bargsP"
+    bvsP   =     ( do reserved "forall"
+                      xs <- many (locParserP (bTyVar <$> symbolP))
+                      reservedOp  "."
+                      return (fmap (`RVar` mempty) <$> xs)
+                 )
+           <|> return []
+
+
+infixGenP :: Assoc -> Parser ()
+infixGenP assoc = do
+   spaces
+   p <- maybeDigit
+   spaces
+   s <- infixIdP
+   spaces
+   addOperatorP (FInfix p s Nothing assoc)
+
+
+infixP :: Parser ()
+infixP = infixGenP AssocLeft
+
+infixlP :: Parser ()
+infixlP = infixGenP AssocLeft
+
+infixrP :: Parser ()
+infixrP = infixGenP AssocRight
+
+maybeDigit :: Parser (Maybe Int)
+maybeDigit
+  = try (satisfy isDigit >>= return . Just . read . (:[]))
+  <|> return Nothing
+
+------------------------------------------------------------------------
+----------------------- Wrapped Constructors ---------------------------
+------------------------------------------------------------------------
+
+bRProp :: [((Symbol, τ), Symbol)]
+       -> Expr -> Ref τ (RType c BTyVar (UReft Reft))
+bRProp []    _    = panic Nothing "Parse.bRProp empty list"
+bRProp syms' expr = RProp ss $ bRVar (BTV dummyName) mempty mempty r
+  where
+    (ss, (v, _))  = (init syms, last syms)
+    syms          = [(y, s) | ((_, s), y) <- syms']
+    su            = mkSubst [(x, EVar y) | ((x, _), y) <- syms']
+    r             = su `subst` Reft (v, expr)
+
+bRVar :: tv -> Strata -> Predicate -> r -> RType c tv (UReft r)
+bRVar α s p r             = RVar α (MkUReft r p s)
+
+bLst :: Maybe (RType BTyCon tv (UReft r))
+     -> [RTProp BTyCon tv (UReft r)]
+     -> r
+     -> RType BTyCon tv (UReft r)
+bLst (Just t) rs r        = RApp (mkBTyCon $ dummyLoc listConName) [t] rs (reftUReft r)
+bLst (Nothing) rs r       = RApp (mkBTyCon $ dummyLoc listConName) []  rs (reftUReft r)
+
+bTup :: (PPrint r, Reftable r)
+     => [RType BTyCon tv (UReft r)]
+     -> [RTProp BTyCon tv (UReft r)]
+     -> r
+     -> RType BTyCon tv (UReft r)
+bTup [t] _ r | isTauto r  = t
+             | otherwise  = t `strengthen` (reftUReft r)
+bTup ts rs r              = RApp (mkBTyCon $ dummyLoc tupConName) ts rs (reftUReft r)
+
+
+-- Temporarily restore this hack benchmarks/esop2013-submission/Array.hs fails
+-- w/o it
+-- TODO RApp Int [] [p] true should be syntactically different than RApp Int [] [] p
+-- bCon b s [RProp _ (RHole r1)] [] _ r = RApp b [] [] $ r1 `meet` (MkUReft r mempty s)
+bCon :: c
+     -> Strata
+     -> [RTProp c tv (UReft r)]
+     -> [RType c tv (UReft r)]
+     -> Predicate
+     -> r
+     -> RType c tv (UReft r)
+bCon b s rs            ts p r = RApp b ts rs $ MkUReft r p s
+
+bAppTy :: (Foldable t, PPrint r, Reftable r)
+       => tv -> t (RType c tv (UReft r)) -> r -> RType c tv (UReft r)
+bAppTy v ts r  = ts' `strengthen` reftUReft r
+  where
+    ts'        = foldl' (\a b -> RAppTy a b mempty) (RVar v mempty) ts
+
+reftUReft :: r -> UReft r
+reftUReft r    = MkUReft r mempty mempty
+
+predUReft :: Monoid r => Predicate -> UReft r
+predUReft p    = MkUReft dummyReft p mempty
+
+dummyReft :: Monoid a => a
+dummyReft      = mempty
+
+dummyTyId :: IsString a => a
+dummyTyId      = ""
+
+------------------------------------------------------------------
+--------------------------- Measures -----------------------------
+------------------------------------------------------------------
+
+type BPspec = Pspec (Located BareType) LocSymbol
+
+data Pspec ty ctor
+  = Meas    (Measure ty ctor)
+  | Assm    (LocSymbol, ty)
+  | Asrt    (LocSymbol, ty)
+  | LAsrt   (LocSymbol, ty)
+  | Asrts   ([LocSymbol], (ty, Maybe [Located Expr]))
+  | Impt    Symbol
+  | DDecl   DataDecl
+  | NTDecl  DataDecl
+  | Incl    FilePath
+  | Invt    ty
+  | IAlias  (ty, ty)
+  | Alias   (RTAlias Symbol BareType)
+  | EAlias  (RTAlias Symbol Expr)
+  | Embed   (LocSymbol, FTycon)
+  | Qualif  Qualifier
+  | Decr    (LocSymbol, [Int])
+  | LVars   LocSymbol
+  | Lazy    LocSymbol
+  | Insts   (LocSymbol, Maybe Int)
+  | HMeas   LocSymbol
+  | Reflect LocSymbol
+  | Inline  LocSymbol
+  | ASize   LocSymbol
+  | HBound  LocSymbol
+  | PBound  (Bound ty Expr)
+  | Pragma  (Located String)
+  | CMeas   (Measure ty ())
+  | IMeas   (Measure ty ctor)
+  | Class   (RClass ty)
+  | RInst   (RInstance ty)
+  | Varia   (LocSymbol, [Variance])
+  | BFix    ()
+  | Define  (LocSymbol, Symbol)
+  deriving (Data, Typeable, Show)
+
+-- | For debugging
+{-instance Show (Pspec a b) where
+  show (Meas   _) = "Meas"
+  show (Assm   _) = "Assm"
+  show (Asrt   _) = "Asrt"
+  show (LAsrt  _) = "LAsrt"
+  show (Asrts  _) = "Asrts"
+  show (Impt   _) = "Impt"
+  show (DDecl  _) = "DDecl"
+  show (NTDecl _) = "NTDecl"
+  show (Incl   _) = "Incl"
+  show (Invt   _) = "Invt"
+  show (IAlias _) = "IAlias"
+  show (Alias  _) = "Alias"
+  show (EAlias _) = "EAlias"
+  show (Embed  _) = "Embed"
+  show (Qualif _) = "Qualif"
+  show (Decr   _) = "Decr"
+  show (LVars  _) = "LVars"
+  show (Lazy   _) = "Lazy"
+  -- show (Axiom  _) = "Axiom"
+  show (Insts  _) = "Insts"
+  show (Reflect _) = "Reflect"
+  show (HMeas  _) = "HMeas"
+  show (HBound _) = "HBound"
+  show (Inline _) = "Inline"
+  show (Pragma _) = "Pragma"
+  show (CMeas  _) = "CMeas"
+  show (IMeas  _) = "IMeas"
+  show (Class  _) = "Class"
+  show (Varia  _) = "Varia"
+  show (PBound _) = "Bound"
+  show (RInst  _) = "RInst"
+  show (ASize  _) = "ASize"
+  show (BFix   _) = "BFix"
+  show (Define _) = "Define"-}
+
+mkSpec :: ModName -> [BPspec] -> (ModName, Measure.Spec (Located BareType) LocSymbol)
+mkSpec name xs         = (name,) $ Measure.qualifySpec (symbol name) Measure.Spec
+  { Measure.measures   = [m | Meas   m <- xs]
+  , Measure.asmSigs    = [a | Assm   a <- xs]
+  , Measure.sigs       = [a | Asrt   a <- xs]
+                      ++ [(y, t) | Asrts (ys, (t, _)) <- xs, y <- ys]
+  , Measure.localSigs  = []
+  , Measure.reflSigs   = []
+  , Measure.invariants = [t | Invt   t <- xs]
+  , Measure.ialiases   = [t | IAlias t <- xs]
+  , Measure.imports    = [i | Impt   i <- xs]
+  , Measure.dataDecls  = [d | DDecl  d <- xs] ++ [d | NTDecl d <- xs]
+  , Measure.newtyDecls = [d | NTDecl d <- xs]
+  , Measure.includes   = [q | Incl   q <- xs]
+  , Measure.aliases    = [a | Alias  a <- xs]
+  , Measure.ealiases   = [e | EAlias e <- xs]
+  , Measure.embeds     = M.fromList [e | Embed e <- xs]
+  , Measure.qualifiers = [q | Qualif q <- xs]
+  , Measure.decr       = [d | Decr d   <- xs]
+  , Measure.lvars      = [d | LVars d  <- xs]
+  , Measure.autois     = M.fromList [s | Insts s <- xs]
+  , Measure.pragmas    = [s | Pragma s <- xs]
+  , Measure.cmeasures  = [m | CMeas  m <- xs]
+  , Measure.imeasures  = [m | IMeas  m <- xs]
+  , Measure.classes    = [c | Class  c <- xs]
+  , Measure.dvariance  = [v | Varia  v <- xs]
+  , Measure.rinstance  = [i | RInst  i <- xs]
+  , Measure.termexprs  = [(y, es) | Asrts (ys, (_, Just es)) <- xs, y <- ys]
+  , Measure.lazy       = S.fromList [s | Lazy   s <- xs]
+  , Measure.bounds     = M.fromList [(bname i, i) | PBound i <- xs]
+  , Measure.reflects   = S.fromList [s | Reflect s <- xs]
+  , Measure.hmeas      = S.fromList [s | HMeas  s <- xs]
+  , Measure.inlines    = S.fromList [s | Inline s <- xs]
+  , Measure.autosize   = S.fromList [s | ASize  s <- xs]
+  , Measure.hbounds    = S.fromList [s | HBound s <- xs]
+  , Measure.defs       = M.fromList [d | Define d <- xs]
+  }
+
+-- | Parse a single top level liquid specification
+specP :: Parser BPspec
+specP
+  =     (fallbackSpecP "assume"     (liftM Assm    tyBindP  ))
+    <|> (fallbackSpecP "assert"     (liftM Asrt    tyBindP  ))
+    <|> (fallbackSpecP "autosize"   (liftM ASize   asizeP   ))
+    <|> (reserved "local"         >> liftM LAsrt   tyBindP  )
+
+    -- TODO: These next two are synonyms, kill one
+    <|> (fallbackSpecP "axiomatize" (liftM Reflect axiomP   ))
+    <|> (fallbackSpecP "reflect"    (liftM Reflect axiomP   ))
+
+    <|> (fallbackSpecP "measure"    hmeasureP)
+
+    <|> (fallbackSpecP "define"     (liftM Define  defineP  ))
+    <|> (reserved "infixl"        >> liftM BFix    infixlP  )
+    <|> (reserved "infixr"        >> liftM BFix    infixrP  )
+    <|> (reserved "infix"         >> liftM BFix    infixP   )
+    <|> (fallbackSpecP "inline"     (liftM Inline  inlineP  ))
+
+    <|> (fallbackSpecP "bound"    (((liftM PBound  boundP   )
+                                <|> (liftM HBound  hboundP  ))))
+    <|> (reserved "class"
+         >> ((reserved "measure"  >> liftM CMeas  cMeasureP )
+                                 <|> liftM Class  classP    ))
+    <|> (reserved "instance"
+         >> ((reserved "measure"  >> liftM IMeas  iMeasureP )
+                                 <|> liftM RInst  instanceP ))
+
+    <|> (reserved "import"        >> liftM Impt   symbolP   )
+
+    <|> (reserved "data"
+        >> ((reserved "variance"  >> liftM Varia  datavarianceP)
+                                 <|> liftM DDecl  dataDeclP ))
+
+    <|> (reserved "newtype"       >> liftM NTDecl newtypeP )
+    <|> (reserved "include"       >> liftM Incl   filePathP )
+    <|> (fallbackSpecP "invariant"  (liftM Invt   invariantP))
+    <|> (reserved "using"         >> liftM IAlias invaliasP )
+    <|> (reserved "type"          >> liftM Alias  aliasP    )
+
+    -- TODO: Next two are basically synonyms
+    <|> (fallbackSpecP "predicate"  (liftM EAlias ealiasP   ))
+    <|> (fallbackSpecP "expression" (liftM EAlias ealiasP   ))
+
+    <|> (fallbackSpecP "embed"      (liftM Embed  embedP    ))
+    <|> (fallbackSpecP "qualif"     (liftM Qualif (qualifierP sortP)))
+    <|> (reserved "decrease"      >> liftM Decr   decreaseP )
+    <|> (reserved "lazyvar"       >> liftM LVars  lazyVarP  )
+
+    <|> (reserved "lazy"          >> liftM Lazy   lazyVarP  )
+
+    <|> (reserved "automatic-instances" >> liftM Insts autoinstP  )
+    <|> (reserved "LIQUID"        >> liftM Pragma pragmaP   )
+    <|> {- DEFAULT -}                liftM Asrts  tyBindsP
+    <?> "specP"
+
+-- | Try the given parser on the tail after matching the reserved word, and if
+-- it fails fall back to parsing it as a haskell signature for a function with
+-- the same name.
+fallbackSpecP :: String -> Parser BPspec -> Parser BPspec
+fallbackSpecP kw p = do
+  (Loc l1 l2 _) <- locParserP (reserved kw)
+  (p <|> liftM Asrts (tyBindsRemP (Loc l1 l2 (symbol kw)) ))
+
+-- | Same as tyBindsP, except the single initial symbol has already been matched
+tyBindsRemP :: LocSymbol -> Parser ([LocSymbol], (Located BareType, Maybe [Located Expr]))
+tyBindsRemP sym = do
+  dcolon
+  tb <- termBareTypeP
+  return ([sym],tb)
+
+pragmaP :: Parser (Located String)
+pragmaP = locParserP stringLiteral
+
+autoinstP :: Parser (LocSymbol, Maybe Int)
+autoinstP = do x <- locParserP binderP
+               spaces
+               i <- maybeP (reserved "with" >> integer)
+               return (x, fromIntegral <$> i)
+
+lazyVarP :: Parser LocSymbol
+lazyVarP = locParserP binderP
+
+axiomP :: Parser LocSymbol
+axiomP = locParserP binderP
+
+hboundP :: Parser LocSymbol
+hboundP = locParserP binderP
+
+inlineP :: Parser LocSymbol
+inlineP = locParserP binderP
+
+asizeP :: Parser LocSymbol
+asizeP = locParserP binderP
+
+decreaseP :: Parser (LocSymbol, [Int])
+decreaseP = mapSnd f <$> liftM2 (,) (locParserP binderP) (spaces >> many integer)
+  where
+    f     = ((\n -> fromInteger n - 1) <$>)
+
+filePathP     :: Parser FilePath
+filePathP     = angles $ many1 pathCharP
+  where
+    pathCharP = choice $ char <$> pathChars
+    pathChars = ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ['.', '/']
+
+datavarianceP :: Parser (Located Symbol, [Variance])
+datavarianceP = liftM2 (,) locUpperIdP (spaces >> many varianceP)
+
+varianceP :: Parser Variance
+varianceP = (reserved "bivariant"     >> return Bivariant)
+        <|> (reserved "invariant"     >> return Invariant)
+        <|> (reserved "covariant"     >> return Covariant)
+        <|> (reserved "contravariant" >> return Contravariant)
+        <?> "Invalid variance annotation\t Use one of bivariant, invariant, covariant, contravariant"
+
+tyBindsP :: Parser ([LocSymbol], (Located BareType, Maybe [Located Expr]))
+tyBindsP = xyP (sepBy (locParserP binderP) comma) dcolon termBareTypeP
+
+tyBindNoLocP :: Parser (LocSymbol, BareType)
+tyBindNoLocP = second val <$> tyBindP
+
+tyBindP    :: Parser (LocSymbol, Located BareType)
+tyBindP    = xyP xP dcolon tP
+  where
+    xP     = locParserP binderP
+    tP     = locParserP genBareTypeP
+
+termBareTypeP :: Parser (Located BareType, Maybe [Located Expr])
+termBareTypeP = do
+  t <- locParserP genBareTypeP
+  (termTypeP t
+    <|> return (t, Nothing))
+
+termTypeP :: Located BareType ->Parser (Located BareType, Maybe [Located Expr])
+termTypeP t
+  = do
+       reservedOp "/"
+       es <- brackets $ sepBy (locParserP exprP) comma
+       return (t, Just es)
+
+-- -------------------------------------
+
+invariantP :: Parser (Located BareType)
+invariantP = locParserP genBareTypeP
+
+invaliasP :: Parser (Located BareType, Located BareType)
+invaliasP
+  = do t  <- locParserP genBareTypeP
+       reserved "as"
+       ta <- locParserP genBareTypeP
+       return (t, ta)
+
+genBareTypeP :: Parser BareType
+genBareTypeP = bareTypeP
+
+embedP :: Parser (Located Symbol, FTycon)
+embedP
+  = xyP locUpperIdP (reserved "as") fTyConP
+
+
+aliasP :: Parser (RTAlias Symbol BareType)
+aliasP  = rtAliasP id     bareTypeP
+
+ealiasP :: Parser (RTAlias Symbol Expr)
+ealiasP = try (rtAliasP symbol predP)
+      <|> rtAliasP symbol exprP
+      <?> "ealiasP"
+
+rtAliasP :: (Symbol -> tv) -> Parser ty -> Parser (RTAlias tv ty)
+rtAliasP f bodyP
+  -- TODO:AZ pretty sure that all the 'spaces' can be removed below, given
+  --         proper use of reserved and reservedOp now
+  = do pos  <- getPosition
+       name <- upperIdP
+       spaces
+       args <- sepBy aliasIdP blanks
+       whiteSpace >> reservedOp "=" >> whiteSpace
+       body <- bodyP
+       posE <- getPosition
+       let (tArgs, vArgs) = partition (isSmall . headSym) args
+       return $ RTA name (f <$> tArgs) (f <$> vArgs) body pos posE
+
+aliasIdP :: Parser Symbol
+aliasIdP = condIdP alphaNums (isAlpha . head)
+           where
+             alphaNums = S.fromList $ ['A' .. 'Z'] ++ ['a'..'z'] ++ ['0'..'9']
+
+hmeasureP :: Parser BPspec
+hmeasureP = do
+  b <- locParserP binderP
+  spaces
+  ((do dcolon
+       ty <- locParserP genBareTypeP
+       whiteSpace
+       eqns <- grabs $ measureDefP (rawBodyP <|> tyBodyP ty)
+       return (Meas $ Measure.mkM b ty eqns))
+    <|> (return (HMeas b))
+    )
+
+measureP :: Parser (Measure (Located BareType) LocSymbol)
+measureP
+  = do (x, ty) <- tyBindP
+       whiteSpace
+       eqns    <- grabs $ measureDefP (rawBodyP <|> tyBodyP ty)
+       return   $ Measure.mkM x ty eqns
+
+
+-- | class measure
+cMeasureP :: Parser (Measure (Located BareType) ())
+cMeasureP
+  = do (x, ty) <- tyBindP
+       return $ Measure.mkM x ty []
+
+iMeasureP :: Parser (Measure (Located BareType) LocSymbol)
+iMeasureP = measureP
+
+
+oneClassArg :: Parser [Located BareType]
+oneClassArg
+  = sing <$> locParserP (rit <$> classBTyConP <*> (map val <$> classParams))
+  where
+    rit t as    = RApp t ((`RVar` mempty) <$> as) [] mempty
+    classParams =  (reserved "where" >> return [])
+               <|> ((:) <$> (fmap bTyVar <$> locLowerIdP) <*> classParams)
+    sing x      = [x]
+
+instanceP :: Parser (RInstance (Located BareType))
+instanceP
+  = do _    <- supersP
+       c    <- classBTyConP
+       spaces
+       tvs  <- (try oneClassArg) <|> (manyTill iargsP (try $ reserved "where"))
+       ms   <- sepBy riMethodSigP semi
+       spaces
+       return $ RI c tvs ms
+  where
+    superP   = locParserP (toRCls <$> bareAtomBindP)
+    supersP  = try (((parens (superP `sepBy1` comma)) <|> fmap pure superP)
+                       <* reservedOp "=>")
+               <|> return []
+    toRCls x = x
+
+    iargsP   =   (mkVar . bTyVar <$> tyVarIdP)
+            <|> (parens $ locParserP $ bareTypeP)
+
+
+    mkVar v  = dummyLoc $ RVar v mempty
+
+
+riMethodSigP :: Parser (LocSymbol, RISig (Located BareType))
+riMethodSigP
+  = try (do reserved "assume"
+            (x, t) <- tyBindP
+            return (x, RIAssumed t) )
+ <|> do (x, t) <- tyBindP
+        return (x, RISig t)
+ <?> "riMethodSigP"
+
+
+
+classP :: Parser (RClass (Located BareType))
+classP
+  = do sups <- supersP
+       c    <- classBTyConP
+       spaces
+       tvs  <- manyTill (bTyVar <$> tyVarIdP) (try $ reserved "where")
+       ms   <- grabs tyBindP
+       spaces
+       return $ RClass c sups tvs ms -- sups tvs ms
+  where
+    superP   = locParserP (toRCls <$> bareAtomBindP)
+    supersP  = try (((parens (superP `sepBy1` comma)) <|> fmap pure superP)
+                       <* reservedOp "=>")
+               <|> return []
+    toRCls x = x
+
+rawBodyP :: Parser Body
+rawBodyP
+  = braces $ do
+      v <- symbolP
+      reservedOp "|"
+      p <- predP <* spaces
+      return $ R v p
+
+tyBodyP :: Located BareType -> Parser Body
+tyBodyP ty
+  = case outTy (val ty) of
+      Just bt | isPropBareType bt
+                -> P <$> predP
+      _         -> E <$> exprP
+    where outTy (RAllT _ t)    = outTy t
+          outTy (RAllP _ t)    = outTy t
+          outTy (RFun _ _ t _) = Just t
+          outTy _              = Nothing
+
+locUpperIdP' :: Parser (Located Symbol)
+locUpperIdP' = locParserP upperIdP'
+
+upperIdP' :: Parser Symbol
+upperIdP' = try (symbol <$> condIdP' (isUpper . head))
+        <|> (symbol <$> infixCondIdP')
+
+-- TODO:AZ this looks dodgy, rather use reserved, reservedOp
+condIdP'  :: (String -> Bool) -> Parser Symbol
+condIdP' f
+  = do c  <- letter
+       let isAlphaNumOr' c = isAlphaNum c || ('\''== c)
+       cs <- many (satisfy isAlphaNumOr')
+       blanks
+       if f (c:cs) then return (symbol $ T.pack $ c:cs) else parserZero
+
+infixCondIdP' :: Parser Symbol
+infixCondIdP'
+  = do sym <- parens $ do
+         c1 <- colon
+         -- This is the same thing as 'startsVarSymASCII' from ghc-boot-th,
+         -- but LH can't use that at the moment since it requires GHC 7.10.
+         let isASCIISymbol = (`elem` ("!#$%&*+./<=>?@\\^|~-" :: String))
+         ss <- many (satisfy isASCIISymbol)
+         c2 <- colon
+         return $ symbol $ T.pack $ c1 ++ ss ++ c2
+       blanks
+       return sym
+
+-- | LHS of the thing being defined
+binderP :: Parser Symbol
+binderP    = pwr <$> parens (idP bad)
+         <|> symbol <$> idP badc
+  where
+    idP p  = many1 (satisfy (not . p))
+    badc c = (c == ':') || (c == ',') || bad c
+    bad c  = isSpace c || c `elem` ("(,)" :: String)
+    pwr s  = symbol $ "(" `mappend` s `mappend` ")"
+
+grabs :: ParsecT s u m a -> ParsecT s u m [a]
+grabs p = try (liftM2 (:) p (grabs p))
+       <|> return []
+
+measureDefP :: Parser Body -> Parser (Def (Located BareType) LocSymbol)
+measureDefP bodyP
+  = do mname   <- locParserP symbolP
+       (c, xs) <- measurePatP
+       whiteSpace >> reservedOp "=" >> whiteSpace
+       body    <- bodyP
+       whiteSpace
+       let xs'  = (symbol . val) <$> xs
+       return   $ Def mname [] (symbol <$> c) Nothing ((, Nothing) <$> xs') body
+
+measurePatP :: Parser (LocSymbol, [LocSymbol])
+measurePatP
+  =  parens (try conPatP <|> try consPatP <|> nilPatP <|> tupPatP)
+ <|> nullaryConPatP
+ <?> "measurePatP"
+
+tupPatP :: Parser (Located Symbol, [Located Symbol])
+tupPatP  = mkTupPat  <$> sepBy1 locLowerIdP comma
+
+conPatP :: Parser (Located Symbol, [Located Symbol])
+conPatP  = (,)       <$> locParserP dataConNameP <*> sepBy locLowerIdP whiteSpace
+
+consPatP :: IsString a
+         => Parser (Located a, [Located Symbol])
+consPatP = mkConsPat <$> locLowerIdP  <*> colon <*> locLowerIdP
+
+nilPatP :: IsString a
+        => Parser (Located a, [t])
+nilPatP  = mkNilPat  <$> brackets whiteSpace
+
+nullaryConPatP :: Parser (Located Symbol, [t])
+nullaryConPatP = nilPatP <|> ((,[]) <$> locParserP dataConNameP)
+                 <?> "nullaryConPatP"
+
+mkTupPat :: Foldable t => t a -> (Located Symbol, t a)
+mkTupPat zs     = (tupDataCon (length zs), zs)
+
+mkNilPat :: IsString a => t -> (Located a, [t1])
+mkNilPat _      = (dummyLoc "[]", []    )
+
+mkConsPat :: IsString a => t1 -> t -> t1 -> (Located a, [t1])
+mkConsPat x _ y = (dummyLoc ":" , [x, y])
+
+tupDataCon :: Int -> Located Symbol
+tupDataCon n    = dummyLoc $ symbol $ "(" <> replicate (n - 1) ',' <> ")"
+
+
+-------------------------------------------------------------------------------
+--------------------------------- Predicates ----------------------------------
+-------------------------------------------------------------------------------
+
+dataConFieldsP :: Parser [(Symbol, BareType)]
+dataConFieldsP
+   =  braces (sepBy predTypeDDP comma)
+  <|> sepBy dataConFieldP spaces
+  <?> "dataConFieldP"
+
+dataConFieldP :: Parser (Symbol, BareType)
+dataConFieldP
+   =  parens (try predTypeDDP <|> dbTypeP)
+  <|> dbTypeP
+  <?> "dataConFieldP"
+  where
+    dbTypeP = (,) <$> dummyBindP <*> bareTypeP
+
+predTypeDDP :: Parser (Symbol, BareType)
+predTypeDDP = (,) <$> bbindP <*> bareTypeP
+
+bbindP   :: Parser Symbol
+bbindP   = lowerIdP <* dcolon
+
+dataConP :: Parser (Located Symbol, [(Symbol, BareType)])
+dataConP
+  = do x   <- locParserP dataConNameP
+       spaces
+       xts <- dataConFieldsP
+       return (x, xts)
+
+
+adtDataConP :: Parser (Located Symbol, [(Symbol, BareType)])
+adtDataConP
+  = do x   <- locParserP dataConNameP
+       dcolon
+       xts <- tRepToArgs . toRTypeRep <$> bareTypeP
+       return (x, xts)
+  where
+    tRepToArgs trep = zip (ty_binds trep) (ty_args trep)
+
+dataConNameP :: Parser Symbol
+dataConNameP
+  =  try upperIdP
+ <|> pwr <$> parens (idP bad)
+ <?> "dataConNameP"
+  where
+     idP p  = many1 (satisfy (not . p))
+     bad c  = isSpace c || c `elem` ("(,)" :: String)
+     pwr s  = symbol $ "(" <> s <> ")"
+
+dataSizeP :: Parser (Maybe SizeFun)
+dataSizeP
+  = brackets (Just . SymSizeFun <$> locLowerIdP)
+  <|> return Nothing
+
+
+newtypeP :: Parser DataDecl
+newtypeP = dataDeclP
+
+dataDeclP :: Parser DataDecl
+dataDeclP = do
+  pos <- getPosition
+  x   <- locUpperIdP'
+  spaces
+  fsize <- dataSizeP
+  (     (dcsP pos x fsize)
+    <|> (return $ D x [] [] [] [] pos fsize)
+        )
+  where
+    dcsP pos x fsize = do
+      ts  <- sepBy noWhere blanks
+      ps  <- predVarDefsP
+      dcs <- ((reservedOp "=" >> sepBy dataConP (reservedOp "|"))
+              <|>
+               (reserved "where" >> sepBy adtDataConP (reservedOp "|")))
+      whiteSpace
+      return $ D x ts ps [] dcs pos fsize
+
+    noWhere = try $ do
+      s <- tyVarIdP
+      if s == "where"
+        then parserZero
+        else return s
+
+---------------------------------------------------------------------
+-- | Parsing Qualifiers ---------------------------------------------
+---------------------------------------------------------------------
+
+fTyConP :: Parser FTycon
+fTyConP
+  =   (reserved "int"     >> return intFTyCon)
+  <|> (reserved "Integer" >> return intFTyCon)
+  <|> (reserved "Int"     >> return intFTyCon)
+  <|> (reserved "real"    >> return realFTyCon)
+  <|> (reserved "bool"    >> return boolFTyCon)
+  <|> (symbolFTycon      <$> locUpperIdP)
+  <?> "fTyConP"
+
diff --git a/src/Language/Haskell/Liquid/Prover/Constants.hs b/src/Language/Haskell/Liquid/Prover/Constants.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Prover/Constants.hs
+++ /dev/null
@@ -1,25 +0,0 @@
-module Language.Haskell.Liquid.Prover.Constants where
-
--------------------------------------------------------------------------------
-----------------------------   Debugging  -------------------------------------
--------------------------------------------------------------------------------
-
-debug = True 
-whenLoud act = if debug then act else return ()
-
--------------------------------------------------------------------------------
-------------------------   Constant Numbers   ---------------------------------
--------------------------------------------------------------------------------
-
-delta, epsilon, default_depth :: Int 
-delta   = 5 
-epsilon = 10 
-default_depth = 2 
-
-
--------------------------------------------------------------------------------
-------------------------   Files  ---------------------------------------------
--------------------------------------------------------------------------------
-
-smtFileExtention = ".smt"
-smtFile fn = fn ++ smtFileExtention
diff --git a/src/Language/Haskell/Liquid/Prover/Misc.hs b/src/Language/Haskell/Liquid/Prover/Misc.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Prover/Misc.hs
+++ /dev/null
@@ -1,38 +0,0 @@
-module Language.Haskell.Liquid.Prover.Misc where
-
-import Data.List
-
-
-
-
--------------------------------------------------------------------------------
------------------------   Playing with lists    -------------------------------
--------------------------------------------------------------------------------
-
--- | Powerset 
-powerset = sortBy (\l1 l2 -> compare (length l1) (length l2)) . powerset'
-
-powerset'       :: [a] -> [[a]]
-powerset' []     = [[]]
-powerset' (x:xs) = xss /\/ map (x:) xss
-   where xss = powerset' xs
-
-(/\/)        :: [a] -> [a] -> [a]
-[]     /\/ ys = ys
-(x:xs) /\/ ys = x : (ys /\/ xs)
-
-
-
-
--------------------------------------------------------------------------------
------------------------   Playing with monads   -------------------------------
--------------------------------------------------------------------------------
-
-findM :: (Monad m) => (a -> m Bool) -> [a] -> m (Maybe a)
-findM _ []     = return Nothing 
-findM p (x:xs) = do {r <- p x; if r then return (Just x) else findM p xs}
-
-
-mapSnd f (x, y) = (x, f y)
-
-second3 f (x, y, z) = (x, f y, z)
diff --git a/src/Language/Haskell/Liquid/Prover/Names.hs b/src/Language/Haskell/Liquid/Prover/Names.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Prover/Names.hs
+++ /dev/null
@@ -1,8 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-module Language.Haskell.Liquid.Prover.Names where
-
-import Language.Fixpoint.Types
-
-exprToBoolSym :: Symbol
-exprToBoolSym = "exprToBool"
diff --git a/src/Language/Haskell/Liquid/Prover/Parser.hs b/src/Language/Haskell/Liquid/Prover/Parser.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Prover/Parser.hs
+++ /dev/null
@@ -1,100 +0,0 @@
-module Language.Haskell.Liquid.Prover.Parser where
-
-import Language.Haskell.Liquid.Prover.Types
-import Language.Haskell.Liquid.Prover.Constants (default_depth)
-
-import Text.Parsec
-
-import Language.Fixpoint.Parse hiding (bindP)
-import Language.Fixpoint.Types        (Expr(PAnd), symbol, Sort(FObj))
-
-parseQuery :: String -> IO LQuery
-parseQuery fn = parseFromFile (queryP fn) fn 
-
-
-queryP fn = do
-  n      <- depthP
-  bs     <- sepBy envP   whiteSpace
-  semi
-  vars   <- sepBy bindP  whiteSpace
-  semi
-  ds     <- declsP
-  axioms <- sepBy axiomP whiteSpace
-  semi
-  ctors  <- sepBy ctorP  whiteSpace
-  semi 
-  goal   <- goalP
-  return $ mempty { q_axioms = axioms
-                  , q_vars   = vars
-                  , q_ctors  = ctors
-                  , q_goal   = goal
-                  , q_fname  = fn
-                  , q_depth  = n 
-                  , q_env    = bs
-                  , q_decls  = ds
-                  }
-
-
-declsP :: Parser [Predicate]
-declsP = try (do {n <- sepBy declP whiteSpace; semi; return n} )
-      <|> return []
-
-declP :: Parser Predicate
-declP = reserved "declare" >> predicateP
-
-depthP :: Parser Int 
-depthP = try (do {reserved "depth"; reserved "="; n <- fromInteger <$> integer; semi; return n} )
-      <|> return default_depth
-
-goalP :: Parser Predicate
-goalP = reserved "goal" >> colon >> predicateP
-
-ctorP :: Parser LVarCtor
-ctorP = do reserved "constructor"
-           v <- varP
-           (vs, p) <- try (ctorAxiomP)
-           return $ VarCtor v vs p
-
-ctorAxiomP 
-   =  do reserved "with"
-         reserved "forall"
-         aargs <- argumentsP
-         abody <- predicateP
-         return (aargs, abody) 
-  <|> return ([], Pred $ PAnd [])
-
-bindP :: Parser LVar
-bindP = reserved "bind" >> varP
-
-envP :: Parser LVar
-envP = reserved "constant" >> varP
-
-predicateP :: Parser Predicate
-predicateP = Pred <$> predP
-
-axiomP :: Parser LAxiom
-axiomP = do 
-  reserved "axiom"
-  aname <- mkVar <$> symbolP
-  colon
-  reserved "forall"
-  aargs <- argumentsP
-  abody <- predicateP
-  return $ Axiom aname aargs abody
- where
-   dummySort = FObj (symbol "dummySort")
-   mkVar x   = Var x dummySort ()
-
-
-argumentsP :: Parser ([LVar])
-argumentsP = brackets $ sepBy varP comma
-
-varP :: Parser LVar
-varP = do 
-  x <- symbolP
-  colon
-  s <- sortP
-  return $ Var x s ()
-
-
-
diff --git a/src/Language/Haskell/Liquid/Prover/Pretty.hs b/src/Language/Haskell/Liquid/Prover/Pretty.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Prover/Pretty.hs
+++ /dev/null
@@ -1,64 +0,0 @@
-module Language.Haskell.Liquid.Prover.Pretty where
-
-import Language.Haskell.Liquid.Prover.Types
-
-import Language.Fixpoint.Types hiding (Predicate, EApp, EVar, Expr)
-
-instance PPrint (Var a) where
-   pprintTidy k = pprintTidy k . var_name
-
-instance PPrint (Expr a) where
-   pprintTidy k = pprintTidy k . mkExpr
-
-instance PPrint Predicate where
-   pprintTidy k = pprintTidy k . p_pred
-
-instance Show (Axiom a) where
-   show a = showpp (axiom_name a) ++ ": " ++ "forall"++ par(sep ", " $ map show (axiom_vars a)) ++ "."  ++ show (axiom_body a) ++ "\n"
-
-instance Show (Instance a) where
-   show i = "\nInstance :: " ++ show (inst_axiom i) ++ "With Arguments :: " ++  (sep ", " $ map show (inst_args i))
-                       --      ++ "\n\nPredicate = " ++ show (inst_pred i)  ++ "\n\n"
-
-instance Show (Var a) where
-   show v = showpp (var_name v) ++ " : " ++ showpp (var_sort v)
-
-instance Show (Ctor a) where
-   show c = show (ctor_expr c) ++ "\t \\" ++ (sep ", " $ map show (ctor_vars c)) -- ++ " -> " ++ show (ctor_prop c)
-
-instance Show (VarCtor a) where
-   show c = show (vctor_var c) ++ "\t \\" ++ (sep ", " $ map show (vctor_vars c)) --  ++ " -> " ++ show (vctor_prop c)
-
-instance Show (Expr a) where
-   show (EVar v)    = showpp v
-   show (EApp c es) = show c ++ par (sep ", "  $ map show es)
-
-instance Show Predicate where
-   show (Pred p) = showpp $ pprint p
-
-instance Show (Query a) where
-   show q = "\nQuery\n" ++
-              "\nAxioms::" ++ (showNum $ q_axioms q) ++
-              "\nVars  ::" ++ (sep ", " $ map show   $ q_vars   q) ++
-              "\nCtors ::" ++ (sep ", " $ map show   $ q_ctors  q) ++
-              "\nDecls ::" ++ (sep ", " $ map show   $ q_decls  q) ++
-              "\nGoal  ::" ++ (show $ q_goal q) ++
-              "\nDecls ::" ++ (show $ q_decls q) ++
-              "\nFname ::" ++ (show $ q_fname q)
-
-instance Show (Proof a) where
-  show Invalid    = "\nInvalid\n"
-  show (Proof is) = "\nProof ::\n" ++ (sep "\n" $ map show is)
-
-
-instance Show (ArgExpr a) where
-  show ae = "\nArgExpr for " ++ show (arg_sort ae) ++ "\n\nEXPRS = \n\n" ++  (sep ", " (map show $ arg_exprs ae)) ++
-            "\n\nConstructors = " ++ (sep ", " (map show $ arg_ctors ae)) ++ "\n\n"
-
-showNum ls = concat [ show i ++ " . " ++ show l | (l, i) <- zip ls [1..] ]
-
-
-par str = " (" ++ str ++ ") "
-sep _ []     = []
-sep _ [x]    = x
-sep c (x:xs) = x ++ c ++ sep c xs
diff --git a/src/Language/Haskell/Liquid/Prover/SMTInterface.hs b/src/Language/Haskell/Liquid/Prover/SMTInterface.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Prover/SMTInterface.hs
+++ /dev/null
@@ -1,14 +0,0 @@
-module Language.Haskell.Liquid.Prover.SMTInterface where
-
-import Language.Fixpoint.Smt.Interface 
-
-import Language.Fixpoint.Types
-
-makeContext :: FilePath -> [(Symbol, Sort)] -> IO Context 
-makeContext = makeZ3Context
-
-checkValid :: Context -> [Expr] -> Expr -> IO Bool
-checkValid me is q = checkValidWithContext me [] (pAnd is) q
-
-assert :: Context -> Expr -> IO ()
-assert =  smtAssert
diff --git a/src/Language/Haskell/Liquid/Prover/Solve.hs b/src/Language/Haskell/Liquid/Prover/Solve.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Prover/Solve.hs
+++ /dev/null
@@ -1,304 +0,0 @@
-{-# LANGUAGE PatternGuards #-}
-{-# LANGUAGE TupleSections #-}
-
-module Language.Haskell.Liquid.Prover.Solve where
-
-import Language.Haskell.Liquid.Prover.Types
-import Language.Haskell.Liquid.Prover.SMTInterface
-import Language.Haskell.Liquid.Prover.Pretty ()
-import Language.Haskell.Liquid.Prover.Constants
-import Language.Haskell.Liquid.Prover.Misc (findM, powerset)
-
-import Language.Fixpoint.Smt.Interface (Context)
--- import Language.Fixpoint.Misc 
-import qualified Language.Fixpoint.Types as F 
-
-import Data.List  (nubBy, nub, isPrefixOf, partition)
-import Data.Maybe (isJust, fromJust, catMaybes)
-
-import System.IO
-
--- import Control.Monad (filterM)
-
-import Language.Fixpoint.SortCheck
-import Language.Fixpoint.Types.Refinements (SortedReft)
-
-type PrEnv = F.SEnv SortedReft  
-
-solve :: Query a -> IO (Proof a)
-solve q = 
-  do putStrLn $ "Solving Query\n" ++ show q
-     cxt     <- makeContext (smtFile $ q_fname q) env
-     mapM_ (assert cxt) (p_pred <$> q_decls q)
-     proof   <- iterativeSolve γ (q_depth q) cxt (varCtorToCtor <$> q_ctors q) es (p_pred $ q_goal q) (q_axioms q)
-     putStrLn $ ("\nProof = \n" ++ show proof)
-     return proof
-  where 
-    es    = initExpressions $ filter notGHCVar vars
-    env   = nub ([(var_name v, var_sort v) | v <- ((vctor_var <$> q_ctors q) ++ q_vars q), notGHCVar v ] ++ [(var_name v, var_sort v) | v <- q_env q])
-    γ     = F.fromListSEnv $ [(x, F.trueSortedReft s) | (x,s) <- env]
-    vars  = if q_isHO q then ((vctor_var <$> q_ctors q) ++ q_vars q) else q_vars q
-
-
-notGHCVar v 
-  = not $ isPrefixOf "GHC" (show v)
-
-iterativeSolve :: PrEnv -> Int -> Context -> [Ctor a] -> [Expr a] -> F.Expr -> [Axiom a] -> IO (Proof a)
-iterativeSolve γ iter cxt cts es q axioms = go is0 [] 0 tes
-  where 
-    go _  _      i _  | i == iter = return Invalid 
-    go as old_es i es = do prf   <- findValid cxt is q  
-                           -- putStr ("Validity check with " ++ show is ++ " IS " ++ show prf) 
-                           -- putStrLn ("\nITERATION\n" ++ show i)
-                           if isJust prf 
-                                then do putStrLn "Minimizing Solution"
-                                        Proof <$> minimize cxt (fromJust prf) q
-                                else do es' <-  makeExpressions γ cxt is cts es 
-                                        mapM_ (assertExpressions γ cxt) es'
-                                        go is (mergeExpressions es old_es) (i+1) es' 
-                        where 
-                         is = concatMap (instantiate γ old_es es) asn ++ as
-    (as0, asn) = partition (null . axiom_vars) axioms
-    is0        = (\a -> Inst a [] (axiom_body a)) <$> as0 
-    tes        = groupExpressions γ es 
-
-
-type Arguments a = [(F.Sort, [Expr a])] 
-
-groupExpressions :: PrEnv -> [Expr a] -> Arguments a 
-groupExpressions γ = go [] 
-  where
-    go acc []     = acc
-    go acc (e:es) = go (placeExpr γ acc e) es 
-
-placeExpr :: PrEnv -> Arguments a -> Expr a -> Arguments a 
-placeExpr γ acc e = go [] acc 
-  where
-    t = sortExpr F.dummySpan γ' $ mkExpr e
-    go old_as []           = (t, [e]):(acc ++ old_as)
-    go old_as ((s, es):as) | unifiable s t = (s,e:es):(as ++ old_as)
-                           | otherwise     = go ((s,es):old_as) as 
-    γ' = F.fromListSEnv $ [(x, F.sr_sort s) | (x,s) <- F.toListSEnv γ]
-
-mergeExpressions :: Arguments a -> Arguments a -> Arguments a 
-mergeExpressions as1 as2 = merge as1 as2 
-  where
-    merge as1 []     = as1  
-    merge as1 (a:as) = merge (placeArg as1 a) as 
-
-placeArg as a = go [] a as 
-  where
-    go acc a [] = a:acc
-    go acc (s, es) ((s', es'):as) | unifiable s s' = (s, es++es'):(as++acc) 
-                                  | otherwise      = go ((s', es'):acc) (s, es) as 
-
-
-findValid :: Context -> [Instance a] -> F.Expr -> IO (Maybe [Instance a])
-findValid cxt ps q 
-  = (\b -> if b then Just ps else Nothing) <$> checkValid cxt (p_pred . inst_pred <$> ps) q
-
-minimize :: Context -> [Instance a] -> F.Expr -> IO [Instance a]
-minimize cxt ps q | length ps < epsilon = fromJust <$> bruteSearch cxt ps q 
-minimize cxt ps q = go 1 [] ps 
-  where
-    n = length ps `div` delta
-    go _ acc [] = if (length acc < length ps) then minimize cxt acc q else fromJust <$> bruteSearch cxt acc q  
-    go i acc is = do let (ps1, ps2) = splitAt n is 
-                     let as = p_pred . inst_pred <$> (acc ++ ps2)
-                     res <- checkValid cxt as q
-                     let _msg = show i ++ " / " ++ show delta ++ "\n"
-                     putStr "*" >> hFlush stdout
-                     if res then go (i+1) acc          ps2 
-                            else go (i+1) (acc ++ ps1) ps2 
-
-bruteSearch :: Context -> [Instance a] -> F.Expr -> IO (Maybe [Instance a])
-bruteSearch cxt ps q 
-  = findM (\is -> checkValid cxt (p_pred . inst_pred <$> is) q) (powerset ps)
-
-filterEquivalentExpressions :: PrEnv -> Context -> [Instance a] -> Arguments a -> Arguments a -> IO (Arguments a)
-filterEquivalentExpressions γ cxt is esold esnew 
-  = mapM filterArguments esnew
-  where 
-    filterArguments (s, es) = (s,) <$> foo [] (grapOldArgs s esold) es  
-    f eold e@(EApp c es) = not <$> checkValid cxt ((predCtor γ c (mkExpr <$> es)):(p_pred . inst_pred <$> is))
-                                     (F.POr $ catMaybes $ (makeEq γ e <$> eold))
-    f eold e = not <$> checkValid cxt (p_pred . inst_pred <$> is) (F.POr $ catMaybes $ (makeEq γ e <$> eold))
-
-
-    foo acc _   []     = return acc 
-    foo acc old (e:es) = do r <- f (acc ++ old) e
-                            if r then foo (e:acc) old es 
-                                 else foo acc     old es  
-
-
-
-    grapOldArgs _ []  = [] 
-    grapOldArgs s ((t, es):as) 
-      | unifiable s t = es ++ grapOldArgs s as 
-      | otherwise     = grapOldArgs s as 
-
-makeEq :: PrEnv -> Expr a -> Expr a -> Maybe (F.Expr)
-makeEq γ e1 e2 = case (checkSortedReftFull γ p) of 
-                   Nothing -> Just p 
-                   Just _  -> Nothing 
-              where
-                p = F.PAtom F.Eq (mkExpr e1) (mkExpr e2) 
-
-
-assertExpressions :: PrEnv -> Context -> (F.Sort, [Expr a]) -> IO ()
-assertExpressions γ cxt a = mapM_ go (snd a) 
-  where
-    go (EApp c es) 
-      | length es == length (ctor_vars c)
-      = do mapM go es 
-           assert cxt $ predCtor γ c (mkExpr <$> es)
-    go _    
-      = return ()
-
-predCtor γ c es 
-  | length es /= length (ctor_vars c) && length (ctor_vars c) /= 0
-  = F.PTrue 
-  | otherwise 
-  = case checkSortedReftFull γ p of
-     Nothing -> p
-     Just _  -> F.PTrue 
-  where 
-    su = F.mkSubst $ zip (var_name <$> ctor_vars c) es
-    p  = F.subst su (p_pred $ ctor_prop c)
-
-makeExpressions :: PrEnv -> Context -> [Instance a] -> [Ctor a] -> Arguments a -> IO (Arguments a)
-makeExpressions γ cxt is cts es 
-  = -- traceShow ("\nNew expressions from \n" ++ show cts ++ "\nAND\n" ++ show es) <$> 
-     filterEquivalentExpressions γ cxt is es newes       
-  where
-    newes = groupExpr [] [EApp c ess | c <- cts, ess <- makeCTorArgs c es]
-
-    groupExpr acc []     = acc 
-    groupExpr acc (e:es) = groupExpr (putExpr e (checkSortExpr γ' $ mkExpr e) acc) es  
-
-    γ' = F.fromListSEnv $ [(x, F.sr_sort s) | (x,s) <- F.toListSEnv γ]
-
-
-putExpr _ Nothing  as  
-  = as 
-putExpr e (Just t) []  
-  = [(t, [e])]
-putExpr e (Just t) ((s, es):as)
-  | unifiable t s = (s, e:es):as
-  | otherwise     = (s, es):putExpr e (Just t) as   
-
-
-makeArguments :: [F.Sort] -> Arguments a -> [[Expr a]]
-makeArguments ss es = applyArguments ees 
-  where 
-    ees = -- traceShow ("\nCandicate for \n" ++ show ss  ++ "\nWith arguments \n" ++ show es) 
-          ((`makeCandicates` es) <$> ss)
-
-    makeCandicates _ [] = [] 
-    makeCandicates s ((t,xs):xss) 
-       | unifiable s t  = xs ++ makeCandicates s xss  
-       | otherwise      = makeCandicates s xss 
-
-
-makeCTorArgs :: Ctor a -> Arguments a -> [[Expr a]]
-makeCTorArgs c = makeArguments ((var_sort <$> ctor_vars c) ++ (argumentssort $ ctor_sort c))
-  where
-    argumentssort (F.FAbs _ s)   = argumentssort s 
-    argumentssort (F.FFunc s' s) = s':argumentssort s 
-    argumentssort _              = [] 
-
-applyArguments :: [[a]] -> [[a]]
-applyArguments []           = []
-applyArguments ([]:_)       = [] 
-applyArguments ((x:xs):ess) = [x] : ((map (x:) (filter (not . null ) $ applyArguments ess)) ++ applyArguments (xs:ess))
-
-makeArgumnetsExpr n es = concatMap (`makeArgs` es) [1..n]
-
-arity :: Ctor a -> Int
-arity c 
-  = case F.functionSort $ ctor_sort c of 
-      Nothing -> 0 
-      Just (_, ss, _) -> length ss 
-
-initExpressions :: [Var a] -> [Expr a]
-initExpressions = map EVar
-
-instantiate :: PrEnv -> Arguments a -> Arguments a -> Axiom a -> [Instance a]
-instantiate γ oldses ses a 
-  = {- traceShow ("\nInstances for\n" ++ show a ++ 
-               "ALL expr = " ++ show (oldses, mergeExpressions oldses ses) ++ 
-               "\nTYPES = \n" ++ show ss ++
-               "\nmake arguments = \n" ++ show (makeArguments ss (mergeExpressions ses oldses))
-              ) $ -} 
-     catMaybes (axiomInstance γ a <$> args) 
-  where
-    args   = filter (\es -> length es == length ss && hasNew es) $ makeArguments ss (mergeExpressions ses oldses)
-    hasNew = any (`elem` (concatMap snd ses))
-    ss     = var_sort <$> axiom_vars a 
-
-makeArgs' n es 
-  | length es < n = []
-  | otherwise     = makeArgs n es  
--- NV TODO: allow multiple occurences of the same argument
-duplicateArgs _ e = [e]
-
-makeArgs :: Int -> [Expr a] -> [[Expr a]]
-makeArgs 0 _      = [[]]
-makeArgs n (x:xs) 
- | n == length (x:xs)
- = [x:xs] 
- | otherwise
- = ((x:)<$> makeArgs (n-1) xs) ++ makeArgs n xs
-makeArgs n xs = error ("makeArgs for "  ++ show (n, xs))
-
-
-axiomInstance :: PrEnv -> Axiom a -> [Expr a] -> Maybe (Instance a) 
-axiomInstance γ a es 
-  = case checkSortedReftFull γ $ p_pred pred of
-     Nothing -> Just {-  traceShow "\n\n Add instance" -}  i
-     Just _e  -> {- traceShow (show _e ++ "\n\n Reject instance " ++ show i ) -}   Nothing 
-  where 
-    pred = F.subst (F.mkSubst $ zip (var_name <$> (axiom_vars a)) (mkExpr <$> es)) (axiom_body a)
-    i    = Inst { inst_axiom = a
-                , inst_args  = es
-                , inst_pred  = pred
-                }
-
-
-checkExpr :: PrEnv -> Expr a -> Bool
-checkExpr γ e = not $ isJust $ checkSortedReftFull γ $ mkExpr e 
-
-mkcheckExpr :: PrEnv -> Expr a -> F.Expr
-mkcheckExpr γ e 
-  = case checkSortedReftFull γ e' of
-      Nothing -> e'
-      Just d -> error ("Unsorted expression\n" ++ show e ++ "\nExpr = \n" ++ show e' ++ "\nError\n" ++ show d)
-
-  where e' = mkExpr e   
-
-
-makeSorts :: Query a -> [F.Sort]
-makeSorts q = nubBy unifiable (asorts ++ csorts)
-  where 
-     asorts = var_sort <$> (concatMap axiom_vars $ q_axioms q)
-     csorts = concatMap argumentsort ((var_sort . vctor_var) <$> q_ctors q)
-     argumentsort s = case F.functionSort s of {Nothing -> []; Just (_, ss, s) -> s:ss}
-
-
-
-unifiable :: F.Sort -> F.Sort -> Bool
-unifiable (F.FVar _)   (F.FVar _)       = True 
-unifiable (F.FVar _)   (F.FObj _)       = True 
-unifiable (F.FObj _)   (F.FVar _)       = True 
-unifiable (F.FVar _)   _                = True  
-unifiable _            (F.FVar _)       = True 
-unifiable (F.FObj _)   _                = True 
-unifiable _            (F.FObj _)       = True  
-unifiable (F.FApp t s) (F.FApp t' s') = unifiable t t' && unifiable s s'
-unifiable (F.FFunc t s) (F.FFunc t' s') = unifiable t t' && unifiable s s'
-unifiable (F.FAbs _ t) t'               = unifiable t t'
-unifiable t            (F.FAbs _ t')    = unifiable t t'
-
-unifiable t1 t2 = isJust $ unify (const $ error "NV TODO: prover.Solve") t1 t2
-
-
diff --git a/src/Language/Haskell/Liquid/Prover/Types.hs b/src/Language/Haskell/Liquid/Prover/Types.hs
deleted file mode 100644
--- a/src/Language/Haskell/Liquid/Prover/Types.hs
+++ /dev/null
@@ -1,129 +0,0 @@
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE PatternGuards        #-}
-
-module Language.Haskell.Liquid.Prover.Types where
-
-import Language.Haskell.Liquid.Prover.Constants (default_depth)
-
-import qualified Language.Fixpoint.Types as F
-import Language.Fixpoint.Types hiding (Predicate, EApp, EVar, Expr)
-
-type LVar     = Var     ()
-type LVarCtor = VarCtor ()
-type LAxiom   = Axiom   ()
-type LQuery   = Query   ()
-
-
-data Axiom a = Axiom { axiom_name :: Var a
-                     , axiom_vars :: [LVar]
-                     , axiom_body :: Predicate
-                     }
-
-data Var a   = Var { var_name :: Symbol
-                   , var_sort :: Sort
-                   , var_info :: a
-                   }
-
-instance Eq (Var a) where
-  v1 == v2 = (var_name v1) == (var_name v2)
-
-
--- Note: Ctors may be higher order, like compose
--- when not fully instantiated, the predicate should not be used
-data Ctor a  = Ctor { ctor_expr :: Expr a
-                    , ctor_sort :: Sort 
-                    , ctor_vars :: [LVar]
-                    , ctor_prop :: Predicate
-                    }
-              -- constructors can be expressions like (compose f g)
-
-
-data VarCtor a  = VarCtor { vctor_var  :: Var a
-                          , vctor_vars :: [LVar]
-                          , vctor_prop :: Predicate
-                          }
-
-
-instance Eq (Ctor a) where
-  c1 == c2 = (ctor_expr c1) == (ctor_expr c2)
-
-data Expr a  = EVar (Var a)
-             | EApp (Ctor a) [Expr a]
-
-  deriving (Eq)
-
-newtype Predicate = Pred {p_pred :: F.Expr}
-
-data Proof a     = Invalid
-                 | Proof { p_evidence :: [Instance a]}
-
-data Instance a  = Inst { inst_axiom :: Axiom a
-                        , inst_args  :: [Expr a]
-                        , inst_pred  :: Predicate
-                        }
-
-
-data Query a = Query { q_axioms :: ![Axiom a]
-                     , q_ctors  :: ![VarCtor a]
-                     , q_vars   :: ![Var a]
-                     , q_env    :: ![LVar]
-                     , q_goal   :: !Predicate
-                     , q_fname  :: !FilePath
-                     , q_depth  :: !Int
-                     , q_decls  :: [Predicate]
-                     , q_isHO   :: Bool 
-                     }
-
--- | ArgExpr provides for each sort s
--- | a list of expressions of sort s
--- | and the list of constroctors that can create an expression of sort s.
-data ArgExpr a = ArgExpr { arg_sort  :: Sort
-                         , arg_exprs :: [Expr a]
-                         , arg_ctors :: [Ctor a]
-                         }
-
-instance Monoid Predicate where
-    mempty                      = Pred mempty
-    mappend (Pred p1) (Pred p2) = Pred (p1 `mappend` p2)
-
-instance Monoid (Query a) where
-    mempty        = Query { q_axioms = mempty
-                          , q_ctors  = mempty
-                          , q_vars   = mempty
-                          , q_env    = mempty
-                          , q_goal   = mempty
-                          , q_fname  = mempty
-                          , q_depth  = default_depth
-                          , q_decls  = mempty
-                          , q_isHO   = False 
-                          }
-    mappend q1 q2 = Query { q_axioms = q_axioms q1 `mappend` q_axioms q2
-                          , q_ctors  = q_ctors  q1 `mappend` q_ctors  q2
-                          , q_env    = q_env    q1 `mappend` q_env    q2
-                          , q_vars   = q_vars   q1 `mappend` q_vars   q2
-                          , q_goal   = q_goal   q1 `mappend` q_goal   q2
-                          , q_fname  = q_fname  q1 `mappend` q_fname  q2
-                          , q_decls  = q_decls  q1 `mappend` q_decls  q2
-                          , q_depth  = q_depth  q1 `max`     q_depth  q2
-                          , q_isHO   = q_isHO   q1 ||        q_isHO   q2
-                          }
-
-
-instance F.Subable Predicate where
-  subst su (Pred p)  = Pred $ subst su p
-  substa su (Pred p) = Pred $ substa su p
-  substf su (Pred p) = Pred $ substf su p
-  syms (Pred p)      = syms p
-
-varCtorToCtor :: VarCtor a -> Ctor a
-varCtorToCtor (VarCtor v vs p) = Ctor (EVar v) (var_sort v) vs p
-
-
-isEVar (EVar _) = True
-isEVar _        = False
-
-mkExpr :: Expr a -> F.Expr
-mkExpr (EVar v)    
-  = F.EVar (var_name v)
-mkExpr (EApp c es)
-  = F.eApps (mkExpr $ ctor_expr c) (mkExpr <$> es)
diff --git a/src/Language/Haskell/Liquid/Transforms/ANF.hs b/src/Language/Haskell/Liquid/Transforms/ANF.hs
--- a/src/Language/Haskell/Liquid/Transforms/ANF.hs
+++ b/src/Language/Haskell/Liquid/Transforms/ANF.hs
@@ -1,4 +1,3 @@
-
 --------------------------------------------------------------------------------
 -- | Convert GHC Core into Administrative Normal Form (ANF) --------------------
 --------------------------------------------------------------------------------
@@ -20,9 +19,8 @@
 import           DsMonad                          (initDs)
 import           GHC                              hiding (exprType)
 import           HscTypes
-
-import           OccName                          (mkVarOccFS)
-import           Id                               (mkUserLocalM)
+import           OccName                          (OccName, mkVarOccFS)
+import           Id                               (mkUserLocal)
 import           Literal
 import           MkCore                           (mkCoreLets)
 import           Outputable                       (trace)
@@ -33,36 +31,57 @@
 import           DataCon                          (dataConInstArgTys)
 import           FamInstEnv                       (emptyFamInstEnv)
 import           VarEnv                           (VarEnv, emptyVarEnv, extendVarEnv, lookupWithDefaultVarEnv)
+import           UniqSupply                       (MonadUnique, getUniqueM)
+import           Unique                           (getKey)
 import           Control.Monad.State.Lazy
-import           UniqSupply                       (MonadUnique)
+import           System.Console.CmdArgs.Verbosity (whenLoud)
 import           Language.Fixpoint.Misc             (fst3)
-import           Language.Fixpoint.Types            (anfPrefix)
+import           Language.Fixpoint.Types            (intSymbol, anfPrefix)
+
+import           Language.Haskell.Liquid.UX.Config  (Config, untidyCore, nocaseexpand, noPatternInline)
 import           Language.Haskell.Liquid.Misc       (concatMapM)
-import           Language.Haskell.Liquid.GHC.Misc   (MGIModGuts(..), showPpr, symbolFastString)
+import           Language.Haskell.Liquid.GHC.Misc   (MGIModGuts(..), showCBs, showPpr, symbolFastString)
 import           Language.Haskell.Liquid.Transforms.Rec
+import           Language.Haskell.Liquid.Transforms.Rewrite
 import           Language.Haskell.Liquid.Types.Errors
+
 import qualified Language.Haskell.Liquid.GHC.SpanStack as Sp
+import qualified Language.Haskell.Liquid.GHC.Resugar   as Rs
 import           Data.Maybe                       (fromMaybe)
 import           Data.List                        (sortBy, (\\))
 
 
+
 --------------------------------------------------------------------------------
 -- | A-Normalize a module ------------------------------------------------------
 --------------------------------------------------------------------------------
-anormalize :: Bool -> HscEnv -> MGIModGuts -> IO [CoreBind]
+anormalize :: Config -> HscEnv -> MGIModGuts -> IO [CoreBind]
 --------------------------------------------------------------------------------
-anormalize expandFlag hscEnv modGuts
-  = do -- putStrLn "***************************** GHC CoreBinds ***************************"
-       -- putStrLn $ showPpr orig_cbs
+anormalize cfg hscEnv modGuts
+  = do whenLoud $ do putStrLn "***************************** GHC CoreBinds ***************************"
+                     putStrLn $ showCBs (untidyCore cfg) (mgi_binds modGuts)
+                     putStrLn "***************************** REC CoreBinds ***************************"
+                     putStrLn $ showCBs (untidyCore cfg) orig_cbs
+                     putStrLn "***************************** RWR CoreBinds ***************************"
+                     putStrLn $ showCBs (untidyCore cfg) rwr_cbs
        (fromMaybe err . snd) <$> initDs hscEnv m grEnv tEnv emptyFamInstEnv act
     where
       m        = mgi_module modGuts
       grEnv    = mgi_rdr_env modGuts
       tEnv     = modGutsTypeEnv modGuts
-      act      = concatMapM (normalizeTopBind expandFlag emptyAnfEnv) orig_cbs
+      act      = concatMapM (normalizeTopBind γ0) rwr_cbs
+      rwr_cbs  = rewriteBinds cfg orig_cbs
       orig_cbs = transformRecExpr $ mgi_binds modGuts
       err      = panic Nothing "Oops, cannot A-Normalize GHC Core!"
+      γ0       = emptyAnfEnv cfg
 
+expandFlag :: AnfEnv -> Bool
+expandFlag = not . nocaseexpand . aeCfg
+
+patternFlag :: AnfEnv -> Bool
+patternFlag = not . noPatternInline . aeCfg
+
+modGutsTypeEnv :: MGIModGuts -> TypeEnv
 modGutsTypeEnv mg  = typeEnvFromEntities ids tcs fis
   where
     ids            = bindersOfBinds (mgi_binds mg)
@@ -76,13 +95,13 @@
 -- Can't make the below default for normalizeBind as it
 -- fails tests/pos/lets.hs due to GHCs odd let-bindings
 
-normalizeTopBind :: Bool -> AnfEnv -> Bind CoreBndr -> DsMonad.DsM [CoreBind]
-normalizeTopBind expandFlag γ (NonRec x e)
-  = do e' <- runDsM $ evalStateT (stitch γ e) (DsST expandFlag  [])
+normalizeTopBind :: AnfEnv -> Bind CoreBndr -> DsMonad.DsM [CoreBind]
+normalizeTopBind γ (NonRec x e)
+  = do e' <- runDsM $ evalStateT (stitch γ e) (DsST [])
        return [normalizeTyVars $ NonRec x e']
 
-normalizeTopBind expandFlag γ (Rec xes)
-  = do xes' <- runDsM $ execStateT (normalizeBind γ (Rec xes)) (DsST expandFlag [])
+normalizeTopBind γ (Rec xes)
+  = do xes' <- runDsM $ execStateT (normalizeBind γ (Rec xes)) (DsST [])
        return $ map normalizeTyVars (st_binds xes')
 
 normalizeTyVars :: Bind Id -> Bind Id
@@ -116,9 +135,7 @@
 newtype DsM a = DsM {runDsM :: DsMonad.DsM a}
    deriving (Functor, Monad, MonadUnique, Applicative)
 
-data DsST = DsST { st_expandflag :: Bool
-                 , st_binds      :: [CoreBind]
-                 }
+data DsST = DsST { st_binds :: [CoreBind] }
 
 type DsMW = StateT DsST DsM
 
@@ -126,13 +143,14 @@
 normalizeBind :: AnfEnv -> CoreBind -> DsMW ()
 ------------------------------------------------------------------
 normalizeBind γ (NonRec x e)
-   = do e' <- normalize γ e
-        add [NonRec x e']
+  = do e' <- normalize γ e
+       add [NonRec x e']
 
 normalizeBind γ (Rec xes)
   = do es' <- mapM (stitch γ) es
        add [Rec (zip xs es')]
-    where (xs, es) = unzip xes
+    where
+       (xs, es) = unzip xes
 
 --------------------------------------------------------------------
 normalizeName :: AnfEnv -> CoreExpr -> DsMW CoreExpr
@@ -168,25 +186,30 @@
        add [NonRec x e']
        return $ Var x
 
+shouldNormalize :: Literal -> Bool
 shouldNormalize l = case l of
   LitInteger _ _ -> True
   MachStr _ -> True
   _ -> False
 
 add :: [CoreBind] -> DsMW ()
-add w = modify $ \s -> s{st_binds = st_binds s++w}
+add w = modify $ \s -> s { st_binds = st_binds s ++ w}
 
----------------------------------------------------------------------
+--------------------------------------------------------------------------------
 normalizeLiteral :: AnfEnv -> CoreExpr -> DsMW CoreExpr
----------------------------------------------------------------------
+--------------------------------------------------------------------------------
 normalizeLiteral γ e =
   do x <- lift $ freshNormalVar γ $ exprType e
      add [NonRec x e]
      return $ Var x
 
----------------------------------------------------------------------
+--------------------------------------------------------------------------------
 normalize :: AnfEnv -> CoreExpr -> DsMW CoreExpr
----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+normalize γ e
+  | patternFlag γ
+  , Just p <- Rs.lift e
+  = normalizePattern γ p
 
 normalize γ (Lam x e)
   = do e' <- stitch γ e
@@ -203,8 +226,7 @@
        x'    <- lift $ freshNormalVar γ τx -- rename "wild" to avoid shadowing
        let γ' = extendAnfEnv γ x x'
        as'   <- forM as $ \(c, xs, e') -> liftM (c, xs,) (stitch γ' e')
-       flag  <- st_expandflag <$> get
-       as''  <- lift $ expandDefaultCase γ flag τx as'
+       as''  <- lift $ expandDefaultCase γ τx as'
        return $ Case n x' t as''
     where τx = varType x
 
@@ -218,7 +240,7 @@
   = return e
 
 normalize γ (Cast e τ)
-  = do e'    <- normalizeName γ e
+  = do e' <- normalizeName γ e
        return $ Cast e' τ
 
 normalize γ (App e1 e2)
@@ -233,27 +255,43 @@
 normalize _ (Coercion c)
   = return $ Coercion c
 
+--------------------------------------------------------------------------------
 stitch :: AnfEnv -> CoreExpr -> DsMW CoreExpr
+--------------------------------------------------------------------------------
 stitch γ e
   = do bs'   <- get
-       modify $ \s -> s {st_binds = []}
+       modify $ \s -> s { st_binds = [] }
        e'    <- normalize γ e
        bs    <- st_binds <$> get
        put bs'
        return $ mkCoreLets bs e'
 
 --------------------------------------------------------------------------------
+normalizePattern :: AnfEnv -> Rs.Pattern -> DsMW CoreExpr
+--------------------------------------------------------------------------------
+normalizePattern γ p@(Rs.PatBind {}) = do
+  -- don't normalize the >>= itself, we have a special typing rule for it
+  e1'   <- normalize γ (Rs.patE1 p)
+  e2'   <- stitch    γ (Rs.patE2 p)
+  return $ Rs.lower p { Rs.patE1 = e1', Rs.patE2 = e2' }
+
+normalizePattern γ p@(Rs.PatReturn {}) = do
+  e'    <- normalize γ (Rs.patE p)
+  return $ Rs.lower p { Rs.patE = e' }
+
+normalizePattern _ p@(Rs.PatProject {}) =
+  return (Rs.lower p)
+
+--------------------------------------------------------------------------------
 expandDefaultCase :: AnfEnv
-                  -> Bool
                   -> Type
                   -> [(AltCon, [Id], CoreExpr)]
                   -> DsM [(AltCon, [Id], CoreExpr)]
 --------------------------------------------------------------------------------
-
-expandDefaultCase γ flag tyapp zs@((DEFAULT, _ ,_) : _) | flag
+expandDefaultCase γ tyapp zs@((DEFAULT, _ ,_) : _) | expandFlag γ
   = expandDefaultCase' γ tyapp zs
 
-expandDefaultCase γ _    tyapp@(TyConApp tc _) z@((DEFAULT, _ ,_):dcs)
+expandDefaultCase γ tyapp@(TyConApp tc _) z@((DEFAULT, _ ,_):dcs)
   = case tyConDataCons_maybe tc of
        Just ds -> do let ds' = ds \\ [ d | (DataAlt d, _ , _) <- dcs]
                      if (length ds') == 1
@@ -261,9 +299,10 @@
                       else return z
        Nothing -> return z --
 
-expandDefaultCase _ _ _ z
+expandDefaultCase _ _ z
    = return z
 
+expandDefaultCase' :: AnfEnv -> Type -> [(AltCon, [Id], c)] -> DsM [(AltCon, [Id], c)]
 expandDefaultCase' γ (TyConApp tc argτs) z@((DEFAULT, _ ,e) : dcs)
   = case tyConDataCons_maybe tc of
        Just ds -> do let ds' = ds \\ [ d | (DataAlt d, _ , _) <- dcs]
@@ -274,10 +313,12 @@
 expandDefaultCase' _ _ z
    = return z
 
+cloneCase :: AnfEnv -> [Type] -> t -> DataCon -> DsM (AltCon, [Id], t)
 cloneCase γ argτs e d
   = do xs  <- mapM (freshNormalVar γ) $ dataConInstArgTys d argτs
        return (DataAlt d, xs, e)
 
+sortCases :: [(AltCon, b, c)] -> [(AltCon, b, c)]
 sortCases = sortBy (\x y -> cmpAltCon (fst3 x) (fst3 y))
 
 
@@ -289,18 +330,22 @@
 -- freshNormalVar = mkSysLocalM (symbolFastString anfPrefix)
 
 freshNormalVar :: AnfEnv -> Type -> DsM Id
-freshNormalVar γ t = mkUserLocalM anfOcc t sp
-  where
-    anfOcc         = mkVarOccFS $ symbolFastString anfPrefix
-    sp             = Sp.srcSpan (aeSrcSpan γ)
+freshNormalVar γ t = do
+  u     <- getUniqueM
+  let i  = getKey u
+  let sp = Sp.srcSpan (aeSrcSpan γ)
+  return (mkUserLocal (anfOcc i) u t sp)
 
+anfOcc :: Int -> OccName
+anfOcc = mkVarOccFS . symbolFastString . intSymbol anfPrefix
 
 data AnfEnv = AnfEnv
   { aeVarEnv  :: VarEnv Id
   , aeSrcSpan :: Sp.SpanStack
+  , aeCfg     :: Config
   }
 
-emptyAnfEnv :: AnfEnv
+emptyAnfEnv :: Config -> AnfEnv
 emptyAnfEnv = AnfEnv emptyVarEnv Sp.empty
 
 lookupAnfEnv :: AnfEnv -> Id -> Id -> Id
diff --git a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs
--- a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs
+++ b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs
@@ -4,131 +4,160 @@
 {-# LANGUAGE OverloadedStrings      #-}
 {-# LANGUAGE TupleSections          #-}
 
-module Language.Haskell.Liquid.Transforms.CoreToLogic (
-
-  coreToDef , coreToFun,
-  coreToLogic, coreToPred,
-  mkLit, runToLogic,
-  logicType,
-  strengthenResult
-
+module Language.Haskell.Liquid.Transforms.CoreToLogic
+  ( coreToDef
+  , coreToFun
+  , coreToLogic
+  , mkLit, mkI, mkS
+  , runToLogic
+  , runToLogicWithBoolBinds
+  , logicType
+  , strengthenResult
+  , strengthenResult'
+  , normalize
   ) where
 
-import Prelude hiding (error)
-import GHC hiding (Located)
-import Var
-import Type
-import TypeRep
-
-import qualified CoreSyn   as C
-import Literal
-import IdInfo
-
-import Data.Text.Encoding
-
-import TysWiredIn
-
-
+import           Data.ByteString                       (ByteString)
+import           GHC                                   hiding (Located, exprType)
+import           Prelude                               hiding (error)
+import           Type
+import           TypeRep
+import           Var
 
-import Language.Fixpoint.Misc (snd3)
+import qualified CoreSyn                               as C
+import           Literal
+import           IdInfo
 
-import Language.Fixpoint.Types hiding (Error, R, simplify)
-import qualified Language.Fixpoint.Types as F
-import Language.Haskell.Liquid.GHC.Misc
-import Language.Haskell.Liquid.GHC.Play
-import Language.Haskell.Liquid.Types    hiding (GhcInfo(..), GhcSpec (..), LM)
-import Language.Haskell.Liquid.Misc (mapSnd)
-import Language.Haskell.Liquid.WiredIn
-import Language.Haskell.Liquid.Types.RefType
+import           Data.Text.Encoding
+import           Data.Text.Encoding.Error
 
+import           TysWiredIn
 
-import qualified Data.HashMap.Strict as M
+import           Control.Monad.State
+import           Control.Monad.Except
+import           Control.Monad.Identity
+import           Language.Fixpoint.Misc                (snd3, mapSnd, mapFst)
+import           Language.Fixpoint.Types               hiding (Error, R, simplify)
+import qualified Language.Fixpoint.Types               as F
+import           Language.Haskell.Liquid.GHC.Misc hiding (varSymbol)
+import           Language.Haskell.Liquid.Bare.Misc
+import           Language.Haskell.Liquid.GHC.Play
+import           Language.Haskell.Liquid.Types         hiding (GhcInfo(..), GhcSpec (..), LM)
+-- import           Language.Haskell.Liquid.WiredIn
+import           Language.Haskell.Liquid.Types.RefType
 
+-- import           CoreUtils                                     (exprType)
 
+import qualified Data.HashMap.Strict                   as M
 
 
 logicType :: (Reftable r) => Type -> RRType r
-logicType τ = fromRTypeRep $ t{ty_res = res, ty_binds = binds, ty_args = args, ty_refts = refts}
+logicType τ      = fromRTypeRep $ t { ty_binds = bs, ty_args = as, ty_refts = rs}
   where
-    t   = toRTypeRep $ ofType τ
-    res = mkResType $ ty_res t
-    (binds, args, refts) = unzip3 $ dropWhile (isClassType.snd3) $ zip3 (ty_binds t) (ty_args t) (ty_refts t)
+    t            = toRTypeRep $ ofType τ
+    (bs, as, rs) = unzip3 $ dropWhile (isClassType.snd3) $ zip3 (ty_binds t) (ty_args t) (ty_refts t)
 
 
-    mkResType t
-     | isBool t   = propType
-     | otherwise  = t
-
-isBool (RApp (RTyCon{rtc_tc = c}) _ _ _) = c == boolTyCon
-isBool _ = False
-
-{- strengthenResult type: the refinement depends on whether the result type is a Bool or not:
+{- [NOTE:strengthenResult type]: the refinement depends on whether the result type is a Bool or not:
 
-CASE1: measure f@logic :: X -> Prop <=> f@haskell :: x:X -> {v:Bool | (Prop v) <=> (f@logic x)}
+   CASE1: measure f@logic :: X -> Prop <=> f@haskell :: x:X -> {v:Bool | (Prop v) <=> (f@logic x)}
 
-CASE2: measure f@logic :: X -> Y    <=> f@haskell :: x:X -> {v:Y    | v = (f@logic x)}
+   CASE2: measure f@logic :: X -> Y    <=> f@haskell :: x:X -> {v:Y    | v = (f@logic x)}
 -}
 
 strengthenResult :: Var -> SpecType
 strengthenResult v
   | isBool res
   = -- traceShow ("Type for " ++ showPpr v ++ "\t OF \t" ++ show (ty_binds rep)) $
-    fromRTypeRep $ rep{ty_res = res `strengthen` r, ty_binds = xs}
+    fromRTypeRep $ rep{ty_res = res `strengthen` r , ty_binds = xs}
   | otherwise
   = -- traceShow ("Type for " ++ showPpr v ++ "\t OF \t" ++ show (ty_binds rep)) $
     fromRTypeRep $ rep{ty_res = res `strengthen` r', ty_binds = xs}
-  where rep = toRTypeRep t
-        res = ty_res rep
-        xs  = intSymbol (symbol ("x" :: String)) <$> [1..length $ ty_binds rep]
-        r'  = MkUReft (exprReft (mkEApp f (mkA <$> vxs)))         mempty mempty
-        r   = MkUReft (propReft (mkEApp f (mkA <$> vxs))) mempty mempty
-        vxs = dropWhile (isClassType.snd) $ zip xs (ty_args rep)
-        f   = dummyLoc $ dropModuleNames $ simplesymbol v
-        t   = (ofType $ varType v) :: SpecType
-        mkA = EVar . fst -- if isBool t then EApp (dummyLoc propConName) [(EVar x)] else EVar x
+  where
+    rep = toRTypeRep t
+    res = ty_res rep
+    xs  = intSymbol (symbol ("x" :: String)) <$> [1..length $ ty_binds rep]
+    r'  = MkUReft (exprReft (mkEApp f (mkA <$> vxs))) mempty mempty
+    r   = MkUReft (propReft (mkEApp f (mkA <$> vxs))) mempty mempty
+    vxs = dropWhile (isClassType . snd) $ zip xs (ty_args rep)
+    f   = dummyLoc $ dropModuleNames $ simplesymbol v
+    t   = (ofType $ varType v) :: SpecType
+    mkA = EVar . fst -- if isBool t then EApp (dummyLoc propConName) [(EVar x)] else EVar x
 
 
-simplesymbol = symbol . getName
+strengthenResult' :: Var -> SpecType
+strengthenResult' v
+  | isBool $ ty_res $ toRTypeRep t
+  = go mkProp [] [1..] t
+  | otherwise
+  = go mkExpr [] [1..] t
+  where f   = dummyLoc $ dropModuleNames $ simplesymbol v
+        t   = (ofType $ varType v) :: SpecType
 
-newtype LogicM a = LM {runM :: LState -> Either a Error}
+        -- refine types of meaures: keep going until you find the last data con!
+        -- this code is a hack! we refine the last data constructor,
+        -- it got complicated to support both
+        -- 1. multi parameter measures     (see tests/pos/HasElem.hs)
+        -- 2. measures returning functions (fromReader :: Reader r a -> (r -> a) )
+        -- to simplify, drop support for multi parameter measures
+        go f args i (RAllT a t)
+          = RAllT a $ go f args i t
+        go f args i (RAllP p t)
+          = RAllP p $ go f args i t
+        go f args i (RFun x t1 t2 r)
+          | isClassType t1
+          = RFun x t1 (go f args i t2) r
+        go f args i t@(RFun _ t1 t2 r)
+          | hasRApps t
+          = let x' = intSymbol (symbol ("x" :: String)) (head i)
+            in RFun x' t1 (go f (x':args) (tail i) t2) r
+        go f args _ t
+          = t `strengthen` f args
 
-data LState = LState { symbolMap :: LogicMap
-                     , mkError   :: String -> Error
-                     , ltce      :: TCEmb TyCon
-                     }
+        hasRApps (RApp {})        = True
+        hasRApps (RFun _ t1 t2 _) = hasRApps t1 || hasRApps t2
+        hasRApps _                = False
 
+        mkExpr xs = MkUReft (exprReft $ mkEApp f (EVar <$> reverse xs)) mempty mempty
+        mkProp xs = MkUReft (propReft $ mkEApp f (EVar <$> reverse xs)) mempty mempty
 
-instance Monad LogicM where
-  return = LM . const . Left
-  (LM m) >>= f
-    = LM $ \s -> case m s of
-                (Left x) -> (runM (f x)) s
-                (Right x) -> Right x
 
-instance Functor LogicM where
-  fmap f (LM m) = LM $ \s -> case m s of
-                              (Left  x) -> Left $ f x
-                              (Right x) -> Right x
+type LogicM = ExceptT Error (StateT LState Identity)
 
-instance Applicative LogicM where
-  pure = LM . const . Left
-  (LM f) <*> (LM m)
-    = LM $ \s -> case (f s, m s) of
-                  (Left f , Left x ) -> Left $ f x
-                  (Right f, Left _ ) -> Right f
-                  (Left _ , Right x) -> Right x
-                  (Right _, Right x) -> Right x
+data LState = LState
+  { symbolMap :: LogicMap
+  , mkError   :: String -> Error
+  , ltce      :: TCEmb TyCon
+  , boolbinds :: [Var]
+  }
 
 throw :: String -> LogicM a
-throw str = LM $ \s -> Right $ (mkError s) str
+throw str = do
+  fmkError  <- mkError <$> get
+  throwError $ fmkError str
 
 getState :: LogicM LState
-getState = LM $ Left
+getState = get
 
-runToLogic tce lmap ferror  (LM m)
-  = m $ LState {symbolMap = lmap, mkError = ferror, ltce = tce }
+runToLogic
+  :: TCEmb TyCon -> LogicMap -> (String -> Error) -> LogicM t
+  -> Either Error t
+runToLogic = runToLogicWithBoolBinds []
 
-coreToDef :: Reftable r => LocSymbol -> Var -> C.CoreExpr ->  LogicM [Def (RRType r) DataCon]
+runToLogicWithBoolBinds
+  :: [Var] -> TCEmb TyCon -> LogicMap -> (String -> Error) -> LogicM t
+  -> Either Error t
+runToLogicWithBoolBinds xs tce lmap ferror m
+       = evalState (runExceptT m) s0
+  where
+    s0 = LState { symbolMap = lmap
+                , mkError   = ferror
+                , ltce      = tce
+                , boolbinds = xs
+                }
+
+coreToDef :: Reftable r => LocSymbol -> Var -> C.CoreExpr
+          -> LogicM [Def (Located (RRType r)) DataCon]
 coreToDef x _ e = go [] $ inline_preds $ simplify e
   where
     go args (C.Lam  x e) = go (x:args) e
@@ -138,92 +167,75 @@
       | otherwise        = mapM (goalt      (reverse $ tail args) (head args)) alts
     go _ _               = throw "Measure Functions should have a case at top level"
 
-    goalt args dx ((C.DataAlt d), xs, e)
-      = ((Def x (toArgs id args) d (Just $ ofType $ varType dx) (toArgs Just xs)) . E)
+    goalt args dx (C.DataAlt d, xs, e)
+      = Def x (toArgs id args) d (Just $ varRType dx) (toArgs Just xs) . E
         <$> coreToLg e
     goalt _ _ alt
        = throw $ "Bad alternative" ++ showPpr alt
 
-    goalt_prop args dx ((C.DataAlt d), xs, e)
-      = ((Def x (toArgs id args) d (Just $ ofType $ varType dx) (toArgs Just xs)) . P)
-        <$> coreToPd  e
+    goalt_prop args dx (C.DataAlt d, xs, e)
+      = Def x (toArgs id args) d (Just $ varRType dx) (toArgs Just xs) . P
+        <$> coreToLg  e
     goalt_prop _ _ alt
       = throw $ "Bad alternative" ++ showPpr alt
 
-    toArgs f args = [(symbol x, f $ ofType $ varType x) | x <- args]
+    toArgs f args = [(symbol x, f $ varRType x) | x <- args]
 
     inline_preds = inline (eqType boolTy . varType)
 
+varRType :: (Reftable r) => Var -> Located (RRType r)
+varRType = varLocInfo ofType
+
 coreToFun :: LocSymbol -> Var -> C.CoreExpr ->  LogicM ([Var], Either Expr Expr)
-coreToFun _ v e = go [] $ normalize e
+coreToFun _ _v e = go [] $ normalize e
   where
     go acc (C.Lam x e)  | isTyVar    x = go acc e
     go acc (C.Lam x e)  | isErasable x = go acc e
     go acc (C.Lam x e)  = go (x:acc) e
     go acc (C.Tick _ e) = go acc e
-    go acc e            | eqType rty boolTy
-                        = (reverse acc,) . Left  <$> coreToPd e
-                        | otherwise
-                        = (reverse acc,) . Right <$> coreToLg e
-
-
-    rty = snd $ splitFunTys $ snd $ splitForAllTys $ varType v
-
-coreToPred :: C.CoreExpr -> LogicM Expr
-coreToPred e = coreToPd $ normalize e
-
-
-coreToPd :: C.CoreExpr -> LogicM Expr
-coreToPd (C.Let b p)  = subst1 <$> coreToPd p <*>  makesub b
-coreToPd (C.Tick _ p) = coreToPd p
-coreToPd (C.App (C.Var v) e) | ignoreVar v = coreToPd e
-coreToPd (C.Var x)
-  | x == falseDataConId
-  = return PFalse
-  | x == trueDataConId
-  = return PTrue
-  | eqType boolTy (varType x)
-  = return $ mkEApp (dummyLoc propConName) [(EVar $ symbol x)]
-coreToPd p@(C.App _ _) = toPredApp p
-coreToPd e
-  = coreToLg e
--- coreToPd e
---  = throw ("Cannot transform to Logical Predicate:\t" ++ showPpr e)
-
+    go acc e            = (reverse acc,) . Right <$> coreToLg e
 
 instance Show C.CoreExpr where
   show = showPpr
 
 coreToLogic :: C.CoreExpr -> LogicM Expr
-coreToLogic = coreToLg . simplify
-
+coreToLogic = coreToLg . normalize
 
 coreToLg :: C.CoreExpr -> LogicM Expr
-coreToLg (C.Let b e)  = subst1 <$> coreToLg e <*>  makesub b
-coreToLg (C.Tick _ e) = coreToLg e
-coreToLg (C.App (C.Var v) e) | ignoreVar v = coreToLg e
-coreToLg (C.Lit l)
-  = case mkLit l of
-     Nothing -> throw $ "Bad Literal in measure definition" ++ showPpr l
-     Just i -> return i
+coreToLg (C.Let b e)
+  = subst1 <$> coreToLg e <*>  makesub b
+coreToLg (C.Tick _ e)
+  = coreToLg e
+coreToLg (C.App (C.Var v) e)
+  | ignoreVar v
+  = coreToLg e
 coreToLg (C.Var x)
   | x == falseDataConId
   = return PFalse
   | x == trueDataConId
   = return PTrue
-  | eqType boolTy (varType x)
-  = return $ mkEApp (dummyLoc propConName) [(EVar $ symbol x)]
-coreToLg (C.Var x)           = (symbolMap <$> getState) >>= eVarWithMap x
-coreToLg e@(C.App _ _)       = toLogicApp e
+  | otherwise
+  = (symbolMap <$> getState) >>= eVarWithMap x
+coreToLg e@(C.App _ _)
+  = toPredApp e
 coreToLg (C.Case e b _ alts) | eqType (varType b) boolTy
   = checkBoolAlts alts >>= coreToIte e
 coreToLg (C.Lam x e)
   = do p   <- coreToLg e
-       tce <- ltce <$> getState 
+       tce <- ltce <$> getState
        return $ ELam (symbol x, typeSort tce $ varType x) p
--- coreToLg p@(C.App _ _) = toPredApp p
-coreToLg e                   = throw ("Cannot transform to Logic:\t" ++ showPpr e)
+coreToLg (C.Case e b _ alts)
+  = do p <- coreToLg e
+       casesToLg b p alts
 
+coreToLg (C.Lit l)
+  = case mkLit l of
+     Nothing -> throw $ "Bad Literal in measure definition" ++ showPpr l
+     Just i -> return i
+
+coreToLg e
+  = throw ("Cannot transform to Logic:\t" ++ showPpr e)
+
 checkBoolAlts :: [C.CoreAlt] -> LogicM (C.CoreExpr, C.CoreExpr)
 checkBoolAlts [(C.DataAlt false, [], efalse), (C.DataAlt true, [], etrue)]
   | false == falseDataCon, true == trueDataCon
@@ -234,49 +246,86 @@
 checkBoolAlts alts
   = throw ("checkBoolAlts failed on " ++ showPpr alts)
 
+casesToLg :: Var -> Expr -> [C.CoreAlt] -> LogicM Expr
+casesToLg v e alts
+  = mapM (altToLg e) alts >>= go
+  where
+    go :: [(DataCon, Expr)] -> LogicM Expr
+    go [(_,p)]     = return (p `subst1` su)
+    go ((d,p):dps) = do c <- checkDataCon d e
+                        e' <- go dps
+                        return (EIte c p e' `subst1` su)
+    go []          = throw "Bah"
+
+    su = (symbol v, e)
+
+checkDataCon :: DataCon -> Expr -> LogicM Expr
+checkDataCon d e
+  = return $ EApp (EVar $ makeDataConChecker d) e
+
+altToLg :: Expr -> C.CoreAlt -> LogicM (DataCon, Expr)
+altToLg de (C.DataAlt d, xs, e)
+  = do p <- coreToLg e
+       let su = mkSubst $ concat [ f x i | (x, i) <- zip xs [1..]]
+       return (d, subst su p)
+  where
+    f x i = let t = EApp (EVar $ makeDataSelector d i) de
+            in [(symbol x, t), (simplesymbol x, t)]
+altToLg _ (C.LitAlt _, _, _)
+  = throw "altToLg on Lit"
+altToLg _ (C.DEFAULT, _, _)
+  = throw "altToLg on Default"
+
+coreToIte :: C.CoreExpr -> (C.CoreExpr, C.CoreExpr) -> LogicM Expr
 coreToIte e (efalse, etrue)
-  = do p  <- coreToPd e
+  = do p  <- coreToLg e
        e1 <- coreToLg efalse
        e2 <- coreToLg etrue
        return $ EIte p e2 e1
 
 toPredApp :: C.CoreExpr -> LogicM Expr
-toPredApp p
-  = do let (f, es) = splitArgs p
-       let f'      = tomaybesymbol f
-       go f' es
+toPredApp p = go . mapFst tomaybesymbol . splitArgs $ p
   where
-    go (Just f) [e1, e2]
+    go (Just f, [e1, e2])
       | Just rel <- M.lookup f brels
-      = PAtom rel <$> (coreToLg e1) <*> (coreToLg e2)
-    go (Just f) [e]
+      = PAtom rel <$> coreToLg e1 <*> coreToLg e2
+    go (Just f, [e])
       | f == symbol ("not" :: String)
-      = PNot <$>  coreToPd e
-    go (Just f) [e1, e2]
+      = PNot <$>  coreToLg e
+    go (Just f, [e1, e2])
       | f == symbol ("||" :: String)
-      = POr <$> mapM coreToPd [e1, e2]
+      = POr <$> mapM coreToLg [e1, e2]
       | f == symbol ("&&" :: String)
-      = PAnd <$> mapM coreToPd [e1, e2]
+      = PAnd <$> mapM coreToLg [e1, e2]
       | f == symbol ("==>" :: String)
-      = PImp <$> coreToPd e1 <*> coreToPd e2
-    go (Just f) es
+      = PImp <$> coreToLg e1 <*> coreToLg e2
+    go (Just f, es)
       | f == symbol ("or" :: String)
-      = POr <$> mapM coreToPd es
+      = POr  <$> mapM coreToLg es
       | f == symbol ("and" :: String)
-      = PAnd <$> mapM coreToPd es
-    go _ _ = toLogicApp p
+      = PAnd <$> mapM coreToLg es
+    go (_, _)
+      = toLogicApp p
 
 toLogicApp :: C.CoreExpr -> LogicM Expr
-toLogicApp e
-  =  do let (f, es) = splitArgs e
-        case f of 
-          C.Var _ -> do args       <- mapM coreToLg es
-                        lmap       <- symbolMap <$> getState
-                        def         <- (`mkEApp` args) <$> tosymbol f
-                        (\x -> makeApp def lmap x args) <$> tosymbol' f
-          _ -> do (fe:args) <- mapM coreToLg (f:es) 
-                  return $ foldl EApp fe args  
+toLogicApp e = do
+  let (f, es) = splitArgs e
+  case f of
+    C.Var x -> do args <- mapM coreToLg es
+                  lmap       <- symbolMap <$> getState
+                  def        <- (`mkEApp` args) <$> tosymbol f
+                  bbs        <- boolbinds <$> get
+                  (liftBoolBinds x bbs . (\x -> makeApp def lmap x args)) <$> tosymbol' f
+    _       -> do (fe:args) <- mapM coreToLg (f:es)
+                  return $ foldl EApp fe args
 
+liftBoolBinds :: Var -> [Var] -> Expr -> Expr
+liftBoolBinds x xs e
+  | x `elem` xs
+  = mkProp e
+  | otherwise
+  = e
+
 makeApp :: Expr -> LogicMap -> Located Symbol-> [Expr] -> Expr
 makeApp _ _ f [e] | val f == symbol ("GHC.Num.negate" :: String)
   = ENeg e
@@ -288,20 +337,28 @@
   = eAppWithMap lmap f es def
 
 eVarWithMap :: Id -> LogicMap -> LogicM Expr
-eVarWithMap x lmap
-  = do f' <- tosymbol' (C.Var x :: C.CoreExpr)
-       return $ eAppWithMap lmap f' [] (eVar x )
+eVarWithMap x lmap = do
+  f' <- tosymbol' (C.Var x :: C.CoreExpr)
+  return $ eAppWithMap lmap f' [] (varExpr x)
+
+varExpr :: Var -> Expr
+varExpr x
+  | isPolyCst t = mkEApp (dummyLoc s) []
+  | otherwise   = EVar s
   where
-    eVar x | isPolyCst $ varType x  = mkEApp (dummyLoc $ symbol x) []
-           | otherwise              = EVar $ symbol x
+    t           = varType x
+    s           = varSymbol x
 
-    isPolyCst (ForAllTy _ t) = isCst t
-    isPolyCst _              = False
-    isCst     (ForAllTy _ t) = isCst t
-    isCst     (FunTy _ _)    = False
-    isCst     _              = True
+isPolyCst :: Type -> Bool
+isPolyCst (ForAllTy _ t) = isCst t
+isPolyCst _              = False
 
+isCst :: Type -> Bool
+isCst (ForAllTy _ t) = isCst t
+isCst (FunTy _ _)    = False
+isCst _              = True
 
+
 brels :: M.HashMap Symbol Brel
 brels = M.fromList [ (symbol ("==" :: String), Eq)
                    , (symbol ("/=" :: String), Ne)
@@ -322,27 +379,32 @@
     numSymbol :: String -> Symbol
     numSymbol =  symbol . (++) "GHC.Num."
 
+splitArgs :: C.Expr t -> (C.Expr t, [C.Arg t])
 splitArgs e = (f, reverse es)
  where
     (f, es) = go e
 
     go (C.App (C.Var i) e) | ignoreVar i       = go e
-    go (C.App f (C.Var v)) | isErasable v    = go f
+    go (C.App f (C.Var v)) | isErasable v      = go f
     go (C.App f e) = (f', e:es) where (f', es) = go f
     go f           = (f, [])
 
+tomaybesymbol :: C.CoreExpr -> Maybe Symbol
 tomaybesymbol (C.Var c) | isDataConId  c = Just $ symbol c
 tomaybesymbol (C.Var x) = Just $ simpleSymbolVar x
-tomaybesymbol _         = Nothing 
+tomaybesymbol _         = Nothing
 
-tosymbol e         
- = case tomaybesymbol e of 
-    Just x -> return $ dummyLoc x 
+tosymbol :: C.CoreExpr -> LogicM (Located Symbol)
+tosymbol e
+ = case tomaybesymbol e of
+    Just x -> return $ dummyLoc x
     _      -> throw ("Bad Measure Definition:\n" ++ showPpr e ++ "\t cannot be applied")
 
+tosymbol' :: C.CoreExpr -> LogicM (Located Symbol)
 tosymbol' (C.Var x) = return $ dummyLoc $ simpleSymbolVar' x
 tosymbol'  e        = throw ("Bad Measure Definition:\n" ++ showPpr e ++ "\t cannot be applied")
 
+makesub :: C.CoreBind -> LogicM (Symbol, Expr)
 makesub (C.NonRec x e) =  (symbol x,) <$> coreToLg e
 makesub  _             = throw "Cannot make Logical Substitution of Recursive Definitions"
 
@@ -357,26 +419,38 @@
 mkLit (MachStr s)      = mkS s
 mkLit _                = Nothing -- ELit sym sort
 
+mkI :: Integer -> Maybe Expr
 mkI                    = Just . ECon . I
+
+mkR :: Rational -> Maybe Expr
 mkR                    = Just . ECon . F.R . fromRational
-mkS                    = Just . ESym . SL  . decodeUtf8
 
-ignoreVar i = simpleSymbolVar i `elem` ["I#"]
+mkS :: ByteString -> Maybe Expr
+mkS                    = Just . ESym . SL  . decodeUtf8With lenientDecode
 
+ignoreVar :: Id -> Bool
+ignoreVar i = simpleSymbolVar i `elem` ["I#"]
 
-simpleSymbolVar  = dropModuleNames . symbol . showPpr . getName
+simpleSymbolVar' :: Id -> Symbol
 simpleSymbolVar' = symbol . showPpr . getName
 
+varSymbol :: Var -> Symbol
+varSymbol v | Type.isFunTy (varType v) = simplesymbol v
+varSymbol v                            = symbol v
+
+isErasable :: Id -> Bool
 isErasable v = isPrefixOfSym (symbol ("$"      :: String)) (simpleSymbolVar v)
+
+isANF :: Id -> Bool
 isANF      v = isPrefixOfSym (symbol ("lq_anf" :: String)) (simpleSymbolVar v)
 
+isDead :: Id -> Bool
 isDead     = isDeadOcc . occInfo . idInfo
 
 class Simplify a where
   simplify :: a -> a
   inline   :: (Id -> Bool) -> a -> a
 
-
   normalize :: a -> a
   normalize = inline_preds . inline_anf . simplify
    where
@@ -432,6 +506,7 @@
   inline _ (C.Coercion c)      = C.Coercion c
   inline _ (C.Type t)          = C.Type t
 
+isUndefined :: (t, t1, C.Expr t2) -> Bool
 isUndefined (_, _, e) = isUndefinedExpr e
   where
    -- auto generated undefined case: (\_ -> (patError @type "error message")) void
diff --git a/src/Language/Haskell/Liquid/Transforms/Rec.hs b/src/Language/Haskell/Liquid/Transforms/Rec.hs
--- a/src/Language/Haskell/Liquid/Transforms/Rec.hs
+++ b/src/Language/Haskell/Liquid/Transforms/Rec.hs
@@ -10,33 +10,36 @@
      transformRecExpr, transformScope
      ) where
 
-import           Prelude             hiding (error)
 import           Bag
 import           Coercion
-import           Control.Arrow       (second)
+import           Control.Arrow                        (second)
 import           Control.Monad.State
 import           CoreSyn
 import           CoreUtils
-import qualified Data.HashMap.Strict as M
+import qualified Data.HashMap.Strict                  as M
+import           Data.Hashable
 import           ErrUtils
-import           Id                  (idOccInfo, setIdInfo)
+import           Id                                   (idOccInfo, setIdInfo)
 import           IdInfo
-import           MkCore              (mkCoreLams)
-import           SrcLoc
-import           Type                (mkForAllTys, splitForAllTys)
-import           TypeRep
-import           Unique              hiding (deriveUnique)
-import           Var
-import           Name (isSystemName)
 import           Language.Haskell.Liquid.GHC.Misc
 import           Language.Haskell.Liquid.GHC.Play
-import           Language.Haskell.Liquid.Misc (mapSndM, mapSnd)
+import           Language.Haskell.Liquid.Misc         (mapSndM)
+import           Language.Fixpoint.Misc               (mapSnd)
 import           Language.Haskell.Liquid.Types.Errors
+import           MkCore                               (mkCoreLams)
+import           Name                                 (isSystemName)
+import           Outputable                           (SDoc)
+import           Prelude                              hiding (error)
+import           SrcLoc
+import           Type                                 (mkForAllTys, splitForAllTys)
+import           TypeRep
+import           Unique                               hiding (deriveUnique)
+import           Var
 
-import           Data.List                (foldl', isInfixOf)
+import           Data.List                            (foldl', isInfixOf)
 
 
-import qualified Data.List as L
+import qualified Data.List                            as L
 
 
 transformRecExpr :: CoreProgram -> CoreProgram
@@ -52,6 +55,7 @@
 
 
 
+inlineLoopBreaker :: Bind Id -> Bind Id
 inlineLoopBreaker (NonRec x e) | Just (lbx, lbe) <- hasLoopBreaker be
   = Rec [(x, foldr Lam (sub (M.singleton lbx e') lbe) (αs ++ as))]
   where
@@ -92,21 +96,27 @@
     addFailExpr x (Lam _ e) su = (x, e):su
     addFailExpr _ _         _  = impossible Nothing "internal error" -- this cannot happen
 
+isTypeError :: SDoc -> Bool
 isTypeError s | isInfixOf "Non term variable" (showSDoc s) = False
 isTypeError _ = True
 
+transformScope :: [Bind Id] -> [Bind Id]
 transformScope = outerScTr . innerScTr
 
+outerScTr :: [Bind Id] -> [Bind Id]
 outerScTr = mapNonRec (go [])
   where
    go ack x (xe : xes) | isCaseArg x xe = go (xe:ack) x xes
    go ack _ xes        = ack ++ xes
 
+isCaseArg :: Id -> Bind t -> Bool
 isCaseArg x (NonRec _ (Case (Var z) _ _ _)) = z == x
 isCaseArg _ _                               = False
 
+innerScTr :: Functor f => f (Bind Id) -> f (Bind Id)
 innerScTr = (mapBnd scTrans <$>)
 
+scTrans :: Id -> Expr Id -> Expr Id
 scTrans x e = mapExpr scTrans $ foldr Let e0 bs
   where (bs, e0)           = go [] x e
         go bs x (Let b e)  | isCaseArg x b = go (b:bs) x e
@@ -119,10 +129,16 @@
                 , _loc        :: SrcSpan
                 }
 
+initEnv :: TrEnv
 initEnv = Tr 0 noSrcSpan
 
+transPg :: Traversable t
+        => t (Bind CoreBndr)
+        -> State TrEnv (t (Bind CoreBndr))
 transPg = mapM transBd
 
+transBd :: Bind CoreBndr
+        -> State TrEnv (Bind CoreBndr)
 transBd (NonRec x e) = liftM (NonRec x) (transExpr =<< mapBdM transBd e)
 transBd (Rec xes)    = liftM Rec $ mapM (mapSndM (mapBdM transBd)) xes
 
@@ -135,17 +151,27 @@
   where (tvs, ids, e'')       = collectTyAndValBinders e
         (bs, e')              = collectNonRecLets e''
 
+isNonPolyRec :: Expr CoreBndr -> Bool
 isNonPolyRec (Let (Rec xes) _) = any nonPoly (snd <$> xes)
 isNonPolyRec _                 = False
 
+nonPoly :: CoreExpr -> Bool
 nonPoly = null . fst . splitForAllTys . exprType
 
+collectNonRecLets :: Expr t -> ([Bind t], Expr t)
 collectNonRecLets = go []
   where go bs (Let b@(NonRec _ _) e') = go (b:bs) e'
         go bs e'                      = (reverse bs, e')
 
+appTysAndIds :: [Var] -> [Id] -> Id -> Expr b
 appTysAndIds tvs ids x = mkApps (mkTyApps (Var x) (map TyVarTy tvs)) (map Var ids)
 
+trans :: Foldable t
+      => [TyVar]
+      -> [Var]
+      -> t (Bind Id)
+      -> Expr Var
+      -> State TrEnv (Expr Id)
 trans vs ids bs (Let (Rec xes) e)
   = liftM (mkLam . mkLet) (makeTrans vs liveIds e')
   where liveIds = mkAlive <$> ids
@@ -156,6 +182,10 @@
 
 trans _ _ _ _ = panic Nothing "TransformRec.trans called with invalid input"
 
+makeTrans :: [TyVar]
+          -> [Var]
+          -> Expr Var
+          -> State TrEnv (Expr Var)
 makeTrans vs ids (Let (Rec xes) e)
  = do fids    <- mapM (mkFreshIds vs ids) xs
       let (ids', ys) = unzip fids
@@ -177,10 +207,16 @@
 mkRecBinds xes rs e = Let rs (foldl' f e xes)
   where f e (x, xe) = Let (NonRec x xe) e
 
+mkSubs :: (Eq k, Hashable k)
+       => [k] -> [Var] -> [Id] -> [(k, Id)] -> M.HashMap k (Expr b)
 mkSubs ids tvs xs ys = M.fromList $ s1 ++ s2
   where s1 = (second (appTysAndIds tvs xs)) <$> ys
         s2 = zip ids (Var <$> xs)
 
+mkFreshIds :: [TyVar]
+           -> [Var]
+           -> Var
+           -> State TrEnv ([Var], Id)
 mkFreshIds tvs ids x
   = do ids'  <- mapM fresh ids
        let t  = mkForAllTys tvs $ mkType (reverse ids') $ varType x
@@ -201,27 +237,33 @@
 instance Freshable Var where
   fresh v = liftM (setVarUnique v) freshUnique
 
+freshInt :: MonadState TrEnv m => m Int
 freshInt
   = do s <- get
        let n = freshIndex s
        put s{freshIndex = n+1}
        return n
 
+freshUnique :: MonadState TrEnv m => m Unique
 freshUnique = liftM (mkUnique 'X') freshInt
 
+mkAlive :: Var -> Id
 mkAlive x
   | isId x && isDeadOcc (idOccInfo x)
   = setIdInfo x (setOccInfo (idInfo x) NoOccInfo)
   | otherwise
   = x
 
+mapNonRec :: (b -> [Bind b] -> [Bind b]) -> [Bind b] -> [Bind b]
 mapNonRec f (NonRec x xe:xes) = NonRec x xe : f x (mapNonRec f xes)
 mapNonRec f (xe:xes)          = xe : mapNonRec f xes
 mapNonRec _ []                = []
 
+mapBnd :: (b -> Expr b -> Expr b) -> Bind b -> Bind b
 mapBnd f (NonRec b e)             = NonRec b (mapExpr f  e)
 mapBnd f (Rec bs)                 = Rec (map (second (mapExpr f)) bs)
 
+mapExpr :: (b -> Expr b -> Expr b) -> Expr b -> Expr b
 mapExpr f (Let (NonRec x ex) e)   = Let (NonRec x (f x ex) ) (f x e)
 mapExpr f (App e1 e2)             = App  (mapExpr f e1) (mapExpr f e2)
 mapExpr f (Lam b e)               = Lam b (mapExpr f e)
@@ -230,10 +272,12 @@
 mapExpr f (Tick t e)              = Tick t (mapExpr f e)
 mapExpr _  e                      = e
 
+mapAlt :: (b -> Expr b -> Expr b) -> (t, t1, Expr b) -> (t, t1, Expr b)
 mapAlt f (d, bs, e) = (d, bs, mapExpr f e)
 
 -- Do not apply transformations to inner code
 
+mapBdM :: Monad m => t -> a -> m a
 mapBdM _ = return
 
 -- mapBdM f (Let b e)        = liftM2 Let (f b) (mapBdM f e)
diff --git a/src/Language/Haskell/Liquid/Transforms/RefSplit.hs b/src/Language/Haskell/Liquid/Transforms/RefSplit.hs
--- a/src/Language/Haskell/Liquid/Transforms/RefSplit.hs
+++ b/src/Language/Haskell/Liquid/Transforms/RefSplit.hs
@@ -15,7 +15,7 @@
 import Language.Haskell.Liquid.Types
 import Language.Haskell.Liquid.Types.PrettyPrint ()
 
-import Language.Fixpoint.Types
+import Language.Fixpoint.Types hiding (Predicate)
 import Language.Fixpoint.Misc
 
 splitXRelatedRefs :: Symbol -> SpecType -> (SpecType, SpecType)
@@ -23,6 +23,9 @@
 
 
 
+splitRType :: Symbol
+           -> RType c tv (UReft Reft)
+           -> (RType c tv (UReft Reft), RType c tv (UReft Reft))
 splitRType f (RVar a r) = (RVar a r1, RVar a r2)
   where
         (r1, r2) = splitRef f r
@@ -79,10 +82,13 @@
   where
         (t1, t2) = splitRType x t
 
+splitRef :: Symbol -> UReft Reft -> (UReft Reft, UReft Reft)
 splitRef f (MkUReft r p s) = (MkUReft r1 p1 s, MkUReft r2 p2 s)
         where
                 (r1, r2) = splitReft f r
                 (p1, p2) = splitPred f p
+
+splitReft :: Symbol -> Reft -> (Reft, Reft)
 splitReft f (Reft (v, xs)) = (Reft (v, pAnd xs1), Reft (v, pAnd xs2))
   where
     (xs1, xs2)       = partition (isFree f) (unPAnd xs)
@@ -91,6 +97,7 @@
     unPAnd p         = [p]
 
 
+splitPred :: Symbol -> Predicate -> (Predicate, Predicate)
 splitPred f (Pr ps) = (Pr ps1, Pr ps2)
   where
     (ps1, ps2) = partition g ps
diff --git a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs
@@ -0,0 +1,344 @@
+{-# LANGUAGE CPP                       #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE GADTs                     #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE RankNTypes                #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE TypeSynonymInstances      #-}
+{-# LANGUAGE UndecidableInstances      #-}
+
+-- | This module contains functions for recursively "rewriting"
+--   GHC core using "rules".
+
+module Language.Haskell.Liquid.Transforms.Rewrite
+  ( -- * Top level rewrite function
+    rewriteBinds
+
+  -- * Low-level Rewriting Function
+  -- , rewriteWith
+
+  -- * Rewrite Rule
+  -- ,  RewriteRule
+
+  ) where
+
+import           CoreSyn
+import           Type
+import           TypeRep
+import           TyCon
+import qualified CoreSubst
+import qualified Outputable
+import qualified CoreUtils
+import qualified Var
+import qualified MkCore
+import           Data.Maybe     (fromMaybe)
+import           Control.Monad  (msum)
+import           Language.Fixpoint.Misc       (mapFst, mapSnd)
+
+import           Language.Haskell.Liquid.Misc (safeZipWithError, mapThd3, Nat)
+import           Language.Haskell.Liquid.GHC.Resugar
+import           Language.Haskell.Liquid.GHC.Misc (isTupleId) -- , showPpr, tracePpr)
+import           Language.Haskell.Liquid.UX.Config  (Config, noSimplifyCore)
+-- import           Debug.Trace
+
+--------------------------------------------------------------------------------
+-- | Top-level rewriter --------------------------------------------------------
+--------------------------------------------------------------------------------
+rewriteBinds :: Config -> [CoreBind] -> [CoreBind]
+rewriteBinds cfg
+  | simplifyCore cfg = fmap (rewriteBindWith simplifyPatTuple)
+  | otherwise        = id
+
+simplifyCore :: Config -> Bool
+simplifyCore = not . noSimplifyCore
+
+--------------------------------------------------------------------------------
+-- | A @RewriteRule@ is a function that maps a CoreExpr to another
+--------------------------------------------------------------------------------
+type RewriteRule = CoreExpr -> Maybe CoreExpr
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+rewriteBindWith :: RewriteRule -> CoreBind -> CoreBind
+--------------------------------------------------------------------------------
+rewriteBindWith r (NonRec x e) = NonRec x (rewriteWith r e)
+rewriteBindWith r (Rec xes)    = Rec    (mapSnd (rewriteWith r) <$> xes)
+
+--------------------------------------------------------------------------------
+rewriteWith :: RewriteRule -> CoreExpr -> CoreExpr
+--------------------------------------------------------------------------------
+rewriteWith tx           = go
+  where
+    go                   = txTop . step
+    txTop e              = fromMaybe e (tx e)
+    goB (Rec xes)        = Rec         (mapSnd go <$> xes)
+    goB (NonRec x e)     = NonRec x    (go e)
+    step (Let b e)       = Let (goB b) (go e)
+    step (App e e')      = App (go e)  (go e')
+    step (Lam x e)       = Lam x       (go e)
+    step (Cast e c)      = Cast (go e) c
+    step (Tick t e)      = Tick t      (go e)
+    step (Case e x t cs) = Case (go e) x t (mapThd3 go <$> cs)
+    step e@(Type _)      = e
+    step e@(Lit _)       = e
+    step e@(Var _)       = e
+    step e@(Coercion _)  = e
+
+
+--------------------------------------------------------------------------------
+-- | Rewriting Pattern-Match-Tuples --------------------------------------------
+--------------------------------------------------------------------------------
+
+{-
+    let CrazyPat x1 ... xn = e in e'
+
+    let t : (t1,...,tn) = "CrazyPat e ... (y1, ..., yn)"
+        xn = Proj t n
+        ...
+        x1 = Proj t 1
+    in
+        e'
+
+    "crazy-pat"
+ -}
+
+{- [NOTE] The following is the structure of a @PatMatchTup@
+
+      let x :: (t1,...,tn) = E[(x1,...,xn)]
+          yn = case x of (..., yn) -> yn
+          …
+          y1 = case x of (y1, ...) -> y1
+      in
+          E'
+
+  GOAL: simplify the above to:
+
+      E [ (x1,...,xn) := E' [y1 := x1,...,yn := xn] ]
+
+  TODO: several tests (e.g. tests/pos/zipper000.hs) fail because
+  the above changes the "type" the expression `E` and in "other branches"
+  the new type may be different than the old, e.g.
+
+     let (x::y::_) = e in
+     x + y
+
+     let t = case e of
+               h1::t1 -> case t1 of
+                            (h2::t2) ->  (h1, h2)
+                            DEFAULT  ->  error @ (Int, Int)
+               DEFAULT   -> error @ (Int, Int)
+         x = case t of (h1, _) -> h1
+         y = case t of (_, h2) -> h2
+     in
+         x + y
+
+  is rewritten to:
+
+              h1::t1    -> case t1 of
+                            (h2::t2) ->  h1 + h2
+                            DEFAULT  ->  error @ (Int, Int)
+              DEFAULT   -> error @ (Int, Int)
+
+     case e of
+       h1 :: h2 :: _ -> h1 + h2
+       DEFAULT       -> error @ (Int, Int)
+
+  which, alas, is ill formed.
+
+-}
+
+--------------------------------------------------------------------------------
+
+-- simplifyPatTuple :: RewriteRule
+-- simplifyPatTuple e =
+--  case simplifyPatTuple' e of
+--    Just e' -> if CoreUtils.exprType e == CoreUtils.exprType e'
+--                 then Just e'
+--                 else Just (tracePpr ("YIKES: RWR " ++ showPpr e) e')
+--    Nothing -> Nothing
+
+
+_safeSimplifyPatTuple :: RewriteRule
+_safeSimplifyPatTuple e
+  | Just e' <- simplifyPatTuple e
+  , CoreUtils.exprType e' == CoreUtils.exprType e
+  = Just e'
+  | otherwise
+  = Nothing
+
+--------------------------------------------------------------------------------
+simplifyPatTuple :: RewriteRule
+--------------------------------------------------------------------------------
+simplifyPatTuple (Let (NonRec x e) rest)
+  | Just (n, ts  ) <- varTuple x
+  , 2 <= n
+  , Just (yes, e') <- takeBinds n rest
+  , let ys          = fst <$> yes
+  , Just _         <- hasTuple ys e
+  , matchTypes yes ts
+  = replaceTuple ys e e'
+
+simplifyPatTuple _
+  = Nothing
+
+varTuple :: Var -> Maybe (Int, [Type])
+varTuple x
+  | TyConApp c ts <- Var.varType x
+  , isTupleTyCon c
+  = Just (length ts, ts)
+  | otherwise
+  = Nothing
+
+takeBinds  :: Nat -> CoreExpr -> Maybe ([(Var, CoreExpr)], CoreExpr)
+takeBinds n e
+  | n < 2     = Nothing
+  | otherwise = mapFst reverse <$> go n e
+    where
+      go 0 e                      = Just ([], e)
+      go n (Let (NonRec x e) e')  = do (xes, e'') <- go (n-1) e'
+                                       Just ((x,e) : xes, e'')
+      go _ _                      = Nothing
+
+matchTypes :: [(Var, CoreExpr)] -> [Type] -> Bool
+matchTypes xes ts =  xN == tN
+                  && all (uncurry eqType) (safeZipWithError msg xts ts)
+                  && all isProjection es
+  where
+    xN            = length xes
+    tN            = length ts
+    xts           = Var.varType <$> xs
+    (xs, es)      = unzip xes
+    msg           = "RW:matchTypes"
+
+isProjection :: CoreExpr -> Bool
+isProjection e = case lift e of
+                   Just (PatProject {}) -> True
+                   _                    -> False
+
+--------------------------------------------------------------------------------
+-- | `hasTuple ys e` CHECKS if `e` contains a tuple that "looks like" (y1...yn)
+--------------------------------------------------------------------------------
+hasTuple :: [Var] -> CoreExpr -> Maybe [Var]
+--------------------------------------------------------------------------------
+hasTuple ys = stepE
+  where
+    stepE e
+     | Just xs <- isVarTup ys e = Just xs
+     | otherwise                = go e
+    stepA (DEFAULT,_,_)         = Nothing
+    stepA (_, _, e)             = stepE e
+    go (Let _ e)                = stepE e
+    go (Case _ _ _ cs)          = msum (stepA <$> cs)
+    go _                        = Nothing
+
+--------------------------------------------------------------------------------
+-- | `replaceTuple ys e e'` REPLACES tuples that "looks like" (y1...yn) with e'
+--------------------------------------------------------------------------------
+
+replaceTuple :: [Var] -> CoreExpr -> CoreExpr -> Maybe CoreExpr
+replaceTuple ys e e'           = stepE e
+  where
+    t'                          = CoreUtils.exprType e'
+    stepE e
+     | Just xs <- isVarTup ys e = Just $ substTuple xs ys e'
+     | otherwise                = go e
+    stepA (DEFAULT, xs, err)    = Just (DEFAULT, xs, replaceIrrefutPat t' err)
+    stepA (c, xs, e)            = (c, xs,)   <$> stepE e
+    go (Let b e)                = Let b      <$> stepE e
+    go (Case e x t cs)          = fixCase e x t <$> mapM stepA cs
+    go _                        = Nothing
+
+_errorSkip :: String -> a -> b
+_errorSkip x _ = error x
+
+-- replaceTuple :: [Var] -> CoreExpr -> CoreExpr -> Maybe CoreExpr
+-- replaceTuple ys e e' = tracePpr msg (_replaceTuple ys e e')
+--  where
+--    msg = "replaceTuple: ys = " ++ showPpr ys ++
+--                        " e = " ++ showPpr e  ++
+--                        " e' =" ++ showPpr e'
+
+-- | The substitution (`substTuple`) can change the type of the overall
+--   case-expression, so we must update the type of each `Case` with its
+--   new, possibly updated type. See:
+--   https://github.com/ucsd-progsys/liquidhaskell/pull/752#issuecomment-228946210
+
+fixCase :: CoreExpr -> Var -> Type -> ListNE (Alt Var) -> CoreExpr
+fixCase e x _t cs' = Case e x t' cs'
+  where
+    t'            = CoreUtils.exprType body
+    (_,_,body)    = c
+    c:_           = cs'
+
+{-@  type ListNE a = {v:[a] | len v > 0} @-}
+type ListNE a = [a]
+
+replaceIrrefutPat :: Type -> CoreExpr -> CoreExpr
+replaceIrrefutPat t (App (Lam z e) eVoid)
+  | Just e' <- replaceIrrefutPat' t e
+  = App (Lam z e') eVoid
+
+replaceIrrefutPat t e
+  | Just e' <- replaceIrrefutPat' t e
+  = e'
+
+replaceIrrefutPat _ e
+  = e
+
+replaceIrrefutPat' :: Type -> CoreExpr -> Maybe CoreExpr 
+replaceIrrefutPat' t e
+  | (Var x, _:args) <- collectArgs e
+  , isIrrefutErrorVar x
+  = Just (MkCore.mkCoreApps (Var x) (Type t : args))
+  | otherwise
+  = Nothing
+
+isIrrefutErrorVar :: Var -> Bool
+isIrrefutErrorVar x = MkCore.iRREFUT_PAT_ERROR_ID == x
+
+
+--------------------------------------------------------------------------------
+-- | `substTuple xs ys e'` returns e' [y1 := x1,...,yn := xn]
+--------------------------------------------------------------------------------
+substTuple :: [Var] -> [Var] -> CoreExpr -> CoreExpr
+substTuple xs ys = CoreSubst.substExpr Outputable.empty (mkSubst ys xs)
+
+mkSubst :: [Var] -> [Var] -> CoreSubst.Subst
+mkSubst ys xs = CoreSubst.extendIdSubstList CoreSubst.emptySubst yxs
+  where
+    yxs       = safeZipWithError "RW:mkSubst" ys (Var <$> xs)
+
+--------------------------------------------------------------------------------
+-- | `isVarTup xs e` returns `Just ys` if e == (y1, ... , yn) and xi ~ yi
+--------------------------------------------------------------------------------
+
+isVarTup :: [Var] -> CoreExpr -> Maybe [Var]
+isVarTup xs e
+  | Just ys <- isTuple e
+  , eqVars xs ys         = Just ys
+isVarTup _ _             = Nothing
+
+eqVars :: [Var] -> [Var] -> Bool
+eqVars xs ys = {- F.tracepp ("eqVars: " ++ show xs' ++ show ys') -} xs' == ys'
+  where
+    xs' = {- F.symbol -} show <$> xs
+    ys' = {- F.symbol -} show <$> ys
+
+isTuple :: CoreExpr -> Maybe [Var]
+isTuple e
+  | (Var t, es) <- collectArgs e
+  , isTupleId t
+  , Just xs     <- mapM isVar (secondHalf es)
+  = Just xs
+  | otherwise
+  = Nothing
+
+isVar :: CoreExpr -> Maybe Var
+isVar (Var x) = Just x
+isVar _       = Nothing
+
+secondHalf :: [a] -> [a]
+secondHalf xs = drop (n `div` 2) xs
+  where
+    n         = length xs
diff --git a/src/Language/Haskell/Liquid/Types.hs b/src/Language/Haskell/Liquid/Types.hs
--- a/src/Language/Haskell/Liquid/Types.hs
+++ b/src/Language/Haskell/Liquid/Types.hs
@@ -12,7 +12,7 @@
 {-# LANGUAGE UndecidableInstances       #-}
 {-# LANGUAGE OverloadedStrings          #-}
 {-# LANGUAGE RecordWildCards            #-}
-{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE ConstraintKinds            #-}
 
 -- | This module should contain all the global type definitions and basic instances.
 
@@ -39,17 +39,25 @@
   -- * Default unknown name
   , dummyName, isDummy
 
+  -- * Bare Type Constructors and Variables
+  , BTyCon(..)
+  , mkBTyCon, mkClassBTyCon, mkPromotedBTyCon
+  , isClassBTyCon
+  , BTyVar(..)
+
   -- * Refined Type Constructors
   , RTyCon (RTyCon, rtc_tc, rtc_info)
   , TyConInfo(..), defaultTyConInfo
   , rTyConPVs
   , rTyConPropVs
-  , isClassRTyCon, isClassType, isEqType
+  , isClassRTyCon, isClassType, isEqType, isRVar, isBool
 
   -- * Refinement Types
   , RType (..), Ref(..), RTProp, rPropP
   , RTyVar (..)
   , RTAlias (..)
+  , OkRT
+  , lmapEAlias
 
   -- * Worlds
   , HSeg (..)
@@ -57,9 +65,13 @@
 
   -- * Classes describing operations on `RTypes`
   , TyConable (..)
-  , RefTypable (..)
   , SubsTy (..)
 
+  -- * Type Variables
+  , RTVar (..), RTVInfo (..)
+  , makeRTVar, mapTyVarValue
+  , dropTyVarInfo, rTVarToBind
+
   -- * Predicate Variables
   , PVar (PV, pname, parg, ptype, pargs), isPropPV, pvType
   , PVKind (..)
@@ -69,17 +81,21 @@
   , UReft(..)
 
   -- * Parse-time entities describing refined data types
+  , SizeFun  (..), szFun
   , DataDecl (..)
   , DataConP (..)
   , TyConP (..)
 
   -- * Pre-instantiated RType
-  , RRType, BRType, RRProp
+  , RRType, RRProp
+  , BRType, BRProp
   , BSort, BPVar
+  , RTVU, PVU
 
   -- * Instantiated RType
   , BareType, PrType
   , SpecType, SpecProp
+  , LocBareType, LocSpecType
   , RSort
   , UsedPVar, RPVar, RReft
   , REnv (..)
@@ -100,7 +116,7 @@
 
   -- * Traversing `RType`
   , efoldReft, foldReft, foldReft'
-  , mapReft, mapReftM
+  , mapReft, mapReftM, mapPropM
   , mapBot, mapBind
 
   -- * ???
@@ -108,7 +124,6 @@
   , ignoreOblig
   , addInvCond
 
-
   -- * Inferred Annotations
   , AnnInfo (..)
   , Annot (..)
@@ -124,6 +139,7 @@
   , rTypeValueVar
   , rTypeReft
   , stripRTypeBase
+  , topRTypeBase
 
   -- * Class for values that can be pretty printed
   , PPrint (..), pprint
@@ -181,7 +197,7 @@
   , LogicMap(..), toLogicMap, eAppWithMap, LMap(..)
 
   -- * Refined Instances
-  , RDEnv, DEnv(..), RInstance(..)
+  , RDEnv, DEnv(..), RInstance(..), RISig(..)
 
   -- * Ureftable Instances
   , UReftable(..)
@@ -189,67 +205,63 @@
   -- * String Literals
   , liquidBegin, liquidEnd
 
-  , Axiom(..), HAxiom, LAxiom
+  , Axiom(..), HAxiom, AxiomEq(..)
+
+  , rtyVarUniqueSymbol, tyVarUniqueSymbol, rtyVarType
   )
   where
 
+import           Class
+import           CoreSyn                                (CoreBind, CoreExpr)
+import           Data.String
+import           DataCon
+import           GHC                                    (HscEnv, ModuleName, moduleNameString, getName)
+import           GHC.Generics
+import           Module                                 (moduleNameFS)
+import           NameSet
+import           PrelInfo                               (isNumericClass)
 import Prelude                          hiding  (error)
-import SrcLoc                                   (SrcSpan)
-import TyCon
-import DataCon
-import NameSet
-import Module                                   (moduleNameFS)
+import           SrcLoc                                 (SrcSpan)
+import           TyCon
+import           Type                                   (getClassPredTys_maybe)
 import TypeRep                          hiding  (maybeParen, pprArrowChain)
-import Var
-import GHC                                      (HscEnv, ModuleName, moduleNameString)
-import GHC.Generics
-import Class
-import CoreSyn (CoreBind, CoreExpr)
-import PrelInfo         (isNumericClass)
-import Type             (getClassPredTys_maybe)
-import TysPrim          (eqPrimTyCon)
-import TysWiredIn                               (listTyCon)
-
-
-import            Control.Monad                            (liftM, liftM2, liftM3, liftM4)
-
-
-import            Control.DeepSeq
+import           TysPrim                                (eqPrimTyCon)
+import           TysWiredIn                             (listTyCon, boolTyCon, eqTyCon)
+import           Var
 
-import            Data.Bifunctor
-import            Data.Bifunctor.TH
-import            Data.Typeable                            (Typeable)
-import            Data.Generics                            (Data)
+import           Control.Monad                          (liftM, liftM2, liftM3, liftM4)
+import           Control.DeepSeq
+import           Data.Bifunctor
+--import           Data.Bifunctor.TH
+import           Data.Typeable                          (Typeable)
+import           Data.Generics                          (Data)
+import qualified Data.Binary                            as B
+import qualified Data.Foldable                          as F
+import           Data.Hashable
+import qualified Data.HashMap.Strict                    as M
+import qualified Data.HashSet                           as S
+import           Data.Maybe                             (fromMaybe, mapMaybe)
 
+import           Data.List                              (nub)
+import           Data.Text                              (Text)
 
 
 
-import qualified  Data.Foldable as F
-import            Data.Hashable
-import qualified  Data.HashMap.Strict as M
-import qualified  Data.HashSet as S
-import            Data.Maybe                   (fromMaybe, mapMaybe)
-
-import            Data.List                    (nub)
-import            Data.Text                    (Text)
-import qualified  Data.Text                    as T
-
-
-import            Text.PrettyPrint.HughesPJ    hiding (first)
-import            Text.Printf
+import           Text.PrettyPrint.HughesPJ              hiding (first)
+import           Text.Printf
 
 import           Language.Fixpoint.Misc
-import           Language.Fixpoint.Types      hiding (Error, SrcSpan, Result, Predicate, R)
+import           Language.Fixpoint.Types                hiding (Error, SrcSpan, Result, Predicate, R)
 
 
 
 
-import Language.Haskell.Liquid.GHC.Misc
-import Language.Haskell.Liquid.Types.Variance
-import Language.Haskell.Liquid.Types.Errors
-import Language.Haskell.Liquid.Misc
-import Language.Haskell.Liquid.UX.Config
-import Data.Default
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types.Variance
+import           Language.Haskell.Liquid.Types.Errors
+import           Language.Haskell.Liquid.Misc
+import           Language.Haskell.Liquid.UX.Config
+import           Data.Default
 
 -----------------------------------------------------------------------------
 -- | Printer ----------------------------------------------------------------
@@ -261,10 +273,18 @@
        , ppSs    :: Bool
        , ppShort :: Bool
        }
+    deriving (Show)
 
+ppEnv :: PPEnv
 ppEnv           = ppEnvCurrent
+
+ppEnvCurrent :: PPEnv
 ppEnvCurrent    = PP False False False False
+
+_ppEnvPrintPreds :: PPEnv
 _ppEnvPrintPreds = PP False False False False
+
+ppEnvShort :: PPEnv -> PPEnv
 ppEnvShort pp   = pp { ppShort = True }
 
 
@@ -275,9 +295,10 @@
 
 data GhcInfo = GI {
     target   :: !FilePath
+  , targetMod:: !ModuleName
   , env      :: !HscEnv
   , cbs      :: ![CoreBind]
-  , derVars  :: ![Var]
+  , derVars  :: ![Var]          -- ^ ?
   , impVars  :: ![Var]
   , defVars  :: ![Var]
   , useVars  :: ![Var]
@@ -295,100 +316,115 @@
 -- parsing the target source and dependent libraries
 
 data GhcSpec = SP {
-    tySigs     :: ![(Var, Located SpecType)]     -- ^ Asserted Reftypes
-                                                 -- eg.  see include/Prelude.spec
-  , asmSigs    :: ![(Var, Located SpecType)]     -- ^ Assumed Reftypes
-  , inSigs     :: ![(Var, Located SpecType)]     -- ^ Auto generated Signatures 
-  , ctors      :: ![(Var, Located SpecType)]     -- ^ Data Constructor Measure Sigs
-                                                 -- eg.  (:) :: a -> xs:[a] -> {v: Int | v = 1 + len(xs) }
-  , meas       :: ![(Symbol, Located SpecType)]  -- ^ Measure Types
+    gsTySigs   :: ![(Var, LocSpecType)]          -- ^ Asserted Reftypes
+  , gsAsmSigs  :: ![(Var, LocSpecType)]          -- ^ Assumed Reftypes
+  , gsInSigs   :: ![(Var, LocSpecType)]          -- ^ Auto generated Signatures
+  , gsCtors    :: ![(Var, LocSpecType)]          -- ^ Data Constructor Measure Sigs
+  , gsLits     :: ![(Symbol, LocSpecType)]       -- ^ Literals/Constants
+                                                 -- e.g. datacons: EQ, GT, string lits: "zombie",...
+  , gsMeas     :: ![(Symbol, LocSpecType)]       -- ^ Measure Types
                                                  -- eg.  len :: [a] -> Int
-  , invariants :: ![Located SpecType]            -- ^ Data Type Invariants
+  , gsInvariants :: ![(Maybe Var, LocSpecType)]  -- ^ Data Type Invariants that came from the definition of var measure
                                                  -- eg.  forall a. {v: [a] | len(v) >= 0}
-  , ialiases   :: ![(Located SpecType, Located SpecType)] -- ^ Data Type Invariant Aliases
-  , dconsP     :: ![(DataCon, DataConP)]         -- ^ Predicated Data-Constructors
+  , gsIaliases   :: ![(LocSpecType, LocSpecType)]-- ^ Data Type Invariant Aliases
+  , gsDconsP     :: ![(DataCon, DataConP)]       -- ^ Predicated Data-Constructors
                                                  -- e.g. see tests/pos/Map.hs
-  , tconsP     :: ![(TyCon, TyConP)]             -- ^ Predicated Type-Constructors
+  , gsTconsP     :: ![(TyCon, TyConP)]           -- ^ Predicated Type-Constructors
                                                  -- eg.  see tests/pos/Map.hs
-  , freeSyms   :: ![(Symbol, Var)]               -- ^ List of `Symbol` free in spec and corresponding GHC var
+  , gsFreeSyms   :: ![(Symbol, Var)]             -- ^ List of `Symbol` free in spec and corresponding GHC var
                                                  -- eg. (Cons, Cons#7uz) from tests/pos/ex1.hs
-  , tcEmbeds   :: TCEmb TyCon                    -- ^ How to embed GHC Tycons into fixpoint sorts
+  , gsTcEmbeds   :: TCEmb TyCon                  -- ^ How to embed GHC Tycons into fixpoint sorts
                                                  -- e.g. "embed Set as Set_set" from include/Data/Set.spec
-  , qualifiers :: ![Qualifier]                   -- ^ Qualifiers in Source/Spec files
+  , gsQualifiers :: ![Qualifier]                 -- ^ Qualifiers in Source/Spec files
                                                  -- e.g tests/pos/qualTest.hs
-  , tgtVars    :: ![Var]                         -- ^ Top-level Binders To Verify (empty means ALL binders)
-  , decr       :: ![(Var, [Int])]                -- ^ Lexicographically ordered size witnesses for termination
-  , texprs     :: ![(Var, [Expr])]               -- ^ Lexicographically ordered expressions for termination
-  , lvars      :: !(S.HashSet Var)               -- ^ Variables that should be checked in the environment they are used
-  , lazy       :: !(S.HashSet Var)             -- ^ Binders to IGNORE during termination checking
-  , autosize   :: !(S.HashSet TyCon)             -- ^ Binders to IGNORE during termination checking
-  , config     :: !Config                        -- ^ Configuration Options
-  , exports    :: !NameSet                       -- ^ `Name`s exported by the module being verified
-  , measures   :: [Measure SpecType DataCon]
-  , tyconEnv   :: M.HashMap TyCon RTyCon
-  , dicts      :: DEnv Var SpecType              -- ^ Dictionary Environment
-  , axioms     :: [HAxiom]                       -- Axioms from axiomatized functions
-  , logicMap   :: LogicMap
-  , proofType  :: Maybe Type
+  , gsTgtVars    :: ![Var]                       -- ^ Top-level Binders To Verify (empty means ALL binders)
+  , gsDecr       :: ![(Var, [Int])]              -- ^ Lexicographically ordered size witnesses for termination
+  , gsTexprs     :: ![(Var, [Located Expr])]     -- ^ Lexicographically ordered expressions for termination
+  , gsNewTypes   :: ![(TyCon, LocSpecType)]      -- ^ Mapping of new type type constructors with their refined types.
+  , gsLvars      :: !(S.HashSet Var)             -- ^ Variables that should be checked in the environment they are used
+  , gsLazy       :: !(S.HashSet Var)             -- ^ Binders to IGNORE during termination checking
+  , gsAutosize   :: !(S.HashSet TyCon)           -- ^ Binders to IGNORE during termination checking
+  , gsAutoInst   :: !(M.HashMap Var (Maybe Int))  -- ^ Binders to expand with automatic axiom instances maybe with specified fuel
+  , gsConfig     :: !Config                      -- ^ Configuration Options
+  , gsExports   :: !NameSet                       -- ^ `Name`s exported by the module being verified
+  , gsMeasures  :: [Measure SpecType DataCon]
+  , gsTyconEnv  :: M.HashMap TyCon RTyCon
+  , gsDicts     :: DEnv Var SpecType              -- ^ Dictionary Environment
+  , gsAxioms    :: [AxiomEq]                      -- ^ Axioms from axiomatized functions
+  , gsReflects  :: [Var] -- [HAxiom]              -- ^ Binders for reflected functions
+  , gsLogicMap  :: LogicMap
+  , gsProofType :: Maybe Type
+  , gsRTAliases :: !RTEnv                         -- ^ Refinement type aliases
   }
 
 instance HasConfig GhcSpec where
-  getConfig = config
+  getConfig = gsConfig
 
-data LogicMap = LM { logic_map :: M.HashMap Symbol LMap
-                   , axiom_map :: M.HashMap Var Symbol
-                   } deriving (Show)
+data LogicMap = LM
+  { logic_map :: M.HashMap Symbol LMap
+  , axiom_map :: M.HashMap Var    Symbol
+  } deriving (Show)
 
 instance Monoid LogicMap where
   mempty                        = LM M.empty M.empty
   mappend (LM x1 x2) (LM y1 y2) = LM (M.union x1 y1) (M.union x2 y2)
 
-data LMap = LMap { lvar  :: Symbol
-                 , largs :: [Symbol]
-                 , lexpr :: Expr
-                 }
+data LMap = LMap
+  { lmVar  :: LocSymbol
+  , lmArgs :: [Symbol]
+  , lmExpr :: Expr
+  }
 
 instance Show LMap where
-  show (LMap x xs e) = show x ++ " " ++ show xs ++ "\t|->\t" ++ show e
-
+  show (LMap x xs e) = show x ++ " " ++ show xs ++ "\t |-> \t" ++ show e
 
+toLogicMap :: [(LocSymbol, [Symbol], Expr)] -> LogicMap
 toLogicMap ls = mempty {logic_map = M.fromList $ map toLMap ls}
   where
-    toLMap (x, xs, e) = (x, LMap {lvar = x, largs = xs, lexpr = e})
+    toLMap (x, ys, e) = (val x, LMap {lmVar = x, lmArgs = ys, lmExpr = e})
 
+eAppWithMap :: LogicMap -> Located Symbol -> [Expr] -> Expr -> Expr
 eAppWithMap lmap f es def
-  | Just (LMap _ xs e) <- M.lookup (val f) (logic_map lmap), length xs == length es 
+  | Just (LMap _ xs e) <- M.lookup (val f) (logic_map lmap)
+  , length xs == length es
+  -- NOPROP , length xs <= length es
   = subst (mkSubst $ zip xs es) e
-  | Just (LMap _ xs e) <- M.lookup (val f) (logic_map lmap), isApp e  
+  | Just (LMap _ xs e) <- M.lookup (val f) (logic_map lmap)
+  , isApp e
   = subst (mkSubst $ zip xs es) $ dropApp e (length xs - length es)
   | otherwise
   = def
 
-dropApp e i | i <= 0 = e 
+dropApp :: Expr -> Int -> Expr
+dropApp e i | i <= 0 = e
 dropApp (EApp e _) i = dropApp e (i-1)
 dropApp _ _          = errorstar "impossible"
- 
-isApp (EApp (EVar _) (EVar _)) = True 
-isApp (EApp e (EVar _))        = isApp e 
+
+isApp :: Expr -> Bool
+isApp (EApp (EVar _) (EVar _)) = True
+isApp (EApp e (EVar _))        = isApp e
 isApp _                        = False
 
-data TyConP = TyConP { freeTyVarsTy :: ![RTyVar]
-                     , freePredTy   :: ![PVar RSort]
-                     , freeLabelTy  :: ![Symbol]
-                     , varianceTs   :: !VarianceInfo
-                     , variancePs   :: !VarianceInfo
-                     , sizeFun      :: !(Maybe (Symbol -> Expr))
-                     } deriving (Generic, Data, Typeable)
+data TyConP = TyConP
+  { ty_loc       :: !SourcePos
+  , freeTyVarsTy :: ![RTyVar]
+  , freePredTy   :: ![PVar RSort]
+  , freeLabelTy  :: ![Symbol]
+  , varianceTs   :: !VarianceInfo
+  , variancePs   :: !VarianceInfo
+  , sizeFun      :: !(Maybe SizeFun)
+  } deriving (Generic, Data, Typeable)
 
-data DataConP = DataConP { dc_loc     :: !SourcePos
-                         , freeTyVars :: ![RTyVar]
-                         , freePred   :: ![PVar RSort]
-                         , freeLabels :: ![Symbol]
-                         , tyConsts   :: ![SpecType] -- FIXME: WHAT IS THIS??
-                         , tyArgs     :: ![(Symbol, SpecType)] -- FIXME: These are backwards, why??
-                         , tyRes      :: !SpecType
-                         , dc_locE    :: !SourcePos
-                         } deriving (Generic, Data, Typeable)
+data DataConP = DataConP
+  { dc_loc     :: !SourcePos
+  , freeTyVars :: ![RTyVar]
+  , freePred   :: ![PVar RSort]
+  , freeLabels :: ![Symbol]
+  , tyConsts   :: ![SpecType] -- FIXME: WHAT IS THIS??
+  , tyArgs     :: ![(Symbol, SpecType)] -- FIXME: These are backwards, why??
+  , tyRes      :: !SpecType
+  , dc_locE    :: !SourcePos
+  } deriving (Generic, Data, Typeable)
 
 
 -- | Which Top-Level Binders Should be Verified
@@ -412,7 +448,8 @@
 instance Ord (PVar t) where
   compare (PV n _ _ _)  (PV n' _ _ _) = compare n n'
 
-instance NFData t => NFData (PVar t)
+instance B.Binary t => B.Binary (PVar t)
+instance NFData t   => NFData   (PVar t)
 
 instance Hashable (PVar a) where
   hashWithSalt i (PV n _ _ _) = hashWithSalt i n
@@ -427,16 +464,20 @@
   | PVHProp
   deriving (Generic, Data, Typeable, Functor, F.Foldable, Traversable, Show)
 
-instance NFData a => NFData (PVKind a)
+instance B.Binary a => B.Binary (PVKind a)
+instance NFData a   => NFData   (PVKind a)
 
 
---------------------------------------------------------------------
------------------- Predicates --------------------------------------
---------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Predicates ----------------------------------------------------------------
+--------------------------------------------------------------------------------
 
 type UsedPVar      = PVar ()
+
 newtype Predicate  = Pr [UsedPVar] deriving (Generic, Data, Typeable)
 
+instance B.Binary Predicate
+
 instance NFData Predicate where
   rnf _ = ()
 
@@ -449,8 +490,13 @@
   mappend (MkUReft x y z) (MkUReft x' y' z') = MkUReft (mappend x x') (mappend y y') (mappend z z')
 
 
+pdTrue :: Predicate
 pdTrue         = Pr []
+
+pdAnd :: Foldable t => t Predicate -> Predicate
 pdAnd ps       = Pr (nub $ concatMap pvars ps)
+
+pvars :: Predicate -> [UsedPVar]
 pvars (Pr pvs) = pvs
 
 instance Subable UsedPVar where
@@ -467,25 +513,50 @@
   substa f (Pr pvs) = Pr (substa f <$> pvs)
 
 instance Subable Qualifier where
-  syms   = syms . q_body
+  syms   = syms . qBody
   subst  = mapQualBody . subst
   substf = mapQualBody . substf
   substa = mapQualBody . substa
 
-mapQualBody f q = q { q_body = f (q_body q) }
+mapQualBody :: (Expr -> Expr) -> Qualifier -> Qualifier
+mapQualBody f q = q { qBody = f (qBody q) }
 
 instance NFData r => NFData (UReft r)
 
-instance NFData RTyVar
 
+newtype BTyVar = BTV Symbol deriving (Show, Generic, Data, Typeable)
 
--- MOVE TO TYPES
 newtype RTyVar = RTV TyVar deriving (Generic, Data, Typeable)
 
+instance Eq BTyVar where
+  (BTV x) == (BTV y) = x == y
+
+instance Ord BTyVar where
+  compare (BTV x) (BTV y) = compare x y
+
+instance IsString BTyVar where
+  fromString = BTV . fromString
+
+instance B.Binary BTyVar
+instance Hashable BTyVar
+instance NFData   BTyVar
+instance NFData   RTyVar
+
+instance Symbolic BTyVar where
+  symbol (BTV tv) = tv
+
 instance Symbolic RTyVar where
-  symbol (RTV tv) = symbol . T.pack . showPpr $ tv
+  symbol (RTV tv) = symbol . getName $ tv
 
+data BTyCon = BTyCon
+  { btc_tc    :: !LocSymbol    -- ^ TyCon name with location information
+  , btc_class :: !Bool         -- ^ Is this a class type constructor?
+  , btc_prom  :: !Bool         -- ^ Is Promoted Data Con?
+  }
+  deriving (Generic, Data, Typeable)
 
+instance B.Binary BTyCon
+
 data RTyCon = RTyCon
   { rtc_tc    :: TyCon         -- ^ GHC Type Constructor
   , rtc_pvars :: ![RPVar]      -- ^ Predicate Parameters
@@ -493,30 +564,76 @@
   }
   deriving (Generic, Data, Typeable)
 
+instance Symbolic BTyCon where
+  symbol = val . btc_tc
+
+instance NFData BTyCon
+
 instance NFData RTyCon
 
+rtyVarUniqueSymbol  :: RTyVar -> Symbol
+rtyVarUniqueSymbol (RTV tv) = tyVarUniqueSymbol tv
+
+tyVarUniqueSymbol :: TyVar -> Symbol
+tyVarUniqueSymbol tv = symbol $ show (getName tv) ++ "_" ++ show (varUnique tv)
+
+
+rtyVarType :: RTyVar -> Type
+rtyVarType (RTV v) = TyVarTy v
+
+mkBTyCon :: LocSymbol -> BTyCon
+mkBTyCon x = BTyCon x False False
+
+mkClassBTyCon :: LocSymbol -> BTyCon
+mkClassBTyCon x = BTyCon x True False
+
+mkPromotedBTyCon :: LocSymbol -> BTyCon
+mkPromotedBTyCon x = BTyCon x False True
+
+
 -- | Accessors for @RTyCon@
 
+isBool :: RType RTyCon t t1 -> Bool
+isBool (RApp (RTyCon{rtc_tc = c}) _ _ _) = c == boolTyCon
+isBool _                                 = False
 
-isClassRTyCon = isClassTyCon . rtc_tc
+isRVar :: RType c tv r -> Bool
+isRVar (RVar _ _) = True
+isRVar _          = False
+
+isClassBTyCon :: BTyCon -> Bool
+isClassBTyCon = btc_class
+
+isClassRTyCon :: RTyCon -> Bool
+isClassRTyCon x = (isClassTyCon $ rtc_tc x) || (rtc_tc x == eqTyCon)
+
+rTyConPVs :: RTyCon -> [RPVar]
 rTyConPVs     = rtc_pvars
+
+rTyConPropVs :: RTyCon -> [PVar RSort]
 rTyConPropVs  = filter isPropPV . rtc_pvars
+
+isPropPV :: PVar t -> Bool
 isPropPV      = isProp . ptype
 
+isEqType :: TyConable c => RType c t t1 -> Bool
 isEqType (RApp c _ _ _) = isEqual c
 isEqType _              = False
 
 
+isClassType :: TyConable c => RType c t t1 -> Bool
 isClassType (RApp c _ _ _) = isClass c
 isClassType _              = False
 
 -- rTyConPVHPs = filter isHPropPV . rtc_pvars
 -- isHPropPV   = not . isPropPV
 
+isProp :: PVKind t -> Bool
 isProp (PVProp _) = True
 isProp _          = False
 
 
+defaultTyConInfo :: TyConInfo
 defaultTyConInfo = TyConInfo [] [] Nothing
 
 instance Default TyConInfo where
@@ -540,9 +657,9 @@
 --
 
 data TyConInfo = TyConInfo
-  { varianceTyArgs  :: !VarianceInfo             -- ^ variance info for type variables
-  , variancePsArgs  :: !VarianceInfo             -- ^ variance info for predicate variables
-  , sizeFunction    :: !(Maybe (Symbol -> Expr)) -- ^ logical function that computes the size of the structure
+  { varianceTyArgs  :: !VarianceInfo      -- ^ variance info for type variables
+  , variancePsArgs  :: !VarianceInfo      -- ^ variance info for predicate variables
+  , sizeFunction    :: !(Maybe SizeFun)   -- ^ logical UNARY function that computes the size of the structure
   } deriving (Generic, Data, Typeable)
 
 instance NFData TyConInfo
@@ -553,8 +670,9 @@
 --------------------------------------------------------------------
 ---- Unified Representation of Refinement Types --------------------
 --------------------------------------------------------------------
+type RTVU c tv = RTVar tv (RType c tv ())
+type PVU  c tv = PVar     (RType c tv ())
 
--- MOVE TO TYPES
 data RType c tv r
   = RVar {
       rt_var    :: !tv
@@ -569,15 +687,19 @@
     }
 
   | RAllT {
-      rt_tvbind :: !tv
+      rt_tvbind :: !(RTVU c tv) -- RTVar tv (RType c tv ()))
     , rt_ty     :: !(RType c tv r)
     }
 
+  -- | "forall x y <z :: Nat, w :: Int> . TYPE"
+  --               ^^^^^^^^^^^^^^^^^^^ (rt_pvbind)
   | RAllP {
-      rt_pvbind :: !(PVar (RType c tv ()))
+      rt_pvbind :: !(PVU c tv)  -- ar (RType c tv ()))
     , rt_ty     :: !(RType c tv r)
     }
 
+  -- | "forall <z w> . TYPE"
+  --           ^^^^^ (rt_sbind)
   | RAllS {
       rt_sbind  :: !(Symbol)
     , rt_ty     :: !(RType c tv r)
@@ -621,12 +743,57 @@
             --   see tests/pos/Holes.hs
   deriving (Generic, Data, Typeable, Functor)
 
-instance (NFData c, NFData tv, NFData r) => NFData (RType c tv r)
+instance (B.Binary c, B.Binary tv, B.Binary r) => B.Binary (RType c tv r)
+instance (NFData c, NFData tv, NFData r)       => NFData (RType c tv r)
 
+ignoreOblig :: RType t t1 t2 -> RType t t1 t2
 ignoreOblig (RRTy _ _ _ t) = t
 ignoreOblig t              = t
 
 
+makeRTVar :: tv -> RTVar tv s
+makeRTVar a = RTVar a RTVNoInfo
+
+instance (Eq tv) => Eq (RTVar tv s) where
+  t1 == t2 = (ty_var_value t1) == (ty_var_value t2)
+
+data RTVar tv s = RTVar
+  { ty_var_value :: tv
+  , ty_var_info  :: RTVInfo s
+  } deriving (Generic, Data, Typeable)
+
+mapTyVarValue :: (tv1 -> tv2) -> RTVar tv1 s -> RTVar tv2 s
+mapTyVarValue f v = v {ty_var_value = f $ ty_var_value v}
+
+dropTyVarInfo :: RTVar tv s1 -> RTVar tv s2
+dropTyVarInfo v = v{ty_var_info = RTVNoInfo}
+
+data RTVInfo s
+  = RTVNoInfo
+  | RTVInfo { rtv_name   :: Symbol
+            , rtv_kind   :: s
+            , rtv_is_val :: Bool
+            } deriving (Generic, Data, Typeable, Functor)
+
+
+rTVarToBind :: RTVar RTyVar s  -> Maybe (Symbol, s)
+rTVarToBind = go . ty_var_info
+  where
+    go (RTVInfo {..}) | rtv_is_val = Just (rtv_name, rtv_kind)
+    go _                           = Nothing
+
+ty_var_is_val :: RTVar tv s -> Bool
+ty_var_is_val = rtvinfo_is_val . ty_var_info
+
+rtvinfo_is_val :: RTVInfo s -> Bool
+rtvinfo_is_val RTVNoInfo      = False
+rtvinfo_is_val (RTVInfo {..}) = rtv_is_val
+
+instance (B.Binary tv, B.Binary s) => B.Binary (RTVar tv s)
+instance (NFData tv, NFData s)     => NFData   (RTVar tv s)
+instance (NFData s)                => NFData   (RTVInfo s)
+instance (B.Binary s)              => B.Binary (RTVInfo s)
+
 -- | @Ref@ describes `Prop τ` and `HProp` arguments applied to type constructors.
 --   For example, in [a]<{\h -> v > h}>, we apply (via `RApp`)
 --   * the `RProp`  denoted by `{\h -> v > h}` to
@@ -641,8 +808,10 @@
   , rf_body :: t -- ^ Abstract refinement associated with `RTyCon`
   } deriving (Generic, Data, Typeable, Functor)
 
-instance (NFData τ, NFData t) => NFData (Ref τ t)
+instance (B.Binary τ, B.Binary t) => B.Binary (Ref τ t)
+instance (NFData τ,   NFData t)   => NFData   (Ref τ t)
 
+rPropP :: [(Symbol, τ)] -> r -> Ref τ (RType c tv r)
 rPropP τ r = RProp τ (RHole r)
 
 -- | @RTProp@ is a convenient alias for @Ref@ that will save a bunch of typing.
@@ -662,36 +831,44 @@
                 | HVar UsedPVar
                 deriving (Generic, Data, Typeable)
 
-data UReft r
-  = MkUReft { ur_reft   :: !r
-            , ur_pred   :: !Predicate
-            , ur_strata :: !Strata
-            }
-    deriving (Generic, Data, Typeable, Functor)
+data UReft r = MkUReft
+  { ur_reft   :: !r
+  , ur_pred   :: !Predicate
+  , ur_strata :: !Strata
+  }
+  deriving (Generic, Data, Typeable, Functor, Foldable, Traversable)
 
-type BRType     = RType LocSymbol Symbol
-type RRType     = RType RTyCon    RTyVar
+instance B.Binary r => B.Binary (UReft r)
 
+type BRType     = RType BTyCon BTyVar
+type RRType     = RType RTyCon RTyVar
+
 type BSort      = BRType    ()
 type RSort      = RRType    ()
 
 type BPVar      = PVar      BSort
 type RPVar      = PVar      RSort
 
-type RReft      = UReft     Reft
-type PrType     = RRType    Predicate
-type BareType   = BRType    RReft
-type SpecType   = RRType    RReft
-type SpecProp   = RRProp    RReft
-type RRProp r   = Ref       RSort (RRType r)
+type RReft       = UReft     Reft
+type PrType      = RRType    Predicate
+type BareType    = BRType    RReft
+type SpecType    = RRType    RReft
+type SpecProp    = RRProp    RReft
+type RRProp r    = Ref       RSort (RRType r)
+type BRProp r    = Ref       BSort (BRType r)
 
+type LocBareType = Located BareType
+type LocSpecType = Located SpecType
 
 data Stratum    = SVar Symbol | SDiv | SWhnf | SFin
                   deriving (Generic, Data, Typeable, Eq)
-instance NFData Stratum
 
+instance NFData   Stratum
+instance B.Binary Stratum
+
 type Strata = [Stratum]
 
+isSVar :: Stratum -> Bool
 isSVar (SVar _) = True
 isSVar _        = False
 
@@ -718,22 +895,21 @@
   isNumCls  = const False
   isFracCls = const False
 
-class ( TyConable c
-      , Eq c, Eq tv
-      , Hashable tv
-      , Reftable r
-      , PPrint r
-      ) => RefTypable c tv r
-  where
-    ppRType  :: Prec -> RType c tv r -> Doc
 
+-- Should just make this a @Pretty@ instance but its too damn tedious
+-- to figure out all the constraints.
 
+type OkRT c tv r = ( TyConable c
+                   , PPrint tv, PPrint c, PPrint r
+                   , Reftable r, Reftable (RTProp c tv ()), Reftable (RTProp c tv r)
+                   , Eq c, Eq tv
+                   , Hashable tv
+                   )
 
 -------------------------------------------------------------------------------
 -- | TyConable Instances -------------------------------------------------------
 -------------------------------------------------------------------------------
 
--- MOVE TO TYPES
 instance TyConable RTyCon where
   isFun      = isFunTyCon . rtc_tc
   isList     = (listTyCon ==) . rtc_tc
@@ -747,6 +923,22 @@
   isFracCls c = maybe False (isClassOrSubClass isFractionalClass)
                 (tyConClass_maybe $ rtc_tc c)
 
+
+instance TyConable TyCon where
+  isFun      = isFunTyCon
+  isList     = (listTyCon ==)
+  isTuple    = TyCon.isTupleTyCon
+  isClass c  = isClassTyCon c || c == eqTyCon
+  isEqual    = (eqPrimTyCon ==)
+  ppTycon    = text . showPpr
+
+  isNumCls c  = maybe False (isClassOrSubClass isNumericClass)
+                (tyConClass_maybe $ c)
+  isFracCls c = maybe False (isClassOrSubClass isFractionalClass)
+                (tyConClass_maybe $ c)
+
+
+isClassOrSubClass :: (Class -> Bool) -> Class -> Bool
 isClassOrSubClass p cls
   = p cls || any (isClassOrSubClass p . fst)
                  (mapMaybe getClassPredTys_maybe (classSCTheta cls))
@@ -764,35 +956,60 @@
   isTuple = isTuple . val
   ppTycon = ppTycon . val
 
+instance TyConable BTyCon where
+  isFun   = isFun . btc_tc
+  isList  = isList . btc_tc
+  isTuple = isTuple . btc_tc
+  isClass = isClassBTyCon
+  ppTycon = ppTycon . btc_tc
 
+
 instance Eq RTyCon where
   x == y = rtc_tc x == rtc_tc y
 
+instance Eq BTyCon where
+  x == y = btc_tc x == btc_tc y
+
 instance Fixpoint RTyCon where
-  toFix (RTyCon c _ _) = text $ showPpr c -- <+> text "\n<<" <+> hsep (map toFix ts) <+> text ">>\n"
+  toFix (RTyCon c _ _) = text $ showPpr c
 
+instance Fixpoint BTyCon where
+  toFix = text . symbolString . val . btc_tc
+
 instance Fixpoint Cinfo where
   toFix = text . showPpr . ci_loc
 
 instance PPrint RTyCon where
   pprintTidy _ = text . showPpr . rtc_tc
 
+instance PPrint BTyCon where
+  pprintTidy _ = text . symbolString . val . btc_tc
 
 instance Show RTyCon where
   show = showpp
 
+instance Show BTyCon where
+  show = showpp
+
 --------------------------------------------------------------------------
 -- | Refined Instances ---------------------------------------------------
 --------------------------------------------------------------------------
 
 data RInstance t = RI
-  { riclass :: LocSymbol
-  , ritype  :: t
-  , risigs  :: [(LocSymbol, t)]
-  } deriving Functor
+  { riclass :: BTyCon
+  , ritype  :: [t]
+  , risigs  :: [(LocSymbol, RISig t)]
+  } deriving (Generic, Functor, Data, Typeable, Show)
 
-newtype DEnv x ty = DEnv (M.HashMap x (M.HashMap Symbol ty)) deriving (Monoid)
+data RISig t = RIAssumed t | RISig t
+  deriving (Generic, Functor, Data, Typeable, Show)
 
+instance (B.Binary t) => B.Binary (RInstance t)
+instance (B.Binary t) => B.Binary (RISig t)
+
+newtype DEnv x ty = DEnv (M.HashMap x (M.HashMap Symbol (RISig ty)))
+                    deriving (Monoid, Show)
+
 type RDEnv = DEnv Var SpecType
 
 
@@ -800,54 +1017,65 @@
 -- | Values Related to Specifications ------------------------------------
 --------------------------------------------------------------------------
 
-data Axiom b s e = Axiom { aname  :: (Var, Maybe DataCon)
-                         , abinds :: [b]
-                         , atypes :: [s]
-                         , alhs   :: e
-                         , arhs   :: e
-                         }
-type HAxiom = Axiom Var Type CoreExpr
-type LAxiom = Axiom Symbol Sort Expr
+data Axiom b s e = Axiom
+  { aname  :: (Var, Maybe DataCon)
+  , rname  :: Maybe b
+  , abinds :: [b]
+  , atypes :: [s]
+  , alhs   :: e
+  , arhs   :: e
+  }
 
+type HAxiom = Axiom Var    Type CoreExpr
+data AxiomEq = AxiomEq { axiomName :: Symbol
+                       , axiomArgs :: [Symbol]
+                       , axiomBody :: Expr
+                       , axiomEq   :: Expr
+                       }
 
 instance Show (Axiom Var Type CoreExpr) where
-  show (Axiom (n, c) bs _ts lhs rhs) = "Axiom : " ++
-                                       "\nFun Name: " ++ (showPpr n) ++
-                                       "\nData Con: " ++ (showPpr c) ++
-                                       "\nArguments:" ++ (showPpr bs)  ++
-                                       -- "\nTypes    :" ++ (showPpr ts)  ++
-                                       "\nLHS      :" ++ (showPpr lhs) ++
-                                       "\nRHS      :" ++ (showPpr rhs)
+  show (Axiom (n, c) v bs _ts lhs rhs) = "Axiom : " ++
+                                         "\nFun Name: " ++ (showPpr n) ++
+                                         "\nReal Name: " ++ (showPpr v) ++
+                                         "\nData Con: " ++ (showPpr c) ++
+                                         "\nArguments:" ++ (showPpr bs)  ++
+                                         -- "\nTypes    :" ++ (showPpr ts)  ++
+                                         "\nLHS      :" ++ (showPpr lhs) ++
+                                         "\nRHS      :" ++ (showPpr rhs)
 
 --------------------------------------------------------------------------
 -- | Values Related to Specifications ------------------------------------
 --------------------------------------------------------------------------
+data SizeFun
+  = IdSizeFun            -- ^ \x -> EVar x
+  | SymSizeFun LocSymbol -- ^ \x -> f x
+  deriving (Data, Typeable, Generic)
 
+szFun :: SizeFun -> Symbol -> Expr
+szFun IdSizeFun      = EVar
+szFun (SymSizeFun f) = \x -> mkEApp (symbol <$> f) [EVar x]
 
+instance NFData   SizeFun
+instance B.Binary SizeFun
+
 -- | Data type refinements
-data DataDecl   = D { tycName   :: LocSymbol
-                                -- ^ Type  Constructor Name
-                    , tycTyVars :: [Symbol]
-                                -- ^ Tyvar Parameters
-                    , tycPVars  :: [PVar BSort]
-                                -- ^ PVar  Parameters
-                    , tycTyLabs :: [Symbol]
-                                -- ^ PLabel  Parameters
-                    , tycDCons  :: [(LocSymbol, [(Symbol, BareType)])]
-                                -- ^ [DataCon, [(fieldName, fieldType)]]
-                    , tycSrcPos :: !SourcePos
-                                -- ^ Source Position
-                    , tycSFun   :: (Maybe (Symbol -> Expr))
-                                -- ^ Measure that should decrease in recursive calls
-                    }
-     --              deriving (Show)
+data DataDecl   = D
+  { tycName   :: LocSymbol                           -- ^ Type  Constructor Name
+  , tycTyVars :: [Symbol]                            -- ^ Tyvar Parameters
+  , tycPVars  :: [PVar BSort]                        -- ^ PVar  Parameters
+  , tycTyLabs :: [Symbol]                            -- ^ PLabel  Parameters
+  , tycDCons  :: [(LocSymbol, [(Symbol, BareType)])] -- ^ [DataCon, [(fieldName, fieldType)]]
+  , tycSrcPos :: !SourcePos                          -- ^ Source Position
+  , tycSFun   :: Maybe SizeFun                       -- ^ Measure that should decrease in recursive calls
+  } deriving (Data, Typeable, Generic)
 
+instance B.Binary DataDecl
 
 instance Eq DataDecl where
-   d1 == d2 = tycName d1 == tycName d2
+  d1 == d2 = tycName d1 == tycName d2
 
 instance Ord DataDecl where
-   compare d1 d2 = compare (tycName d1) (tycName d2)
+  compare d1 d2 = compare (tycName d1) (tycName d2)
 
 -- | For debugging.
 instance Show DataDecl where
@@ -856,34 +1084,41 @@
               (show $ tycTyVars dd)
 
 -- | Refinement Type Aliases
+data RTAlias x a = RTA
+  { rtName  :: Symbol             -- ^ name of the alias
+  , rtTArgs :: [x]                -- ^ type parameters
+  , rtVArgs :: [x]                -- ^ value parameters
+  , rtBody  :: a                  -- ^ what the alias expands to
+  , rtPos   :: SourcePos          -- ^ start position
+  , rtPosE  :: SourcePos          -- ^ end   position
+  } deriving (Data, Typeable, Generic)
 
-data RTAlias tv ty
-  = RTA { rtName  :: Symbol
-        , rtTArgs :: [tv]
-        , rtVArgs :: [tv]
-        , rtBody  :: ty
-        , rtPos   :: SourcePos
-        , rtPosE  :: SourcePos
-        }
+instance (B.Binary x, B.Binary a) => B.Binary (RTAlias x a)
 
+mapRTAVars :: (a -> tv) -> RTAlias a ty -> RTAlias tv ty
 mapRTAVars f rt = rt { rtTArgs = f <$> rtTArgs rt
                      , rtVArgs = f <$> rtVArgs rt
                      }
 
-------------------------------------------------------------------------
--- | Constructor and Destructors for RTypes ----------------------------
-------------------------------------------------------------------------
+lmapEAlias :: LMap -> RTAlias Symbol Expr
+lmapEAlias (LMap v ys e) = RTA (val v) [] ys e (loc v) (loc v)
 
-data RTypeRep c tv r
-  = RTypeRep { ty_vars   :: [tv]
-             , ty_preds  :: [PVar (RType c tv ())]
-             , ty_labels :: [Symbol]
-             , ty_binds  :: [Symbol]
-             , ty_refts  :: [r]
-             , ty_args   :: [RType c tv r]
-             , ty_res    :: (RType c tv r)
-             }
 
+--------------------------------------------------------------------------------
+-- | Constructor and Destructors for RTypes ------------------------------------
+--------------------------------------------------------------------------------
+
+data RTypeRep c tv r = RTypeRep
+  { ty_vars   :: [RTVar tv (RType c tv ())]
+  , ty_preds  :: [PVar (RType c tv ())]
+  , ty_labels :: [Symbol]
+  , ty_binds  :: [Symbol]
+  , ty_refts  :: [r]
+  , ty_args   :: [RType c tv r]
+  , ty_res    :: (RType c tv r)
+  }
+
+fromRTypeRep :: RTypeRep c tv r -> RType c tv r
 fromRTypeRep (RTypeRep {..})
   = mkArrow ty_vars ty_preds ty_labels arrs ty_res
   where
@@ -895,32 +1130,50 @@
     (αs, πs, ls, t')  = bkUniv  t
     (xs, ts, rs, t'') = bkArrow t'
 
+mkArrow :: (Foldable t, Foldable t1, Foldable t2, Foldable t3)
+        => t  (RTVar tv (RType c tv ()))
+        -> t1 (PVar (RType c tv ()))
+        -> t2 Symbol
+        -> t3 (Symbol, RType c tv r, r)
+        -> RType c tv r
+        -> RType c tv r
 mkArrow αs πs ls xts = mkUnivs αs πs ls . mkArrs xts
   where
     mkArrs xts t  = foldr (\(b,t1,r) t2 -> RFun b t1 t2 r) t xts
 
+bkArrowDeep :: RType t t1 a -> ([Symbol], [RType t t1 a], [a], RType t t1 a)
 bkArrowDeep (RAllT _ t)     = bkArrowDeep t
 bkArrowDeep (RAllP _ t)     = bkArrowDeep t
 bkArrowDeep (RAllS _ t)     = bkArrowDeep t
 bkArrowDeep (RFun x t t' r) = let (xs, ts, rs, t'') = bkArrowDeep t'  in (x:xs, t:ts, r:rs, t'')
 bkArrowDeep t               = ([], [], [], t)
 
+bkArrow :: RType t t1 a -> ([Symbol], [RType t t1 a], [a], RType t t1 a)
 bkArrow (RFun x t t' r) = let (xs, ts, rs, t'') = bkArrow t'  in (x:xs, t:ts, r:rs, t'')
 bkArrow t               = ([], [], [], t)
 
+safeBkArrow :: RType t t1 a -> ([Symbol], [RType t t1 a], [a], RType t t1 a)
 safeBkArrow (RAllT _ _) = panic Nothing "safeBkArrow on RAllT"
 safeBkArrow (RAllP _ _) = panic Nothing "safeBkArrow on RAllP"
 safeBkArrow (RAllS _ t) = safeBkArrow t
 safeBkArrow t           = bkArrow t
 
+mkUnivs :: (Foldable t, Foldable t1, Foldable t2)
+        => t  (RTVar tv (RType c tv ()))
+        -> t1 (PVar (RType c tv ()))
+        -> t2 Symbol
+        -> RType c tv r
+        -> RType c tv r
 mkUnivs αs πs ls t = foldr RAllT (foldr RAllP (foldr RAllS t ls) πs) αs
 
-bkUniv :: RType t1 a t2 -> ([a], [PVar (RType t1 a ())], [Symbol], RType t1 a t2)
+bkUniv :: RType t1 a t2 -> ([RTVar a (RType t1 a ())], [PVar (RType t1 a ())], [Symbol], RType t1 a t2)
 bkUniv (RAllT α t)      = let (αs, πs, ls, t') = bkUniv t in  (α:αs, πs, ls, t')
 bkUniv (RAllP π t)      = let (αs, πs, ls, t') = bkUniv t in  (αs, π:πs, ls, t')
 bkUniv (RAllS s t)      = let (αs, πs, ss, t') = bkUniv t in  (αs, πs, s:ss, t')
 bkUniv t                = ([], [], [], t)
 
+bkClass :: TyConable c
+        => RType c tv r -> ([(c, [RType c tv r])], RType c tv r)
 bkClass (RFun _ (RApp c t _ _) t' _)
   | isClass c
   = let (cs, t'') = bkClass t' in ((c, t):cs, t'')
@@ -929,8 +1182,14 @@
 bkClass t
   = ([], t)
 
+rFun :: Monoid r
+     => Symbol -> RType c tv r -> RType c tv r -> RType c tv r
 rFun b t t' = RFun b t t' mempty
+
+rCls :: Monoid r => TyCon -> [RType RTyCon tv r] -> RType RTyCon tv r
 rCls c ts   = RApp (RTyCon c [] defaultTyConInfo) ts [] mempty
+
+rRCls :: Monoid r => c -> [RType c tv r] -> RType c tv r
 rRCls rc ts = RApp rc ts [] mempty
 
 addInvCond :: SpecType -> RReft -> SpecType
@@ -994,16 +1253,25 @@
 
   ofReft r = MkUReft (ofReft r) mempty mempty
 
+instance Expression (UReft ()) where
+  expr = expr . toReft
+
+
+
+isTauto_ureft :: Reftable r => UReft r -> Bool
 isTauto_ureft u      = isTauto (ur_reft u) && isTauto (ur_pred u) -- && (isTauto $ ur_strata u)
 
+ppTy_ureft :: Reftable r => UReft r -> Doc -> Doc
 ppTy_ureft u@(MkUReft r p s) d
   | isTauto_ureft  u  = d
   | otherwise         = ppr_reft r (ppTy p d) s
 
+ppr_reft :: (PPrint [t], Reftable r) => r -> Doc -> [t] -> Doc
 ppr_reft r d s       = braces (pprint v <+> colon <+> d <> ppr_str s <+> text "|" <+> pprint r')
   where
     r'@(Reft (v, _)) = toReft r
 
+ppr_str :: PPrint [t] => [t] -> Doc
 ppr_str [] = empty
 ppr_str s  = text "^" <> pprint s
 
@@ -1013,7 +1281,7 @@
   substf f (MkUReft r z l) = MkUReft (substf f r) (substf f z) (substf f l)
   substa f (MkUReft r z l) = MkUReft (substa f r) (substa f z) (substa f l)
 
-instance (Reftable r, RefTypable c tv r) => Subable (RTProp c tv r) where
+instance (Reftable r, TyConable c) => Subable (RTProp c tv r) where
   syms (RProp  ss r)     = (fst <$> ss) ++ syms r
 
   subst su (RProp ss (RHole r)) = RProp ss (RHole (subst su r))
@@ -1026,16 +1294,13 @@
   substa f (RProp  ss t) = RProp ss (substa f <$> t)
 
 
-instance (Subable r, RefTypable c tv r) => Subable (RType c tv r) where
+instance (Subable r, Reftable r, TyConable c) => Subable (RType c tv r) where
   syms        = foldReft (\_ r acc -> syms r ++ acc) []
   substa f    = mapReft (substa f)
   substf f    = emapReft (substf . substfExcept f) []
   subst su    = emapReft (subst  . substExcept su) []
   subst1 t su = emapReft (\xs r -> subst1Except xs r su) [] t
 
-
-
-
 instance Reftable Predicate where
   isTauto (Pr ps)      = null ps
 
@@ -1052,29 +1317,31 @@
 
   ofReft = todo Nothing "TODO: Predicate.ofReft"
 
+pToRef :: PVar a -> Expr
 pToRef p = pApp (pname p) $ (EVar $ parg p) : (thd3 <$> pargs p)
 
 pApp      :: Symbol -> [Expr] -> Expr
 pApp p es = mkEApp (dummyLoc $ pappSym $ length es) (EVar p:es)
 
+pappSym :: Show a => a -> Symbol
 pappSym n  = symbol $ "papp" ++ show n
 
 ---------------------------------------------------------------
 --------------------------- Visitors --------------------------
 ---------------------------------------------------------------
 
+isTrivial :: (Reftable r, TyConable c) => RType c tv r -> Bool
 isTrivial t = foldReft (\_ r b -> isTauto r && b) True t
 
 mapReft ::  (r1 -> r2) -> RType c tv r1 -> RType c tv r2
 mapReft f = emapReft (\_ -> f) []
 
 emapReft ::  ([Symbol] -> r1 -> r2) -> [Symbol] -> RType c tv r1 -> RType c tv r2
-
 emapReft f γ (RVar α r)          = RVar  α (f γ r)
 emapReft f γ (RAllT α t)         = RAllT α (emapReft f γ t)
 emapReft f γ (RAllP π t)         = RAllP π (emapReft f γ t)
 emapReft f γ (RAllS p t)         = RAllS p (emapReft f γ t)
-emapReft f γ (RFun x t t' r)     = RFun  x (emapReft f γ t) (emapReft f (x:γ) t') (f γ r)
+emapReft f γ (RFun x t t' r)     = RFun  x (emapReft f γ t) (emapReft f (x:γ) t') (f (x:γ) r)
 emapReft f γ (RApp c ts rs r)    = RApp  c (emapReft f γ <$> ts) (emapRef f γ <$> rs) (f γ r)
 emapReft f γ (RAllE z t t')      = RAllE z (emapReft f γ t) (emapReft f γ t')
 emapReft f γ (REx z t t')        = REx   z (emapReft f γ t) (emapReft f γ t')
@@ -1096,6 +1363,7 @@
 -- set all types to basic types, haskell `tx -> t` is translated to Arrow tx t
 -- isBase _ = True
 
+isBase :: RType t t1 t2 -> Bool
 isBase (RAllT _ t)      = isBase t
 isBase (RAllP _ t)      = isBase t
 isBase (RVar _ _)       = True
@@ -1104,8 +1372,10 @@
 isBase (RAppTy t1 t2 _) = isBase t1 && isBase t2
 isBase (RRTy _ _ _ t)   = isBase t
 isBase (RAllE _ _ t)    = isBase t
+isBase (REx _ _ t)      = isBase t
 isBase _                = False
 
+isFunTy :: RType t t1 t2 -> Bool
 isFunTy (RAllE _ _ t)    = isFunTy t
 isFunTy (RAllS _ t)      = isFunTy t
 isFunTy (RAllT _ t)      = isFunTy t
@@ -1131,7 +1401,21 @@
 mapRefM  :: (Monad m) => (t -> m s) -> (RTProp c tv t) -> m (RTProp c tv s)
 mapRefM  f (RProp s t)         = liftM   (RProp s)      (mapReftM f t)
 
+mapPropM :: (Monad m) => (RTProp c tv r -> m (RTProp c tv r)) -> RType c tv r -> m (RType c tv r)
+mapPropM _ (RVar α r)         = return $ RVar  α r
+mapPropM f (RAllT α t)        = liftM   (RAllT α)   (mapPropM f t)
+mapPropM f (RAllP π t)        = liftM   (RAllP π)   (mapPropM f t)
+mapPropM f (RAllS s t)        = liftM   (RAllS s)   (mapPropM f t)
+mapPropM f (RFun x t t' r)    = liftM3  (RFun x)    (mapPropM f t)          (mapPropM f t') (return r)
+mapPropM f (RApp c ts rs r)   = liftM3  (RApp  c)   (mapM (mapPropM f) ts)  (mapM f rs)     (return r)
+mapPropM f (RAllE z t t')     = liftM2  (RAllE z)   (mapPropM f t)          (mapPropM f t')
+mapPropM f (REx z t t')       = liftM2  (REx z)     (mapPropM f t)          (mapPropM f t')
+mapPropM _ (RExprArg e)       = return  $ RExprArg e
+mapPropM f (RAppTy t t' r)    = liftM3  RAppTy (mapPropM f t) (mapPropM f t') (return r)
+mapPropM _ (RHole r)          = return $ RHole r
+mapPropM f (RRTy xts r o t)   = liftM4  RRTy (mapM (mapSndM (mapPropM f)) xts) (return r) (return o) (mapPropM f t)
 
+
 --------------------------------------------------------------------------------
 -- foldReft :: (Reftable r, TyConable c) => (r -> a -> a) -> a -> RType c tv r -> a
 --------------------------------------------------------------------------------
@@ -1140,30 +1424,45 @@
 --------------------------------------------------------------------------------
 foldReft :: (Reftable r, TyConable c) => (SEnv (RType c tv r) -> r -> a -> a) -> a -> RType c tv r -> a
 --------------------------------------------------------------------------------
-foldReft f = foldReft' id (\γ _ -> f γ)
+foldReft  f = foldReft' (\_ _ -> False) id (\γ _ -> f γ)
 
 --------------------------------------------------------------------------------
 foldReft' :: (Reftable r, TyConable c)
-          => (RType c tv r -> b)
+          => (Symbol -> RType c tv r -> Bool)
+          -> (RType c tv r -> b)
           -> (SEnv b -> Maybe (RType c tv r) -> r -> a -> a)
           -> a -> RType c tv r -> a
 --------------------------------------------------------------------------------
-foldReft' g f = efoldReft (\_ _ -> []) g (\γ t r z -> f γ t r z) (\_ γ -> γ) emptySEnv
+foldReft' logicBind g f = efoldReft logicBind (\_ _ -> []) (\_ -> []) g (\γ t r z -> f γ t r z) (\_ γ -> γ) emptySEnv
 
 
 
 -- efoldReft :: Reftable r =>(p -> [RType c tv r] -> [(Symbol, a)])-> (RType c tv r -> a)-> (SEnv a -> Maybe (RType c tv r) -> r -> c1 -> c1)-> SEnv a-> c1-> RType c tv r-> c1
-efoldReft cb g f fp = go
+efoldReft :: (Reftable r, TyConable c)
+          => (Symbol -> RType c tv r -> Bool)
+          -> (c  -> [RType c tv r] -> [(Symbol, a)])
+          -> (RTVar tv (RType c tv ()) -> [(Symbol, a)])
+          -> (RType c tv r -> a)
+          -> (SEnv a -> Maybe (RType c tv r) -> r -> b -> b)
+          -> (PVar (RType c tv ()) -> SEnv a -> SEnv a)
+          -> SEnv a
+          -> b
+          -> RType c tv r
+          -> b
+efoldReft logicBind cb dty g f fp = go
   where
     -- folding over RType
     go γ z me@(RVar _ r)                = f γ (Just me) r z
-    go γ z (RAllT _ t)                  = go γ z t
+    go γ z (RAllT a t)
+       | ty_var_is_val a                = go (insertsSEnv γ (dty a)) z t
+       | otherwise                      = go γ z t
     go γ z (RAllP p t)                  = go (fp p γ) z t
     go γ z (RAllS _ t)                  = go γ z t
     go γ z me@(RFun _ (RApp c ts _ _) t' r)
        | isClass c                      = f γ (Just me) r (go (insertsSEnv γ (cb c ts)) (go' γ z ts) t')
-    go γ z me@(RFun x t t' r)           = f γ (Just me) r (go (insertSEnv x (g t) γ) (go γ z t) t')
---     go γ z me@(RFun _ t t' r)           = f γ (Just me) r (go γ (go γ z t) t')
+    go γ z me@(RFun x t t' r)
+       | logicBind x t                  = f γ (Just me) r (go (insertSEnv x (g t) γ) (go γ z t) t')
+       | otherwise                      = f γ (Just me) r (go γ (go γ z t) t')
     go γ z me@(RApp _ ts rs r)          = f γ (Just me) r (ho' γ (go' (insertSEnv (rTypeValueVar me) (g me) γ) z ts) rs)
 
     go γ z (RAllE x t t')               = go (insertSEnv x (g t) γ) (go γ z t) t'
@@ -1186,6 +1485,7 @@
 
     envtoType xts = foldr (\(x,t1) t2 -> rFun x t1 t2) (snd $ last xts) (init xts)
 
+mapBot :: (RType c tv r -> RType c tv r) -> RType c tv r -> RType c tv r
 mapBot f (RAllT α t)       = RAllT α (mapBot f t)
 mapBot f (RAllP π t)       = RAllP π (mapBot f t)
 mapBot f (RAllS s t)       = RAllS s (mapBot f t)
@@ -1196,9 +1496,13 @@
 mapBot f (RAllE b t1 t2)   = RAllE b  (mapBot f t1) (mapBot f t2)
 mapBot f (RRTy e r o t)    = RRTy (mapSnd (mapBot f) <$> e) r o (mapBot f t)
 mapBot f t'                = f t'
+
+mapBotRef :: (RType c tv r -> RType c tv r)
+          -> Ref τ (RType c tv r) -> Ref τ (RType c tv r)
 mapBotRef _ (RProp s (RHole r)) = RProp s $ RHole r
 mapBotRef f (RProp s t)    = RProp  s $ mapBot f t
 
+mapBind :: (Symbol -> Symbol) -> RType c tv r -> RType c tv r
 mapBind f (RAllT α t)      = RAllT α (mapBind f t)
 mapBind f (RAllP π t)      = RAllP π (mapBind f t)
 mapBind f (RAllS s t)      = RAllS s (mapBind f t)
@@ -1212,6 +1516,8 @@
 mapBind _ (RExprArg e)     = RExprArg e
 mapBind f (RAppTy t t' r)  = RAppTy (mapBind f t) (mapBind f t') r
 
+mapBindRef :: (Symbol -> Symbol)
+           -> Ref τ (RType c tv r) -> Ref τ (RType c tv r)
 mapBindRef f (RProp s (RHole r)) = RProp (mapFst f <$> s) (RHole r)
 mapBindRef f (RProp s t)         = RProp (mapFst f <$> s) $ mapBind f t
 
@@ -1223,6 +1529,7 @@
 toRSort :: RType c tv r -> RType c tv ()
 toRSort = stripAnnotations . mapBind (const dummySymbol) . fmap (const ())
 
+stripAnnotations :: RType c tv r -> RType c tv r
 stripAnnotations (RAllT α t)      = RAllT α (stripAnnotations t)
 stripAnnotations (RAllP _ t)      = stripAnnotations t
 stripAnnotations (RAllS _ t)      = stripAnnotations t
@@ -1233,10 +1540,13 @@
 stripAnnotations (RApp c ts rs r) = RApp c (stripAnnotations <$> ts) (stripAnnotationsRef <$> rs) r
 stripAnnotations (RRTy _ _ _ t)   = stripAnnotations t
 stripAnnotations t                = t
+
+stripAnnotationsRef :: Ref τ (RType c tv r) -> Ref τ (RType c tv r)
 stripAnnotationsRef (RProp s (RHole r)) = RProp s (RHole r)
 stripAnnotationsRef (RProp s t)         = RProp s $ stripAnnotations t
 
 
+insertsSEnv :: SEnv a -> [(Symbol, a)] -> SEnv a
 insertsSEnv  = foldr (\(x, t) γ -> insertSEnv x t γ)
 
 rTypeValueVar :: (Reftable r) => RType c tv r -> Symbol
@@ -1245,8 +1555,9 @@
 rTypeReft :: (Reftable r) => RType c tv r -> Reft
 rTypeReft = fromMaybe trueReft . fmap toReft . stripRTypeBase
 
-  
+
 -- stripRTypeBase ::  RType a -> Maybe a
+stripRTypeBase :: RType t t1 a -> Maybe a
 stripRTypeBase (RApp _ _ _ x)
   = Just x
 stripRTypeBase (RVar _ x)
@@ -1258,6 +1569,10 @@
 stripRTypeBase _
   = Nothing
 
+topRTypeBase :: (Reftable r) => RType c tv r -> RType c tv r
+topRTypeBase = mapRBase top
+
+mapRBase :: (r -> r) -> RType c tv r -> RType c tv r
 mapRBase f (RApp c ts rs r) = RApp c ts rs $ f r
 mapRBase f (RVar a r)       = RVar a $ f r
 mapRBase f (RFun x t1 t2 r) = RFun x t1 t2 $ f r
@@ -1272,9 +1587,13 @@
         f (MkUReft r p _) = MkUReft r p [l]
 
 
+makeDivType :: SpecType -> SpecType
 makeDivType = makeLType SDiv
+
+makeFinType :: SpecType -> SpecType
 makeFinType = makeLType SFin
 
+getStrata :: RType t t1 (UReft r) -> [Stratum]
 getStrata = maybe [] ur_strata . stripRTypeBase
 
 -----------------------------------------------------------------------------
@@ -1304,8 +1623,8 @@
 
 
 instance PPrint Predicate where
-  pprintTidy _ (Pr [])       = text "True"
-  pprintTidy k (Pr pvs)      = hsep $ punctuate (text "&") (map (pprintTidy k) pvs)
+  pprintTidy _ (Pr [])  = text "True"
+  pprintTidy k (Pr pvs) = hsep $ punctuate (text "&") (pprintTidy k <$> pvs)
 
 
 -- | The type used during constraint generation, used
@@ -1323,32 +1642,37 @@
 instance NFData REnv where
   rnf (REnv {}) = ()
 
-------------------------------------------------------------------------
--- | Error Data Type ---------------------------------------------------
-------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Error Data Type -----------------------------------------------------------
+--------------------------------------------------------------------------------
 
-type ErrorResult = FixResult UserError
-type Error       = TError SpecType
+type ErrorResult    = FixResult UserError
+type Error          = TError SpecType
 
+
 instance NFData a => NFData (TError a)
 
-------------------------------------------------------------------------
--- | Source Information Associated With Constraints --------------------
-------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Source Information Associated With Constraints ----------------------------
+--------------------------------------------------------------------------------
 
 data Cinfo    = Ci { ci_loc :: !SrcSpan
                    , ci_err :: !(Maybe Error)
+                   , ci_var :: !(Maybe Var)
                    }
                 deriving (Eq, Ord, Generic)
 
 instance NFData Cinfo
 
 --------------------------------------------------------------------------------
---- Module Names
+-- | Module Names --------------------------------------------------------------
 --------------------------------------------------------------------------------
 
-data ModName = ModName !ModType !ModuleName deriving (Eq,Ord)
+data ModName = ModName !ModType !ModuleName deriving (Eq, Ord)
 
+instance PPrint ModName where
+  pprintTidy _ = text . show
+
 instance Show ModName where
   show = getModString
 
@@ -1360,36 +1684,46 @@
 
 data ModType = Target | SrcImport | SpecImport deriving (Eq,Ord)
 
+isSrcImport :: ModName -> Bool
 isSrcImport (ModName SrcImport _) = True
 isSrcImport _                     = False
 
+isSpecImport :: ModName -> Bool
 isSpecImport (ModName SpecImport _) = True
 isSpecImport _                      = False
 
+getModName :: ModName -> ModuleName
 getModName (ModName _ m) = m
 
+getModString :: ModName -> String
 getModString = moduleNameString . getModName
 
 
--------------------------------------------------------------------------------
------------ Refinement Type Aliases -------------------------------------------
--------------------------------------------------------------------------------
-
-data RTEnv   = RTE { typeAliases :: M.HashMap Symbol (RTAlias RTyVar SpecType)
-                   , exprAliases :: M.HashMap Symbol (RTAlias Symbol Expr)
-                   }
+--------------------------------------------------------------------------------
+-- | Refinement Type Aliases ---------------------------------------------------
+--------------------------------------------------------------------------------
+data RTEnv = RTE
+  { typeAliases :: M.HashMap Symbol (RTAlias RTyVar SpecType)
+  , exprAliases :: M.HashMap Symbol (RTAlias Symbol Expr)
+  }
 
 instance Monoid RTEnv where
-  (RTE ta1 ea1) `mappend` (RTE ta2 ea2)
-    = RTE (ta1 `M.union` ta2) (ea1 `M.union` ea2)
-  mempty = RTE M.empty M.empty
+  mempty                          = RTE M.empty M.empty
+  (RTE x y) `mappend` (RTE x' y') = RTE (x `M.union` x') (y `M.union` y')
 
+mapRT :: (M.HashMap Symbol (RTAlias RTyVar SpecType)
+       -> M.HashMap Symbol (RTAlias RTyVar SpecType))
+       -> RTEnv -> RTEnv
 mapRT f e = e { typeAliases = f $ typeAliases e }
+
+mapRE :: (M.HashMap Symbol (RTAlias Symbol Expr)
+       -> M.HashMap Symbol (RTAlias Symbol Expr))
+      -> RTEnv -> RTEnv
 mapRE f e = e { exprAliases = f $ exprAliases e }
 
 
 --------------------------------------------------------------------------------
---- Measures
+-- | Measures
 --------------------------------------------------------------------------------
 data Body
   = E Expr          -- ^ Measure Refinement: {v | v = e }
@@ -1399,10 +1733,10 @@
 
 data Def ty ctor = Def
   { measure :: LocSymbol
-  , dparams :: [(Symbol, ty)]
+  , dparams :: [(Symbol, ty)]          -- measure parameters
   , ctor    :: ctor
   , dsort   :: Maybe ty
-  , binds   :: [(Symbol, Maybe ty)]
+  , binds   :: [(Symbol, Maybe ty)]    -- measure binders: the ADT argument fields
   , body    :: Body
   } deriving (Show, Data, Typeable, Generic, Eq, Functor)
 
@@ -1412,9 +1746,27 @@
   , eqns :: [Def ty ctor]
   } deriving (Data, Typeable, Generic, Functor)
 
-deriveBifunctor ''Def
-deriveBifunctor ''Measure
+instance Bifunctor Def where
+  first f (Def m ps c s bs b) =
+    Def m (map (second f) ps) c (fmap f s) (map (second (fmap f)) bs) b
+  second f (Def m ps c s bs b) =
+    Def m ps (f c) s bs b
 
+instance Bifunctor Measure where
+  first f (M n s es) =
+    M n (f s) (map (first f) es)
+  second f (M n s es) =
+    M n s (map (second f) es)
+
+instance                             B.Binary Body
+instance (B.Binary t, B.Binary c) => B.Binary (Def     t c)
+instance (B.Binary t, B.Binary c) => B.Binary (Measure t c)
+
+-- NOTE: don't use the TH versions since they seem to cause issues
+-- building on windows :(
+-- deriveBifunctor ''Def
+-- deriveBifunctor ''Measure
+
 data CMeasure ty = CM
   { cName :: LocSymbol
   , cSort :: ty
@@ -1423,21 +1775,24 @@
 instance PPrint Body where
   pprintTidy k (E e)   = pprintTidy k e
   pprintTidy k (P p)   = pprintTidy k p
-  pprintTidy k (R v p) = braces (pprintTidy k v <+> text "|" <+> pprintTidy k p)
+  pprintTidy k (R v p) = braces (pprintTidy k v <+> "|" <+> pprintTidy k p)
 
 instance PPrint a => PPrint (Def t a) where
-  pprintTidy k (Def m p c _ bs body) = pprintTidy k m <+> pprintTidy k (fst <$> p) <+> cbsd <> text " = " <> pprintTidy k body
-    where cbsd = parens (pprintTidy k c <> hsep (pprintTidy k `fmap` (fst <$> bs)))
+  pprintTidy k (Def m p c _ bs body)
+           = pprintTidy k m <+> pprintTidy k (fst <$> p) <+> cbsd <+> "=" <+> pprintTidy k body
+    where
+      cbsd = parens (pprintTidy k c <> hsep (pprintTidy k `fmap` (fst <$> bs)))
 
 instance (PPrint t, PPrint a) => PPrint (Measure t a) where
-  pprintTidy k (M n s eqs) =  pprintTidy k n <> text " :: " <> pprintTidy k s
-                     $$ vcat (pprintTidy k `fmap` eqs)
+  pprintTidy k (M n s eqs) =  pprintTidy k n <+> "::" <+> pprintTidy k s
+                              $$ vcat (pprintTidy k `fmap` eqs)
 
+
 instance PPrint (Measure t a) => Show (Measure t a) where
   show = showpp
 
 instance PPrint t => PPrint (CMeasure t) where
-  pprintTidy k (CM n s) =  pprintTidy k n <> text " :: " <> pprintTidy k s
+  pprintTidy k (CM n s) =  pprintTidy k n <+> "::" <+> pprintTidy k s
 
 instance PPrint (CMeasure t) => Show (CMeasure t) where
   show = showpp
@@ -1472,16 +1827,28 @@
   subst su (P e)   = P $ subst su e
   subst su (R s e) = R s $ subst su e
 
+instance Subable t => Subable (WithModel t) where
+  syms (NoModel t)     = syms t
+  syms (WithModel _ t) = syms t
 
+  substa f = fmap (substa f)
 
-data RClass ty
-  = RClass { rcName    :: LocSymbol
-           , rcSupers  :: [ty]
-           , rcTyVars  :: [Symbol]
-           , rcMethods :: [(LocSymbol,ty)]
-           } deriving (Show, Functor)
+  substf f = fmap (substf f)
 
+  subst su = fmap (subst su)
 
+data RClass ty = RClass
+  { rcName    :: BTyCon
+  , rcSupers  :: [ty]
+  , rcTyVars  :: [BTyVar]
+  , rcMethods :: [(LocSymbol,ty)]
+  } deriving (Show, Functor, Data, Typeable, Generic)
+
+
+
+instance B.Binary ty => B.Binary (RClass ty)
+
+
 ------------------------------------------------------------------------
 -- | Annotations -------------------------------------------------------
 ------------------------------------------------------------------------
@@ -1510,19 +1877,20 @@
 
 data Output a = O
   { o_vars   :: Maybe [String]
-  , o_errors :: ![UserError]
+  -- , o_errors :: ![UserError]
   , o_types  :: !(AnnInfo a)
   , o_templs :: !(AnnInfo a)
   , o_bots   :: ![SrcSpan]
   , o_result :: ErrorResult
   } deriving (Typeable, Generic, Functor)
 
-emptyOutput = O Nothing [] mempty mempty [] mempty
+emptyOutput :: Output a
+emptyOutput = O Nothing {- [] -} mempty mempty [] mempty
 
 instance Monoid (Output a) where
   mempty        = emptyOutput
   mappend o1 o2 = O { o_vars   = sortNub <$> mappend (o_vars   o1) (o_vars   o2)
-                    , o_errors = sortNub  $  mappend (o_errors o1) (o_errors o2)
+                    -- , o_errors = sortNub  $  mappend (o_errors o1) (o_errors o2)
                     , o_types  =             mappend (o_types  o1) (o_types  o2)
                     , o_templs =             mappend (o_templs o1) (o_templs o2)
                     , o_bots   = sortNub  $  mappend (o_bots o1)   (o_bots   o2)
@@ -1534,14 +1902,15 @@
 --------------------------------------------------------------------------------
 
 data KVKind
-  = RecBindE
-  | NonRecBindE
+  = RecBindE    Var -- ^ Recursive binder      @letrec x = ...@
+  | NonRecBindE Var -- ^ Non recursive binder  @let x = ...@
   | TypeInstE
   | PredInstE
   | LamE
-  | CaseE
+  | CaseE       Int -- ^ Int is the number of cases
   | LetE
-  deriving (Generic, Eq, Ord, Show, Enum, Data, Typeable)
+  | ProjectE        -- ^ Projecting out field of
+  deriving (Generic, Eq, Ord, Show, Data, Typeable)
 
 instance Hashable KVKind
 
@@ -1640,23 +2009,27 @@
 -- Nasty PP stuff
 --------------------------------------------------------------------------------
 
+instance PPrint BTyVar where
+  pprintTidy _ (BTV α) = text $ symbolString α
+
 instance PPrint RTyVar where
-  pprintTidy _k (RTV α)
-   | ppTyVar ppEnv = ppr_tyvar α
-   | otherwise     = ppr_tyvar_short α
+  pprintTidy _ (RTV α)
+   | ppTyVar ppEnv  = ppr_tyvar α
+   | otherwise      = ppr_tyvar_short α
+   where
+     ppr_tyvar :: Var -> Doc
+     ppr_tyvar       = text . tvId
 
-ppr_tyvar       = text . tvId
-ppr_tyvar_short = text . showPpr
+     ppr_tyvar_short :: TyVar -> Doc
+     ppr_tyvar_short = text . showPpr
 
 instance (PPrint r, Reftable r, PPrint t, PPrint (RType c tv r)) => PPrint (Ref t (RType c tv r)) where
-  pprintTidy k (RProp ss s) = ppRefArgs (fst <$> ss) <+> pprintTidy k s
-  -- pprint (RProp ss (RHole s)) = ppRefArgs (fst <$> ss) <+> pprint s
-  -- pprint (RProp ss s) = ppRefArgs (fst <$> ss) <+> pprint (fromMaybe mempty (stripRTypeBase s))
-
+  pprintTidy k (RProp ss s) = ppRefArgs k (fst <$> ss) <+> pprintTidy k s
 
-ppRefArgs :: [Symbol] -> Doc
-ppRefArgs [] = empty
-ppRefArgs ss = text "\\" <> hsep (ppRefSym <$> ss ++ [vv Nothing]) <+> text "->"
+ppRefArgs :: Tidy -> [Symbol] -> Doc
+ppRefArgs _ [] = empty
+ppRefArgs k ss = text "\\" <> hsep (ppRefSym k <$> ss ++ [vv Nothing]) <+> "->"
 
-ppRefSym "" = text "_"
-ppRefSym s  = pprint s
+ppRefSym :: (Eq a, IsString a, PPrint a) => Tidy -> a -> Doc
+ppRefSym _ "" = text "_"
+ppRefSym k s  = pprintTidy k s
diff --git a/src/Language/Haskell/Liquid/Types/Annotations.hs b/src/Language/Haskell/Liquid/Types/Annotations.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/Types/Annotations.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module Language.Haskell.Liquid.Types.Annotations (
+  ) where
+
+import Data.Data
+import Data.Typeable
+
+import Language.Haskell.TH.Syntax
+
diff --git a/src/Language/Haskell/Liquid/Types/Bounds.hs b/src/Language/Haskell/Liquid/Types/Bounds.hs
--- a/src/Language/Haskell/Liquid/Types/Bounds.hs
+++ b/src/Language/Haskell/Liquid/Types/Bounds.hs
@@ -1,5 +1,8 @@
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE FlexibleContexts   #-}
+{-# LANGUAGE TupleSections      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
 
 module Language.Haskell.Liquid.Types.Bounds (
 
@@ -15,31 +18,31 @@
 
 import Prelude hiding (error)
 import Text.PrettyPrint.HughesPJ
-
+import GHC.Generics
 import Data.List (partition)
 import Data.Maybe
 import Data.Hashable
--- import Data.Monoid
 import Data.Bifunctor
-
+import Data.Data
+import qualified Data.Binary         as B
 import qualified Data.HashMap.Strict as M
--- import Control.Applicative           ((<$>))
 
 import Language.Fixpoint.Types
-
 import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Misc  (mapFst, mapSnd)
+import Language.Fixpoint.Misc  (mapFst, mapSnd)
 import Language.Haskell.Liquid.Types.RefType
 
 
-data Bound t e
-  = Bound { bname   :: LocSymbol         -- ^ The name of the bound
-          , tyvars  :: [t]               -- ^ Type variables that appear in the bounds
-          , bparams :: [(LocSymbol, t)]  -- ^ These are abstract refinements, for now
-          , bargs   :: [(LocSymbol, t)]  -- ^ These are value variables
-          , bbody   :: e                 -- ^ The body of the bound
-          }
+data Bound t e = Bound
+  { bname   :: LocSymbol         -- ^ The name of the bound
+  , tyvars  :: [t]               -- ^ Type variables that appear in the bounds
+  , bparams :: [(LocSymbol, t)]  -- ^ These are abstract refinements, for now
+  , bargs   :: [(LocSymbol, t)]  -- ^ These are value variables
+  , bbody   :: e                 -- ^ The body of the bound
+  } deriving (Data, Typeable, Generic)
 
+instance (B.Binary t, B.Binary e) => B.Binary (Bound t e)
+
 type RBound        = RRBound RSort
 type RRBound tv    = Bound tv Expr
 
@@ -48,33 +51,32 @@
 
 
 instance Hashable (Bound t e) where
-        hashWithSalt i = hashWithSalt i . bname
+  hashWithSalt i = hashWithSalt i . bname
 
 instance Eq (Bound t e) where
-  b1 == b2 = (bname b1) == (bname b2)
+  b1 == b2 = bname b1 == bname b2
 
 instance (PPrint e, PPrint t) => (Show (Bound t e)) where
-        show = showpp
+  show = showpp
 
 
 instance (PPrint e, PPrint t) => (PPrint (Bound t e)) where
-        pprintTidy k (Bound s vs ps xs e) =   text "bound" <+> pprintTidy k s <+>
-                                        text "forall" <+> pprintTidy k vs <+> text "." <+>
-                                        pprintTidy k (fst <$> ps) <+> text "=" <+>
-                                        pprint_bsyms k (fst <$> xs) <+> pprintTidy k e
-
-pprint_bsyms _ [] = text ""
-pprint_bsyms k xs = text "\\" <+> pprintTidy k xs <+> text "->"
+  pprintTidy k (Bound s vs ps xs e) = "bound" <+> pprintTidy k s <+>
+                                      "forall" <+> pprintTidy k vs <+> "." <+>
+                                      pprintTidy k (fst <$> ps) <+> "=" <+>
+                                      ppBsyms k (fst <$> xs) <+> pprintTidy k e
+    where
+      ppBsyms _ [] = ""
+      ppBsyms k xs = "\\" <+> pprintTidy k xs <+> "->"
 
 instance Bifunctor Bound where
-        first  f (Bound s vs ps xs e) = Bound s (f <$> vs) (mapSnd f <$> ps) (mapSnd f <$> xs) e
-        second f (Bound s vs ps xs e) = Bound s vs ps xs (f e)
-
+  first  f (Bound s vs ps xs e) = Bound s (f <$> vs) (mapSnd f <$> ps) (mapSnd f <$> xs) e
+  second f (Bound s vs ps xs e) = Bound s vs ps xs (f e)
 
-makeBound :: (PPrint r, UReftable r)
-          => RRBound RSort -> [RRType r] -> [Symbol] -> (RRType r) -> (RRType r)
-makeBound (Bound _  vs ps xs p) ts qs t
-  = RRTy cts mempty OCons t
+makeBound :: (PPrint r, UReftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r)
+          => RRBound RSort -> [RRType r] -> [Symbol] -> RRType r -> RRType r
+makeBound (Bound _  vs ps xs p) ts qs
+         = RRTy cts mempty OCons
   where
     cts  = (\(x, t) -> (x, foldr subsTyVar_meet t su)) <$> cts'
 
@@ -99,7 +101,7 @@
     go [] = panic Nothing "Bound with empty symbols"
 
     go [(x, t)]      = [(dummySymbol, tp t x), (dummySymbol, tq t x)]
-    go ((x, t):xtss) = (val x, mkt t x):(go xtss)
+    go ((x, t):xtss) = (val x, mkt t x) : go xtss
 
     mkt t x = ofRSort t `strengthen` ofUReft (MkUReft (Reft (val x, mempty))
                                                 (Pr $ M.lookupDefault [] (val x) ps) mempty)
@@ -119,29 +121,33 @@
   where
     makeAR ps       = M.fromListWith (++) $ map (toUsedPVars penv) ps
 
+isPApp :: [(Symbol, a)] -> Expr -> Bool
 isPApp penv (EApp (EVar p) _)  = isJust $ lookup p penv
-isPApp penv (EApp e _)         = isPApp penv e 
+isPApp penv (EApp e _)         = isPApp penv e
 isPApp _    _                  = False
 
+toUsedPVars :: [(Symbol, Symbol)] -> Expr -> (Symbol, [PVar ()])
 toUsedPVars penv q@(EApp _ e) = (x, [toUsedPVar penv q])
   where
     -- NV : TODO make this a better error
-    x = case unProp e of {EVar x -> x; e -> todo Nothing ("Bound fails in " ++ show e) }
+    x = case {- unProp -} e of {EVar x -> x; e -> todo Nothing ("Bound fails in " ++ show e) }
 toUsedPVars _ _ = impossible Nothing "This cannot happen"
 
-unProp (EApp (EVar f) e)
-  | f == propConName
-  = e
-unProp e
-  = e
+-- unProp :: Expr -> Expr
+-- unProp (EApp (EVar f) e)
+--    | f == propConName
+--    = e
+-- unProp e
+--    = e
 
+toUsedPVar :: [(Symbol, Symbol)] -> Expr -> PVar ()
 toUsedPVar penv ee@(EApp _ _)
   = PV q (PVProp ()) e (((), dummySymbol,) <$> es')
    where
-     EVar e = unProp $ last es
+     EVar e = {- unProp $ -} last es
      es'    = init es
      Just q = lookup p penv
-     (EVar p, es) = splitEApp ee 
+     (EVar p, es) = splitEApp ee
 
 toUsedPVar _ _ = impossible Nothing "This cannot happen"
 
diff --git a/src/Language/Haskell/Liquid/Types/Dictionaries.hs b/src/Language/Haskell/Liquid/Types/Dictionaries.hs
--- a/src/Language/Haskell/Liquid/Types/Dictionaries.hs
+++ b/src/Language/Haskell/Liquid/Types/Dictionaries.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleContexts     #-}
+
 module Language.Haskell.Liquid.Types.Dictionaries (
     makeDictionaries
   , makeDictionary
@@ -8,37 +11,52 @@
   , dinsert
   , dlookup
   , dhasinfo
+  , mapRISig
+  , fromRISig 
   ) where
 
-import Prelude hiding (error)
+import           Data.Hashable
+import           Prelude                                   hiding (error)
 
-import Var
+import           Var
 
 
 
-import Language.Fixpoint.Types
+import           Language.Fixpoint.Types
 
-import Language.Haskell.Liquid.GHC.Misc (dropModuleNames)
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Misc (mapFst)
 
-import qualified Data.HashMap.Strict as M
-import Language.Haskell.Liquid.Types.PrettyPrint ()
+import           Language.Haskell.Liquid.Types.PrettyPrint ()
 
+import           Language.Haskell.Liquid.GHC.Misc          (dropModuleNames)
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Types.RefType ()
+import           Language.Fixpoint.Misc                (mapFst)
+
+import qualified Data.HashMap.Strict                       as M
+
 makeDictionaries :: [RInstance SpecType] -> DEnv Symbol SpecType
 makeDictionaries = DEnv . M.fromList . map makeDictionary
 
 
-makeDictionary :: RInstance SpecType -> (Symbol, M.HashMap Symbol SpecType)
-makeDictionary (RI c t xts) = (makeDictionaryName c t, M.fromList (mapFst val <$> xts))
+makeDictionary :: RInstance SpecType -> (Symbol, M.HashMap Symbol (RISig SpecType))
+makeDictionary (RI c ts xts) = (makeDictionaryName (btc_tc c) ts, M.fromList (mapFst val <$> xts))
 
-makeDictionaryName :: Located Symbol -> SpecType -> Symbol
-makeDictionaryName t (RApp c _ _ _) = symbol ("$f" ++ symbolString (val t) ++ c')
-  where
-        c' = symbolString (dropModuleNames $ symbol $ rtc_tc c)
+makeDictionaryName :: Located Symbol -> [SpecType] -> Symbol
+makeDictionaryName t ts
+  = symbol ("$f" ++ symbolString (val t) ++ concatMap makeDicTypeName ts)
 
-makeDictionaryName _ _              = panic Nothing "makeDictionaryName: called with invalid type"
 
+makeDicTypeName :: SpecType -> String
+makeDicTypeName (RFun _ _ _ _)
+  = "(->)"
+makeDicTypeName (RApp c _ _ _)
+  = symbolString $ dropModuleNames $ symbol $ rtc_tc c
+makeDicTypeName (RVar a _)
+  = show a
+makeDicTypeName t
+  = panic Nothing ("makeDicTypeName: called with invalid type " ++ show t)
+
+
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 ------------------------ Dictionay Environment -------------------------------
@@ -46,19 +64,34 @@
 ------------------------------------------------------------------------------
 
 
-dfromList :: [(Var, M.HashMap Symbol t)] -> DEnv Var t
+dfromList :: [(Var, M.HashMap Symbol (RISig t))] -> DEnv Var t
 dfromList = DEnv . M.fromList
 
 dmapty :: (a -> b) -> DEnv v a -> DEnv v b
-dmapty f (DEnv e) = DEnv (M.map (M.map f) e)
+dmapty f (DEnv e) = DEnv (M.map (M.map (mapRISig f)) e)
 
+mapRISig :: (a -> b) -> RISig a -> RISig b 
+mapRISig f (RIAssumed t) = RIAssumed (f t)
+mapRISig f (RISig     t) = RISig     (f t)
+
+
+fromRISig :: RISig a -> a 
+fromRISig (RIAssumed t) = t 
+fromRISig (RISig     t) = t 
+
+dmap :: (v1 -> v2) -> M.HashMap k v1 -> M.HashMap k v2
 dmap f xts = M.map f xts
 
+dinsert :: (Eq x, Hashable x)
+        => DEnv x ty -> x -> M.HashMap Symbol (RISig ty) -> DEnv x ty
 dinsert (DEnv denv) x xts = DEnv $ M.insert x xts denv
 
+dlookup :: (Eq k, Hashable k)
+        => DEnv k t -> k -> Maybe (M.HashMap Symbol (RISig t))
 dlookup (DEnv denv) x     = M.lookup x denv
 
 
+dhasinfo :: Show a1 => Maybe (M.HashMap Symbol a) -> a1 -> Maybe a
 dhasinfo Nothing _    = Nothing
 dhasinfo (Just xts) x = M.lookup x' xts
   where
diff --git a/src/Language/Haskell/Liquid/Types/Errors.hs b/src/Language/Haskell/Liquid/Types/Errors.hs
--- a/src/Language/Haskell/Liquid/Types/Errors.hs
+++ b/src/Language/Haskell/Liquid/Types/Errors.hs
@@ -22,9 +22,11 @@
   -- * Subtyping Obligation Type
   , Oblig (..)
 
+  -- * Adding a Model of the context
+  , WithModel (..), dropModel
+
   -- * Panic (unexpected failures)
   , UserError
-  --, HiddenType (..)
   , panic
   , panicDoc
   , todo
@@ -41,19 +43,20 @@
   ) where
 
 import           Prelude                      hiding (error)
-
+-- import           Data.Bifunctor
 import           SrcLoc                      -- (SrcSpan (..), noSrcSpan)
 import           FastString
 import           GHC.Generics
 import           Control.DeepSeq
 import           Data.Typeable                (Typeable)
 import           Data.Generics                (Data)
+import qualified Data.Binary as B
 import           Data.Maybe
 import           Text.PrettyPrint.HughesPJ
 import           Data.Aeson hiding (Result)
 import qualified Data.HashMap.Strict as M
-import           Language.Fixpoint.Types      (showpp, Tidy (..), PPrint (..), pprint, Symbol, Expr)
-import           Language.Fixpoint.Misc (dcolon)
+import           Language.Fixpoint.Types      (pprint, showpp, Tidy (..), PPrint (..), Symbol, Expr)
+import           Language.Fixpoint.Misc       ({- traceShow, -} dcolon)
 import           Language.Haskell.Liquid.Misc (intToString)
 import           Text.Parsec.Error            (ParseError)
 import qualified Control.Exception as Ex
@@ -65,11 +68,11 @@
 
 
 instance PPrint ParseError where
-  pprintTidy _ e = vcat $ tail $ map text ls
+  pprintTidy _ e = vcat $ tail $ text <$> ls
     where
-      ls = lines $ showErrorMessages "or" "unknown parse error"
-                                     "expecting" "unexpected" "end of input"
-                                     (errorMessages e)
+      ls         = lines $ showErrorMessages "or" "unknown parse error"
+                               "expecting" "unexpected" "end of input"
+                               (errorMessages e)
 
 --------------------------------------------------------------------------------
 -- | Context information for Error Messages ------------------------------------
@@ -86,7 +89,7 @@
   e1 <= e2 = ctErr e1 <= ctErr e2
 
 --------------------------------------------------------------------------------
-errorWithContext :: TError t -> IO (CtxError t)
+errorWithContext :: TError Doc -> IO (CtxError Doc)
 --------------------------------------------------------------------------------
 errorWithContext e = CtxError e <$> srcSpanContext (pos e)
 
@@ -99,15 +102,15 @@
 
 srcSpanInfo :: SrcSpan -> Maybe (FilePath, Int, Int, Int)
 srcSpanInfo (RealSrcSpan s)
-  | l == l'           = Just (f, l, c, c')
-  | otherwise         = Nothing
+  | l == l'   = Just (f, l, c, c')
+  | otherwise = Nothing
   where
-     f  = unpackFS $ srcSpanFile s
-     l  = srcSpanStartLine s
-     c  = srcSpanStartCol  s
-     l' = srcSpanEndLine   s
-     c' = srcSpanEndCol    s
-srcSpanInfo _         = Nothing
+     f        = unpackFS $ srcSpanFile s
+     l        = srcSpanStartLine s
+     c        = srcSpanStartCol  s
+     l'       = srcSpanEndLine   s
+     c'       = srcSpanEndCol    s
+srcSpanInfo _ = Nothing
 
 getFileLine :: FilePath -> Int -> IO (Maybe String)
 getFileLine f i = do
@@ -128,7 +131,7 @@
                             ]
   where
     lnum n           = text (show n) <+> text "|"
-    cursor           = blanks (c - 1) <> pointer (c' - c)
+    cursor           = blanks (c - 1) <> pointer (max 1 (c' - c))
     blanks n         = text $ replicate n ' '
     pointer n        = text $ replicate n '^'
 
@@ -142,6 +145,7 @@
   | OCons -- ^ Obligation that proves subtyping constraints
   deriving (Generic, Data, Typeable)
 
+instance B.Binary Oblig
 instance Show Oblig where
   show OTerm = "termination-condition"
   show OInv  = "invariant-obligation"
@@ -171,6 +175,14 @@
                , texp :: !t
                } -- ^ liquid type error
 
+  | ErrSubTypeModel
+               { pos  :: !SrcSpan
+               , msg  :: !Doc
+               , ctxM  :: !(M.HashMap Symbol (WithModel t))
+               , tactM :: !(WithModel t)
+               , texp :: !t
+               } -- ^ liquid type error with a counter-example
+
   | ErrFCrash  { pos  :: !SrcSpan
                , msg  :: !Doc
                , ctx  :: !(M.HashMap Symbol t)
@@ -267,7 +279,7 @@
   | ErrMismatch { pos   :: !SrcSpan -- ^ haskell type location
                 , var   :: !Doc
                 , hs    :: !Doc
-                , lq    :: !Doc
+                , lqTy  :: !Doc
                 , lqPos :: !SrcSpan -- ^ lq type location
                 } -- ^ Mismatch between Liquid and Haskell types
 
@@ -289,16 +301,11 @@
                        } -- ^ Illegal RTAlias application (from BSort, eg. in PVar)
 
   | ErrAliasApp { pos   :: !SrcSpan
-                , nargs :: !Int
                 , dname :: !Doc
                 , dpos  :: !SrcSpan
-                , dargs :: !Int
+                , msg   :: !Doc
                 }
 
-  | ErrSaved    { pos :: !SrcSpan
-                , msg :: !Doc
-                } -- ^ Previously saved error, that carries over after DiffCheck
-
   | ErrTermin   { pos  :: !SrcSpan
                 , bind :: ![Doc]
                 , msg  :: !Doc
@@ -314,11 +321,24 @@
                 , msg   :: !Doc
                 } -- ^ Non well sorted Qualifier
 
+  | ErrSaved    { pos :: !SrcSpan
+                , nam :: !Doc
+                , msg :: !Doc
+                } -- ^ Previously saved error, that carries over after DiffCheck
+
+  | ErrFilePragma { pos :: !SrcSpan
+                  }
+
+  | ErrTyCon    { pos    :: !SrcSpan
+                , msg    :: !Doc
+                , tcname :: !Doc
+                }
+
   | ErrOther    { pos   :: SrcSpan
                 , msg   :: !Doc
                 } -- ^ Sigh. Other.
 
-  deriving (Typeable, Generic, Functor)
+  deriving (Typeable, Generic , Functor )
 
 instance NFData ParseError where
   rnf t = seq t ()
@@ -341,6 +361,21 @@
 --------------------------------------------------------------------------------
 type UserError  = TError Doc
 
+instance PPrint UserError where
+  pprintTidy k = ppError k empty . fmap (pprintTidy Lossy)
+
+data WithModel t
+  = NoModel t
+  | WithModel !Doc t
+  deriving (Functor, Show, Eq, Generic)
+
+instance NFData t => NFData (WithModel t)
+
+dropModel :: WithModel t -> t
+dropModel m = case m of
+  NoModel t     -> t
+  WithModel _ t -> t
+
 instance PPrint SrcSpan where
   pprintTidy _ = pprSrcSpan
 
@@ -376,9 +411,6 @@
    pathDoc = text $ normalise $ unpackFS path
    ecol'   = if ecol == 0 then ecol else ecol - 1
 
-instance PPrint UserError where
-  pprintTidy k = ppError k empty . fmap pprint
-
 instance Show UserError where
   show = showpp
 
@@ -430,32 +462,67 @@
   where
     dSp          = pprint (pos e) <> text ": Error:"
 
+nests :: Foldable t => Int -> t Doc -> Doc
 nests n      = foldr (\d acc -> nest n (d $+$ acc)) empty
+
+sepVcat :: Doc -> [Doc] -> Doc
 sepVcat d ds = vcat $ intersperse d ds
+
+blankLine :: Doc
 blankLine    = sizedText 5 " "
 
 ppFull :: Tidy -> Doc -> Doc
 ppFull Full  d = d
 ppFull Lossy _ = empty
 
-ppReqInContext :: (PPrint t, PPrint c) => t -> t -> c -> Doc
-ppReqInContext tA tE c
+ppReqInContext :: PPrint t => Tidy -> t -> t -> M.HashMap Symbol t -> Doc
+ppReqInContext td tA tE c
   = sepVcat blankLine
       [ nests 2 [ text "Inferred type"
-                , text "VV :" <+> pprint tA]
+                , text "VV :" <+> pprintTidy td tA]
       , nests 2 [ text "not a subtype of Required type"
-                , text "VV :" <+> pprint tE]
+                , text "VV :" <+> pprintTidy td tE]
       , nests 2 [ text "In Context"
-                , pprint c                 ]]
+                , vsep (map (uncurry (pprintBind td)) (M.toList c))
+                ]
+      ]
 
+pprintBind :: PPrint t => Tidy -> Symbol -> t -> Doc
+pprintBind td v t = pprintTidy td v <+> char ':' <+> pprintTidy td t
 
-ppPropInContext :: (PPrint p, PPrint c) => p -> c -> Doc
-ppPropInContext p c
+ppReqModelInContext
+  :: (PPrint t) => Tidy -> WithModel t -> t -> (M.HashMap Symbol (WithModel t)) -> Doc
+ppReqModelInContext td tA tE c
   = sepVcat blankLine
+      [ nests 2 [ text "Inferred type"
+                , pprintModel td "VV" tA]
+      , nests 2 [ text "not a subtype of Required type"
+                , pprintModel td "VV" (NoModel tE)]
+      , nests 2 [ text "In Context"
+                , vsep (map (uncurry (pprintModel td)) (M.toList c))
+                ]
+      ]
+
+vsep :: [Doc] -> Doc
+vsep = vcat . intersperse (char ' ')
+
+pprintModel :: PPrint t => Tidy -> Symbol -> WithModel t -> Doc
+pprintModel td v wm = case wm of
+  NoModel t
+    -> pprintTidy td v <+> char ':' <+> pprintTidy td t
+  WithModel m t
+    -> pprintTidy td v <+> char ':' <+> pprintTidy td t $+$
+       pprintTidy td v <+> char '=' <+> pprintTidy td m
+
+ppPropInContext :: (PPrint p, PPrint c) => Tidy -> p -> c -> Doc
+ppPropInContext td p c
+  = sepVcat blankLine
       [ nests 2 [ text "Property"
-                , pprint p]
+                , pprintTidy td p]
       , nests 2 [ text "Not provable in context"
-                , pprint c                 ]]
+                , pprintTidy td c
+                ]
+      ]
 
 instance ToJSON RealSrcSpan where
   toJSON sp = object [ "filename"  .= f
@@ -467,6 +534,7 @@
     where
       (f, l1, c1, l2, c2) = unpackRealSrcSpan sp
 
+unpackRealSrcSpan :: RealSrcSpan -> (String, Int, Int, Int, Int)
 unpackRealSrcSpan rsp = (f, l1, c1, l2, c2)
   where
     f                 = unpackFS $ srcSpanFile rsp
@@ -512,25 +580,32 @@
   parseJSON _          = mempty
 
 errSaved :: SrcSpan -> String -> TError a
-errSaved x = ErrSaved x . text
+errSaved sp body = ErrSaved sp (text n) (text $ unlines m)
+  where
+    n : m        = lines body
 
 --------------------------------------------------------------------------------
 ppError' :: (PPrint a, Show a) => Tidy -> Doc -> Doc -> TError a -> Doc
 --------------------------------------------------------------------------------
 ppError' td dSp dCtx (ErrAssType _ o _ c p)
-  = dSp <+> pprint o
+  = dSp <+> pprintTidy td o
         $+$ dCtx
-        $+$ (ppFull td $ ppPropInContext p c)
+        $+$ (ppFull td $ ppPropInContext td p c)
 
 ppError' td dSp dCtx (ErrSubType _ _ c tA tE)
   = dSp <+> text "Liquid Type Mismatch"
         $+$ dCtx
-        $+$ (ppFull td $ ppReqInContext tA tE c)
+        $+$ (ppFull td $ ppReqInContext td tA tE c)
 
+ppError' td dSp dCtx (ErrSubTypeModel _ _ c tA tE)
+  = dSp <+> text "Liquid Type Mismatch"
+        $+$ dCtx
+        $+$ (ppFull td $ ppReqModelInContext td tA tE c)
+
 ppError' td  dSp dCtx (ErrFCrash _ _ c tA tE)
   = dSp <+> text "Fixpoint Crash on Constraint"
         $+$ dCtx
-        $+$ (ppFull td $ ppReqInContext tA tE c)
+        $+$ (ppFull td $ ppReqInContext td tA tE c)
 
 ppError' _ dSp dCtx (ErrParse _ _ e)
   = dSp <+> text "Cannot parse specification:"
@@ -641,23 +716,30 @@
         $+$ text "Type alias:" <+> pprint dn
         $+$ text "Defined at:" <+> pprint dl
 
-ppError' _ dSp dCtx (ErrAliasApp _ n name dl dn)
+ppError' _ dSp dCtx (ErrAliasApp _ name dl s)
   = dSp <+> text "Malformed Type Alias Application"
         $+$ dCtx
         $+$ text "Type alias:" <+> pprint name
         $+$ text "Defined at:" <+> pprint dl
-        $+$ text "Expects"     <+> pprint dn <+> text "arguments, but is given" <+> pprint n
+        $+$ s
 
-ppError' _ dSp _ (ErrSaved _ s)
-  = dSp <+> s
+ppError' _ dSp dCtx (ErrSaved _ name s)
+  = dSp <+> name -- <+> "(saved)"
+        $+$ dCtx
+        $+$ {- nest 4 -} s
 
+ppError' _ dSp dCtx (ErrFilePragma _)
+  = dSp <+> text "--idirs, --c-files, and --ghc-option cannot be used in file-level pragmas"
+        $+$ dCtx
+
 ppError' _ dSp dCtx (ErrOther _ s)
   = dSp <+> text "Uh oh."
         $+$ dCtx
         $+$ nest 4 s
 
-ppError' _ dSp _ (ErrTermin _ xs s)
+ppError' _ dSp dCtx (ErrTermin _ xs s)
   = dSp <+> text "Termination Error"
+        $+$ dCtx
         <+> (hsep $ intersperse comma xs) $+$ s
 
 ppError' _ dSp _ (ErrRClass p0 c is)
@@ -671,4 +753,8 @@
       =   text "Refined instance for:" <+> t
       $+$ text "Defined at:" <+> pprint p
 
+ppError' _ dSp _ (ErrTyCon _ msg ty)
+  = dSp <+> text "Bad Data Refinement for " <+> ty
+    $+$ (nest 4 msg)
+ppVar :: PPrint a => a -> Doc
 ppVar v = text "`" <> pprint v <> text "'"
diff --git a/src/Language/Haskell/Liquid/Types/Literals.hs b/src/Language/Haskell/Liquid/Types/Literals.hs
--- a/src/Language/Haskell/Liquid/Types/Literals.hs
+++ b/src/Language/Haskell/Liquid/Types/Literals.hs
@@ -4,29 +4,26 @@
          literalFRefType
        , literalFReft
        , literalConst
+
+       , mkI, mkS
        ) where
 
 import Prelude hiding (error)
 import TypeRep
 import Literal
 import qualified TyCon  as TC
-import Language.Haskell.Liquid.Measure
+
 import Language.Haskell.Liquid.Types
 import Language.Haskell.Liquid.Types.RefType
-import Language.Haskell.Liquid.Transforms.CoreToLogic (mkLit)
-
+import Language.Haskell.Liquid.Transforms.CoreToLogic (mkLit, mkI, mkS)
 
 import qualified Language.Fixpoint.Types as F
 
-import qualified Data.Text as T
-
-
-
-
 ---------------------------------------------------------------
 ----------------------- Typing Literals -----------------------
 ---------------------------------------------------------------
 
+makeRTypeBase :: Monoid r => Type -> r -> RType RTyCon RTyVar r
 makeRTypeBase (TyVarTy α)    x
   = RVar (rTyVar α) x
 makeRTypeBase (TyConApp c ts) x
@@ -34,19 +31,15 @@
 makeRTypeBase _              _
   = panic Nothing "RefType : makeRTypeBase"
 
+literalFRefType :: Literal -> RType RTyCon RTyVar F.Reft
 literalFRefType l
   = makeRTypeBase (literalType l) (literalFReft l)
 
+literalFReft :: Literal -> F.Reft
 literalFReft l = maybe mempty mkReft $ mkLit l
 
-mkReft e = case e of
-            F.ESym (F.SL str) ->
-              -- FIXME: unsorted equality is shady, better to not embed Add# as int..
-              F.meet (F.uexprReft e)
-                     (F.reft "v" (F.PAtom F.Eq
-                                  (F.mkEApp (name strLen) [F.EVar "v"])
-                                  (F.ECon (F.I (fromIntegral (T.length str))))))
-            _ -> F.exprReft e
+mkReft :: F.Expr -> F.Reft
+mkReft = F.exprReft
 
 -- | `literalConst` returns `Nothing` for unhandled lits because
 --    otherwise string-literals show up as global int-constants
diff --git a/src/Language/Haskell/Liquid/Types/Meet.hs b/src/Language/Haskell/Liquid/Types/Meet.hs
--- a/src/Language/Haskell/Liquid/Types/Meet.hs
+++ b/src/Language/Haskell/Liquid/Types/Meet.hs
@@ -19,8 +19,8 @@
     (hsSp, hsT)      = hs
     (lqSp, lqT)      = lq
     err              = ErrMismatch lqSp v hsD lqD hsSp
-    hsD              = pprint (toRSort hsT)
-    lqD              = pprint (toRSort lqT)
+    hsD              = F.pprint (toRSort hsT)
+    lqD              = F.pprint (toRSort lqT)
 
 meetError :: Error -> SpecType -> SpecType -> SpecType
 meetError e t t'
diff --git a/src/Language/Haskell/Liquid/Types/Names.hs b/src/Language/Haskell/Liquid/Types/Names.hs
--- a/src/Language/Haskell/Liquid/Types/Names.hs
+++ b/src/Language/Haskell/Liquid/Types/Names.hs
@@ -1,6 +1,11 @@
-module Language.Haskell.Liquid.Types.Names where
+module Language.Haskell.Liquid.Types.Names
+  (lenLocSymbol, anyTypeSymbol) where
 
 import Language.Fixpoint.Types
 
-
+-- RJ: Please add docs
+lenLocSymbol :: Located Symbol
 lenLocSymbol = dummyLoc $ symbol ("autolen" :: String)
+
+anyTypeSymbol :: Symbol
+anyTypeSymbol = symbol ("GHC.Prim.Any" :: String)
diff --git a/src/Language/Haskell/Liquid/Types/PredType.hs b/src/Language/Haskell/Liquid/Types/PredType.hs
--- a/src/Language/Haskell/Liquid/Types/PredType.hs
+++ b/src/Language/Haskell/Liquid/Types/PredType.hs
@@ -33,7 +33,7 @@
 import qualified TyCon                           as TC
 import           Type
 import           TypeRep
-
+import           Data.Hashable
 import qualified Data.HashMap.Strict             as M
 import           Data.List                       (foldl', partition)
 
@@ -52,15 +52,19 @@
 
 import           Data.Default
 
+makeTyConInfo :: [(TC.TyCon, TyConP)] -> M.HashMap TC.TyCon RTyCon
 makeTyConInfo = hashMapMapWithKey mkRTyCon . M.fromList
 
 mkRTyCon ::  TC.TyCon -> TyConP -> RTyCon
-mkRTyCon tc (TyConP αs' ps _ tyvariance predvariance size) = RTyCon tc pvs' (mkTyConInfo tc tyvariance predvariance size)
-  where τs   = [rVar α :: RSort |  α <- tyConTyVarsDef tc]
-        pvs' = subts (zip αs' τs) <$> ps
+mkRTyCon tc (TyConP _ αs' ps _ tyvariance predvariance size)
+  = RTyCon tc pvs' (mkTyConInfo tc tyvariance predvariance size)
+  where
+    τs   = [rVar α :: RSort |  α <- tyConTyVarsDef tc]
+    pvs' = subts (zip αs' τs) <$> ps
 
 dataConPSpecType :: DataCon -> DataConP -> SpecType
-dataConPSpecType dc (DataConP _ vs ps ls cs yts rt _) = mkArrow vs ps ls ts' rt'
+dataConPSpecType dc (DataConP _ vs ps ls cs yts rt _)
+  = mkArrow makeVars ps ls ts' rt'
   where
     (xs, ts) = unzip $ reverse yts
     -- mkDSym   = (`mappend` symbol dc) . (`mappend` "_") . symbol
@@ -75,33 +79,39 @@
     su       = F.mkSubst [(x, F.EVar y) | (x, y) <- zip xs ys]
     rt'      = subst su rt
 
+
+    makeVars = zipWith (\v a -> RTVar v (rTVarInfo a :: RTVInfo RSort)) vs (fst $ splitForAllTys $ dataConRepType dc)
+
 instance PPrint TyConP where
-  pprintTidy k (TyConP vs ps ls _ _ _)
-    = (parens $ hsep (punctuate comma (map (pprintTidy k) vs))) <+>
-      (parens $ hsep (punctuate comma (map (pprintTidy k) ps))) <+>
-      (parens $ hsep (punctuate comma (map (pprintTidy k) ls)))
+  pprintTidy k (TyConP _ vs ps ls _ _ _)
+    = (parens $ hsep (punctuate comma (pprintTidy k <$> vs))) <+>
+      (parens $ hsep (punctuate comma (pprintTidy k <$> ps))) <+>
+      (parens $ hsep (punctuate comma (pprintTidy k <$> ls)))
 
 instance Show TyConP where
  show = showpp -- showSDoc . ppr
 
 instance PPrint DataConP where
   pprintTidy k (DataConP _ vs ps ls cs yts t _)
-     = (parens $ hsep (punctuate comma (map (pprintTidy k) vs))) <+>
-       (parens $ hsep (punctuate comma (map (pprintTidy k) ps))) <+>
-       (parens $ hsep (punctuate comma (map (pprintTidy k) ls))) <+>
-       (parens $ hsep (punctuate comma (map (pprintTidy k) cs))) <+>
-       (parens $ hsep (punctuate comma (map (pprintTidy k) yts))) <+>
+     = (parens $ hsep (punctuate comma (pprintTidy k <$> vs)))  <+>
+       (parens $ hsep (punctuate comma (pprintTidy k <$> ps)))  <+>
+       (parens $ hsep (punctuate comma (pprintTidy k <$> ls)))  <+>
+       (parens $ hsep (punctuate comma (pprintTidy k <$> cs)))  <+>
+       (parens $ hsep (punctuate comma (pprintTidy k <$> yts))) <+>
        pprintTidy k t
 
 instance Show DataConP where
   show = showpp
 
+dataConTy :: Monoid r
+          => M.HashMap RTyVar (RType RTyCon RTyVar r)
+          -> Type -> RType RTyCon RTyVar r
 dataConTy m (TyVarTy v)
   = M.lookupDefault (rVar v) (RTV v) m
 dataConTy m (FunTy t1 t2)
   = rFun dummySymbol (dataConTy m t1) (dataConTy m t2)
 dataConTy m (ForAllTy α t)
-  = RAllT (rTyVar α) (dataConTy m t)
+  = RAllT (makeRTVar $ RTV α) (dataConTy m t)
 dataConTy m (TyConApp c ts)
   = rApp c (dataConTy m <$> ts) [] mempty
 dataConTy _ _
@@ -111,6 +121,8 @@
 ----- Interface: Replace Predicate With Uninterprented Function Symbol -----
 ----------------------------------------------------------------------------
 
+replacePredsWithRefs :: (UsedPVar, (Symbol, [((), Symbol, F.Expr)]) -> F.Expr)
+                     -> UReft Reft -> UReft Reft
 replacePredsWithRefs (p, r) (MkUReft (Reft(v, rs)) (Pr ps) s)
   = MkUReft (Reft (v, rs'')) (Pr ps2) s
   where
@@ -118,6 +130,7 @@
     rs'              = r . (v,) . pargs <$> ps1
     (ps1, ps2)       = partition (== p) ps
 
+pVartoRConc :: PVar t -> (Symbol, [(a, b, F.Expr)]) -> F.Expr
 pVartoRConc p (v, args) | length args == length (pargs p)
   = pApp (pname p) $ EVar v : (thd3 <$> args)
 
@@ -142,6 +155,9 @@
 
 
 -- rpredType    :: (PPrint r, Reftable r) => PVKind (RRType r) -> [RRType r] -> RRType r
+rpredType :: Reftable r
+          => PVKind (RType RTyCon tv a)
+          -> [RType RTyCon tv a] -> RType RTyCon tv r
 rpredType (PVProp t) ts = RApp predRTyCon  (uRTypeGen <$> t : ts) [] mempty
 rpredType PVHProp    ts = RApp wpredRTyCon (uRTypeGen <$>     ts) [] mempty
 
@@ -219,6 +235,21 @@
 -- | Requires: @not $ null πs@
 -- substRCon :: String -> (RPVar, SpecType) -> SpecType -> SpecType
 
+substRCon
+  :: (PPrint t, PPrint t2, Eq tv, Reftable r, Hashable tv, PPrint tv, PPrint r,
+      SubsTy tv (RType RTyCon tv ()) r,
+      SubsTy tv (RType RTyCon tv ()) (RType RTyCon tv ()),
+      SubsTy tv (RType RTyCon tv ()) RTyCon,
+      SubsTy tv (RType RTyCon tv ()) tv,
+      Reftable (RType RTyCon tv r),
+      SubsTy tv (RType RTyCon tv ()) (RTVar tv (RType RTyCon tv ())),
+      FreeVar RTyCon tv)
+  => [Char]
+  -> (t, Ref RSort (RType RTyCon tv r))
+  -> RType RTyCon tv r
+  -> [PVar t2]
+  -> r
+  -> RType RTyCon tv r
 substRCon msg (_, RProp ss t1@(RApp c1 ts1 rs1 r1)) t2@(RApp c2 ts2 rs2 _) πs r2'
   | rtc_tc c1 == rtc_tc c2 = RApp c1 ts rs $ meetListWithPSubs πs ss r1 r2'
   where
@@ -235,6 +266,7 @@
 
 substRCon msg su t _ _        = panic Nothing $ msg ++ " substRCon " ++ showpp (su, t)
 
+pad :: [Char] -> (a -> a) -> [a] -> [a] -> ([a], [a])
 pad _ f [] ys   = (f <$> ys, ys)
 pad _ f xs []   = (xs, f <$> xs)
 pad msg _ xs ys
@@ -244,6 +276,10 @@
     nxs         = length xs
     nys         = length ys
 
+substPredP :: [Char]
+           -> (RPVar, Ref RSort (RRType RReft))
+           -> Ref RSort (RType RTyCon RTyVar RReft)
+           -> Ref RSort SpecType
 substPredP _ su p@(RProp _ (RHole _))
   = panic Nothing ("PredType.substPredP1 called on invalid inputs: " ++ showpp (su, p))
 substPredP msg su@(p, RProp ss _) (RProp s t)
@@ -253,11 +289,13 @@
    n   = length ss - length (freeArgsPs p t)
 
 
+splitRPvar :: PVar t -> UReft r -> (UReft r, [UsedPVar])
 splitRPvar pv (MkUReft x (Pr pvs) s) = (MkUReft x (Pr pvs') s, epvs)
   where
     (epvs, pvs')               = partition (uPVar pv ==) pvs
 
 -- TODO: rewrite using foldReft
+freeArgsPs :: PVar (RType t t1 ()) -> RType t t1 (UReft t2) -> [Symbol]
 freeArgsPs p (RVar _ r)
   = freeArgsPsRef p r
 freeArgsPs p (RFun _ t1 t2 r)
@@ -284,13 +322,22 @@
 freeArgsPs p (RRTy env r _ t)
   = nub $ concatMap (freeArgsPs p) (snd <$> env) ++ freeArgsPsRef p r ++ freeArgsPs p t
 
+freeArgsPsRef :: PVar t1 -> UReft t -> [Symbol]
 freeArgsPsRef p (MkUReft _ (Pr ps) _) = [x | (_, x, w) <- (concatMap pargs ps'),  (EVar x) == w]
   where
    ps' = f <$> filter (uPVar p ==) ps
    f q = q {pargs = pargs q ++ drop (length (pargs q)) (pargs $ uPVar p)}
 
+meetListWithPSubs :: (Foldable t, PPrint t1, Reftable b)
+                  => t (PVar t1) -> [(Symbol, RSort)] -> b -> b -> b
 meetListWithPSubs πs ss r1 r2    = foldl' (meetListWithPSub ss r1) r2 πs
 
+meetListWithPSubsRef :: (Foldable t, Reftable (RType t1 t2 t3))
+                     => t (PVar t4)
+                     -> [(Symbol, b)]
+                     -> Ref τ (RType t1 t2 t3)
+                     -> Ref τ (RType t1 t2 t3)
+                     -> Ref τ (RType t1 t2 t3)
 meetListWithPSubsRef πs ss r1 r2 = foldl' ((meetListWithPSubRef ss) r1) r2 πs
 
 meetListWithPSub ::  (Reftable r, PPrint t) => [(Symbol, RSort)]-> r -> r -> PVar t -> r
@@ -304,6 +351,12 @@
   where
     su  = mkSubst [(x, y) | (x, (_, _, y)) <- zip (fst <$> ss) (pargs π)]
 
+meetListWithPSubRef :: (Reftable (RType t t1 t2))
+                    => [(Symbol, b)]
+                    -> Ref τ (RType t t1 t2)
+                    -> Ref τ (RType t t1 t2)
+                    -> PVar t3
+                    -> Ref τ (RType t t1 t2)
 meetListWithPSubRef _ (RProp _ (RHole _)) _ _ -- TODO: Is this correct?
   = panic Nothing "PredType.meetListWithPSubRef called with invalid input"
 meetListWithPSubRef _ _ (RProp _ (RHole _)) _
@@ -330,6 +383,7 @@
 predName   = "Pred"
 wpredName  = "WPred"
 
+symbolType :: Symbol -> Type
 symbolType = TyVarTy . symbolTyVar
 
 
@@ -352,4 +406,5 @@
     args   = FVar <$> [n..(2*n-1)]
 
 
+predFTyCon :: FTycon
 predFTyCon = symbolFTycon $ dummyLoc predName
diff --git a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs
--- a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs
+++ b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs
@@ -1,17 +1,18 @@
 -- | This module contains a single function that converts a RType -> Doc
 --   without using *any* simplifications.
 
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ConstraintKinds   #-}
-{-# LANGUAGE FlexibleContexts  #-}
-{-# LANGUAGE TupleSections     #-}
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE ConstraintKinds      #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE TupleSections        #-}
+{-# LANGUAGE UndecidableInstances #-}
 
 module Language.Haskell.Liquid.Types.PrettyPrint
   ( -- * Printable RTypes
     OkRT
+
     -- * Printers
   , rtypeDoc
-  , ppr_rtype
 
   -- * Printing Lists (TODO: move to fixpoint)
   , pprManyOrdered
@@ -20,22 +21,23 @@
 
   ) where
 
-import           Prelude hiding (error)
-import           TypeRep hiding (maybeParen)
+import qualified Data.HashMap.Strict              as M
+import qualified Data.List                        as L                               -- (sort)
+import           Data.String
 import           ErrUtils                         (ErrMsg)
-import           HscTypes                         (SourceError)
-import           SrcLoc
 import           GHC                              (Name, Class)
-import           Var              (Var)
-import           TyCon            (TyCon)
-import qualified Data.List    as L -- (sort)
-import qualified Data.HashMap.Strict as M
-import           Text.PrettyPrint.HughesPJ
+import           HscTypes                         (SourceError)
 import           Language.Fixpoint.Misc
-import           Language.Haskell.Liquid.Misc
+import           Language.Fixpoint.Types          hiding (Error, SrcSpan, Predicate)
 import           Language.Haskell.Liquid.GHC.Misc
-import           Language.Fixpoint.Types       hiding (Error, SrcSpan, Predicate)
-import           Language.Haskell.Liquid.Types hiding (sort)
+import           Language.Haskell.Liquid.Misc
+import           Language.Haskell.Liquid.Types    hiding (sort)
+import           Prelude                          hiding (error)
+import           SrcLoc
+import           Text.PrettyPrint.HughesPJ
+import           TyCon                            (TyCon)
+import           TypeRep                          hiding (maybeParen)
+import           Var                              (Var)
 
 --------------------------------------------------------------------------------
 pprManyOrdered :: (PPrint a, Ord a) => Tidy -> String -> [a] -> [Doc]
@@ -43,9 +45,9 @@
 pprManyOrdered k msg = map ((text msg <+>) . pprintTidy k) . L.sort
 
 --------------------------------------------------------------------------------
-pprintLongList :: PPrint a => [a] -> Doc
+pprintLongList :: PPrint a => Tidy -> [a] -> Doc
 --------------------------------------------------------------------------------
-pprintLongList = brackets . vcat . map pprint
+pprintLongList k = brackets . vcat . map (pprintTidy k)
 
 
 --------------------------------------------------------------------------------
@@ -70,13 +72,15 @@
   pprintTidy _ = pprDoc
 
 instance PPrint TyCon where
-  pprintTidy _ = pprDoc
+  pprintTidy Lossy = shortModules . pprDoc
+  pprintTidy Full  =                pprDoc
 
 instance PPrint Type where
   pprintTidy _ = pprDoc -- . tidyType emptyTidyEnv -- WHY WOULD YOU DO THIS???
 
 instance PPrint Class where
-  pprintTidy _ = pprDoc
+  pprintTidy Lossy = shortModules . pprDoc
+  pprintTidy Full  =                pprDoc
 
 instance Show Predicate where
   show = showpp
@@ -88,48 +92,63 @@
   pprintTidy _ (AnnLoc l) = text "AnnLoc" <+> pprDoc l
 
 instance PPrint a => PPrint (AnnInfo a) where
-  pprintTidy _ (AI m) = vcat $ map pprAnnInfoBinds $ M.toList m
+  pprintTidy k (AI m) = vcat $ pprAnnInfoBinds k <$> M.toList m
 
 instance PPrint a => Show (AnnInfo a) where
   show = showpp
 
-pprAnnInfoBinds (l, xvs)
-  = vcat $ map (pprAnnInfoBind . (l,)) xvs
+pprAnnInfoBinds :: (PPrint a, PPrint b) => Tidy -> (SrcSpan, [(Maybe a, b)]) -> Doc
+pprAnnInfoBinds k (l, xvs)
+  = vcat $ (pprAnnInfoBind k . (l,)) <$> xvs
 
-pprAnnInfoBind (RealSrcSpan k, xv)
-  = xd $$ pprDoc l $$ pprDoc c $$ pprint n $$ vd $$ text "\n\n\n"
+pprAnnInfoBind :: (PPrint a, PPrint b) => Tidy -> (SrcSpan, (Maybe a, b)) -> Doc
+pprAnnInfoBind k (RealSrcSpan sp, xv)
+  = xd $$ pprDoc l $$ pprDoc c $$ pprintTidy k n $$ vd $$ text "\n\n\n"
     where
-      l        = srcSpanStartLine k
-      c        = srcSpanStartCol k
-      (xd, vd) = pprXOT xv
+      l        = srcSpanStartLine sp
+      c        = srcSpanStartCol sp
+      (xd, vd) = pprXOT k xv
       n        = length $ lines $ render vd
 
-pprAnnInfoBind (_, _)
+pprAnnInfoBind _ (_, _)
   = empty
 
-pprXOT (x, v) = (xd, pprint v)
+pprXOT :: (PPrint a, PPrint a1) => Tidy -> (Maybe a, a1) -> (Doc, Doc)
+pprXOT k (x, v) = (xd, pprintTidy k v)
   where
-    xd = maybe (text "unknown") pprint x
+    xd          = maybe "unknown" (pprintTidy k) x
+
+instance PPrint LMap where
+  pprintTidy _ (LMap x xs e) = hcat [pprint x, pprint xs, text "|->", pprint e ]
+
+instance PPrint LogicMap where
+  pprintTidy _ (LM lm am) = vcat [ text "Logic Map"
+                                 , nest 2 $ text "logic-map"
+                                 , nest 4 $ pprint lm
+                                 , nest 2 $ text "axiom-map"
+                                 , nest 4 $ pprint am
+                                 ]
 --------------------------------------------------------------------------------
 -- | Pretty Printing RefType ---------------------------------------------------
 --------------------------------------------------------------------------------
+instance (OkRT c tv r) => PPrint (RType c tv r) where
+  -- RJ: THIS IS THE CRUCIAL LINE, the following prints short types.
+  pprintTidy _ = rtypeDoc Lossy
+  -- pprintTidy _ = ppRType TopPrec
 
--- Should just make this a @Pretty@ instance but its too damn tedious
--- to figure out all the constraints.
+instance (PPrint tv, PPrint ty) => PPrint (RTAlias tv ty) where
+  pprintTidy = ppAlias
 
-type OkRT c tv r = ( TyConable c
-                   , PPrint tv
-                   , PPrint c
-                   , PPrint r
-                   , Reftable r
-                   , Reftable (RTProp c tv ())
-                   , Reftable (RTProp c tv r)
-                   , RefTypable c tv ()
-                   , RefTypable c tv r
-                   , PPrint (RType c tv r)
-                   , PPrint (RType c tv ())
-                   )
+ppAlias :: (PPrint tv, PPrint ty) => Tidy -> RTAlias tv ty -> Doc
+ppAlias k a = text "type" <+> pprint (rtName a)
+                          <+> pprints k space (rtTArgs a)
+                          <+> pprints k space (rtVArgs a)
+                          <+> text " = "
+                          <+> pprint (rtBody a)
 
+pprints :: (PPrint a) => Tidy -> Doc -> [a] -> Doc
+pprints k c = sep . punctuate c . map (pprintTidy k)
+
 --------------------------------------------------------------------------------
 rtypeDoc :: (OkRT c tv r) => Tidy -> RType c tv r -> Doc
 --------------------------------------------------------------------------------
@@ -138,6 +157,10 @@
     ppE Lossy = ppEnvShort ppEnv
     ppE Full  = ppEnv
 
+instance PPrint Tidy where
+  pprintTidy _ Full  = "Full"
+  pprintTidy _ Lossy = "Lossy"
+
 --------------------------------------------------------------------------------
 ppr_rtype :: (OkRT c tv r) => PPEnv -> Prec -> RType c tv r -> Doc
 --------------------------------------------------------------------------------
@@ -149,8 +172,8 @@
   = ppr_forall bb p t
 ppr_rtype _ _ (RVar a r)
   = ppTy r $ pprint a
-ppr_rtype bb p t@(RFun _ _ _ r)
-  = ppTy r $ maybeParen p FunPrec $ ppr_rty_fun bb empty t
+ppr_rtype bb p t@(RFun _ _ _ _)
+  = maybeParen p FunPrec $ ppr_rty_fun bb empty t
 ppr_rtype bb p (RApp c [t] rs r)
   | isList c
   = ppTy r $ brackets (ppr_rtype bb p t) <> ppReftPs bb p rs
@@ -186,10 +209,17 @@
 ppr_rtype _ _ (RHole r)
   = ppTy r $ text "_"
 
+ppTyConB :: TyConable c => PPEnv -> c -> Doc
 ppTyConB bb
-  | ppShort bb = text . symbolString . dropModuleNames . symbol . render . ppTycon
+  | ppShort bb = shortModules . ppTycon
   | otherwise  = ppTycon
 
+shortModules :: Doc -> Doc
+shortModules = text . symbolString . dropModuleNames . symbol . render
+
+ppr_rsubtype
+  :: (OkRT c tv r, PPrint a, PPrint (RType c tv r), PPrint (RType c tv ()))
+  => PPEnv -> Prec -> [(a, RType c tv r)] -> Doc
 ppr_rsubtype bb p e
   = pprint_env <+> text "|-" <+> ppr_rtype bb p tl <+> "<:" <+> ppr_rtype bb p tr
   where
@@ -200,48 +230,44 @@
     pprint_bind (x, t) = pprint x <+> colon <> colon <+> ppr_rtype bb p t
     pprint_env         = hsep $ punctuate comma (pprint_bind <$> env)
 
-{- NUKE?
-ppSpine (RAllT _ t)      = text "RAllT" <+> parens (ppSpine t)
-ppSpine (RAllP _ t)      = text "RAllP" <+> parens (ppSpine t)
-ppSpine (RAllS _ t)      = text "RAllS" <+> parens (ppSpine t)
-ppSpine (RAllE _ _ t)    = text "RAllE" <+> parens (ppSpine t)
-ppSpine (REx _ _ t)      = text "REx" <+> parens (ppSpine t)
-ppSpine (RFun _ i o _)   = ppSpine i <+> text "->" <+> ppSpine o
-ppSpine (RAppTy t t' _)  = text "RAppTy" <+> parens (ppSpine t) <+> parens (ppSpine t')
-ppSpine (RHole _)        = text "RHole"
-ppSpine (RApp c _ _ _)   = text "RApp" <+> parens (pprint c)
-ppSpine (RVar _ _)       = text "RVar"
-ppSpine (RExprArg _)     = text "RExprArg"
-ppSpine (RRTy _ _ _ _)   = text "RRTy"
-
--}
-
 -- | From GHC: TypeRep
 maybeParen :: Prec -> Prec -> Doc -> Doc
 maybeParen ctxt_prec inner_prec pretty
   | ctxt_prec < inner_prec = pretty
   | otherwise                  = parens pretty
 
--- ppExists :: (RefTypable p c tv (), RefTypable p c tv r) => Bool -> Prec -> RType p c tv r -> Doc
+ppExists
+  :: (OkRT c tv r, PPrint c, PPrint tv, PPrint (RType c tv r),
+      PPrint (RType c tv ()), Reftable (RTProp c tv r),
+      Reftable (RTProp c tv ()))
+  => PPEnv -> Prec -> RType c tv r -> Doc
 ppExists bb p t
   = text "exists" <+> brackets (intersperse comma [ppr_dbind bb TopPrec x t | (x, t) <- zs]) <> dot <> ppr_rtype bb p t'
     where (zs,  t')               = split [] t
           split zs (REx x t t')   = split ((x,t):zs) t'
           split zs t                = (reverse zs, t)
 
--- ppAllExpr :: (RefTypable p c tv (), RefTypable p c tv r) => Bool -> Prec -> RType p c tv r -> Doc
+ppAllExpr
+  :: (OkRT c tv r, PPrint (RType c tv r), PPrint (RType c tv ()))
+  => PPEnv -> Prec -> RType c tv r -> Doc
 ppAllExpr bb p t
   = text "forall" <+> brackets (intersperse comma [ppr_dbind bb TopPrec x t | (x, t) <- zs]) <> dot <> ppr_rtype bb p t'
     where (zs,  t')               = split [] t
           split zs (RAllE x t t') = split ((x,t):zs) t'
           split zs t                = (reverse zs, t)
 
+ppReftPs
+  :: (OkRT c tv r, PPrint (RType c tv r), PPrint (RType c tv ()),
+      Reftable (Ref (RType c tv ()) (RType c tv r)))
+  => t -> t1 -> [Ref (RType c tv ()) (RType c tv r)] -> Doc
 ppReftPs _ _ rs
   | all isTauto rs   = empty
   | not (ppPs ppEnv) = empty
   | otherwise        = angleBrackets $ hsep $ punctuate comma $ ppr_ref <$> rs
 
--- ppr_dbind :: (RefTypable p c tv (), RefTypable p c tv r) => Bool -> Prec -> Symbol -> RType p c tv r -> Doc
+ppr_dbind
+  :: (OkRT c tv r, PPrint (RType c tv r), PPrint (RType c tv ()))
+  => PPEnv -> Prec -> Symbol -> RType c tv r -> Doc
 ppr_dbind bb p x t
   | isNonSymbol x || (x == dummySymbol)
   = ppr_rtype bb p t
@@ -249,16 +275,20 @@
   = pprint x <> colon <> ppr_rtype bb p t
 
 
+ppr_rty_fun
+  :: ( OkRT c tv r, PPrint (RType c tv r), PPrint (RType c tv ()))
+  => PPEnv -> Doc -> RType c tv r -> Doc
 ppr_rty_fun bb prefix t
   = prefix <+> ppr_rty_fun' bb t
 
-ppr_rty_fun' bb (RFun b t t' _)
-  = ppr_dbind bb FunPrec b t <+> ppr_rty_fun bb arrow t'
+ppr_rty_fun'
+  :: ( OkRT c tv r, PPrint (RType c tv r), PPrint (RType c tv ()))
+  => PPEnv -> RType c tv r -> Doc
+ppr_rty_fun' bb (RFun b t t' r)
+  = ppTy r $ ppr_dbind bb FunPrec b t <+> ppr_rty_fun bb arrow t'
 ppr_rty_fun' bb t
   = ppr_rtype bb TopPrec t
 
-
--- ppr_forall :: (RefTypable p c tv (), RefTypable p c tv r) => Bool -> Prec -> RType p c tv r -> Doc
 ppr_forall :: (OkRT c tv r) => PPEnv -> Prec -> RType c tv r -> Doc
 ppr_forall bb p t = maybeParen p FunPrec $ sep [
                       ppr_foralls (ppPs bb) (ty_vars trep) (ty_preds trep) (ty_labels trep)
@@ -276,17 +306,24 @@
     ppr_clss []               = empty
     ppr_clss cs               = (parens $ hsep $ punctuate comma (uncurry (ppr_cls bb p) <$> cs)) <+> text "=>"
 
-    dαs αs                    = sep $ pprint <$> αs
+    dαs αs                    = ppr_rtvar_def αs
 
     -- dπs :: Bool -> [PVar a] -> Doc
     dπs _ []                  = empty
     dπs False _               = empty
     dπs True πs               = angleBrackets $ intersperse comma $ ppr_pvar_def bb p <$> πs
 
+ppr_rtvar_def :: (PPrint tv) => [RTVar tv (RType c tv ())] -> Doc
+ppr_rtvar_def = sep . map (pprint . ty_var_value)
+
 ppr_symbols :: [Symbol] -> Doc
 ppr_symbols [] = empty
 ppr_symbols ss = angleBrackets $ intersperse comma $ pprint <$> ss
 
+ppr_cls
+  :: (OkRT c tv r, PPrint a, PPrint (RType c tv r),
+      PPrint (RType c tv ()))
+  => PPEnv -> Prec -> a -> [RType c tv r] -> Doc
 ppr_cls bb p c ts
   = pp c <+> hsep (map (ppr_rtype bb p) ts)
   where
@@ -302,8 +339,10 @@
 
 
 ppr_pvar_kind :: (OkRT c tv ()) => PPEnv -> Prec -> PVKind (RType c tv ()) -> Doc
-ppr_pvar_kind bb p (PVProp t) = ppr_pvar_sort bb p t <+> arrow <+> ppr_name propConName
-ppr_pvar_kind _ _ (PVHProp)   = ppr_name hpropConName
+ppr_pvar_kind bb p (PVProp t) = ppr_pvar_sort bb p t <+> arrow <+> ppr_name boolConName -- propConName
+ppr_pvar_kind _ _ (PVHProp)   = panic Nothing "TODO: ppr_pvar_kind:hprop" -- ppr_name hpropConName
+
+ppr_name :: Symbol -> Doc
 ppr_name                      = text . symbolString
 
 ppr_pvar_sort :: (OkRT c tv ()) => PPEnv -> Prec -> RType c tv () -> Doc
@@ -317,15 +356,17 @@
 ppRefArgs [] = empty
 ppRefArgs ss = text "\\" <> hsep (ppRefSym <$> ss ++ [vv Nothing]) <+> text "->"
 
+ppRefSym :: (Eq a, IsString a, PPrint a) => a -> Doc
 ppRefSym "" = text "_"
 ppRefSym s  = pprint s
 
+dot :: Doc
 dot                = char '.'
 
 instance (PPrint r, Reftable r) => PPrint (UReft r) where
   pprintTidy k (MkUReft r p _)
-    --- | isTauto r  = pprintTidy k p
-    --- | isTauto p  = pprintTidy k r
+    | isTauto r  = pprintTidy k p
+    | isTauto p  = pprintTidy k r
     | otherwise  = pprintTidy k p <> text " & " <> pprintTidy k r
 
 --------------------------------------------------------------------------------
diff --git a/src/Language/Haskell/Liquid/Types/RefType.hs b/src/Language/Haskell/Liquid/Types/RefType.hs
--- a/src/Language/Haskell/Liquid/Types/RefType.hs
+++ b/src/Language/Haskell/Liquid/Types/RefType.hs
@@ -11,11 +11,13 @@
 {-# LANGUAGE RankNTypes                #-}
 {-# LANGUAGE GADTs                     #-}
 {-# LANGUAGE PatternGuards             #-}
+{-# LANGUAGE ImplicitParams            #-}
+{-# LANGUAGE ConstraintKinds           #-}
 
 -- | Refinement Types. Mostly mirroring the GHC Type definition, but with
 --   room for refinements of various sorts.
-
 -- TODO: Desperately needs re-organization.
+
 module Language.Haskell.Liquid.Types.RefType (
 
   -- * Functions for lifting Reft-values to Spec-values
@@ -31,44 +33,59 @@
   -- * Functions for manipulating `Predicate`s
   , pdVar
   , findPVar
-  , freeTyVars, tyClasses, tyConName
+  , FreeVar, freeTyVars, tyClasses, tyConName
 
-  -- TODO: categorize these!
-  , ofType, toType
-  , rTyVar, rVar, rApp, rEx
-  , symbolRTyVar
-  , addTyConInfo
-  , appRTyCon
-  , typeSort, typeUniqueSymbol
-  , strengthen
-  , generalize, normalizePds
+  -- * Quantifying RTypes
+  , quantifyRTy
+  , quantifyFreeRTy
+
+  -- * RType constructors
+  , ofType, toType, bareOfType
+  , bTyVar, rTyVar, rVar, rApp, rEx
+  , symbolRTyVar, bareRTyVar
+  , tyConBTyCon
+
+  -- * Substitutions
   , subts, subvPredicate, subvUReft
   , subsTyVar_meet, subsTyVar_meet', subsTyVar_nomeet
   , subsTyVars_nomeet, subsTyVars_meet
-  , dataConMsReft, dataConReft
-  , classBinds
 
+  -- * Destructors
+  , addTyConInfo
+  , appRTyCon
+  , typeUniqueSymbol
+  , classBinds
   , isSizeable
 
+
   -- * Manipulating Refinements in RTypes
+  , strengthen
+  , generalize
+  , normalizePds
+  , dataConMsReft
+  , dataConReft
   , rTypeSortedReft
   , rTypeSort
+  , typeSort
   , shiftVV
 
+  -- * TODO: classify these
   , mkDataConIdsTy
   , mkTyConInfo
-
   , meetable
   , strengthenRefTypeGen
   , strengthenDataConType
-
   , isBaseTy
+  , updateRTVar, isValKind, kindToRType
+  , rTVarInfo
 
   ) where
 
+-- import           GHC.Stack
 import Prelude hiding (error)
 import WwLib
 import FamInstEnv (emptyFamInstEnv)
+import Name             hiding (varName)
 import Var
 import Kind
 import GHC              hiding (Located)
@@ -77,7 +94,7 @@
 import TypeRep          hiding (maybeParen, pprArrowChain)
 import Type             (splitFunTys, expandTypeSynonyms, substTyWith, isClassPred)
 import TysWiredIn       (listTyCon, intDataCon, trueDataCon, falseDataCon,
-                         intTyCon, charTyCon)
+                         intTyCon, charTyCon, typeNatKind, typeSymbolKind, stringTy, intTy)
 
 -- import           Data.Monoid      hiding ((<>))
 import           Data.Maybe               (fromMaybe, isJust, fromJust)
@@ -93,8 +110,8 @@
 import Language.Haskell.Liquid.Types.Errors
 import Language.Haskell.Liquid.Types.PrettyPrint
 import qualified Language.Fixpoint.Types as F
-import Language.Fixpoint.Types hiding (shiftVV, Predicate)
-import Language.Fixpoint.Types.Visitor (mapKVars)
+import Language.Fixpoint.Types hiding (shiftVV, Predicate, isNumeric)
+import Language.Fixpoint.Types.Visitor (mapKVars, Visitable)
 import Language.Haskell.Liquid.Types hiding (R, DataConP (..), sort)
 
 import Language.Haskell.Liquid.Types.Variance
@@ -102,11 +119,15 @@
 import Language.Haskell.Liquid.Misc
 import Language.Haskell.Liquid.Types.Names
 import Language.Fixpoint.Misc
-import Language.Haskell.Liquid.GHC.Misc (typeUniqueString, tvId, showPpr, stringTyVar, tyConTyVarsDef)
+import Language.Haskell.Liquid.GHC.Misc (locNamedThing, typeUniqueString, showPpr, stringTyVar, tyConTyVarsDef)
+import Language.Haskell.Liquid.GHC.Play (mapType, stringClassArg)
 
 import Data.List (sort, foldl')
 
+-- -- import Debug.Trace
 
+strengthenDataConType :: Symbolic t
+                      => (t, RType c tv (UReft Reft)) -> (t, RType c tv (UReft Reft))
 strengthenDataConType (x, t) = (x, fromRTypeRep trep{ty_res = tres})
     where
       trep = toRTypeRep t
@@ -118,13 +139,14 @@
            | null xs            = mkEApp (dummyLoc x') []
            | otherwise          = mkEApp (dummyLoc x') (EVar <$> xs)
 
+pdVar :: PVar t -> Predicate
 pdVar v        = Pr [uPVar v]
 
 findPVar :: [PVar (RType c tv ())] -> UsedPVar -> PVar (RType c tv ())
-findPVar ps p
-  = PV name ty v (zipWith (\(_, _, e) (t, s, _) -> (t, s, e)) (pargs p) args)
-  where PV name ty v args = fromMaybe (msg p) $ L.find ((== pname p) . pname) ps
-        msg p = panic Nothing $ "RefType.findPVar" ++ showpp p ++ "not found"
+findPVar ps p = PV name ty v (zipWith (\(_, _, e) (t, s, _) -> (t, s, e)) (pargs p) args)
+  where
+    PV name ty v args = fromMaybe (msg p) $ L.find ((== pname p) . pname) ps
+    msg p = panic Nothing $ "RefType.findPVar" ++ showpp p ++ "not found"
 
 -- | Various functions for converting vanilla `Reft` to `Spec`
 
@@ -155,10 +177,11 @@
 
 instance ( SubsTy tv (RType c tv ()) (RType c tv ())
          , SubsTy tv (RType c tv ()) c
-         , RefTypable c tv ()
-         , RefTypable c tv r
          , OkRT c tv r
          , FreeVar c tv
+         , SubsTy tv (RType c tv ()) r
+         , SubsTy tv (RType c tv ()) tv
+         , SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ()))
          )
         => Monoid (RType c tv r)  where
   mempty  = panic Nothing "mempty: RType"
@@ -168,10 +191,12 @@
 -- MOVE TO TYPES
 instance ( SubsTy tv (RType c tv ()) c
          , OkRT c tv r
-         , RefTypable c tv r
-         , RefTypable c tv ()
          , FreeVar c tv
-         , SubsTy tv (RType c tv ()) (RType c tv ()))
+         , SubsTy tv (RType c tv ()) r
+         , SubsTy tv (RType c tv ()) (RType c tv ())
+         , SubsTy tv (RType c tv ()) tv
+         , SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ()))
+         )
          => Monoid (RTProp c tv r) where
   mempty         = panic Nothing "mempty: RTProp"
 
@@ -188,11 +213,12 @@
                                 (subst (mkSubst $ zip (fst <$> s2) (EVar . fst <$> s1)) t2)
 
 instance ( OkRT c tv r
-         , RefTypable c tv r
-         , RefTypable c tv ()
          , FreeVar c tv
+         , SubsTy tv (RType c tv ()) r
          , SubsTy tv (RType c tv ()) (RType c tv ())
-         , SubsTy tv (RType c tv ()) c) => Reftable (RTProp c tv r) where
+         , SubsTy tv (RType c tv ()) c
+         , SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ()))
+         ) => Reftable (RTProp c tv r) where
   isTauto (RProp _ (RHole r)) = isTauto r
   isTauto (RProp _ t)         = isTrivial t
   top (RProp _ (RHole _))     = panic Nothing "RefType: Reftable top called on (RProp _ (RHole _))"
@@ -229,7 +255,7 @@
 -- | Reftable Instances -------------------------------------------------------
 -------------------------------------------------------------------------------
 
-instance (PPrint r, Reftable r) => Reftable (RType RTyCon RTyVar r) where
+instance (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r) => Reftable (RType RTyCon RTyVar r) where
   isTauto     = isTrivial
   ppTy        = panic Nothing "ppTy RProp Reftable"
   toReft      = panic Nothing "toReft on RType"
@@ -238,11 +264,6 @@
   ofReft      = panic Nothing "ofReft on RType"
 
 
-
--------------------------------------------------------------------------------
--- | RefTypable Instances -----------------------------------------------------
--------------------------------------------------------------------------------
-
 -- MOVE TO TYPES
 instance Fixpoint String where
   toFix = text
@@ -260,15 +281,17 @@
   freeVars = (RTV <$>) . tyConTyVarsDef . rtc_tc
 
 -- MOVE TO TYPES
-instance FreeVar LocSymbol Symbol where
+instance FreeVar BTyCon BTyVar where
   freeVars _ = []
 
 -- Eq Instances ------------------------------------------------------
 
 -- MOVE TO TYPES
-instance (RefTypable c tv ()) => Eq (RType c tv ()) where
+instance (Eq c, Eq tv, Hashable tv) => Eq (RType c tv ()) where
   (==) = eqRSort M.empty
 
+eqRSort :: (Eq a, Eq k, Hashable k)
+        => M.HashMap k k -> RType a k t -> RType a k t1 -> Bool
 eqRSort m (RAllP _ t) (RAllP _ t')
   = eqRSort m t t'
 eqRSort m (RAllS _ t) (RAllS _ t')
@@ -279,7 +302,7 @@
   | a == a'
   = eqRSort m t t'
   | otherwise
-  = eqRSort (M.insert a' a m) t t'
+  = eqRSort (M.insert (ty_var_value a') (ty_var_value a) m) t t'
 eqRSort m (RAllT _ t) t'
   = eqRSort m t t'
 eqRSort m t (RAllT _ t')
@@ -299,24 +322,30 @@
 eqRSort _ _ _
   = False
 
---------------------------------------------------------------------
--- | Wrappers for GHC Type Elements --------------------------------
---------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Wrappers for GHC Type Elements --------------------------------------------
+--------------------------------------------------------------------------------
 
 instance Eq Predicate where
   (==) = eqpd
 
+eqpd :: Predicate -> Predicate -> Bool
 eqpd (Pr vs) (Pr ws)
   = and $ (length vs' == length ws') : [v == w | (v, w) <- zip vs' ws']
-    where vs' = sort vs
-          ws' = sort ws
+    where
+      vs' = sort vs
+      ws' = sort ws
 
 
 instance Eq RTyVar where
-  RTV α == RTV α' = tvId α == tvId α'
+  -- FIXME: need to compare unique and string because we reuse
+  -- uniques in stringTyVar and co.
+  RTV α == RTV α' = α == α' && getOccName α == getOccName α'
 
 instance Ord RTyVar where
-  compare (RTV α) (RTV α') = compare (tvId α) (tvId α')
+  compare (RTV α) (RTV α') = case compare α α' of
+    EQ -> compare (getOccName α) (getOccName α')
+    o  -> o
 
 instance Hashable RTyVar where
   hashWithSalt i (RTV α) = hashWithSalt i α
@@ -327,27 +356,102 @@
 instance Hashable RTyCon where
   hashWithSalt i = hashWithSalt i . rtc_tc
 
---------------------------------------------------------------------
----------------------- Helper Functions ----------------------------
---------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Helper Functions (RJ: Helping to do what?) --------------------------------
+--------------------------------------------------------------------------------
 
-rVar        = (`RVar` mempty) . RTV
-rTyVar      = RTV
+rVar :: Monoid r => TyVar -> RType c RTyVar r
+rVar   = (`RVar` mempty) . RTV
 
+rTyVar :: TyVar -> RTyVar
+rTyVar = RTV
+
+updateRTVar :: Monoid r => RTVar RTyVar i -> RTVar RTyVar (RType RTyCon RTyVar r)
+updateRTVar (RTVar (RTV a) _) = RTVar (RTV a) (rTVarInfo a)
+
+rTVar :: Monoid r => TyVar -> RTVar RTyVar (RRType r)
+rTVar a = RTVar (RTV a) (rTVarInfo a)
+
+bTVar :: Monoid r => TyVar -> RTVar BTyVar (BRType r)
+bTVar a = RTVar (BTV (symbol a)) (bTVarInfo a)
+
+bTVarInfo :: Monoid r => TyVar -> RTVInfo (BRType r)
+bTVarInfo = mkTVarInfo kindToBRType
+
+rTVarInfo :: Monoid r => TyVar -> RTVInfo (RRType r)
+rTVarInfo = mkTVarInfo kindToRType
+
+mkTVarInfo :: (Kind -> s) -> TyVar -> RTVInfo s
+mkTVarInfo k2t a = RTVInfo
+  { rtv_name   = symbol    $ varName a
+  , rtv_kind   = k2t       $ tyVarKind a
+  , rtv_is_val = isValKind $ tyVarKind a
+  }
+
+kindToRType :: Monoid r => Type -> RRType r
+kindToRType = kindToRType_ ofType
+
+kindToBRType :: Monoid r => Type -> BRType r
+kindToBRType = kindToRType_ bareOfType
+
+kindToRType_ :: (Type -> z) -> Type -> z
+kindToRType_ ofType        = ofType . go
+  where
+    go t
+     | t == typeSymbolKind = stringTy
+     | t == typeNatKind    = intTy
+     | otherwise           = t
+
+isValKind :: Kind -> Bool
+isValKind x = x == typeNatKind || x == typeSymbolKind
+
+bTyVar :: Symbol -> BTyVar
+bTyVar      = BTV
+
+symbolRTyVar :: Symbol -> RTyVar
 symbolRTyVar = rTyVar . stringTyVar . symbolString
 
+bareRTyVar :: BTyVar -> RTyVar
+bareRTyVar (BTV tv) = symbolRTyVar tv
+
+normalizePds :: (OkRT c tv r) => RType c tv r -> RType c tv r
 normalizePds t = addPds ps t'
-  where (t', ps) = nlzP [] t
+  where
+    (t', ps)   = nlzP [] t
 
+rPred :: PVar (RType c tv ()) -> RType c tv r -> RType c tv r
 rPred     = RAllP
+
+rEx :: Foldable t
+    => t (Symbol, RType c tv r) -> RType c tv r -> RType c tv r
 rEx xts t = foldr (\(x, tx) t -> REx x tx t) t xts
-rApp c    = RApp (RTyCon c [] (mkTyConInfo c [] [] Nothing))
 
+rApp :: TyCon
+     -> [RType RTyCon tv r]
+     -> [RTProp RTyCon tv r]
+     -> r
+     -> RType RTyCon tv r
+rApp c = RApp (tyConRTyCon c)
+
+tyConRTyCon :: TyCon -> RTyCon
+tyConRTyCon c = RTyCon c [] (mkTyConInfo c [] [] Nothing)
+
+-- bApp :: (Monoid r) => TyCon -> [BRType r] -> BRType r
+bApp :: TyCon -> [BRType r] -> [BRProp r] -> r -> BRType r
+bApp c = RApp (tyConBTyCon c)
+
+tyConBTyCon :: TyCon -> BTyCon
+tyConBTyCon = mkBTyCon . fmap tyConName . locNamedThing
+-- tyConBTyCon = mkBTyCon . fmap symbol . locNamedThing
+
 --- NV TODO : remove this code!!!
 
+addPds :: Foldable t
+       => t (PVar (RType c tv ())) -> RType c tv r -> RType c tv r
 addPds ps (RAllT v t) = RAllT v $ addPds ps t
 addPds ps t           = foldl' (flip rPred) t ps
 
+nlzP :: (OkRT c tv r) => [PVar (RType c tv ())] -> RType c tv r -> (RType c tv r, [PVar (RType c tv ())])
 nlzP ps t@(RVar _ _ )
  = (t, ps)
 nlzP ps (RFun b t1 t2 r)
@@ -379,22 +483,23 @@
  = panic Nothing $ "RefType.nlzP: cannot handle " ++ show t
 
 strengthenRefTypeGen, strengthenRefType ::
-         ( RefTypable c tv ()
-         , RefTypable c tv r
-         , OkRT c tv r
+         (  OkRT c tv r
          , FreeVar c tv
          , SubsTy tv (RType c tv ()) (RType c tv ())
          , SubsTy tv (RType c tv ()) c
+         , SubsTy tv (RType c tv ()) r
+         , SubsTy tv (RType c tv ()) tv
+         , SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ()))
          ) => RType c tv r -> RType c tv r -> RType c tv r
 
 strengthenRefType_ ::
-         ( RefTypable c tv ()
-         , RefTypable c tv r
-         -- , PPrint (RType c tv r)
-         , OkRT c tv r
+         ( OkRT c tv r
          , FreeVar c tv
          , SubsTy tv (RType c tv ()) (RType c tv ())
          , SubsTy tv (RType c tv ()) c
+         , SubsTy tv (RType c tv ()) r
+         , SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ()))
+         , SubsTy tv (RType c tv ()) tv
          ) => (RType c tv r -> RType c tv r -> RType c tv r)
            ->  RType c tv r -> RType c tv r -> RType c tv r
 
@@ -427,8 +532,8 @@
 meetable t1 t2 = toRSort t1 == toRSort t2
 
 strengthenRefType_ f (RAllT a1 t1) (RAllT a2 t2)
-  = RAllT a1 $ strengthenRefType_ f t1 (subsTyVar_meet (a2, toRSort t, t) t2)
-  where t = RVar a1 mempty
+  = RAllT a1 $ strengthenRefType_ f t1 (subsTyVar_meet (ty_var_value a2, toRSort t, t) t2)
+  where t = RVar (ty_var_value a1) mempty
 
 strengthenRefType_ f (RAllT a t1) t2
   = RAllT a $ strengthenRefType_ f t1 t2
@@ -497,9 +602,15 @@
 strengthen t _                  = t
 
 
+quantifyRTy :: Eq tv => [RTVar tv (RType c tv ())] -> RType c tv r -> RType c tv r
+quantifyRTy tvs ty = foldr RAllT ty tvs
 
+quantifyFreeRTy :: Eq tv => RType c tv r -> RType c tv r
+quantifyFreeRTy ty = quantifyRTy (freeTyVars ty) ty
+
+
 -------------------------------------------------------------------------
-addTyConInfo :: (PPrint r, Reftable r)
+addTyConInfo :: (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r)
              => (M.HashMap TyCon FTycon)
              -> (M.HashMap TyCon RTyCon)
              -> RRType r
@@ -508,7 +619,7 @@
 addTyConInfo tce tyi = mapBot (expandRApp tce tyi)
 
 -------------------------------------------------------------------------
-expandRApp :: (PPrint r, Reftable r)
+expandRApp :: (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r)
            => (M.HashMap TyCon FTycon)
            -> (M.HashMap TyCon RTyCon)
            -> RRType r
@@ -532,16 +643,30 @@
 
 expandRApp _ _ t               = t
 
+rtPropTop
+  :: (OkRT c tv r,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+   => PVar (RType c tv ()) -> Ref (RType c tv ()) (RType c tv r)
 rtPropTop pv = case ptype pv of
                  PVProp t -> RProp xts $ ofRSort t
                  PVHProp  -> RProp xts $ mempty
                where
                  xts      =  pvArgs pv
 
-rtPropPV rc = safeZipWith msg mkRTProp
-  where
-    msg     = "appRefts: " ++ showFix rc
+rtPropPV :: (Fixpoint a, Reftable r)
+         => a
+         -> [PVar (RType c tv ())]
+         -> [Ref (RType c tv ()) (RType c tv r)]
+         -> [Ref (RType c tv ()) (RType c tv r)]
+rtPropPV _rc = zipWith mkRTProp
 
+mkRTProp :: Reftable r
+         => PVar (RType c tv ())
+         -> Ref (RType c tv ()) (RType c tv r)
+         -> Ref (RType c tv ()) (RType c tv r)
 mkRTProp pv (RProp ss (RHole r))
   = RProp ss $ (ofRSort $ pvType pv) `strengthen` r
 
@@ -551,9 +676,13 @@
   | otherwise
   = RProp (pvArgs pv) t
 
+pvArgs :: PVar t -> [(Symbol, t)]
 pvArgs pv = [(s, t) | (t, s, _) <- pargs pv]
 
 
+appRTyCon :: SubsTy RTyVar (RType c RTyVar ()) RPVar
+          => M.HashMap TyCon FTycon
+          -> M.HashMap TyCon RTyCon -> RTyCon -> [RType c RTyVar r] -> RTyCon
 appRTyCon tce tyi rc ts = RTyCon c ps' (rtc_info rc'')
   where
     c    = rtc_tc rc
@@ -567,24 +696,27 @@
 
 -- RJ: The code of `isNumeric` is incomprehensible.
 -- Please fix it to use intSort instead of intFTyCon
+isNumeric :: M.HashMap TyCon FTycon -> RTyCon -> Bool
 isNumeric tce c
   =  fromMaybe
        (symbolFTycon . dummyLoc $ tyConName (rtc_tc c))
        (M.lookup (rtc_tc c) tce) == F.intFTyCon
 
+addNumSizeFun :: RTyCon -> RTyCon
 addNumSizeFun c
-  = c {rtc_info = (rtc_info c) {sizeFunction = Just EVar} }
+  = c {rtc_info = (rtc_info c) {sizeFunction = Just IdSizeFun } }
 
 
-generalize :: (RefTypable c tv r) => RType c tv r -> RType c tv r
+generalize :: (Eq tv) => RType c tv r -> RType c tv r
 generalize t = mkUnivs (freeTyVars t) [] [] t
 
+freeTyVars :: Eq tv => RType c tv r -> [RTVar tv (RType c tv ())]
 freeTyVars (RAllP _ t)     = freeTyVars t
 freeTyVars (RAllS _ t)     = freeTyVars t
 freeTyVars (RAllT α t)     = freeTyVars t L.\\ [α]
 freeTyVars (RFun _ t t' _) = freeTyVars t `L.union` freeTyVars t'
 freeTyVars (RApp _ ts _ _) = L.nub $ concatMap freeTyVars ts
-freeTyVars (RVar α _)      = [α]
+freeTyVars (RVar α _)      = [makeRTVar α]
 freeTyVars (RAllE _ tx t)  = freeTyVars tx `L.union` freeTyVars t
 freeTyVars (REx _ tx t)    = freeTyVars tx `L.union` freeTyVars t
 freeTyVars (RExprArg _)    = []
@@ -593,6 +725,7 @@
 freeTyVars (RRTy e _ _ t)  = L.nub $ concatMap freeTyVars (t:(snd <$> e))
 
 
+tyClasses :: (OkRT RTyCon tv r) => RType RTyCon tv r -> [(Class, [RType RTyCon tv r])]
 tyClasses (RAllP _ t)     = tyClasses t
 tyClasses (RAllS _ t)     = tyClasses t
 tyClasses (RAllT _ t)     = tyClasses t
@@ -615,52 +748,162 @@
 -- TODO: Rewrite subsTyvars with Traversable
 --------------------------------------------------------------------------------
 
+subsTyVars_meet
+  :: (Eq tv, Foldable t, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => t (tv, RType c tv (), RType c tv r) -> RType c tv r -> RType c tv r
 subsTyVars_meet        = subsTyVars True
+
+subsTyVars_nomeet
+  :: (Eq tv, Foldable t, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => t (tv, RType c tv (), RType c tv r) -> RType c tv r -> RType c tv r
 subsTyVars_nomeet      = subsTyVars False
+
+subsTyVar_nomeet
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => (tv, RType c tv (), RType c tv r) -> RType c tv r -> RType c tv r
 subsTyVar_nomeet       = subsTyVar False
+
+subsTyVar_meet
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => (tv, RType c tv (), RType c tv r) -> RType c tv r -> RType c tv r
 subsTyVar_meet         = subsTyVar True
+
+subsTyVar_meet'
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => (tv, RType c tv r) -> RType c tv r -> RType c tv r
 subsTyVar_meet' (α, t) = subsTyVar_meet (α, toRSort t, t)
 
+subsTyVars
+  :: (Eq tv, Foldable t, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => Bool
+  -> t (tv, RType c tv (), RType c tv r)
+  -> RType c tv r
+  -> RType c tv r
 subsTyVars meet ats t = foldl' (flip (subsTyVar meet)) t ats
+
+subsTyVar
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => Bool
+  -> (tv, RType c tv (), RType c tv r)
+  -> RType c tv r
+  -> RType c tv r
 subsTyVar meet        = subsFree meet S.empty
 
+subsFree
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => Bool
+  -> S.HashSet tv
+  -> (tv, RType c tv (), RType c tv r)
+  -> RType c tv r
+  -> RType c tv r
 subsFree m s z (RAllS l t)
   = RAllS l (subsFree m s z t)
 subsFree m s z@(α, τ,_) (RAllP π t)
   = RAllP (subt (α, τ) π) (subsFree m s z t)
-subsFree m s z (RAllT α t)
-  = RAllT α $ subsFree m (α `S.insert` s) z t
-subsFree m s z@(_, _, _) (RFun x t t' r)
-  = RFun x (subsFree m s z t) (subsFree m s z t') r
+subsFree m s z@(a, τ, _) (RAllT α t)
+  -- subt inside the type variable instantiates the kind of the variable
+  = RAllT (subt (a, τ) α) $ subsFree m (ty_var_value α `S.insert` s) z t
+subsFree m s z@(α, τ, _) (RFun x t t' r)
+  = RFun x (subsFree m s z t) (subsFree m s z t') (subt (α, τ) r)
 subsFree m s z@(α, τ, _) (RApp c ts rs r)
-  = RApp (subt z' c) (subsFree m s z <$> ts) (subsFreeRef m s z <$> rs) r
+  = RApp (subt z' c) (subsFree m s z <$> ts) (subsFreeRef m s z <$> rs) (subt (α, τ) r)
     where z' = (α, τ) -- UNIFY: why instantiating INSIDE parameters?
-subsFree meet s (α', _, t') t@(RVar α r)
+subsFree meet s (α', τ, t') (RVar α r)
   | α == α' && not (α `S.member` s)
-  = if meet then t' `strengthen` r else t'
+  = if meet then t' `strengthen` (subt (α, τ) r) else t'
   | otherwise
-  = t
+  = RVar (subt (α', τ) α) r
 subsFree m s z (RAllE x t t')
   = RAllE x (subsFree m s z t) (subsFree m s z t')
 subsFree m s z (REx x t t')
   = REx x (subsFree m s z t) (subsFree m s z t')
-subsFree m s z@(_, _, _) (RAppTy t t' r)
-  = subsFreeRAppTy m s (subsFree m s z t) (subsFree m s z t') r
+subsFree m s z@(α, τ, _) (RAppTy t t' r)
+  = subsFreeRAppTy m s (subsFree m s z t) (subsFree m s z t') (subt (α, τ) r)
 subsFree _ _ _ t@(RExprArg _)
   = t
-subsFree m s z (RRTy e r o t)
-  = RRTy (mapSnd (subsFree m s z) <$> e) r o (subsFree m s z t)
-subsFree _ _ _ t@(RHole _)
-  = t
+subsFree m s z@(α, τ, _) (RRTy e r o t)
+  = RRTy (mapSnd (subsFree m s z) <$> e) (subt (α, τ) r) o (subsFree m s z t)
+subsFree _ _ (α, τ, _) (RHole r)
+  = RHole (subt (α, τ) r)
 
-subsFrees m s zs t = foldl' (flip(subsFree m s)) t zs
+subsFrees
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => Bool
+  -> S.HashSet tv
+  -> [(tv, RType c tv (), RType c tv r)]
+  -> RType c tv r
+  -> RType c tv r
+subsFrees m s zs t = foldl' (flip (subsFree m s)) t zs
 
 -- GHC INVARIANT: RApp is Type Application to something other than TYCon
+subsFreeRAppTy
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()),
+      FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => Bool
+  -> S.HashSet tv
+  -> RType c tv r
+  -> RType c tv r
+  -> r
+  -> RType c tv r
 subsFreeRAppTy m s (RApp c ts rs r) t' r'
   = mkRApp m s c (ts ++ [t']) rs r r'
 subsFreeRAppTy _ _ t t' r'
   = RAppTy t t' r'
 
+mkRApp
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => Bool
+  -> S.HashSet tv
+  -> c
+  -> [RType c tv r]
+  -> [RTProp c tv r]
+  -> r
+  -> r
+  -> RType c tv r
 mkRApp m s c ts rs r r'
   | isFun c, [t1, t2] <- ts
   = RFun dummySymbol t1 t2 $ refAppTyToFun r'
@@ -669,28 +912,110 @@
   where
     zs = [(tv, toRSort t, t) | (tv, t) <- zip (freeVars c) ts]
 
+refAppTyToFun :: Reftable r => r -> r
 refAppTyToFun r
   | isTauto r = r
   | otherwise = panic Nothing "RefType.refAppTyToFun"
 
+subsFreeRef
+  :: (Eq tv, Hashable tv, Reftable r, TyConable c,
+      SubsTy tv (RType c tv ()) c, SubsTy tv (RType c tv ()) r,
+      SubsTy tv (RType c tv ()) (RType c tv ()), FreeVar c tv,
+      SubsTy tv (RType c tv ()) tv,
+      SubsTy tv (RType c tv ()) (RTVar tv (RType c tv ())))
+  => Bool
+  -> S.HashSet tv
+  -> (tv, RType c tv (), RType c tv r)
+  -> RTProp c tv r
+  -> RTProp c tv r
 subsFreeRef _ _ (α', τ', _) (RProp ss (RHole r))
   = RProp (mapSnd (subt (α', τ')) <$> ss) (RHole r)
 subsFreeRef m s (α', τ', t')  (RProp ss t)
   = RProp (mapSnd (subt (α', τ')) <$> ss) $ subsFree m s (α', τ', fmap top t') t
 
 
--------------------------------------------------------------------
-------------------- Type Substitutions ----------------------------
--------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Type Substitutions --------------------------------------------------------
+--------------------------------------------------------------------------------
 
+subts :: (Foldable t, SubsTy tv ty c) => t (tv, ty) -> c -> c
 subts = flip (foldr subt)
 
+instance SubsTy RTyVar (RType RTyCon RTyVar ()) RTyVar where
+  subt (RTV x, t) (RTV z) | isTyVar z, tyVarKind z == TyVarTy x
+    = RTV (setVarType z $ toType t)
+  subt _ v
+    = v
+
+instance SubsTy RTyVar (RType RTyCon RTyVar ()) (RTVar RTyVar (RType RTyCon RTyVar ())) where
+  -- NV TODO: update kind
+  subt su rty = rty { ty_var_value = subt su $ ty_var_value rty }
+
+
+instance SubsTy BTyVar (RType c BTyVar ()) BTyVar where
+  subt _ = id
+
+instance SubsTy BTyVar (RType c BTyVar ()) (RTVar BTyVar (RType c BTyVar ())) where
+  subt _ = id
+
 instance SubsTy tv ty ()   where
   subt _ = id
 
-instance SubsTy tv ty Reft where
+instance SubsTy tv ty Symbol where
   subt _ = id
 
+
+
+instance (SubsTy tv ty Expr) => SubsTy tv ty Reft where
+  subt su (Reft (x, e)) = Reft (x, subt su e)
+
+
+instance (SubsTy tv ty Sort) => SubsTy tv ty Expr where
+  subt su (ELam (x, s) e) = ELam (x, subt su s) $ subt su e
+  subt su (EApp e1 e2)    = EApp (subt su e1) (subt su e2)
+  subt su (ENeg e)        = ENeg (subt su e)
+  subt su (PNot e)        = PNot (subt su e)
+  subt su (EBin b e1 e2)  = EBin b (subt su e1) (subt su e2)
+  subt su (EIte e e1 e2)  = EIte (subt su e) (subt su e1) (subt su e2)
+  subt su (ECst e s)      = ECst (subt su e) (subt su s)
+  subt su (ETApp e s)     = ETApp (subt su e) (subt su s)
+  subt su (ETAbs e x)     = ETAbs (subt su e) x
+  subt su (PAnd es)       = PAnd (subt su <$> es)
+  subt su (POr  es)       = POr  (subt su <$> es)
+  subt su (PImp e1 e2)    = PImp (subt su e1) (subt su e2)
+  subt su (PIff e1 e2)    = PIff (subt su e1) (subt su e2)
+  subt su (PAtom b e1 e2) = PAtom b (subt su e1) (subt su e2)
+  subt su (PAll xes e)    = PAll (subt su <$> xes) (subt su e)
+  subt su (PExist xes e)  = PExist (subt su <$> xes) (subt su e)
+  subt _ e                = e
+
+instance (SubsTy tv ty a, SubsTy tv ty b) => SubsTy tv ty (a, b) where
+  subt su (x, y) = (subt su x, subt su y)
+
+instance SubsTy BTyVar (RType BTyCon BTyVar ()) Sort where
+  subt (v, RVar α _) (FObj s)
+    | symbol v == s = FObj $ symbol α
+    | otherwise     = FObj s
+  subt _ s          = s
+
+
+instance SubsTy Symbol RSort Sort where
+  subt (v, RVar α _) (FObj s)
+    | symbol v == s = FObj $ rTyVarSymbol α
+    | otherwise     = FObj s
+  subt _ s          = s
+
+
+instance SubsTy RTyVar RSort Sort where
+  subt (v, sv) (FObj s)
+    | rtyVarUniqueSymbol v == s
+      || symbol v == s
+    = typeSort M.empty $ toType sv
+    | otherwise
+    = FObj s
+  subt _ s
+    = s
+
 instance (SubsTy tv ty ty) => SubsTy tv ty (PVKind ty) where
   subt su (PVProp t) = PVProp (subt su t)
   subt _   PVHProp   = PVHProp
@@ -712,6 +1037,9 @@
 instance SubsTy RTyVar RSort SpecType where
   subt (α, τ) = subsTyVar_meet (α, τ, ofRSort τ)
 
+instance SubsTy TyVar Type SpecType where
+  subt (α, τ) = subsTyVar_meet (RTV α, ofType τ, ofType τ)
+
 instance SubsTy RTyVar RTyVar SpecType where
   subt (α, a) = subt (α, RVar a () :: RSort)
 
@@ -719,11 +1047,17 @@
 instance SubsTy RTyVar RSort RSort where
   subt (α, τ) = subsTyVar_meet (α, τ, ofRSort τ)
 
+instance SubsTy tv RSort Predicate where
+  subt _ = id -- NV TODO
+
+instance (SubsTy tv ty r) => SubsTy tv ty (UReft r) where
+  subt su r = r {ur_reft = subt su $ ur_reft r}
+
 -- Here the "String" is a Bare-TyCon. TODO: wrap in newtype
-instance SubsTy Symbol BSort LocSymbol where
+instance SubsTy BTyVar BSort BTyCon where
   subt _ t = t
 
-instance SubsTy Symbol BSort BSort where
+instance SubsTy BTyVar BSort BSort where
   subt (α, τ) = subsTyVar_meet (α, τ, ofRSort τ)
 
 instance (SubsTy tv ty (UReft r), SubsTy tv ty (RType c tv ())) => SubsTy tv ty (RTProp c tv (UReft r))  where
@@ -736,32 +1070,58 @@
 subvPredicate :: (UsedPVar -> UsedPVar) -> Predicate -> Predicate
 subvPredicate f (Pr pvs) = Pr (f <$> pvs)
 
----------------------------------------------------------------
+--------------------------------------------------------------------------------
+ofType :: Monoid r => Type -> RRType r
+--------------------------------------------------------------------------------
+ofType      = ofType_ $ TyConv
+  { tcFVar  = rVar
+  , tcFTVar = rTVar
+  , tcFApp  = \c ts -> rApp c ts [] mempty
+  , tcFLit  = ofLitType rApp
+  }
 
-ofType = ofType_ . expandTypeSynonyms
+--------------------------------------------------------------------------------
+bareOfType :: Monoid r => Type -> BRType r
+--------------------------------------------------------------------------------
+bareOfType  = ofType_ $ TyConv
+  { tcFVar  = (`RVar` mempty) . BTV . symbol
+  , tcFTVar = bTVar
+  , tcFApp  = \c ts -> bApp c ts [] mempty
+  , tcFLit  = ofLitType bApp
+  }
 
-ofType_ (TyVarTy α)
-  = rVar α
-ofType_ (FunTy τ τ')
-  = rFun dummySymbol (ofType_ τ) (ofType_ τ')
-ofType_ (ForAllTy α τ)
-  | isKindVar α
-  = ofType_ τ
-  | otherwise
-  = RAllT (rTyVar α) $ ofType_ τ
-ofType_ (TyConApp c τs)
-  | Just (αs, τ) <- TC.synTyConDefn_maybe c
-  = ofType_ $ substTyWith αs τs τ
-  | otherwise
-  = rApp c (ofType_ <$> filter (not . isKind) τs) [] mempty
-ofType_ (AppTy t1 t2)
-  = RAppTy (ofType_ t1) (ofType t2) mempty
-ofType_ (LitTy x)
-  = fromTyLit x
+--------------------------------------------------------------------------------
+ofType_ :: Monoid r => TyConv c tv r -> Type -> RType c tv r
+--------------------------------------------------------------------------------
+ofType_ tx = go . expandTypeSynonyms
   where
-    fromTyLit (NumTyLit _) = rApp intTyCon [] [] mempty
-    fromTyLit (StrTyLit _) = rApp listTyCon [rApp charTyCon [] [] mempty] [] mempty
+    go (TyVarTy α)
+      = tcFVar tx α
+    go (FunTy τ τ')
+      = rFun dummySymbol (go τ) (go τ')
+    go (ForAllTy α τ)
+      = RAllT (tcFTVar tx α) $ go τ
+    go (TyConApp c τs)
+      | Just (αs, τ) <- TC.synTyConDefn_maybe c
+      = go (substTyWith αs τs τ)
+      | otherwise
+      = tcFApp tx c (go <$> τs) -- [] mempty
+    go (AppTy t1 t2)
+      = RAppTy (go t1) (ofType_ tx t2) mempty
+    go (LitTy x)
+      = tcFLit tx x
 
+ofLitType :: (Monoid r) => (TyCon -> [t] -> [p] -> r -> t) -> TyLit -> t
+ofLitType rF (NumTyLit _) = rF intTyCon [] [] mempty
+ofLitType rF (StrTyLit _) = rF listTyCon [rF charTyCon [] [] mempty] [] mempty
+
+data TyConv c tv r = TyConv
+  { tcFVar  :: TyVar -> RType c tv r
+  , tcFTVar :: TyVar -> RTVar tv (RType c tv ())
+  , tcFApp  :: TyCon -> [RType c tv r] -> RType c tv r
+  , tcFLit  :: TyLit -> RType c tv r
+  }
+
 --------------------------------------------------------------------------------
 -- | Converting to Fixpoint ----------------------------------------------------
 --------------------------------------------------------------------------------
@@ -793,8 +1153,10 @@
       | otherwise
       = mkEApp (dummyLoc $ symbol c) (eVar <$> xs)
 
+isBaseDataCon :: DataCon -> Bool
 isBaseDataCon c = and $ isBaseTy <$> dataConOrigArgTys c ++ dataConRepArgTys c
 
+isBaseTy :: Type -> Bool
 isBaseTy (TyVarTy _)     = True
 isBaseTy (AppTy _ _)     = False
 isBaseTy (TyConApp _ ts) = and $ isBaseTy <$> ts
@@ -803,6 +1165,7 @@
 isBaseTy (LitTy _)       = True
 
 
+dataConMsReft :: Reftable r => RType c tv r -> [Symbol] -> Reft
 dataConMsReft ty ys  = subst su (rTypeReft (ignoreOblig $ ty_res trep))
   where
     trep = toRTypeRep ty
@@ -810,14 +1173,17 @@
     ts   = ty_args  trep
     su   = mkSubst $ [(x, EVar y) | ((x, _), y) <- zip (zip xs ts) ys]
 
----------------------------------------------------------------
----------------------- Embedding RefTypes ---------------------
----------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Embedding RefTypes --------------------------------------------------------
+--------------------------------------------------------------------------------
+
+type ToTypeable r = (Reftable r, PPrint r, SubsTy RTyVar (RRType ()) r)
+
 -- TODO: remove toType, generalize typeSort
-toType  :: (Reftable r, PPrint r) => RRType r -> Type
+toType  :: (ToTypeable r) => RRType r -> Type
 toType (RFun _ t t' _)
   = FunTy (toType t) (toType t')
-toType (RAllT (RTV α) t)
+toType (RAllT a t) | RTV α <- ty_var_value a
   = ForAllTy α (toType t)
 toType (RAllP _ t)
   = toType t
@@ -828,8 +1194,8 @@
 toType (RApp (RTyCon {rtc_tc = c}) ts _ _)
   = TyConApp c (toType <$> filter notExprArg ts)
   where
-  notExprArg (RExprArg _) = False
-  notExprArg _            = True
+    notExprArg (RExprArg _) = False
+    notExprArg _            = True
 toType (RAllE _ _ t)
   = toType t
 toType (REx _ _ t)
@@ -850,10 +1216,10 @@
 -- | Annotations and Solutions -------------------------------------------------
 --------------------------------------------------------------------------------
 
-rTypeSortedReft ::  (PPrint r, Reftable r) => TCEmb TyCon -> RRType r -> SortedReft
+rTypeSortedReft ::  (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r) => TCEmb TyCon -> RRType r -> SortedReft
 rTypeSortedReft emb t = RR (rTypeSort emb t) (rTypeReft t)
 
-rTypeSort     ::  (PPrint r, Reftable r) => TCEmb TyCon -> RRType r -> Sort
+rTypeSort     ::  (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r) => TCEmb TyCon -> RRType r -> Sort
 rTypeSort tce = typeSort tce . toType
 
 -------------------------------------------------------------------------------
@@ -862,9 +1228,9 @@
 applySolution = fmap . fmap . mapReft . appSolRefa
   where
     mapReft f (MkUReft (Reft (x, z)) p s) = MkUReft (Reft (x, f z)) p s
--- OLD    appSolRefa _ ra@(RConc _)        = ra
--- OLD    appSolRefa s (RKvar k su)        = RConc $ subst su $ M.lookupDefault PTop k s
 
+appSolRefa :: Visitable t
+           => M.HashMap KVar Expr -> t -> t
 appSolRefa s p = mapKVars f p
   where
     f k        = Just $ M.lookupDefault PTop k s
@@ -890,9 +1256,9 @@
   = t -- errorstar $ "shiftVV: cannot handle " ++ showpp t
 
 
-------------------------------------------------------------------------
----------------- Auxiliary Stuff Used Elsewhere ------------------------
-------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- |Auxiliary Stuff Used Elsewhere ---------------------------------------------
+--------------------------------------------------------------------------------
 
 -- MOVE TO TYPES
 instance (Show tv, Show ty) => Show (RTAlias tv ty) where
@@ -902,13 +1268,14 @@
       (unwords (show <$> xs))
       (show t) (show p)
 
-----------------------------------------------------------------
------------- From Old Fixpoint ---------------------------------
-----------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | From Old Fixpoint ---------------------------------------------------------
+--------------------------------------------------------------------------------
 
 typeUniqueSymbol :: Type -> Symbol
 typeUniqueSymbol = symbol . typeUniqueString
 
+
 typeSort :: TCEmb TyCon -> Type -> Sort
 typeSort tce τ@(ForAllTy _ _)
   = typeSortForAll tce τ
@@ -918,45 +1285,69 @@
   = fAppTC (tyConFTyCon tce c) (typeSort tce <$> τs)
 typeSort tce (AppTy t1 t2)
   = fApp (typeSort tce t1) [typeSort tce t2]
+typeSort _tce (TyVarTy tv)
+  = let x = FObj $ tyVarUniqueSymbol tv
+    in x
 typeSort _ τ
   = FObj $ typeUniqueSymbol τ
 
-tyConFTyCon tce c    = fromMaybe (symbolFTycon $ dummyLoc $ tyConName c) (M.lookup c tce)
+tyConFTyCon :: M.HashMap TyCon FTycon -> TyCon -> FTycon
+tyConFTyCon tce c
+  = fromMaybe (symbolNumInfoFTyCon (dummyLoc $ tyConName c) (isNumCls c) (isFracCls c))
+              (M.lookup c tce)
 
+typeSortForAll :: TCEmb TyCon -> Type -> Sort
 typeSortForAll tce τ
   = genSort $ typeSort tce tbody
   where genSort t           = foldl (flip FAbs) (sortSubst su t) [0..n-1]
         (as, tbody)         = splitForAllTys τ
         su                  = M.fromList $ zip sas (FVar <$>  [0..])
-        sas                 = (typeUniqueSymbol . TyVarTy) <$> as
+        sas                 = tyVarUniqueSymbol <$> as
         n                   = length as
 
+-- RJ: why not make this the Symbolic instance?
+tyConName :: TyCon -> Symbol
 tyConName c
   | listTyCon == c    = listConName
   | TC.isTupleTyCon c = tupConName
   | otherwise         = symbol c
 
+typeSortFun :: TCEmb TyCon -> Type -> Sort
 typeSortFun tce t -- τ1 τ2
   = mkFFunc 0  sos
   where sos  = typeSort tce <$> τs
         τs   = grabArgs [] t
 
+grabArgs :: [Type] -> Type -> [Type]
 grabArgs τs (FunTy τ1 τ2)
-  | not $ isClassPred τ1 = grabArgs (τ1:τs) τ2
-  | otherwise            = grabArgs τs τ2
-grabArgs τs τ            = reverse (τ:τs)
+  | Just a <- stringClassArg τ1
+  = grabArgs τs (mapType (\t -> if t == a then stringTy else t) τ2)
+  | not $ isClassPred τ1
+  = grabArgs (τ1:τs) τ2
+  | otherwise
+  = grabArgs τs τ2
+grabArgs τs τ
+  = reverse (τ:τs)
 
 
+mkDataConIdsTy :: (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r)
+               => (DataCon, RType RTyCon RTyVar r) -> [(Var, RType RTyCon RTyVar r)]
 mkDataConIdsTy (dc, t) = [ expandProductType x t | x <- dataConImplicitIds dc]
 
+expandProductType :: (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r)
+                  => Var -> RType RTyCon RTyVar r -> (Var, RType RTyCon RTyVar r)
 expandProductType x t
   | ofType (varType x) == toRSort t = (x, t)
   | otherwise                       = (x, t')
-     where t'         = fromRTypeRep $ trep {ty_binds = xs', ty_args = ts', ty_refts = rs'}
-           τs         = fst $ splitFunTys $ toType t
-           trep       = toRTypeRep t
-           (xs', ts', rs') = unzip3 $ concatMap mkProductTy $ zip4 τs (ty_binds trep) (ty_args trep) (ty_refts trep)
+     where
+      t'         = fromRTypeRep $ trep {ty_binds = xs', ty_args = ts', ty_refts = rs'}
+      τs         = fst $ splitFunTys $ snd $ splitForAllTys $ toType t
+      trep       = toRTypeRep t
+      (xs', ts', rs') = unzip3 $ concatMap mkProductTy $ zip4 τs (ty_binds trep) (ty_args trep) (ty_refts trep)
 
+mkProductTy :: (Monoid t, Monoid r)
+            => (Type, Symbol, RType RTyCon RTyVar r, t)
+            -> [(Symbol, RType RTyCon RTyVar r, t)]
 mkProductTy (τ, x, t, r) = maybe [(x, t, r)] f $ deepSplitProductType_maybe menv τ
   where f    = ((<$>) ((dummySymbol, , mempty) . ofType)) . third4
         menv = (emptyFamInstEnv, emptyFamInstEnv)
@@ -965,6 +1356,7 @@
 -- | Binders generated by class predicates, typically for constraining tyvars (e.g. FNum)
 -----------------------------------------------------------------------------------------
 
+classBinds :: TyConable c => RType c RTyVar t -> [(Symbol, SortedReft)]
 classBinds (RApp c ts _ _)
    | isFracCls c
    = [(rTyVarSymbol a, trueSortedReft FFrac) | (RVar a _) <- ts]
@@ -973,17 +1365,21 @@
 classBinds _
   = []
 
+rTyVarSymbol :: RTyVar -> Symbol
 rTyVarSymbol (RTV α) = typeUniqueSymbol $ TyVarTy α
 
------------------------------------------------------------------------------------------
---------------------------- Termination Predicates --------------------------------------
------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Termination Predicates ----------------------------------------------------
+--------------------------------------------------------------------------------
 
+makeNumEnv :: (Foldable t, TyConable c) => t (RType c b t1) -> [b]
 makeNumEnv = concatMap go
   where
     go (RApp c ts _ _) | isNumCls c || isFracCls c = [ a | (RVar a _) <- ts]
     go _ = []
 
+isDecreasing :: (Eq a, Foldable t1)
+             => S.HashSet TyCon -> t1 a -> RType RTyCon a t -> Bool
 isDecreasing autoenv  _ (RApp c _ _ _)
   =  isJust (sizeFunction (rtc_info c)) -- user specified size or
   || isSizeable autoenv tc
@@ -993,8 +1389,18 @@
 isDecreasing _ _ _
   = False
 
+makeDecrType :: Symbolic a
+             => S.HashSet TyCon
+             -> [(a, (Symbol, RType RTyCon t (UReft Reft)))]
+             -> (Symbol, RType RTyCon t (UReft Reft))
 makeDecrType autoenv = mkDType autoenv [] []
 
+mkDType :: Symbolic a
+        => S.HashSet TyCon
+        -> [(Symbol, Symbol, Symbol -> Expr)]
+        -> [Expr]
+        -> [(a, (Symbol, RType RTyCon t (UReft Reft)))]
+        -> (Symbol, RType RTyCon t (UReft Reft))
 mkDType autoenv xvs acc [(v, (x, t))]
   = (x, ) $ t `strengthen` tr
   where
@@ -1016,10 +1422,11 @@
   = panic Nothing "RefType.mkDType called on invalid input"
 
 isSizeable  :: S.HashSet TyCon -> TyCon -> Bool
-isSizeable autoenv tc =  S.member tc autoenv --   TC.isAlgTyCon tc -- && TC.isRecursiveTyCon tc
+isSizeable autoenv tc = S.member tc autoenv --   TC.isAlgTyCon tc -- && TC.isRecursiveTyCon tc
 
+mkDecrFun :: S.HashSet TyCon -> RType RTyCon t t1 -> Symbol -> Expr
 mkDecrFun autoenv (RApp c _ _ _)
-  | Just f <- sizeFunction $ rtc_info c
+  | Just f <- szFun <$> sizeFunction (rtc_info c)
   = f
   | isSizeable autoenv $ rtc_tc c
   = \v -> F.mkEApp lenLocSymbol [F.EVar v]
@@ -1028,17 +1435,20 @@
 mkDecrFun _ _
   = panic Nothing "RefType.mkDecrFun called on invalid input"
 
+cmpLexRef :: [(t1, t1, t1 -> Expr)] -> (t, t, t -> Expr) -> Expr
 cmpLexRef vxs (v, x, g)
   = pAnd $  (PAtom Lt (g x) (g v)) : (PAtom Ge (g x) zero)
          :  [PAtom Eq (f y) (f z) | (y, z, f) <- vxs]
          ++ [PAtom Ge (f y) zero  | (y, _, f) <- vxs]
   where zero = ECon $ I 0
 
+makeLexRefa :: [Located Expr] -> [Located Expr] -> UReft Reft
 makeLexRefa es' es = uTop $ Reft (vv, PIff (EVar vv) $ pOr rs)
   where
-    rs = makeLexReft [] [] es es'
+    rs = makeLexReft [] [] (val <$> es) (val <$> es')
     vv = "vvRec"
 
+makeLexReft :: [(Expr, Expr)] -> [Expr] -> [Expr] -> [Expr] -> [Expr]
 makeLexReft _ acc [] []
   = acc
 makeLexReft old acc (e:es) (e':es')
@@ -1053,11 +1463,11 @@
   = panic Nothing "RefType.makeLexReft on invalid input"
 
 --------------------------------------------------------------------------------
-mkTyConInfo :: TyCon -> VarianceInfo -> VarianceInfo -> (Maybe (Symbol -> Expr)) -> TyConInfo
-mkTyConInfo c usertyvar userprvariance f
-  = TyConInfo (if null usertyvar then defaulttyvar else usertyvar) userprvariance f
+mkTyConInfo :: TyCon -> VarianceInfo -> VarianceInfo -> Maybe SizeFun -> TyConInfo
+mkTyConInfo c userTv userPv f = TyConInfo tcTv userPv f
   where
-        defaulttyvar      = makeTyConVariance c
+    tcTv                      = if null userTv then defTv else userTv
+    defTv                     = makeTyConVariance c
 
 
 makeTyConVariance :: TyCon -> VarianceInfo
@@ -1104,35 +1514,32 @@
 
 
 dataConsOfTyCon :: TyCon -> S.HashSet TyCon
-dataConsOfTyCon c = mconcat $ go <$> [t | dc <- TC.tyConDataCons c, t <- DataCon.dataConOrigArgTys dc]
+dataConsOfTyCon = dcs S.empty
   where
-    go (ForAllTy _ t)  = go t
-    go (TyVarTy _)     = S.empty
-    go (AppTy t1 t2)   = go t1 `S.union` go t2
-    go (TyConApp c ts) = S.insert c $ mconcat $ go <$> ts
-    go (FunTy t1 t2)   = go t1 `S.union` go t2
-    go (LitTy _)       = S.empty
+    dcs vis c               = mconcat $ go vis <$> [t | dc <- TC.tyConDataCons c, t <- DataCon.dataConOrigArgTys dc]
+    go  vis (ForAllTy _ t)  = go vis t
+    go  _   (TyVarTy _)     = S.empty
+    go  vis (AppTy t1 t2)   = go vis t1 `S.union` go vis t2
+    go  vis (TyConApp c ts)
+      | c `S.member` vis
+      = S.empty
+      | otherwise
+      = (S.insert c $ mconcat $ go vis <$> ts) `S.union` dcs (S.insert c vis) c
+    go  vis (FunTy t1 t2)   = go vis t1 `S.union` go vis t2
+    go  _   (LitTy _)       = S.empty
 
 --------------------------------------------------------------------------------
 -- | Printing Refinement Types -------------------------------------------------
 --------------------------------------------------------------------------------
 
--- MOVE TO TYPES
-instance (SubsTy Symbol (RType c Symbol ()) c, TyConable c, Reftable r, PPrint r, PPrint c, FreeVar c Symbol, SubsTy Symbol (RType c Symbol ()) (RType c Symbol ())) => RefTypable c Symbol r where
-  ppRType = ppr_rtype ppEnv
-
--- MOVE TO TYPES
-instance (Reftable r, PPrint r) => RefTypable RTyCon RTyVar r where
-  ppRType = ppr_rtype ppEnv
-
 instance Show RTyVar where
   show = showpp
 
 instance PPrint (UReft r) => Show (UReft r) where
   show = showpp
 
-instance (RefTypable c tv r) => PPrint (RType c tv r) where
-  pprintTidy _ = ppRType TopPrec
+-- ppHack :: (?callStack :: CallStack) => a -> b
+-- ppHack _ = errorstar "OOPS"
 
 instance PPrint (RType c tv r) => Show (RType c tv r) where
   show = showpp
@@ -1141,5 +1548,4 @@
   show = showpp
 
 instance PPrint REnv where
-  pprintTidy k re = text "RENV" $+$
-              pprintTidy k (reLocal re)
+  pprintTidy k re = "RENV" $+$ pprintTidy k (reLocal re)
diff --git a/src/Language/Haskell/Liquid/Types/Strata.hs b/src/Language/Haskell/Liquid/Types/Strata.hs
--- a/src/Language/Haskell/Liquid/Types/Strata.hs
+++ b/src/Language/Haskell/Liquid/Types/Strata.hs
@@ -13,10 +13,12 @@
 import Language.Fixpoint.Types (Symbol)
 import Language.Haskell.Liquid.Types hiding (Def, Loc)
 
+(<:=) :: (Foldable t, Foldable t1) => t Stratum -> t1 Stratum -> Bool
 s1 <:= s2
   | any (==SDiv) s1 && any (==SFin) s2 = False
   | otherwise                          = True
 
+solveStrata :: [([Stratum], [Stratum])] -> [(Symbol, Stratum)]
 solveStrata = go True [] []
   where go False solved _   [] = solved
         go True  solved acc [] = go False solved [] $ {-traceShow ("OLD \n" ++ showMap solved acc ) $ -} subsS solved <$> acc
@@ -28,13 +30,22 @@
                                    | otherwise   = go True (solve l ++ solved) (l:acc) ls
 
 
+allSVars :: ([Stratum], [Stratum]) -> Bool
 allSVars (xs, ys) = all isSVar $ xs ++ ys
+
+noSVar :: ([Stratum], [Stratum]) -> Bool
 noSVar   (xs, ys) = all (not . isSVar) (xs ++ ys)
+
+noUpdate :: (Foldable t, Foldable t1) => (t1 Stratum, t Stratum) -> Bool
 noUpdate (xs, ys) = (not $ updateFin(xs, ys)) && (not $ updateDiv (xs, ys))
 
+updateFin :: (Foldable t, Foldable t1) => (t1 Stratum, t Stratum) -> Bool
 updateFin (xs, ys) = any (==SFin) ys && any isSVar   xs
+
+updateDiv :: (Foldable t, Foldable t1) => (t1 Stratum, t Stratum) -> Bool
 updateDiv (xs, ys) = any isSVar   ys && any (==SDiv) xs
 
+solve :: ([Stratum], [Stratum]) -> [(Symbol, Stratum)]
 solve (xs, ys)
   | any (== SDiv) xs = [(l, SDiv) | SVar l <- ys]
   | any (== SFin) ys = [(l, SFin) | SVar l <- xs]
diff --git a/src/Language/Haskell/Liquid/Types/Variance.hs b/src/Language/Haskell/Liquid/Types/Variance.hs
--- a/src/Language/Haskell/Liquid/Types/Variance.hs
+++ b/src/Language/Haskell/Liquid/Types/Variance.hs
@@ -8,9 +8,12 @@
 import Data.Typeable
 import Data.Data
 import GHC.Generics
+import Data.Binary
 
 type VarianceInfo = [Variance]
+
 data Variance = Invariant | Bivariant | Contravariant | Covariant
               deriving (Data, Typeable, Show, Generic)
 
+instance Binary Variance
 instance NFData Variance
diff --git a/src/Language/Haskell/Liquid/Types/Visitors.hs b/src/Language/Haskell/Liquid/Types/Visitors.hs
--- a/src/Language/Haskell/Liquid/Types/Visitors.hs
+++ b/src/Language/Haskell/Liquid/Types/Visitors.hs
@@ -14,18 +14,21 @@
 
   ) where
 
-import Prelude hiding (error)
-import DataCon
-import Literal
-import CoreSyn
+import           CoreSyn
+import           Data.Hashable
+import           DataCon
+import           Literal
+import           Prelude                          hiding (error)
 
-import Var
+import           TypeRep
+import           Var
+import           FastString (fastStringToByteString)
 
-import Data.List (foldl', (\\), delete)
+import           Data.List                        (foldl', (\\), delete)
 
-import qualified Data.HashSet        as S
-import Language.Fixpoint.Misc
-import Language.Haskell.Liquid.GHC.Misc ()
+import qualified Data.HashSet                     as S
+import           Language.Fixpoint.Misc
+import           Language.Haskell.Liquid.GHC.Misc ()
 
 
 ------------------------------------------------------------------------------
@@ -65,7 +68,7 @@
       (xs, es)              = unzip xes
 
   literals (NonRec _ e)      = literals e
-  literals (Rec xes)         = concatMap literals $ map snd xes
+  literals (Rec xes)         = concatMap (literals . snd) xes
 
 instance CBVisitable (Expr Var) where
   freeVars = exprFreeVars
@@ -73,17 +76,19 @@
   letVars  = exprLetVars
   literals = exprLiterals
 
+exprFreeVars :: S.HashSet Id -> Expr Id -> [Id]
 exprFreeVars = go
   where
     go env (Var x)         = if x `S.member` env then [] else [x]
-    go env (App e a)       = (go env e) ++ (go env a)
+    go env (App e a)       = go env e ++ go env a
     go env (Lam x e)       = go (extendEnv env [x]) e
-    go env (Let b e)       = (freeVars env b) ++ (go (extendEnv env (bindings b)) e)
+    go env (Let b e)       = freeVars env b ++ go (extendEnv env (bindings b)) e
     go env (Tick _ e)      = go env e
     go env (Cast e _)      = go env e
-    go env (Case e x _ cs) = (go env e) ++ (concatMap (freeVars (extendEnv env [x])) cs)
+    go env (Case e x _ cs) = go env e ++ concatMap (freeVars (extendEnv env [x])) cs
     go _   _               = []
 
+exprReadVars :: (CBVisitable (Alt t), CBVisitable (Bind t)) => Expr t -> [Id]
 exprReadVars = go
   where
     go (Var x)             = [x]
@@ -92,9 +97,10 @@
     go (Let b e)           = readVars b ++ go e
     go (Tick _ e)          = go e
     go (Cast e _)          = go e
-    go (Case e _ _ cs)     = (go e) ++ (concatMap readVars cs)
+    go (Case e _ _ cs)     = go e ++ concatMap readVars cs
     go _                   = []
 
+exprLetVars :: Expr Var -> [Var]
 exprLetVars = go
   where
     go (Var _)             = []
@@ -106,6 +112,8 @@
     go (Case e x _ cs)     = x : go e ++ concatMap letVars cs
     go _                   = []
 
+exprLiterals :: (CBVisitable (Alt t), CBVisitable (Bind t))
+             => Expr t -> [Literal]
 exprLiterals = go
   where
     go (Lit l)             = [l]
@@ -114,17 +122,24 @@
     go (Lam _ e)           = go e
     go (Tick _ e)          = go e
     go (Cast e _)          = go e
-    go (Case e _ _ cs)     = (go e) ++ (concatMap literals cs)
+    go (Case e _ _ cs)     = go e ++ concatMap literals cs
+    go (Type t)            = go' t
     go _                   = []
 
+    go' (LitTy tl)         = [tyLitToLit tl]
+    go' _                  = []
 
+
+    tyLitToLit (StrTyLit fs) = MachStr $ fastStringToByteString fs
+    tyLitToLit (NumTyLit i)  = MachInt i
+
+
 instance CBVisitable (Alt Var) where
   freeVars env (a, xs, e) = freeVars env a ++ freeVars (extendEnv env xs) e
   readVars (_,_, e)       = readVars e
   letVars  (_,xs,e)       = xs ++ letVars e
   literals (c,_, e)       = literals c ++ literals e
 
-
 instance CBVisitable AltCon where
   freeVars _ (DataAlt dc) = dataConImplicitIds dc
   freeVars _ _            = []
@@ -133,11 +148,9 @@
   literals (LitAlt l)     = [l]
   literals _              = []
 
-
-
+extendEnv :: (Eq a, Hashable a) => S.HashSet a -> [a] -> S.HashSet a
 extendEnv = foldl' (flip S.insert)
 
-bindings (NonRec x _)
-  = [x]
-bindings (Rec  xes  )
-  = map fst xes
+bindings :: Bind t -> [t]
+bindings (NonRec x _) = [x]
+bindings (Rec  xes  ) = map fst xes
diff --git a/src/Language/Haskell/Liquid/UX/ACSS.hs b/src/Language/Haskell/Liquid/UX/ACSS.hs
--- a/src/Language/Haskell/Liquid/UX/ACSS.hs
+++ b/src/Language/Haskell/Liquid/UX/ACSS.hs
@@ -66,6 +66,8 @@
 litSpans lits = zip lits $ spans lits
   where spans = tokenSpans Nothing . map unL
 
+hsannot' :: Maybe Loc
+         -> Bool -> CommentTransform -> (String, AnnMap) -> String
 hsannot' baseLoc anchor tx =
     CSS.pre
     . (if anchor then concatMap (renderAnchors renderAnnotToken)
@@ -83,16 +85,19 @@
     annots     = fmap (spanAnnot linWidth annm) spans
     linWidth   = length $ show $ length $ lines src
 
+spanAnnot :: Int -> AnnMap -> Loc -> Annotation
 spanAnnot w (Ann ts es _) span = A t e b
   where
     t = fmap snd (M.lookup span ts)
     e = fmap (\_ -> "ERROR") $ find (span `inRange`) [(x,y) | (x,y,_) <- es]
     b = spanLine w span
 
+spanLine :: t -> Loc -> Maybe (Int, t)
 spanLine w (L (l, c))
   | c == 1    = Just (l, w)
   | otherwise = Nothing
 
+inRange :: Loc -> (Loc, Loc) -> Bool
 inRange (L (l0, c0)) (L (l, c), L (l', c'))
   = l <= l0 && c <= c0 && l0 <= l' && c0 < c'
 
@@ -120,15 +125,20 @@
 
 
 
+renderTypAnnot :: (PrintfArg t, PrintfType t) => Maybe String -> t -> t
 renderTypAnnot (Just ann) s = printf "<a class=annot href=\"#\"><span class=annottext>%s</span>%s</a>" (escape ann) s
 renderTypAnnot Nothing    s = s
 
+renderErrAnnot :: (PrintfArg t1, PrintfType t1) => Maybe t -> t1 -> t1
 renderErrAnnot (Just _) s   = printf "<span class=hs-error>%s</span>" s
 renderErrAnnot Nothing  s   = s
 
+renderLinAnnot :: (Show t, PrintfArg t1, PrintfType t1)
+               => Maybe (t, Int) -> t1 -> t1
 renderLinAnnot (Just d) s   = printf "<span class=hs-linenum>%s: </span>%s" (lineString d) s
 renderLinAnnot Nothing  s   = s
 
+lineString :: Show t => (t, Int) -> [Char]
 lineString (i, w) = (replicate (w - (length is)) ' ') ++ is
   where is        = show i
 
@@ -169,6 +179,7 @@
 srcModuleName :: String -> String
 srcModuleName = fromMaybe "Main" . tokenModule . tokenise
 
+tokenModule :: [(TokenType, [Char])] -> Maybe [Char]
 tokenModule toks
   = do i <- findIndex ((Keyword, "module") ==) toks
        let (_, toks')  = splitAt (i+2) toks
@@ -176,6 +187,7 @@
        let (toks'', _) = splitAt j toks'
        return $ concatMap snd toks''
 
+breakS :: [Char]
 breakS = "MOUSEOVER ANNOTATIONS"
 
 annotParse :: String -> String -> AnnMap
@@ -184,6 +196,10 @@
     (ts, es)       = partitionEithers $ parseLines mname 0 $ lines s
 
 
+parseLines :: [Char]
+           -> Int
+           -> [[Char]]
+           -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
 parseLines _ _ []
   = []
 
@@ -215,7 +231,10 @@
   show (Ann ts es _ ) =  "\n\n" ++ (concatMap ppAnnotTyp $ M.toList ts)
                                 ++ (concatMap ppAnnotErr [(x,y) | (x,y,_) <- es])
 
+ppAnnotTyp :: (PrintfArg t, PrintfType t1) => (Loc, (t, String)) -> t1
 ppAnnotTyp (L (l, c), (x, s))     = printf "%s\n%d\n%d\n%d\n%s\n\n\n" x l c (length $ lines s) s
+
+ppAnnotErr :: PrintfType t => (Loc, Loc) -> t
 ppAnnotErr (L (l, c), L (l', c')) = printf " \n%d\n%d\n0\n%d\n%d\n\n\n\n" l c l' c'
 
 
@@ -249,6 +268,7 @@
 classify (x:xs)         = Lit x: classify xs
 
 
+allProg :: [Char] -> [[Char]] -> [Lit]
 allProg name  = go
   where
     end       = "\\end{" ++ name ++ "}"
diff --git a/src/Language/Haskell/Liquid/UX/Annotate.hs b/src/Language/Haskell/Liquid/UX/Annotate.hs
--- a/src/Language/Haskell/Liquid/UX/Annotate.hs
+++ b/src/Language/Haskell/Liquid/UX/Annotate.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE FlexibleContexts         #-}
+{-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE TupleSections              #-}
 {-# LANGUAGE NoMonomorphismRestriction  #-}
 {-# LANGUAGE OverloadedStrings          #-}
@@ -17,58 +17,60 @@
 
 module Language.Haskell.Liquid.UX.Annotate (specAnchor, mkOutput, annotate) where
 
-import           Prelude                  hiding (error)
-import           GHC                      ( SrcSpan (..)
+import           Data.Hashable
+import           Data.String
+import           GHC                                          ( SrcSpan (..)
                                           , srcSpanStartCol
                                           , srcSpanEndCol
                                           , srcSpanStartLine
                                           , srcSpanEndLine)
-import           Text.PrettyPrint.HughesPJ hiding (first)
-import           GHC.Exts                 (groupWith, sortWith)
+import           GHC.Exts                                     (groupWith, sortWith)
+import           Prelude                                      hiding (error)
+import qualified SrcLoc
+import           Text.PrettyPrint.HughesPJ                    hiding (first)
+import           Text.Printf
 
-import           Data.Char                (isSpace)
-import           Data.Function            (on)
-import           Data.List                (sortBy)
-import           Data.Maybe               (mapMaybe)
+import           Data.Char                                    (isSpace)
+import           Data.Function                                (on)
+import           Data.List                                    (sortBy)
+import           Data.Maybe                                   (mapMaybe)
 
 import           Data.Aeson
-import           Control.Arrow            hiding ((<+>))
+import           Control.Arrow                                hiding ((<+>))
 -- import           Control.Applicative      ((<$>))
-import           Control.Monad            (when, forM_)
+import           Control.Monad                                (when, forM_)
 
-import           System.Exit                      (ExitCode (..))
-import           System.FilePath          (takeFileName, dropFileName, (</>))
-import           System.Directory         (findExecutable, copyFile)
-import           Text.Printf              (printf)
-import qualified Data.List              as L
-import qualified Data.Vector            as V
-import qualified Data.ByteString.Lazy   as B
-import qualified Data.Text              as T
-import qualified Data.HashMap.Strict    as M
-import qualified Language.Haskell.Liquid.UX.ACSS as ACSS
+import           System.Exit                                  (ExitCode (..))
+import           System.FilePath                              (takeFileName, dropFileName, (</>))
+import           System.Directory                             (findExecutable, copyFile)
+import qualified Data.List                                    as L
+import qualified Data.Vector                                  as V
+import qualified Data.ByteString.Lazy                         as B
+import qualified Data.Text                                    as T
+import qualified Data.HashMap.Strict                          as M
+import qualified Language.Haskell.Liquid.UX.ACSS              as ACSS
 import           Language.Haskell.HsColour.Classify
 import           Language.Fixpoint.Utils.Files
 import           Language.Fixpoint.Misc
 import           Language.Haskell.Liquid.GHC.Misc
-import           Language.Fixpoint.Types hiding (Error, Loc, Constant (..), Located (..))
+import           Language.Fixpoint.Types                      hiding (Error, Loc, Constant (..), Located (..))
 import           Language.Haskell.Liquid.Misc
 import           Language.Haskell.Liquid.Types.PrettyPrint
 import           Language.Haskell.Liquid.Types.RefType
 
-import           Language.Haskell.Liquid.UX.Errors ()
+import           Language.Haskell.Liquid.UX.Errors            ()
 import           Language.Haskell.Liquid.UX.Tidy
-import           Language.Haskell.Liquid.Types hiding (Located(..), Def(..))
+import           Language.Haskell.Liquid.Types                hiding (Located(..), Def(..))
 import           Language.Haskell.Liquid.Types.Specifications
 
 
-
 -- | @output@ creates the pretty printed output
 --------------------------------------------------------------------------------------------
 mkOutput :: Config -> ErrorResult -> FixSolution -> AnnInfo (Annot SpecType) -> Output Doc
 --------------------------------------------------------------------------------------------
 mkOutput cfg res sol anna
   = O { o_vars   = Nothing
-      , o_errors = []
+      -- , o_errors = []
       , o_types  = toDoc <$> annTy
       , o_templs = toDoc <$> annTmpl
       , o_bots   = mkBots    annTy
@@ -82,14 +84,12 @@
 
 -- | @annotate@ actually renders the output to files
 -------------------------------------------------------------------
-annotate :: Config -> FilePath -> Output Doc -> IO ()
+annotate :: Config -> [FilePath] -> Output Doc -> IO ACSS.AnnMap
 -------------------------------------------------------------------
-annotate cfg srcF out
-  = do generateHtml srcF tpHtmlF tplAnnMap
-       generateHtml srcF tyHtmlF typAnnMap
-       writeFile         vimF  $ vimAnnot cfg annTyp
-       B.writeFile       jsonF $ encode typAnnMap
-       when showWarns $ forM_ bots (printf "WARNING: Found false in %s\n" . showPpr)
+annotate cfg srcFs out
+  = do when showWarns  $ forM_ bots (printf "WARNING: Found false in %s\n" . showPpr)
+       when doAnnotate $ mapM_ (doGenerate cfg tplAnnMap typAnnMap annTyp) srcFs
+       return typAnnMap
     where
        tplAnnMap  = mkAnnMap cfg res annTpl
        typAnnMap  = mkAnnMap cfg res annTyp
@@ -97,19 +97,30 @@
        annTyp     = o_types  out
        res        = o_result out
        bots       = o_bots   out
+       showWarns  = not $ nowarnings    cfg
+       doAnnotate = not $ noannotations cfg
+
+doGenerate :: Config -> ACSS.AnnMap -> ACSS.AnnMap -> AnnInfo Doc -> FilePath -> IO ()
+doGenerate cfg tplAnnMap typAnnMap annTyp srcF
+  = do generateHtml srcF tpHtmlF tplAnnMap
+       generateHtml srcF tyHtmlF typAnnMap
+       writeFile         vimF  $ vimAnnot cfg annTyp
+       B.writeFile       jsonF $ encode typAnnMap
+    where
        tyHtmlF    = extFileName Html                   srcF
        tpHtmlF    = extFileName Html $ extFileName Cst srcF
        _annF      = extFileName Annot srcF
        jsonF      = extFileName Json  srcF
        vimF       = extFileName Vim   srcF
-       showWarns  = not $ nowarnings cfg
 
+mkBots :: Reftable r => AnnInfo (RType c tv r) -> [GHC.SrcSpan]
 mkBots (AI m) = [ src | (src, (Just _, t) : _) <- sortBy (compare `on` fst) $ M.toList m
                       , isFalse (rTypeReft t) ]
 
 writeFilesOrStrings :: FilePath -> [Either FilePath String] -> IO ()
 writeFilesOrStrings tgtFile = mapM_ $ either (`copyFile` tgtFile) (tgtFile `appendFile`)
 
+generateHtml :: FilePath -> FilePath -> ACSS.AnnMap -> IO ()
 generateHtml srcF htmlF annm
   = do src     <- readFile srcF
        let lhs  = isExtFile LHs srcF
@@ -118,31 +129,37 @@
        copyFile cssFile (dropFileName htmlF </> takeFileName cssFile)
        renderHtml lhs htmlF srcF (takeFileName cssFile) body
 
+renderHtml :: Bool -> FilePath -> String -> String -> String -> IO ()
 renderHtml True  = renderPandoc
 renderHtml False = renderDirect
 
 -------------------------------------------------------------------------
 -- | Pandoc HTML Rendering (for lhs + markdown source) ------------------
 -------------------------------------------------------------------------
-
-renderPandoc htmlFile srcFile css body
-  = do renderFn <- maybe renderDirect renderPandoc' <$> findExecutable "pandoc"
-       renderFn htmlFile srcFile css body
+renderPandoc :: FilePath -> String -> String -> String -> IO ()
+renderPandoc htmlFile srcFile css body = do
+  renderFn <- maybe renderDirect renderPandoc' <$> findExecutable "pandoc"
+  renderFn htmlFile srcFile css body
 
-renderPandoc' pandocPath htmlFile srcFile css body
-  = do _  <- writeFile mdFile $ pandocPreProc body
-       ec <- executeShellCommand "pandoc" cmd
-       writeFilesOrStrings htmlFile [Right (cssHTML css)]
-       checkExitCode cmd ec
-    where mdFile = extFileName Mkdn srcFile
-          cmd    = pandocCmd pandocPath mdFile htmlFile
+renderPandoc' :: FilePath -> FilePath -> FilePath -> String -> String -> IO ()
+renderPandoc' pandocPath htmlFile srcFile css body = do
+  _  <- writeFile mdFile $ pandocPreProc body
+  ec <- executeShellCommand "pandoc" cmd
+  writeFilesOrStrings htmlFile [Right (cssHTML css)]
+  checkExitCode cmd ec
+  where
+    mdFile = extFileName Mkdn srcFile
+    cmd    = pandocCmd pandocPath mdFile htmlFile
 
+checkExitCode :: Monad m => String -> ExitCode -> m ()
 checkExitCode _   (ExitSuccess)   = return ()
 checkExitCode cmd (ExitFailure n) = panic Nothing $ "cmd: " ++ cmd ++ " failure code " ++ show n
 
-pandocCmd pandocPath mdFile htmlFile
-  = printf "%s -f markdown -t html %s > %s" pandocPath mdFile htmlFile
+pandocCmd :: FilePath -> FilePath -> FilePath -> String
+pandocCmd -- pandocPath mdFile htmlFile
+  = printf "%s -f markdown -t html %s > %s" -- pandocPath mdFile htmlFile
 
+pandocPreProc :: String -> String
 pandocPreProc  = T.unpack
                . strip beg code
                . strip end code
@@ -156,32 +173,26 @@
     code       = "code"
     spec       = "spec"
     strip x y  = T.replace (T.pack $ printf "\\%s{%s}" x y) T.empty
-    -- stripBcode = T.replace (T.pack "\\begin{code}") T.empty
-    -- stripEcode = T.replace (T.pack "\\end{code}")   T.empty
-    -- stripBspec = T.replace (T.pack "\\begin{code}") T.empty
-    -- stripEspec = T.replace (T.pack "\\end{code}")   T.empty
 
 
-
-
 -------------------------------------------------------------------------
 -- | Direct HTML Rendering (for non-lhs/markdown source) ----------------
 -------------------------------------------------------------------------
 
 -- More or less taken from hscolour
 
+renderDirect :: FilePath -> String -> String -> String -> IO ()
 renderDirect htmlFile srcFile css body
-  = writeFile htmlFile $! (top'n'tail full srcFile css $! body)
+  = writeFile htmlFile $! (topAndTail full srcFile css $! body)
     where full = True -- False  -- TODO: command-line-option
 
--- | @top'n'tail True@ is used for standalone HTML,
---   @top'n'tail False@ for embedded HTML
-
-top'n'tail True  title css = (htmlHeader title css ++) . (++ htmlClose)
-top'n'tail False _    _    = id
+-- | @topAndTail True@ is used for standalone HTML; @topAndTail False@ for embedded HTML
+topAndTail :: Bool -> String -> String -> String -> String
+topAndTail True  title css = (htmlHeader title css ++) . (++ htmlClose)
+topAndTail False _    _    = id
 
 -- Use this for standalone HTML
-
+htmlHeader :: String -> String -> String
 htmlHeader title css = unlines
   [ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">"
   , "<html>"
@@ -194,8 +205,10 @@
   , "Put mouse over identifiers to see inferred types"
   ]
 
+htmlClose :: IsString a => a
 htmlClose  = "\n</body>\n</html>"
 
+cssHTML :: String -> String
 cssHTML css = unlines
   [ "<head>"
   , "<link type='text/css' rel='stylesheet' href='"++ css ++ "' />"
@@ -213,24 +226,31 @@
 mkAnnMap :: Config -> ErrorResult -> AnnInfo Doc -> ACSS.AnnMap
 mkAnnMap cfg res ann     = ACSS.Ann (mkAnnMapTyp cfg ann) (mkAnnMapErr res) (mkStatus res)
 
+mkStatus :: FixResult t -> ACSS.Status
 mkStatus (Safe)          = ACSS.Safe
 mkStatus (Unsafe _)      = ACSS.Unsafe
 mkStatus (Crash _ _)     = ACSS.Error
 
 
 
+mkAnnMapErr :: PPrint (TError t)
+            => FixResult (TError t) -> [(Loc, Loc, String)]
 mkAnnMapErr (Unsafe ls)  = mapMaybe cinfoErr ls
 mkAnnMapErr (Crash ls _) = mapMaybe cinfoErr ls
 mkAnnMapErr _            = []
 
+cinfoErr :: PPrint (TError t) => TError t -> Maybe (Loc, Loc, String)
 cinfoErr e = case pos e of
                RealSrcSpan l -> Just (srcSpanStartLoc l, srcSpanEndLoc l, showpp e)
                _             -> Nothing
 
 
 -- mkAnnMapTyp :: (RefTypable a c tv r, RefTypable a c tv (), PPrint tv, PPrint a) =>Config-> AnnInfo (RType a c tv r) -> M.HashMap Loc (String, String)
+mkAnnMapTyp :: Config -> AnnInfo Doc -> M.HashMap Loc (String, String)
 mkAnnMapTyp cfg z = M.fromList $ map (first srcSpanStartLoc) $ mkAnnMapBinders cfg z
 
+mkAnnMapBinders :: Config
+                -> AnnInfo Doc -> [(SrcLoc.RealSrcSpan, (String, String))]
 mkAnnMapBinders cfg (AI m)
   = map (second bindStr . head . sortWith (srcSpanEndCol . fst))
   $ groupWith (lineCol . fst) locBinds
@@ -242,6 +262,7 @@
 closeAnnots :: AnnInfo (Annot SpecType) -> AnnInfo SpecType
 closeAnnots = closeA . filterA . collapseA
 
+closeA :: AnnInfo (Annot b) -> AnnInfo b
 closeA a@(AI m)   = cf <$> a
   where
     cf (AnnLoc l)  = case m `mlookup` l of
@@ -253,13 +274,16 @@
     cf (AnnDef t) = t
     cf (AnnRDf t) = t
 
+filterA :: AnnInfo (Annot t) -> AnnInfo (Annot t)
 filterA (AI m) = AI (M.filter ff m)
   where
     ff [(_, AnnLoc l)] = l `M.member` m
     ff _               = True
 
+collapseA :: AnnInfo (Annot t) -> AnnInfo (Annot t)
 collapseA (AI m) = AI (fmap pickOneA m)
 
+pickOneA :: [(t, Annot t1)] -> [(t, Annot t1)]
 pickOneA xas = case (rs, ds, ls, us) of
                  (x:_, _, _, _) -> [x]
                  (_, x:_, _, _) -> [x]
@@ -277,21 +301,25 @@
 ------------------------------------------------------------------------------
 
 -- | The token used for refinement symbols inside the highlighted types in @-blocks.
+refToken :: TokenType
 refToken = Keyword
 
 -- | The top-level function for tokenizing @-block annotations. Used to
 -- tokenize comments by ACSS.
+tokAnnot :: String -> [(TokenType, String)]
 tokAnnot s
   = case trimLiquidAnnot s of
       Just (l, body, r) -> [(refToken, l)] ++ tokBody body ++ [(refToken, r)]
       Nothing           -> [(Comment, s)]
 
+trimLiquidAnnot :: String -> Maybe (String, String, String)
 trimLiquidAnnot ('{':'-':'@':ss)
   | drop (length ss - 3) ss == "@-}"
   = Just (liquidBegin, take (length ss - 3) ss, liquidEnd)
 trimLiquidAnnot _
   = Nothing
 
+tokBody :: String -> [(TokenType, String)]
 tokBody s
   | isData s  = tokenise s
   | isType s  = tokenise s
@@ -299,9 +327,16 @@
   | isMeas s  = tokenise s
   | otherwise = tokeniseSpec s
 
+isMeas :: String -> Bool
 isMeas = spacePrefix "measure"
+
+isData :: String -> Bool
 isData = spacePrefix "data"
+
+isType :: String -> Bool
 isType = spacePrefix "type"
+
+isIncl :: String -> Bool
 isIncl = spacePrefix "include"
 
 {-@ spacePrefix :: String -> s:String -> Bool / [len s] @-}
@@ -312,21 +347,18 @@
 spacePrefix _ _ = False
 
 
-tokeniseSpec       ::  String -> [(TokenType, String)]
-tokeniseSpec str   = {- traceShow ("tokeniseSpec: " ++ str) $ -} tokeniseSpec' str
-
-tokeniseSpec'      = tokAlt . chopAltDBG -- [('{', ':'), ('|', '}')]
+tokeniseSpec :: String -> [(TokenType, String)]
+tokeniseSpec       = tokAlt . chopAltDBG
   where
     tokAlt (s:ss)  = tokenise s ++ tokAlt' ss
     tokAlt _       = []
     tokAlt' (s:ss) = (refToken, s) : tokAlt ss
     tokAlt' _      = []
 
-chopAltDBG y = {- traceShow ("chopAlts: " ++ y) $ -}
-  filter (/= "") $ concatMap (chopAlts [("{", ":"), ("|", "}")])
-  $ chopAlts [("<{", "}>"), ("{", "}")] y
-
-
+chopAltDBG :: String -> [String]
+chopAltDBG y = filter (/= "")
+             $ concatMap (chopAlts [("{", ":"), ("|", "}")])
+             $ chopAlts [("<{", "}>"), ("{", "}")] y
 
 
 ------------------------------------------------------------------------
@@ -345,10 +377,10 @@
 ------------------------------------------------------------------------
 -- | Creating Vim Annotations ------------------------------------------
 ------------------------------------------------------------------------
-
 vimAnnot     :: Config -> AnnInfo Doc -> String
 vimAnnot cfg = L.intercalate "\n" . map vimBind . mkAnnMapBinders cfg
 
+vimBind :: (Show a, PrintfType t) => (SrcLoc.RealSrcSpan, (String, a)) -> t
 vimBind (sp, (v, ann)) = printf "%d:%d-%d:%d::%s" l1 c1 l2 c2 (v ++ " :: " ++ show ann)
   where
     l1  = srcSpanStartLine sp
@@ -402,6 +434,8 @@
     grp          = L.foldl' (\m (r,c,x) -> ins r c x m) (Asc M.empty)
     binders      = [(l, c, x, s) | (L (l, c), (x, s)) <- M.toList $ ACSS.types a]
 
+ins :: (Eq k, Eq k1, Hashable k, Hashable k1)
+    => k -> k1 -> a -> Assoc k (Assoc k1 a) -> Assoc k (Assoc k1 a)
 ins r c x (Asc m)  = Asc (M.insert r (Asc (M.insert c x rm)) m)
   where
     Asc rm         = M.lookupDefault (Asc M.empty) r m
@@ -419,10 +453,6 @@
 {-@ assume GHC.Exts.sortWith :: Ord b => (a -> b) -> xs:[a] -> ListXs a xs @-}
 {-@ assume GHC.Exts.groupWith :: Ord b => (a -> b) -> [a] -> [ListNE a] @-}
 
-{- junkProp :: ListNE Int @-}
--- junkProp :: [Int]
--- junkProp = [ 8 ]
-
 --------------------------------------------------------------------------------
 -- | A Little Unit Test --------------------------------------------------------
 --------------------------------------------------------------------------------
@@ -448,4 +478,5 @@
                   ])
          ]
 
+i :: (Eq k, Hashable k) => [(k, a)] -> Assoc k a
 i = Asc . M.fromList
diff --git a/src/Language/Haskell/Liquid/UX/CTags.hs b/src/Language/Haskell/Liquid/UX/CTags.hs
--- a/src/Language/Haskell/Liquid/UX/CTags.hs
+++ b/src/Language/Haskell/Liquid/UX/CTags.hs
@@ -1,9 +1,10 @@
-{-# LANGUAGE TupleSections #-}
 -- | This module contains the code for generating "tags" for constraints
--- based on their source, i.e. the top-level binders under which the
--- constraint was generated. These tags are used by fixpoint to
--- prioritize constraints by the "source-level" function.
+--   based on their source, i.e. the top-level binders under which the
+--   constraint was generated. These tags are used by fixpoint to
+--   prioritize constraints by the "source-level" function.
 
+{-# LANGUAGE TupleSections #-}
+
 module Language.Haskell.Liquid.UX.CTags (
     -- * Type for constraint tags
     TagKey, TagEnv
@@ -15,7 +16,8 @@
   , makeTagEnv
 
     -- * Accessing @TagEnv@
-  , getTag, memTagEnv
+  , getTag
+  , memTagEnv
 
 ) where
 
@@ -29,7 +31,8 @@
 
 import Language.Fixpoint.Types          (Tag)
 import Language.Haskell.Liquid.Types.Visitors (freeVars)
-import Language.Haskell.Liquid.Misc     (mapSnd)
+import Language.Haskell.Liquid.Types.PrettyPrint ()
+import Language.Fixpoint.Misc     (mapSnd)
 
 -- | The @TagKey@ is the top-level binder, and @Tag@ is a singleton Int list
 
@@ -45,7 +48,7 @@
 memTagEnv = M.member
 
 makeTagEnv :: [CoreBind] -> TagEnv
-makeTagEnv = M.map (:[]) . callGraphRanks . makeCallGraph
+makeTagEnv = {- tracepp "TAGENV" . -} M.map (:[]) . callGraphRanks . makeCallGraph
 
 -- makeTagEnv = M.fromList . (`zip` (map (:[]) [1..])). L.sort . map fst . concatMap bindEqns
 
@@ -69,5 +72,6 @@
         xs        = S.fromList $ map fst xes
         calls     = filter (`S.member` xs) . freeVars S.empty
 
+bindEqns :: Bind t -> [(t, Expr t)]
 bindEqns (NonRec x e) = [(x, e)]
 bindEqns (Rec xes)    = xes
diff --git a/src/Language/Haskell/Liquid/UX/CmdLine.hs b/src/Language/Haskell/Liquid/UX/CmdLine.hs
--- a/src/Language/Haskell/Liquid/UX/CmdLine.hs
+++ b/src/Language/Haskell/Liquid/UX/CmdLine.hs
@@ -20,8 +20,12 @@
    -- * Update Configuration With Pragma
    , withPragmas
 
+   -- * Canonicalize Paths in Config
+   , canonicalizePaths
+
    -- * Exit Function
    , exitWithResult
+   , addErrors
 
    -- * Diff check mode
    , diffcheck
@@ -30,9 +34,11 @@
 
 import Prelude hiding (error)
 
+
 import Control.Monad
 import Data.Maybe
-
+import Data.Aeson (encode)
+import qualified Data.ByteString.Lazy.Char8 as B
 import System.Directory
 import System.Exit
 import System.Environment
@@ -47,19 +53,26 @@
 import System.FilePath                     (dropFileName, isAbsolute,
                                             takeDirectory, (</>))
 
-import Language.Fixpoint.Types.Config      hiding (Config, linear, elimStats,
-                                              getOpts, cores, minPartSize,
-                                              maxPartSize, newcheck, eliminate)
-import Language.Fixpoint.Utils.Files
+import qualified Language.Fixpoint.Types.Config as FC
+-- a   hiding (Config, linear, elimBound, elimStats,
+-- nonLinCuts, getOpts, cores, minPartSize,
+-- maxPartSize, eliminate, defConfig,
+-- stringTheory,
+-- withPragmas,
+-- extensionality,
+-- alphaEquivalence, betaEquivalence, normalForm)
+-- import Language.Fixpoint.Utils.Files
 import Language.Fixpoint.Misc
 import Language.Fixpoint.Types.Names
 import Language.Fixpoint.Types             hiding (Error, Result, saveQuery)
+import qualified Language.Fixpoint.Types as F
 import Language.Haskell.Liquid.UX.Annotate
+import Language.Haskell.Liquid.UX.Config
 import Language.Haskell.Liquid.GHC.Misc
 import Language.Haskell.Liquid.Misc
 import Language.Haskell.Liquid.Types.PrettyPrint
-import Language.Haskell.Liquid.Types       hiding (config, name, typ)
-
+import Language.Haskell.Liquid.Types       hiding (name, typ)
+import qualified Language.Haskell.Liquid.UX.ACSS as ACSS
 
 
 import Text.Parsec.Pos                     (newPos)
@@ -100,24 +113,57 @@
     = def
           &= help "Allow higher order binders into the logic"
 
+ , extensionality
+    = def
+          &= help "Allow function extentionality axioms"
+
+ , alphaEquivalence
+    = def
+          &= help "Allow lambda alpha-equivalence axioms"
+
+ , betaEquivalence
+    = def
+          &= help "Allow lambda beta-equivalence axioms"
+
+ , normalForm
+    = def
+          &= help "Allow lambda normalization-equivalence axioms"
+
+ , higherorderqs
+    = def
+          &= help "Allow higher order qualifiers to get automatically instantiated"
+
  , linear
     = def
           &= help "Use uninterpreted integer multiplication and division"
 
+ , stringTheory
+    = def
+          &= help "Interpretation of Strings by z3"
+
  , saveQuery
     = def &= help "Save fixpoint query to file (slow)"
 
- , binders
-    = def &= help "Check a specific set of binders"
+ , checks
+    = def &= help "Check a specific (top-level) binder"
+          &= name "check-var"
 
- , noPrune
+ , pruneUnsorted
     = def &= help "Disable prunning unsorted Predicates"
-          &= name "no-prune-unsorted"
+          &= name "prune-unsorted"
 
  , notermination
     = def &= help "Disable Termination Check"
           &= name "no-termination-check"
 
+ , gradual 
+    = def &= help "Enable gradual refinementtype checking"
+          &= name "gradual"
+
+ , totalHaskell
+    = def &= help "Check for termination and totality, Overrides no-termination flags"
+          &= name "total-Haskell"
+
  , autoproofs
     = def &= help "Automatically construct proofs from axioms"
           &= name "auto-proofs"
@@ -126,10 +172,14 @@
     = def &= help "Don't display warnings, only show errors"
           &= name "no-warnings"
 
- , trustinternals
-    = def &= help "Trust all ghc auto generated code"
-          &= name "trust-internals"
+ , noannotations
+    = def &= help "Don't create intermediate annotation files"
+          &= name "no-annotations"
 
+ , trustInternals
+    = False &= help "Trust GHC generated code"
+            &= name "trust-internals"
+
  , nocaseexpand
     = def &= help "Don't expand the default case in a case-expression"
           &= name "no-case-expand"
@@ -147,19 +197,18 @@
     = def &= help "Use m cores to solve logical constraints"
 
  , minPartSize
-    = defaultMinPartSize &= help "If solving on multiple cores, ensure that partitions are of at least m size"
+    = FC.defaultMinPartSize
+    &= help "If solving on multiple cores, ensure that partitions are of at least m size"
 
  , maxPartSize
-    = defaultMaxPartSize &= help ("If solving on multiple cores, once there are as many partitions " ++
-                                  "as there are cores, don't merge partitions if they will exceed this " ++
-                                  "size. Overrides the minpartsize option.")
+    = FC.defaultMaxPartSize
+    &= help ("If solving on multiple cores, once there are as many partitions " ++
+             "as there are cores, don't merge partitions if they will exceed this " ++
+             "size. Overrides the minpartsize option.")
 
  , smtsolver
     = def &= help "Name of SMT-Solver"
 
- , newcheck
-    = True &= help "New fixpoint check"
-
  , noCheckUnknown
     = def &= explicit
           &= name "no-check-unknown"
@@ -190,10 +239,6 @@
           &= typ "OPTION"
           &= help "Tell GHC to compile and link against these files"
 
- , eliminate
-    = def &= name "eliminate"
-          &= help "Use experimental 'eliminate' feature"
-
  , port
      = defaultPort
           &= name "port"
@@ -203,11 +248,20 @@
     = def &= help "Exact Type for Data Constructors"
           &= name "exact-data-cons"
 
+ , noMeasureFields
+    = def &= help "Do not automatically lift data constructor fields into measures"
+          &= name "no-measure-fields"
+
  , scrapeImports
     = False &= help "Scrape qualifiers from imported specifications"
             &= name "scrape-imports"
             &= explicit
 
+ , scrapeInternals
+    = False &= help "Scrape qualifiers from auto generated specifications"
+            &= name "scrape-internals"
+            &= explicit
+
  , scrapeUsedImports
     = False &= help "Scrape qualifiers from used, imported specifications"
             &= name "scrape-used-imports"
@@ -217,6 +271,73 @@
     = False &= name "elimStats"
             &= help "Print eliminate stats"
 
+ , elimBound
+    = Nothing
+            &= name "elimBound"
+            &= help "Maximum chain length for eliminating KVars"
+
+ , noslice
+    = False
+            &= name "noSlice"
+            &= help "Disable non-concrete KVar slicing"
+
+ , json
+    = False &= name "json"
+            &= help "Print results in JSON (for editor integration)"
+
+ , counterExamples
+    = False &= name "counter-examples"
+            &= help "Attempt to generate counter-examples to type errors (experimental!)"
+
+ , timeBinds
+    = False &= name "time-binds"
+            &= help "Solve each (top-level) asserted type signature separately & time solving."
+
+  , untidyCore
+    = False &= name "untidy-core"
+            &= help "Print fully qualified identifier names in verbose mode"
+
+  , eliminate
+    = FC.Some
+            &= name "eliminate"
+            &= help "Use elimination for 'all' (use TRUE for cut-kvars), 'some' (use quals for cut-kvars) or 'none' (use quals for all kvars)."
+
+  -- , noEliminate
+  --  = False &= name "no-eliminate"
+  --          &= help "Don't use KVar elimination during solving"
+
+  --, oldEliminate
+  --  = False &= name "old-eliminate"
+  --          &= help "Use old eliminate algorithm (temp. for benchmarking)"
+
+  , noPatternInline
+    = False &= name "no-pattern-inline"
+            &= help "Don't inline special patterns (e.g. `>>=` and `return`) during constraint generation."
+
+  , noSimplifyCore
+    = False &= name "no-simplify-core"
+            &= help "Don't simplify GHC core before constraint generation"
+
+  , nonLinCuts
+    = True  &= name "non-linear-cuts"
+            &= help "(TRUE) Treat non-linear kvars as cuts"
+
+  , autoInstantiate
+    = def
+          &= help "How to instantiate axiomatized functions `smtinstances` for SMT instantiation, `liquidinstances` for terminating instantiation"
+          &= name "automatic-instances"
+
+  , proofMethod
+    = def
+          &= help "Specify what method to use to create instances. Options `arithmetic`, `rewrite`, `allmathods`. Default is `rewrite`"
+          &= name "proof-method"
+  , fuel 
+    = defFuel &= help "Fuel parameter for liquid instances (default is 2)"
+        &= name "fuel"
+
+  , debugInstantionation 
+    = False &= help "Debug Progress in liquid instantiation"
+        &= name "debug-instantiation"
  } &= verbosity
    &= program "liquid"
    &= help    "Refinement Types for Haskell"
@@ -237,6 +358,7 @@
                          config { modeValue = (modeValue config) { cmdArgsValue = cfg0 } }
                          as
   cfg    <- fixConfig cfg1
+  when (json cfg) $ setVerbosity Quiet
   whenNormal $ putStrLn copyright
   withSmtSolver cfg
 
@@ -256,21 +378,21 @@
 withSmtSolver cfg =
   case smtsolver cfg of
     Just _  -> return cfg
-    Nothing -> do smts <- mapM findSmtSolver [Z3, Cvc4, Mathsat]
+    Nothing -> do smts <- mapM findSmtSolver [FC.Z3, FC.Cvc4, FC.Mathsat]
                   case catMaybes smts of
                     (s:_) -> return (cfg {smtsolver = Just s})
                     _     -> panic Nothing noSmtError
   where
     noSmtError = "LiquidHaskell requires an SMT Solver, i.e. z3, cvc4, or mathsat to be installed."
 
-findSmtSolver :: SMTSolver -> IO (Maybe SMTSolver)
+findSmtSolver :: FC.SMTSolver -> IO (Maybe FC.SMTSolver)
 findSmtSolver smt = maybe Nothing (const $ Just smt) <$> findExecutable (show smt)
 
 fixConfig :: Config -> IO Config
 fixConfig cfg = do
   pwd <- getCurrentDirectory
   cfg <- canonicalizePaths pwd cfg
-  return $ fixDiffCheck cfg
+  return $ canonConfig cfg
 
 -- | Attempt to canonicalize all `FilePath's in the `Config' so we don't have
 --   to worry about relative paths.
@@ -288,130 +410,178 @@
   | isdir        = canonicalizePath (tgt </> f)
   | otherwise    = canonicalizePath (takeDirectory tgt </> f)
 
-fixDiffCheck :: Config -> Config
-fixDiffCheck cfg = cfg { diffcheck = diffcheck cfg && not (fullcheck cfg) }
-
-envCfg = do so <- lookupEnv "LIQUIDHASKELL_OPTS"
-            case so of
-              Nothing -> return defConfig
-              Just s  -> parsePragma $ envLoc s
-         where
-            envLoc  = Loc l l
-            l       = newPos "ENVIRONMENT" 0 0
+envCfg :: IO Config
+envCfg = do
+  so <- lookupEnv "LIQUIDHASKELL_OPTS"
+  case so of
+    Nothing -> return defConfig
+    Just s  -> parsePragma $ envLoc s
+  where
+    envLoc  = Loc l l
+    l       = newPos "ENVIRONMENT" 0 0
 
+copyright :: String
 copyright = "LiquidHaskell Copyright 2009-15 Regents of the University of California. All Rights Reserved.\n"
 
+-- [NOTE:searchpath]
+-- 1. not convinced we should add the file's directory to the search path
+-- 2. tests fail if you flip order of idirs'
+
 mkOpts :: Config -> IO Config
-mkOpts cfg
-  = do let files' = sortNub $ files cfg
-       id0 <- getIncludeDir
-       return  $ cfg { files = files' }
-                     { idirs = -- NOTE: not convinced we should add the file's directory
-                               -- to the search path
-                               (dropFileName <$> files') ++
-                               [id0 </> gHC_VERSION, id0] ++ idirs cfg }
-                              -- tests fail if you flip order of idirs'
+mkOpts cfg = do
+  let files' = sortNub $ files cfg
+  id0       <- getIncludeDir
+  return     $ cfg { files       = files'
+                   , idirs       = (dropFileName <$> files')    -- [NOTE:searchpath]
+                                ++ [id0 </> gHC_VERSION, id0]
+                                ++ idirs cfg
+                   }
 
----------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 -- | Updating options
----------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+canonConfig :: Config -> Config
+canonConfig cfg = cfg
+  { diffcheck   = diffcheck cfg && not (fullcheck cfg)
+  -- , eliminate   = if higherOrderFlag cfg then FC.All else eliminate cfg
+  }
 
----------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 withPragmas :: Config -> FilePath -> [Located String] -> IO Config
----------------------------------------------------------------------------------------
-withPragmas cfg fp ps = foldM withPragma cfg ps >>= canonicalizePaths fp
+--------------------------------------------------------------------------------
+withPragmas cfg fp ps
+  = foldM withPragma cfg ps >>= canonicalizePaths fp >>= (return . canonConfig)
 
 withPragma :: Config -> Located String -> IO Config
 withPragma c s = withArgs [val s] $ cmdArgsRun
           config { modeValue = (modeValue config) { cmdArgsValue = c } }
-   --(c `mappend`) <$> parsePragma s
 
 parsePragma   :: Located String -> IO Config
 parsePragma = withPragma defConfig
-   --withArgs [val s] $ cmdArgsRun config
 
 defConfig :: Config
-defConfig = Config { files          = def
-                   , idirs          = def
-                   , newcheck       = True
-                   , fullcheck      = def
-                   , linear         = def
-                   , higherorder    = def
-                   , diffcheck      = def
-                   , saveQuery      = def
-                   , binders        = def
-                   , noCheckUnknown = def
-                   , notermination  = def
-                   , autoproofs     = def
-                   , nowarnings     = def
-                   , trustinternals = def
-                   , nocaseexpand   = def
-                   , strata         = def
-                   , notruetypes    = def
-                   , totality       = def
-                   , noPrune        = def
-                   , exactDC        = def
-                   , cores          = def
-                   , minPartSize    = defaultMinPartSize
-                   , maxPartSize    = defaultMaxPartSize
-                   , maxParams      = defaultMaxParams
-                   , smtsolver      = def
-                   , shortNames     = def
-                   , shortErrors    = def
-                   , cabalDir       = def
-                   , ghcOptions     = def
-                   , cFiles         = def
-                   , eliminate      = def
-                   , port           = defaultPort
-                   , scrapeImports  = False
-                   , scrapeUsedImports  = False
-                   , elimStats      = False
+defConfig = Config { files             = def
+                   , idirs             = def
+                   , fullcheck         = def
+                   , linear            = def
+                   , stringTheory      = def
+                   , higherorder       = def
+                   , extensionality    = def
+                   , alphaEquivalence  = def
+                   , betaEquivalence   = def
+                   , normalForm        = def
+                   , higherorderqs     = def
+                   , diffcheck         = def
+                   , saveQuery         = def
+                   , checks            = def
+                   , noCheckUnknown    = def
+                   , notermination     = def
+                   , gradual           = False 
+                   , totalHaskell      = def
+                   , autoproofs        = def
+                   , nowarnings        = def
+                   , noannotations     = def
+                   , trustInternals    = False
+                   , nocaseexpand      = def
+                   , strata            = def
+                   , notruetypes       = def
+                   , totality          = def
+                   , pruneUnsorted     = def
+                   , exactDC           = def
+                   , noMeasureFields   = def
+                   , cores             = def
+                   , minPartSize       = FC.defaultMinPartSize
+                   , maxPartSize       = FC.defaultMaxPartSize
+                   , maxParams         = defaultMaxParams
+                   , smtsolver         = def
+                   , shortNames        = def
+                   , shortErrors       = def
+                   , cabalDir          = def
+                   , ghcOptions        = def
+                   , cFiles            = def
+                   , port              = defaultPort
+                   , scrapeInternals   = False
+                   , scrapeImports     = False
+                   , scrapeUsedImports = False
+                   , elimStats         = False
+                   , elimBound         = Nothing
+                   , json              = False
+                   , counterExamples   = False
+                   , timeBinds         = False
+                   , untidyCore        = False
+                   -- , noEliminate       = False
+                   , eliminate         = FC.Some
+                   , noPatternInline   = False
+                   , noSimplifyCore    = False
+                   , nonLinCuts        = True
+                   , autoInstantiate   = def 
+                   , proofMethod       = def 
+                   , fuel              = defFuel
+                   , debugInstantionation = False 
+                   , noslice              = False 
                    }
 
+defFuel :: Int 
+defFuel = 2
 
 ------------------------------------------------------------------------
 -- | Exit Function -----------------------------------------------------
 ------------------------------------------------------------------------
 
 ------------------------------------------------------------------------
-exitWithResult :: Config -> FilePath -> Output Doc -> IO (Output Doc)
+exitWithResult :: Config -> [FilePath] -> Output Doc -> IO (Output Doc)
 ------------------------------------------------------------------------
-exitWithResult cfg target out
-  = do {-# SCC "annotate" #-} annotate cfg target out
-       donePhase Loud "annotate"
-       writeCheckVars $ o_vars  out
-       cr <- resultWithContext r
-       writeResult cfg (colorResult r) cr
-       writeFile   (extFileName Result target) (showFix cr)
-       return $ out { o_result = r }
-    where
-       r         = o_result out `addErrors` o_errors out
+exitWithResult cfg targets out = do
+  annm <- {-# SCC "annotate" #-} annotate cfg targets out
+  whenNormal $ donePhase Loud "annotate"
+  -- let r = o_result out -- `addErrors` o_errors out
+  consoleResult cfg out annm
+  return out -- { o_result = r }
 
+consoleResult :: Config -> Output a -> ACSS.AnnMap -> IO ()
+consoleResult cfg
+  | json cfg  = consoleResultJson cfg
+  | otherwise = consoleResultFull cfg
 
-resultWithContext :: ErrorResult -> IO (FixResult CError)
+consoleResultFull :: Config -> Output a -> t -> IO ()
+consoleResultFull cfg out _ = do
+   let r = o_result out
+   writeCheckVars $ o_vars out
+   cr <- resultWithContext r
+   writeResult cfg (colorResult r) cr
+
+consoleResultJson :: t -> t1 -> ACSS.AnnMap -> IO ()
+consoleResultJson _ _ annm = do
+  putStrLn "RESULT"
+  B.putStrLn . encode . ACSS.errors $ annm
+
+resultWithContext :: FixResult UserError -> IO (FixResult CError)
 resultWithContext = mapM errorWithContext
 
+instance Show (CtxError Doc) where
+  show = showpp
 
+writeCheckVars :: Symbolic a => Maybe [a] -> IO ()
 writeCheckVars Nothing     = return ()
 writeCheckVars (Just [])   = colorPhaseLn Loud "Checked Binders: None" ""
 writeCheckVars (Just ns)   = colorPhaseLn Loud "Checked Binders:" "" >> forM_ ns (putStrLn . symbolString . dropModuleNames . symbol)
 
-type CError = CtxError Doc -- SpecType
+type CError = CtxError Doc
 
-writeResult :: Config -> Moods -> FixResult CError -> IO ()
+writeResult :: Config -> Moods -> F.FixResult CError -> IO ()
 writeResult cfg c          = mapM_ (writeDoc c) . zip [0..] . resDocs tidy
   where
-    tidy                   = if shortErrors cfg then Lossy else Full
+    tidy                   = if shortErrors cfg then F.Lossy else F.Full
     writeDoc c (i, d)      = writeBlock c i $ lines $ render d
     writeBlock _ _ []      = return ()
     writeBlock c 0 ss      = forM_ ss (colorPhaseLn c "")
     writeBlock _  _ ss     = forM_ ("\n" : ss) putStrLn
 
 
-resDocs :: Tidy -> FixResult CError -> [Doc]
-resDocs _ Safe             = [text "RESULT: SAFE"]
-resDocs k (Crash xs s)     = text "RESULT: ERROR"  : text s : pprManyOrdered k "" (errToFCrash <$> xs)
-resDocs k (Unsafe xs)      = text "RESULT: UNSAFE" : pprManyOrdered k "" (nub xs)
+resDocs :: F.Tidy -> F.FixResult CError -> [Doc]
+resDocs _ F.Safe           = [text "RESULT: SAFE"]
+resDocs k (F.Crash xs s)   = text "RESULT: ERROR"  : text s : pprManyOrdered k "" (errToFCrash <$> xs)
+resDocs k (F.Unsafe xs)    = text "RESULT: UNSAFE" : pprManyOrdered k "" (nub xs)
 
 errToFCrash :: CtxError a -> CtxError a
 errToFCrash ce = ce { ctErr    = tx $ ctErr ce}
@@ -423,11 +593,11 @@
    TODO: Never used, do I need to exist?
 reportUrl = text "Please submit a bug report at: https://github.com/ucsd-progsys/liquidhaskell" -}
 
-
+addErrors :: FixResult a -> [a] -> FixResult a
 addErrors r []             = r
 addErrors Safe errs        = Unsafe errs
 addErrors (Unsafe xs) errs = Unsafe (xs ++ errs)
 addErrors r  _             = r
 
-instance Fixpoint (FixResult CError) where
-  toFix = vcat . resDocs Full
+instance Fixpoint (F.FixResult CError) where
+  toFix = vcat . resDocs F.Full
diff --git a/src/Language/Haskell/Liquid/UX/Config.hs b/src/Language/Haskell/Liquid/UX/Config.hs
--- a/src/Language/Haskell/Liquid/UX/Config.hs
+++ b/src/Language/Haskell/Liquid/UX/Config.hs
@@ -1,48 +1,78 @@
------------------------------------------------------------------------------
--- | Command Line Config Options --------------------------------------------
------------------------------------------------------------------------------
-
+--------------------------------------------------------------------------------
+-- | Command Line Config Options -----------------------------------------------
+--------------------------------------------------------------------------------
 
 {-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE DeriveGeneric #-}
 
 module Language.Haskell.Liquid.UX.Config (
-
    -- * Configuration Options
      Config (..)
    , HasConfig (..)
    , hasOpt
+   , totalityCheck
+   , terminationCheck
+
+   , Instantiate (..)
+   , allowSMTInstationation
+   , allowLiquidInstationation
+   , allowLiquidInstationationGlobal
+   , allowLiquidInstationationLocal
+
+   , ProofMethod (..)
+   , allowRewrite
+   , allowArithmetic 
    ) where
 
 import Prelude hiding (error)
 
 import Data.Serialize ( Serialize )
 import Language.Fixpoint.Types.Config hiding (Config)
-import Data.Typeable  (Typeable)
-import Data.Generics  (Data)
+-- import Data.Typeable  (Typeable)
+-- import Data.Generics  (Data)
 import GHC.Generics
 
+import System.Console.CmdArgs
+
+
+totalityCheck :: Config -> Bool
+totalityCheck config
+  = totality config || totalHaskell config
+
+terminationCheck :: Config -> Bool
+terminationCheck config
+  = totalHaskell config || not (notermination config)
+
+
 -- NOTE: adding strictness annotations breaks the help message
 data Config = Config {
     files          :: [FilePath] -- ^ source files to check
   , idirs          :: [FilePath] -- ^ path to directory for including specs
-  , newcheck       :: Bool       -- ^ new liquid-fixpoint sort check
   , diffcheck      :: Bool       -- ^ check subset of binders modified (+ dependencies) since last check
   , linear         :: Bool       -- ^ uninterpreted integer multiplication and division
+  , stringTheory   :: Bool       -- ^ interpretation of string theory in the logic
   , higherorder    :: Bool       -- ^ allow higher order binders into the logic
+  , higherorderqs  :: Bool       -- ^ allow higher order qualifiers
+  , extensionality :: Bool       -- ^ allow function extentionality axioms
+  , alphaEquivalence :: Bool     -- ^ allow lambda alpha-equivalence axioms
+  , betaEquivalence  :: Bool     -- ^ allow lambda beta-equivalence axioms
+  , normalForm     :: Bool       -- ^ allow lambda normalization-equivalence axioms
   , fullcheck      :: Bool       -- ^ check all binders (overrides diffcheck)
   , saveQuery      :: Bool       -- ^ save fixpoint query
-  , binders        :: [String]   -- ^ set of binders to check
+  , checks         :: [String]   -- ^ set of binders to check
   , noCheckUnknown :: Bool       -- ^ whether to complain about specifications for unexported and unused values
   , notermination  :: Bool       -- ^ disable termination check
+  , gradual        :: Bool       -- ^ enable gradual type checking 
+  , totalHaskell   :: Bool       -- ^ Check for termination and totality, Overrides no-termination flags
   , autoproofs     :: Bool       -- ^ automatically construct proofs from axioms
   , nowarnings     :: Bool       -- ^ disable warnings output (only show errors)
-  , trustinternals :: Bool       -- ^ type all internal variables with true
+  , noannotations  :: Bool       -- ^ disable creation of intermediate annotation files
+  , trustInternals :: Bool       -- ^ type all internal variables with true
   , nocaseexpand   :: Bool       -- ^ disable case expand
   , strata         :: Bool       -- ^ enable strata analysis
   , notruetypes    :: Bool       -- ^ disable truing top level types
   , totality       :: Bool       -- ^ check totality in definitions
-  , noPrune        :: Bool       -- ^ disable prunning unsorted Refinements
+  , pruneUnsorted  :: Bool       -- ^ enable prunning unsorted Refinements
   , cores          :: Maybe Int  -- ^ number of cores used to solve constraints
   , minPartSize    :: Int        -- ^ Minimum size of a partition
   , maxPartSize    :: Int        -- ^ Maximum size of a partition. Overrides minPartSize
@@ -53,20 +83,88 @@
   , cabalDir       :: Bool       -- ^ find and use .cabal file to include paths to sources for imported modules
   , ghcOptions     :: [String]   -- ^ command-line options to pass to GHC
   , cFiles         :: [String]   -- ^ .c files to compile and link against (for GHC)
-  , eliminate      :: Bool
+  , eliminate      :: Eliminate  -- ^ eliminate (i.e. don't use qualifs for) for "none", "cuts" or "all" kvars
+  -- , noEliminate    :: Bool       -- ^ don't eliminate non-top-level and non-recursive KVars
+  --, oldEliminate   :: Bool       -- ^ use old eliminate algorithm (for benchmarking only)
   , port           :: Int        -- ^ port at which lhi should listen
   , exactDC        :: Bool       -- ^ Automatically generate singleton types for data constructors
-  , scrapeImports  :: Bool       -- ^ scrape qualifiers from imported specifications
+  , noMeasureFields :: Bool      -- ^ Do not automatically lift data constructor fields into measures
+  , scrapeImports   :: Bool      -- ^ scrape qualifiers from imported specifications
+  , scrapeInternals :: Bool      -- ^ scrape qualifiers from auto specifications
   , scrapeUsedImports  :: Bool   -- ^ scrape qualifiers from used, imported specifications
-  , elimStats      :: Bool       -- ^ print eliminate stats
+  , elimStats       :: Bool       -- ^ print eliminate stats
+  , elimBound       :: Maybe Int  -- ^ eliminate upto given depth of KVar chains
+  , json            :: Bool       -- ^ print results (safe/errors) as JSON
+  , counterExamples :: Bool       -- ^ attempt to generate counter-examples to type errors
+  , timeBinds       :: Bool       -- ^ check and time each (asserted) type-sig separately
+  , noPatternInline :: Bool       -- ^ treat code patterns (e.g. e1 >>= \x -> e2) specially for inference
+  , untidyCore      :: Bool       -- ^ print full blown core (with untidy names) in verbose mode
+  , noSimplifyCore  :: Bool       -- ^ simplify GHC core before constraint-generation
+  , nonLinCuts      :: Bool       -- ^ treat non-linear kvars as cuts
+  , autoInstantiate :: Instantiate -- ^ How to instantiate axioms
+  , proofMethod     :: ProofMethod -- ^ How to create automatic instances 
+  , fuel            :: Int         -- ^ Fuel for axiom instantiation 
+  , debugInstantionation :: Bool   -- ^ Debug Instantiation  
+  , noslice         :: Bool        -- ^ Disable non-concrete KVar slicing
   } deriving (Generic, Data, Typeable, Show, Eq)
 
+instance Serialize ProofMethod
+instance Serialize Instantiate
 instance Serialize SMTSolver
 instance Serialize Config
 
+data Instantiate = NoInstances | SMTInstances | LiquidInstances | LiquidInstancesLocal
+  deriving (Eq, Data, Typeable, Generic)
 
+data ProofMethod = Arithmetic | Rewrite | AllMethods 
+  deriving (Eq, Data, Typeable, Generic)
+
+
+allowSMTInstationation, allowLiquidInstationation, allowLiquidInstationationLocal, allowLiquidInstationationGlobal :: Config -> Bool 
+allowSMTInstationation    cfg = autoInstantiate cfg == SMTInstances
+
+allowLiquidInstationation cfg =  autoInstantiate cfg == LiquidInstances
+                              || autoInstantiate cfg == LiquidInstancesLocal 
+
+allowLiquidInstationationGlobal cfg = autoInstantiate cfg == LiquidInstances
+allowLiquidInstationationLocal  cfg = autoInstantiate cfg == LiquidInstancesLocal
+
+allowRewrite, allowArithmetic :: Config -> Bool 
+allowRewrite    cfg = proofMethod cfg == Rewrite    || proofMethod cfg == AllMethods
+allowArithmetic cfg = proofMethod cfg == Arithmetic || proofMethod cfg == AllMethods
+
+
+
+instance Default ProofMethod where
+  def = Rewrite
+
+instance Show ProofMethod where
+  show Arithmetic = "arithmetic"
+  show Rewrite    = "rewrite"
+  show AllMethods = "all"  
+
+
+instance Default Instantiate where
+  def = NoInstances
+
+instance Show Instantiate where
+  show NoInstances           = "none"
+  show SMTInstances          = "SMT"
+  show LiquidInstancesLocal  = "liquid-local"  
+  show LiquidInstances       = "liquid-global"  
+
+
 class HasConfig t where
   getConfig :: t -> Config
+
+  patternFlag :: t -> Bool
+  patternFlag = not . noPatternInline . getConfig
+
+  higherOrderFlag :: t -> Bool
+  higherOrderFlag = higherorder . getConfig
+
+
+
 
 hasOpt :: HasConfig t => t -> (Config -> Bool) -> Bool
 hasOpt t f = f (getConfig t)
diff --git a/src/Language/Haskell/Liquid/UX/DiffCheck.hs b/src/Language/Haskell/Liquid/UX/DiffCheck.hs
--- a/src/Language/Haskell/Liquid/UX/DiffCheck.hs
+++ b/src/Language/Haskell/Liquid/UX/DiffCheck.hs
@@ -3,9 +3,9 @@
 --   modified since it was last checked, as determined by a diff against
 --   a saved version of the file.
 
-{-# LANGUAGE OverloadedStrings         #-}
-{-# LANGUAGE FlexibleContexts          #-}
-{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE FlexibleInstances #-}
 
 module Language.Haskell.Liquid.UX.DiffCheck (
 
@@ -16,49 +16,54 @@
    , slice
 
    -- * Use target binders to generate DiffCheck target
-   , thin
+   , thin -- , ThinDeps (..)
 
    -- * Save current information for next time
    , saveResult
 
+   -- * Names of top-level binders that are rechecked
+   , checkedVars
+
+   -- * CoreBinds defining given set of Var
+   , filterBinds
    )
    where
 
-import            Prelude                       hiding (error)
 
-import            Data.Aeson
-import qualified  Data.Text as T
-import            Data.Algorithm.Diff
-
-import            Data.Maybe                    (listToMaybe, mapMaybe, fromMaybe)
-import            Data.Hashable
-import qualified  Data.IntervalMap.FingerTree as IM
-import            CoreSyn                       hiding (sourceName)
-import            Name
-import            SrcLoc hiding (Located)
-import            Var
-import qualified  Data.HashSet                  as S
-import qualified  Data.HashMap.Strict           as M
-import qualified  Data.List                     as L
-import            System.Directory                (copyFile, doesFileExist)
-import            Language.Fixpoint.Types         (FixResult (..), Located (..))
-import            Language.Fixpoint.Utils.Files
-import            Language.Haskell.Liquid.Types   (ErrorResult, SpecType, GhcSpec (..), AnnInfo (..), DataConP (..), Output (..))
-import            Language.Haskell.Liquid.Misc    (mkGraph)
-import            Language.Haskell.Liquid.GHC.Misc
-import            Language.Haskell.Liquid.Types.Visitors
-import            Language.Haskell.Liquid.UX.Errors   ()
-import            Text.Parsec.Pos                  (sourceName, sourceLine, sourceColumn, SourcePos, newPos)
-import            Text.PrettyPrint.HughesPJ        (text, render, Doc)
-import            Language.Haskell.Liquid.Types.Errors
-
-import qualified  Data.ByteString               as B
-import qualified  Data.ByteString.Lazy          as LB
-
+import           FastString                             (FastString)
+import           Prelude                                hiding (error)
+import           Data.Aeson
+import qualified Data.Text                              as T
+import           Data.Algorithm.Diff
+import           Data.Maybe                             (listToMaybe, mapMaybe, fromMaybe)
+import           Data.Hashable
+import qualified Data.IntervalMap.FingerTree            as IM
+import           CoreSyn                                hiding (sourceName)
+import           Name                                   (getSrcSpan, NamedThing)
+import           Outputable                             (Outputable, OutputableBndr)
+import           SrcLoc                                 hiding (Located)
+import           Var
+import qualified Data.HashSet                           as S
+import qualified Data.HashMap.Strict                    as M
+import qualified Data.List                              as L
+import           System.Directory                       (copyFile, doesFileExist)
+import           Language.Fixpoint.Types                (PPrint (..), FixResult (..), Located (..))
+-- import            Language.Fixpoint.Misc          (traceShow)
+import           Language.Fixpoint.Utils.Files
+import           Language.Haskell.Liquid.Types          (LocSpecType, ErrorResult, GhcSpec (..), AnnInfo (..), DataConP (..), Output (..))
+import           Language.Haskell.Liquid.Misc           (ifM, mkGraph)
+import           Language.Haskell.Liquid.GHC.Misc
+import           Language.Haskell.Liquid.Types.Visitors
+import           Language.Haskell.Liquid.UX.Errors      ()
+import           Text.Parsec.Pos                        (sourceName, sourceLine, sourceColumn, SourcePos, newPos)
+import           Text.PrettyPrint.HughesPJ              (text, render, Doc)
+import           Language.Haskell.Liquid.Types.Errors
+import qualified Data.ByteString                        as B
+import qualified Data.ByteString.Lazy                   as LB
 
--------------------------------------------------------------------------
--- Data Types -----------------------------------------------------------
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Data Types ----------------------------------------------------------------
+--------------------------------------------------------------------------------
 
 -- | Main type of value returned for diff-check.
 data DiffCheck = DC { newBinds  :: [CoreBind]
@@ -66,6 +71,9 @@
                     , newSpec   :: !GhcSpec
                     }
 
+instance PPrint DiffCheck where
+  pprintTidy k = pprintTidy k . checkedVars
+
 -- | Variable definitions
 data Def  = D { start  :: Int -- ^ line at which binder definition starts
               , end    :: Int -- ^ line at which binder definition ends
@@ -85,15 +93,22 @@
 instance Show Def where
   show (D i j x) = showPpr x ++ " start: " ++ show i ++ " end: " ++ show j
 
-
+--------------------------------------------------------------------------------
+-- | `checkedNames` returns the names of the top-level binders that will be checked
+--------------------------------------------------------------------------------
+checkedVars              ::  DiffCheck -> [Var]
+checkedVars              = concatMap names . newBinds
+   where
+     names (NonRec v _ ) = [v]
+     names (Rec xs)      = fst <$> xs
 
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 -- | `slice` returns a subset of the @[CoreBind]@ of the input `target`
 --    file which correspond to top-level binders whose code has changed
 --    and their transitive dependencies.
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 slice :: FilePath -> [CoreBind] -> GhcSpec -> IO (Maybe DiffCheck)
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 slice target cbs sp = ifM (doesFileExist savedFile)
                           doDiffCheck
                           (return Nothing)
@@ -102,37 +117,36 @@
     doDiffCheck     = sliceSaved target savedFile cbs sp
 
 sliceSaved :: FilePath -> FilePath -> [CoreBind] -> GhcSpec -> IO (Maybe DiffCheck)
-sliceSaved target savedFile coreBinds spec
-  = do (is, lm) <- lineDiff target savedFile
-       result   <- loadResult target
-       return    $ sliceSaved' is lm (DC coreBinds result spec)
+sliceSaved target savedFile coreBinds spec = do
+  (is, lm) <- lineDiff target savedFile
+  result   <- loadResult target
+  return    $ sliceSaved' target is lm (DC coreBinds result spec)
 
-sliceSaved' :: [Int] -> LMap -> DiffCheck -> Maybe DiffCheck
-sliceSaved' is lm (DC coreBinds result spec)
-  | globalDiff is spec = Nothing
-  | otherwise          = Just $ DC cbs' res' sp'
+sliceSaved' :: FilePath -> [Int] -> LMap -> DiffCheck -> Maybe DiffCheck
+sliceSaved' srcF is lm (DC coreBinds result spec)
+  | gDiff     = Nothing
+  | otherwise = Just $ DC cbs' res' sp'
   where
-    cbs'             = thinWith sigs coreBinds $ diffVars is dfs
-    sigs             = S.fromList $ M.keys sigm
-    sigm             = sigVars is spec
-    res'             = adjustOutput lm cm result
-    cm               = checkedItv chDfs
-    dfs              = coreDefs coreBinds ++ specDefs spec
-    chDfs            = coreDefs cbs'
-    sp'              = assumeSpec sigm spec
+    gDiff     = globalDiff srcF is spec
+    sp'       = assumeSpec sigm spec
+    res'      = adjustOutput lm cm result
+    cm        = checkedItv (coreDefs cbs')
+    cbs'      = thinWith sigs coreBinds (diffVars is defs)
+    defs      = coreDefs coreBinds ++ specDefs srcF spec
+    sigs      = S.fromList $ M.keys sigm
+    sigm      = sigVars srcF is spec
 
--- Add the specified signatures for vars-with-preserved-sigs,
--- whose bodies have been pruned from [CoreBind] into the "assumes"
-assumeSpec :: M.HashMap Var (Located SpecType) -> GhcSpec -> GhcSpec
-assumeSpec sigm sp = sp { asmSigs = M.toList $ M.union sigm assm }
+-- | Add the specified signatures for vars-with-preserved-sigs,
+--   whose bodies have been pruned from [CoreBind] into the "assumes"
+
+assumeSpec :: M.HashMap Var LocSpecType -> GhcSpec -> GhcSpec
+assumeSpec sigm sp = sp { gsAsmSigs = M.toList $ M.union sigm assm }
   where
-    assm           = M.fromList $ asmSigs sp
-    -- sigm'       = trace ("INCCHECK: sigm = " ++ show zs) sigm
-    -- zs          = M.keys sigm
+    assm           = M.fromList $ gsAsmSigs sp
 
 diffVars :: [Int] -> [Def] -> [Var]
-diffVars ls defs'    = -- tracePpr ("INCCHECK: diffVars lines = " ++ show ls ++ " defs= " ++ show defs) $
-                       go (L.sort ls) defs
+diffVars ls defs'    = tracePpr ("INCCHECK: diffVars lines = " ++ show ls ++ " defs= " ++ show defs) $
+                         go (L.sort ls) defs
   where
     defs             = L.sort defs'
     go _      []     = []
@@ -142,38 +156,53 @@
       | i > end d    = go (i:is) ds
       | otherwise    = binder d : go (i:is) ds
 
-sigVars :: [Int] -> GhcSpec -> M.HashMap Var (Located SpecType)
-sigVars ls sp = M.fromList $ filter (ok . snd) $ specSigs sp
+sigVars :: FilePath -> [Int] -> GhcSpec -> M.HashMap Var LocSpecType
+sigVars srcF ls sp = M.fromList $ filter (ok . snd) $ specSigs sp
   where
-    ok        = not . isDiff ls
+    ok             = not . isDiff srcF ls
 
-globalDiff :: [Int] -> GhcSpec -> Bool
-globalDiff lines spec = measDiff || invsDiff || dconsDiff
+globalDiff :: FilePath -> [Int] -> GhcSpec -> Bool
+globalDiff srcF ls spec = measDiff || invsDiff || dconsDiff
   where
-    measDiff  = any (isDiff lines) (snd <$> meas spec)
-    invsDiff  = any (isDiff lines) (invariants spec)
-    dconsDiff = any (isDiff lines) (dloc . snd <$> dconsP spec)
+    measDiff  = any (isDiff srcF ls) (snd <$> gsMeas spec)
+    invsDiff  = any (isDiff srcF ls) (snd <$> gsInvariants spec)
+    dconsDiff = any (isDiff srcF ls) (dloc . snd <$> gsDconsP spec)
     dloc dc   = Loc (dc_loc dc) (dc_locE dc) ()
 
-isDiff :: [Int] -> Located a -> Bool
-isDiff lines x = any hits lines
+isDiff :: FilePath -> [Int] -> Located a -> Bool
+isDiff srcF ls x = file x == srcF && any hits ls
   where
-    hits i = line x <= i && i <= lineE x
+    hits i       = line x <= i && i <= lineE x
 
--------------------------------------------------------------------------
--- | @thin@ returns a subset of the @[CoreBind]@ given which correspond
---   to those binders that depend on any of the @Var@s provided.
--------------------------------------------------------------------------
-thin :: [CoreBind] -> [Var] -> [CoreBind]
--------------------------------------------------------------------------
-thin = thinWith S.empty
+--------------------------------------------------------------------------------
+-- | @thin cbs sp vs@ returns a subset of the @cbs :: [CoreBind]@ which
+--   correspond to the definitions of @vs@ and the functions transitively
+--   called therein for which there are *no* type signatures. Callees with
+--   type signatures are assumed to satisfy those signatures.
+--------------------------------------------------------------------------------
 
+{- data ThinDeps = Trans [Var] -- ^ Check all transitive dependencies
+              | None   Var  -- ^ Check only the given binders
+ -}
+
+--------------------------------------------------------------------------------
+thin :: [CoreBind] -> GhcSpec -> [Var] -> DiffCheck
+--------------------------------------------------------------------------------
+-- thin cbs sp (Trans vs) = DC (thinWith S.empty cbs vs ) mempty sp
+thin cbs sp vs = DC (filterBinds      cbs vs') mempty sp'
+  where
+    vs'        = txClosure (coreDeps cbs) xs (S.fromList vs)
+    sp'        = assumeSpec sigs' sp
+    sigs'      = foldr M.delete (M.fromList xts) vs
+    xts        = specSigs sp
+    xs         = S.fromList $ fst <$> xts
+
 thinWith :: S.HashSet Var -> [CoreBind] -> [Var] -> [CoreBind]
 thinWith sigs cbs xs = filterBinds cbs ys
   where
-     ys       = calls `S.union` calledBy
-     calls    = txClosure (coreDeps cbs) sigs (S.fromList xs)
-     calledBy = dependsOn (coreDeps cbs) xs
+    ys       = calls `S.union` calledBy
+    calls    = txClosure (coreDeps cbs) sigs (S.fromList xs)
+    calledBy = dependsOn (coreDeps cbs) xs
 
 coreDeps    :: [CoreBind] -> Deps
 coreDeps bs = mkGraph $ calls ++ calls'
@@ -182,63 +211,70 @@
     calls'  = [(y, x) | (x, y) <- calls]
     deps b  = [(x, y) | x <- bindersOf b
                       , y <- freeVars S.empty b]
--- Given a call graph, and a list of vars, this function checks all functions
--- to see if they call any of the functions in the vars list. If any do, then
--- they must also be rechecked.
+
+-- | Given a call graph, and a list of vars, `dependsOn`
+--   checks all functions to see if they call any of the
+--   functions in the vars list.
+--   If any do, then they must also be rechecked.
+
 dependsOn :: Deps -> [Var] -> S.HashSet Var
-dependsOn cg vars = S.fromList results
-   where
-      preds = map S.member vars
-      filteredMaps = M.filter <$> preds <*> pure cg
-      results = map fst $ M.toList $ M.unions filteredMaps
+dependsOn cg vars  = S.fromList results
+  where
+    preds          = map S.member vars
+    filteredMaps   = M.filter <$> preds <*> pure cg
+    results        = map fst $ M.toList $ M.unions filteredMaps
 
 txClosure :: Deps -> S.HashSet Var -> S.HashSet Var -> S.HashSet Var
-txClosure d sigs xs = go S.empty xs
+txClosure d sigs    = go S.empty
   where
-    next           = S.unions . fmap deps . S.toList
-    deps x         = M.lookupDefault S.empty x d
+    next            = S.unions . fmap deps . S.toList
+    deps x          = M.lookupDefault S.empty x d
     go seen new
-      | S.null new = seen
-      | otherwise  = let seen' = S.union seen new
-                         new'  = next new `S.difference` seen'
-                         new'' = new'  `S.difference` sigs
-                     in go seen' new''
+      | S.null new  = seen
+      | otherwise   = let seen' = S.union seen new
+                          new'  = next new `S.difference` seen'
+                          new'' = new'     `S.difference` sigs
+                      in go seen' new''
 
 
 
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 filterBinds        :: [CoreBind] -> S.HashSet Var -> [CoreBind]
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 filterBinds cbs ys = filter f cbs
   where
     f (NonRec x _) = x `S.member` ys
     f (Rec xes)    = any (`S.member` ys) $ fst <$> xes
 
 
--------------------------------------------------------------------------
-specDefs :: GhcSpec -> [Def]
--------------------------------------------------------------------------
-specDefs       = map def . specSigs
+--------------------------------------------------------------------------------
+specDefs :: FilePath -> GhcSpec -> [Def]
+--------------------------------------------------------------------------------
+specDefs srcF  = map def . filter sameFile . specSigs
   where
     def (x, t) = D (line t) (lineE t) x
+    sameFile   = (srcF ==) . file . snd
 
-specSigs :: GhcSpec -> [(Var, Located SpecType)]
-specSigs sp = tySigs sp ++ asmSigs sp ++ ctors sp
+specSigs :: GhcSpec -> [(Var, LocSpecType)]
+specSigs sp = gsTySigs sp ++ gsAsmSigs sp ++ gsCtors sp
 
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 coreDefs     :: [CoreBind] -> [Def]
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 coreDefs cbs = L.sort [D l l' x | b <- cbs
                                 , x <- bindersOf b
                                 , isGoodSrcSpan (getSrcSpan x)
                                 , (l, l') <- coreDef b]
+
+coreDef :: (NamedThing a, OutputableBndr a)
+        => Bind a -> [(Int, Int)]
 coreDef b    = meetSpans b eSp vSp
   where
     eSp      = lineSpan b $ catSpans b $ bindSpans b
     vSp      = lineSpan b $ catSpans b $ getSrcSpan <$> bindersOf b
 
 
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 -- | `meetSpans` cuts off the start-line to be no less than the line at which
 --   the binder is defined. Without this, i.e. if we ONLY use the ticks and
 --   spans appearing inside the definition of the binder (i.e. just `eSp`)
@@ -249,6 +285,7 @@
 --   where `spanEnd` is a single line function around 1092 but where
 --   the generated span starts mysteriously at 222 where Data.List is imported.
 
+meetSpans :: Ord t1 => t -> Maybe (t1, t2) -> Maybe (t1, t3) -> [(t1, t2)]
 meetSpans _ Nothing       _
   = []
 meetSpans _ (Just (l,l')) Nothing
@@ -256,25 +293,34 @@
 meetSpans _ (Just (l,l')) (Just (m,_))
   = [(max l m, l')]
 
+lineSpan :: t -> SrcSpan -> Maybe (Int, Int)
 lineSpan _ (RealSrcSpan sp) = Just (srcSpanStartLine sp, srcSpanEndLine sp)
 lineSpan _ _                = Nothing
 
+catSpans :: (NamedThing r, OutputableBndr r)
+         => Bind r -> [SrcSpan] -> SrcSpan
 catSpans b []               = panic Nothing $ "DIFFCHECK: catSpans: no spans found for " ++ showPpr b
 catSpans b xs               = foldr combineSrcSpans noSrcSpan [x | x@(RealSrcSpan z) <- xs, bindFile b == srcSpanFile z]
 
+bindFile
+  :: (Outputable r, NamedThing r) =>
+     Bind r -> FastString
 bindFile (NonRec x _) = varFile x
 bindFile (Rec xes)    = varFile $ fst $ head xes
 
+varFile :: (Outputable a, NamedThing a) => a -> FastString
 varFile b = case getSrcSpan b of
               RealSrcSpan z -> srcSpanFile z
               _             -> panic Nothing $ "DIFFCHECK: getFile: no file found for: " ++ showPpr b
 
 
+bindSpans :: NamedThing a => Bind a -> [SrcSpan]
 bindSpans (NonRec x e)    = getSrcSpan x : exprSpans e
 bindSpans (Rec    xes)    = map getSrcSpan xs ++ concatMap exprSpans es
   where
     (xs, es)              = unzip xes
 
+exprSpans :: NamedThing a => Expr a -> [SrcSpan]
 exprSpans (Tick t e)
   | isJunkSpan sp         = exprSpans e
   | otherwise             = [sp]
@@ -289,21 +335,21 @@
 exprSpans (Case e x _ cs) = getSrcSpan x : exprSpans e ++ concatMap altSpans cs
 exprSpans _               = []
 
+altSpans :: (NamedThing a, NamedThing a1) => (t, [a], Expr a1) -> [SrcSpan]
 altSpans (_, xs, e)       = map getSrcSpan xs ++ exprSpans e
 
+isJunkSpan :: SrcSpan -> Bool
 isJunkSpan (RealSrcSpan _) = False
 isJunkSpan _               = True
 
--------------------------------------------------------------------------
--- | Diff Interface -----------------------------------------------------
--------------------------------------------------------------------------
-
-
+--------------------------------------------------------------------------------
+-- | Diff Interface ------------------------------------------------------------
+--------------------------------------------------------------------------------
 -- | `lineDiff new old` compares the contents of `src` with `dst`
 --   and returns the lines of `src` that are different.
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 lineDiff :: FilePath -> FilePath -> IO ([Int], LMap)
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 lineDiff new old  = lineDiff' <$> getLines new <*> getLines old
   where
     getLines      = fmap lines . readFile
@@ -316,9 +362,9 @@
     diffLineCount = fmap length <$> getGroupedDiff new old
 
 -- | Identifies lines that have changed
-diffLines :: Int -- ^ Starting line
-             -> [Diff Int] -- ^ List of lengths of diffs
-             -> [Int] -- ^ List of changed line numbers
+diffLines :: Int        -- ^ Starting line
+          -> [Diff Int] -- ^ List of lengths of diffs
+          -> [Int]      -- ^ List of changed line numbers
 diffLines _ []                        = []
 diffLines curr (Both lnsUnchgd _ : d) = diffLines toSkip d
    where toSkip = curr + lnsUnchgd
@@ -343,9 +389,9 @@
 
 -- | @save@ creates an .saved version of the @target@ file, which will be
 --    used to find what has changed the /next time/ @target@ is checked.
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 saveResult :: FilePath -> Output Doc -> IO ()
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 saveResult target res
   = do copyFile target saveF
        B.writeFile errF $ LB.toStrict $ encode res
@@ -353,17 +399,17 @@
        saveF = extFileName Saved  target
        errF  = extFileName Cache  target
 
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 loadResult   :: FilePath -> IO (Output Doc)
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 loadResult f = ifM (doesFileExist jsonF) out (return mempty)
   where
     jsonF    = extFileName Cache f
     out      = (fromMaybe mempty . decode . LB.fromStrict) <$> B.readFile jsonF
 
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 adjustOutput :: LMap -> ChkItv -> Output Doc -> Output Doc
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 adjustOutput lm cm o  = mempty { o_types  = adjustTypes  lm cm (o_types  o) }
                                { o_result = adjustResult lm cm (o_result o) }
 
@@ -384,31 +430,41 @@
 adjustErrors :: LMap -> ChkItv -> [TError a] -> [TError a]
 adjustErrors lm cm                = mapMaybe adjustError
   where
-    adjustError (ErrSaved sp m)   =  (`ErrSaved` m) <$> adjustSrcSpan lm cm sp
-    adjustError e                 = Just e
+    adjustError e                 = case adjustSrcSpan lm cm (pos e) of
+                                      Just sp' -> Just (e {pos = sp'})
+                                      Nothing  -> Nothing
 
--------------------------------------------------------------------------
+    -- adjustError (ErrSaved sp m)   =  (`ErrSaved` m) <$>
+    -- adjustError e                 = Just e
+
+--------------------------------------------------------------------------------
 adjustSrcSpan :: LMap -> ChkItv -> SrcSpan -> Maybe SrcSpan
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 adjustSrcSpan lm cm sp
   = do sp' <- adjustSpan lm sp
        if isCheckedSpan cm sp'
          then Nothing
          else Just sp'
 
+isCheckedSpan :: IM.IntervalMap Int a -> SrcSpan -> Bool
 isCheckedSpan cm (RealSrcSpan sp) = isCheckedRealSpan cm sp
 isCheckedSpan _  _                = False
+
+isCheckedRealSpan :: IM.IntervalMap Int a -> RealSrcSpan -> Bool
 isCheckedRealSpan cm              = not . null . (`IM.search` cm) . srcSpanStartLine
 
+adjustSpan :: LMap -> SrcSpan -> Maybe SrcSpan
 adjustSpan lm (RealSrcSpan rsp)   = RealSrcSpan <$> adjustReal lm rsp
 adjustSpan _  sp                  = Just sp
+
+adjustReal :: LMap -> RealSrcSpan -> Maybe RealSrcSpan
 adjustReal lm rsp
   | Just δ <- getShift l1 lm      = Just $ realSrcSpan f (l1 + δ) c1 (l2 + δ) c2
   | otherwise                     = Nothing
   where
     (f, l1, c1, l2, c2)           = unpackRealSrcSpan rsp
-    
 
+
 -- | @getShift lm old@ returns @Just δ@ if the line number @old@ shifts by @δ@
 -- in the diff and returns @Nothing@ otherwise.
 getShift     :: Int -> LMap -> Maybe Int
@@ -425,9 +481,9 @@
     is            = [IM.Interval l1 l2 | D l1 l2 _ <- chDefs]
 
 
--------------------------------------------------------------------------
--- | Aeson instances ----------------------------------------------------
--------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Aeson instances -----------------------------------------------------------
+--------------------------------------------------------------------------------
 
 instance ToJSON SourcePos where
   toJSON p = object [   "sourceName"   .= f
@@ -474,15 +530,11 @@
 instance FromJSON (Output Doc)
 
 
+file :: Located a -> FilePath
+file = sourceName . loc
+
 line :: Located a -> Int
 line  = sourceLine . loc
 
 lineE :: Located a -> Int
 lineE = sourceLine . locE
-
--------------------------------------------------------------------------
----- Helper functions ---------------------------------------------------
--------------------------------------------------------------------------
-
-ifM :: (Monad m) => m Bool -> m b -> m b -> m b
-ifM b x y = b >>= \z -> if z then x else y
diff --git a/src/Language/Haskell/Liquid/UX/Errors.hs b/src/Language/Haskell/Liquid/UX/Errors.hs
--- a/src/Language/Haskell/Liquid/UX/Errors.hs
+++ b/src/Language/Haskell/Liquid/UX/Errors.hs
@@ -23,7 +23,10 @@
 import           Language.Haskell.Liquid.Types
 import           Language.Haskell.Liquid.Misc        (single)
 
+-- import Debug.Trace
+
 type Ctx = M.HashMap Symbol SpecType
+type CtxM = M.HashMap Symbol (WithModel SpecType)
 
 ------------------------------------------------------------------------
 tidyError :: FixSolution -> Error -> Error
@@ -31,7 +34,6 @@
 tidyError sol
   = fmap (tidySpecType Full)
   . tidyErrContext sol
-  . applySolution sol
 
 tidyErrContext :: FixSolution -> Error -> Error
 tidyErrContext _ e@(ErrSubType {})
@@ -42,6 +44,14 @@
       tA      = tact e
       tE      = texp e
 
+tidyErrContext _ e@(ErrSubTypeModel {})
+  = e { ctxM = c', tactM = fmap (subst θ) tA, texp = fmap (subst θ) tE }
+    where
+      (θ, c') = tidyCtxM xs $ ctxM e
+      xs      = syms tA ++ syms tE
+      tA      = tactM e
+      tE      = texp e
+
 tidyErrContext _ e@(ErrAssType {})
   = e { ctx = c', cond = subst θ p }
     where
@@ -62,7 +72,14 @@
     (θ, xts)  = tidyTemps $ second stripReft <$> tidyREnv xs m
     tBind x t = (x', shiftVV t x') where x' = tidySymbol x
 
+tidyCtxM       :: [Symbol] -> CtxM -> (Subst, CtxM)
+tidyCtxM xs m  = (θ, M.fromList yts)
+  where
+    yts       = [tBind x t | (x, t) <- xts]
+    (θ, xts)  = tidyTemps $ second (fmap stripReft) <$> tidyREnvM xs m
+    tBind x t = (x', fmap (\t -> shiftVV t x') t) where x' = tidySymbol x
 
+
 stripReft     :: SpecType -> SpecType
 stripReft t   = maybe t' (strengthen t') ro
   where
@@ -81,6 +98,13 @@
     xs'       = expandFix deps xs
     deps y    = maybe [] (syms . rTypeReft) (M.lookup y m)
     ok        = not . isFunTy
+
+tidyREnvM      :: [Symbol] -> CtxM -> [(Symbol, WithModel SpecType)]
+tidyREnvM xs m = [(x, t) | x <- xs', t <- maybeToList (M.lookup x m), ok t]
+  where
+    xs'       = expandFix deps xs
+    deps y    = maybe [] (syms . rTypeReft . dropModel) (M.lookup y m)
+    ok        = not . isFunTy . dropModel
 
 expandFix :: (Eq a, Hashable a) => (a -> [a]) -> [a] -> [a]
 expandFix f               = S.toList . go S.empty
diff --git a/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs b/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs
@@ -0,0 +1,209 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TupleSections #-}
+
+module Language.Haskell.Liquid.UX.QuasiQuoter (
+    -- * LiquidHaskell Specification QuasiQuoter
+    lq
+
+    -- * QuasiQuoter Annotations
+  , LiquidQuote(..)
+  ) where
+
+import SrcLoc (SrcSpan)
+
+import Data.Data
+import Data.List
+
+import qualified Data.Text as T
+
+import Language.Haskell.TH.Lib
+import Language.Haskell.TH.Syntax
+import Language.Haskell.TH.Quote
+
+import Text.Parsec.Pos
+import Text.PrettyPrint.HughesPJ
+
+import Language.Fixpoint.Types hiding (Error, Loc, SrcSpan)
+import qualified Language.Fixpoint.Types as F
+
+import Language.Haskell.Liquid.GHC.Misc (fSrcSpan)
+import Language.Haskell.Liquid.Parse
+import Language.Haskell.Liquid.Types
+import Language.Haskell.Liquid.Types.RefType
+import Language.Haskell.Liquid.UX.Tidy
+
+--------------------------------------------------------------------------------
+-- LiquidHaskell Specification QuasiQuoter -------------------------------------
+--------------------------------------------------------------------------------
+
+lq :: QuasiQuoter
+lq = QuasiQuoter
+  { quoteExp  = bad
+  , quotePat  = bad
+  , quoteType = bad
+  , quoteDec  = lqDec
+  }
+  where
+    bad = fail "`lq` quasiquoter can only be used as a top-level declaration"
+
+lqDec :: String -> Q [Dec]
+lqDec src = do
+  pos <- locSourcePos <$> location
+  case singleSpecP pos src of
+    Left err -> throwErrorInQ $ errorToUserError err
+    Right spec -> do
+      prg <- pragAnnD ModuleAnnotation $
+               conE 'LiquidQuote `appE` dataToExpQ' spec
+      case mkSpecDecs spec of
+        Left err ->
+          throwErrorInQ err
+        Right decs ->
+          return $ prg : decs
+
+throwErrorInQ :: UserError -> Q a
+throwErrorInQ err =
+  fail . showpp =<< runIO (errorWithContext err)
+
+--------------------------------------------------------------------------------
+-- Liquid Haskell to Template Haskell ------------------------------------------
+--------------------------------------------------------------------------------
+
+-- Spec to Dec -----------------------------------------------------------------
+
+mkSpecDecs :: BPspec -> Either UserError [Dec]
+mkSpecDecs (Asrt (name, ty)) =
+  return . SigD (symbolName name)
+    <$> simplifyBareType name (quantifyFreeRTy $ val ty)
+mkSpecDecs (LAsrt (name, ty)) =
+  return . SigD (symbolName name)
+    <$> simplifyBareType name (quantifyFreeRTy $ val ty)
+mkSpecDecs (Asrts (names, (ty, _))) =
+  (\t -> (`SigD` t) . symbolName <$> names)
+    <$> simplifyBareType (head names) (quantifyFreeRTy $ val ty)
+mkSpecDecs (Alias rta) =
+  return . (TySynD name tvs) <$> simplifyBareType lsym (rtBody rta)
+  where
+    lsym = F.Loc (rtPos rta) (rtPosE rta) (rtName rta)
+    name = symbolName $ rtName rta
+    tvs  = PlainTV . symbolName <$> rtTArgs rta
+mkSpecDecs _ =
+  Right []
+
+-- Symbol to TH Name -----------------------------------------------------------
+
+symbolName :: Symbolic s => s -> Name
+symbolName = mkName . symbolString . symbol
+
+-- BareType to TH Type ---------------------------------------------------------
+
+simplifyBareType :: LocSymbol -> BareType -> Either UserError Type
+simplifyBareType s t = case simplifyBareType' t of
+  Simplified t' ->
+    Right t'
+  FoundExprArg l ->
+    Left $ ErrTySpec l (pprint $ val s) (pprint t) $ text
+      "Found expression argument in bad location in type"
+  FoundHole ->
+    Left $ ErrTySpec (fSrcSpan s) (pprint $ val s) (pprint t) $ text
+      "Can't write LiquidHaskell type with hole in a quasiquoter"
+
+simplifyBareType' :: BareType -> Simpl Type
+simplifyBareType' = simplifyBareType'' ([], [])
+
+simplifyBareType'' :: ([BTyVar], [BareType]) -> BareType -> Simpl Type
+
+simplifyBareType'' ([], []) (RVar v _) =
+  return $ VarT $ symbolName v
+simplifyBareType'' ([], []) (RAppTy t1 t2 _) =
+  AppT <$> simplifyBareType' t1 <*> simplifyBareType' t2
+simplifyBareType'' ([], []) (RFun _ i o _) =
+  (\x y -> ArrowT `AppT` x `AppT` y)
+    <$> simplifyBareType' i <*> simplifyBareType' o
+simplifyBareType'' ([], []) (RApp cc as _ _) =
+  let c  = btc_tc cc
+      c' | isFun   c = ArrowT
+         | isTuple c = TupleT (length as)
+         | isList  c = ListT
+         | otherwise = ConT $ symbolName c
+  in  foldl' AppT c' <$> sequenceA (filterExprArgs $ simplifyBareType' <$> as)
+
+simplifyBareType'' _ (RExprArg e) =
+  FoundExprArg $ fSrcSpan e
+simplifyBareType'' _ (RHole _) =
+  FoundHole
+
+simplifyBareType'' s(RAllP _ t) =
+  simplifyBareType'' s t
+simplifyBareType'' s (RAllS _ t) =
+  simplifyBareType'' s t
+simplifyBareType'' s (RAllE _ _ t) =
+  simplifyBareType'' s t
+simplifyBareType'' s (REx _ _ t) =
+  simplifyBareType'' s t
+simplifyBareType'' s (RRTy _ _ _ t) =
+  simplifyBareType'' s t
+
+simplifyBareType'' (tvs, cls) (RFun _ i o _)
+  | isClassType i = simplifyBareType'' (tvs, i : cls) o
+simplifyBareType'' (tvs, cls) (RAllT tv t) =
+  simplifyBareType'' (ty_var_value tv : tvs, cls) t
+
+simplifyBareType'' (tvs, cls) t =
+  ForallT (PlainTV . symbolName <$> reverse tvs)
+    <$> mapM simplifyBareType' (reverse cls)
+    <*> simplifyBareType' t
+
+
+data Simpl a = Simplified a
+             | FoundExprArg SrcSpan
+             | FoundHole
+               deriving (Functor)
+
+instance Applicative Simpl where
+  pure = Simplified
+
+  Simplified   f <*> Simplified   x = Simplified $ f x
+  _              <*> FoundExprArg l = FoundExprArg l
+  _              <*> FoundHole      = FoundHole
+  FoundExprArg l <*> _              = FoundExprArg l
+  FoundHole      <*> _              = FoundHole
+
+instance Monad Simpl where
+  return = Simplified
+
+  Simplified   x >>= f = f x
+  FoundExprArg l >>= _ = FoundExprArg l
+  FoundHole      >>= _ = FoundHole
+
+filterExprArgs :: [Simpl a] -> [Simpl a]
+filterExprArgs = filter check
+  where
+    check (FoundExprArg _) = False
+    check _ = True
+
+--------------------------------------------------------------------------------
+-- QuasiQuoter Annotations -----------------------------------------------------
+--------------------------------------------------------------------------------
+
+newtype LiquidQuote = LiquidQuote { liquidQuoteSpec :: BPspec }
+                      deriving (Data, Typeable)
+
+--------------------------------------------------------------------------------
+-- Template Haskell Utility Functions ------------------------------------------
+--------------------------------------------------------------------------------
+
+locSourcePos :: Loc -> SourcePos
+locSourcePos loc =
+  newPos (loc_filename loc) (fst $ loc_start loc) (snd $ loc_start loc)
+
+dataToExpQ' :: Data a => a -> Q Exp
+dataToExpQ' = dataToExpQ (const Nothing `extQ` textToExpQ)
+
+textToExpQ :: T.Text -> Maybe ExpQ
+textToExpQ text = Just $ varE 'T.pack `appE` stringE (T.unpack text)
+
+extQ :: (Typeable a, Typeable b) => (a -> q) -> (b -> q) -> a -> q
+extQ f g a = maybe (f a) g (cast a)
+
diff --git a/src/Language/Haskell/Liquid/UX/Server.hs b/src/Language/Haskell/Liquid/UX/Server.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Liquid/UX/Server.hs
@@ -0,0 +1,58 @@
+module Language.Haskell.Liquid.UX.Server (getType) where
+
+import           Prelude hiding (error)
+
+-- import           Control.Monad ((<<))
+import           Language.Haskell.Liquid.Types (Output(..))
+import qualified Language.Haskell.Liquid.UX.ACSS as A
+import           Text.PrettyPrint.HughesPJ    hiding (Mode)
+import           Language.Fixpoint.Utils.Files
+import           System.Directory
+import           Data.Time.Clock (UTCTime)
+import qualified Control.Exception as Ex
+import           Data.Aeson
+import qualified Data.ByteString.Lazy   as B
+
+-- data Time = TimeTodo deriving (Eq, Ord, Show)
+
+getType :: IO (Output Doc) -> FilePath -> Int -> Int -> IO String
+getType k srcF line col = do
+  act <- action srcF
+  case act of
+    Reuse    -> getTypeInfo line col <$>       getAnnMap srcF
+    Rebuild  -> getTypeInfo line col <$> (k >> getAnnMap srcF)
+    NoSource -> return "Missing Source"
+
+--------------------------------------------------------------------------------
+-- | How to Get Info
+--------------------------------------------------------------------------------
+
+data Action = Rebuild | Reuse | NoSource
+
+action :: FilePath -> IO Action
+action srcF = timeAction <$> modificationTime srcF <*> modificationTime jsonF
+  where
+    jsonF   = extFileName Json srcF
+
+timeAction :: Maybe UTCTime -> Maybe UTCTime -> Action
+timeAction (Just srcT) (Just jsonT)
+  | srcT < jsonT  = Reuse
+timeAction (Just _) _ = Rebuild
+timeAction Nothing _  = NoSource
+
+modificationTime :: FilePath -> IO (Maybe UTCTime)
+modificationTime f = (Just <$> getModificationTime f) `Ex.catch` handler
+  where
+    handler :: IOError -> IO (Maybe UTCTime)
+    handler = const (return Nothing)
+
+--------------------------------------------------------------------------------
+
+getTypeInfo :: Int -> Int -> Maybe A.AnnMap -> String
+getTypeInfo _ _ Nothing     = "ERROR: corrupt annotation info"
+getTypeInfo l c (Just info) = error "TODO: getTypeInfo"
+
+getAnnMap :: FilePath -> IO (Maybe A.AnnMap)
+getAnnMap srcF = decode <$> B.readFile jsonF
+  where
+    jsonF      = extFileName Json srcF
diff --git a/src/Language/Haskell/Liquid/UX/Tidy.hs b/src/Language/Haskell/Liquid/UX/Tidy.hs
--- a/src/Language/Haskell/Liquid/UX/Tidy.hs
+++ b/src/Language/Haskell/Liquid/UX/Tidy.hs
@@ -24,33 +24,27 @@
     -- * Final result
   , Result (..)
 
+    -- * Error to UserError
+  , errorToUserError
+
     -- * MOVE TO TYPES
   , cinfoError
   ) where
 
-import           Prelude             hiding (error)
-
-import qualified Data.HashMap.Strict as M
-import qualified Data.HashSet        as S
-import qualified Data.List           as L
-import qualified Data.Text           as T
-
-
-import qualified Control.Exception  as Ex
-
-import Language.Haskell.Liquid.GHC.Misc      (showPpr, stringTyVar)
-
-import Language.Fixpoint.Types      hiding (Result, SrcSpan, Error)
-import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Types.RefType (rVar, subsTyVars_meet)
-import Language.Haskell.Liquid.Types.PrettyPrint
-
-
-
-
-
-import Data.Generics                       (everywhere, mkT)
-import Text.PrettyPrint.HughesPJ
+import           Data.Hashable
+import           Prelude                                   hiding (error)
+import qualified Data.HashMap.Strict                       as M
+import qualified Data.HashSet                              as S
+import qualified Data.List                                 as L
+import qualified Data.Text                                 as T
+import qualified Control.Exception                         as Ex
+import           Language.Haskell.Liquid.GHC.Misc          (showPpr, stringTyVar)
+import           Language.Fixpoint.Types                   hiding (Result, SrcSpan, Error)
+import           Language.Haskell.Liquid.Types
+import           Language.Haskell.Liquid.Types.RefType     (rVar, subsTyVars_meet, FreeVar)
+import           Language.Haskell.Liquid.Types.PrettyPrint
+import           Data.Generics                             (everywhere, mkT)
+import           Text.PrettyPrint.HughesPJ
 
 
 ------------------------------------------------------------------------
@@ -64,21 +58,21 @@
   result e = Crash [e] ""
 
 instance Result [Error] where
-  result es = Crash (e2u <$> es) ""
+  result es = Crash (errorToUserError <$> es) ""
 
 instance Result Error where
   result e  = result [e] --  Crash [pprint e] ""
 
 instance Result (FixResult Cinfo) where
-  result = fmap (e2u . cinfoError)
+  result = fmap (errorToUserError . cinfoError)
 
-e2u :: Error -> UserError
-e2u = fmap ppSpecTypeErr
+errorToUserError :: Error -> UserError
+errorToUserError = fmap ppSpecTypeErr
 
 -- TODO: move to Types.hs
 cinfoError :: Cinfo -> Error
-cinfoError (Ci _ (Just e)) = e
-cinfoError (Ci l _)        = ErrOther l (text $ "Cinfo:" ++ showPpr l)
+cinfoError (Ci _ (Just e) _) = e
+cinfoError (Ci l _ _)        = ErrOther l (text $ "Cinfo:" ++ showPpr l)
 
 -------------------------------------------------------------------------
 isTmpSymbol    :: Symbol -> Bool
@@ -98,6 +92,7 @@
 tidyValueVars :: SpecType -> SpecType
 tidyValueVars = mapReft $ \u -> u { ur_reft = tidyVV $ ur_reft u }
 
+tidyVV :: Reft -> Reft
 tidyVV r@(Reft (va,_))
   | isJunk va = shiftVV r v'
   | otherwise = r
@@ -145,15 +140,17 @@
     pool = [[c] | c <- ['a'..'z']] ++ [ "t" ++ show i | i <- [1..]]
 
 
+bindersTx :: [Symbol] -> Symbol -> Symbol
 bindersTx ds   = \y -> M.lookupDefault y y m
   where
     m          = M.fromList $ zip ds $ var <$> [1..]
     var        = symbol . ('x' :) . show
 
 
+tyVars :: RType t a t1 -> [a]
 tyVars (RAllP _ t)     = tyVars t
 tyVars (RAllS _ t)     = tyVars t
-tyVars (RAllT α t)     = α : tyVars t
+tyVars (RAllT α t)     = ty_var_value α : tyVars t
 tyVars (RFun _ t t' _) = tyVars t ++ tyVars t'
 tyVars (RAppTy t t' _) = tyVars t ++ tyVars t'
 tyVars (RApp _ ts _ _) = concatMap tyVars ts
@@ -164,13 +161,23 @@
 tyVars (RRTy _ _ _ t)  = tyVars t
 tyVars (RHole _)       = []
 
+subsTyVarsAll
+  :: (Eq k, Hashable k,
+      Reftable r, TyConable c, SubsTy k (RType c k ()) c,
+      SubsTy k (RType c k ()) r,
+      SubsTy k (RType c k ()) k,
+      SubsTy k (RType c k ()) (RType c k ()),
+      SubsTy k (RType c k ()) (RTVar k (RType c k ())),
+      FreeVar c k)
+   => [(k, RType c k (), RType c k r)] -> RType c k r -> RType c k r
 subsTyVarsAll ats = go
   where
     abm            = M.fromList [(a, b) | (a, _, RVar b _) <- ats]
-    go (RAllT a t) = RAllT (M.lookupDefault a a abm) (go t)
+    go (RAllT a t) = RAllT (makeRTVar $ M.lookupDefault (ty_var_value a) (ty_var_value a) abm) (go t)
     go t           = subsTyVars_meet ats t
 
 
+funBinds :: RType t t1 t2 -> [Symbol]
 funBinds (RAllT _ t)      = funBinds t
 funBinds (RAllP _ t)      = funBinds t
 funBinds (RAllS _ t)      = funBinds t
@@ -192,10 +199,8 @@
 --------------------------------------------------------------------------------
 panicError = Ex.throw
 
--- ^ This function is put in this module as
---   it depends on the Exception instance,
---   which depends on the PPrint instance,
---   which depends on tidySpecType.
+-- ^ This function is put in this module as it depends on the Exception instance,
+--   which depends on the PPrint instance, which depends on tidySpecType.
 
 --------------------------------------------------------------------------------
 -- | Pretty Printing Error Messages --------------------------------------------
@@ -204,6 +209,7 @@
 -- | Need to put @PPrint Error@ instance here (instead of in Types),
 --   as it depends on @PPrint SpecTypes@, which lives in this module.
 
+
 instance PPrint (CtxError Doc) where
   pprintTidy k ce = ppError k (ctCtx ce) $ ctErr ce
 
@@ -212,11 +218,14 @@
 
 instance PPrint Error where
   pprintTidy k = ppError k empty . fmap ppSpecTypeErr
-
+ 
 ppSpecTypeErr :: SpecType -> Doc
-ppSpecTypeErr = rtypeDoc     Lossy
-              . tidySpecType Lossy
-              . fmap (everywhere (mkT noCasts))
+ppSpecTypeErr = ppSpecType Lossy
+
+ppSpecType :: Tidy -> SpecType -> Doc
+ppSpecType k = rtypeDoc     k
+             . tidySpecType k
+             . fmap (everywhere (mkT noCasts))
   where
     noCasts (ECst x _) = x
     noCasts e          = e
diff --git a/src/Language/Haskell/Liquid/WiredIn.hs b/src/Language/Haskell/Liquid/WiredIn.hs
--- a/src/Language/Haskell/Liquid/WiredIn.hs
+++ b/src/Language/Haskell/Liquid/WiredIn.hs
@@ -1,11 +1,13 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 module Language.Haskell.Liquid.WiredIn
-       ( propType
-       , propTyCon
-       , hpropTyCon
-       , pdVarReft
-       , wiredTyCons, wiredDataCons
+       (
+       -- propType
+       -- , propTyCon
+       -- , hpropTyCon,
+         pdVarReft
+       , wiredTyCons
+       , wiredDataCons
        , wiredSortedSyms
 
        -- | Constants for automatic proofs
@@ -13,10 +15,11 @@
        , proofTyConName, combineProofsName
        ) where
 
-import Prelude hiding (error)
+import Prelude                                hiding (error)
+import Var
 
 import Language.Haskell.Liquid.Types
-import Language.Haskell.Liquid.Misc (mapSnd)
+import Language.Fixpoint.Misc           (mapSnd)
 import Language.Haskell.Liquid.Types.RefType
 import Language.Haskell.Liquid.GHC.Misc
 import Language.Haskell.Liquid.Types.Variance
@@ -25,6 +28,7 @@
 
 
 import Language.Fixpoint.Types
+import qualified Language.Fixpoint.Types as F
 
 import BasicTypes
 import DataCon
@@ -36,14 +40,20 @@
 
 
 
+wiredSortedSyms :: [(Symbol, Sort)]
 wiredSortedSyms = [(pappSym n, pappSort n) | n <- [1..pappArity]]
 
 -----------------------------------------------------------------------
 -- | LH Primitive TyCons ----------------------------------------------
 -----------------------------------------------------------------------
 
+dictionaryVar :: Var
 dictionaryVar   = stringVar "tmp_dictionary_var" (ForAllTy dictionaryTyVar $ TyVarTy dictionaryTyVar)
+
+dictionaryTyVar :: TyVar
 dictionaryTyVar = stringTyVar "da"
+
+dictionaryBind :: Bind Var
 dictionaryBind = Rec [(v, Lam a $ App (Var v) (Type $ TyVarTy a))]
   where
    v = dictionaryVar
@@ -62,7 +72,6 @@
 proofTyConName :: Symbol
 proofTyConName = "Proof"
 
-propTyCon, hpropTyCon :: TyCon
 
 
 {- ATTENTION: Uniques should be different when defining TyCons
@@ -70,24 +79,30 @@
    bool in fixpoint, as propTyCon is a bool
  -}
 
-propTyCon  = symbolTyCon 'w' 25 propConName
-hpropTyCon = symbolTyCon 'w' 26 hpropConName
+-- propTyCon :: TyCon
+-- propTyCon  = symbolTyCon 'w' 25 propConName
 
+-- hpropTyCon :: TyCon
+-- hpropTyCon = symbolTyCon 'w' 26 hpropConName
+
 -----------------------------------------------------------------------
 -- | LH Primitive Types ----------------------------------------------
 -----------------------------------------------------------------------
 
-propType :: Reftable r => RRType r
-propType = RApp (RTyCon propTyCon [] defaultTyConInfo) [] [] mempty
+-- propType :: Reftable r => RRType r
+-- propType = RApp (RTyCon propTyCon [] defaultTyConInfo) [] [] mempty
 
---------------------------------------------------------------------
------- Predicate Types for WiredIns --------------------------------
---------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- | Predicate Types for WiredIns ----------------------------------------------
+--------------------------------------------------------------------------------
 
 maxArity :: Arity
 maxArity = 7
 
+wiredTyCons :: [(TyCon, TyConP)]
 wiredTyCons     = fst wiredTyDataCons
+
+wiredDataCons :: [(DataCon, Located DataConP)]
 wiredDataCons   = snd wiredTyDataCons
 
 wiredTyDataCons :: ([(TyCon, TyConP)] , [(DataCon, Located DataConP)])
@@ -96,7 +111,7 @@
     (tcs, dcs)  = unzip $ listTyDataCons : map tupleTyDataCons [2..maxArity]
 
 listTyDataCons :: ([(TyCon, TyConP)] , [(DataCon, DataConP)])
-listTyDataCons   = ( [(c, TyConP [RTV tyv] [p] [] [Covariant] [Covariant] (Just fsize))]
+listTyDataCons   = ( [(c, TyConP l0 [RTV tyv] [p] [] [Covariant] [Covariant] (Just fsize))]
                    , [(nilDataCon, DataConP l0 [RTV tyv] [p] [] [] [] lt l0)
                    , (consDataCon, DataConP l0 [RTV tyv] [p] [] [] cargs  lt l0)])
     where
@@ -105,18 +120,18 @@
       [tyv]      = tyConTyVarsDef c
       t          = rVar tyv :: RSort
       fld        = "fldList"
-      x          = "xListSelector"
-      xs         = "xsListSelector"
+      x          = "head"
+      xs         = "tail"
       p          = PV "p" (PVProp t) (vv Nothing) [(t, fld, EVar fld)]
       px         = pdVarReft $ PV "p" (PVProp t) (vv Nothing) [(t, fld, EVar x)]
       lt         = rApp c [xt] [rPropP [] $ pdVarReft p] mempty
       xt         = rVar tyv
       xst        = rApp c [RVar (RTV tyv) px] [rPropP [] $ pdVarReft p] mempty
       cargs      = [(xs, xst), (x, xt)]
-      fsize z    = mkEApp (dummyLoc "len") [EVar z]
+      fsize      = SymSizeFun (dummyLoc "len")
 
 tupleTyDataCons :: Int -> ([(TyCon, TyConP)] , [(DataCon, DataConP)])
-tupleTyDataCons n = ( [(c, TyConP (RTV <$> tyvs) ps [] tyvarinfo pdvarinfo Nothing)]
+tupleTyDataCons n = ( [(c, TyConP l0 (RTV <$> tyvs) ps [] tyvarinfo pdvarinfo Nothing)]
                     , [(dc, DataConP l0 (RTV <$> tyvs) ps [] []  cargs  lt l0)])
   where
     tyvarinfo     = replicate n     Covariant
@@ -140,11 +155,20 @@
     mks_ x        = (\i -> symbol (x++ show i)) <$> [2..n]
 
 
+pdVarReft :: PVar t -> UReft Reft
 pdVarReft = (\p -> MkUReft mempty p mempty) . pdVar
 
+mkps :: [Symbol]
+     -> [t] -> [(Symbol, F.Expr)] -> [PVar t]
 mkps ns (t:ts) ((f,x):fxs) = reverse $ mkps_ ns ts fxs [(t, f, x)] []
 mkps _  _      _           = panic Nothing "Bare : mkps"
 
+mkps_ :: [Symbol]
+      -> [t]
+      -> [(Symbol, F.Expr)]
+      -> [(t, Symbol, F.Expr)]
+      -> [PVar t]
+      -> [PVar t]
 mkps_ []     _       _          _    ps = ps
 mkps_ (n:ns) (t:ts) ((f, x):xs) args ps = mkps_ ns ts xs (a:args) (p:ps)
   where
diff --git a/src/LiquidHaskell.hs b/src/LiquidHaskell.hs
new file mode 100644
--- /dev/null
+++ b/src/LiquidHaskell.hs
@@ -0,0 +1,7 @@
+module LiquidHaskell (
+    -- * LiquidHaskell Specification QuasiQuoter
+    lq
+  ) where
+
+import Language.Haskell.Liquid.UX.QuasiQuoter
+
diff --git a/src/Target.hs b/src/Target.hs
new file mode 100644
--- /dev/null
+++ b/src/Target.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE LambdaCase #-}
+module Main where
+
+import Language.Haskell.Interpreter
+import System.Environment
+import System.Exit
+import System.IO
+import Test.Target
+import Text.Printf
+
+main :: IO ()
+main = do
+  [src, binder] <- getArgs
+  r <- runInterpreter $ do
+    loadModules [src]
+    mods <- getLoadedModules
+    -- liftIO $ print mods
+    setImportsQ $ map (\m -> (m,Nothing)) mods
+                             ++ [("Test.Target", Nothing), ("Prelude", Nothing)]
+    set [languageExtensions := [TemplateHaskell]]
+    let expr = printf "$(targetResultTH '%s \"%s\")" binder src
+    -- liftIO $ putStrLn expr
+    interpret expr (as :: IO Result)
+  case r of
+    Left e -> hPrint stderr e >> exitWith (ExitFailure 2)
+    Right x -> x >>= \case
+      Errored e -> hPutStrLn stderr e >> exitWith (ExitFailure 2)
+      Failed s  -> printf "Found counter-example: %s\n" s >> exitWith (ExitFailure 1)
+      Passed n  -> printf "OK! Passed %d tests.\n" n >> exitSuccess
diff --git a/src/Test/Target.hs b/src/Test/Target.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ViewPatterns #-}
+module Test.Target
+  ( target, targetResult, targetWith, targetResultWith
+  , targetTH, targetResultTH, targetWithTH, targetResultWithTH
+  , Result(..), Testable, Targetable(..)
+  , TargetOpts(..), defaultOpts
+  , Test(..)
+  , monomorphic
+  ) where
+
+
+import           Control.Monad
+import           Control.Monad.Catch
+import           Control.Monad.State
+import qualified Language.Haskell.TH             as TH
+import qualified Language.Haskell.TH.Syntax      as TH
+import           System.Process                  (terminateProcess)
+import           Test.QuickCheck.All             (monomorphic)
+import           Text.Printf                     (printf)
+
+import           Language.Fixpoint.Types.Names
+import           Language.Fixpoint.Smt.Interface 
+import qualified Language.Fixpoint.Types.Config  as F
+
+import           Test.Target.Monad
+import           Test.Target.Targetable (Targetable(..))
+import           Test.Target.Targetable.Function ()
+import           Test.Target.Testable
+import           Test.Target.Types
+import           Test.Target.Util
+
+-- | Test whether a function inhabits its refinement type by enumerating valid
+-- inputs and calling the function.
+target :: Testable f
+       => f -- ^ the function
+       -> String -- ^ the name of the function
+       -> FilePath -- ^ the path to the module that defines the function
+       -> IO ()
+target f name path
+  = targetWith f name path defaultOpts
+
+targetTH :: TH.Name -> TH.Q (TH.TExp (FilePath -> IO ()))
+targetTH f = TH.unsafeTExpCoerce
+           $ TH.appsE [TH.varE 'target, monomorphic f, TH.stringE (show f)]
+
+-- targetTH :: TH.ExpQ -- (TH.TExp (Testable f => f -> TH.Name -> IO ()))
+-- targetTH = TH.location >>= \TH.Loc {..} ->
+--   [| \ f n -> target f (show n) loc_filename |]
+
+-- | Like 'target', but returns the 'Result' instead of printing to standard out.
+targetResult :: Testable f => f -> String -> FilePath -> IO Result
+targetResult f name path
+  = targetResultWith f name path defaultOpts
+
+targetResultTH :: TH.Name -> TH.Q (TH.TExp (FilePath -> IO Result))
+targetResultTH f = TH.unsafeTExpCoerce
+                 $ TH.appsE [TH.varE 'targetResult, monomorphic f, TH.stringE (show f)]
+
+-- | Like 'target', but accepts options to control the enumeration depth,
+-- solver, and verbosity.
+targetWith :: Testable f => f -> String -> FilePath -> TargetOpts -> IO ()
+targetWith f name path opts
+  = do res <- targetResultWith f name path opts
+       case res of
+         Passed n -> printf "OK. Passed %d tests\n\n" n
+         Failed x -> printf "Found counter-example: %s\n\n" x
+         Errored x -> printf "Error! %s\n\n" x
+
+targetWithTH :: TH.Name -> TH.Q (TH.TExp (FilePath -> TargetOpts -> IO ()))
+targetWithTH f = TH.unsafeTExpCoerce
+               $ TH.appsE [TH.varE 'targetWith, monomorphic f, TH.stringE (show f)]
+
+-- | Like 'targetWith', but returns the 'Result' instead of printing to standard out.
+targetResultWith :: Testable f => f -> String -> FilePath -> TargetOpts -> IO Result
+targetResultWith f name path opts
+  = do when (verbose opts) $
+         printf "Testing %s\n" name
+       sp  <- getSpec (ghcOpts opts) path
+       ctx <- mkContext
+       do r <- runTarget opts (initState path sp ctx) $ do
+                 ty <- safeFromJust "targetResultWith" . lookup (symbol name) <$> gets sigs
+                 test f ty
+          _ <- cleanupContext ctx
+          return r
+        `onException` terminateProcess (ctxPid ctx)
+  where
+    mkContext = if logging opts
+                then makeContext F.defConfig{F.solver = solver opts} (".target/" ++ name)
+                else makeContextNoLog F.defConfig{F.solver = solver opts}
+
+targetResultWithTH :: TH.Name -> TH.Q (TH.TExp (FilePath -> TargetOpts -> IO Result))
+targetResultWithTH f = TH.unsafeTExpCoerce
+                     $ TH.appsE [TH.varE 'targetResultWith, monomorphic f, TH.stringE (show f)]
+
+data Test = forall t. Testable t => T t
diff --git a/src/Test/Target/Eval.hs b/src/Test/Target/Eval.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Eval.hs
@@ -0,0 +1,216 @@
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE LambdaCase        #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ViewPatterns      #-}
+module Test.Target.Eval ( eval, evalWith, evalExpr ) where
+
+
+
+import           Control.Monad.Catch
+import           Control.Monad.State
+import qualified Data.HashMap.Strict             as M
+
+import           Data.List
+import           Data.Maybe
+import qualified Data.Set                        as S
+
+
+import           Text.Printf
+
+import qualified GHC
+
+import           Language.Fixpoint.Smt.Theories  (theorySymbols)
+import           Language.Fixpoint.Types         hiding (R)
+import           Language.Haskell.Liquid.Types   hiding (var)
+
+import           Test.Target.Expr
+import           Test.Target.Monad
+
+import           Test.Target.Types
+import           Test.Target.Util
+
+-- import           Debug.Trace
+
+-- | Evaluate a refinement with the given expression substituted for the value
+-- variable.
+eval :: Reft -> Expr -> Target Bool
+eval r e = do
+  cts <- gets freesyms
+  evalWith (M.fromList $ map (\(_, c) -> (c, c `VC` [])) cts) r e
+
+-- | Evaluate a refinement with the given expression substituted for the value
+-- variable, in the given environment of free symbols.
+evalWith :: M.HashMap Symbol Val -> Reft -> Expr -> Target Bool
+evalWith m (Reft (v, p)) x
+  = do xx <- evalExpr x m
+                  -- FIXME: tidy is suspicious!!
+       evalPred p (M.insert (tidySymbol v) xx m)
+
+
+evalPred :: Expr -> M.HashMap Symbol Val -> Target Bool
+evalPred PTrue           _ = return True
+evalPred PFalse          _ = return False
+evalPred (PAnd ps)       m = and <$> sequence [evalPred p m | p <- ps]
+evalPred (POr ps)        m = or  <$> sequence [evalPred p m | p <- ps]
+evalPred (PNot p)        m = not <$> evalPred p m
+evalPred (PImp p q)      m = do pv <- evalPred p m
+                                if pv
+                                   then evalPred q m
+                                   else return True
+evalPred (PIff p q)      m = and <$> sequence [ evalPred (p `imp` q) m
+                                              , evalPred (q `imp` p) m
+                                              ]
+evalPred (PAtom b e1 e2) m = evalBrel b <$> evalExpr e1 m <*> evalExpr e2 m
+evalPred e@(splitEApp_maybe -> Just (f, es))    m
+  | f == "Set_emp" || f == "Set_sng" || f `M.member` theorySymbols
+  = mapM (`evalExpr` m) es >>= \es' -> fromExpr <$> evalSet f es'
+  | otherwise
+  = filter ((==f) . val . name) <$> gets measEnv >>= \case
+      [] -> error $ "evalPred: cannot evaluate " ++ show e -- VC f <$> mapM (`evalExpr` m) es
+                      --FIXME: should really extend this to multi-param measures..
+      ms -> do e' <- evalExpr (head es) m
+               fromExpr <$> applyMeasure (symbolString f) (concatMap eqns ms) e' m
+-- evalPred (PBexp e)       m = (==0) <$> evalPred e m
+evalPred p               _ = throwM $ EvalError $ "evalPred: " ++ show p
+-- evalExpr (PAll ss p)     m = undefined
+-- evalExpr PTop            m = undefined
+-- evalExpr :: Expr -> M.HashMap Symbol Expr -> Target Expr
+
+fromExpr :: Val -> Bool
+fromExpr (VB True) = True
+fromExpr (VB False) = False
+fromExpr e = error $ "fromExpr: " ++ show e ++ " is not boolean"
+
+evalExpr :: Expr -> M.HashMap Symbol Val -> Target Val
+evalExpr e m = do
+  -- traceShowM ("evalExpr", e)
+  evalExpr' e m
+
+evalExpr' :: Expr -> M.HashMap Symbol Val -> Target Val
+evalExpr' (ECon i)       _ = return $! VV i
+evalExpr' (EVar x)       m = return $! -- traceShow (x,m)
+                                       -- FIXME: tidy is fishy!!
+                                       -- datacons are embedded as vars and may not
+                                       -- be in the freesym environment
+                                    fromMaybe (VC x []) (M.lookup (tidySymbol x) m)
+evalExpr' (ESym s)       _ = return $! VX s
+evalExpr' (EBin b e1 e2) m = evalBop b <$> evalExpr' e1 m <*> evalExpr' e2 m
+evalExpr' (splitEApp_maybe -> Just (f, es))    m
+  | f == "Set_emp" || f == "Set_sng" || f `M.member` theorySymbols
+  = mapM (`evalExpr'` m) es >>= \es' -> evalSet f es'
+  | otherwise
+  = filter ((==f) . val . name) <$> gets measEnv >>= \case
+      [] -> VC f <$> mapM (`evalExpr'` m) es
+                      --FIXME: should really extend this to multi-param measures..
+      ms -> do e' <- evalExpr' (head es) m
+               applyMeasure (symbolString f) (concatMap eqns ms) e' m
+evalExpr' (EIte p e1 e2) m
+  = do b <- evalPred p m
+       if b
+         then evalExpr' e1 m
+         else evalExpr' e2 m
+evalExpr' e              _ = throwM $ EvalError $ printf "evalExpr(%s)" (show e)
+
+evalBrel :: Brel -> Val -> Val -> Bool
+evalBrel Eq = (==)
+evalBrel Ne = (/=)
+evalBrel Ueq = (==)
+evalBrel Une = (/=)
+evalBrel Gt = (>)
+evalBrel Ge = (>=)
+evalBrel Lt = (<)
+evalBrel Le = (<=)
+
+applyMeasure :: String -> [Language.Haskell.Liquid.Types.Def SpecType GHC.DataCon] -> Val -> M.HashMap Symbol Val -> Target Val
+applyMeasure name eqns (VC f es) env -- (splitEApp_maybe -> Just (f, es)) env
+  = do
+       -- traceShowM ("applyMeasure", name)
+       meq >>= \eq -> evalBody eq es env
+  where
+    -- FIXME: tidy is fishy!!
+    ct = symbolString . tidySymbol $ case f of
+      "GHC.Types.[]" -> "[]"
+      "GHC.Types.:"  -> ":"
+      "GHC.Tuple.(,)" -> "(,)"
+      "GHC.Tuple.(,,)" -> "(,,)"
+      "GHC.Tuple.(,,,)" -> "(,,,)"
+      "GHC.Tuple.(,,,,)" -> "(,,,,)"
+      x -> x
+    meq = case find ((==ct) . show . ctor) eqns of
+           Nothing -> throwM $ EvalError $ printf "applyMeasure(%s): no equation for %s" name (show ct)
+           Just x -> return x
+
+applyMeasure n _ e           _
+  = throwM $ EvalError $ printf "applyMeasure(%s, %s)" n (showpp e)
+
+-- setSym :: Symbol
+-- setSym = "LC_SET"
+
+-- nubSort :: [Expr] -> [Expr]
+-- nubSort = nub . Data.List.sort
+
+-- mkSet :: [Expr] -> Expr
+-- mkSet = app setSym . nubSort
+
+evalSet :: Symbol -> [Val] -> Target Val
+evalSet "Set_emp" [VS s]
+  = return $! if S.null s then VB True else VB False
+evalSet "Set_sng" [v]
+  = return $! VS $ S.singleton v
+-- TODO!!
+evalSet "Set_add" [v, VS s]
+  = return $! VS $ S.insert v s
+evalSet "Set_cap" [VS s1, VS s2]
+  = return $! VS $ S.intersection s1 s2
+evalSet "Set_cup" [VS s1, VS s2]
+  = return $! VS $ S.union s1 s2
+evalSet "Set_dif" [VS s1, VS s2]
+  = return $! VS $ s1 S.\\ s2
+evalSet "Set_sub" [VS s1, VS s2]
+  = return $! VB $ S.isSubsetOf s1 s2
+evalSet "Set_mem" [v, VS s]
+  = return $! VB $ S.member v s
+evalSet f es = throwM $ EvalError $ printf "evalSet(%s, %s)" (show f) (show es)
+
+evalBody
+  :: Language.Haskell.Liquid.Types.Def ty ctor
+     -> [Val] -> M.HashMap Symbol Val -> Target Val
+evalBody eq xs env = go $ body eq
+  where
+    go (E e) = evalExpr e env'
+    go (P p) = evalPred p env' >>= \b -> return $ if b then VB True else VB False
+    go (R v p) = do e <- evalRel v p env'
+                    case e of
+                      Nothing -> throwM $ EvalError $ "evalBody can't handle: " ++ show (R v p)
+                      Just e  -> return e
+    --go (R v (PBexp (EApp f e))) | val f == "Set_emp" = return $ app setSym []
+    ----FIXME: figure out how to handle the general case..
+    --go (R v p) = return (ECon (I 0))
+
+    env' = M.union (M.fromList (zip (map fst (binds eq)) xs)) env
+    -- su = mkSubst $ zip (map fst (binds eq)) xs
+
+evalRel :: Symbol -> Expr -> M.HashMap Symbol Val -> Target (Maybe Val)
+evalRel v (PAnd ps)       m = Just . head . catMaybes <$> sequence [evalRel v p m | p <- ps]
+evalRel v (PImp p q)      m = do pv <- evalPred p m
+                                 if pv
+                                    then evalRel v q m
+                                    else return Nothing
+evalRel v (PAtom Eq (EVar v') e2) m
+  | v == v'
+  = Just <$> evalExpr e2 m
+-- evalRel v (PBexp (EApp f [EVar v'])) _
+evalRel v (EApp (EVar f) (EVar v')) _
+  | v == v' && f == "Set_emp"
+  = return $! Just $ VS S.empty
+evalRel _ p               _
+  = throwM $ EvalError $ "evalRel: " ++ show p
+
+
+evalBop :: Bop -> Val -> Val -> Val
+evalBop Plus  (VV (I x)) (VV (I y)) = VV . I $ x + y
+evalBop Minus (VV (I x)) (VV (I y)) = VV . I $ x - y
+evalBop Times (VV (I x)) (VV (I y)) = VV . I $ x * y
+evalBop Div   (VV (I x)) (VV (I y)) = VV . I $ x `div` y
+evalBop Mod   (VV (I x)) (VV (I y)) = VV . I $ x `mod` y
+evalBop b     e1           e2       = error $ printf "evalBop(%s, %s, %s)" (show b) (show e1) (show e2)
diff --git a/src/Test/Target/Expr.hs b/src/Test/Target/Expr.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Expr.hs
@@ -0,0 +1,69 @@
+module Test.Target.Expr where
+
+import Language.Fixpoint.Types
+
+
+eq :: Expr -> Expr -> Expr
+eq  = PAtom Eq
+infix 4 `eq`
+
+ge :: Expr -> Expr -> Expr
+ge  = PAtom Ge
+infix 5 `ge`
+
+le :: Expr -> Expr -> Expr
+le  = PAtom Le
+infix 5 `le`
+
+gt :: Expr -> Expr -> Expr
+gt  = PAtom Gt
+infix 5 `gt`
+
+lt :: Expr -> Expr -> Expr
+lt  = PAtom Lt
+infix 5 `lt`
+
+iff :: Expr -> Expr -> Expr
+iff = PIff
+infix 3 `iff`
+
+imp :: Expr -> Expr -> Expr
+imp = PImp
+infix 3 `imp`
+
+
+app :: Symbolic a => a -> [Expr] -> Expr
+-- app f es = EApp (dummyLoc $ symbol f) es
+app = mkEApp . dummyLoc . symbol
+
+var :: Symbolic a => a -> Expr
+var = EVar . symbol
+
+-- prop :: Symbolic a => a -> Expr
+-- prop = PBexp . EVar . symbol
+prop :: Expr -> Expr
+prop = id
+
+instance Num Expr where
+  fromInteger = ECon . I . fromInteger
+  (+) = EBin Plus
+  (-) = EBin Minus
+  (*) = EBin Times
+  abs = error "abs of Liquid.Fixpoint.Types.Expr"
+  signum = error "signum of Liquid.Fixpoint.Types.Expr"
+
+-- instance Real Expr where
+--   toRational (ECon (I i)) = fromIntegral i
+--   toRational x            = error $ "toRational: " ++ show x
+
+-- instance Enum Expr where
+--   toEnum = ECon . I . fromIntegral
+--   fromEnum (ECon (I i)) = fromInteger i
+--   fromEnum x            = error $ "fromEnum: " ++ show x
+
+-- instance Integral Expr where
+--   div = EBin Div
+--   mod = EBin Mod
+--   quotRem x y = (x `div` y, x `mod` y)
+--   toInteger (ECon (I i)) = i
+--   toInteger x            = error $ "toInteger: " ++ show x
diff --git a/src/Test/Target/Monad.hs b/src/Test/Target/Monad.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Monad.hs
@@ -0,0 +1,303 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE RankNTypes                 #-}
+{-# LANGUAGE RecordWildCards            #-}
+{-# LANGUAGE ViewPatterns               #-}
+module Test.Target.Monad
+  ( whenVerbose
+  , noteUsed
+  , addDep
+  , addConstraint
+  , addConstructor
+  , addSort
+  , addVariable
+  , inModule
+  , making
+  , lookupCtor
+  , guarded
+  , fresh
+  , freshChoice
+  , freshInt
+  , getValue
+  , Target, runTarget
+  , TargetState(..), initState
+  , TargetOpts(..), defaultOpts
+  ) where
+
+import           Control.Applicative
+import           Control.Arrow                    (first, second, (***))
+import qualified Control.Exception                as Ex
+import           Control.Monad
+import           Control.Monad.Catch
+import           Control.Monad.Reader
+import           Control.Monad.State
+
+import qualified Data.HashMap.Strict              as M
+import qualified Data.HashSet                     as S
+import           Data.IORef
+import           Data.List                        hiding (sort)
+
+import qualified Data.Text                        as ST
+import qualified Data.Text.Lazy                   as T
+import qualified Data.Text.Lazy.Builder           as Builder
+import           System.IO.Unsafe
+-- import           Text.Printf
+
+import           Language.Fixpoint.Smt.Interface  hiding (SMTLIB2(..))
+import           Language.Fixpoint.Types
+import           Language.Fixpoint.Types.Config (SMTSolver(..))
+import           Language.Haskell.Liquid.Types.PredType
+import           Language.Haskell.Liquid.Types.RefType
+
+import           Language.Haskell.Liquid.Types    hiding (var, Target)
+
+import qualified GHC
+import qualified Type as GHC
+
+import           Test.Target.Serialize
+import           Test.Target.Types
+import           Test.Target.Util
+
+-- import           Debug.Trace
+
+
+newtype Target a = Target (StateT TargetState (ReaderT TargetOpts IO) a)
+  deriving ( Functor, Applicative, Monad, MonadIO, Alternative
+           , MonadState TargetState, MonadCatch, MonadReader TargetOpts )
+instance MonadThrow Target where
+  throwM = Ex.throw
+
+runTarget :: TargetOpts -> TargetState -> Target a -> IO a
+runTarget opts st (Target x) = runReaderT (evalStateT x st) opts
+
+-- evalTarget :: TargetOpts -> TargetState -> Target a -> IO a
+-- evalTarget o s (Target x) = runReaderT (evalStateT x s) o
+
+-- execTarget :: GhcSpec -> Target a -> IO TargetState
+-- execTarget e (Target x) = execStateT x (initGS e)
+
+seed :: IORef Int
+seed = unsafePerformIO $ newIORef 0
+{-# NOINLINE seed #-}
+
+freshInt :: Target Int
+freshInt = liftIO $ do
+  n <- readIORef seed
+  modifyIORef' seed (+1)
+  return n
+
+data TargetOpts = TargetOpts
+  { depth      :: !Int
+  , solver     :: !SMTSolver
+  , verbose    :: !Bool
+  , logging    :: !Bool
+  , keepGoing  :: !Bool
+    -- ^ whether to keep going after finding a counter-example, useful for
+    -- checking coverage
+  , maxSuccess :: !(Maybe Int)
+    -- ^ whether to stop after a certain number of successful tests, or
+    -- enumerate the whole input space
+  , scDepth    :: !Bool
+    -- ^ whether to use SmallCheck's notion of depth
+  , ghcOpts    :: ![String]
+    -- ^ extra options to pass to GHC
+  }
+
+defaultOpts :: TargetOpts
+defaultOpts = TargetOpts
+  { depth = 3
+  , solver = Z3
+  , verbose = False
+  , logging = True
+  , keepGoing = False
+  , maxSuccess = Nothing
+  , scDepth = True
+  , ghcOpts = []
+  }
+
+data TargetState = TargetState
+  { variables    :: ![Variable]
+  , choices      :: ![Variable]
+  , constraints  :: !Constraint
+  , deps         :: !(M.HashMap Symbol [Symbol])
+  , realized     :: ![(Symbol, Value)]
+  , dconEnv      :: ![(Symbol, DataConP)]
+  , ctorEnv      :: !DataConEnv
+  , measEnv      :: !MeasureEnv
+  , embEnv       :: !(TCEmb GHC.TyCon)
+  , tyconInfo    :: !(M.HashMap GHC.TyCon RTyCon)
+  , freesyms     :: ![(Symbol,Symbol)]
+  , constructors :: ![Variable] -- (S.HashSet Variable)  --[(String, String)]
+  , sigs         :: ![(Symbol, SpecType)]
+  , chosen       :: !(Maybe Symbol)
+  , sorts        :: !(S.HashSet Sort)
+  , modName      :: !Symbol
+  , filePath     :: !FilePath
+  , makingTy     :: !Sort
+  , smtContext   :: !Context
+  }
+
+initState :: FilePath -> GhcSpec -> Context -> TargetState
+initState fp sp ctx = TargetState
+  { variables    = []
+  , choices      = []
+  , constraints  = []
+  , deps         = mempty
+  , realized     = []
+  , dconEnv      = dcons
+  , ctorEnv      = cts
+  , measEnv      = meas
+  , embEnv       = gsTcEmbeds sp
+  , tyconInfo    = tyi
+  , freesyms     = free
+  , constructors = []
+  , sigs         = sigs
+  , chosen       = Nothing
+  , sorts        = S.empty
+  , modName      = ""
+  , filePath     = fp
+  , makingTy     = FObj ""
+  , smtContext   = ctx
+  }
+  where
+    -- FIXME: can we NOT tidy???
+    dcons = tidyF $ map (first symbol) (gsDconsP sp)
+
+    -- NOTE: we want to tidy all occurrences of nullary datacons in the signatures
+    cts   = subst su $ tidyF $ map (symbol *** val) (gsCtors sp)
+    sigs  = subst su $ tidyF $ map (symbol *** val) $ gsTySigs sp
+
+    tyi   = makeTyConInfo (gsTconsP sp)
+    free  = tidyS $ map (second symbol)
+          $ gsFreeSyms sp ++ map (\(c,_) -> (symbol c, c)) (gsCtors sp)
+    meas  = gsMeasures sp
+    tidyF = map (first tidySymbol)
+    tidyS = map (second tidySymbol)
+    su = mkSubst (map (second eVar) free)
+
+whenVerbose :: Target () -> Target ()
+whenVerbose x
+  = do v <- asks verbose
+       when v x
+
+noteUsed :: (Symbol, Value) -> Target ()
+noteUsed (v,x) = modify $ \s@(TargetState {..}) -> s { realized = (v,x) : realized }
+
+-- TODO: does this type make sense? should it be Symbol -> Symbol -> Target ()?
+addDep :: Symbol -> Expr -> Target ()
+addDep from (EVar to) = modify $ \s@(TargetState {..}) ->
+  s { deps = M.insertWith (flip (++)) from [to] deps }
+addDep _ _ = return ()
+
+addConstraint :: Expr -> Target ()
+addConstraint p = modify $ \s@(TargetState {..}) -> s { constraints = p:constraints }
+
+addConstructor :: Variable -> Target ()
+addConstructor c
+  = modify $ \s@(TargetState {..}) -> s { constructors = nub $ c:constructors }
+
+inModule :: Symbol -> Target a -> Target a
+inModule m act
+  = do m' <- gets modName
+       modify $ \s -> s { modName = m }
+       r <- act
+       modify $ \s -> s { modName = m' }
+       return r
+
+making :: Sort -> Target a -> Target a
+making ty act
+  = do ty' <- gets makingTy
+       modify $ \s -> s { makingTy = ty }
+       r <- act
+       modify $ \s -> s { makingTy = ty' }
+       return r
+
+-- | Find the refined type of a data constructor.
+lookupCtor :: Symbol -> SpecType -> Target SpecType
+lookupCtor c (toType -> t)
+             -- FIXME: WTF, how do two symbols share a Text
+             -- without being equal??
+  = do mt <- find (\(c', _) -> symbolText c == symbolText c')
+               <$> gets ctorEnv
+       case mt of
+         Just (_, t) -> return t
+         Nothing -> do
+           -- m  <- gets filePath
+           -- o  <- asks ghcOpts
+           let tc = GHC.tyConAppTyCon t
+           let dcs = GHC.tyConDataCons tc
+           let Just dc = find (\d -> c == symbol (GHC.getName d)) dcs
+           let t = ofType (GHC.dataConUserType dc)
+           -- t <- io $ runGhc o $ do
+           --        _ <- loadModule m
+           --        traceShowM c
+           --        t <- GHC.exprType (printf "(%s)" (symbolString c))
+           --        return (ofType t)
+           modify $ \s@(TargetState {..}) -> s { ctorEnv = (c,t) : ctorEnv }
+           return t
+
+-- | Given a data constructor @d@ and an action, create a new choice variable
+-- @c@ and execute the action while guarding any generated constraints with
+-- @c@. Returns @(action-result, c)@.
+guarded :: String -> Target Expr -> Target (Expr, Expr)
+guarded cn act
+  = do c  <- freshChoice cn
+       mc <- gets chosen
+       modify $ \s -> s { chosen = Just c }
+       x <- act
+       modify $ \s -> s { chosen = mc }
+       return (x, EVar c)
+
+-- | Generate a fresh variable of the given 'Sort'.
+fresh :: Sort -> Target Symbol
+fresh sort
+  = do n <- freshInt
+       let sorts' = sortTys sort
+       let x = symbol $ ST.unpack (ST.intercalate "->" $ map (symbolText.unObj) sorts') ++ show n
+       addVariable (x, sort)
+       return x
+
+addSort :: Sort -> Target ()
+addSort sort = do
+  let sorts' = sortTys sort
+  modify $ \s@(TargetState {..}) -> s { sorts = S.union (S.fromList (arrowize sort : sorts')) sorts }
+
+addVariable :: Variable -> Target ()
+addVariable (v, sort) = do
+  addSort sort
+  modify $ \s@(TargetState {..}) -> s { variables = (v, sort) : variables }
+
+
+sortTys :: Sort -> [Sort]
+--sortTys (FFunc _ ts) = concatMap sortTys ts
+sortTys t
+  | Just (_, ts, t) <- functionSort t
+  = concatMap sortTys ts ++ [t]
+  | otherwise
+  = [t]
+
+arrowize :: Sort -> Sort
+arrowize = FObj . symbol . ST.intercalate "->" . map (symbolText . unObj) . sortTys
+
+unObj :: Sort -> Symbol
+unObj FInt     = "Int"
+unObj (FObj s) = s
+unObj s        = error $ "unObj: " ++ show s
+
+-- | Given a data constructor @d@, create a new choice variable corresponding to
+-- @d@.
+freshChoice :: String -> Target Symbol
+freshChoice cn
+  = do n <- freshInt
+       let x = symbol $ T.unpack (Builder.toLazyText $ smt2 choicesort)
+                        ++ "-" ++ cn ++ "-" ++ show n
+       modify $ \s@(TargetState {..}) -> s { variables = (x,choicesort) : variables }
+       return x
+
+-- | Ask the SMT solver for the 'Value' of the given variable.
+getValue :: Symbol -> Target Value
+getValue v = do
+  ctx <- gets smtContext
+  Values [x] <- io $ ensureValues $ command ctx (GetValue [v])
+  noteUsed x
+  return (snd x)
diff --git a/src/Test/Target/Serialize.hs b/src/Test/Target/Serialize.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Serialize.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Target.Serialize where
+
+import qualified Data.List as List
+import Data.Maybe
+import Data.Text.Lazy.Builder (Builder)
+import qualified Data.Text.Lazy.Builder as Builder
+import Data.Text.Format
+
+import Language.Fixpoint.Misc
+import Language.Fixpoint.Smt.Interface (Command(..))
+import qualified Language.Fixpoint.Smt.Theories as Thy
+import Language.Fixpoint.Types
+
+class SMTLIB2 a where
+  smt2 :: a -> Builder
+
+instance SMTLIB2 Sort where
+  smt2 s@(FFunc _ _)           = errorstar $ "smt2 FFunc: " ++ show s
+  smt2 FInt                    = "Int"
+  smt2 FReal                   = "Real"
+  smt2 t
+    | t == boolSort            = "Bool"
+  smt2 t
+    | Just d <- Thy.smt2Sort t = d
+  smt2 (FObj s)                = Builder.fromText $ symbolSafeText s
+  smt2 _                       = "Int"
+
+
+instance SMTLIB2 Symbol where
+  smt2 s
+    | Just t <- Thy.smt2Symbol s = t
+  smt2 s                         = Builder.fromText $ symbolSafeText  s
+
+instance SMTLIB2 (Symbol, Sort) where
+  smt2 (sym, t) = build "({} {})" (smt2 sym, smt2 t)
+
+instance SMTLIB2 SymConst where
+  smt2   = smt2   . symbol
+
+instance SMTLIB2 Constant where
+  smt2 (I n)   = build "{}" (Only n)
+  smt2 (R d)   = build "{}" (Only d)
+  smt2 (L t _) = build "{}" (Only t) -- errorstar $ "Horrors, how to translate: " ++ show c
+
+instance SMTLIB2 LocSymbol where
+  smt2 = smt2 . val
+
+instance SMTLIB2 Bop where
+  smt2 Plus   = "+"
+  smt2 Minus  = "-"
+  smt2 Times  = "*"
+  smt2 Div    = "/"
+  smt2 RTimes = "*"
+  smt2 RDiv   = "/"
+  smt2 Mod    = "mod"
+
+instance SMTLIB2 Brel where
+  smt2 Eq    = "="
+  smt2 Ueq   = "="
+  smt2 Gt    = ">"
+  smt2 Ge    = ">="
+  smt2 Lt    = "<"
+  smt2 Le    = "<="
+  smt2 _     = errorstar "SMTLIB2 Brel"
+
+instance SMTLIB2 Expr where
+  smt2 (ESym z)         = smt2 (symbol z)
+  smt2 (ECon c)         = smt2 c
+  smt2 (EVar x)         = smt2 x
+  smt2 e@(EApp _ _)     = smt2App e
+  smt2 (ENeg e)         = build "(- {})" (Only $ smt2 e)
+  smt2 (EBin o e1 e2)   = build "({} {} {})" (smt2 o, smt2 e1, smt2 e2)
+  smt2 (EIte e1 e2 e3)  = build "(ite {} {} {})" (smt2 e1, smt2 e2, smt2 e3)
+  smt2 (ECst e _)       = smt2 e
+  smt2 (PTrue)          = "true"
+  smt2 (PFalse)         = "false"
+  smt2 (PAnd [])        = "true"
+  smt2 (PAnd ps)        = build "(and {})"   (Only $ smt2s ps)
+  smt2 (POr [])         = "false"
+  smt2 (POr ps)         = build "(or  {})"   (Only $ smt2s ps)
+  smt2 (PNot p)         = build "(not {})"   (Only $ smt2  p)
+  smt2 (PImp p q)       = build "(=> {} {})" (smt2 p, smt2 q)
+  smt2 (PIff p q)       = build "(= {} {})"  (smt2 p, smt2 q)
+  smt2 (PExist bs p)    = build "(exists ({}) {})"  (smt2s bs, smt2 p)
+  smt2 (PAll   bs p)    = build "(forall ({}) {})"  (smt2s bs, smt2 p)
+
+  smt2 (PAtom r e1 e2)  = mkRel r e1 e2
+  -- FIXME
+  smt2  _e               = "true" -- errorstar ("smtlib2 Pred  " ++ show e)
+
+
+
+smt2App :: Expr -> Builder
+smt2App e = fromMaybe (build "({} {})" (smt2 f, smt2many (smt2 <$> es)))
+                      (Thy.smt2App f (smt2 <$> es))
+  where
+    (f, es) = splitEApp e
+
+
+
+mkRel :: (SMTLIB2 a, SMTLIB2 a1) => Brel -> a -> a1 -> Builder
+mkRel Ne  e1 e2         = mkNe e1 e2
+mkRel Une e1 e2         = mkNe e1 e2
+mkRel r   e1 e2         = build "({} {} {})" (smt2 r, smt2 e1, smt2 e2)
+
+mkNe :: (SMTLIB2 a, SMTLIB2 a1) => a -> a1 -> Builder
+mkNe  e1 e2             = build "(not (= {} {}))" (smt2 e1, smt2 e2)
+
+instance SMTLIB2 Command where
+  smt2 (Declare x ts t)    = build "(declare-fun {} ({}) {})"     (smt2 x, smt2s ts, smt2 t)
+  smt2 (Define t)          = build "(declare-sort {})"            (Only $ smt2 t)
+  smt2 (Assert Nothing p)  = build "(assert {})"                  (Only $ smt2 p)
+  smt2 (Assert (Just i) p) = build "(assert (! {} :named p-{}))"  (smt2 p, i)
+  smt2 (AssertAxiom t)     = build "(assert {})"                  (Only $ smt2 t)
+  smt2 (Distinct az)       = build "(assert (distinct {}))"       (Only $ smt2s az)
+  smt2 (Push)              = "(push 1)"
+  smt2 (Pop)               = "(pop 1)"
+  smt2 (CheckSat)          = "(check-sat)"
+  smt2 (GetValue xs)       = mconcat . List.intersperse " "
+                           $ ["(get-value ("] ++ fmap smt2 xs ++ ["))"]
+  smt2 (CMany cmds)        = smt2many (smt2 <$> cmds)
+
+instance SMTLIB2 (Triggered Expr) where
+  smt2 (TR _ e) = smt2 e  
+
+smt2s    :: SMTLIB2 a => [a] -> Builder
+smt2s as = smt2many (smt2 <$> as)
+
+smt2many :: [Builder] -> Builder
+smt2many = mconcat . List.intersperse " "
diff --git a/src/Test/Target/Targetable.hs b/src/Test/Target/Targetable.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Targetable.hs
@@ -0,0 +1,572 @@
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE DefaultSignatures    #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE KindSignatures       #-}
+{-# LANGUAGE LambdaCase           #-}
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE ScopedTypeVariables  #-}
+{-# LANGUAGE TypeOperators        #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+
+{-# LANGUAGE ImplicitParams       #-}
+module Test.Target.Targetable
+  ( Targetable(..), qquery
+  , unfold, apply, unapply
+  , oneOf, whichOf
+  , constrain, ofReft
+  ) where
+
+import           Control.Applicative
+import           Control.Arrow                   (second)
+
+import           Control.Monad.Reader
+import           Control.Monad.State
+import           Data.Char
+import qualified Data.HashMap.Strict             as M
+import           Data.List
+import           Data.Maybe
+
+import           Data.Proxy
+import qualified Data.Text                       as T
+import           Data.Word                       (Word8)
+import           GHC.Generics
+import           GHC.Stack
+
+import           Language.Fixpoint.Types         hiding (prop, ofReft, reft)
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types   hiding (var)
+
+import           Test.Target.Expr
+import           Test.Target.Eval
+import           Test.Target.Monad
+
+
+import           Test.Target.Util
+
+-- import Debug.Trace
+
+--------------------------------------------------------------------------------
+--- Constrainable Data
+--------------------------------------------------------------------------------
+-- | A class of datatypes for which we can efficiently generate constrained
+-- values by querying an SMT solver.
+--
+-- If possible, instances should not be written by hand, but rather by using the
+-- default implementations via "GHC.Generics", e.g.
+--
+-- > import GHC.Generics
+-- > import Test.Target.Targetable
+-- >
+-- > data Foo = ... deriving Generic
+-- > instance Targetable Foo
+class Targetable a where
+  -- | Construct an SMT query describing all values of the given type up to the
+  -- given 'Depth'.
+  query   :: (?loc :: CallStack) => Proxy a -> Depth -> Symbol -> SpecType -> Target Symbol
+
+  -- | Reconstruct a Haskell value from the SMT model.
+  decode  :: Symbol
+             -- ^ the symbolic variable corresponding to the root of the value
+          -> SpecType
+             -- ^ the type of values we're generating (you can probably ignore this)
+          -> Target a
+
+  -- | Check whether a Haskell value inhabits the given type. Also returns a
+  -- logical expression corresponding to the Haskell value.
+  check   :: a -> SpecType -> Target (Bool, Expr)
+
+  -- | Translate a Haskell value into a logical expression.
+  toExpr  :: a -> Expr
+
+  -- | What is the Haskell type? (Mainly used to make the SMT queries more
+  -- readable).
+  getType :: Proxy a -> Sort
+
+  default getType :: (Generic a, Rep a ~ D1 d f, Datatype d)
+                  => Proxy a -> Sort
+  getType _ = FObj $ qualifiedDatatypeName (undefined :: Rep a a)
+
+  default query :: (?loc :: CallStack) => (Generic a, GQuery (Rep a))
+                => Proxy a -> Int -> Symbol -> SpecType -> Target Symbol
+  query p d x t = do
+    -- traceShowM ("query")
+    -- traceShowM ("query", t)
+    gquery (reproxyRep p) d x t
+
+  default toExpr :: (Generic a, GToExpr (Rep a))
+                 => a -> Expr
+  toExpr = gtoExpr . from
+
+  default decode :: (Generic a, GDecode (Rep a))
+                 => Symbol -> SpecType -> Target a
+  decode v _ = do
+    x <- whichOf v
+    (c, fs) <- unapply x
+    to <$> gdecode c fs
+
+  default check :: (Generic a, GCheck (Rep a))
+                => a -> SpecType -> Target (Bool, Expr)
+  check v t = gcheck (from v) t
+
+qquery :: Targetable a => Proxy a -> Int -> SpecType -> Target Symbol
+qquery p d t = fresh (getType p) >>= \x -> query p d x t
+
+reproxy :: proxy a -> Proxy b
+reproxy _ = Proxy
+{-# INLINE reproxy #-}
+
+-- | Given a data constuctor @d@ and a refined type for @d@s output,
+-- return a list of types representing suitable arguments for @d@.
+unfold :: Symbol -> SpecType -> Target [(Symbol, SpecType)]
+unfold cn t = do
+  -- traceShowM ("unfold.cn", cn)
+  dcp <- lookupCtor cn t
+  -- traceShowM ("unfold.dcp")
+  -- traceShowM ("unfold.t.r", reft t)
+  tyi <- gets tyconInfo
+  emb <- gets embEnv
+  let ts = applyPreds (addTyConInfo emb tyi t) dcp
+  -- traceM "unfold.ts.rs"
+  -- mapM_ (traceShowM . rt_reft . snd) ts
+  return ts
+
+-- | Given a data constructor @d@ and a list of expressions @xs@, construct a
+-- new expression corresponding to @d xs@.
+apply :: Symbol -> SpecType -> [Expr] -> Target Expr
+apply c t vs = do
+  -- traceShowM ("apply")
+  -- traceShowM ("apply", c, vs)
+  mc <- gets chosen
+  case mc of
+    Just ch -> mapM_ (addDep ch) vs
+    Nothing -> return ()
+  let x = app c vs
+  t <- lookupCtor c t
+  -- traceShowM ("apply.ctor", c, t)
+  let (xs, _, _, rt) = bkArrowDeep t
+      su             = mkSubst $ zip (map symbol xs) vs
+  addConstructor (c, rTypeSort mempty t)
+  constrain $ ofReft (subst su $ reft rt) x
+  return x
+
+
+-- | Split a symbolic variable representing the application of a data
+-- constructor into a pair of the data constructor and the sub-variables.
+unapply :: Symbol -> Target (Symbol, [Symbol])
+unapply c = do
+  let [_,cn,_] = T.splitOn "-" $ symbolText c
+  deps <- gets deps
+  return (symbol cn, M.lookupDefault [] c deps)
+
+-- | Given a symbolic variable and a list of @(choice, var)@ pairs,
+-- @oneOf x choices@ asserts that @x@ must equal one of the @var@s in
+-- @choices@.
+oneOf :: Symbol -> [(Expr,Expr)] -> Target ()
+oneOf x cs
+  = do cs <- forM cs $ \(y,c) -> do
+               addDep x c
+               constrain $ prop c `imp` (var x `eq` y)
+               return $ prop c
+       constrain $ pOr cs
+       constrain $ pAnd [ PNot $ pAnd [x, y]
+                        | [x, y] <- filter ((==2) . length) $ subsequences cs ]
+
+-- | Given a symbolic variable @x@, figure out which of @x@s choice varaibles
+-- was picked and return it.
+whichOf :: Symbol -> Target Symbol
+whichOf v = do
+  deps <- gets deps
+  let Just cs = M.lookup v deps
+  -- traceShowM (v, cs)
+  -- FIXME: should be a singleton list...
+  c:_  <- catMaybes <$> forM cs (\c -> do
+    val <- getValue c
+    if val == "true"
+      then return (Just c)
+      else return Nothing)
+  return c
+
+
+-- | Assert a logical predicate, guarded by the current choice variable.
+constrain :: (?loc :: CallStack) => Expr -> Target ()
+constrain p = do
+  -- traceShowM ("constrain")
+  -- traceM (showCallStack ?loc)
+  -- traceShowM ("constrain", p)
+  mc <- gets chosen
+  case mc of
+    Nothing -> addConstraint p
+    Just c  -> let p' = prop (var c) `imp` p
+               in addConstraint p'
+
+-- | Given a refinement @{v | p}@ and an expression @e@, construct
+-- the predicate @p[e/v]@.
+ofReft :: Reft -> Expr -> Expr
+ofReft (Reft (v, p)) e
+  = let x = mkSubst [(v, e)]
+    in subst x p
+
+--------------------------------------------------------------------------------
+--- Instances
+--------------------------------------------------------------------------------
+instance Targetable () where
+  getType _ = FObj "GHC.Tuple.()"
+  query _ _ x _ = return x -- fresh (FObj "GHC.Tuple.()")
+  -- this is super fiddly, but seemingly required since GHC.exprType chokes on "GHC.Tuple.()"
+  toExpr _   = app ("()" :: Symbol) []
+
+  decode _ _ = return ()
+  check _ t = do
+    let e = app ("()" :: Symbol) []
+    b <- eval (reft t) e
+    return (b,e)
+
+instance Targetable Int where
+  getType _ = FObj "GHC.Types.Int"
+  query _ d x t = -- fresh FInt >>= \x ->
+    do -- traceShowM ("query.int", var x)
+       -- traceShowM ("queyr.int", reft t)
+       constrain $ ofReft (reft t) (var x)
+       -- use the unfolding depth to constrain the range of Ints, like QuickCheck
+       constrain $ var x `ge` fromIntegral (negate d)
+       constrain $ var x `le` fromIntegral d
+       return x
+  toExpr i = ECon $ I $ fromIntegral i
+
+  decode v _ = read . T.unpack <$> getValue v
+
+  check v t = do
+    let e = fromIntegral v
+    b <- eval (reft t) e
+    return (b, e)
+
+instance Targetable Integer where
+  getType _ = FObj "GHC.Integer.Type.Integer"
+  query _ d x t = query (Proxy :: Proxy Int) d x t
+  toExpr  x = toExpr (fromIntegral x :: Int)
+
+  decode v t = decode v t >>= \(x::Int) -> return . fromIntegral $ x
+
+  check v t = do
+    let e = fromIntegral v
+    b <- eval (reft t) e
+    return (b, e)
+
+instance Targetable Char where
+  getType _ = FObj "GHC.Types.Char"
+  query _ d x t = -- fresh FInt >>= \x ->
+    do constrain $ var x `ge` 0
+       constrain $ var x `le` fromIntegral d
+       constrain $ ofReft (reft t) (var x)
+       return x
+  toExpr  c = ESym $ SL $ T.singleton c
+
+  decode v t = decode v t >>= \(x::Int) -> return . chr $ x + ord 'a'
+
+  check v t = do
+    let e = ESym $ SL $ T.singleton v
+    b <- eval (reft t) e
+    return (b, e)
+
+instance Targetable Word8 where
+  getType _ = FObj "GHC.Word.Word8"
+  query _ d x t = -- fresh FInt >>= \x ->
+    do _ <- asks depth
+       constrain $ var x `ge` 0
+       constrain $ var x `le` fromIntegral d
+       constrain $ ofReft (reft t) (var x)
+       return x
+  toExpr i   = ECon $ I $ fromIntegral i
+
+  decode v t = decode v t >>= \(x::Int) -> return $ fromIntegral x
+
+  check v t = do
+    let e = fromIntegral v
+    b <- eval (reft t) e
+    return (b, e)
+
+instance Targetable Bool
+  -- getType _ = FObj "GHC.Types.Bool"
+  -- query _ _ x t = -- fresh boolsort >>= \x ->
+  --   do constrain $ ofReft (reft t) (var x)
+  --      return x
+
+  -- decode v _ = getValue v >>= \case
+  --   "true"  -> return True
+  --   "false" -> return False
+  --   x       -> Ex.throwM (SmtError $ "expected boolean, got: " ++ T.unpack x)
+
+
+instance Targetable a => Targetable [a]
+instance Targetable a => Targetable (Maybe a)
+instance (Targetable a, Targetable b) => Targetable (Either a b)
+instance (Targetable a, Targetable b) => Targetable (a,b)
+instance (Targetable a, Targetable b, Targetable c) => Targetable (a,b,c)
+instance (Targetable a, Targetable b, Targetable c, Targetable d) => Targetable (a,b,c,d)
+
+
+-- instance (Num a, Integral a, Targetable a) => Targetable (Ratio a) where
+--   getType _ = FObj "GHC.Real.Ratio"
+--   query _ d t = query (Proxy :: Proxy Int) d t
+--   decode v t= decode v t >>= \ (x::Int) -> return (fromIntegral x)
+--   -- query _ d t = fresh (FObj "GHC.Real.Ratio") >>= \x ->
+--   --   do query (Proxy :: Proxy Int) d t
+--   --      query (Proxy :: Proxy Int) d t
+--   --      return x
+--   -- stitch d t = do x :: Int <- stitch d t
+--   --                 y' :: Int <- stitch d t
+--   --                 -- we should really modify `t' above to have Z3 generate non-zero denoms
+--   --                 let y = if y' == 0 then 1 else y'
+--   --                 let toA z = fromIntegral z :: a
+--   --                 return $ toA x % toA y
+--   toExpr x = EApp (dummyLoc "GHC.Real.:%") [toExpr (numerator x), toExpr (denominator x)]
+--   check = undefined
+
+
+reproxyRep :: Proxy a -> Proxy (Rep a a)
+reproxyRep = reproxy
+
+
+--------------------------------------------------------------------------------
+--- Sums of Products
+--------------------------------------------------------------------------------
+class GToExpr f where
+  gtoExpr      :: f a -> Expr
+
+class GQuery f where
+  gquery       :: (?loc :: CallStack) => Proxy (f a) -> Int -> Symbol -> SpecType -> Target Symbol
+
+class GDecode f where
+  gdecode      :: Symbol -> [Symbol] -> Target (f a)
+
+class GCheck f where
+  gcheck       :: f a -> SpecType -> Target (Bool, Expr)
+
+reproxyGElem :: Proxy (M1 d c f a) -> Proxy (f a)
+reproxyGElem = reproxy
+
+instance (Datatype c, GToExprCtor f) => GToExpr (D1 c f) where
+  gtoExpr (M1 x) = app (qualify mod (symbolString d)) xs
+    where
+      mod  = GHC.Generics.moduleName (undefined :: D1 c f a)
+      (EVar d, xs) = splitEApp $ gtoExprCtor x
+
+instance (Datatype c, GQueryCtors f) => GQuery (D1 c f) where
+  gquery p d x t = inModule mod . making sort $ do
+    --traceShowM ("gquery", sort)
+    xs <- gqueryCtors (reproxyGElem p) d t
+    -- x  <- fresh sort
+    oneOf x xs
+    constrain $ ofReft (reft t) (var x)
+    return x
+   where
+     mod  = symbol $ GHC.Generics.moduleName (undefined :: D1 c f a)
+     sort = FObj $ qualifiedDatatypeName (undefined :: D1 c f a)
+
+instance (Datatype c, GDecode f) => GDecode (D1 c f) where
+  gdecode c vs = M1 <$> making sort (gdecode c vs)
+    where
+      sort = FObj $ qualifiedDatatypeName (undefined :: D1 c f a)
+
+instance (Datatype c, GCheck f) => GCheck (D1 c f) where
+  gcheck (M1 x) t = inModule mod . making sort $ gcheck x t
+    where
+      mod  = symbol $ GHC.Generics.moduleName (undefined :: D1 c f a)
+      sort = FObj $ qualifiedDatatypeName (undefined :: D1 c f a)
+
+
+instance (Targetable a) => GToExpr (K1 i a) where
+  gtoExpr (K1 x) = toExpr x
+
+instance (Targetable a) => GQuery (K1 i a) where
+  gquery p d _ t = do
+    let p' = reproxy p :: Proxy a
+    ty <- gets makingTy
+    depth <- asks depth
+    sc <- asks scDepth
+    let d' = if getType p' == ty || sc
+                then d
+                else depth
+
+    qquery p' d' t
+
+instance Targetable a => GDecodeFields (K1 i a) where
+  gdecodeFields (v:vs) = do
+    x <- decode v undefined
+    return (vs, K1 x)
+  gdecodeFields _ = error "gdecodeFields []"
+
+instance Targetable a => GCheckFields (K1 i a) where
+  gcheckFields (K1 x) ((f,t):ts) = do
+    (b, v) <- check x t
+    return (b, [v], subst (mkSubst [(f, v)]) ts)
+  gcheckFields _ _ = error "gcheckFields _ []"
+
+qualify :: String -> String -> String
+qualify m x = m ++ ('.':x)
+{-# INLINE qualify #-}
+
+qualifiedDatatypeName :: Datatype d => D1 d f a -> Symbol
+qualifiedDatatypeName d = symbol $ qualify m (datatypeName d)
+  where m = GHC.Generics.moduleName d
+{-# INLINE qualifiedDatatypeName #-}
+
+--------------------------------------------------------------------------------
+--- Sums
+--------------------------------------------------------------------------------
+class GToExprCtor f where
+  gtoExprCtor   :: f a -> Expr
+
+class GQueryCtors f where
+  gqueryCtors :: (?loc :: CallStack) => Proxy (f a) -> Int -> SpecType -> Target [(Expr, Expr)]
+
+reproxyLeft :: Proxy ((c (f :: * -> *) (g :: * -> *)) a) -> Proxy (f a)
+reproxyLeft = reproxy
+
+reproxyRight :: Proxy ((c (f :: * -> *) (g :: * -> *)) a) -> Proxy (g a)
+reproxyRight = reproxy
+
+instance (GToExprCtor f, GToExprCtor g) => GToExprCtor (f :+: g) where
+  gtoExprCtor (L1 x) = gtoExprCtor x
+  gtoExprCtor (R1 x) = gtoExprCtor x
+
+instance (GQueryCtors f, GQueryCtors g) => GQueryCtors (f :+: g) where
+  gqueryCtors p d t = do
+    xs <- gqueryCtors (reproxyLeft p) d t
+    ys <- gqueryCtors (reproxyRight p) d t
+    return $! xs++ys
+
+instance (GDecode f, GDecode g) => GDecode (f :+: g) where
+  gdecode c vs =  L1 <$> gdecode c vs
+              <|> R1 <$> gdecode c vs
+
+instance (GCheck f, GCheck g) => GCheck (f :+: g) where
+  gcheck (L1 x) t = gcheck x t
+  gcheck (R1 x) t = gcheck x t
+
+
+instance (Constructor c, GToExprFields f) => GToExprCtor (C1 c f) where
+  gtoExprCtor c@(M1 x)  = app (symbol $ conName c) (gtoExprFields x)
+
+instance (Constructor c, GRecursive f, GQueryFields f) => GQueryCtors (C1 c f) where
+  gqueryCtors p d t | d <= 0
+    = do ty <- gets makingTy
+         if gisRecursive p ty
+           then return []
+           else pure <$> gqueryCtor p 0 t
+  gqueryCtors p d t = pure <$> gqueryCtor p d t
+
+instance (Constructor c, GDecodeFields f) => GDecode (C1 c f) where
+  gdecode c vs
+    | c == symbol (conName (undefined :: C1 c f a))
+    = M1 . snd <$> gdecodeFields vs
+    | otherwise
+    = empty
+
+instance (Constructor c, GCheckFields f) => GCheck (C1 c f) where
+  gcheck (M1 x) t = do
+    mod <- symbolString <$> gets modName
+    let cn = symbol $ qualify mod (conName (undefined :: C1 c f a))
+    ts <- unfold cn t
+    (b, vs, _) <- gcheckFields x ts
+    let v = app cn vs
+    b'  <- eval (reft t) v
+    return (b && b', v)
+
+gisRecursive :: (Constructor c, GRecursive f)
+             => Proxy (C1 c f a) -> Sort -> Bool
+gisRecursive (p :: Proxy (C1 c f a)) t
+  = t `elem` gconArgTys (reproxyGElem p)
+
+gqueryCtor :: (?loc :: CallStack) => (Constructor c, GQueryFields f)
+           => Proxy (C1 c f a) -> Int -> SpecType -> Target (Expr, Expr)
+gqueryCtor (p :: Proxy (C1 c f a)) d t
+  = guarded cn $ do
+      -- traceShowM ("gqueryCtor", cn, t)
+      mod <- symbolString <$> gets modName
+      ts  <- unfold (symbol $ qualify mod cn) t
+      xs  <- gqueryFields (reproxyGElem p) d ts
+      apply (symbol $ qualify mod cn) t xs
+  where
+    cn = conName (undefined :: C1 c f a)
+
+--------------------------------------------------------------------------------
+--- Products
+--------------------------------------------------------------------------------
+class GToExprFields f where
+  gtoExprFields :: f a -> [Expr]
+
+class GRecursive f where
+  gconArgTys  :: Proxy (f a) -> [Sort]
+
+class GQueryFields f where
+  gqueryFields  :: (?loc :: CallStack) => Proxy (f a) -> Int -> [(Symbol,SpecType)] -> Target [Expr]
+
+class GDecodeFields f where
+  gdecodeFields :: [Symbol] -> Target ([Symbol], f a)
+
+class GCheckFields f where
+  gcheckFields :: f a -> [(Symbol, SpecType)]
+               -> Target (Bool, [Expr], [(Symbol, SpecType)])
+
+
+instance (GToExprFields f, GToExprFields g) => GToExprFields (f :*: g) where
+  gtoExprFields (f :*: g) = gtoExprFields f ++ gtoExprFields g
+
+instance (GRecursive f, GRecursive g) => GRecursive (f :*: g) where
+  gconArgTys p = gconArgTys (reproxyLeft p) ++ gconArgTys (reproxyRight p)
+
+instance (GQueryFields f, GQueryFields g) => GQueryFields (f :*: g) where
+  gqueryFields p d ts = do
+    xs <- gqueryFields (reproxyLeft p) d ts
+    let su = mkSubst $ zipWith (\x t -> (fst t, x)) xs ts
+    let ts' = drop (length xs) ts
+    ys <- gqueryFields (reproxyRight p) d (map (second (subst su)) ts')
+    return $ xs ++ ys
+
+instance (GDecodeFields f, GDecodeFields g) => GDecodeFields (f :*: g) where
+  gdecodeFields vs = do
+    (vs', ls)  <- gdecodeFields vs
+    (vs'', rs) <- gdecodeFields vs'
+    return (vs'', ls :*: rs)
+
+instance (GCheckFields f, GCheckFields g) => GCheckFields (f :*: g) where
+  gcheckFields (f :*: g) ts = do
+    (bl,fs,ts')  <- gcheckFields f ts
+    (br,gs,ts'') <- gcheckFields g ts'
+    return (bl && br, fs ++ gs, ts'')
+
+
+instance (GToExpr f) => GToExprFields (S1 c f) where
+  gtoExprFields (M1 x)     = [gtoExpr x]
+
+instance Targetable a => GRecursive (S1 c (K1 i a)) where
+  gconArgTys _ = [getType (Proxy :: Proxy a)]
+
+instance (GQuery f) => GQueryFields (S1 c f) where
+  gqueryFields p d (t:_) = sequence [var <$> gquery (reproxyGElem p) (d-1) "" (snd t)]
+  gqueryFields _ _ _     = error "gqueryfields _ _ []"
+
+instance GDecodeFields f => GDecodeFields (S1 c f) where
+  gdecodeFields vs = do
+    (vs', x) <- gdecodeFields vs
+    return (vs', M1 x)
+
+instance (GCheckFields f) => GCheckFields (S1 c f) where
+  gcheckFields (M1 x) ts = gcheckFields x ts
+
+instance GToExprFields U1 where
+  gtoExprFields _ = []
+
+instance GRecursive U1 where
+  gconArgTys _    = []
+
+instance GQueryFields U1 where
+  gqueryFields _ _ _ = return []
+
+instance GDecodeFields U1 where
+  gdecodeFields vs = return (vs, U1)
+
+instance GCheckFields U1 where
+  gcheckFields _ ts = return (True, [], ts)
diff --git a/src/Test/Target/Targetable/Function.hs b/src/Test/Target/Targetable/Function.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Targetable/Function.hs
@@ -0,0 +1,184 @@
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE ScopedTypeVariables  #-}
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE ViewPatterns         #-}
+
+module Test.Target.Targetable.Function () where
+
+import           Control.Arrow                   (second)
+import           Control.Monad
+import qualified Control.Monad.Catch             as Ex
+import           Control.Monad.Reader
+import           Control.Monad.State
+import           Data.Char
+import qualified Data.HashMap.Strict             as M
+import           Data.IORef
+import           Data.Proxy
+import qualified Data.Text                       as ST
+import qualified Data.Text.Lazy.Builder          as Builder
+import           System.IO.Unsafe
+
+import qualified GHC
+import           Language.Fixpoint.Smt.Interface hiding (SMTLIB2(..))
+import           Language.Fixpoint.Types         hiding (ofReft, reft)
+import           Language.Haskell.Liquid.GHC.Misc (qualifiedNameSymbol)
+import           Language.Haskell.Liquid.Types.RefType (addTyConInfo, rTypeSort)
+import           Language.Haskell.Liquid.Types   hiding (var)
+
+import           Test.Target.Targetable
+import           Test.Target.Eval
+import           Test.Target.Expr
+import           Test.Target.Monad
+import           Test.Target.Serialize
+import           Test.Target.Types
+import           Test.Target.Util
+
+
+getCtors :: SpecType -> [GHC.DataCon]
+getCtors (RApp c _ _ _) = GHC.tyConDataCons $ rtc_tc c
+getCtors (RAppTy t _ _) = getCtors t
+getCtors (RFun _ i o _) = getCtors i ++ getCtors o
+getCtors (RVar _ _)     = []
+getCtors t              = error $ "getCtors: " ++ showpp t
+
+dataConSymbol_noUnique :: GHC.DataCon -> Symbol
+dataConSymbol_noUnique = qualifiedNameSymbol . GHC.getName
+
+genFun :: Targetable a => Proxy a -> t -> Symbol -> SpecType -> Target Symbol
+genFun _p _ x (stripQuals -> t)
+  = do forM_ (getCtors t) $ \dc -> do
+         let c = dataConSymbol_noUnique dc
+         t <- lookupCtor c t
+         addConstructor (c, rTypeSort mempty t)
+       return x -- fresh (getType p)
+
+stitchFun :: forall f. (Targetable (Res f))
+          => Proxy f -> SpecType -> Target ([Expr] -> Res f)
+stitchFun _ (bkArrowDeep . stripQuals -> (vs, tis, _, to))
+  = do mref <- io $ newIORef []
+       d <- asks depth
+       state' <- get
+       opts   <- ask
+       let st = state' { variables = [], choices = [], constraints = []
+                       , deps = mempty, constructors = [] }
+       return $ \es -> unsafePerformIO $ runTarget opts st $ do
+         -- let es = map toExpr xs
+         mv <- lookup es <$> io (readIORef mref)
+         case mv of
+           Just v  -> return v
+           Nothing -> do
+             cts <- gets freesyms
+             let env = map (second (`VC` [])) cts
+             bs <- zipWithM (evalType (M.fromList env)) tis es
+             case and bs of
+               --FIXME: better error message
+               False -> Ex.throwM $ PreconditionCheckFailed $ show $ zip es tis
+               True  -> do
+                 ctx <- gets smtContext
+                 _ <- io $ command ctx Push
+                 xes <- zipWithM genExpr es tis
+                 let su = mkSubst $ zipWith (\v e -> (v, var e)) vs xes
+                 xo <- qquery (Proxy :: Proxy (Res f)) d (subst su to)
+                 vs <- gets variables
+                 mapM_ (\x -> io . smtWrite ctx . Builder.toLazyText $
+                              makeDecl (symbol x) (snd x)) vs
+                 cs <- gets constraints
+                 mapM_ (\c -> io . smtWrite ctx . Builder.toLazyText $
+                              smt2 $ Assert Nothing c) cs
+
+                 resp <- io $ command ctx CheckSat
+                 when (resp == Unsat) $ Ex.throwM SmtFailedToProduceOutput
+
+                 o <- decode xo to
+                 -- whenVerbose $ io $ printf "%s -> %s\n" (show es) (show o)
+                 io (modifyIORef' mref ((es,o):))
+                 _ <- io $ command ctx Pop
+                 return o
+
+genExpr :: Expr -> SpecType -> Target Symbol
+genExpr (splitEApp_maybe -> Just (c, es)) t
+  = do let ts = rt_args t
+       xes <- zipWithM genExpr es ts
+       (xs, _, _, to) <- bkArrowDeep . stripQuals <$> lookupCtor c t
+       let su  = mkSubst $ zip xs $ map var xes
+           to' = subst su to
+       x <- fresh $ FObj $ symbol $ rtc_tc $ rt_tycon to'
+       addConstraint $ ofReft (reft to') (var x)
+       return x
+genExpr (ECon (I i)) _t
+  = do x <- fresh FInt
+       addConstraint $ var x `eq` expr i
+       return x
+genExpr (ESym (SL s)) _t | ST.length s == 1
+  -- This is a Char, so encode it as an Int
+  = do x <- fresh FInt
+       addConstraint $ var x `eq` expr (ord $ ST.head s)
+       return x
+genExpr e _t = error $ "genExpr: " ++ show e
+
+evalType :: M.HashMap Symbol Val -> SpecType -> Expr -> Target Bool
+evalType m t e@(splitEApp_maybe -> Just (c, xs))
+  = do dcp <- lookupCtor c t
+       tyi <- gets tyconInfo
+       vts <- freshen $ applyPreds (addTyConInfo M.empty tyi t) dcp
+       liftM2 (&&) (evalWith m (toReft $ rt_reft t) e) (evalTypes m vts xs)
+evalType m t e
+  = evalWith m (toReft $ rt_reft t) e
+
+freshen :: [(Symbol, SpecType)] -> Target [(Symbol, SpecType)]
+freshen [] = return []
+freshen ((v,t):vts)
+  = do n <- freshInt
+       let v' = symbol . (++show n) . symbolString $ v
+           su = mkSubst [(v,var v')]
+           t' = subst su t
+       vts' <- freshen $ subst su vts
+       return ((v',t'):vts')
+
+evalTypes
+  :: M.HashMap Symbol Val
+     -> [(Symbol, SpecType)] -> [Expr] -> Target Bool
+evalTypes _ []         []     = return True
+evalTypes m ((v,t):ts) (x:xs)
+  = do xx <- evalExpr x m
+       -- FIXME: tidy??
+       let m' = M.insert (tidySymbol v) xx m
+       liftM2 (&&) (evalType m' t x) (evalTypes m' ts xs)
+
+evalTypes _ _ _ = error "evalTypes called with lists of unequal length!"
+
+instance (Targetable a, Targetable b, b ~ Res (a -> b))
+  => Targetable (a -> b) where
+  getType _ = mkFFunc 0 [getType (Proxy :: Proxy a), getType (Proxy :: Proxy b)]
+  query = genFun
+  decode _ t
+    = do f <- stitchFun (Proxy :: Proxy (a -> b)) t
+         return $ \a -> f [toExpr a]
+  toExpr  _ = var ("FUNCTION" :: Symbol)
+  check _ _ = error "can't check a function!"
+
+instance {-# OVERLAPPING #-} ( Targetable a, Targetable b, Targetable c
+                             , c ~ Res (a -> b -> c)
+                             ) => Targetable (a -> b -> c) where
+  getType _ = mkFFunc 0 [getType (Proxy :: Proxy a), getType (Proxy :: Proxy b)
+                        ,getType (Proxy :: Proxy c)]
+  query = genFun
+  decode _ t
+    = do f <- stitchFun (Proxy :: Proxy (a -> b -> c)) t
+         return $ \a b -> f [toExpr a, toExpr b]
+  toExpr  _ = var ("FUNCTION" :: Symbol)
+  check _ _ = error "can't check a function!"
+
+instance {-# OVERLAPPING #-} ( Targetable a, Targetable b, Targetable c, Targetable d
+                             , d ~ Res (a -> b -> c -> d)
+                             ) => Targetable (a -> b -> c -> d) where
+  getType _ = mkFFunc 0 [getType (Proxy :: Proxy a), getType (Proxy :: Proxy b)
+                        ,getType (Proxy :: Proxy c), getType (Proxy :: Proxy d)]
+  query = genFun
+  decode _ t
+    = do f <- stitchFun (Proxy :: Proxy (a -> b -> c -> d)) t
+         return $ \a b c -> f [toExpr a, toExpr b, toExpr c]
+  toExpr  _ = var ("FUNCTION" :: Symbol)
+  check _ _ = error "can't check a function!"
diff --git a/src/Test/Target/Testable.hs b/src/Test/Target/Testable.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Testable.hs
@@ -0,0 +1,225 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE BangPatterns         #-}
+{-# LANGUAGE ConstraintKinds      #-}
+{-# LANGUAGE DoAndIfThenElse      #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE LambdaCase           #-}
+{-# LANGUAGE ScopedTypeVariables  #-}
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE ViewPatterns         #-}
+module Test.Target.Testable (test, Testable, setup) where
+
+
+import Prelude hiding (error, undefined)
+
+import           Control.Exception               (AsyncException, evaluate)
+import           Control.Monad
+import           Control.Monad.Catch
+import           Control.Monad.Reader
+import           Control.Monad.State
+import qualified Data.HashMap.Strict             as M
+import qualified Data.HashSet                    as S
+import qualified Data.List                       as L
+import           Data.Proxy
+import qualified Data.Text                       as ST
+import qualified Data.Text.Lazy.Builder          as Builder
+import           Data.Text.Format                hiding (print)
+import           Text.Printf
+
+import           Language.Fixpoint.Smt.Interface hiding (SMTLIB2(..))
+-- import           Language.Fixpoint.Smt.Serialize
+import           Language.Fixpoint.Smt.Theories  (theorySymbols)
+import           Language.Fixpoint.Types         hiding (Result)
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types   hiding (env, var, Only)
+
+import           Test.Target.Targetable          hiding (apply)
+-- import           Test.Target.Eval
+import           Test.Target.Expr
+import           Test.Target.Monad
+import           Test.Target.Serialize
+import           Test.Target.Types
+import           Test.Target.Util
+
+import GHC.Err.Located
+
+-- import Debug.Trace
+
+-- | Test that a function inhabits the given refinement type by enumerating
+-- valid inputs and calling the function on the inputs.
+test :: Testable f => f -> SpecType -> Target Result
+test f t
+  = do d <- asks depth
+       vs <- queryArgs f d t
+       setup
+       let (xs, tis, _, to) = bkArrowDeep $ stripQuals t
+       ctx <- gets smtContext
+       try (process f ctx vs (zip xs tis) to) >>= \case
+         Left  (e :: TargetException) -> return $ Errored $ show e
+         Right r                      -> return r
+
+process :: Testable f
+        => f -> Context -> [Symbol] -> [(Symbol,SpecType)] -> SpecType
+        -> Target Result
+process f ctx vs xts to = go 0 =<< io (command ctx CheckSat)
+  where
+    go !n Unsat    = return $ Passed n
+    go _  (Error e)= throwM $ SmtError $ ST.unpack e
+    go !n Sat      = do
+      when (n `mod` 100 == 0) $ whenVerbose $ io $ printf "Checked %d inputs\n" n
+      let n' = n + 1
+      xs <- decodeArgs f vs (map snd xts)
+      whenVerbose $ io $ print xs
+      er <- io $ try $ evaluate (apply f xs)
+      -- whenVerbose $ io $ print er
+      case er of
+        Left (e :: SomeException)
+          -- DON'T catch AsyncExceptions since they are used by @timeout@
+          | Just (_ :: AsyncException) <- fromException e -> throwM e
+          | Just (SmtError _) <- fromException e -> throwM e
+          | Just (ExpectedValues _) <- fromException e -> throwM e
+          | otherwise -> do
+              real <- gets realized
+              modify $ \s@(TargetState {..}) -> s { realized = [] }
+              let model = [ build "(= {} {})" (symbolText x, v) | (x,v) <- real ]
+              unless (null model) $
+                void $ io $ smtWrite ctx $ Builder.toLazyText
+                          $ build "(assert (not (and {})))"
+                     $ Only $ smt2many model
+              mbKeepGoing xs n'
+        Right r -> do
+          real <- gets realized
+          modify $ \s@(TargetState {..}) -> s { realized = [] }
+          let su = mkSubst $ mkExprs f (map fst xts) xs
+          (sat, _) <- check r (subst su to)
+
+          -- refute model *after* checking output in case we have HOFs, which
+          -- need to query the solver. if this is the last set of inputs, e.g.
+          -- refuting the current model forces the solver to return unsat next
+          -- time, the solver will return unsat when the HOF queries for an output,
+          -- causing us to return a spurious error
+          let model = [ build "(= {} {})" (symbolText x, v) | (x,v) <- real ]
+          unless (null model) $
+            void $ io $ smtWrite ctx $ Builder.toLazyText
+                 $ build "(assert (not (and {})))"
+                 $ Only $ smt2many model
+
+          case sat of
+            False -> mbKeepGoing xs n'
+            True -> do
+              asks maxSuccess >>= \case
+                Nothing -> go n' =<< io (command ctx CheckSat)
+                Just m | m == n' -> return $ Passed m
+                       | otherwise -> go n' =<< io (command ctx CheckSat)
+
+    go _ r = error $ "go _ " ++ show r
+
+    mbKeepGoing xs n = do
+      kg <- asks keepGoing
+      if kg
+        then go n =<< io (command ctx CheckSat)
+        else return (Failed $ show xs)
+
+-- | A class of functions that Target can test. A function is @Testable@ /iff/
+-- all of its component types are 'Targetable' and all of its argument types are
+-- 'Show'able.
+--
+-- You should __never__ have to define a new 'Testable' instance.
+class (AllHave Targetable (Args f), Targetable (Res f)
+      ,AllHave Show (Args f)) => Testable f where
+  queryArgs  :: f -> Int -> SpecType -> Target [Symbol]
+  decodeArgs :: f -> [Symbol] -> [SpecType] -> Target (HList (Args f))
+  apply      :: f -> HList (Args f) -> Res f
+  mkExprs    :: f -> [Symbol] -> HList (Args f) -> [(Symbol,Expr)]
+
+instance {-# OVERLAPPING #-} (Show a, Targetable a, Testable b) => Testable (a -> b) where
+  queryArgs f d (stripQuals -> (RFun x i o _))
+    = do v  <- qquery (Proxy :: Proxy a) d i
+         vs <- queryArgs (f undefined) d (subst (mkSubst [(x,var v)]) o)
+         return (v:vs)
+  queryArgs _ _ t = error $ "queryArgs called with non-function type: " ++ show t
+  decodeArgs f (v:vs) (t:ts)
+    = liftM2 (:::) (decode v t) (decodeArgs (f undefined) vs ts)
+  decodeArgs _ _ _ = error "decodeArgs called with empty list"
+  apply f (x ::: xs)
+    = apply (f x) xs
+  apply _ _ = error "apply called with empty list"
+  mkExprs f (v:vs) (x ::: xs)
+    = (v, toExpr x) : mkExprs (f undefined) vs xs
+  mkExprs _ _ _ = error "mkExprs called with empty list"
+
+instance {-# OVERLAPPING #-}
+  (Targetable a, Args a ~ '[], Res a ~ a) => Testable a
+  where
+  queryArgs _ _ _  = return []
+  decodeArgs _ _ _ = return Nil
+  apply f _        = f
+  mkExprs _ _ _    = []
+
+
+func :: Sort -> Bool
+func (FAbs  _ s) = func s
+func (FFunc _ _) = True
+func _           = False
+
+setup :: Target ()
+setup = {-# SCC "setup" #-} do
+   ctx <- gets smtContext
+   emb <- gets embEnv
+
+   -- declare sorts
+   ss  <- S.toList <$> gets sorts
+   let defSort b e = io $ smtWrite ctx $ Builder.toLazyText
+                   $ build "(define-sort {} () {})" (b,e)
+   defSort ("CHOICE" :: Builder.Builder) ("Bool" :: Builder.Builder)
+          -- FIXME: shouldn't need the nub, wtf?
+   forM_ (L.nub (map smt2 ss)) $ \s ->
+     defSort s ("Int" :: Builder.Builder)
+
+   -- declare constructors
+   cts <- gets constructors
+   mapM_ (\ (c,t) -> do
+             io $ smtWrite ctx . Builder.toLazyText $ makeDecl (symbol c) t) cts
+   let nullary = [var c | (c,t) <- cts, not (func t)]
+   unless (null nullary) $
+     void $ io $ smtWrite ctx . Builder.toLazyText $ smt2 $ Distinct nullary
+   -- declare variables
+   vs <- gets variables
+   let defVar (x,t) = io $ smtWrite ctx $ Builder.toLazyText (makeDecl x (arrowize t))
+   mapM_ defVar vs
+   -- declare measures
+   ms <- gets measEnv
+   let defFun x t = io $ smtWrite ctx $ Builder.toLazyText (makeDecl x t)
+   forM_ ms $ \m -> do
+     let x = val (name m)
+     unless (x `M.member` theorySymbols) $
+       defFun x (rTypeSort emb (sort m))
+   -- assert constraints
+   cs <- gets constraints
+   --mapM_ (\c -> do {i <- gets seed; modify $ \s@(GS {..}) -> s { seed = seed + 1 };
+   --                 io . command ctx $ Assert (Just i) c})
+   --  cs
+   mapM_ (io . smtWrite ctx . Builder.toLazyText . smt2 . Assert Nothing) cs
+   -- deps <- V.fromList . map (symbol *** symbol) <$> gets deps
+   -- io $ generateDepGraph "deps" deps cs
+   -- return (ctx,vs,deps)
+
+-- sortTys :: Sort -> [Sort]
+-- sortTys (FFunc _ ts) = concatMap sortTys ts
+-- sortTys t            = [t]
+
+arrowize :: Sort -> Sort
+arrowize t
+  | Just (_, ts, t) <- functionSort t
+  = FObj . symbol . ST.intercalate "->" . map (symbolText . unObj) $ (ts ++ [t])
+  | otherwise
+  = t
+
+unObj :: Sort -> Symbol
+unObj FInt     = "Int"
+unObj (FObj s) = s
+unObj s        = error $ "unObj: " ++ show s
diff --git a/src/Test/Target/Types.hs b/src/Test/Target/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Types.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DeriveDataTypeable   #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+module Test.Target.Types where
+
+import qualified Control.Monad.Catch             as Ex
+import qualified Data.Set                        as S
+import qualified Data.Text                       as T
+import           Data.Typeable
+import           GHC.Generics
+import           Text.PrettyPrint
+
+import           Language.Fixpoint.Smt.Interface hiding (SMTLIB2(..))
+import           Language.Fixpoint.Types
+import           Language.Haskell.Liquid.Types
+
+import           GHC
+
+import           Test.Target.Serialize
+
+
+
+data TargetException
+  = SmtFailedToProduceOutput
+  | SmtError String
+  | ExpectedValues Response
+  | PreconditionCheckFailed String
+  | EvalError String
+  deriving Typeable
+
+instance Show TargetException where
+  show SmtFailedToProduceOutput
+    = "The SMT solver was unable to produce an output value."
+  show (SmtError s)
+    = "Unexpected error from the solver: " ++ s
+  show (ExpectedValues r)
+    = "Expected a Values response from the solver, got: " ++ show r
+  show (PreconditionCheckFailed e)
+    = "The pre-condition check for a generated function failed: " ++ e
+  show (EvalError s)
+    = "Couldn't evaluate a concrete refinement: " ++ s
+
+instance Ex.Exception TargetException
+
+ensureValues :: Ex.MonadThrow m => m Response -> m Response
+ensureValues x = do
+  a <- x
+  case a of
+    Values _ -> return a
+    r        -> Ex.throwM $ ExpectedValues r
+
+type Constraint = [Expr]
+type Variable   = ( Symbol -- the name
+                  , Sort   -- the `Sort'
+                  )
+type Value      = T.Text
+
+instance Symbolic Variable where
+  symbol (x, _) = symbol x
+
+instance SMTLIB2 Constraint where
+  smt2 = smt2 . PAnd
+
+type DataConEnv = [(Symbol, SpecType)]
+type MeasureEnv = [Measure SpecType DataCon]
+
+boolsort, choicesort :: Sort
+boolsort   = FObj "Bool"
+choicesort = FObj "CHOICE"
+
+data Result = Passed !Int
+            | Failed !String
+            | Errored !String
+            deriving (Show, Typeable)
+
+-- resultPassed (Passed i) = i
+
+data Val
+  = VB !Bool
+  | VV !Constant
+  | VX !SymConst
+  | VS !(S.Set Val) -- ??
+  | VC Symbol [Val]
+  deriving (Generic, Show, Eq, Ord)
+
+instance PPrint Val where
+  pprintTidy t (VB b) = pprintTidy t b
+  pprintTidy t (VV v) = pprintTidy t v
+  pprintTidy t (VX x) = pprintTidy t x
+  pprintTidy t (VS s) = "Set.fromList" <+> pprintTidy t (S.toList s)
+  pprintTidy t (VC c vs) = parens $ pprintTidy t c <+> hsep (map (pprintTidy t) vs)
diff --git a/src/Test/Target/Util.hs b/src/Test/Target/Util.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Target/Util.hs
@@ -0,0 +1,182 @@
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE ParallelListComp #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ViewPatterns #-}
+module Test.Target.Util where
+
+
+import           Control.Monad.IO.Class
+import           Data.List
+import           Data.Maybe
+
+import           Data.Generics                   (everywhere, mkT)
+import           Data.Text.Format                hiding (print)
+import           Data.Text.Lazy.Builder          (Builder)
+import           Debug.Trace
+
+import qualified DynFlags as GHC
+import qualified GhcMonad as GHC
+import qualified GHC
+import qualified GHC.Exts as GHC
+import qualified GHC.Paths
+import qualified HscTypes as GHC
+
+-- import           Language.Fixpoint.Smt.Interface
+-- import           Language.Fixpoint.Smt.Serialize
+
+
+import           Language.Fixpoint.Types          hiding (prop)
+import           Language.Haskell.Liquid.UX.CmdLine
+import           Language.Haskell.Liquid.GHC.Interface
+import           Language.Haskell.Liquid.Types.PredType
+import           Language.Haskell.Liquid.Types.RefType
+import           Language.Haskell.Liquid.Types    hiding (var)
+
+import           Test.Target.Serialize
+
+
+type Depth = Int
+
+io ::  MonadIO m => IO a -> m a
+io = liftIO
+
+myTrace :: Show a => String -> a -> a
+myTrace s x = trace (s ++ ": " ++ show x) x
+
+reft :: SpecType -> Reft
+reft = toReft . rt_reft
+
+data HList (a :: [*]) where
+  Nil   :: HList '[]
+  (:::) :: a -> HList bs -> HList (a ': bs)
+
+instance AllHave Show as => Show (HList as) where
+  show Nil         = "()"
+  show (x ::: Nil) = show x
+  show (x ::: xs)  = show x ++ ", " ++ show xs
+
+type family Map (f :: a -> b) (xs :: [a]) :: [b] where
+  Map f '[]       = '[]
+  Map f (x ': xs) = f x ': Map f xs
+
+type family Constraints (cs :: [GHC.Constraint]) :: GHC.Constraint
+type instance Constraints '[]       = ()
+type instance Constraints (c ': cs) = (c, Constraints cs)
+
+type AllHave (c :: k -> GHC.Constraint) (xs :: [k]) = Constraints (Map c xs)
+
+type family Args a where
+  Args (a -> b) = a ': Args b
+  Args a        = '[]
+
+type family Res a where
+  Res (a -> b) = Res b
+  Res a        = a
+
+-- liquid-fixpoint started encoding `FObj s` as `Int` in 0.3.0.0, but we
+-- want to preserve the type aliases for easier debugging.. so here's a
+-- copy of the SMTLIB2 Sort instance..
+-- smt2Sort :: Sort -> T.Text
+-- smt2Sort s = case s of
+--   FObj s' -> smt2 s'
+--   _       -> smt2 s
+-- smt2Sort s           | Just t <- Thy.smt2Sort s = t
+-- smt2Sort FInt        = "Int"
+-- smt2Sort (FApp t []) | t == intFTyCon = "Int"
+-- smt2Sort (FApp t []) | t == boolFTyCon = "Bool"
+-- --smt2Sort (FApp t [FApp ts _,_]) | t == appFTyCon  && fTyconSymbol ts == "Set_Set" = "Set"
+-- smt2Sort (FObj s)    = smt2 s
+-- smt2Sort s@(FFunc _ _) = error $ "smt2 FFunc: " ++ show s
+-- smt2Sort _           = "Int"
+
+makeDecl :: Symbol -> Sort -> Builder
+-- FIXME: hack..
+makeDecl x t
+  | Just (_, ts, t) <- functionSort t
+  = build "(declare-fun {} ({}) {})"
+          (smt2 x, smt2s ts, smt2 t)
+makeDecl x t
+  = build "(declare-const {} {})" (smt2 x, smt2 t)
+
+safeFromJust :: String -> Maybe a -> a
+safeFromJust msg Nothing  = error $ "safeFromJust: " ++ msg
+safeFromJust _   (Just x) = x
+
+applyPreds :: SpecType -> SpecType -> [(Symbol,SpecType)]
+applyPreds sp' dc = -- trace ("sp : " ++ showpp sp') $ trace ("dc : " ++ showpp dc)
+                    zip xs (map tx ts)
+  where
+    sp = removePreds <$> sp'
+    removePreds (MkUReft r _ _) = MkUReft r mempty mempty
+    (as, ps, _, t) = bkUniv dc
+    (xs, ts, _, _) = bkArrow . snd $ bkClass t
+    -- args  = reverse tyArgs
+    su    = [(ty_var_value tv, toRSort t, t) | tv <- as | t <- rt_args sp]
+    sup   = [(p, r) | p <- ps | r <- rt_pargs sp]
+    tx    = (\t -> replacePreds "applyPreds" t sup)
+          . everywhere (mkT $ propPsToProp sup)
+          . subsTyVars_meet su
+
+propPsToProp :: [(RPVar, SpecProp)] -> SpecProp -> SpecProp
+propPsToProp su r = foldr propPToProp r su
+
+propPToProp :: (RPVar, SpecProp) -> SpecProp -> SpecProp
+propPToProp (p, r) (RProp _ (RHole (MkUReft _ (Pr [up]) _)))
+  | pname p == pname up
+  = r
+propPToProp _ m = m
+
+splitEApp_maybe :: Expr -> Maybe (Symbol, [Expr])
+splitEApp_maybe e@(EApp {}) = go [] e
+  where
+    go acc (EApp f e) = go (e:acc) f
+    go acc (EVar s)   = Just (s, acc)
+    go _   _          = Nothing -- error $ "splitEApp_maybe: " ++ showpp e
+splitEApp_maybe _ = Nothing
+
+stripQuals :: SpecType -> SpecType
+stripQuals = snd . bkClass . fourth4 . bkUniv
+
+fourth4 :: (t, t1, t2, t3) -> t3
+fourth4 (_,_,_,d) = d
+
+getSpec :: [String] -> FilePath -> IO GhcSpec
+getSpec opts target
+  = do cfg  <- getOpts ["--quiet"]
+       spec . head . fst <$> getGhcInfos Nothing (cfg {ghcOptions = opts}) [target]
+       -- case info of
+       --   Left err -> error $ show err
+       --   Right i  -> return $ spec i
+
+runGhc :: [String] -> GHC.Ghc a -> IO a
+runGhc o x = GHC.runGhc (Just GHC.Paths.libdir) $ do
+               df <- GHC.getSessionDynFlags
+               let df' = df { GHC.ghcMode   = GHC.CompManager
+                            , GHC.ghcLink   = GHC.NoLink --GHC.LinkInMemory
+                            , GHC.hscTarget = GHC.HscNothing --GHC.HscInterpreted
+                            -- , GHC.optLevel  = 0 --2
+                            , GHC.log_action = \_ _ _ _ _ -> return ()
+                            } `GHC.gopt_set` GHC.Opt_ImplicitImportQualified
+                              `GHC.xopt_set` GHC.Opt_MagicHash
+               (df'',_,_) <- GHC.parseDynamicFlags df' (map GHC.noLoc o)
+               _ <- GHC.setSessionDynFlags df''
+               x
+
+loadModule :: FilePath -> GHC.Ghc GHC.ModSummary
+loadModule f = do target <- GHC.guessTarget f Nothing
+                  --lcheck <- GHC.guessTarget "src/Test/Target.hs" Nothing
+                  GHC.setTargets [target] -- [target,lcheck]
+                  _ <- GHC.load GHC.LoadAllTargets
+                  modGraph <- GHC.getModuleGraph
+                  let m = fromJust $ find ((==f) . GHC.msHsFilePath) modGraph
+                  GHC.setContext [ GHC.IIModule (GHC.ms_mod_name m)
+                                 --, GHC.IIDecl $ GHC.simpleImportDecl
+                                 --             $ GHC.mkModuleName "Test.Target"
+                                 ]
+                  return m
diff --git a/stack.yaml b/stack.yaml
new file mode 100644
--- /dev/null
+++ b/stack.yaml
@@ -0,0 +1,20 @@
+flags:
+  liquid-fixpoint:
+    devel: true
+  liquidhaskell:
+    devel: true
+
+packages:
+- ./liquid-fixpoint
+- ./liquiddesugar
+- '.'
+
+extra-deps:
+- dotgen-0.4.2
+- fgl-visualize-0.1.0.1
+- intern-0.9.1.4
+- located-base-0.1.1.0
+
+# compiler-check: newer-minor
+resolver: lts-6.30
+pvp-bounds: both
diff --git a/syntax/hsannot.css b/syntax/hsannot.css
new file mode 100644
--- /dev/null
+++ b/syntax/hsannot.css
@@ -0,0 +1,51 @@
+
+.hs-keyglyph, .hs-layout {color: red;}
+.hs-keyword {color: blue;}
+.hs-comment, .hs-comment a {color: green;}
+.hs-str, .hs-chr {color: teal;}
+.hs-keyword,.hs-conid, .hs-varid, .hs-conop, .hs-varop, .hs-num, .hs-cpp, .hs-sel, .hs-definition {}
+
+/*
+a.annot{
+    position:relative; 
+    color:#000;
+    text-decoration:none
+  }
+
+a.annot:hover{z-index:25; background-color:#ff0}
+
+a.annot span{display: none}
+
+a.annot:hover span{ 
+    display:block;
+    position:absolute;
+    top:2em; 
+    left:2em; 
+    border:5px solid #b4eeb4; 
+    background-color: #b4eeb4;
+    color:#000;
+    text-align: left 
+  }
+*/
+
+.annot{
+    position:relative; 
+    color:#000;
+    text-decoration:none
+  }
+
+.annot:hover{z-index:25; background-color:#ff0}
+
+.anntitle {display: none}
+
+.annot:hover span{ /*the span will display just on :hover state*/
+    display:block;
+    position:absolute;
+    top:2em; 
+    left:2em; 
+    border:5px solid #b4eeb4; 
+    background-color: #b4eeb4;
+    color:#000;
+    text-align: left 
+  }
+
diff --git a/syntax/hscolour.css b/syntax/hscolour.css
new file mode 100644
--- /dev/null
+++ b/syntax/hscolour.css
@@ -0,0 +1,46 @@
+.hs-keyglyph, .hs-layout {color: red;}
+.hs-keyword {color: blue;}
+.hs-comment, .hs-comment a {color: green;}
+.hs-str, .hs-chr {color: teal;}
+.hs-keyword,.hs-conid, .hs-varid, .hs-conop, .hs-varop, .hs-num, .hs-cpp, .hs-sel, .hs-definition {}
+
+a.annot{
+    position:relative; 
+    color:#000;
+    text-decoration:none
+  }
+
+a.annot:hover{z-index:25; background-color:#ff0}
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 2px solid #FFAD33;
+  padding: 0.8em 1em;
+}
+
+/* 
+.classic { padding: 0.8em 1em; }
+.custom { padding: 0.5em 0.8em 0.8em 2em; }
+* html a:hover { background: transparent; }
+.classic {background: #FFFFAA; border: 1px solid #FFAD33; }
+.critical { background: #FFCCAA; border: 1px solid #FF3334;	}
+.help { background: #9FDAEE; border: 1px solid #2BB0D7;	}
+.info { background: #9FDAEE; border: 1px solid #2BB0D7;	}
+.warning { background: #FFFFAA; border: 1px solid #FFAD33; }
+*/
diff --git a/syntax/liquidBody.css b/syntax/liquidBody.css
new file mode 100644
--- /dev/null
+++ b/syntax/liquidBody.css
@@ -0,0 +1,145 @@
+html {
+    font-family: "helvetica";
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+/* pygments */
+
+pre {
+	background-color: #f0f0f0;
+	border-top: 1px solid #ccc;
+	border-bottom: 1px solid #ccc;
+	padding: 5px;
+	font-size: 13px;
+	font-family: Bitstream Vera Sans Mono,monospace;
+}
+
+/********************** Links **************************************/
+
+a:hover { 
+  color: black; /* #1d4c77; */
+  /* text-decoration:underline */
+}
+
+
+/********************** General Divs ********************************/
+
+div#navigation {
+    text-align: center;
+    border-bottom: 4px solid black;
+}
+
+div#navigation a {
+    color: white;
+    text-decoration: none;
+    background-color: black;
+    padding: 3px 10px 3px 10px;
+    margin: 0px 10px 0px 10px;
+}
+
+body {
+    width: 700px;
+    /* width: 900px; */
+    margin: 0px auto 0px auto;
+}
+
+div#header {
+    height: 32px;
+    padding: 20px 0px 20px 60px;
+}
+
+div#header img {
+    display: inline;
+    vertical-align: middle;
+}
+
+div#header h1 {
+    padding-left: 10px;
+    display: inline;
+    text-transform: uppercase;
+    vertical-align: middle;
+}
+
+div#main {
+    margin: 0px auto 0px auto;
+    width: 760px;
+}
+
+div#sidebar {
+    margin-right: 30px;
+    width: 160px;
+    float: left;
+    text-align: right;
+}
+
+div#sidebar a {
+    display: block;
+    font-size: 110%;
+    text-decoration: none;
+    margin-bottom: 10px;
+    text-transform: uppercase;
+}
+
+div#content {
+    width: 570px;
+    float: right;
+}
+
+div#footer {
+    padding-top: 30px;
+    clear: both;
+    font-size: 90%;
+    text-align: center;
+}
+
+
+h2 {
+    font-size: 120%;
+    text-transform: uppercase;
+}
+
+h3 {
+    font-size: 100%;
+    text-transform: uppercase;
+}
+
+div.column {
+    width: 50%;
+    float: left;
+}
+
+div.column p {
+    padding-right: 15px;
+}
+
+img {
+    display: block;
+    margin: 10px auto 10px auto;
+    border: none;
+}
+
+ul {
+    list-style-type: square;
+    padding-left: 1em;
+    margin-left: 1em;
+}
+
+
+
+p.caption {
+    display: none;
+}
+
+img {
+  border:0px;
+  margin-left:auto;
+  margin-right:auto;
+  display:block
+}
diff --git a/syntax/liquid_dark_blog.css b/syntax/liquid_dark_blog.css
new file mode 100644
--- /dev/null
+++ b/syntax/liquid_dark_blog.css
@@ -0,0 +1,101 @@
+.hs-linenum {
+  color: #666666; //CCCCCC;
+  font-style: italic;
+}
+
+.hs-error {
+  background-color: #B80000 ;
+}
+
+.hs-keyglyph, .hs-layout { /* color: red; */ 
+  color: white;
+}
+
+.hs-keyword {
+  color: #75D075 ; 
+  //font-weight: bold;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: #7FFFD4;}
+
+.hs-conid { 
+  color: #00FFFF; 
+  //font-weight: bold; 
+}
+
+.hs-definition { 
+  color: #FFFFFF;   /* #ADFF2F; */
+  // font-weight: bold; 
+}
+
+.hs-varid, .hs-varop {
+  color: white; /* #BDDEFF; */
+}
+
+.hs-num, .hs-conop {
+  color: aquamarine;
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none;
+  white-space: pre; 
+}
+
+// a.annot:hover { 
+//   z-index:25; 
+//   background-color:#585858;
+//   /* background-color:#ff0  */
+// }
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  
+  border-radius: 5px 5px;
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  white-space:pre ;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 9999;
+  margin-left: 5; 
+  padding: 0.8em 1em;
+  border: 3px solid #6495ED ; // #5F9EA0; #FFAD33;
+  background: #EBF5FF; // #C3F6FA  #F7F8FD  #C1CDCD #FFFFAA; 
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+pre {
+  border-radius: 5px 5px;
+  // font-family: Bitstream Vera Sans Mono,monospace;
+  font-size: 100%;
+  // color: rgb(255, 255, 255);
+  // background-color: rgb(0, 0, 0);
+  // margin-bottom: 2em;
+  padding: 8px;
+  display: block;
+  overflow: visible; 
+}
+
diff --git a/syntax/liquid_light_blog.css b/syntax/liquid_light_blog.css
new file mode 100644
--- /dev/null
+++ b/syntax/liquid_light_blog.css
@@ -0,0 +1,106 @@
+.hs-linenum {
+  color: #CCCCCC;
+  font-style: italic;
+}
+
+
+.hs-error {
+  background-color: #FF8585 ;
+}
+
+.hs-keyglyph {
+  color: #007020
+}
+
+.hs-keyword {
+  color: #007020;
+  // font-weight: bold;
+}
+
+.hs-comment, .hs-comment a {color: green;}
+
+.hs-str, .hs-chr {color: teal;}
+
+.hs-conid { 
+  color: #902000;   /* color: #00FFFF; color: #0E84B5; */
+  //font-weight: bold;  
+}
+
+.hs-definition { 
+  color: #06287E 
+  /* font-weight: bold; */ 
+}
+
+.hs-varid, .hs-varop, .hs-layout {
+  color: black; 
+}
+
+.hs-num {
+  color: #40A070;
+}
+
+.hs-conop {
+  color: #902000; 
+}
+
+.hs-cpp {
+  color: orange;
+}
+
+.hs-sel  {}
+
+a.annot {
+  position:relative; 
+  color:#000;
+  text-decoration:none; 
+  white-space: pre; 
+}
+
+a.annot:hover { 
+  z-index:25; 
+  background-color: #D8D8D8;
+}
+
+a.annot span.annottext{display: none}
+
+a.annot:hover span.annottext{ 
+  
+  border-radius: 5px 5px;
+  
+  -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+  
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); 
+  -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); 
+
+  white-space:pre;
+  display:block;
+  position: absolute; 
+  left: 1em; top: 2em; 
+  z-index: 99;
+  margin-left: 5; 
+  background: #FFFFAA; 
+  border: 3px solid #FFAD33;
+  padding: 0.8em 1em;
+}
+
+code {
+   /* font-weight: bold; */
+   background-color: rgb(250, 250, 250); 
+   border: 1px solid rgb(200, 200, 200);
+   padding-left: 4px;
+   padding-right: 4px;
+}
+
+pre {
+  background-color: #f0f0f0;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc;
+  padding: 5px;
+  font-size: 120%;
+  // font-family: Bitstream Vera Sans Mono,monospace;
+  display: block;
+  overflow: visible;
+}
+
diff --git a/tests/Parser.hs b/tests/Parser.hs
new file mode 100644
--- /dev/null
+++ b/tests/Parser.hs
@@ -0,0 +1,500 @@
+{-# LANGUAGE DeriveDataTypeable  #-}
+{-# LANGUAGE DoAndIfThenElse     #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | Simple test suite to test the parser.
+--
+-- Run as:
+--
+-- $ stack test :liquidhaskell-parser
+
+module Main where
+
+import           Data.Data
+import           Data.Generics.Aliases
+import           Data.Generics.Schemes
+import           Language.Fixpoint.Types.Spans
+import qualified Language.Haskell.Liquid.Parse as LH
+-- import qualified Language.Haskell.Liquid.Types as LH
+import           Text.Parsec.Pos
+import           Test.Tasty
+import           Test.Tasty.HUnit
+import           Test.Tasty.Runners.AntXML
+
+-- ---------------------------------------------------------------------
+
+-- | Test suite entry point, returns exit failure if any test fails.
+main :: IO ()
+main =  defaultMainWithIngredients (
+                antXMLRunner:defaultIngredients
+              ) tests
+
+tests :: TestTree
+tests =
+  testGroup "Tests"
+    [
+      testSucceeds
+    , testSpecP
+    , testReservedAliases
+    , testFails
+    , testErrorReporting
+    ]
+
+-- ---------------------------------------------------------------------
+
+-- Test that the top level production works, each of the sub-elements will be tested separately
+testSpecP :: TestTree
+testSpecP =
+  testGroup "specP"
+    [ testCase "assume" $
+       parseSingleSpec "assume foo :: a -> a " @?=
+          "Assm (\"foo\" (dummyLoc),lq_tmp$db##0:a -> a (dummyLoc))"
+
+    , testCase "assert" $
+       parseSingleSpec "assert myabs :: Int -> PosInt" @?=
+          "Asrt (\"myabs\" (dummyLoc),lq_tmp$db##0:Int -> PosInt (dummyLoc))"
+
+    , testCase "autosize" $
+       parseSingleSpec "autosize List" @?=
+          "ASize \"List\" (dummyLoc)"
+
+    , testCase "local" $
+       parseSingleSpec "local foo :: Nat -> Nat" @?=
+          "LAsrt (\"foo\" (dummyLoc),lq_tmp$db##0:Nat -> Nat (dummyLoc))"
+
+    , testCase "axiomatize" $
+       parseSingleSpec "axiomatize fibA" @?=
+          "Reflect \"fibA\" (dummyLoc)"
+
+    , testCase "reflect" $
+       parseSingleSpec "reflect map" @?=
+          "Reflect \"map\" (dummyLoc)"
+
+    , testCase "measure HMeas" $
+       parseSingleSpec "measure isAbs" @?=
+          "HMeas \"isAbs\" (dummyLoc)"
+
+    , testCase "measure Meas" $
+       parseSingleSpec "measure fv :: Expr -> (Set Bndr)" @?=
+          "Meas fv :: lq_tmp$db##0:Expr -> (Set Bndr)"
+
+    , testCase "define" $
+       parseSingleSpec "define $ceq = eqN" @?=
+          "Define (\"$ceq\" (dummyLoc),\"eqN\")"
+
+    , testCase "infixl" $
+       parseSingleSpec "infixl 9 +++" @?=
+          "BFix ()"
+
+    , testCase "infixr" $
+       parseSingleSpec "infixr 9 +++" @?=
+          "BFix ()"
+
+    , testCase "infix" $
+       parseSingleSpec "infix 9 +++" @?=
+          "BFix ()"
+
+    , testCase "inline" $
+       parseSingleSpec "inline eqelems" @?=
+          "Inline \"eqelems\" (dummyLoc)"
+
+    , testCase "bound PBound" $
+       parseSingleSpec "bound Foo = true" @?=
+          "PBound bound Foo forall [] . [] =  true"
+
+    , testCase "bound HBound" $
+       parseSingleSpec "bound step" @?=
+          "HBound \"step\" (dummyLoc)"
+
+    , testCase "class measure" $
+       parseSingleSpec "class measure sz :: forall a. a -> Int" @?=
+          "CMeas sz :: lq_tmp$db##0:a -> Int"
+
+    , testCase "instance measure" $
+       parseSingleSpec "instance measure sz :: MList a -> Int" @?=
+          "IMeas sz :: lq_tmp$db##0:(MList a) -> Int"
+
+    , testCase "instance" $
+       parseSingleSpec "instance VerifiedNum Int where\n  - :: x:Int -> y:Int -> OkInt {x - y} " @?=
+          "RInst (RI {riclass = VerifiedNum, ritype = [Int (dummyLoc)], risigs = [(\"-\" (dummyLoc),RISig x:Int -> y:Int -> (OkInt {x - y}) (dummyLoc))]})"
+
+    , testCase "class" $
+       parseSingleSpec "class Sized s where\n  size :: forall a. x:s a -> {v:Nat | v = sz x}" @?=
+          "Class (RClass {rcName = Sized, rcSupers = [], rcTyVars = [BTV \"s\"], rcMethods = [(\"size\" (dummyLoc),x:s a -> {v##0 : Nat | v##0 == sz x} (dummyLoc))]})"
+
+    , testCase "import" $
+       parseSingleSpec "import Foo" @?=
+          "Impt \"Foo\""
+
+    , testCase "data variance" $
+       parseSingleSpec "data variance IO bivariant" @?=
+          "Varia (\"IO\" (dummyLoc),[Bivariant])"
+
+    , testCase "data" $
+       parseSingleSpec "data Bob = B {foo :: Int}" @?=
+          "DDecl DataDecl: data = \"Bob\" (dummyLoc), tyvars = []"
+
+    , testCase "newtype" $
+       parseSingleSpec "newtype Foo = Bar {x :: Nat}" @?=
+          "NTDecl DataDecl: data = \"Foo\" (dummyLoc), tyvars = []"
+
+    , testCase "include" $
+       parseSingleSpec "include <listSet.hquals>" @?=
+          "Incl \"listSet.hquals\""
+
+    , testCase "invariant" $
+       parseSingleSpec "invariant {v:Tree a | 0 <= ht v}" @?=
+          "Invt {v##0 : (Tree a) | 0 <= ht v##0} (dummyLoc)"
+
+    , testCase "using" $
+       parseSingleSpec "using (Tree a) as  {v:Tree a   | 0 <= height v}" @?=
+          -- "IAlias ((Tree a) (dummyLoc),{v##0 : (Tree a) | 0 <= height v##0} (dummyLoc))"
+             "IAlias ((Tree a) (dummyLoc),{v##2 : (Tree a) | 0 <= height v##2} (dummyLoc))"
+
+    , testCase "type" $
+       parseSingleSpec "type PosInt = {v: Int | v >= 0}" @?=
+          "Alias type PosInt   = {v##0 : Int | v##0 >= 0} -- defined at \"Fixpoint.Types.dummyLoc\" (line 0, column 0)"
+
+    , testCase "predicate" $
+       parseSingleSpec "predicate Pos X  = X > 0" @?=
+          "EAlias type Pos  \"X\" = PAtom Gt (EVar \"X\") (ECon (I 0)) -- defined at \"Fixpoint.Types.dummyLoc\" (line 0, column 0)"
+
+    , testCase "expression" $
+       parseSingleSpec "expression Avg Xs = ((sumD Xs) / (lenD Xs))" @?=
+          "EAlias type Avg  \"Xs\" = EBin Div (EApp (EVar \"sumD\") (EVar \"Xs\")) (EApp (EVar \"lenD\") (EVar \"Xs\")) -- defined at \"Fixpoint.Types.dummyLoc\" (line 0, column 0)"
+
+    , testCase "embed" $
+       parseSingleSpec "embed Set as Set_Set" @?=
+          "Embed (\"Set\" (dummyLoc),TC \"Set_Set\" (dummyLoc) (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False}))"
+
+    , testCase "qualif" $
+       parseSingleSpec "qualif Foo(v:Int): v < 0" @?=
+          "Qualif (Q {qName = \"Foo\", qParams = [(\"v\",FInt)], qBody = PAtom Lt (EVar \"v\") (ECon (I 0)), qPos = \"Fixpoint.Types.dummyLoc\" (line 0, column 0)})"
+
+    , testCase "decrease" $
+       parseSingleSpec "decrease insert 3" @?=
+          "Decr (\"insert\" (dummyLoc),[2])"
+
+    , testCase "lazyvar" $
+       parseSingleSpec "lazyvar z" @?=
+          "LVars \"z\" (dummyLoc)"
+
+    , testCase "lazy" $
+       parseSingleSpec "lazy eval" @?=
+          "Lazy \"eval\" (dummyLoc)"
+
+    , testCase "automatic-instances" $
+       parseSingleSpec "automatic-instances foo with 5" @?=
+          "Insts (\"foo\" (dummyLoc),Just 5)"
+
+    , testCase "LIQUID" $
+       parseSingleSpec "LIQUID \"--automatic-instances=liquidinstances\" " @?=
+          "Pragma \"--automatic-instances=liquidinstances\" (dummyLoc)"
+
+    , testCase "default parser (Asrts)" $
+       parseSingleSpec " assumeIndices :: t:ByteStringNE -> s:BS.ByteString -> [OkPos t s]" @?=
+          "Asrts ([\"assumeIndices\" (dummyLoc)],(t:ByteStringNE -> s:ByteString -> [(OkPos t s)] (dummyLoc),Nothing))"
+    ]
+
+-- ---------------------------------------------------------------------
+
+-- Test that haskell functions having the same name as liquidhaskell keywords are parsed correctly
+testReservedAliases :: TestTree
+testReservedAliases =
+  testGroup "reserved aliases"
+    [ testCase "assume" $
+       parseSingleSpec "assume :: Int -> Bool " @?=
+          "Asrts ([\"assume\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "assert" $
+       parseSingleSpec "assert :: Int -> Bool " @?=
+          "Asrts ([\"assert\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "autosize" $
+       parseSingleSpec "autosize :: Int -> Bool " @?=
+          "Asrts ([\"autosize\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "axiomatize" $
+       parseSingleSpec "axiomatize :: Int -> Bool " @?=
+          "Asrts ([\"axiomatize\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "reflect" $
+       parseSingleSpec "reflect :: Int -> Bool " @?=
+          "Asrts ([\"reflect\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "measure" $
+       parseSingleSpec "measure :: Int -> Bool " @?=
+          "Asrts ([\"measure\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "define" $
+       parseSingleSpec "define :: Int -> Bool " @?=
+          "Asrts ([\"define\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "defined" $
+       parseSingleSpec "defined :: Int -> Bool " @?=
+          "Asrts ([\"defined\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "inline" $
+       parseSingleSpec "inline :: Int -> Bool " @?=
+          "Asrts ([\"inline\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "bound" $
+       parseSingleSpec "bound :: Int -> Bool " @?=
+          "Asrts ([\"bound\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "invariant" $
+       parseSingleSpec "invariant :: Int -> Bool " @?=
+          "Asrts ([\"invariant\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "predicate" $
+       parseSingleSpec "predicate :: Int -> Bool " @?=
+          "Asrts ([\"predicate\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "expression" $
+       parseSingleSpec "expression :: Int -> Bool " @?=
+          "Asrts ([\"expression\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "embed" $
+       parseSingleSpec "embed :: Int -> Bool " @?=
+          "Asrts ([\"embed\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+
+    , testCase "qualif" $
+       parseSingleSpec "qualif :: Int -> Bool " @?=
+          "Asrts ([\"qualif\" (dummyLoc)],(lq_tmp$db##0:Int -> Bool (dummyLoc),Nothing))"
+    ]
+
+-- ---------------------------------------------------------------------
+
+testSucceeds :: TestTree
+testSucceeds =
+  testGroup "Should succeed"
+    [ testCase "x :: Int" $
+       (parseSingleSpec "x :: Int") @?=
+          "Asrts ([\"x\" (dummyLoc)],(Int (dummyLoc),Nothing))"
+
+    , testCase "x :: a" $
+       (parseSingleSpec "x :: a") @?=
+          "Asrts ([\"x\" (dummyLoc)],(a (dummyLoc),Nothing))"
+
+    , testCase "x :: a -> a" $
+       (parseSingleSpec "x :: a -> a") @?=
+          -- "Asrts ([\"x\" (dummyLoc)],(a -> a (dummyLoc),Nothing))"
+             "Asrts ([\"x\" (dummyLoc)],(lq_tmp$db##0:a -> a (dummyLoc),Nothing))"
+
+    , testCase "x :: Int -> Int" $
+       (parseSingleSpec "x :: Int -> Int") @?=
+          -- "Asrts ([\"x\" (dummyLoc)],(Int -> Int (dummyLoc),Nothing))"
+             "Asrts ([\"x\" (dummyLoc)],(lq_tmp$db##0:Int -> Int (dummyLoc),Nothing))"
+
+    , testCase "k:Int -> Int" $
+       (parseSingleSpec "x :: k:Int -> Int") @?=
+          "Asrts ([\"x\" (dummyLoc)],(k:Int -> Int (dummyLoc),Nothing))"
+
+    , testCase "type spec 1 " $
+       parseSingleSpec "type IncrListD a D = [a]<{\\x y -> (x+D) <= y}>" @?=
+          "Alias type IncrListD \"a\" \"D\" = [a] -- defined at \"Fixpoint.Types.dummyLoc\" (line 0, column 0)"
+
+    , testCase "type spec 2 " $
+       parseSingleSpec "takeL :: Ord a => x:a -> [a] -> [{v:a|v<=x}]" @?=
+          -- "Asrts ([\"takeL\" (dummyLoc)],((Ord a) -> x:a -> lq_tmp$db##1:[a] -> [{v##2 : a | v##2 <= x}] (dummyLoc),Nothing))"
+             "Asrts ([\"takeL\" (dummyLoc)],((Ord a) -> x:a -> lq_tmp$db##1:[a] -> [{v##4 : a | v##4 <= x}] (dummyLoc),Nothing))"
+
+    , testCase "type spec 3" $
+       parseSingleSpec "bar :: t 'Nothing" @?=
+          "Asrts ([\"bar\" (dummyLoc)],(t Nothing (dummyLoc),Nothing))"
+
+    , testCase "type spec 4" $
+       parseSingleSpec "Cons :: forall <l>.a -> L^l a -> L^l a" @?=
+          "Asrts ([\"Cons\" (dummyLoc)],(lq_tmp$db##0:a -> lq_tmp$db##1:(L a) -> (L a) (dummyLoc),Nothing))"
+
+    , testCase "type spec 5" $
+       parseSingleSpec "mapKeysWith :: (Ord k2) => (a -> a -> a) -> (k1->k2) -> OMap k1 a -> OMap k2 a" @?=
+             "Asrts ([\"mapKeysWith\" (dummyLoc)],((Ord k2) -> lq_tmp$db##2:(lq_tmp$db##3:a -> lq_tmp$db##4:a -> a) -> lq_tmp$db##6:(lq_tmp$db##7:k1 -> k2) -> lq_tmp$db##9:(OMap k1 a) -> (OMap k2 a) (dummyLoc),Nothing))"
+
+    , testCase "type spec 6 " $
+       parseSingleSpec (unlines $
+         [ "data Tree [ht] a = Nil"
+         , "            | Tree { key :: a"
+         , "                   , l   :: Tree {v:a | v < key }"
+         , "                   , r   :: Tree {v:a | key < v }"
+         , "                   }" ])
+        @?=
+          "DDecl DataDecl: data = \"Tree\" (dummyLoc), tyvars = [\"a\"]"
+
+    , testCase "type spec 7" $
+       parseSingleSpec "type AVLL a X    = AVLTree {v:a | v < X}" @?=
+              "Alias type AVLL \"a\" \"X\" = (AVLTree {v##1 : a | v##1 < X}) -- defined at \"Fixpoint.Types.dummyLoc\" (line 0, column 0)"
+
+    , testCase "type spec 8" $
+       parseSingleSpec "type AVLR a X    = AVLTree {v:a |X< v} " @?=
+          -- "Alias type AVLR \"a\" \"X\" = (AVLTree {v##0 : a | X < v##0}) -- defined at \"Fixpoint.Types.dummyLoc\" (line 0, column 0)"
+             "Alias type AVLR \"a\" \"X\" = (AVLTree {v##1 : a | X < v##1}) -- defined at \"Fixpoint.Types.dummyLoc\" (line 0, column 0)"
+
+    , testCase "type spec 9 " $
+       parseSingleSpec (unlines $
+      [ "assume (++) :: forall <p :: a -> Bool, q :: a -> Bool, r :: a -> Bool>."
+      , "  {x::a<p> |- a<q> <: {v:a| x <= v}} "
+      , "  {a<p> <: a<r>} "
+      , "  {a<q> <: a<r>} "
+      , "  Ord a => OList (a<p>) -> OList (a<q>) -> OList a<r> "])
+        @?=
+             "Assm (\"(++)\" (dummyLoc),(Ord a) =>\n{x :: {VV : a | true} |- {VV : a | true} <: {v##8 : a | x <= v##8}} =>\n{|- {VV : a | true} <: {VV : a | true}} =>\n{|- {VV : a | true} <: {VV : a | true}} =>\nlq_tmp$db##14:(OList {VV : a | true}) -> lq_tmp$db##16:(OList {VV : a | true}) -> (OList {VV : a | true}) (dummyLoc))"
+
+    , testCase "type spec 10" $
+       parseSingleSpec (unlines $
+          [ "data AstF f <ix :: AstIndex -> Bool>"
+          , "  = Lit Int    (i :: AstIndex<ix>)"
+          , "  | Var String (i :: AstIndex<ix>)"
+          , "  | App (fn :: f) (arg :: f)"
+          , "  | Paren (ast :: f)" ])
+          @?=
+          "DDecl DataDecl: data = \"AstF\" (dummyLoc), tyvars = [\"f\"]"
+
+    , testCase "type spec 11" $
+       parseSingleSpec "assume     :: b:_ -> a -> {v:a | b} " @?=
+          "Asrts ([\"assume\" (dummyLoc)],(b:{VV : _ | $HOLE} -> lq_tmp$db##0:a -> {v##1 : a | b} (dummyLoc),Nothing))"
+
+    , testCase "type spec 12" $
+       parseSingleSpec (unlines $
+          [ "app :: forall <p :: Int -> Bool, q :: Int -> Bool>. "
+          , "       {Int<q> <: Int<p>}"
+          , "       {x::Int<q> |- {v:Int| v = x + 1} <: Int<q>}"
+          , "       (Int<p> -> ()) -> x:Int<q> -> ()" ])
+          @?=
+             "Asrts ([\"app\" (dummyLoc)],({|- Int <: Int} =>\n{x :: Int |- {v##7 : Int | v##7 == x + 1} <: Int} =>\nlq_tmp$db##9:(lq_tmp$db##10:Int -> ()) -> x:Int -> () (dummyLoc),Nothing))"
+
+    , testCase "type spec 13" $
+       parseSingleSpec (unlines $
+          [ " ssum :: forall<p :: a -> Bool, q :: a -> Bool>. "
+          , "         {{v:a | v == 0} <: a<q>}"
+          , "         {x::a<p> |- {v:a | x <= v} <: a<q>}"
+          , "         xs:[{v:a<p> | 0 <= v}] -> {v:a<q> | len xs >= 0 && 0 <= v } "])
+          @?=
+             "Asrts ([\"ssum\" (dummyLoc)],({|- {v##4 : a | v##4 == 0} <: {VV : a | true}} =>\n{x :: {VV : a | true} |- {v##7 : a | x <= v##7} <: {VV : a | true}} =>\nxs:[{v##9 : a | 0 <= v##9}] -> {v##10 : a | len xs >= 0\n                                            && 0 <= v##10} (dummyLoc),Nothing))"
+
+    , testCase "type spec 14" $
+       parseSingleSpec (unlines $
+          [ " predicate ValidChunk V XS N "
+          , " = if len XS == 0 "
+          , "     then (len V == 0) "
+          , "     else (((1 < len XS && 1 < N) => (len V  < len XS)) "
+          , "       && ((len XS <= N ) => len V == 1)) "])
+          @?=
+          "EAlias type ValidChunk  \"V\" \"XS\" \"N\" = PAnd [PImp (PAtom Eq (EApp (EVar \"len\") (EVar \"XS\")) (ECon (I 0))) (PAtom Eq (EApp (EVar \"len\") (EVar \"V\")) (ECon (I 0))),PImp (PNot (PAtom Eq (EApp (EVar \"len\") (EVar \"XS\")) (ECon (I 0)))) (PAnd [PImp (PAnd [PAtom Lt (ECon (I 1)) (EApp (EVar \"len\") (EVar \"XS\")),PAtom Lt (ECon (I 1)) (EVar \"N\")]) (PAtom Lt (EApp (EVar \"len\") (EVar \"V\")) (EApp (EVar \"len\") (EVar \"XS\"))),PImp (PAtom Le (EApp (EVar \"len\") (EVar \"XS\")) (EVar \"N\")) (PAtom Eq (EApp (EVar \"len\") (EVar \"V\")) (ECon (I 1)))])] -- defined at \"Fixpoint.Types.dummyLoc\" (line 0, column 0)"
+
+    , testCase "type spec 15" $
+       parseSingleSpec "assume (=*=.) :: Arg a => f:(a -> b) -> g:(a -> b) -> (r:a -> {f r == g r}) -> {v:(a -> b) | f == g}" @?=
+             "Assm (\"(=*=.)\" (dummyLoc),(Arg a) -> f:(lq_tmp$db##1:a -> b) -> g:(lq_tmp$db##3:a -> b) -> lq_tmp$db##5:(r:a -> {VV : _ | f r == g r}) -> {VV : lq_tmp$db##7:a -> b | f == g} (dummyLoc))"
+
+    , testCase "type spec 16" $
+       parseSingleSpec "sort :: (Ord a) => xs:[a] -> OListN a {len xs}" @?=
+           "Asrts ([\"sort\" (dummyLoc)],((Ord a) -> xs:[a] -> (OListN a {len xs}) (dummyLoc),Nothing))"
+
+    , testCase "type spec 17" $
+       parseSingleSpec " ==. :: x:a -> y:{a| x == y} -> {v:b | v ~~ x && v ~~ y } " @?=
+           "Asrts ([\"==.\" (dummyLoc)],(x:a -> y:{y##0 : a | x == y##0} -> {v##1 : b | v##1 ~~ x\n                                               && v##1 ~~ y} (dummyLoc),Nothing))"
+
+    , testCase "type spec 18" $
+       parseSingleSpec "measure snd :: (a,b) -> b" @?=
+           "Meas snd :: lq_tmp$db##0:(a, b) -> b"
+
+    , testCase "type spec 19" $
+       parseSingleSpec "returnST :: xState:a \n             -> ST <{\\xs xa v -> (xa = xState)}> a s " @?=
+                     -- returnST :: a -> ST a s
+                     -- returnST x = S $ \s -> (x, s)
+           "Asrts ([\"returnST\" (dummyLoc)],(xState:a -> (ST a s) (dummyLoc),Nothing))"
+
+    , testCase "type spec 20" $
+       parseSingleSpec "makeq :: l:_ -> r:{ _ | size r <= size l + 1} -> _ " @?=
+           "Asrts ([\"makeq\" (dummyLoc)],(l:{VV : _ | $HOLE} -> r:{r##0 : _ | size r##0 <= size l + 1} -> {VV : _ | $HOLE} (dummyLoc),Nothing))"
+
+    , testCase "type spec 21" $
+       parseSingleSpec "newRGRef :: forall <p :: a -> Bool, r :: a -> a -> Bool >.\n   e:a<p> ->\n  e2:a<r e> ->\n  f:(x:a<p> -> y:a<r x> -> {v:a<p> | (v = y)}) ->\n IO (RGRef <p, r> a)" @?=
+            "Asrts ([\"newRGRef\" (dummyLoc)],(e:{VV : a | true} -> e2:{VV : a | true} -> f:(x:{VV : a | true} -> y:{VV : a | true} -> {v##5 : a | v##5 == y}) -> (IO (RGRef a)) (dummyLoc),Nothing))"
+
+    , testCase "type spec 22" $
+       parseSingleSpec "cycle        :: {v: [a] | len(v) > 0 } -> [a]" @?=
+            "Asrts ([\"cycle\" (dummyLoc)],(v:{v##0 : [a] | len v##0 > 0} -> [a] (dummyLoc),Nothing))"
+
+    , testCase "type spec 23" $
+       parseSingleSpec "cons :: x:a -> _ -> {v:[a] | hd v = x} " @?=
+         "Asrts ([\"cons\" (dummyLoc)],(x:a -> lq_tmp$db##0:{VV : _ | $HOLE} -> {v##1 : [a] | hd v##1 == x} (dummyLoc),Nothing))"
+
+    , testCase "type spec 24" $
+       parseSingleSpec "set :: a:Vector a -> i:Idx a -> a -> {v:Vector a | vlen v = vlen a}" @?=
+         "Asrts ([\"set\" (dummyLoc)],(a:(Vector a) -> i:(Idx a) -> lq_tmp$db##0:a -> {v##1 : (Vector a) | vlen v##1 == vlen a} (dummyLoc),Nothing))"
+
+    , testCase "type spec 25" $
+       parseSingleSpec "assume GHC.Prim.+#  :: x:GHC.Prim.Int# -> y:GHC.Prim.Int# -> {v: GHC.Prim.Int# | v = x + y}" @?=
+         "Assm (\"GHC.Prim.+#\" (dummyLoc),x:Int# -> y:Int# -> {v##0 : Int# | v##0 == x + y} (dummyLoc))"
+
+    , testCase "type spec 26" $
+       parseSingleSpec " measure isEVar " @?=
+         "HMeas \"isEVar\" (dummyLoc)"
+
+    , testCase "type spec 27" $
+       parseSingleSpec (unlines $
+         [ "data List a where"
+         , "    Nil  :: List a "
+         , "  | Cons :: listHead:a -> listTail:List a -> List a  "])
+        @?=
+          "DDecl DataDecl: data = \"List\" (dummyLoc), tyvars = [\"a\"]"
+
+    , testCase "type spec 28" $
+       parseSingleSpec (unlines $
+         [ "data List2 a b <p :: a -> Bool> where"
+         , "    Nil2  :: List2 a "
+         , "  | Cons2 :: listHead:a -> listTail:List a -> List2 a b"])
+        @?=
+          "DDecl DataDecl: data = \"List2\" (dummyLoc), tyvars = [\"a\",\"b\"]"
+
+    ]
+
+-- ---------------------------------------------------------------------
+
+testFails :: TestTree
+testFails =
+  testGroup "Does fail"
+    [ testCase "Maybe k:Int -> Int" $
+          parseSingleSpec "x :: Maybe k:Int -> Int" @?=
+            "<test>:1:13: Error: Cannot parse specification:\n    unexpected ':'\n    expecting stratumP, monoPredicateP, white space, bareTyArgP, mmonoPredicateP, \"->\", \"=>\", \"/\" or end of input"
+    ]
+
+
+-- ---------------------------------------------------------------------
+
+testErrorReporting :: TestTree
+testErrorReporting =
+  testGroup "Error reprting"
+    [ testCase "assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignPtrN a n " $
+          parseSingleSpec "assume mallocForeignPtrBytes :: n:Nat -> IO (ForeignPtrN a n " @?=
+            "<test>:1:62: Error: Cannot parse specification:\n    unexpected end of input\n    expecting bareTyArgP"
+
+    , testCase "Missing |" $
+          parseSingleSpec "ff :: {v:Nat  v >= 0 }" @?=
+          -- parseSingleSpec "ff :: {v :  }" @?=
+            "<test>:1:9: Error: Cannot parse specification:\n    unexpected \":\"\n    expecting operator, white space or \"}\""
+    ]
+
+-- ---------------------------------------------------------------------
+
+-- | Parse a single type signature containing LH refinements. To be
+-- used in the REPL.
+parseSingleSpec :: String -> String
+parseSingleSpec src =
+  case LH.singleSpecP (initialPos "<test>") src of
+    Left err  -> show err
+    Right res -> show $ dummyLocs res
+
+-- ---------------------------------------------------------------------
+
+dummyLocs :: (Data a) => a -> a
+dummyLocs = everywhere (mkT posToDummy)
+  where
+    posToDummy :: SourcePos -> SourcePos
+    posToDummy _ = dummyPos "Fixpoint.Types.dummyLoc"
+
+-- ---------------------------------------------------------------------
diff --git a/tests/TestCommits.hs b/tests/TestCommits.hs
new file mode 100644
--- /dev/null
+++ b/tests/TestCommits.hs
@@ -0,0 +1,115 @@
+#!/usr/bin/env runhaskell
+
+{- GeneralizedNewtypeDeriving -}
+
+import System.Environment   (getArgs)
+import System.Process       (system)
+import Text.Printf          (printf)
+import Data.List            (isSuffixOf, stripPrefix)
+import Data.Maybe           (fromMaybe)
+
+{- | Run this script as:
+
+     $ ./TestCommit.hs commits.txt
+
+     where commits.txt is a file with a single git commit on each line, OR
+
+     $ ./TestCommit.hs NUMBER
+
+     which will get the last N(UMBER) of commits from the `branch`
+
+ -}
+
+--------------------------------------------------------------------------------
+-- | Configuration parameters
+--------------------------------------------------------------------------------
+
+project :: String
+project = "liquidhaskell"
+-- project = "liquidhaskell --fast --test-arguments=\"-p Peano\""
+
+branch :: String
+branch = "develop"
+
+tmpFile :: FilePath
+tmpFile = "/tmp/commits"
+
+summaryPath :: FilePath
+summaryPath = "/Users/rjhala/research/stack/lh-test/tests/logs/cur/summary.csv"
+
+--------------------------------------------------------------------------------
+main :: IO ()
+--------------------------------------------------------------------------------
+main = do
+  p <- strParam . head <$> getArgs
+  case p of
+    File f -> testCommits f
+    Size n -> makeCommits n
+
+makeCommits :: Int -> IO ()
+makeCommits n = do
+  system (genCommand n)
+  putStrLn $ "Wrote commits into: " ++ tmpFile
+
+testCommits :: FilePath -> IO ()
+testCommits f = do
+  is <- readCommits f
+  putStrLn "Generating test summaries for:"
+  mapM_ (putStrLn . ("  " ++)) is
+  runCmd setupCmd
+  mapM_ runCommit is
+  runCmd setupCmd
+
+strParam :: String -> Param
+strParam s
+  | ".txt" `isSuffixOf` s = File s
+  | otherwise             = Size (read s)
+
+--------------------------------------------------------------------------------
+-- | Types
+--------------------------------------------------------------------------------
+data Param = File FilePath
+           | Size Int
+
+type CommitId = String
+type Command  = [String]
+
+
+--------------------------------------------------------------------------------
+_commits :: Param -> IO [CommitId]
+--------------------------------------------------------------------------------
+_commits (File f) = readCommits f
+_commits (Size n) = system (genCommand n) >> readCommits tmpFile
+
+genCommand :: Int -> String
+genCommand n = printf "git log -n %d --walk-reflogs %s | grep \"commit \" > %s"
+                 n branch tmpFile
+
+readCommits :: FilePath -> IO [CommitId]
+readCommits f = map strCommit . lines <$> readFile f
+
+strCommit :: String -> CommitId
+strCommit s = fromMaybe s (stripPrefix "commit " s)
+
+
+--------------------------------------------------------------------------------
+runCommit :: CommitId -> IO ()
+--------------------------------------------------------------------------------
+runCommit i = do
+  putStrLn ("Running commit: " ++ i)
+  runCmd (commitCmd i)
+
+runCmd :: Command -> IO ()
+runCmd = mapM_ system
+
+setupCmd :: Command
+setupCmd = [ printf "git checkout %s" branch ]
+
+commitCmd :: CommitId -> Command
+commitCmd i =
+  [ printf "git checkout %s"       i
+  ,        "git submodule update"
+  , printf "stack test %s"         project
+  , printf "cp %s ~/tmp/summary-%s.csv" summaryPath i
+  ]
+
diff --git a/tests/crash/BadPragma0.hs b/tests/crash/BadPragma0.hs
new file mode 100644
--- /dev/null
+++ b/tests/crash/BadPragma0.hs
@@ -0,0 +1,7 @@
+{-@ LIQUID "--idirs=.." @-}
+
+module Bad where 
+
+i :: Int
+i = 1
+
diff --git a/tests/crash/BadPragma1.hs b/tests/crash/BadPragma1.hs
new file mode 100644
--- /dev/null
+++ b/tests/crash/BadPragma1.hs
@@ -0,0 +1,7 @@
+{-@ LIQUID "--c-files=./wow.c" @-}
+
+module Bad where 
+
+i :: Int
+i = 1
+
diff --git a/tests/crash/BadPragma2.hs b/tests/crash/BadPragma2.hs
new file mode 100644
--- /dev/null
+++ b/tests/crash/BadPragma2.hs
@@ -0,0 +1,7 @@
+{-@ LIQUID "--ghc-option=-O0" @-}
+
+module Bad where 
+
+i :: Int
+i = 1
+
diff --git a/tests/crash/HigherOrder.hs b/tests/crash/HigherOrder.hs
new file mode 100644
--- /dev/null
+++ b/tests/crash/HigherOrder.hs
@@ -0,0 +1,3 @@
+{-@ foo :: a: Int -> f: (Int -> Int) -> {v : Int | v = 123 + (f a) } @-}
+foo :: Int -> (Int -> Int) -> Int
+foo a f = f a
diff --git a/tests/crash/RClass.hs b/tests/crash/RClass.hs
--- a/tests/crash/RClass.hs
+++ b/tests/crash/RClass.hs
@@ -6,14 +6,12 @@
   @-}
   foo :: a -> a       
 
-
 instance Foo Int where
   {-@ instance Foo Int where
-       foo :: x:Int -> {v:Int | v = x + 1} @-}
+       foo :: x:Int -> {v:Int | v = x + 1 == 9} @-}
   foo x = x + 1
 
 instance Foo Integer where
   {-@ instance Foo Integer where
        foo :: x:Integer -> {v:Integer | v = x + 1} @-}
   foo x = x + 1
-
diff --git a/tests/crash/SizeFunMissing.hs b/tests/crash/SizeFunMissing.hs
new file mode 100644
--- /dev/null
+++ b/tests/crash/SizeFunMissing.hs
@@ -0,0 +1,13 @@
+module MapReduce where
+
+{-@ data List [llen] a = N | C {lhead :: a, ltail :: List a} @-}
+data List a = N | C a (List a)
+
+{-@ measure llen @-}
+llen :: List a -> Bool 
+llen N = True  
+llen (C _ xs) = False -- 1 + llen xs
+
+
+{-@ data List2 [llen2] a = N2 | C2 {lhead2 :: a, ltail2 :: List2 a} @-}
+data List2 a = N2 | C2 a (List2 a)
diff --git a/tests/crash/T691.hs b/tests/crash/T691.hs
new file mode 100644
--- /dev/null
+++ b/tests/crash/T691.hs
@@ -0,0 +1,7 @@
+-- We should reject the below to disallow uppercase binders
+
+module NoUpperCaseBinders where
+
+{-@ id :: Foo:Int -> Int  @-}
+id :: Int -> Int
+id x = x
diff --git a/tests/crash/T773.hs b/tests/crash/T773.hs
new file mode 100644
--- /dev/null
+++ b/tests/crash/T773.hs
@@ -0,0 +1,11 @@
+-- | Right now this gives a rather mysterious error, 
+--   cannot unify `int` with `(a b)` it would be nice 
+--   to actually point out the offending sub-expression, namely `len x`.
+
+module LiquidR where
+
+{-@ measure goober :: String -> Int @-}
+
+{-@ incr :: x:Int -> {v:Bool | goober x == 0} @-}
+incr :: Int -> Bool
+incr = undefined
diff --git a/tests/crash/T774.hs b/tests/crash/T774.hs
new file mode 100644
--- /dev/null
+++ b/tests/crash/T774.hs
@@ -0,0 +1,10 @@
+
+-- | Why does this NOT fail?! Clearly there is a sort error?!
+
+module LiquidR where
+
+{-@ measure goober :: String -> Int @-}
+
+{-@ incr :: x:Int -> y:Int -> {v:Bool | goober x == goober y} @-}
+incr :: Int -> Int -> Bool
+incr = undefined
diff --git a/tests/elim/Ackermann0.hs b/tests/elim/Ackermann0.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/Ackermann0.hs
@@ -0,0 +1,90 @@
+
+-- | Proving ackermann properties from
+-- | http://www.cs.yorku.ca/~gt/papers/Ackermann-function.pdf
+
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{- LIQUID "--maxparams=5"     @-}
+{-@ LIQUID "--eliminate"       @-}
+{- LIQUID "--scrape-internals" @-}
+
+
+module Ackermann where
+
+import Proves
+-- import Helper
+
+-- | First ackermann definition
+
+{-@ axiomatize ack @-}
+{-@ ack :: n:Nat -> x:Nat -> Nat / [n, x] @-}
+ack :: Int -> Int -> Int
+ack n x
+  | n == 0
+  = x + 2
+  | x == 0
+  = 2
+  | otherwise
+  = ack (n-1) (ack n (x-1))
+
+-- | Second ackermann definition
+
+{-@ axiomatize iack @-}
+{-@ iack :: Nat -> Nat -> Nat -> Nat @-}
+{- measure iack :: Int -> Int -> Int -> Int @-}
+{- iack :: h:Nat -> n:Nat -> x:Nat -> {v:Nat | v == iack h n x && v == if h == 0 then x else ack n (iack (h-1) n x) } @-}
+iack :: Int -> Int -> Int -> Int
+iack h n x
+  = if h == 0 then x else ack n (iack (h-1) n x)
+
+-- | Equivalence of definitions
+
+{-@ def_eq :: n:Nat -> x:Nat -> {v:Proof | ack (n+1) x == iack x n 2 }  / [x]@-}
+def_eq :: Int -> Int -> Proof
+def_eq n x
+  = undefined
+
+lemma3_eq :: Int -> Int -> Int -> Proof
+{-@ lemma3_eq :: n:Nat -> x:Nat -> y:{Nat | x <= y} -> {v:Proof | ack n x <= ack n y} / [y] @-}
+lemma3_eq n x y
+  = undefined
+
+
+
+-- | Lemma 2.4
+{-@ type Pos = {v:Int | 0 < v } @-}
+
+lemma4 :: Int -> Int -> Proof
+{-@ lemma4 :: x:Pos -> n:Nat -> {v:Proof | ack n x < ack (n+1) x } @-}
+lemma4 x n
+  = undefined
+
+
+lemma4_eq     :: Int -> Int -> Bool
+{-@ lemma4_eq :: n:Nat -> x:Nat -> {v:Bool | ack n x <= ack (n+1) x } @-}
+lemma4_eq n x
+  = undefined
+
+
+-- Lemma 2.7
+
+lemma7 :: Int -> Int -> Int -> Bool
+{-@ lemma7 :: h:Nat -> n:Nat -> x:Nat
+           -> {v:Bool | iack h n x <= iack h (n+1) x } @-}
+lemma7 h n x
+  | x == 0 , h == 0
+  = proof $
+     iack 0 n 0 ==! (0 :: Int)
+                ==! iack 0 (n+1) 0
+  | h == 0
+  = proof $
+      iack 0 n x ==! x
+                 ==! iack 0 (n+1) x
+  | h > 0
+  = proof $
+      iack h n x ==! ack n (iack (h-1) n x)
+                 <=! ack (n+1) (iack (h-1) n x)     ? lemma4_eq n (iack (h-1) n x)
+                 <=! ack (n+1) (iack (h-1) (n+1) x) ? (lemma7 (h-1) n x
+                                                     &&& lemma3_eq (n+1) (iack (h-1) n x) (iack (h-1) (n+1) x)
+                                                      )
+                 <=! iack h (n+1) x ? True
diff --git a/tests/elim/Ackermann0_inline.hs b/tests/elim/Ackermann0_inline.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/Ackermann0_inline.hs
@@ -0,0 +1,91 @@
+
+-- | Proving ackermann properties from
+-- | http://www.cs.yorku.ca/~gt/papers/Ackermann-function.pdf
+
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{- LIQUID "--maxparams=5"     @-}
+{-@ LIQUID "--eliminate"       @-}
+{- LIQUID "--scrape-internals" @-}
+
+
+module Ackermann where
+
+import Proves
+-- import Helper
+
+-- | First ackermann definition
+
+{-@ axiomatize ack @-}
+{-@ ack :: n:Nat -> x:Nat -> Nat / [n, x] @-}
+ack :: Int -> Int -> Int
+ack n x
+  | n == 0
+  = x + 2
+  | x == 0
+  = 2
+  | otherwise
+  = ack (n-1) (ack n (x-1))
+
+-- | Second ackermann definition
+
+{-@ axiomatize iack @-}
+{-@ iack :: Nat -> Nat -> Nat -> Nat @-}
+{- measure iack :: Int -> Int -> Int -> Int @-}
+{- iack :: h:Nat -> n:Nat -> x:Nat -> {v:Nat | v == iack h n x && v == if h == 0 then x else ack n (iack (h-1) n x) } @-}
+iack :: Int -> Int -> Int -> Int
+iack h n x
+  = if h == 0 then x else ack n (iack (h-1) n x)
+
+-- | Equivalence of definitions
+
+{-@ def_eq :: n:Nat -> x:Nat -> {v:Proof | ack (n+1) x == iack x n 2 }  / [x]@-}
+def_eq :: Int -> Int -> Proof
+def_eq n x
+  = undefined
+
+lemma3_eq :: Int -> Int -> Int -> Proof
+{-@ lemma3_eq :: n:Nat -> x:Nat -> y:{Nat | x <= y} -> {v:Proof | ack n x <= ack n y} / [y] @-}
+lemma3_eq n x y
+  = undefined
+
+
+
+-- | Lemma 2.4
+{-@ type Pos = {v:Int | 0 < v } @-}
+
+lemma4 :: Int -> Int -> Proof
+{-@ lemma4 :: x:Pos -> n:Nat -> {v:Proof | ack n x < ack (n+1) x } @-}
+lemma4 x n
+  = undefined
+
+
+lemma4_eq     :: Int -> Int -> Bool
+{-@ lemma4_eq :: n:Nat -> x:Nat -> {v:Bool | ack n x <= ack (n+1) x } @-}
+lemma4_eq n x
+  = undefined
+
+
+-- Lemma 2.7
+
+lemma7 :: Int -> Int -> Int -> Bool
+{-@ lemma7 :: h:Nat -> n:Nat -> x:Nat
+           -> {v:Bool | iack h n x <= iack h (n+1) x } @-}
+lemma7 h n x
+  | x == 0 , h == 0
+  = proof (
+     iack 0 n 0 ==! (0 :: Int)
+                ==! iack 0 (n+1) 0 )
+  | h == 0
+  = proof (
+      iack 0 n x ==! x
+                 ==! iack 0 (n+1) x )
+  | h > 0
+  = proof (
+      ((
+      iack h n x ==! ack n (iack (h-1) n x)
+                 <=! ack (n+1) (iack (h-1) n x) ) (lemma4_eq n (iack (h-1) n x))
+                 <=! ack (n+1) (iack (h-1) (n+1) x) ) (lemma7 (h-1) n x
+                                                     &&& lemma3_eq (n+1) (iack (h-1) n x) (iack (h-1) (n+1) x)
+                                                      )
+                 <=! iack h (n+1) x )
diff --git a/tests/elim/ElimApply.hs b/tests/elim/ElimApply.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/ElimApply.hs
@@ -0,0 +1,40 @@
+-- | A simple depth test for `--eliminate`. The size of the max KInfo depth is
+--   about 2x the number of calls to `incr`.
+module ElimMonad (prop) where
+
+{-@ prop :: x:Nat -> {v:Int | v = x + 30} @-}
+prop :: Int -> Int
+prop x = incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr
+       $ incr x
+
+{-@ incr :: dog:Int -> {v:Int | v == dog + 1} @-}
+incr :: Int -> Int
+incr cat = cat + 1
diff --git a/tests/elim/ElimMonad.hs b/tests/elim/ElimMonad.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/ElimMonad.hs
@@ -0,0 +1,34 @@
+-- | A simple depth test for `--eliminate`. The size of the max KInfo depth is
+--   about 2x the number of calls to `incr`.
+module ElimMonad (prop) where
+
+{-@ prop :: x:Nat -> IO {v:Int | v = x + 22} @-}
+prop :: Int -> IO Int
+prop x = do
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  x <- incr x
+  return x
+
+{-@ incr :: dog:Int -> IO {v:Int | v == dog + 1} @-}
+incr :: Int -> IO Int
+incr cat = return (cat + 1)
diff --git a/tests/elim/ElimMonad00.hs b/tests/elim/ElimMonad00.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/ElimMonad00.hs
@@ -0,0 +1,20 @@
+-- | A simple depth test for `--eliminate`. The size of the max KInfo depth is
+--   about 2x the number of calls to `incr`.
+module ElimMonad (prop) where
+
+{-@ prop :: x:Nat -> IO {v:Int | v = x + 3} @-}
+prop :: Int -> IO Int
+prop apple = do
+  banana  <- incr apple
+  cherry  <- incr banana
+  falafel <- incr cherry
+  return falafel 
+
+{-@ incr :: dog:Int -> IO {v:Int | v == dog + 1} @-}
+incr :: Int -> IO Int
+incr cat = return (cat + 1)
+
+
+{-@ zonk :: (Monad m) => Nat -> m Nat @-}
+zonk :: (Monad m) => Int -> m Int
+zonk mouse = return (mouse + 1)
diff --git a/tests/elim/ElimMonad2.hs b/tests/elim/ElimMonad2.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/ElimMonad2.hs
@@ -0,0 +1,33 @@
+-- | A simple depth test for `--eliminate`. The size of the max KInfo depth is
+--   about 2x the number of calls to `incr`.
+module ElimMonad (prop) where
+
+{-@ prop :: x:Nat -> IO {v:Int | v = x + 20} @-}
+prop :: Int -> IO Int
+prop x = do
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+  x <- if (x >= 0) then incr x else incr x
+
+  return x
+
+{-@ incr :: dog:Int -> IO {v:Int | v == dog + 1} @-}
+incr :: Int -> IO Int
+incr cat = return (cat + 1)
diff --git a/tests/elim/T658.hs b/tests/elim/T658.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/T658.hs
@@ -0,0 +1,5 @@
+-- #658, fails if you comment out test1 (and test2?)
+
+{-@ test3 :: n:Nat -> lst:{ [a] | n < len lst} -> {v : [a] | len v = len lst } @-}
+test3 :: Int -> [a] -> [a]
+test3 n lst = a ++ b where (a, b) = splitAt n lst
diff --git a/tests/elim/fresh1-sel.hs b/tests/elim/fresh1-sel.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/fresh1-sel.hs
@@ -0,0 +1,24 @@
+module Dummy (foo) where
+
+import GHC.ST (ST, runST)
+
+data Pair a b = Pair {pair1 :: a, pair2 :: b}
+
+{-@ foo :: Int -> Nat @-}
+foo :: Int -> Int
+foo b = y + z
+  where
+    y = pair1 blob
+    z = pair2 blob
+    blob = runST $ do yogurt      <- undefined
+                      (zag, zink) <- thing2 yogurt
+                      oink        <- thing1 zag
+                      return  (Pair oink zink)
+
+{-@ thing2 :: Int -> ST s (Int, Int) @-}
+thing2 :: Int -> ST s (Int, Int)
+thing2 = undefined
+
+{-@ thing1 :: Int -> ST s Int @-}
+thing1 :: Int -> ST s Int
+thing1 = undefined
diff --git a/tests/elim/fresh1.hs b/tests/elim/fresh1.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/fresh1.hs
@@ -0,0 +1,22 @@
+module Dummy (foo) where
+
+import GHC.ST (ST, runST)
+
+data Pair a b = Pair a b
+
+{-@ foo :: Int -> Nat @-}
+foo :: Int -> Int
+foo b = y + z
+  where
+    (Pair y z) = runST $ do yogurt      <- undefined
+                            (zag, zink) <- thing2 yogurt
+                            oink        <- thing1 zag
+                            return  (Pair oink zink)
+
+{-@ thing2 :: Int -> ST s (Int, Int) @-}
+thing2 :: Int -> ST s (Int, Int)
+thing2 = undefined
+
+{-@ thing1 :: Int -> ST s Int @-}
+thing1 :: Int -> ST s Int
+thing1 = undefined
diff --git a/tests/elim/fresh2.hs b/tests/elim/fresh2.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/fresh2.hs
@@ -0,0 +1,15 @@
+module Dummy (foo) where
+
+data Pair a b = Pair a b
+
+{-@ foo :: Nat -> Nat -> Nat -> Nat @-}
+foo :: Int -> Int -> Int -> Int
+foo a b c = x + y + z 
+  where
+    Pair x (Pair y z) = runList $ do xiggety <- return (a + 1)
+                                     yogurt  <- return (b + 1)
+                                     zagbert <- return (c + 1)
+                                     return  (Pair xiggety (Pair yogurt zagbert))
+
+runList :: [a] -> a
+runList = undefined
diff --git a/tests/elim/rwr0.hs b/tests/elim/rwr0.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/rwr0.hs
@@ -0,0 +1,6 @@
+module Foo where
+
+moo :: Int -> Int
+moo n = x + y
+  where
+    (x, y) = (n, n + 1)
diff --git a/tests/elim/tup3-2.hs b/tests/elim/tup3-2.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup3-2.hs
@@ -0,0 +1,24 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b} 
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    t2 = (\z2 -> let y2  = fst t1
+                     y2' = snd t1
+                 in Pair y2 y2') ()
+
+    aga  = fst t2
+
+    maga = snd t2
+
+
diff --git a/tests/elim/tup3-3.hs b/tests/elim/tup3-3.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup3-3.hs
@@ -0,0 +1,27 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b} 
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    t2 = (\z2 -> let y2  = fst t1
+                     y2' = snd t1
+                 in Pair y2 y2') ()
+
+    t3 = (\z3 -> let y3  = fst t2
+                     y3' = snd t2
+                 in Pair y3 y3') ()
+
+    aga  = fst t3
+    maga = snd t3
+
+
diff --git a/tests/elim/tup3-4.hs b/tests/elim/tup3-4.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup3-4.hs
@@ -0,0 +1,37 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b} 
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    t2 = (\z2 -> let y2  = fst t1
+                     y2' = snd t1
+                 in Pair y2 y2') ()
+
+    t3 = (\z3 -> let y3  = fst t2
+                     y3' = snd t2
+                 in Pair y3 y3') ()
+
+    t4 = (\z4 -> let y4  = fst t3
+                     y4' = snd t3
+                 in Pair y4 y4') ()
+
+    aga  = fst t4
+    maga = snd t4
+
+{-
+bar :: Int -> Int
+bar n =
+  let e = (n, (n+1, n+2)) in
+  case e of
+    (x, (y, z)) -> x + y + z
+-}
diff --git a/tests/elim/tup3-5.hs b/tests/elim/tup3-5.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup3-5.hs
@@ -0,0 +1,30 @@
+module Foo where
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in (y1, y1')) thing
+
+    t2 = (\z2 -> let y2  = fst t1
+                     y2' = snd t1
+                 in (y2, y2')) ()
+
+    t3 = (\z3 -> let y3  = fst t2
+                     y3' = snd t2
+                 in (y3, y3') ) ()
+
+    t4 = (\z4 -> let y4  = fst t3
+                     y4' = snd t3
+                 in (y4, y4')) ()
+
+    t5 = (\z5 -> let y5  = fst t4
+                     y5' = snd t4
+                 in (y5, y5')) ()
+
+    aga  = fst t5
+    maga = snd t5
+
diff --git a/tests/elim/tup3-6.hs b/tests/elim/tup3-6.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup3-6.hs
@@ -0,0 +1,34 @@
+module Foo where
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in (y1, y1')) thing
+
+    t2 = (\z2 -> let y2  = fst t1
+                     y2' = snd t1
+                 in (y2, y2')) ()
+
+    t3 = (\z3 -> let y3  = fst t2
+                     y3' = snd t2
+                 in (y3, y3') ) ()
+
+    t4 = (\z4 -> let y4  = fst t3
+                     y4' = snd t3
+                 in (y4, y4')) ()
+
+    t5 = (\z5 -> let y5  = fst t4
+                     y5' = snd t4
+                 in (y5, y5')) ()
+
+    t6 = (\z5 -> let y6  = fst t5
+                     y6' = snd t5
+                 in (y6, y6')) ()
+
+    aga  = fst t6
+    maga = snd t6
+
diff --git a/tests/elim/tup4-1.hs b/tests/elim/tup4-1.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup4-1.hs
@@ -0,0 +1,16 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b}
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    Pair aga maga = t1
diff --git a/tests/elim/tup4-2.hs b/tests/elim/tup4-2.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup4-2.hs
@@ -0,0 +1,20 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b}
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    t2 = (\z1 -> case t1 of 
+                   Pair y2 y2' -> Pair y2 y2'
+         ) () 
+
+    Pair aga maga = t2
diff --git a/tests/elim/tup4-3.hs b/tests/elim/tup4-3.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup4-3.hs
@@ -0,0 +1,24 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b}
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    t2 = (\z1 -> case t1 of 
+                   Pair y2 y2' -> Pair y2 y2')
+         () 
+
+    t3 = (\z1 -> case t2 of 
+                   Pair y3 y3' -> Pair y3 y3')
+         () 
+
+    Pair aga maga = t3
diff --git a/tests/elim/tup4-4.hs b/tests/elim/tup4-4.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup4-4.hs
@@ -0,0 +1,28 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b}
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    t2 = (\z1 -> case t1 of 
+                   Pair y2 y2' -> Pair y2 y2')
+         () 
+
+    t3 = (\z1 -> case t2 of 
+                   Pair y3 y3' -> Pair y3 y3')
+         () 
+
+    t4 = (\z1 -> case t3 of 
+                   Pair y4 y4' -> Pair y4 y4')
+         () 
+
+    Pair aga maga = t6
diff --git a/tests/elim/tup4-5.hs b/tests/elim/tup4-5.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup4-5.hs
@@ -0,0 +1,32 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b}
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    t2 = (\z1 -> case t1 of 
+                   Pair y2 y2' -> Pair y2 y2')
+         () 
+
+    t3 = (\z1 -> case t2 of 
+                   Pair y3 y3' -> Pair y3 y3')
+         () 
+
+    t4 = (\z1 -> case t3 of 
+                   Pair y4 y4' -> Pair y4 y4')
+         () 
+
+    t5 = (\z1 -> case t4 of 
+                   Pair y5 y5' -> Pair y5 y5')
+         () 
+
+    Pair aga maga = t6
diff --git a/tests/elim/tup4-6.hs b/tests/elim/tup4-6.hs
new file mode 100644
--- /dev/null
+++ b/tests/elim/tup4-6.hs
@@ -0,0 +1,36 @@
+module Foo where
+
+import Prelude hiding (fst, snd)
+
+data Pair a b = Pair {fst :: a, snd :: b}
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int
+bar thing = aga + maga
+  where
+    t1 = (\z1 -> let mickey = z1
+                     y1      = mickey
+                     y1'     = mickey + 1
+                 in Pair y1 y1') thing
+
+    t2 = (\z1 -> case t1 of 
+                   Pair y2 y2' -> Pair y2 y2')
+         ) () 
+
+    t3 = (\z1 -> case t2 of 
+                   Pair y3 y3' -> Pair y3 y3')
+         ) () 
+
+    t4 = (\z1 -> case t3 of 
+                   Pair y4 y4' -> Pair y4 y4')
+         ) () 
+
+    t5 = (\z1 -> case t4 of 
+                   Pair y5 y5' -> Pair y5 y5')
+         ) () 
+
+    t6 = (\z1 -> case t5 of 
+                   Pair y6 y6' -> Pair y6 y6')
+         ) () 
+
+    Pair aga maga = t6
diff --git a/tests/equationalproofs/neg/Append.hs b/tests/equationalproofs/neg/Append.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/neg/Append.hs
@@ -0,0 +1,93 @@
+{-
+  A first example in equalional reasoning. 
+  From the definition of append we should be able to 
+  semi-automatically prove the three axioms.
+ -}
+
+{-@ LIQUID "--no-termination" @-}
+
+module Append where
+
+data L a = N |  C a (L a) deriving (Eq)
+
+data Proof = Proof 
+
+
+append :: L a -> L a -> L a 
+append N xs        = xs
+append (C y ys) xs = C y (append ys xs) 
+
+
+{- All the followin will be autocatically generated by the definition of append
+  and a liquid annotation
+
+  axiomatize append
+
+ -}
+
+{-@ measure append :: L a -> L a -> L a @-}
+{-@ assume append :: xs:L a -> ys:L a -> {v:L a | v == append xs ys } @-}
+
+{-@ assume axiom_append_nil :: xs:L a -> {v:Proof | append N xs == xs} @-} 
+axiom_append_nil :: L a -> Proof 
+axiom_append_nil xs = Proof
+
+{-@ assume axiom_append_cons :: x:a -> xs: L a -> ys: L a 
+          -> {v:Proof | append (C x xs) ys == C x (append xs ys) } @-} 
+axiom_append_cons :: a -> L a -> L a -> Proof 
+axiom_append_cons x xs ys = Proof
+
+
+-- | Proof library: 
+
+{-@ toProof :: l:a -> r:{a|l = r} -> {v:Proof | l = r } @-}
+toProof :: a -> a -> Proof
+toProof x y = Proof
+
+{-@ eqProof :: l:a -> r:a -> {v:Proof | l = r} -> {v:a | v = l } @-}
+eqProof :: a -> a -> Proof -> a 
+eqProof x y _ = y 
+
+
+
+-- | Proof 1: N is neutral element 
+
+{-@ prop_nil :: xs:L a -> {v:Proof | (append xs N == xs) <=> true } @-}
+prop_nil     :: Eq a => L a -> Proof
+prop_nil N   =  axiom_append_nil N 
+
+prop_nil (C x xs) = toProof e1 $ eqProof e1 (eqProof e2 e3 pr2) pr1
+   where
+   	e1  = append (C x xs) N
+   	pr1 = prop_nil xs
+   	e2  = C x (append xs N)
+   	pr2 = prop_nil xs
+   	e3  = C x xs
+
+
+-- | Proof 2: append is associative
+
+
+{-@ prop_assoc :: xs:L a -> ys:L a -> zs:L a
+               -> {v:Proof | (append (append xs ys) zs == append N (append ys zs))} @-}
+prop_assoc :: Eq a => L a -> L a -> L a -> Proof
+prop_assoc N ys zs = toProof (append (append N ys) zs) $
+	                 eqProof (append (append N ys) zs) 
+                    (eqProof (append ys zs) 
+                             (append N (append ys zs))
+                             (axiom_append_nil (append ys zs))
+                    )(axiom_append_nil ys)     
+
+prop_assoc (C x xs) ys zs = 
+	toProof e1 $ 
+	eqProof e1 (eqProof e2 (eqProof e3 (eqProof e4 e5 pr4) pr3) pr2) pr1 
+  where
+  	e1  = append (append (C x xs) ys) zs
+  	pr1 = axiom_append_cons x xs ys
+  	e2  = append (C x (append xs ys)) zs
+  	pr2 = axiom_append_cons x (append xs ys) zs
+  	e3  = C x (append (append xs ys) zs)
+  	pr3 = prop_assoc xs ys zs
+  	e4  = C x (append xs (append ys zs))
+  	pr4 = axiom_append_cons x xs (append ys zs)
+  	e5  = append (C x xs) (append ys zs)
diff --git a/tests/equationalproofs/neg/Axiomatize.hs b/tests/equationalproofs/neg/Axiomatize.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/neg/Axiomatize.hs
@@ -0,0 +1,119 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE QuasiQuotes #-}
+module Axiomatize where
+
+import Language.Haskell.TH
+import Language.Haskell.TH.Quote
+
+import Debug.Trace
+
+import Control.Applicative
+import Data.List ((\\))
+import Data.Maybe (fromMaybe)
+
+data Proof = Proof
+
+axiomatize :: Q [Dec] -> Q [Dec]
+axiomatize q = do d <- q
+                  let vts = [(x, t) | FunD x _ <- d, SigD y t <- d, x == y ]
+                  ds <- mapM (axiomatizeOne vts) d
+                  return $ trace (show d) $ concat ds
+
+axiomatizeOne :: [(Name, Type)] -> Dec -> Q [Dec]
+axiomatizeOne env f@(FunD name cs)
+  = do axioms <- makeAxioms (lookup name env) name cs
+       return $ f:axioms
+axiomatizeOne _ (SigD _ _)
+  = return []
+axiomatizeOne _ d
+  = error $ "axiomatizeOne: Cannot axiomatize" ++ show d
+
+makeAxioms :: Maybe Type -> Name -> [Clause] -> Q [Dec]
+makeAxioms t f cs = concat <$> mapM go cs
+  where
+    go :: Clause -> Q [Dec]
+    go (Clause ps (NormalB (CaseE e ms)) []) = mapM (makeAxiomMatch f ps e) ms
+    go (Clause ps (NormalB _) [])            = makeAxiomPattern t f ps
+    go d = error $ "makeAxioms: Cannot axiomatize\n" ++ show d
+
+
+
+makeAxiomPattern :: Maybe Type -> Name -> [Pat] -> Q [Dec]
+makeAxiomPattern t g ps
+  = do ifs <- mapM reify (fst <$> ds)
+       ff <- makeFun f xs <$> axiom_body
+       ft <- makeSigT t f ps
+       return $ [ff] ++ ft
+  where
+    f = mkName $ makeNamePattern g (fst <$> ds)
+    ds = [(n, dps) |  ConP n dps <- ps]
+    xs = [x | VarP x <- (ps ++ concat (snd <$> ds))]
+
+makeSigT Nothing _ _
+  = return []
+makeSigT (Just t) f ps
+  = do r <- [t|Proof|]
+       ifs <- mapM reify (fst . snd <$> ds)
+       let ts2 = concat $ zipWith makePTys ds ifs
+       return $ [SigD f $ mkUnivArrow (as, ts1 ++ ts2, r)]
+  where
+    (as, ts, _) = bkUnivFun t
+    ts1 = [t | (t, VarP _) <- zip ts ps]
+    ds  = [(t, (n, dps)) |  (t, ConP n dps) <- zip ts ps]
+
+makePTys :: (Type, (Name, [Pat])) -> Info -> [Type]
+makePTys (tr, (n, dps)) (DataConI m t _ _) | n == m
+  = (applySub θ <$> [t | (t, VarP _) <- zip ts dps])
+  where (as, ts, r) = bkUnivFun t
+        θ = unify r tr
+makePTys _ _ = error "makePTys: on invalid arguments"
+
+
+unify (VarT n) t = [(n,t)]
+unify t (VarT n) = [(n,t)]
+unify (AppT t1 t2) (AppT t1' t2') = unify t1 t1' ++ unify t2 t2'
+unify (ForallT _ _ t1) t2 = unify t1 t2
+unify t1 (ForallT _ _ t2) = unify t1 t2
+unify _ _  = []
+
+applySub :: [(Name, Type)] -> Type -> Type
+applySub θ t@(VarT v) = fromMaybe t (lookup v θ)
+applySub θ (AppT t1 t2) = AppT (applySub θ t1) (applySub θ t2)
+applySub θ (ForallT _ _ _) = error "applySub: TODO"
+applySub θ t = t
+
+
+bkUnivFun = go [] []
+  where
+    go as xs (ForallT vs _ t)   = go (as ++ vs) xs t
+    go as xs (AppT (AppT ArrowT tx) t) = go as (tx:xs) t
+    go as xs t                  = (as, reverse xs, t)
+
+mkUnivArrow (as, ts, r) = ForallT as [] $ mkArrow ts r
+  where
+    mkArrow []     r = r
+    mkArrow (t:ts) r = AppT (AppT ArrowT t) $ mkArrow ts r
+
+makeAxiomMatch :: Name -> [Pat] -> Exp -> Match -> Q Dec
+makeAxiomMatch g ps (VarE x) (Match (ConP dc dps) bd decs)
+  = makeFun f xs <$> axiom_body
+  where f  = mkName $ makeName g x dc
+        xs = [p | VarP p <- ps ++ dps] \\ [x]
+
+makeFun :: Name -> [Name] -> Exp -> Dec
+makeFun f xs bd = FunD f [Clause (VarP <$> xs) (NormalB bd) []]
+
+axiom_body :: Q Exp
+axiom_body = [|Proof|]
+
+sep = "_"
+mkSep :: [String] -> String
+mkSep []  = []
+mkSep [x] = x
+mkSep (x:xs) = x ++ sep ++ mkSep xs
+
+eq  = "is"
+makeName fname x dc
+  = mkSep ["axiom", nameBase fname, nameBase x, eq, nameBase dc]
+
+makeNamePattern fname dcs = mkSep $ ["axiom", nameBase fname] ++ (nameBase <$> dcs)
diff --git a/tests/equationalproofs/neg/Equational.hs b/tests/equationalproofs/neg/Equational.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/neg/Equational.hs
@@ -0,0 +1,35 @@
+module Equational where
+
+
+import Language.Haskell.Liquid.Prelude
+import Axiomatize
+
+
+{-@ toProof :: l:a -> r:{a | l == r} -> {v:Proof | l == r } @-}
+toProof :: a -> a -> Proof
+toProof x y = Proof
+
+
+{-@ (===) :: l:a -> r:a -> {v:Proof | l = r} -> {v:a | v = l } @-}
+(===) :: a -> a -> Proof -> a
+(===) x y _ = y
+
+
+
+{-@ type Equal X Y = {v:Proof | X == Y} @-}
+
+{-@ bound chain @-}
+chain :: (Proof -> Bool) -> (Proof -> Bool) -> (Proof -> Bool)
+      -> Proof -> Proof -> Proof -> Bool
+chain p q r = \v1 v2 v3 -> p v1 ==> q v2 ==> r v3
+
+{-@  by :: forall <p :: Proof -> Prop, q :: Proof -> Prop, r :: Proof -> Prop>.
+                 {vp::Proof<p> |- Proof<q> <: Proof<r> }
+                 Proof<p> -> Proof<q> -> Proof<r>
+@-}
+by :: Proof -> Proof -> Proof
+by _ r = r
+
+{-@ refl :: x:a -> Equal x x @-}
+refl :: a -> Proof
+refl x = Proof
diff --git a/tests/equationalproofs/neg/Fibonacci.hs b/tests/equationalproofs/neg/Fibonacci.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/neg/Fibonacci.hs
@@ -0,0 +1,67 @@
+
+{-# LANGUAGE TemplateHaskell      #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+{-@ LIQUID "--no-prune"        @-}
+
+
+module FunctionAbstraction where
+import Axiomatize
+import Equational 
+
+
+{-@ measure fib :: Int -> Int @-}
+{-@ assume fib ::
+         n:Nat 
+      -> {v:Nat| v == fib n && if n == 0 then v == 0 else (if n == 1 then v == 1 else v == fib (n-1) + fib (n-2)) } @-}
+fib :: Int -> Int 
+fib n 
+  | n <  0    = error "cannot happen" 
+  | n == 0    = 0 
+  | n == 1    = 1
+  | otherwise = fib (n-1) + fib (n-2)
+
+infixr 2 `with`
+
+{-@ with :: forall <p :: Bool -> Prop, q::Bool -> Prop, r :: Bool -> Prop>. 
+                 {vp::Bool<p> |- Bool<q> <: Bool<r> }
+                 Bool<p> -> Bool<q> -> Bool<r> @-}
+
+with :: Bool -> Bool -> Bool
+with _ r = r
+
+fib_increasing0 :: Int -> Bool
+{-@ fib_increasing0 :: x:{Nat | x > 1} -> {v:Bool | fib x > 0} @-}
+fib_increasing0 x 
+  | x == 2
+  = fib 2 == fib 1 + fib 0 `with` fib x > 0 
+  | x > 2 
+  = fib_increasing0 (x-1) `with` 
+    fib (x-2) >= 0        `with` 
+    fib x > 0
+
+{-@ fib_increasing :: x:Nat -> y:{Nat | x < y} -> {v:Bool | fib x < fib y} / [x, y] @-} 
+fib_increasing :: Int -> Int -> Bool 
+fib_increasing x y 
+  | x == 0, y == 1
+  = fib y == 1 `with` fib x == 0
+  | x == 0
+  = fib_increasing0 y `with` fib x == 0 
+  | x == 1, y == 2
+  = fib x == 1 `with`
+    fib y == fib (y-1) + fib (y-2) 
+  | x == 1, 2 < y
+  = fib x == 1 `with` fib y == fib (y-1) + fib (y-2) `with`
+    2 < y `with` fib_increasing 1 (y-1) `with`
+    1 < fib (y-1) `with` 0 < fib (y-2) 
+  | otherwise
+  = fib x == fib (x-1) + fib (x-2) `with`
+    fib y == fib (y-1) + fib (y-2) `with`
+    fib_increasing (x-1) (y-1) `with`
+    fib (x-1) <= fib (y-1) `with` 
+    fib_increasing (x-2) (y-2) `with`
+    fib (x-2) <= fib (y-2) 
diff --git a/tests/equationalproofs/pos/AppendArrow.hs b/tests/equationalproofs/pos/AppendArrow.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/AppendArrow.hs
@@ -0,0 +1,106 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+-- |   A first example in equalional reasoning.
+-- |  From the definition of append we should be able to
+-- |  semi-automatically prove the two axioms.
+
+-- | Note for soundness we need
+-- | totallity: all the cases should be covered
+-- | termination: we cannot have diverging things into proofs
+
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+module Append where
+
+import Axiomatize
+import Equational
+
+data L a = N |  C a (L a)
+
+instance Eq a => Eq (L a) where
+  N == N                 = True
+  (C x xs) == (C x' xs') = x == x' && xs == xs'
+
+{-@ axiomatize append @-}
+
+$(axiomatize
+  [d| append :: L a -> L a -> L a
+      append N xs        = xs
+      append (C y ys) xs = C y (append ys xs)
+    |])
+
+
+
+{-
+axiom_append_N :: xs: L a -> {v:Proof  |  append N xs == xs }
+axiom_append_N xs = Proof  
+
+axiom_append_C :: xs: L a -> y:a > ys: L a 
+                -> {v:Proof  |  append (C y ys) xs == C y (append ys xs) }
+axiom_append_C xs y ys  = Proof 
+-}
+
+
+
+-- | Proof 1: N is neutral element
+
+
+-- | axiomatixation of append will not be a haskell function anymore,
+-- | thus the user cannot directly access it.
+-- | use a function called `use_axiom` to apply these axioms.
+
+-- prop_app_nil :: Eq a => L a -> Proof
+
+{-@ prop_app_nil :: ys:L a -> {v:Proof | append ys N == ys} @-}
+prop_app_nil :: (Eq a) => L a -> Proof
+prop_app_nil N        = axiom_append_N N
+prop_app_nil (C x xs)
+    = 
+                                      -- (C x xs) ++ N
+           (axiom_append_C N x xs)
+                                      -- == C x (xs ++ N)
+      `by` (prop_app_nil xs)
+                                      -- == C x xs
+
+
+
+
+-- | Proof 2: append is associative
+
+{-@ prop_assoc :: xs:L a -> ys:L a -> zs:L a
+               -> {v:Proof | append (append xs ys) zs == append xs (append ys zs) } @-}
+
+prop_assoc :: Eq a => L a -> L a -> L a -> Proof
+
+prop_assoc N ys zs  = auto 2 (append (append N ys) zs == append N (append ys zs))
+-- =    refl (append (append N ys) zs) 
+--           axiom_append_N ys             -- == append ys zs
+--      `by` axiom_append_N (append ys zs) -- == append N (append ys zs)
+
+
+prop_assoc (C x xs) ys zs
+    = auto 2 (append (append (C x xs) ys) zs == append (C x xs) (append ys zs))
+--      = refl e1
+--        `by` pr1 `by` pr2 `by` pr3 `by` pr4
+  where
+    e1  = append (append (C x xs) ys) zs
+    pr1 = axiom_append_C ys x xs
+    e2  = append (C x (append xs ys)) zs
+    pr2 = axiom_append_C zs x (append xs ys)
+    e3  = C x (append (append xs ys) zs)
+    pr3 = prop_assoc xs ys zs
+    e4  = C x (append xs (append ys zs))
+    pr4 = axiom_append_C (append ys zs) x xs
+    e5  = append (C x xs) (append ys zs)
+
+
+{-@ data L [llen] @-}
+{-@ invariant {v: L a | llen v >= 0} @-}
+
+{-@ measure llen @-}
+llen :: L a -> Int
+llen N = 0
+llen (C x xs) = 1 + llen xs
diff --git a/tests/equationalproofs/pos/AppendAxiom.hs b/tests/equationalproofs/pos/AppendAxiom.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/AppendAxiom.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+{-@ LIQUID "--no-termination" @-}
+
+import Axiomatize
+
+data L a = N | C a (L a)
+
+
+{-@ axiomatize append @-}
+$(axiomatize
+  [d| append :: L a -> L a -> L a
+      append xs N = xs
+      append xs (C y ys) = xs
+    |])
+
+$(axiomatize
+      [d| appendCase xs ys = case xs of {N -> ys; C x xs -> C x (append xs ys)}
+    |])
+
+use_axiomN, use_axiomCaseN :: L a -> Proof
+use_axiomN xs = axiom_append_N xs
+use_axiomCaseN = axiom_appendCase_xs_is_N
+
+use_axiomC, use_axiomCaseC :: L a -> a -> L a -> Proof
+use_axiomC = axiom_append_C
+use_axiomCaseC = axiom_appendCase_xs_is_C
diff --git a/tests/equationalproofs/pos/AppendVerbose.hs b/tests/equationalproofs/pos/AppendVerbose.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/AppendVerbose.hs
@@ -0,0 +1,110 @@
+-- |   A first example in equalional reasoning.
+-- |  From the definition of append we should be able to
+-- |  semi-automatically prove the two axioms.
+
+-- | Note for soundness we need
+-- | totallity: all the cases should be covered
+-- | termination: we cannot have diverging things into proofs
+
+{-@ LIQUID "--totality" @-}
+
+module Append where
+
+import Language.Haskell.Liquid.Prelude
+
+data L a = N |  C a (L a) deriving (Eq)
+
+{-@ N :: {v:L a | llen v == 0 && v == N } @-}
+{-@ C :: x:a -> xs:L a -> {v:L a | llen v == llen xs + 1 && v == C x xs } @-}
+
+{-@ data L [llen] @-}
+{-@ invariant {v: L a | llen v >= 0} @-}
+
+{-@ measure llen :: L a -> Int @-}
+llen :: L a -> Int
+llen N = 0
+llen (C x xs) = 1 + llen xs
+
+
+append :: L a -> L a -> L a
+append N xs        = xs
+append (C y ys) xs = C y (append ys xs)
+
+
+-- | All the followin will be autocatically generated by the definition of append
+-- |  and a liquid annotation
+-- |
+-- |  axiomatize append
+-- |
+
+{-@ measure append :: L a -> L a -> L a @-}
+{-@ assume append :: xs:L a -> ys:L a -> {v:L a | v == append xs ys } @-}
+
+{-@ assume axiom_append_nil :: xs:L a -> {v:Proof | append N xs == xs} @-}
+axiom_append_nil :: L a -> Proof
+axiom_append_nil xs = Proof
+
+{-@ assume axiom_append_cons :: x:a -> xs: L a -> ys: L a
+          -> {v:Proof | append (C x xs) ys == C x (append xs ys) } @-}
+axiom_append_cons :: a -> L a -> L a -> Proof
+axiom_append_cons x xs ys = Proof
+
+
+-- | Proof library:
+
+data Proof = Proof
+
+
+{-@ toProof :: l:a -> r:{a|l = r} -> {v:Proof | l = r } @-}
+toProof :: a -> a -> Proof
+toProof x y = Proof
+
+
+{-@ (===) :: l:a -> r:a -> {v:Proof | l = r} -> {v:a | v = l } @-}
+(===) :: a -> a -> Proof -> a
+(===) x y _ = y
+
+-- | Proof 1: N is neutral element
+
+{-@ prop_nil :: xs:L a -> {v:Proof | (append xs N == xs) } @-}
+prop_nil     :: Eq a => L a -> Proof
+prop_nil N   =  axiom_append_nil N
+
+prop_nil (C x xs) = toProof e1 $ ((
+  e1 === e2) pr1
+     === e3) pr2
+   where
+   	e1  = append (C x xs) N
+   	pr1 = axiom_append_cons x xs N
+   	e2  = C x (append xs N)
+   	pr2 = prop_nil xs
+   	e3  = C x xs
+
+-- | Proof 2: append is associative
+
+
+
+{-@ prop_assoc :: xs:L a -> ys:L a -> zs:L a
+               -> {v:Proof | (append (append xs ys) zs == append xs (append ys zs))} @-}
+prop_assoc :: Eq a => L a -> L a -> L a -> Proof
+prop_assoc N ys zs =
+  toProof (append (append N ys) zs) $ ((
+    append (append N ys) zs === append ys zs)             (axiom_append_nil ys)
+                            === append N (append ys zs))  (axiom_append_nil (append ys zs))
+
+prop_assoc (C x xs) ys zs =
+  toProof e1 $ ((((
+   e1  === e2) pr1
+       === e3) pr2
+       === e4) pr3
+       === e5) pr4
+  where
+    e1  = append (append (C x xs) ys) zs
+    pr1 = axiom_append_cons x xs ys
+    e2  = append (C x (append xs ys)) zs
+    pr2 = axiom_append_cons x (append xs ys) zs
+    e3  = C x (append (append xs ys) zs)
+    pr3 = prop_assoc xs ys zs
+    e4  = C x (append xs (append ys zs))
+    pr4 = axiom_append_cons x xs (append ys zs)
+    e5  = append (C x xs) (append ys zs)
diff --git a/tests/equationalproofs/pos/Arrow.hs b/tests/equationalproofs/pos/Arrow.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/Arrow.hs
@@ -0,0 +1,3 @@
+module Arrow where
+
+data Arrow a b = Arr {runFun :: a -> b}
diff --git a/tests/equationalproofs/pos/Axiomatize.hs b/tests/equationalproofs/pos/Axiomatize.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/Axiomatize.hs
@@ -0,0 +1,136 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE QuasiQuotes     #-}
+
+module Axiomatize where
+
+import Language.Haskell.TH
+import Language.Haskell.TH.Quote
+import Language.Haskell.TH.Syntax
+
+import Debug.Trace
+
+import Control.Applicative
+import Data.List ((\\))
+import Data.Maybe (fromMaybe)
+
+data Proof = Proof
+
+
+{-@ auto :: Int -> b:{v:Bool |Prop v} -> Proof @-}
+auto :: Int -> Bool -> Proof
+auto _ _ = Proof
+
+
+{-@ rewrite :: Int -> b:{v:Bool |Prop v} -> Proof @-}
+rewrite :: Int -> Bool -> Proof
+rewrite _ _ = Proof
+
+{-@ cases :: Int -> b:{v:Bool |Prop v} -> Proof @-}
+cases :: Int -> Bool -> Proof
+cases _ _ = Proof
+
+
+axiomatize :: Q [Dec] -> Q [Dec]
+axiomatize q = do d <- q
+                  let vts = [(x, t) | FunD x _ <- d, SigD y t <- d, x == y ]
+                  ds <- mapM (axiomatizeOne vts) d
+                  return $ concat ds
+
+axiomatizeOne :: [(Name, Type)] -> Dec -> Q [Dec]
+axiomatizeOne env f@(FunD name cs)
+  = do axioms <- makeAxioms (lookup name env) name cs
+       return $ f:axioms
+axiomatizeOne _ (SigD _ _)
+  = return []
+axiomatizeOne _ d
+  = error $ "axiomatizeOne: Cannot axiomatize" ++ show d
+
+makeAxioms :: Maybe Type -> Name -> [Clause] -> Q [Dec]
+makeAxioms t f cs = concat <$> mapM go cs
+  where
+    go :: Clause -> Q [Dec]
+    go (Clause ps (NormalB (CaseE e ms)) []) = mapM (makeAxiomMatch f ps e) ms
+    go (Clause ps (NormalB _) [])            = makeAxiomPattern t f ps
+    go d = error $ "makeAxioms: Cannot axiomatize\n" ++ show d
+
+
+
+makeAxiomPattern :: Maybe Type -> Name -> [Pat] -> Q [Dec]
+makeAxiomPattern t g ps
+  = do ifs <- mapM reify (fst <$> ds)
+       ff <- makeFun f xs <$> axiom_body
+       ft <- makeSigT t f ps
+       return $ [ff] ++ ft
+  where
+    f = mkName $ makeNamePattern g (fst <$> ds)
+    ds = [(n, dps) |  ConP n dps <- ps]
+    xs = [x | VarP x <- (ps ++ concat (snd <$> ds))]
+
+makeSigT Nothing _ _
+  = return []
+makeSigT (Just t) f ps
+  = do r <- [t|Proof|]
+       ifs <- mapM reify (fst . snd <$> ds)
+       let ts2 = concat $ zipWith makePTys ds ifs
+       return [SigD f $ mkUnivArrow (as, ts1 ++ ts2, r)]
+  where
+    (as, ts, _) = bkUnivFun t
+    ts1 = [t | (t, VarP _) <- zip ts ps]
+    ds  = [(t, (n, dps)) |  (t, ConP n dps) <- zip ts ps]
+
+makePTys :: (Type, (Name, [Pat])) -> Info -> [Type]
+makePTys (tr, (n, dps)) (DataConI m t _ _) | n == m
+  = (applySub θ <$> [t | (t, VarP _) <- zip ts dps])
+  where (as, ts, r) = bkUnivFun t
+        θ = unify r tr
+makePTys _ _ = error "makePTys: on invalid arguments"
+
+
+unify (VarT n) t = [(n,t)]
+unify t (VarT n) = [(n,t)]
+unify (AppT t1 t2) (AppT t1' t2') = unify t1 t1' ++ unify t2 t2'
+unify (ForallT _ _ t1) t2 = unify t1 t2
+unify t1 (ForallT _ _ t2) = unify t1 t2
+unify _ _  = []
+
+applySub :: [(Name, Type)] -> Type -> Type
+applySub θ t@(VarT v) = fromMaybe t (lookup v θ)
+applySub θ (AppT t1 t2) = AppT (applySub θ t1) (applySub θ t2)
+applySub θ (ForallT _ _ _) = error "applySub: TODO"
+applySub θ t = t
+
+
+bkUnivFun = go [] []
+  where
+    go as xs (ForallT vs _ t)   = go (as ++ vs) xs t
+    go as xs (AppT (AppT ArrowT tx) t) = go as (tx:xs) t
+    go as xs t                  = (as, reverse xs, t)
+
+mkUnivArrow (as, ts, r) = ForallT as [] $ mkArrow ts r
+  where
+    mkArrow []     r = r
+    mkArrow (t:ts) r = AppT (AppT ArrowT t) $ mkArrow ts r
+
+makeAxiomMatch :: Name -> [Pat] -> Exp -> Match -> Q Dec
+makeAxiomMatch g ps (VarE x) (Match (ConP dc dps) bd decs)
+  = makeFun f xs <$> axiom_body
+  where f  = mkName $ makeName g x dc
+        xs = [p | VarP p <- ps ++ dps] \\ [x]
+
+makeFun :: Name -> [Name] -> Exp -> Dec
+makeFun f xs bd = FunD f [Clause (VarP <$> xs) (NormalB bd) []]
+
+axiom_body :: Q Exp
+axiom_body = [|Proof|]
+
+sep = "_"
+mkSep :: [String] -> String
+mkSep []  = []
+mkSep [x] = x
+mkSep (x:xs) = x ++ sep ++ mkSep xs
+
+eq  = "is"
+makeName fname x dc
+  = mkSep ["axiom", nameBase fname, nameBase x, eq, nameBase dc]
+
+makeNamePattern fname dcs = mkSep $ ["axiom", nameBase fname] ++ (nameBase <$> dcs)
diff --git a/tests/equationalproofs/pos/ConcatMap.hs b/tests/equationalproofs/pos/ConcatMap.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/ConcatMap.hs
@@ -0,0 +1,98 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--higherorder"     @-}
+{- LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+
+module ConcatMap where
+
+import Axiomatize
+import Equational 
+import Prelude hiding (map, concatMap, concat)
+
+data L a = N |  C a (L a)
+
+instance Eq a => Eq (L a) where
+  N == N                 = True
+  (C x xs) == (C x' xs') = x == x' && xs == xs'
+
+{-@ axiomatize append @-}
+$(axiomatize
+  [d| append :: L a -> L a -> L a 
+      append N ys        = ys 
+      append (C x xs) ys = C x (append xs ys)
+    |])
+
+{-@ axiomatize map @-}
+$(axiomatize
+  [d| map :: (a -> b) -> L a -> L b
+      map f N        = N
+      map f (C x xs) = f x `C` map f xs 
+    |])
+
+{-@ axiomatize concatMap @-}
+$(axiomatize
+  [d| concatMap :: (a -> L b) -> L a -> L b
+      concatMap f N        = N 
+      concatMap f (C x xs) = append (f x) (concatMap f xs)
+    |])
+
+
+{-@ axiomatize concatt @-}
+
+$(axiomatize
+  [d| concatt :: L (L a) -> L a 
+      concatt N        = N 
+      concatt (C x xs) = append x (concatt xs)
+     |])
+
+
+--   "concat/map" forall f xs . concat $ map f xs = concatMap f xs
+
+{-@ prop_concatMap :: f:(a -> L (L a)) -> xs:L a
+                   -> {v:Proof | (concatt (map f xs) == concatMap f xs) }  @-}
+
+prop_concatMap :: Eq a => (a -> L (L a)) -> L a -> Proof  
+prop_concatMap f xs
+   = cases 2 (concatt (map f xs) == concatMap f xs)
+
+{- 
+prop_concatMap f (C x xs)
+   = auto 1 (concatt (map f (C x xs)) == concatMap f (C x xs))
+-} 
+-- prop_concatMap f N
+--    = auto 1 (concatt (map f N) == concatMap f N)
+--   = refl e1 `by` pr1 `by` pr2 `by` pr3 
+{- 
+  where
+    e1  = concatt (map f N)
+    pr1 = axiom_map_N f
+    e2  = concatt N
+    pr2 = axiom_concatt_N
+    e3  = N
+    pr3 = axiom_concatMap_N f 
+    e4  = concatMap f N
+-}
+
+-- prop_concatMap f (C x xs) 
+--   = auto 2 (concatt (map f (C x xs)) == concatMap f (C x xs))
+{-
+  = refl e1 `by` pr1 `by` pr2 `by` pr3 `by` pr4 
+  where 
+    e1  = concatt (map f (C x xs)) 
+    pr1 = axiom_concatt_C (f x) (map f xs)
+    pr2 = axiom_concatMap_C f x xs 
+    pr3 = axiom_map_C f x xs 
+    pr4 = prop_concatMap f xs  
+-}
+
+{-@ data L [llen] @-}
+{-@ invariant {v: L a | llen v >= 0} @-}
+
+{-@ measure llen @-}
+llen          :: L a -> Int
+llen N        = 0
+llen (C x xs) = 1 + llen xs
diff --git a/tests/equationalproofs/pos/Equational.hs b/tests/equationalproofs/pos/Equational.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/Equational.hs
@@ -0,0 +1,35 @@
+module Equational where
+
+
+import Language.Haskell.Liquid.Prelude
+import Axiomatize
+
+
+{-@ toProof :: l:a -> r:{a | l == r} -> {v:Proof | l == r } @-}
+toProof :: a -> a -> Proof
+toProof x y = Proof
+
+
+{-@ (===) :: l:a -> r:a -> {v:Proof | l = r} -> {v:a | v = l } @-}
+(===) :: a -> a -> Proof -> a
+(===) x y _ = y
+
+
+
+{-@ type Equal X Y = {v:Proof | X == Y} @-}
+
+{-@ bound chain @-}
+chain :: (Proof -> Bool) -> (Proof -> Bool) -> (Proof -> Bool)
+      -> Proof -> Proof -> Proof -> Bool
+chain p q r = \v1 v2 v3 -> p v1 ==> q v2 ==> r v3
+
+{-@  by :: forall <p :: Proof -> Prop, q :: Proof -> Prop, r :: Proof -> Prop>.
+                 {vp::Proof<p> |- Proof<q> <: Proof<r> }
+                 Proof<p> -> Proof<q> -> Proof<r>
+@-}
+by :: Proof -> Proof -> Proof
+by _ r = r
+
+{-@ refl :: x:a -> Equal x x @-}
+refl :: a -> Proof
+refl x = Proof
diff --git a/tests/equationalproofs/pos/MapAppend.hs b/tests/equationalproofs/pos/MapAppend.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/MapAppend.hs
@@ -0,0 +1,79 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+
+module Append where
+
+import Axiomatize
+import Equational 
+import Prelude hiding (map)
+
+data L a = N |  C a (L a)
+
+instance Eq a => Eq (L a) where
+  N == N                 = True
+  (C x xs) == (C x' xs') = x == x' && xs == xs'
+
+{-@ axiomatize map @-}
+$(axiomatize
+  [d| map :: (a -> b) -> L a -> L b
+      map f N        = N
+      map f (C x xs) = C (f x) (map f xs) 
+    |])
+
+
+{-@ axiomatize append @-}
+$(axiomatize
+  [d| append :: L a -> L a -> L a 
+      append N ys        = ys 
+      append (C x xs) ys = C x (append xs ys)
+    |])
+
+
+
+--   "map/append" forall f xs ys. map f (xs ++ ys) = map f xs ++ map f ys
+{-@ prop_map_append ::  f:(a -> a) -> xs:L a -> ys:L a 
+                    -> {v:Proof | map f (append xs ys) == append (map f xs) (map f ys) }
+  @-}
+prop_map_append :: Eq a => (a -> a) -> L a -> L a -> Proof
+-- prop_map_append f N ys = auto 2 (map f (N `append` ys) == map f N `append` map f ys) 
+-- prop_map_append f N ys = auto 2 (map f (N `append` ys) == map f N `append` map f ys) 
+prop_map_append f xs ys = cases 2 (map f (xs `append` ys) == map f xs `append` map f ys) 
+
+{- Generated axioms: 
+1. axiom_append_N (map f ys)
+2. axiom_append_N ys 
+3. axiom_map_N f 
+-}  
+
+{-  
+prop_map_append f (C x xs) ys = 
+  auto 2  (map f (append (C x xs) ys) == append (map f (C x xs)) (map f ys))
+  -- refl (append (map f (C x xs)) (map f ys))
+  --   `by` pr1 `by` pr2 `by` pr3 `by` pr4 `by` pr5 
+    where
+      e1  = append (map f (C x xs)) (map f ys)
+      pr1 = axiom_map_C f x xs
+      e2  = append (C (f x) (map f xs)) (map f ys)
+      pr2 = axiom_append_C  (map f ys) (f x) (map f xs)
+      e3  = C (f x) (append (map f xs) (map f ys))
+      pr3 = prop_map_append f xs ys
+      e4 = C (f x) (map f (append xs ys))
+      pr4 = axiom_map_C f x (append xs ys)
+      e5  = map f (C x (append xs ys))
+      pr5 = axiom_append_C ys x xs
+      e6  = map f (append (C x xs) ys)
+-}
+
+
+{-@ data L [llen] @-}
+{-@ invariant {v: L a | llen v >= 0} @-}
+
+{-@ measure llen @-}
+llen          :: L a -> Int
+llen N        = 0
+llen (C x xs) = 1 + llen xs
diff --git a/tests/equationalproofs/pos/MonadicLaws.hs b/tests/equationalproofs/pos/MonadicLaws.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/MonadicLaws.hs
@@ -0,0 +1,88 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+{-@ LIQUID "--higherorder"      @-}
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+module Append where
+
+import Axiomatize
+import Equational
+import Prelude hiding (return, (>>=))
+
+
+data L a = N |  C a (L a)
+
+-- | Definition of the list monad
+
+{-@ axiomatize return @-}
+$(axiomatize
+  [d| return :: a -> L a
+      return x = C x N
+    |])
+
+
+{-@ axiomatize append @-}
+$(axiomatize
+  [d| append :: L a -> L a -> L a
+      append N ys        = ys
+      append (C x xs) ys = C x (append xs ys)
+    |])
+
+{-@ axiomatize bind @-}
+$(axiomatize
+  [d| bind :: L a -> (a -> L a) -> L a
+      bind N        f = N
+      bind (C x xs) f = append (f x) (xs `bind` f)
+    |])
+
+
+-- NV TODO:
+-- 2. check why failure to prove takes so long
+
+-- | Left identity: return a >>= f ≡ f a
+
+prop_left_identity :: Eq a => a -> (a -> L a) -> Proof
+{-@ prop_left_identity :: x:a -> f:(a -> L a)
+                       -> {v:Proof | bind (return x) f == f x} @-}
+prop_left_identity x f = auto 2 (bind (return x) f == f x)
+{- 
+  where
+    e1  = bind (return x) f
+    pr1 = axiom_return x
+    e2  = bind (C x N) f
+    pr2 = axiom_bind_C f x N
+    e3  = append (f x) (bind N f)
+    pr3 = axiom_bind_N f
+    e4  = append (f x) N
+    pr4 = prop_app_nil (f x)
+    e5  = f x
+-}
+
+-- | Right Identity m >>= return ≡  m
+{-@ prop_right_identity :: Eq a => xs:L a -> {v:Proof | bind xs return == xs } @-}
+prop_right_identity :: Eq a => L a -> Proof
+prop_right_identity xs =  cases 2 (bind xs return == xs) 
+
+{-@ prop_app_nil :: ys:L a -> {v:Proof | append ys N == ys} @-}
+prop_app_nil :: (Eq a) => L a -> Proof
+prop_app_nil N        = auto 1 (append N N        == N     )
+prop_app_nil (C x xs) = auto 1 (append (C x xs) N == C x xs)
+
+
+-- | List definition
+
+
+instance Eq a => Eq (L a) where
+  N == N                 = True
+  (C x xs) == (C x' xs') = x == x' && xs == xs'
+
+{-@ data L [llen] @-}
+{-@ invariant {v: L a | llen v >= 0} @-}
+
+{-@ measure llen @-}
+llen :: L a -> Int
+llen N = 0
+llen (C x xs) = 1 + llen xs
diff --git a/tests/equationalproofs/pos/MonadicLawsMaybe.hs b/tests/equationalproofs/pos/MonadicLawsMaybe.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/MonadicLawsMaybe.hs
@@ -0,0 +1,79 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+{-@ LIQUID "--higherorder"      @-}
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+module Append where
+
+import Axiomatize
+import Equational
+import Prelude hiding (Monad(..), Maybe (..))
+
+
+data Maybe a = Nothing | Just a deriving (Eq)
+
+-- | Definition of the list monad
+
+{-@ axiomatize return @-}
+$(axiomatize
+  [d| return :: a -> Maybe a
+      return x = Just x 
+    |])
+
+{-@ axiomatize bind @-}
+$(axiomatize
+  [d| bind :: Maybe a -> (a -> Maybe b) -> Maybe b
+      bind Nothing  f = Nothing
+      bind (Just x) f = f x 
+    |])
+
+-- | Left identity: return a >>= f ≡ f a
+
+{-@ prop_left_identity :: x:a -> f:(a -> Maybe a) -> {v:Proof | bind (return x) f == f x} @-}
+prop_left_identity :: Eq a => a -> (a -> Maybe a) -> Proof
+prop_left_identity x  f = rewrite 3 (bind (return x) f == f x)
+
+{- 
+prop_left_identity x  f = pr1 `by` pr2 
+  where
+    e1  = bind (return x) f 
+    pr1 = axiom_return x 
+    e2  = bind (Just x) f 
+    pr2 = axiom_bind_Just f x 
+    e3  = f x   
+-}
+
+
+-- | Right Identity m >>= return ≡  m
+{-@ prop_right_identity :: m:Maybe a -> {v:Proof | bind m return == m } @-}
+prop_right_identity :: Eq a => Maybe a -> Proof
+prop_right_identity Nothing  = rewrite 0 (bind Nothing  return == Nothing) 
+prop_right_identity (Just x) = rewrite 0 (bind (Just x) return == Just x)  
+
+{- 
+prop_right_identity Nothing = pr1 
+  where
+    e1  = bind Nothing return
+    pr1 = axiom_bind_Nothing return
+    e2  = Nothing
+
+prop_right_identity (Just x) = pr1 `by` pr2 
+  where
+    e1  = bind (Just x) return 
+    pr1 = axiom_bind_Just return x 
+    e2  = return x 
+    pr2 = axiom_return x 
+    e3  = Just x 
+-}
+
+
+-- | Left Associativity: (m >>= f) >>= g ≡  m >>= (\x -> f x >>= g)
+
+prop_left_associativity :: Eq a => Maybe a -> (a -> Maybe a) -> (a -> Maybe a) -> Proof 
+prop_left_associativity m f g = Proof
+
+
+
diff --git a/tests/equationalproofs/pos/MonadicLawsMaybeAssoc.hs b/tests/equationalproofs/pos/MonadicLawsMaybeAssoc.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/pos/MonadicLawsMaybeAssoc.hs
@@ -0,0 +1,57 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+{-@ LIQUID "--higherorder"      @-}
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+module Append where
+
+import Axiomatize
+import Equational
+import Prelude hiding (Monad(..), Maybe (..))
+
+
+data Maybe a = Nothing | Just a deriving (Eq)
+
+-- | Definition of the list monad
+
+{-@ axiomatize return @-}
+$(axiomatize
+  [d| return :: a -> Maybe a
+      return x = Just x 
+    |])
+
+{-@ axiomatize bind @-}
+$(axiomatize
+  [d| bind :: Maybe a -> (a -> Maybe b) -> Maybe b
+      bind Nothing  f = Nothing
+      bind (Just x) f = f x 
+    |])
+
+
+-- HERE 
+
+-- | Left Associativity: (m >>= f) >>= g ≡  m >>= (\x -> f x >>= g)
+
+{- prop_left_associativity :: m:Maybe a -> f:(a -> Maybe a) -> g:(a -> Maybe a) 
+                            -> {v: Proof |  bind (bind m f) g == bind m (\x:a -> (bind (f x) g ))} @-}
+prop_left_associativity :: Eq a => Maybe a -> (a -> Maybe a) -> (a -> Maybe a) ->  Proof 
+prop_left_associativity Nothing f g = pr1 `by` pr2 `by` pr3 
+  where
+  	h   =  \x -> (bind (f x) g)
+  	e1  = bind (bind Nothing f) g 
+  	pr1 = axiom_bind_Nothing f
+  	e2  = bind Nothing g 
+  	pr2 = axiom_bind_Nothing g 
+  	e3  = Nothing 
+  	pr3 = axiom_bind_Nothing h 
+  	e4  = bind Nothing h 
+
+{- prop_left_associativity :: m:Maybe a -> f:(a -> Maybe a) -> g:(a -> Maybe a) 
+                            -> {v: Proof |  bind (bind m f) g == bind m (\x:a -> (bind (f x) g ))} @-}
+prop_left_associativity (Just x) f g = undefined --  bind (bind m f) g == bind m (\x -> (bind (f x) g ))
+
+
+
diff --git a/tests/equationalproofs/todo/Helper.hs b/tests/equationalproofs/todo/Helper.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/todo/Helper.hs
@@ -0,0 +1,72 @@
+
+-- | Proving ackermann properties from
+-- | http://www.cs.yorku.ca/~gt/papers/Ackermann-function.pdf
+
+{-@ LIQUID "--higherorder"   @-}
+{-@ LIQUID "--autoproofs"    @-}
+{-@ LIQUID "--totality"      @-}
+{-@ LIQUID "--maxparams=10"  @-}
+{-@ LIQUID "--higherorderqs" @-}
+{-@ LIQUID "--eliminate"     @-}
+
+
+module Helper (
+
+  gen_increasing, gen_increasing2
+
+  , abstract
+
+  ) where
+
+import Proves
+
+-- | Function abstractio: Can I prove this?
+
+{-@ assume abstract :: f:(a -> b) -> g:(a -> b) -> (x:a -> {v:Proof | f x == g x })
+             -> {v:Proof | f == g } @-}
+abstract :: (a -> b) -> (a -> b) -> (a -> Proof) -> Proof
+abstract _ _ _ = simpleProof
+
+
+
+
+-- | forall f :: a -> a
+-- |   if    forall x:Nat.   f x < f (x+1)
+-- |   then  forall x,y:Nat.  x < y => f x < f y
+
+
+gen_increasing :: (Int -> Int) -> (Int -> Proof) -> (Int -> Int -> Proof)
+
+
+
+{-@ gen_increasing :: f:(Nat -> Int)
+                   -> (z:Nat -> {v:Proof | f z < f (z+1) })
+                   ->  x:Nat -> y:{Nat | x < y } -> {v:Proof | f x < f y } / [y] @-}
+gen_increasing f thm x y
+
+  | x + 1 == y
+  = proof $
+      f y ==! f (x + 1)
+           >! f x       ?  thm x
+
+  | x + 1 < y
+  = proof $
+      f x  <! f (y-1)   ?   gen_increasing f thm x (y-1)
+           <! f y       ?   thm (y-1)
+
+
+gen_increasing2 :: (Int -> a -> Int) -> (a -> Int -> Proof) -> (a -> Int -> Int -> Proof)
+{-@ gen_increasing2 :: f:(Nat -> a -> Int)
+                    -> (w:a -> z:Nat -> {v:Proof | f z w < f (z+1) w })
+                    ->  c:a -> x:Nat -> y:{Nat | x < y } -> {v:Proof | f x c < f y c } / [y] @-}
+gen_increasing2 f thm c x y
+  | x + 1 == y
+  = proof $
+      f y c ==! f (x + 1) c
+             >! f x c        ? thm c x
+
+  | x + 1 < y
+  = proof $
+      f x c <! f (y-1) c    ? gen_increasing2 f thm c x (y-1)
+            <! f y c        ? thm c (y-1)
+
diff --git a/tests/equationalproofs/todo/MapFusion.hs b/tests/equationalproofs/todo/MapFusion.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/todo/MapFusion.hs
@@ -0,0 +1,90 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+-- |   A first example in equalional reasoning.
+-- |  From the definition of append we should be able to
+-- |  semi-automatically prove the two axioms.
+
+-- | Note for soundness we need
+-- | totallity: all the cases should be covered
+-- | termination: we cannot have diverging things into proofs
+
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+module Append where
+
+import Axiomatize
+import Equational 
+import Prelude hiding (map)
+
+data L a = N |  C a (L a)
+
+instance Eq a => Eq (L a) where
+  N == N                 = True
+  (C x xs) == (C x' xs') = x == x' && xs == xs'
+
+{-@ axiomatize map @-}
+
+
+$(axiomatize
+  [d| map :: (a -> b) -> L a -> L b
+      map f N        = N
+      map f (C x xs) = f x `C` map f xs 
+    |])
+
+-- axioms: 
+-- axiom_map_N :: forall f. map f N == N
+-- axiom_map_C :: forall f x xs. map f (C x xs) == C (f x) (map f xs) 
+
+{-@ axiomatize compose @-}
+
+$(axiomatize
+  [d| compose :: (b -> c) ->(a -> b) -> (a -> c)
+      compose f g x = f (g x) 
+    |])
+
+{-@ prop_fusion :: f:(a -> a) -> g:(a -> a) -> xs:L a
+                -> {v:Proof | map f (map g xs) ==  map (compose f g) xs }  @-}
+prop_fusion     :: Eq a => (a -> a) -> (a -> a) -> L a -> Proof
+
+prop_fusion f g N = 
+--   refl e1 `by` pr1 `by` pr2 `by` pr3
+    auto 2 (map f (map g N)  ==  map (compose f g) N)
+{-
+  where
+    e1  = map f (map g N)
+    pr1 = axiom_map_N g
+    e2  = map f N
+    pr2 = axiom_map_N f
+    e3  = N
+    pr3 = axiom_map_N (compose f g)
+    e4  = map (compose f g) N
+-}
+
+prop_fusion f g (C x xs) = 
+   auto 2 (map f (map g (C x xs)) == map (compose f g) (C x xs))
+--    refl e1 `by` pr1 `by` pr2 `by` pr3 `by` pr4 `by` pr5
+{-
+  where
+    e1 = map f (map g (C x xs))
+    pr1 = axiom_map_C g x xs
+    e2 = map f (C (g x) (map g xs))
+    pr2 = axiom_map_C f (g x) (map g xs)
+    e3 = C (f (g x)) (map f (map g xs))
+    pr3 = prop_fusion f g xs
+    e4 = C (f (g x)) (map (compose f g) xs)
+    pr4 = axiom_compose f g x
+    e5 = C ((compose f g) x) (map (compose f g) xs)
+    pr5 = axiom_map_C (compose f g) x xs
+    e6 = map (compose f g) (C x xs)
+-}
+
+{-@ data L [llen] @-}
+{-@ invariant {v: L a | llen v >= 0} @-}
+
+{-@ measure llen @-}
+llen          :: L a -> Int
+llen N        = 0
+llen (C x xs) = 1 + llen xs
diff --git a/tests/equationalproofs/todo/MonadicLawsAssoc.hs b/tests/equationalproofs/todo/MonadicLawsAssoc.hs
new file mode 100644
--- /dev/null
+++ b/tests/equationalproofs/todo/MonadicLawsAssoc.hs
@@ -0,0 +1,122 @@
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+{-@ LIQUID "--higherorder"      @-}
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+module Append where
+
+import Axiomatize
+import Equational
+import Prelude hiding (return, (>>=))
+
+
+data L a = N |  C a (L a)
+
+-- | Definition of the list monad
+
+{-@ axiomatize return @-}
+$(axiomatize
+  [d| return :: a -> L a
+      return x = C x N
+    |])
+
+
+{-@ axiomatize append @-}
+$(axiomatize
+  [d| append :: L a -> L a -> L a
+      append N ys        = ys
+      append (C x xs) ys = C x (append xs ys)
+    |])
+
+{-@ axiomatize bind @-}
+$(axiomatize
+  [d| bind :: L a -> (a -> L a) -> L a
+      bind N        f = N
+      bind (C x xs) f = append (f x) (xs `bind` f)
+    |])
+
+-- | Left Associativity: (m >>= f) >>= g ≡  m >>= (\x -> f x >>= g)
+
+
+helper :: Eq a => a -> L a -> (a -> L a) -> (a -> L a) -> Proof
+{-@ helper ::  x:a -> xs:L a -> f:(a -> L a) -> g:(a -> L a) 
+            ->   {v: Proof| bind (append (f x) (bind N f)) g == append (bind (f x) g) (bind (bind N f) g)} @-}
+helper x xs f g 
+--   = auto 2 (bind (append fx N) g == bind fx  g )
+--     = refl (bind (append (f x) (bind N f)) g) `by` pr1 `by` pr2 `by` pr3 `by` pr4 `by` pr5 
+     = auto 2 (bind (append (f x) N) g ==  bind (f x) g ) 
+  where 
+{- 
+    e1  = bind (append (f x) (bind N f)) g
+    pr1 = axiom_bind_N f 
+    e2  = bind (append (f x) N) g
+    pr2 = prop_app_nil (f x)
+    e3  = bind (f x) g 
+    pr3 = prop_app_nil (bind (f x)  g)
+    e4  = append (bind (f x) g) N
+    pr4 = axiom_bind_N f     
+    e5  = append (bind (f x) g) (bind N f)
+    pr5 = axiom_bind_N g   
+    e6  = append (bind (f x) g) (bind (bind N f) g)
+
+-}
+
+
+helper x xs f g 
+  = undefined -- auto 2 ((append (f x) (xs `bind` f)) `bind` g ==  append (f x `bind` g) ((xs `bind` f) `bind` g)) 
+
+
+{-@ prop_app_nil :: ys:L a -> {v:Proof | append ys N == ys} @-}
+prop_app_nil :: (Eq a) => L a -> Proof
+prop_app_nil N        = auto 1 (append N N        == N     )
+prop_app_nil (C x xs) = auto 1 (append (C x xs) N == C x xs)
+
+prop_left_assoc :: Eq a => L a -> (a -> L a) -> (a -> L a) -> Proof
+{-@ prop_left_assoc :: m: L a -> f:(a -> L a) -> g:(a -> L a) -> Proof @-}
+prop_left_assoc N f g 
+  = refl ((N `bind` f) `bind` g) `by` pr1 `by` pr2 `by` pr3 
+  where
+    e1  = (N `bind` f) `bind` g
+    pr1 = axiom_bind_N f 
+    e2  = N `bind` g
+    pr2 = axiom_bind_N g
+    e3  = N
+    pr3 = axiom_bind_N ((\x -> f x `bind` g))
+    e4  = N `bind` (\x -> f x `bind` g)
+
+
+prop_left_assoc (C x xs) f g 
+  = undefined -- refl ((C x xs `bind` f) `bind` g) 
+  where
+    e1  = (C x xs `bind` f) `bind` g
+
+    e2 = (append (f x) (xs `bind` f)) `bind` g 
+
+
+
+
+    ei =  append (f x `bind` g) ((xs `bind` f) `bind` g)
+    ej =  append ((\x -> f x `bind` g) x) ((xs `bind` f) `bind` g)
+
+
+
+    ek =  append ((\x -> f x `bind` g) x) (xs `bind` (\x -> f x `bind` g))
+    en =  C x xs `bind` (\x -> f x `bind` g)
+
+-- | List definition
+
+
+instance Eq a => Eq (L a) where
+  N == N                 = True
+  (C x xs) == (C x' xs') = x == x' && xs == xs'
+
+{-@ data L [llen] @-}
+{-@ invariant {v: L a | llen v >= 0} @-}
+
+{-@ measure llen @-}
+llen :: L a -> Int
+llen N = 0
+llen (C x xs) = 1 + llen xs
diff --git a/tests/error_messages/crash/TerminationExpr.hs b/tests/error_messages/crash/TerminationExpr.hs
new file mode 100644
--- /dev/null
+++ b/tests/error_messages/crash/TerminationExpr.hs
@@ -0,0 +1,8 @@
+module TerminationExpr where
+
+{-@ showSep :: _ -> xs:_ -> _ / [len ys] @-} -- use xs as reducing param
+showSep :: String -> [String] -> String
+showSep sep []     = ""
+showSep sep [x]    = x
+showSep sep (x:xs) = x ++ sep ++ showSep sep xs
+
diff --git a/tests/error_messages/crash/TerminationExpr1.hs b/tests/error_messages/crash/TerminationExpr1.hs
new file mode 100644
--- /dev/null
+++ b/tests/error_messages/crash/TerminationExpr1.hs
@@ -0,0 +1,8 @@
+module TerminationExpr where
+
+{-@ showSep :: _ -> xs:_ -> _ / [xs] @-} -- use xs as reducing param
+showSep :: String -> [String] -> String
+showSep sep []     = ""
+showSep sep [x]    = x
+showSep sep (x:xs) = x ++ sep ++ showSep sep xs
+
diff --git a/tests/error_messages/pos/TerminationExpr.hs b/tests/error_messages/pos/TerminationExpr.hs
new file mode 100644
--- /dev/null
+++ b/tests/error_messages/pos/TerminationExpr.hs
@@ -0,0 +1,8 @@
+module TerminationExpr where
+
+{-@ showSep :: _ -> xs:_ -> _ / [len xs] @-} -- use xs as reducing param
+showSep :: String -> [String] -> String
+showSep sep []     = ""
+showSep sep [x]    = x
+showSep sep (x:xs) = x ++ sep ++ showSep sep xs
+
diff --git a/tests/gradual/neg/Gradual.hs b/tests/gradual/neg/Gradual.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/neg/Gradual.hs
@@ -0,0 +1,17 @@
+module Gradual where
+
+{-@ LIQUID "--gradual" @-}
+{-@ LIQUID "--eliminate=none" @-}
+
+{-@ unsafe :: {v:Int | ?? } -> Int  -> (Int, Int) @-}
+unsafe :: Int -> Int -> (Int, Int)
+unsafe _ x = (bar1 x, bar2 x)
+
+
+{-@ bar1 :: {v:Int | v < 0} -> Int @-}
+bar1 :: Int -> Int 
+bar1 x = x 
+
+{-@ bar2 :: {v:Int | v = 0} -> Int @-}
+bar2 :: Int -> Int 
+bar2 x = x
diff --git a/tests/gradual/neg/Interpretations.hs b/tests/gradual/neg/Interpretations.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/neg/Interpretations.hs
@@ -0,0 +1,19 @@
+-- | Sec 4 from Gradual Refinement Types 
+
+module Interpretations where
+{-@ LIQUID "--gradual" @-}
+{-@ LIQUID "--eliminate=none" @-}
+
+{-@ g :: Int -> {v:Int | v == 0 && ?? } -> Int @-} 
+g :: Int -> Int -> Int 
+g = div 
+
+
+{-@ h :: {v:Int | ?? } -> {v:Int | ?? } -> {v:Int | v == 0 && ?? } -> Int @-} 
+h :: Int -> Int -> Int -> Int 
+h x y = div (x + y)
+
+
+{-@ f :: {v:Int | ?? } -> Int -> Int @-} 
+f :: Int -> Int -> Int 
+f = div
diff --git a/tests/gradual/neg/Intro.hs b/tests/gradual/neg/Intro.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/neg/Intro.hs
@@ -0,0 +1,36 @@
+-- | Sec 1 from Gradual Refinement Types 
+
+module Intro where
+
+{-@ LIQUID "--gradual" @-}
+{-@ LIQUID "--eliminate=none" @-}
+
+
+checkPos :: Int -> Int 
+{-@ checkPos :: {v:Int | 0 < v} -> {v:Int | 0 < v} @-}
+checkPos x = x 
+
+{-@ check :: {v:Int | true } -> {v:Bool | true } -} 
+check :: Int -> Bool 
+check x = undefined 
+
+safe x = if check x then checkPos x else checkPos (-x) 
+
+
+a :: Int -> Bool 
+{-@ a :: {v:Int | v < 0} -> Bool @-}
+a = undefined
+
+
+b :: Int -> Int 
+{-@ b :: {v:Int | v < 10} -> Int @-}
+b = undefined
+
+
+{-@ g0 :: {v:Int | true } -> Int @-} 
+g0 :: Int -> Int 
+g0 x = if a x then 1 `div` x else b x 
+
+{-@ g1 :: {v:Int | 0 < v && ?? } -> Int @-} 
+g1 :: Int -> Int 
+g1 x = if a x then 1 `div` x else b x 
diff --git a/tests/gradual/pos/Discussion.hs b/tests/gradual/pos/Discussion.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/pos/Discussion.hs
@@ -0,0 +1,33 @@
+-- | Sec 9 from Gradual Refinement Types 
+
+module Discussion where
+{-@ LIQUID "--gradual" @-}
+{-@ LIQUID "--eliminate=none" @-}
+
+{-@ get :: {v:Int | 0 <= v } -> Int @-} 
+get :: Int -> Int 
+get = undefined 
+
+{-@ check0 :: x:Int -> {v:Bool | ?? } @-} 
+check0 :: Int -> Bool 
+check0 = undefined 
+safe0 x = if check0 x then get x else get (-x)
+
+
+{-@ check1 :: x:Int -> {v:Bool | (v => 0 <= x) && (not v => x < 0) } @-} 
+check1 :: Int -> Bool 
+check1 = undefined 
+
+safe1 x = if check1 x then get x else get (-x)
+
+
+{-@ assume qual :: x:Int -> {v:Bool | (not v) => (x <= 0)} @-}
+qual :: Int -> Bool 
+qual = undefined 
+
+{-@ assume check2 :: x:Int -> {v:Bool | (v => (0 <= x)) && ?? } @-} 
+check2 :: Int -> Bool 
+check2 = undefined 
+
+safe2 :: Int -> Int 
+safe2 x = if check2 x then get x else get (-x)
diff --git a/tests/gradual/pos/Dynamic.hs b/tests/gradual/pos/Dynamic.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/pos/Dynamic.hs
@@ -0,0 +1,14 @@
+-- | Sec 5 from Gradual Refinement Types 
+
+module Interpretations where
+{-@ LIQUID "--gradual" @-}
+{-@ LIQUID "--eliminate=none" @-}
+
+{-@ f :: {v:Int | 0 < v } -> Int @-} 
+f :: Int -> Int 
+f = undefined  
+
+
+{-@ g :: x:{Int | ?? } -> y:{Int | x <= y } -> Int @-} 
+g :: Int -> Int -> Int 
+g x y = f y + x 
diff --git a/tests/gradual/pos/Gradual.hs b/tests/gradual/pos/Gradual.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/pos/Gradual.hs
@@ -0,0 +1,20 @@
+module Gradual where
+
+{-@ LIQUID "--gradual"        @-}
+{-@ LIQUID "--savequery"      @-}
+
+{-@ safe :: {v:Int | ??  } -> Int @-}
+safe :: Int ->  Int
+safe x = if foo () then bar1 x else bar2 x
+
+{-@ foo :: () -> {v:Bool | true } @-} 
+foo :: () -> Bool 
+foo = undefined 
+
+{-@ bar1 :: {v:Int | v < 0 } -> Int @-}
+bar1 :: Int -> Int 
+bar1 x = x 
+
+{-@ bar2 :: {v:Int | v = 0} -> Int @-}
+bar2 :: Int -> Int 
+bar2 x = x
diff --git a/tests/gradual/pos/Interpretations.hs b/tests/gradual/pos/Interpretations.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/pos/Interpretations.hs
@@ -0,0 +1,19 @@
+-- | Sec 4 from Gradual Refinement Types 
+
+module Interpretations where
+{-@ LIQUID "--gradual"        @-}
+{-@ LIQUID "--savequery"      @-}
+{-@ LIQUID "--eliminate=none" @-}
+
+{-@ g :: Int -> {v:Int | ?? } -> Int @-} 
+g :: Int -> Int -> Int 
+g = div 
+
+
+{-@ h :: {v:Int | ?? } -> {v:Int | ?? } -> {v:Int |  ?? } -> Int @-} 
+h :: Int -> Int -> Int -> Int 
+h x y z = div (x + y) z
+
+{-@ f :: {v:Int | ?? } -> Int -> Int @-} 
+f :: Int -> Int -> Int 
+f = flip div
diff --git a/tests/gradual/pos/Intro.hs b/tests/gradual/pos/Intro.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/pos/Intro.hs
@@ -0,0 +1,36 @@
+-- | Sec 1 from Gradual Refinement Types 
+
+module Intro where
+
+{-@ LIQUID "--gradual"        @-}
+{-@ LIQUID "--savequery"      @-}
+
+
+checkPos :: Int -> Int 
+{-@ checkPos :: {v:Int | 0 < v} -> {v:Int | 0 < v} @-}
+checkPos x = x 
+
+{-@ check :: {v:Int | ?? } -> {v:Bool | ?? } @-} 
+check :: Int -> Bool 
+check x = undefined 
+
+safe x = if check x then checkPos x else checkPos (-x) 
+
+
+a :: Int -> Bool 
+{-@ a :: {v:Int | v < 0} -> Bool @-}
+a = undefined
+
+
+b :: Int -> Int 
+{-@ b :: {v:Int | v < 10} -> Int @-}
+b = undefined
+
+
+{-@ g0 :: {v:Int | ?? } -> Int @-} 
+g0 :: Int -> Int 
+g0 x = if a x then 1 `div` x else b x 
+
+{-@ g1 :: {v:Int | 0 < v && ?? } -> Int @-} 
+g1 :: Int -> Int 
+g1 x = if a (x-2) then 1 `div` x else b x 
diff --git a/tests/gradual/todo/Measures.hs b/tests/gradual/todo/Measures.hs
new file mode 100644
--- /dev/null
+++ b/tests/gradual/todo/Measures.hs
@@ -0,0 +1,12 @@
+-- | Sec 8 from Gradual Refinement Types 
+
+module Measures where
+{-@ LIQUID "--gradual" @-}
+{-@ LIQUID "--extensionality" @-}
+{-@ LIQUID "--eliminate=none" @-}
+{-@ LIQUID "--scrape-used-imports" @-}
+
+-- This does not work because I need the special locality treatment for measures
+{-@ f :: x:{v:[a] | ?? } -> {v:Int | ?? } -> a -> Bool @-}
+f :: Eq a => [a] -> Int -> a -> Bool  
+f xs i y= xs!!i == y 
diff --git a/tests/log/summary-develop.csv b/tests/log/summary-develop.csv
new file mode 100644
--- /dev/null
+++ b/tests/log/summary-develop.csv
@@ -0,0 +1,690 @@
+ (HEAD, origin/develop, develop) : 282e73b5d0aec4d7b9d4b650508fc02ec377ef0a
+Timestamp: 2016-05-06 17:22:05 -0700
+Epoch Timestamp: 1462580525
+--------------------------------------------------------------------------------
+test, time(s), result
+
+Tests/Unit/pos/zipW2.hs, 0.8046, True
+Tests/Unit/pos/zipW1.hs, 0.7420, True
+Tests/Unit/pos/zipW.hs, 0.7591, True
+Tests/Unit/pos/zipSO.hs, 0.8517, True
+Tests/Unit/pos/zipper000.hs, 0.9855, True
+Tests/Unit/pos/zipper0.hs, 1.2729, True
+Tests/Unit/pos/zipper.hs, 3.0113, True
+Tests/Unit/pos/wrap1.hs, 0.9779, True
+Tests/Unit/pos/wrap0.hs, 0.7580, True
+Tests/Unit/pos/Words1.hs, 0.6964, True
+Tests/Unit/pos/Words.hs, 0.6662, True
+Tests/Unit/pos/WBL0.hs, 1.8904, True
+Tests/Unit/pos/WBL.hs, 1.4032, True
+Tests/Unit/pos/vector2.hs, 1.3548, True
+Tests/Unit/pos/vector1b.hs, 1.0504, True
+Tests/Unit/pos/vector1a.hs, 1.0712, True
+Tests/Unit/pos/vector1.hs, 1.0077, True
+Tests/Unit/pos/vector00.hs, 0.7860, True
+Tests/Unit/pos/vector0.hs, 1.2047, True
+Tests/Unit/pos/vecloop.hs, 0.9001, True
+Tests/Unit/pos/Variance.hs, 0.6916, True
+Tests/Unit/pos/unusedtyvars.hs, 0.6755, True
+Tests/Unit/pos/tyvar.hs, 0.6821, True
+Tests/Unit/pos/TypeAlias.hs, 0.6753, True
+Tests/Unit/pos/tyfam0.hs, 0.7293, True
+Tests/Unit/pos/tyExpr.hs, 0.6789, True
+Tests/Unit/pos/tyclass0.hs, 0.6572, True
+Tests/Unit/pos/tupparse.hs, 0.7410, True
+Tests/Unit/pos/tup0.hs, 0.6751, True
+Tests/Unit/pos/transTAG.hs, 1.6077, True
+Tests/Unit/pos/transpose.hs, 1.8173, True
+Tests/Unit/pos/trans.hs, 1.0137, True
+Tests/Unit/pos/ToyMVar.hs, 0.9254, True
+Tests/Unit/pos/TopLevel.hs, 0.7259, True
+Tests/Unit/pos/top0.hs, 0.7734, True
+Tests/Unit/pos/TokenType.hs, 0.6585, True
+Tests/Unit/pos/testRec.hs, 0.7121, True
+Tests/Unit/pos/Test761.hs, 0.7347, True
+Tests/Unit/pos/test2.hs, 0.7204, True
+Tests/Unit/pos/test1.hs, 0.7415, True
+Tests/Unit/pos/test00c.hs, 0.8976, True
+Tests/Unit/pos/test00b.hs, 0.7311, True
+Tests/Unit/pos/test000.hs, 0.7302, True
+Tests/Unit/pos/test00.old.hs, 0.7125, True
+Tests/Unit/pos/test00.hs, 0.7197, True
+Tests/Unit/pos/test00-int.hs, 0.7304, True
+Tests/Unit/pos/test0.hs, 0.7181, True
+Tests/Unit/pos/TerminationNum0.hs, 0.6990, True
+Tests/Unit/pos/TerminationNum.hs, 0.6751, True
+Tests/Unit/pos/Termination.lhs, 1.2537, True
+Tests/Unit/pos/term0.hs, 0.8020, True
+Tests/Unit/pos/Term.hs, 0.7211, True
+Tests/Unit/pos/take.hs, 1.0053, True
+Tests/Unit/pos/tagBinder.hs, 0.6522, True
+Tests/Unit/pos/T598.hs, 0.8593, True
+Tests/Unit/pos/T595a.hs, 0.6777, True
+Tests/Unit/pos/T595.hs, 0.7500, True
+Tests/Unit/pos/T531.hs, 0.6583, True
+Tests/Unit/pos/Sum.hs, 0.7563, True
+Tests/Unit/pos/StructRec.hs, 0.6970, True
+Tests/Unit/pos/Strings.hs, 0.7272, True
+Tests/Unit/pos/StringLit.hs, 0.6739, True
+Tests/Unit/pos/string00.hs, 0.7237, True
+Tests/Unit/pos/StrictPair1.hs, 0.9248, True
+Tests/Unit/pos/StrictPair0.hs, 0.7165, True
+Tests/Unit/pos/StreamInvariants.hs, 0.6783, True
+Tests/Unit/pos/stateInvarint.hs, 0.8960, True
+Tests/Unit/pos/StateF00.hs, 0.7136, True
+Tests/Unit/pos/StateConstraints00.hs, 0.6941, True
+Tests/Unit/pos/StateConstraints0.hs, 8.5580, True
+Tests/Unit/pos/StateConstraints.hs, 4.7533, True
+Tests/Unit/pos/State1.hs, 0.7221, True
+Tests/Unit/pos/state00.hs, 0.7158, True
+Tests/Unit/pos/State.hs, 0.8828, True
+Tests/Unit/pos/stacks0.hs, 0.7889, True
+Tests/Unit/pos/StackClass.hs, 0.7319, True
+Tests/Unit/pos/spec0.hs, 0.8261, True
+Tests/Unit/pos/Solver.hs, 1.1833, True
+Tests/Unit/pos/SimplerNotation.hs, 0.6711, True
+Tests/Unit/pos/selfList.hs, 0.9645, True
+Tests/Unit/pos/scanr.hs, 0.8346, True
+Tests/Unit/pos/SafePartialFunctions.hs, 0.7138, True
+Tests/Unit/pos/risers.hs, 1.2191, True
+Tests/Unit/pos/ResolvePred.hs, 0.6941, True
+Tests/Unit/pos/ResolveB.hs, 0.6481, True
+Tests/Unit/pos/ResolveA.hs, 0.6623, True
+Tests/Unit/pos/Resolve.hs, 0.6608, True
+Tests/Unit/pos/repeatHigherOrder.hs, 1.0108, True
+Tests/Unit/pos/Repeat.hs, 0.7135, True
+Tests/Unit/pos/RelativeComplete.hs, 0.7293, True
+Tests/Unit/pos/recursion0.hs, 0.7034, True
+Tests/Unit/pos/RecSelector.hs, 0.7960, True
+Tests/Unit/pos/RecQSort0.hs, 0.9562, True
+Tests/Unit/pos/RecQSort.hs, 1.0206, True
+Tests/Unit/pos/RecordSelectorError.hs, 0.7164, True
+Tests/Unit/pos/record1.hs, 0.7421, True
+Tests/Unit/pos/record0.hs, 0.8318, True
+Tests/Unit/pos/rec_annot_go.hs, 0.8982, True
+Tests/Unit/pos/RealProps1.hs, 0.7265, True
+Tests/Unit/pos/RealProps.hs, 0.7535, True
+Tests/Unit/pos/RBTree.hs, 1.0661, True
+Tests/Unit/pos/RBTree-ord.hs, 8.2893, True
+Tests/Unit/pos/RBTree-height.hs, 3.4410, True
+Tests/Unit/pos/RBTree-color.hs, 3.7845, True
+Tests/Unit/pos/RBTree-col-height.hs, 5.2851, True
+Tests/Unit/pos/rangeAdt.hs, 1.6620, True
+Tests/Unit/pos/range1.hs, 0.8005, True
+Tests/Unit/pos/range.hs, 0.9886, True
+Tests/Unit/pos/qualTest.hs, 0.7478, True
+Tests/Unit/pos/QSort.hs, 1.4716, True
+Tests/Unit/pos/propmeasure1.hs, 0.6626, True
+Tests/Unit/pos/propmeasure.hs, 0.7961, True
+Tests/Unit/pos/Propability.hs, 0.7806, True
+Tests/Unit/pos/profcrasher.hs, 0.7105, True
+Tests/Unit/pos/Product.hs, 1.0069, True
+Tests/Unit/pos/primInt0.hs, 0.8484, True
+Tests/Unit/pos/pred.hs, 0.7099, True
+Tests/Unit/pos/pragma0.hs, 0.6917, True
+Tests/Unit/pos/poslist_dc.hs, 0.8027, True
+Tests/Unit/pos/poslist.hs, 0.9802, True
+Tests/Unit/pos/polyqual.hs, 0.9248, True
+Tests/Unit/pos/polyfun.hs, 0.7572, True
+Tests/Unit/pos/poly4.hs, 0.7345, True
+Tests/Unit/pos/poly3a.hs, 0.7303, True
+Tests/Unit/pos/poly3.hs, 0.7437, True
+Tests/Unit/pos/poly2.hs, 0.7846, True
+Tests/Unit/pos/poly2-degenerate.hs, 0.7547, True
+Tests/Unit/pos/poly1.hs, 0.7808, True
+Tests/Unit/pos/poly0.hs, 0.7877, True
+Tests/Unit/pos/PointDist.hs, 0.9880, True
+Tests/Unit/pos/PlugHoles.hs, 0.6744, True
+Tests/Unit/pos/PersistentVector.hs, 0.8074, True
+Tests/Unit/pos/Permutation.hs, 2.0219, True
+Tests/Unit/pos/partialmeasure.hs, 0.7036, True
+Tests/Unit/pos/partial-tycon.hs, 0.6908, True
+Tests/Unit/pos/pargs1.hs, 0.6910, True
+Tests/Unit/pos/pargs.hs, 0.6989, True
+Tests/Unit/pos/PairMeasure0.hs, 0.7290, True
+Tests/Unit/pos/PairMeasure.hs, 0.7137, True
+Tests/Unit/pos/pair00.hs, 1.2826, True
+Tests/Unit/pos/pair0.hs, 1.4063, True
+Tests/Unit/pos/pair.hs, 1.5088, True
+Tests/Unit/pos/Overwrite.hs, 0.7084, True
+Tests/Unit/pos/OrdList.hs, 20.4459, True
+Tests/Unit/pos/nullterm.hs, 1.0949, True
+Tests/Unit/pos/NoExhaustiveGuardsError.hs, 0.7121, True
+Tests/Unit/pos/NoCaseExpand.hs, 1.0609, True
+Tests/Unit/pos/niki1.hs, 0.7688, True
+Tests/Unit/pos/niki.hs, 0.7512, True
+Tests/Unit/pos/nats.hs, 1.1694, True
+Tests/Unit/pos/MutualRec.hs, 1.9639, True
+Tests/Unit/pos/mutrec.hs, 0.7172, True
+Tests/Unit/pos/MultipleInvariants.hs, 0.7027, True
+Tests/Unit/pos/multi-pred-app-00.hs, 0.6771, True
+Tests/Unit/pos/Moo.hs, 0.6658, True
+Tests/Unit/pos/monad7.hs, 0.9704, True
+Tests/Unit/pos/monad6.hs, 0.7766, True
+Tests/Unit/pos/monad5.hs, 0.9161, True
+Tests/Unit/pos/monad2.hs, 0.6981, True
+Tests/Unit/pos/monad1.hs, 0.6731, True
+Tests/Unit/pos/modTest.hs, 0.7711, True
+Tests/Unit/pos/Mod2.hs, 0.6876, True
+Tests/Unit/pos/Mod1.hs, 0.6902, True
+Tests/Unit/pos/MergeSort.hs, 2.2196, True
+Tests/Unit/pos/Merge1.hs, 0.8288, True
+Tests/Unit/pos/MeasureSets.hs, 0.7270, True
+Tests/Unit/pos/Measures1.hs, 0.6718, True
+Tests/Unit/pos/Measures.hs, 0.6792, True
+Tests/Unit/pos/MeasureDups.hs, 0.7601, True
+Tests/Unit/pos/MeasureContains.hs, 0.7507, True
+Tests/Unit/pos/meas9.hs, 0.7991, True
+Tests/Unit/pos/meas8.hs, 0.7465, True
+Tests/Unit/pos/meas7.hs, 0.7121, True
+Tests/Unit/pos/meas6.hs, 0.8840, True
+Tests/Unit/pos/meas5.hs, 1.2681, True
+Tests/Unit/pos/meas4.hs, 0.8438, True
+Tests/Unit/pos/meas3.hs, 0.8466, True
+Tests/Unit/pos/meas2.hs, 0.7545, True
+Tests/Unit/pos/meas11.hs, 0.7639, True
+Tests/Unit/pos/meas10.hs, 0.8027, True
+Tests/Unit/pos/meas1.hs, 0.7810, True
+Tests/Unit/pos/meas0a.hs, 0.7873, True
+Tests/Unit/pos/meas00a.hs, 0.7200, True
+Tests/Unit/pos/meas00.hs, 0.7592, True
+Tests/Unit/pos/meas0.hs, 0.7601, True
+Tests/Unit/pos/maybe4.hs, 0.7064, True
+Tests/Unit/pos/maybe3.hs, 0.7180, True
+Tests/Unit/pos/maybe2.hs, 1.1633, True
+Tests/Unit/pos/maybe1.hs, 0.8372, True
+Tests/Unit/pos/maybe000.hs, 0.7200, True
+Tests/Unit/pos/maybe00.hs, 0.6818, True
+Tests/Unit/pos/maybe0.hs, 0.7295, True
+Tests/Unit/pos/maybe.hs, 1.1110, True
+Tests/Unit/pos/mapTvCrash.hs, 0.7188, True
+Tests/Unit/pos/maps1.hs, 0.8033, True
+Tests/Unit/pos/maps.hs, 0.7911, True
+Tests/Unit/pos/mapreduce.hs, 1.8906, True
+Tests/Unit/pos/mapreduce-bare.hs, 3.5676, True
+Tests/Unit/pos/Map2.hs, 16.4156, True
+Tests/Unit/pos/Map0.hs, 15.6414, True
+Tests/Unit/pos/Map.hs, 15.3783, True
+Tests/Unit/pos/malformed0.hs, 1.1082, True
+Tests/Unit/pos/Loo.hs, 0.6856, True
+Tests/Unit/pos/LocalTermExpr.hs, 0.7751, True
+Tests/Unit/pos/LocalSpecImp.hs, 0.6857, True
+Tests/Unit/pos/LocalSpec0.hs, 0.6765, True
+Tests/Unit/pos/LocalSpec.hs, 0.7340, True
+Tests/Unit/pos/LocalLazy.hs, 0.7356, True
+Tests/Unit/pos/LocalHole.hs, 0.7306, True
+Tests/Unit/pos/lit.hs, 0.6990, True
+Tests/Unit/pos/ListSort.hs, 2.9328, True
+Tests/Unit/pos/listSetDemo.hs, 0.8246, True
+Tests/Unit/pos/listSet.hs, 0.8183, True
+Tests/Unit/pos/ListReverse-LType.hs, 0.7676, True
+Tests/Unit/pos/ListRange.hs, 0.8350, True
+Tests/Unit/pos/ListRange-LType.hs, 0.8313, True
+Tests/Unit/pos/listqual.hs, 0.7386, True
+Tests/Unit/pos/ListQSort.hs, 1.4220, True
+Tests/Unit/pos/ListQSort-LType.hs, 1.3387, True
+Tests/Unit/pos/ListMSort.hs, 2.4582, True
+Tests/Unit/pos/ListMSort-LType.hs, 4.0770, True
+Tests/Unit/pos/ListLen.hs, 1.3169, True
+Tests/Unit/pos/ListLen-LType.hs, 1.2292, True
+Tests/Unit/pos/ListKeys.hs, 0.7766, True
+Tests/Unit/pos/ListISort.hs, 1.1008, True
+Tests/Unit/pos/ListISort-LType.hs, 1.2977, True
+Tests/Unit/pos/ListElem.hs, 0.8845, True
+Tests/Unit/pos/ListConcat.hs, 1.0046, True
+Tests/Unit/pos/listAnf.hs, 0.8492, True
+Tests/Unit/pos/LiquidClass.hs, 0.7707, True
+Tests/Unit/pos/LiquidArray.hs, 0.8232, True
+Tests/Unit/pos/lex.hs, 0.8430, True
+Tests/Unit/pos/lets.hs, 1.2676, True
+Tests/Unit/pos/LazyWhere1.hs, 0.8079, True
+Tests/Unit/pos/LazyWhere.hs, 0.7932, True
+Tests/Unit/pos/LambdaEvalTiny.hs, 1.5356, True
+Tests/Unit/pos/LambdaEvalSuperTiny.hs, 1.6086, True
+Tests/Unit/pos/LambdaEvalMini.hs, 3.4929, True
+Tests/Unit/pos/LambdaEval.hs, 24.2819, True
+Tests/Unit/pos/LambdaDeBruijn.hs, 1.6556, True
+Tests/Unit/pos/kmpVec.hs, 1.4646, True
+Tests/Unit/pos/kmpIO.hs, 0.8855, True
+Tests/Unit/pos/kmp.hs, 1.8785, True
+Tests/Unit/pos/Keys.hs, 0.7501, True
+Tests/Unit/pos/jeff.hs, 10.8492, True
+Tests/Unit/pos/ite1.hs, 0.6996, True
+Tests/Unit/pos/ite.hs, 0.7147, True
+Tests/Unit/pos/invlhs.hs, 0.6895, True
+Tests/Unit/pos/Invariants.hs, 1.0537, True
+Tests/Unit/pos/Interpreter.lhs, 3.0512, True
+Tests/Unit/pos/inline1.hs, 0.9490, True
+Tests/Unit/pos/inline.hs, 0.9680, True
+Tests/Unit/pos/initarray.hs, 1.2632, True
+Tests/Unit/pos/infix.hs, 0.8903, True
+Tests/Unit/pos/Infinity.hs, 0.8567, True
+Tests/Unit/pos/incRec.hs, 0.7327, True
+Tests/Unit/pos/implies.hs, 0.8057, True
+Tests/Unit/pos/imp0.hs, 0.7640, True
+Tests/Unit/pos/idNat0.hs, 0.7022, True
+Tests/Unit/pos/idNat.hs, 0.7317, True
+Tests/Unit/pos/IcfpDemo.hs, 0.9190, True
+Tests/Unit/pos/Holes.hs, 0.8138, True
+Tests/Unit/pos/hole-fun.hs, 0.7088, True
+Tests/Unit/pos/hole-app.hs, 0.7188, True
+Tests/Unit/pos/HigherOrderRecFun.hs, 0.7236, True
+Tests/Unit/pos/hello.hs, 1.0276, True
+Tests/Unit/pos/HedgeUnion.hs, 0.8780, True
+Tests/Unit/pos/HaskellMeasure.hs, 0.7298, True
+Tests/Unit/pos/HasElem.hs, 0.7334, True
+Tests/Unit/pos/grty3.hs, 0.7470, True
+Tests/Unit/pos/grty2.hs, 0.7321, True
+Tests/Unit/pos/grty1.hs, 0.7348, True
+Tests/Unit/pos/grty0.hs, 0.7204, True
+Tests/Unit/pos/Graph.hs, 0.9780, True
+Tests/Unit/pos/Gradual.hs, 0.0003, True
+Tests/Unit/pos/GoodHMeas.hs, 0.7365, True
+Tests/Unit/pos/Goo.hs, 0.8339, True
+Tests/Unit/pos/go_ugly_type.hs, 1.0360, True
+Tests/Unit/pos/go.hs, 1.0016, True
+Tests/Unit/pos/gimme.hs, 0.8045, True
+Tests/Unit/pos/GhcSort3.T.hs, 1.6722, True
+Tests/Unit/pos/GhcSort3.hs, 3.7254, True
+Tests/Unit/pos/GhcSort2.hs, 2.9714, True
+Tests/Unit/pos/GhcSort1.hs, 3.6082, True
+Tests/Unit/pos/GhcListSort.hs, 6.7895, True
+Tests/Unit/pos/GeneralizedTermination.hs, 0.8259, True
+Tests/Unit/pos/GCD.hs, 0.9686, True
+Tests/Unit/pos/GADTs.hs, 0.7504, True
+Tests/Unit/pos/gadtEval.hs, 1.2798, True
+Tests/Unit/pos/Fractional.hs, 0.7503, True
+Tests/Unit/pos/forloop.hs, 0.8764, True
+Tests/Unit/pos/for.hs, 0.9395, True
+Tests/Unit/pos/Foo.hs, 0.7369, True
+Tests/Unit/pos/foldr.hs, 0.8026, True
+Tests/Unit/pos/foldN.hs, 0.7592, True
+Tests/Unit/pos/Foldl.hs, 5.6430, True
+Tests/Unit/pos/Fixme.hs, 0.4782, False
+Tests/Unit/pos/filterAbs.hs, 0.8910, True
+Tests/Unit/pos/FFI.hs, 0.8925, True
+Tests/Unit/pos/failName.hs, 0.7885, True
+Tests/Unit/pos/extype.hs, 0.7870, True
+Tests/Unit/pos/exp0.hs, 0.8220, True
+Tests/Unit/pos/ex1.hs, 0.8220, True
+Tests/Unit/pos/ex01.hs, 0.7283, True
+Tests/Unit/pos/ex0.hs, 0.7740, True
+Tests/Unit/pos/Even0.hs, 0.7382, True
+Tests/Unit/pos/Even.hs, 0.6989, True
+Tests/Unit/pos/Eval.hs, 0.8454, True
+Tests/Unit/pos/eqelems.hs, 0.7296, True
+Tests/Unit/pos/elim01.hs, 0.7712, True
+Tests/Unit/pos/elim00.hs, 0.9294, True
+Tests/Unit/pos/elems.hs, 0.7497, True
+Tests/Unit/pos/elements.hs, 1.2040, True
+Tests/Unit/pos/duplicate-bind.hs, 0.7624, True
+Tests/Unit/pos/dropwhile.hs, 1.1568, True
+Tests/Unit/pos/div000.hs, 0.7194, True
+Tests/Unit/pos/Diff.hs, 0.7179, True
+Tests/Unit/pos/deptupW.hs, 0.8146, True
+Tests/Unit/pos/deptup3.hs, 0.8304, True
+Tests/Unit/pos/deptup1.hs, 1.0227, True
+Tests/Unit/pos/deptup0.hs, 0.9218, True
+Tests/Unit/pos/deptup.hs, 1.2726, True
+Tests/Unit/pos/deppair1.hs, 0.8677, True
+Tests/Unit/pos/deppair0.hs, 0.9051, True
+Tests/Unit/pos/deepmeas0.hs, 0.8856, True
+Tests/Unit/pos/DB00.hs, 0.8001, True
+Tests/Unit/pos/dataConQuals.hs, 0.7328, True
+Tests/Unit/pos/datacon1.hs, 0.7359, True
+Tests/Unit/pos/datacon0.hs, 0.8782, True
+Tests/Unit/pos/datacon-inv.hs, 0.7463, True
+Tests/Unit/pos/DataBase.hs, 0.7912, True
+Tests/Unit/pos/data2.hs, 0.8629, True
+Tests/Unit/pos/cut00.hs, 0.9637, True
+Tests/Unit/pos/csgordon_issue_296.hs, 0.9568, True
+Tests/Unit/pos/CountMonad.hs, 0.8422, True
+Tests/Unit/pos/coretologic.hs, 0.9599, True
+Tests/Unit/pos/contra0.hs, 0.8227, True
+Tests/Unit/pos/ConstraintsAppend.hs, 1.3965, True
+Tests/Unit/pos/Constraints.hs, 0.8104, True
+Tests/Unit/pos/comprehensionTerm.hs, 1.1129, True
+Tests/Unit/pos/CompareConstraints.hs, 1.2335, True
+Tests/Unit/pos/compare2.hs, 0.7855, True
+Tests/Unit/pos/compare1.hs, 0.7883, True
+Tests/Unit/pos/compare.hs, 0.8621, True
+Tests/Unit/pos/CommentedOut.hs, 1.1233, True
+Tests/Unit/pos/Coercion.hs, 0.7177, True
+Tests/Unit/pos/cmptag0.hs, 0.7769, True
+Tests/Unit/pos/ClojurVector.hs, 0.9000, True
+Tests/Unit/pos/ClassReg.hs, 0.7063, True
+Tests/Unit/pos/Class2.hs, 0.6933, True
+Tests/Unit/pos/Class.hs, 1.1571, True
+Tests/Unit/pos/case-lambda-join.hs, 1.1120, True
+Tests/Unit/pos/BST000.hs, 1.8360, True
+Tests/Unit/pos/BST.hs, 8.7355, True
+Tests/Unit/pos/bounds1.hs, 0.7379, True
+Tests/Unit/pos/Books.hs, 0.7995, True
+Tests/Unit/pos/BinarySearch.hs, 0.9454, True
+Tests/Unit/pos/bar.hs, 0.7507, True
+Tests/Unit/pos/bangPatterns.hs, 0.7607, True
+Tests/Unit/pos/AVLRJ.hs, 2.6742, True
+Tests/Unit/pos/AVL.hs, 2.2005, True
+Tests/Unit/pos/Avg.hs, 0.7753, True
+Tests/Unit/pos/AutoTerm1.hs, 0.7302, True
+Tests/Unit/pos/AutoTerm.hs, 0.8322, True
+Tests/Unit/pos/AutoSize.hs, 0.7583, True
+Tests/Unit/pos/AssumedRecursive.hs, 0.6913, True
+Tests/Unit/pos/Assume0.hs, 0.7300, True
+Tests/Unit/pos/Assume.hs, 0.7824, True
+Tests/Unit/pos/anish1.hs, 0.7696, True
+Tests/Unit/pos/anftest.hs, 0.7671, True
+Tests/Unit/pos/anfbug.hs, 0.8209, True
+Tests/Unit/pos/AmortizedQueue.hs, 0.9068, True
+Tests/Unit/pos/alphaconvert-Set.hs, 1.0940, True
+Tests/Unit/pos/alphaconvert-List.hs, 1.3082, True
+Tests/Unit/pos/alias01.hs, 1.1252, True
+Tests/Unit/pos/alias00.hs, 0.8920, True
+Tests/Unit/pos/adt0.hs, 1.0042, True
+Tests/Unit/pos/Ackermann.hs, 0.7849, True
+Tests/Unit/pos/absref-crash0.hs, 0.7734, True
+Tests/Unit/pos/absref-crash.hs, 0.6982, True
+Tests/Unit/pos/Abs.hs, 0.7181, True
+Tests/Unit/neg/wrap1.hs, 1.3518, True
+Tests/Unit/neg/wrap0.hs, 0.9953, True
+Tests/Unit/neg/vector2.hs, 1.7215, True
+Tests/Unit/neg/vector1a.hs, 1.9218, True
+Tests/Unit/neg/vector0a.hs, 0.9550, True
+Tests/Unit/neg/vector00.hs, 0.9021, True
+Tests/Unit/neg/vector0.hs, 1.0318, True
+Tests/Unit/neg/Variance1.hs, 0.7439, True
+Tests/Unit/neg/Variance.hs, 0.7758, True
+Tests/Unit/neg/tyclass0-unsafe.hs, 0.6881, True
+Tests/Unit/neg/truespec.hs, 0.7141, True
+Tests/Unit/neg/trans.hs, 1.5066, True
+Tests/Unit/neg/TopLevel.hs, 0.7302, True
+Tests/Unit/neg/testRec.hs, 0.7466, True
+Tests/Unit/neg/test2.hs, 0.7476, True
+Tests/Unit/neg/test1.hs, 0.7466, True
+Tests/Unit/neg/test00c.hs, 0.6952, True
+Tests/Unit/neg/test00b.hs, 0.7418, True
+Tests/Unit/neg/test00a.hs, 0.8298, True
+Tests/Unit/neg/test00.hs, 0.9917, True
+Tests/Unit/neg/TermReal.hs, 0.7058, True
+Tests/Unit/neg/TerminationNum0.hs, 0.7346, True
+Tests/Unit/neg/TerminationNum.hs, 0.7075, True
+Tests/Unit/neg/T602.hs, 0.6791, True
+Tests/Unit/neg/sumPoly.hs, 0.7132, True
+Tests/Unit/neg/sumk.hs, 0.7128, True
+Tests/Unit/neg/Sum.hs, 0.7617, True
+Tests/Unit/neg/Strings.hs, 0.6868, True
+Tests/Unit/neg/string00.hs, 0.7364, True
+Tests/Unit/neg/StrictPair1.hs, 0.9501, True
+Tests/Unit/neg/StrictPair0.hs, 0.6993, True
+Tests/Unit/neg/StreamInvariants.hs, 0.7106, True
+Tests/Unit/neg/Strata.hs, 0.7056, True
+Tests/Unit/neg/StateConstraints00.hs, 0.7992, True
+Tests/Unit/neg/StateConstraints0.hs, 16.0782, True
+Tests/Unit/neg/StateConstraints.hs, 1.2671, True
+Tests/Unit/neg/state00.hs, 0.7449, True
+Tests/Unit/neg/state0.hs, 0.7596, True
+Tests/Unit/neg/stacks.hs, 1.0375, True
+Tests/Unit/neg/Solver.hs, 1.2094, True
+Tests/Unit/neg/SafePartialFunctions.hs, 0.7671, True
+Tests/Unit/neg/risers.hs, 0.8194, True
+Tests/Unit/neg/RG.hs, 1.0699, True
+Tests/Unit/neg/revshape.hs, 0.7196, True
+Tests/Unit/neg/RecSelector.hs, 0.6860, True
+Tests/Unit/neg/RecQSort.hs, 0.9479, True
+Tests/Unit/neg/record0.hs, 0.7339, True
+Tests/Unit/neg/range.hs, 1.2283, True
+Tests/Unit/neg/qsloop.hs, 0.8831, True
+Tests/Unit/neg/prune0.hs, 0.8038, True
+Tests/Unit/neg/Propability0.hs, 0.7573, True
+Tests/Unit/neg/Propability.hs, 0.9722, True
+Tests/Unit/neg/pred.hs, 0.6142, True
+Tests/Unit/neg/pragma0-unsafe.hs, 0.6792, True
+Tests/Unit/neg/poslist.hs, 0.9945, True
+Tests/Unit/neg/polypred.hs, 0.7344, True
+Tests/Unit/neg/poly2.hs, 0.7499, True
+Tests/Unit/neg/poly2-degenerate.hs, 0.7735, True
+Tests/Unit/neg/poly1.hs, 0.7975, True
+Tests/Unit/neg/poly0.hs, 0.8463, True
+Tests/Unit/neg/partial.hs, 0.7387, True
+Tests/Unit/neg/pargs1.hs, 0.6893, True
+Tests/Unit/neg/pargs.hs, 0.6881, True
+Tests/Unit/neg/PairMeasure.hs, 0.7136, True
+Tests/Unit/neg/pair0.hs, 1.5614, True
+Tests/Unit/neg/pair.hs, 1.8548, True
+Tests/Unit/neg/NoMethodBindingError.hs, 0.9186, True
+Tests/Unit/neg/NoExhaustiveGuardsError.hs, 1.0346, True
+Tests/Unit/neg/nestedRecursion.hs, 0.7612, True
+Tests/Unit/neg/MultipleInvariants.hs, 0.7557, True
+Tests/Unit/neg/multi-pred-app-00.hs, 0.7912, True
+Tests/Unit/neg/mr00.hs, 0.8983, True
+Tests/Unit/neg/monad7.hs, 1.0344, True
+Tests/Unit/neg/monad6.hs, 0.7788, True
+Tests/Unit/neg/monad5.hs, 0.8094, True
+Tests/Unit/neg/monad4.hs, 0.8482, True
+Tests/Unit/neg/monad3.hs, 0.8773, True
+Tests/Unit/neg/MergeSort.hs, 2.3962, True
+Tests/Unit/neg/MeasureDups.hs, 0.9041, True
+Tests/Unit/neg/MeasureContains.hs, 0.8477, True
+Tests/Unit/neg/meas9.hs, 0.8463, True
+Tests/Unit/neg/meas7.hs, 0.6972, True
+Tests/Unit/neg/meas5.hs, 1.3677, True
+Tests/Unit/neg/meas3.hs, 0.8661, True
+Tests/Unit/neg/meas2.hs, 0.8490, True
+Tests/Unit/neg/meas0.hs, 0.8479, True
+Tests/Unit/neg/maps.hs, 0.8663, True
+Tests/Unit/neg/mapreduce.hs, 1.9294, True
+Tests/Unit/neg/mapreduce-tiny.hs, 0.7899, True
+Tests/Unit/neg/LocalSpec.hs, 0.7284, True
+Tests/Unit/neg/lit.hs, 0.7143, True
+Tests/Unit/neg/ListRange.hs, 0.8867, True
+Tests/Unit/neg/ListQSort.hs, 1.1796, True
+Tests/Unit/neg/listne.hs, 0.7354, True
+Tests/Unit/neg/ListMSort.hs, 3.0937, True
+Tests/Unit/neg/ListKeys.hs, 0.7417, True
+Tests/Unit/neg/ListISort.hs, 1.4745, True
+Tests/Unit/neg/ListISort-LType.hs, 0.9603, True
+Tests/Unit/neg/ListElem.hs, 0.7397, True
+Tests/Unit/neg/ListConcat.hs, 0.7548, True
+Tests/Unit/neg/list00.hs, 0.7566, True
+Tests/Unit/neg/LiquidClass1.hs, 0.7092, True
+Tests/Unit/neg/LiquidClass.hs, 0.7203, True
+Tests/Unit/neg/LazyWhere1.hs, 0.8003, True
+Tests/Unit/neg/LazyWhere.hs, 0.9225, True
+Tests/Unit/neg/inc2.hs, 0.7466, True
+Tests/Unit/neg/HolesTop.hs, 0.9127, True
+Tests/Unit/neg/HigherOrder.hs, 0.7817, True
+Tests/Unit/neg/HasElem.hs, 0.7434, True
+Tests/Unit/neg/grty3.hs, 0.7035, True
+Tests/Unit/neg/grty2.hs, 0.8840, True
+Tests/Unit/neg/grty1.hs, 0.8554, True
+Tests/Unit/neg/grty0.hs, 0.6871, True
+Tests/Unit/neg/Gradual.hs, 0.6900, True
+Tests/Unit/neg/GeneralizedTermination.hs, 0.7566, True
+Tests/Unit/neg/GADTs.hs, 0.6887, True
+Tests/Unit/neg/FunSoundness.hs, 0.7136, True
+Tests/Unit/neg/foldN1.hs, 0.9769, True
+Tests/Unit/neg/foldN.hs, 0.7434, True
+Tests/Unit/neg/filterAbs.hs, 1.0046, True
+Tests/Unit/neg/ex1-unsafe.hs, 0.8217, True
+Tests/Unit/neg/ex0-unsafe.hs, 0.9005, True
+Tests/Unit/neg/Even.hs, 0.9582, True
+Tests/Unit/neg/Eval.hs, 0.9271, True
+Tests/Unit/neg/errorloc.hs, 0.8200, True
+Tests/Unit/neg/errmsg.hs, 0.8111, True
+Tests/Unit/neg/elim000.hs, 0.7172, True
+Tests/Unit/neg/deptupW.hs, 0.8099, True
+Tests/Unit/neg/deppair0.hs, 0.7881, True
+Tests/Unit/neg/datacon-eq.hs, 0.6728, True
+Tests/Unit/neg/csv.hs, 2.8290, True
+Tests/Unit/neg/coretologic.hs, 0.7554, True
+Tests/Unit/neg/contra0.hs, 0.7926, True
+Tests/Unit/neg/ConstraintsAppend.hs, 1.3149, True
+Tests/Unit/neg/Constraints.hs, 0.7211, True
+Tests/Unit/neg/concat2.hs, 1.0606, True
+Tests/Unit/neg/concat1.hs, 1.1431, True
+Tests/Unit/neg/concat.hs, 0.9653, True
+Tests/Unit/neg/CompareConstraints.hs, 1.2517, True
+Tests/Unit/neg/Class5.hs, 0.6889, True
+Tests/Unit/neg/Class4.hs, 0.7185, True
+Tests/Unit/neg/Class3.hs, 0.7414, True
+Tests/Unit/neg/Class2.hs, 0.7606, True
+Tests/Unit/neg/Class1.hs, 0.8845, True
+Tests/Unit/neg/CastedTotality.hs, 0.7359, True
+Tests/Unit/neg/Books.hs, 0.7527, True
+Tests/Unit/neg/BigNum.hs, 0.6869, True
+Tests/Unit/neg/Baz.hs, 0.7232, True
+Tests/Unit/neg/BadHMeas.hs, 0.6922, True
+Tests/Unit/neg/AutoTerm1.hs, 0.7150, True
+Tests/Unit/neg/AutoTerm.hs, 0.6996, True
+Tests/Unit/neg/AutoSize.hs, 0.6847, True
+Tests/Unit/neg/Ast.hs, 0.7312, True
+Tests/Unit/neg/ass0.hs, 0.6693, True
+Tests/Unit/neg/alias00.hs, 0.7076, True
+Tests/Unit/neg/AbsApp.hs, 0.7236, True
+Tests/Unit/crash/Unbound.hs, 0.6585, True
+Tests/Unit/crash/typeAliasDup.hs, 0.7039, True
+Tests/Unit/crash/T691.hs, 0.3838, True
+Tests/Unit/crash/T649.hs, 0.6714, True
+Tests/Unit/crash/RClass.hs, 0.6643, True
+Tests/Unit/crash/Qualif.hs, 0.6772, True
+Tests/Unit/crash/predparams.hs, 0.6148, True
+Tests/Unit/crash/num-float-error1.hs, 0.6533, True
+Tests/Unit/crash/num-float-error.hs, 0.6597, True
+Tests/Unit/crash/MultipleRecordSelectors.hs, 0.6499, True
+Tests/Unit/crash/Mismatch.hs, 0.6438, True
+Tests/Unit/crash/LocalTermExpr.hs, 0.6758, True
+Tests/Unit/crash/LocalHole.hs, 0.6734, True
+Tests/Unit/crash/issue594.hs, 0.6514, True
+Tests/Unit/crash/hole-crash3.hs, 0.6306, True
+Tests/Unit/crash/hole-crash2.hs, 0.6071, True
+Tests/Unit/crash/hole-crash1.hs, 0.6453, True
+Tests/Unit/crash/HigherOrder.hs, 0.6374, True
+Tests/Unit/crash/HaskellMeasure.hs, 0.6146, True
+Tests/Unit/crash/FunRef2.hs, 0.6536, True
+Tests/Unit/crash/FunRef1.hs, 0.6525, True
+Tests/Unit/crash/funref.hs, 0.6751, True
+Tests/Unit/crash/errmsg-mismatch.hs, 0.6581, True
+Tests/Unit/crash/errmsg-dc-type.hs, 0.6385, True
+Tests/Unit/crash/errmsg-dc-num.hs, 0.6550, True
+Tests/Unit/crash/CyclicTypeAlias3.hs, 0.5705, True
+Tests/Unit/crash/CyclicTypeAlias2.hs, 0.5883, True
+Tests/Unit/crash/CyclicTypeAlias1.hs, 0.5971, True
+Tests/Unit/crash/CyclicTypeAlias0.hs, 0.5745, True
+Tests/Unit/crash/CyclicPredAlias3.hs, 0.6564, True
+Tests/Unit/crash/CyclicPredAlias2.hs, 0.7405, True
+Tests/Unit/crash/CyclicPredAlias1.hs, 0.5976, True
+Tests/Unit/crash/CyclicPredAlias0.hs, 0.6159, True
+Tests/Unit/crash/CyclicExprAlias3.hs, 0.6998, True
+Tests/Unit/crash/CyclicExprAlias2.hs, 0.7905, True
+Tests/Unit/crash/CyclicExprAlias1.hs, 0.7896, True
+Tests/Unit/crash/CyclicExprAlias0.hs, 0.7455, True
+Tests/Unit/crash/BadSyn4.hs, 0.6347, True
+Tests/Unit/crash/BadSyn3.hs, 0.6292, True
+Tests/Unit/crash/BadSyn2.hs, 0.8681, True
+Tests/Unit/crash/BadSyn1.hs, 0.6858, True
+Tests/Unit/crash/BadPragma2.hs, 0.4173, True
+Tests/Unit/crash/BadPragma1.hs, 0.3918, True
+Tests/Unit/crash/BadPragma0.hs, 0.3815, True
+Tests/Unit/crash/BadExprArg.hs, 0.6657, True
+Tests/Unit/crash/Ast.hs, 0.7110, True
+Tests/Unit/crash/Assume1.hs, 0.6973, True
+Tests/Unit/crash/Assume.hs, 0.7036, True
+Tests/Unit/crash/AbsRef.hs, 0.8573, True
+Tests/Unit/parser/pos/TokensAsPrefixes.hs, 0.6883, True
+Tests/Unit/parser/pos/Parens.hs, 0.8073, True
+Tests/Unit/error/crash/TerminationExpr1.hs, 0.8753, True
+Tests/Unit/error/crash/TerminationExpr.hs, 0.7385, True
+Tests/Benchmarks/text/Setup.lhs, 1.4109, True
+Tests/Benchmarks/text/Data/Text.hs, 68.9904, True
+Tests/Benchmarks/text/Data/Text/UnsafeChar.hs, 3.7855, True
+Tests/Benchmarks/text/Data/Text/Unsafe.hs, 2.8610, True
+Tests/Benchmarks/text/Data/Text/Search.hs, 12.8558, True
+Tests/Benchmarks/text/Data/Text/Private.hs, 2.2493, True
+Tests/Benchmarks/text/Data/Text/Lazy.hs, 77.9932, True
+Tests/Benchmarks/text/Data/Text/Internal.hs, 3.9795, True
+Tests/Benchmarks/text/Data/Text/Fusion.hs, 21.5058, True
+Tests/Benchmarks/text/Data/Text/Foreign.hs, 3.1733, True
+Tests/Benchmarks/text/Data/Text/Encoding.hs, 79.9221, True
+Tests/Benchmarks/text/Data/Text/Array.hs, 1.7552, True
+Tests/Benchmarks/text/Data/Text/Lazy/Search.hs, 94.5214, True
+Tests/Benchmarks/text/Data/Text/Lazy/Internal.hs, 5.0826, True
+Tests/Benchmarks/text/Data/Text/Lazy/Fusion.hs, 8.3652, True
+Tests/Benchmarks/text/Data/Text/Lazy/Encoding.hs, 13.1258, True
+Tests/Benchmarks/text/Data/Text/Lazy/Builder.hs, 16.1850, True
+Tests/Benchmarks/text/Data/Text/Fusion/Size.hs, 1.6748, True
+Tests/Benchmarks/bytestring/Data/ByteString.T.hs, 50.2732, True
+Tests/Benchmarks/bytestring/Data/ByteString.hs, 45.2544, True
+Tests/Benchmarks/bytestring/Data/ByteString/Unsafe.hs, 2.4628, True
+Tests/Benchmarks/bytestring/Data/ByteString/LazyZip.hs, 95.9668, True
+Tests/Benchmarks/bytestring/Data/ByteString/Lazy.hs, 77.7830, True
+Tests/Benchmarks/bytestring/Data/ByteString/Internal.hs, 5.1267, True
+Tests/Benchmarks/bytestring/Data/ByteString/Fusion.T.hs, 19.2232, True
+Tests/Benchmarks/bytestring/Data/ByteString/Fusion.hs, 15.2251, True
+Tests/Benchmarks/bytestring/Data/ByteString/Char8.hs, 7.7081, True
+Tests/Benchmarks/bytestring/Data/ByteString/Lazy/Internal.hs, 1.5104, True
+Tests/Benchmarks/bytestring/Data/ByteString/Lazy/Char8.hs, 8.9567, True
+Tests/Benchmarks/esop/Toy.hs, 1.3708, True
+Tests/Benchmarks/esop/Splay.hs, 11.5167, True
+Tests/Benchmarks/esop/ListSort.hs, 3.0115, True
+Tests/Benchmarks/esop/GhcListSort.hs, 5.8081, True
+Tests/Benchmarks/esop/Fib.hs, 1.8856, True
+Tests/Benchmarks/esop/Base.hs, 120.6181, True
+Tests/Benchmarks/esop/Array.hs, 4.5661, True
+Tests/Benchmarks/vect-algs/Setup.lhs, 1.1730, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Termination.hs, 0.9729, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Search.hs, 4.3748, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Radix.hs, 2.7923, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Optimal.hs, 7.0432, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Merge.hs, 4.8165, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Intro.hs, 6.9406, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Insertion.hs, 1.3704, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Heap.hs, 26.8470, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Common.hs, 1.0665, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Combinators.hs, 0.7115, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/AmericanFlag.hs, 4.9445, True
+Tests/Benchmarks/hscolour/Setup.hs, 0.7075, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour.hs, 5.2269, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/TTY.hs, 1.1365, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Output.hs, 0.8852, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Options.hs, 0.7858, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/MIRC.hs, 2.4293, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/LaTeX.hs, 19.0297, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/InlineCSS.hs, 1.6110, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/HTML.hs, 4.3644, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/General.hs, 0.7459, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/CSS.hs, 1.5377, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Colourise.hs, 2.7581, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/ColourHighlight.hs, 2.5077, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Classify.hs, 182.7523, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/ANSI.hs, 1.7264, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Anchors.hs, 45.4617, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/ACSS.hs, 9.6555, True
+Tests/Benchmarks/icfp_pos/WhileTest.hs, 1.0173, True
+Tests/Benchmarks/icfp_pos/WhileM.hs, 0.9205, True
+Tests/Benchmarks/icfp_pos/TwiceM.hs, 5.8141, True
+Tests/Benchmarks/icfp_pos/TestM.hs, 0.7240, True
+Tests/Benchmarks/icfp_pos/RIO2.hs, 14.6012, True
+Tests/Benchmarks/icfp_pos/Privileges.hs, 0.7326, True
+Tests/Benchmarks/icfp_pos/Overview.lhs, 6.0587, True
+Tests/Benchmarks/icfp_pos/Incr.hs, 0.9888, True
+Tests/Benchmarks/icfp_pos/Incr-elim.hs, 0.8710, True
+Tests/Benchmarks/icfp_pos/IfM2.hs, 3.0492, True
+Tests/Benchmarks/icfp_pos/IfM.hs, 5.0953, True
+Tests/Benchmarks/icfp_pos/ICFP15.lhs, 1.5533, True
+Tests/Benchmarks/icfp_pos/FoldL.hs, 5.1710, True
+Tests/Benchmarks/icfp_pos/FoldAbs.hs, 4.8517, True
+Tests/Benchmarks/icfp_pos/FindRec.hs, 8.9019, True
+Tests/Benchmarks/icfp_pos/Filter.lhs, 0.9800, True
+Tests/Benchmarks/icfp_pos/dropwhile.hs, 0.8640, True
+Tests/Benchmarks/icfp_pos/DBMovies.hs, 4.0305, True
+Tests/Benchmarks/icfp_pos/CopyRec.hs, 16.2289, True
+Tests/Benchmarks/icfp_pos/Composition.hs, 0.8499, True
+Tests/Benchmarks/icfp_pos/CompareConstraints.hs, 1.1438, True
+Tests/Benchmarks/icfp_pos/Append.hs, 1.0370, True
+Tests/Benchmarks/icfp_neg/WhileM.hs, 1.1374, True
+Tests/Benchmarks/icfp_neg/TwiceM.hs, 31.7745, True
+Tests/Benchmarks/icfp_neg/TestM.hs, 0.8845, True
+Tests/Benchmarks/icfp_neg/Records.hs, 0.8419, True
+Tests/Benchmarks/icfp_neg/IfM.hs, 5.1471, True
+Tests/Benchmarks/icfp_neg/DBMovies.hs, 3.6141, True
+Tests/Benchmarks/icfp_neg/Composition.hs, 0.8425, True
diff --git a/tests/log/summary-map_fusion.csv b/tests/log/summary-map_fusion.csv
new file mode 100644
--- /dev/null
+++ b/tests/log/summary-map_fusion.csv
@@ -0,0 +1,693 @@
+ (HEAD, origin/map_fusion, alive) : 39270565bff1a7e9759178f4512ecbd54d1c5321
+Timestamp: 2016-05-13 14:33:42 -0700
+Epoch Timestamp: 1463175222
+--------------------------------------------------------------------------------
+test, time(s), result
+
+Tests/Unit/pos/zipW2.hs, 0.8528, True
+Tests/Unit/pos/zipW1.hs, 0.7792, True
+Tests/Unit/pos/zipW.hs, 0.8702, True
+Tests/Unit/pos/zipSO.hs, 1.2959, True
+Tests/Unit/pos/zipper000.hs, 1.4411, True
+Tests/Unit/pos/zipper0.hs, 1.9472, True
+Tests/Unit/pos/zipper.hs, 3.9550, True
+Tests/Unit/pos/wrap1.hs, 1.6970, True
+Tests/Unit/pos/wrap0.hs, 1.2780, True
+Tests/Unit/pos/Words1.hs, 0.8589, True
+Tests/Unit/pos/Words.hs, 0.6962, True
+Tests/Unit/pos/WBL0.hs, 2.8234, True
+Tests/Unit/pos/WBL.hs, 2.0757, True
+Tests/Unit/pos/vector2.hs, 1.5296, True
+Tests/Unit/pos/vector1b.hs, 1.0971, True
+Tests/Unit/pos/vector1a.hs, 1.1458, True
+Tests/Unit/pos/vector1.hs, 1.2775, True
+Tests/Unit/pos/vector00.hs, 0.8321, True
+Tests/Unit/pos/vector0.hs, 1.3749, True
+Tests/Unit/pos/vecloop.hs, 0.9556, True
+Tests/Unit/pos/Variance.hs, 0.7168, True
+Tests/Unit/pos/unusedtyvars.hs, 0.6860, True
+Tests/Unit/pos/tyvar.hs, 0.6717, True
+Tests/Unit/pos/TypeAlias.hs, 0.8266, True
+Tests/Unit/pos/tyfam0.hs, 0.8357, True
+Tests/Unit/pos/tyExpr.hs, 0.8061, True
+Tests/Unit/pos/tyclass0.hs, 0.8227, True
+Tests/Unit/pos/tupparse.hs, 0.7772, True
+Tests/Unit/pos/tup0.hs, 0.7000, True
+Tests/Unit/pos/transTAG.hs, 1.7704, True
+Tests/Unit/pos/transpose.hs, 1.8750, True
+Tests/Unit/pos/trans.hs, 1.0275, True
+Tests/Unit/pos/ToyMVar.hs, 0.9426, True
+Tests/Unit/pos/TopLevel.hs, 0.7082, True
+Tests/Unit/pos/top0.hs, 0.7992, True
+Tests/Unit/pos/TokenType.hs, 0.6787, True
+Tests/Unit/pos/testRec.hs, 0.7470, True
+Tests/Unit/pos/Test761.hs, 0.7316, True
+Tests/Unit/pos/test2.hs, 0.7369, True
+Tests/Unit/pos/test1.hs, 0.7590, True
+Tests/Unit/pos/test00c.hs, 0.9207, True
+Tests/Unit/pos/test00b.hs, 0.7364, True
+Tests/Unit/pos/test000.hs, 0.7571, True
+Tests/Unit/pos/test00.old.hs, 0.7179, True
+Tests/Unit/pos/test00.hs, 0.7389, True
+Tests/Unit/pos/test00-int.hs, 0.7191, True
+Tests/Unit/pos/test0.hs, 0.7547, True
+Tests/Unit/pos/TerminationNum0.hs, 0.7110, True
+Tests/Unit/pos/TerminationNum.hs, 0.6873, True
+Tests/Unit/pos/Termination.lhs, 0.9198, True
+Tests/Unit/pos/term0.hs, 0.7938, True
+Tests/Unit/pos/Term.hs, 0.7501, True
+Tests/Unit/pos/take.hs, 1.0478, True
+Tests/Unit/pos/tagBinder.hs, 0.6868, True
+Tests/Unit/pos/T598.hs, 0.8284, True
+Tests/Unit/pos/T595a.hs, 0.7056, True
+Tests/Unit/pos/T595.hs, 0.7731, True
+Tests/Unit/pos/T531.hs, 0.6767, True
+Tests/Unit/pos/Sum.hs, 0.7500, True
+Tests/Unit/pos/StructRec.hs, 0.7115, True
+Tests/Unit/pos/Strings.hs, 0.7493, True
+Tests/Unit/pos/StringLit.hs, 0.6792, True
+Tests/Unit/pos/string00.hs, 0.7272, True
+Tests/Unit/pos/StrictPair1.hs, 0.9594, True
+Tests/Unit/pos/StrictPair0.hs, 0.7250, True
+Tests/Unit/pos/StreamInvariants.hs, 0.7065, True
+Tests/Unit/pos/stateInvarint.hs, 0.8923, True
+Tests/Unit/pos/StateF00.hs, 0.7380, True
+Tests/Unit/pos/StateConstraints00.hs, 0.7112, True
+Tests/Unit/pos/StateConstraints0.hs, 9.0070, True
+Tests/Unit/pos/StateConstraints.hs, 5.0289, True
+Tests/Unit/pos/State1.hs, 0.7464, True
+Tests/Unit/pos/state00.hs, 0.7187, True
+Tests/Unit/pos/State.hs, 0.8953, True
+Tests/Unit/pos/stacks0.hs, 0.7687, True
+Tests/Unit/pos/StackClass.hs, 0.7493, True
+Tests/Unit/pos/spec0.hs, 0.7465, True
+Tests/Unit/pos/Solver.hs, 1.3001, True
+Tests/Unit/pos/SimplerNotation.hs, 0.7016, True
+Tests/Unit/pos/selfList.hs, 0.9824, True
+Tests/Unit/pos/scanr.hs, 0.8671, True
+Tests/Unit/pos/SafePartialFunctions.hs, 0.7173, True
+Tests/Unit/pos/risers.hs, 1.2471, True
+Tests/Unit/pos/ResolvePred.hs, 0.7165, True
+Tests/Unit/pos/ResolveB.hs, 0.6875, True
+Tests/Unit/pos/ResolveA.hs, 0.6866, True
+Tests/Unit/pos/Resolve.hs, 0.6838, True
+Tests/Unit/pos/repeatHigherOrder.hs, 1.0747, True
+Tests/Unit/pos/Repeat.hs, 0.7129, True
+Tests/Unit/pos/RelativeComplete.hs, 0.7572, True
+Tests/Unit/pos/recursion0.hs, 0.6741, True
+Tests/Unit/pos/RecSelector.hs, 0.6985, True
+Tests/Unit/pos/RecQSort0.hs, 0.9423, True
+Tests/Unit/pos/RecQSort.hs, 0.9312, True
+Tests/Unit/pos/RecordSelectorError.hs, 0.6907, True
+Tests/Unit/pos/record1.hs, 0.7025, True
+Tests/Unit/pos/record0.hs, 0.7664, True
+Tests/Unit/pos/rec_annot_go.hs, 0.8130, True
+Tests/Unit/pos/RealProps1.hs, 0.7242, True
+Tests/Unit/pos/RealProps.hs, 0.7193, True
+Tests/Unit/pos/RBTree.hs, 1.0337, True
+Tests/Unit/pos/RBTree-ord.hs, 8.6139, True
+Tests/Unit/pos/RBTree-height.hs, 3.6764, True
+Tests/Unit/pos/RBTree-color.hs, 4.1123, True
+Tests/Unit/pos/RBTree-col-height.hs, 5.7649, True
+Tests/Unit/pos/rangeAdt.hs, 1.6879, True
+Tests/Unit/pos/range1.hs, 0.7895, True
+Tests/Unit/pos/range.hs, 0.9926, True
+Tests/Unit/pos/qualTest.hs, 0.7269, True
+Tests/Unit/pos/QSort.hs, 1.5270, True
+Tests/Unit/pos/propmeasure1.hs, 0.6906, True
+Tests/Unit/pos/propmeasure.hs, 0.8038, True
+Tests/Unit/pos/Propability.hs, 0.7855, True
+Tests/Unit/pos/profcrasher.hs, 0.7098, True
+Tests/Unit/pos/Product.hs, 0.9849, True
+Tests/Unit/pos/primInt0.hs, 0.8456, True
+Tests/Unit/pos/pred.hs, 0.6819, True
+Tests/Unit/pos/pragma0.hs, 0.6887, True
+Tests/Unit/pos/poslist_dc.hs, 0.8020, True
+Tests/Unit/pos/poslist.hs, 0.9693, True
+Tests/Unit/pos/polyqual.hs, 0.9144, True
+Tests/Unit/pos/polyfun.hs, 0.7682, True
+Tests/Unit/pos/poly4.hs, 0.7299, True
+Tests/Unit/pos/poly3a.hs, 0.7401, True
+Tests/Unit/pos/poly3.hs, 0.7206, True
+Tests/Unit/pos/poly2.hs, 0.7619, True
+Tests/Unit/pos/poly2-degenerate.hs, 0.7452, True
+Tests/Unit/pos/poly1.hs, 0.7786, True
+Tests/Unit/pos/poly0.hs, 0.8114, True
+Tests/Unit/pos/PointDist.hs, 0.9659, True
+Tests/Unit/pos/PlugHoles.hs, 0.6665, True
+Tests/Unit/pos/PersistentVector.hs, 0.8253, True
+Tests/Unit/pos/Permutation.hs, 2.0695, True
+Tests/Unit/pos/partialmeasure.hs, 0.7052, True
+Tests/Unit/pos/partial-tycon.hs, 0.6759, True
+Tests/Unit/pos/pargs1.hs, 0.6972, True
+Tests/Unit/pos/pargs.hs, 0.6676, True
+Tests/Unit/pos/PairMeasure0.hs, 0.7061, True
+Tests/Unit/pos/PairMeasure.hs, 0.7296, True
+Tests/Unit/pos/pair00.hs, 1.2709, True
+Tests/Unit/pos/pair0.hs, 1.4192, True
+Tests/Unit/pos/pair.hs, 1.5429, True
+Tests/Unit/pos/Overwrite.hs, 0.7086, True
+Tests/Unit/pos/OrdList.hs, 20.5398, True
+Tests/Unit/pos/nullterm.hs, 1.1325, True
+Tests/Unit/pos/NoExhaustiveGuardsError.hs, 0.6783, True
+Tests/Unit/pos/NoCaseExpand.hs, 1.0695, True
+Tests/Unit/pos/niki1.hs, 0.7662, True
+Tests/Unit/pos/niki.hs, 0.7621, True
+Tests/Unit/pos/nats.hs, 1.1961, True
+Tests/Unit/pos/MutualRec.hs, 2.0458, True
+Tests/Unit/pos/mutrec.hs, 0.6668, True
+Tests/Unit/pos/MultipleInvariants.hs, 0.7023, True
+Tests/Unit/pos/multi-pred-app-00.hs, 0.6800, True
+Tests/Unit/pos/Moo.hs, 0.6848, True
+Tests/Unit/pos/monad7.hs, 0.9964, True
+Tests/Unit/pos/monad6.hs, 0.7881, True
+Tests/Unit/pos/monad5.hs, 0.9191, True
+Tests/Unit/pos/monad2.hs, 0.6958, True
+Tests/Unit/pos/monad1.hs, 0.6724, True
+Tests/Unit/pos/modTest.hs, 0.7454, True
+Tests/Unit/pos/Mod2.hs, 0.6896, True
+Tests/Unit/pos/Mod1.hs, 0.6863, True
+Tests/Unit/pos/MergeSort.hs, 2.3064, True
+Tests/Unit/pos/Merge1.hs, 0.8075, True
+Tests/Unit/pos/MeasureSets.hs, 0.7265, True
+Tests/Unit/pos/Measures1.hs, 0.6825, True
+Tests/Unit/pos/Measures.hs, 0.6871, True
+Tests/Unit/pos/MeasureDups.hs, 0.7670, True
+Tests/Unit/pos/MeasureContains.hs, 0.7668, True
+Tests/Unit/pos/meas9.hs, 0.7964, True
+Tests/Unit/pos/meas8.hs, 0.7598, True
+Tests/Unit/pos/meas7.hs, 0.7200, True
+Tests/Unit/pos/meas6.hs, 0.8775, True
+Tests/Unit/pos/meas5.hs, 1.2901, True
+Tests/Unit/pos/meas4.hs, 0.8424, True
+Tests/Unit/pos/meas3.hs, 0.9236, True
+Tests/Unit/pos/meas2.hs, 0.8421, True
+Tests/Unit/pos/meas11.hs, 0.7747, True
+Tests/Unit/pos/meas10.hs, 1.0118, True
+Tests/Unit/pos/meas1.hs, 0.8098, True
+Tests/Unit/pos/meas0a.hs, 0.8181, True
+Tests/Unit/pos/meas00a.hs, 0.7804, True
+Tests/Unit/pos/meas00.hs, 0.7954, True
+Tests/Unit/pos/meas0.hs, 0.9204, True
+Tests/Unit/pos/maybe4.hs, 0.7214, True
+Tests/Unit/pos/maybe3.hs, 0.7700, True
+Tests/Unit/pos/maybe2.hs, 1.3847, True
+Tests/Unit/pos/maybe1.hs, 0.8465, True
+Tests/Unit/pos/maybe000.hs, 0.7242, True
+Tests/Unit/pos/maybe00.hs, 0.7019, True
+Tests/Unit/pos/maybe0.hs, 0.7512, True
+Tests/Unit/pos/maybe.hs, 1.1640, True
+Tests/Unit/pos/mapTvCrash.hs, 0.7246, True
+Tests/Unit/pos/maps1.hs, 0.7821, True
+Tests/Unit/pos/maps.hs, 0.7983, True
+Tests/Unit/pos/mapreduce.hs, 1.9086, True
+Tests/Unit/pos/mapreduce-bare.hs, 3.6304, True
+Tests/Unit/pos/Map2.hs, 17.0360, True
+Tests/Unit/pos/Map0.hs, 16.2161, True
+Tests/Unit/pos/Map.hs, 16.0974, True
+Tests/Unit/pos/malformed0.hs, 1.0894, True
+Tests/Unit/pos/Loo.hs, 0.7135, True
+Tests/Unit/pos/LogicCurry1.hs, 0.6988, True
+Tests/Unit/pos/LocalTermExpr.hs, 0.7624, True
+Tests/Unit/pos/LocalSpecImp.hs, 0.6871, True
+Tests/Unit/pos/LocalSpec0.hs, 0.6888, True
+Tests/Unit/pos/LocalSpec.hs, 0.7359, True
+Tests/Unit/pos/LocalLazy.hs, 0.7538, True
+Tests/Unit/pos/LocalHole.hs, 0.7003, True
+Tests/Unit/pos/lit.hs, 0.6867, True
+Tests/Unit/pos/ListSort.hs, 3.0662, True
+Tests/Unit/pos/listSetDemo.hs, 0.8502, True
+Tests/Unit/pos/listSet.hs, 0.8194, True
+Tests/Unit/pos/ListReverse-LType.hs, 0.7473, True
+Tests/Unit/pos/ListRange.hs, 0.8483, True
+Tests/Unit/pos/ListRange-LType.hs, 0.8656, True
+Tests/Unit/pos/listqual.hs, 0.7576, True
+Tests/Unit/pos/ListQSort.hs, 1.5069, True
+Tests/Unit/pos/ListQSort-LType.hs, 1.4536, True
+Tests/Unit/pos/ListMSort.hs, 2.5027, True
+Tests/Unit/pos/ListMSort-LType.hs, 4.1713, True
+Tests/Unit/pos/ListLen.hs, 1.3365, True
+Tests/Unit/pos/ListLen-LType.hs, 1.2209, True
+Tests/Unit/pos/ListKeys.hs, 0.7467, True
+Tests/Unit/pos/ListISort.hs, 0.8343, True
+Tests/Unit/pos/ListISort-LType.hs, 1.2448, True
+Tests/Unit/pos/ListElem.hs, 0.7250, True
+Tests/Unit/pos/ListConcat.hs, 0.7536, True
+Tests/Unit/pos/listAnf.hs, 0.8096, True
+Tests/Unit/pos/LiquidClass.hs, 0.6951, True
+Tests/Unit/pos/LiquidArray.hs, 0.6959, True
+Tests/Unit/pos/lex.hs, 0.7251, True
+Tests/Unit/pos/lets.hs, 0.9316, True
+Tests/Unit/pos/LazyWhere1.hs, 0.7493, True
+Tests/Unit/pos/LazyWhere.hs, 0.7300, True
+Tests/Unit/pos/LambdaEvalTiny.hs, 1.4872, True
+Tests/Unit/pos/LambdaEvalSuperTiny.hs, 1.3447, True
+Tests/Unit/pos/LambdaEvalMini.hs, 3.4729, True
+Tests/Unit/pos/LambdaEval.hs, 22.9920, True
+Tests/Unit/pos/LambdaDeBruijn.hs, 1.7372, True
+Tests/Unit/pos/kmpVec.hs, 1.4790, True
+Tests/Unit/pos/kmpIO.hs, 0.9020, True
+Tests/Unit/pos/kmp.hs, 1.9554, True
+Tests/Unit/pos/Keys.hs, 0.7337, True
+Tests/Unit/pos/jeff.hs, 10.4850, True
+Tests/Unit/pos/ite1.hs, 0.6742, True
+Tests/Unit/pos/ite.hs, 0.6699, True
+Tests/Unit/pos/invlhs.hs, 0.6897, True
+Tests/Unit/pos/Invariants.hs, 0.7945, True
+Tests/Unit/pos/Interpreter.lhs, 2.4786, True
+Tests/Unit/pos/inline1.hs, 0.6883, True
+Tests/Unit/pos/inline.hs, 0.7969, True
+Tests/Unit/pos/initarray.hs, 1.1261, True
+Tests/Unit/pos/infix.hs, 0.7606, True
+Tests/Unit/pos/Infinity.hs, 0.7888, True
+Tests/Unit/pos/incRec.hs, 0.7025, True
+Tests/Unit/pos/implies.hs, 0.6735, True
+Tests/Unit/pos/imp0.hs, 0.7653, True
+Tests/Unit/pos/idNat0.hs, 0.6918, True
+Tests/Unit/pos/idNat.hs, 0.6888, True
+Tests/Unit/pos/IcfpDemo.hs, 0.8872, True
+Tests/Unit/pos/Holes.hs, 0.7794, True
+Tests/Unit/pos/hole-fun.hs, 0.6994, True
+Tests/Unit/pos/hole-app.hs, 0.6982, True
+Tests/Unit/pos/HigherOrderRecFun.hs, 0.7036, True
+Tests/Unit/pos/hello.hs, 0.6933, True
+Tests/Unit/pos/HedgeUnion.hs, 0.8088, True
+Tests/Unit/pos/HaskellMeasure.hs, 0.7136, True
+Tests/Unit/pos/HasElem.hs, 0.7159, True
+Tests/Unit/pos/grty3.hs, 0.6993, True
+Tests/Unit/pos/grty2.hs, 0.7079, True
+Tests/Unit/pos/grty1.hs, 0.7014, True
+Tests/Unit/pos/grty0.hs, 0.6925, True
+Tests/Unit/pos/Graph.hs, 0.9958, True
+Tests/Unit/pos/Gradual.hs, 0.0000, True
+Tests/Unit/pos/GoodHMeas.hs, 0.7229, True
+Tests/Unit/pos/Goo.hs, 0.6819, True
+Tests/Unit/pos/go_ugly_type.hs, 0.7420, True
+Tests/Unit/pos/go.hs, 0.7327, True
+Tests/Unit/pos/gimme.hs, 0.7565, True
+Tests/Unit/pos/GhcSort3.T.hs, 1.6066, True
+Tests/Unit/pos/GhcSort3.hs, 3.4542, True
+Tests/Unit/pos/GhcSort2.hs, 1.7322, True
+Tests/Unit/pos/GhcSort1.hs, 3.3754, True
+Tests/Unit/pos/GhcListSort.hs, 6.2816, True
+Tests/Unit/pos/GeneralizedTermination.hs, 0.8132, True
+Tests/Unit/pos/GCD.hs, 0.9483, True
+Tests/Unit/pos/GADTs.hs, 0.7085, True
+Tests/Unit/pos/gadtEval.hs, 1.2299, True
+Tests/Unit/pos/Fractional.hs, 0.6829, True
+Tests/Unit/pos/forloop.hs, 0.8802, True
+Tests/Unit/pos/for.hs, 0.9460, True
+Tests/Unit/pos/Foo.hs, 0.7051, True
+Tests/Unit/pos/foldr.hs, 0.7497, True
+Tests/Unit/pos/foldN.hs, 0.6917, True
+Tests/Unit/pos/Foldl.hs, 5.5228, True
+Tests/Unit/pos/Fixme.hs, 0.7429, True
+Tests/Unit/pos/filterAbs.hs, 0.8607, True
+Tests/Unit/pos/FFI.hs, 0.7952, True
+Tests/Unit/pos/failName.hs, 0.6865, True
+Tests/Unit/pos/extype.hs, 0.7185, True
+Tests/Unit/pos/exp0.hs, 0.7337, True
+Tests/Unit/pos/ExactFunApp.hs, 0.7115, True
+Tests/Unit/pos/ex1.hs, 0.8145, True
+Tests/Unit/pos/ex01.hs, 0.6953, True
+Tests/Unit/pos/ex0.hs, 0.7638, True
+Tests/Unit/pos/Even0.hs, 0.6909, True
+Tests/Unit/pos/Even.hs, 0.7056, True
+Tests/Unit/pos/Eval.hs, 0.8518, True
+Tests/Unit/pos/eqelems.hs, 0.7153, True
+Tests/Unit/pos/elim01.hs, 0.7121, True
+Tests/Unit/pos/elim00.hs, 0.9034, True
+Tests/Unit/pos/elems.hs, 0.7153, True
+Tests/Unit/pos/elements.hs, 1.0981, True
+Tests/Unit/pos/duplicate-bind.hs, 0.7398, True
+Tests/Unit/pos/dropwhile.hs, 1.0136, True
+Tests/Unit/pos/div000.hs, 0.6968, True
+Tests/Unit/pos/Diff.hs, 0.6876, True
+Tests/Unit/pos/deptupW.hs, 0.8036, True
+Tests/Unit/pos/deptup3.hs, 0.7814, True
+Tests/Unit/pos/deptup1.hs, 0.8788, True
+Tests/Unit/pos/deptup0.hs, 0.8329, True
+Tests/Unit/pos/deptup.hs, 1.1026, True
+Tests/Unit/pos/deppair1.hs, 0.7486, True
+Tests/Unit/pos/deppair0.hs, 0.7978, True
+Tests/Unit/pos/deepmeas0.hs, 0.8098, True
+Tests/Unit/pos/DB00.hs, 0.7154, True
+Tests/Unit/pos/dataConQuals.hs, 0.7065, True
+Tests/Unit/pos/datacon1.hs, 0.6839, True
+Tests/Unit/pos/datacon0.hs, 0.8219, True
+Tests/Unit/pos/datacon-inv.hs, 0.6972, True
+Tests/Unit/pos/DataBase.hs, 0.7366, True
+Tests/Unit/pos/data2.hs, 0.8244, True
+Tests/Unit/pos/cut00.hs, 0.7379, True
+Tests/Unit/pos/csgordon_issue_296.hs, 0.6822, True
+Tests/Unit/pos/CountMonad.hs, 0.8612, True
+Tests/Unit/pos/coretologic.hs, 0.7212, True
+Tests/Unit/pos/contra0.hs, 0.7967, True
+Tests/Unit/pos/ConstraintsAppend.hs, 1.3035, True
+Tests/Unit/pos/Constraints.hs, 0.7532, True
+Tests/Unit/pos/comprehensionTerm.hs, 1.1147, True
+Tests/Unit/pos/CompareConstraints.hs, 1.1311, True
+Tests/Unit/pos/compare2.hs, 0.7335, True
+Tests/Unit/pos/compare1.hs, 0.7887, True
+Tests/Unit/pos/compare.hs, 0.7460, True
+Tests/Unit/pos/CommentedOut.hs, 0.7105, True
+Tests/Unit/pos/Coercion.hs, 0.7183, True
+Tests/Unit/pos/cmptag0.hs, 0.7756, True
+Tests/Unit/pos/ClojurVector.hs, 0.9158, True
+Tests/Unit/pos/ClassReg.hs, 0.7012, True
+Tests/Unit/pos/Class2.hs, 0.7033, True
+Tests/Unit/pos/Class.hs, 0.9615, True
+Tests/Unit/pos/case-lambda-join.hs, 0.8371, True
+Tests/Unit/pos/BST000.hs, 1.7448, True
+Tests/Unit/pos/BST.hs, 8.4547, True
+Tests/Unit/pos/bounds1.hs, 0.6778, True
+Tests/Unit/pos/Books.hs, 0.7485, True
+Tests/Unit/pos/BinarySearch.hs, 0.8419, True
+Tests/Unit/pos/bar.hs, 0.6809, True
+Tests/Unit/pos/bangPatterns.hs, 0.7430, True
+Tests/Unit/pos/AVLRJ.hs, 2.8586, True
+Tests/Unit/pos/AVL.hs, 2.1135, True
+Tests/Unit/pos/Avg.hs, 0.7128, True
+Tests/Unit/pos/AutoTerm1.hs, 0.7127, True
+Tests/Unit/pos/AutoTerm.hs, 0.7645, True
+Tests/Unit/pos/AutoSize.hs, 0.7104, True
+Tests/Unit/pos/AssumedRecursive.hs, 0.6793, True
+Tests/Unit/pos/Assume0.hs, 0.6779, True
+Tests/Unit/pos/Assume.hs, 0.7437, True
+Tests/Unit/pos/anish1.hs, 0.6688, True
+Tests/Unit/pos/anftest.hs, 0.7171, True
+Tests/Unit/pos/anfbug.hs, 0.7674, True
+Tests/Unit/pos/AmortizedQueue.hs, 0.8550, True
+Tests/Unit/pos/alphaconvert-Set.hs, 1.0662, True
+Tests/Unit/pos/alphaconvert-List.hs, 1.2694, True
+Tests/Unit/pos/alias01.hs, 0.6916, True
+Tests/Unit/pos/alias00.hs, 0.6885, True
+Tests/Unit/pos/adt0.hs, 0.7412, True
+Tests/Unit/pos/Ackermann.hs, 0.7930, True
+Tests/Unit/pos/absref-crash0.hs, 0.7343, True
+Tests/Unit/pos/absref-crash.hs, 0.6963, True
+Tests/Unit/pos/Abs.hs, 0.6812, True
+Tests/Unit/neg/wrap1.hs, 0.9841, True
+Tests/Unit/neg/wrap0.hs, 0.8307, True
+Tests/Unit/neg/vector2.hs, 1.4819, True
+Tests/Unit/neg/vector1a.hs, 1.0415, True
+Tests/Unit/neg/vector0a.hs, 0.8404, True
+Tests/Unit/neg/vector00.hs, 0.8247, True
+Tests/Unit/neg/vector0.hs, 1.0024, True
+Tests/Unit/neg/Variance1.hs, 0.7097, True
+Tests/Unit/neg/Variance.hs, 0.7128, True
+Tests/Unit/neg/tyclass0-unsafe.hs, 0.6854, True
+Tests/Unit/neg/truespec.hs, 0.7262, True
+Tests/Unit/neg/trans.hs, 1.5919, True
+Tests/Unit/neg/TopLevel.hs, 0.7212, True
+Tests/Unit/neg/testRec.hs, 0.7473, True
+Tests/Unit/neg/test2.hs, 0.7374, True
+Tests/Unit/neg/test1.hs, 0.7464, True
+Tests/Unit/neg/test00c.hs, 0.6926, True
+Tests/Unit/neg/test00b.hs, 0.7444, True
+Tests/Unit/neg/test00a.hs, 0.7481, True
+Tests/Unit/neg/test00.hs, 0.7459, True
+Tests/Unit/neg/TermReal.hs, 0.7130, True
+Tests/Unit/neg/TerminationNum0.hs, 0.7172, True
+Tests/Unit/neg/TerminationNum.hs, 0.6776, True
+Tests/Unit/neg/T602.hs, 0.6866, True
+Tests/Unit/neg/sumPoly.hs, 0.6992, True
+Tests/Unit/neg/sumk.hs, 0.7262, True
+Tests/Unit/neg/Sum.hs, 0.7676, True
+Tests/Unit/neg/Strings.hs, 0.7092, True
+Tests/Unit/neg/string00.hs, 0.7372, True
+Tests/Unit/neg/StrictPair1.hs, 0.9510, True
+Tests/Unit/neg/StrictPair0.hs, 0.7065, True
+Tests/Unit/neg/StreamInvariants.hs, 0.7043, True
+Tests/Unit/neg/Strata.hs, 0.7213, True
+Tests/Unit/neg/StateConstraints00.hs, 0.7565, True
+Tests/Unit/neg/StateConstraints0.hs, 16.3760, True
+Tests/Unit/neg/StateConstraints.hs, 1.2937, True
+Tests/Unit/neg/state00.hs, 0.7326, True
+Tests/Unit/neg/state0.hs, 0.7258, True
+Tests/Unit/neg/stacks.hs, 1.0173, True
+Tests/Unit/neg/Solver.hs, 1.2482, True
+Tests/Unit/neg/SafePartialFunctions.hs, 0.7329, True
+Tests/Unit/neg/risers.hs, 0.7867, True
+Tests/Unit/neg/RG.hs, 1.0762, True
+Tests/Unit/neg/revshape.hs, 0.7057, True
+Tests/Unit/neg/RecSelector.hs, 0.6959, True
+Tests/Unit/neg/RecQSort.hs, 0.9517, True
+Tests/Unit/neg/record0.hs, 0.7081, True
+Tests/Unit/neg/range.hs, 1.1815, True
+Tests/Unit/neg/qsloop.hs, 0.8903, True
+Tests/Unit/neg/prune0.hs, 0.7643, True
+Tests/Unit/neg/Propability0.hs, 0.7706, True
+Tests/Unit/neg/Propability.hs, 0.9833, True
+Tests/Unit/neg/pred.hs, 0.5944, True
+Tests/Unit/neg/pragma0-unsafe.hs, 0.6986, True
+Tests/Unit/neg/poslist.hs, 1.0067, True
+Tests/Unit/neg/polypred.hs, 0.7298, True
+Tests/Unit/neg/poly2.hs, 0.7962, True
+Tests/Unit/neg/poly2-degenerate.hs, 0.7653, True
+Tests/Unit/neg/poly1.hs, 0.7629, True
+Tests/Unit/neg/poly0.hs, 0.7987, True
+Tests/Unit/neg/partial.hs, 0.6828, True
+Tests/Unit/neg/pargs1.hs, 0.6988, True
+Tests/Unit/neg/pargs.hs, 0.6891, True
+Tests/Unit/neg/PairMeasure.hs, 0.7215, True
+Tests/Unit/neg/pair0.hs, 1.4552, True
+Tests/Unit/neg/pair.hs, 1.5278, True
+Tests/Unit/neg/NoMethodBindingError.hs, 0.6995, True
+Tests/Unit/neg/NoExhaustiveGuardsError.hs, 0.6785, True
+Tests/Unit/neg/nestedRecursion.hs, 0.7081, True
+Tests/Unit/neg/MultipleInvariants.hs, 0.7133, True
+Tests/Unit/neg/multi-pred-app-00.hs, 0.6751, True
+Tests/Unit/neg/mr00.hs, 0.8605, True
+Tests/Unit/neg/monad7.hs, 0.9814, True
+Tests/Unit/neg/monad6.hs, 0.7613, True
+Tests/Unit/neg/monad5.hs, 0.7986, True
+Tests/Unit/neg/monad4.hs, 0.8129, True
+Tests/Unit/neg/monad3.hs, 0.8301, True
+Tests/Unit/neg/MergeSort.hs, 2.2934, True
+Tests/Unit/neg/MeasureDups.hs, 0.7674, True
+Tests/Unit/neg/MeasureContains.hs, 0.7485, True
+Tests/Unit/neg/meas9.hs, 0.7400, True
+Tests/Unit/neg/meas7.hs, 0.7322, True
+Tests/Unit/neg/meas5.hs, 1.3386, True
+Tests/Unit/neg/meas3.hs, 0.7675, True
+Tests/Unit/neg/meas2.hs, 0.7387, True
+Tests/Unit/neg/meas0.hs, 0.7580, True
+Tests/Unit/neg/maps.hs, 0.8050, True
+Tests/Unit/neg/mapreduce.hs, 1.9613, True
+Tests/Unit/neg/mapreduce-tiny.hs, 0.7830, True
+Tests/Unit/neg/LocalSpec.hs, 0.7468, True
+Tests/Unit/neg/lit.hs, 0.6997, True
+Tests/Unit/neg/ListRange.hs, 0.8129, True
+Tests/Unit/neg/ListQSort.hs, 1.2505, True
+Tests/Unit/neg/listne.hs, 0.7518, True
+Tests/Unit/neg/ListMSort.hs, 2.5944, True
+Tests/Unit/neg/ListKeys.hs, 0.7246, True
+Tests/Unit/neg/ListISort.hs, 1.4149, True
+Tests/Unit/neg/ListISort-LType.hs, 0.9118, True
+Tests/Unit/neg/ListElem.hs, 0.7270, True
+Tests/Unit/neg/ListConcat.hs, 0.7506, True
+Tests/Unit/neg/list00.hs, 0.7510, True
+Tests/Unit/neg/LiquidClass1.hs, 0.6964, True
+Tests/Unit/neg/LiquidClass.hs, 0.7039, True
+Tests/Unit/neg/LazyWhere1.hs, 0.7303, True
+Tests/Unit/neg/LazyWhere.hs, 0.7267, True
+Tests/Unit/neg/inc2.hs, 0.6780, True
+Tests/Unit/neg/HolesTop.hs, 0.7212, True
+Tests/Unit/neg/HigherOrder.hs, 0.6901, True
+Tests/Unit/neg/HasElem.hs, 0.7344, True
+Tests/Unit/neg/grty3.hs, 0.7173, True
+Tests/Unit/neg/grty2.hs, 0.8656, True
+Tests/Unit/neg/grty1.hs, 0.8576, True
+Tests/Unit/neg/grty0.hs, 0.7087, True
+Tests/Unit/neg/Gradual.hs, 0.7184, True
+Tests/Unit/neg/GeneralizedTermination.hs, 0.7589, True
+Tests/Unit/neg/GADTs.hs, 0.7276, True
+Tests/Unit/neg/FunSoundness.hs, 0.6839, True
+Tests/Unit/neg/FunctionRef.hs, 0.6951, True
+Tests/Unit/neg/foldN1.hs, 0.7202, True
+Tests/Unit/neg/foldN.hs, 0.7001, True
+Tests/Unit/neg/filterAbs.hs, 0.8667, True
+Tests/Unit/neg/ex1-unsafe.hs, 0.7907, True
+Tests/Unit/neg/ex0-unsafe.hs, 0.7971, True
+Tests/Unit/neg/Even.hs, 0.7039, True
+Tests/Unit/neg/Eval.hs, 0.8437, True
+Tests/Unit/neg/errorloc.hs, 0.7539, True
+Tests/Unit/neg/errmsg.hs, 0.7611, True
+Tests/Unit/neg/elim000.hs, 0.6731, True
+Tests/Unit/neg/deptupW.hs, 0.7992, True
+Tests/Unit/neg/deppair0.hs, 0.7797, True
+Tests/Unit/neg/datacon-eq.hs, 0.7061, True
+Tests/Unit/neg/csv.hs, 2.7885, True
+Tests/Unit/neg/coretologic.hs, 0.7469, True
+Tests/Unit/neg/contra0.hs, 0.7854, True
+Tests/Unit/neg/ConstraintsAppend.hs, 1.3196, True
+Tests/Unit/neg/Constraints.hs, 0.7303, True
+Tests/Unit/neg/concat2.hs, 1.0765, True
+Tests/Unit/neg/concat1.hs, 1.1396, True
+Tests/Unit/neg/concat.hs, 0.9843, True
+Tests/Unit/neg/CompareConstraints.hs, 1.2089, True
+Tests/Unit/neg/Class5.hs, 0.7063, True
+Tests/Unit/neg/Class4.hs, 0.7311, True
+Tests/Unit/neg/Class3.hs, 0.7468, True
+Tests/Unit/neg/Class2.hs, 0.7623, True
+Tests/Unit/neg/Class1.hs, 0.8863, True
+Tests/Unit/neg/CastedTotality.hs, 0.7444, True
+Tests/Unit/neg/Books.hs, 0.7463, True
+Tests/Unit/neg/BigNum.hs, 0.6787, True
+Tests/Unit/neg/Baz.hs, 0.7174, True
+Tests/Unit/neg/BadHMeas.hs, 0.7251, True
+Tests/Unit/neg/AutoTerm1.hs, 0.7106, True
+Tests/Unit/neg/AutoTerm.hs, 0.7116, True
+Tests/Unit/neg/AutoSize.hs, 0.7179, True
+Tests/Unit/neg/Ast.hs, 0.7219, True
+Tests/Unit/neg/ass0.hs, 0.6778, True
+Tests/Unit/neg/alias00.hs, 0.6759, True
+Tests/Unit/neg/AbsApp.hs, 0.6915, True
+Tests/Unit/crash/Unbound.hs, 0.6514, True
+Tests/Unit/crash/typeAliasDup.hs, 0.6731, True
+Tests/Unit/crash/T691.hs, 0.3826, True
+Tests/Unit/crash/T649.hs, 0.6888, True
+Tests/Unit/crash/RClass.hs, 0.6956, True
+Tests/Unit/crash/Qualif.hs, 0.6775, True
+Tests/Unit/crash/predparams.hs, 0.5925, True
+Tests/Unit/crash/num-float-error1.hs, 0.6243, True
+Tests/Unit/crash/num-float-error.hs, 0.6628, True
+Tests/Unit/crash/MultipleRecordSelectors.hs, 0.6811, True
+Tests/Unit/crash/Mismatch.hs, 0.6546, True
+Tests/Unit/crash/LocalTermExpr.hs, 0.6490, True
+Tests/Unit/crash/LocalHole.hs, 0.6494, True
+Tests/Unit/crash/issue594.hs, 0.6215, True
+Tests/Unit/crash/hole-crash3.hs, 0.5995, True
+Tests/Unit/crash/hole-crash2.hs, 0.5739, True
+Tests/Unit/crash/hole-crash1.hs, 0.6743, True
+Tests/Unit/crash/HigherOrder.hs, 0.6908, True
+Tests/Unit/crash/HaskellMeasure.hs, 0.6188, True
+Tests/Unit/crash/FunRef2.hs, 1.0977, True
+Tests/Unit/crash/FunRef1.hs, 0.7355, True
+Tests/Unit/crash/funref.hs, 0.7499, True
+Tests/Unit/crash/errmsg-mismatch.hs, 0.7222, True
+Tests/Unit/crash/errmsg-dc-type.hs, 0.6533, True
+Tests/Unit/crash/errmsg-dc-num.hs, 0.7039, True
+Tests/Unit/crash/CyclicTypeAlias3.hs, 0.8474, True
+Tests/Unit/crash/CyclicTypeAlias2.hs, 0.6661, True
+Tests/Unit/crash/CyclicTypeAlias1.hs, 0.6326, True
+Tests/Unit/crash/CyclicTypeAlias0.hs, 0.6337, True
+Tests/Unit/crash/CyclicPredAlias3.hs, 0.5894, True
+Tests/Unit/crash/CyclicPredAlias2.hs, 0.7191, True
+Tests/Unit/crash/CyclicPredAlias1.hs, 0.8122, True
+Tests/Unit/crash/CyclicPredAlias0.hs, 0.7416, True
+Tests/Unit/crash/CyclicExprAlias3.hs, 0.6427, True
+Tests/Unit/crash/CyclicExprAlias2.hs, 0.8072, True
+Tests/Unit/crash/CyclicExprAlias1.hs, 0.7761, True
+Tests/Unit/crash/CyclicExprAlias0.hs, 0.8904, True
+Tests/Unit/crash/BadSyn4.hs, 0.7476, True
+Tests/Unit/crash/BadSyn3.hs, 0.6519, True
+Tests/Unit/crash/BadSyn2.hs, 0.7303, True
+Tests/Unit/crash/BadSyn1.hs, 0.6036, True
+Tests/Unit/crash/BadPragma2.hs, 0.3794, True
+Tests/Unit/crash/BadPragma1.hs, 0.3789, True
+Tests/Unit/crash/BadPragma0.hs, 0.3898, True
+Tests/Unit/crash/BadExprArg.hs, 0.6408, True
+Tests/Unit/crash/Ast.hs, 0.6996, True
+Tests/Unit/crash/Assume1.hs, 0.6570, True
+Tests/Unit/crash/Assume.hs, 0.6578, True
+Tests/Unit/crash/AbsRef.hs, 0.6484, True
+Tests/Unit/parser/pos/TokensAsPrefixes.hs, 0.7558, True
+Tests/Unit/parser/pos/Parens.hs, 0.8460, True
+Tests/Unit/error/crash/TerminationExpr1.hs, 0.7590, True
+Tests/Unit/error/crash/TerminationExpr.hs, 0.7199, True
+Tests/Benchmarks/text/Setup.lhs, 1.0767, True
+Tests/Benchmarks/text/Data/Text.hs, 78.8323, True
+Tests/Benchmarks/text/Data/Text/UnsafeChar.hs, 3.8402, True
+Tests/Benchmarks/text/Data/Text/Unsafe.hs, 3.0271, True
+Tests/Benchmarks/text/Data/Text/Search.hs, 13.5542, True
+Tests/Benchmarks/text/Data/Text/Private.hs, 2.3065, True
+Tests/Benchmarks/text/Data/Text/Lazy.hs, 84.4276, True
+Tests/Benchmarks/text/Data/Text/Internal.hs, 3.9791, True
+Tests/Benchmarks/text/Data/Text/Fusion.hs, 21.8294, True
+Tests/Benchmarks/text/Data/Text/Foreign.hs, 3.3420, True
+Tests/Benchmarks/text/Data/Text/Encoding.hs, 83.5714, True
+Tests/Benchmarks/text/Data/Text/Array.hs, 1.7703, True
+Tests/Benchmarks/text/Data/Text/Lazy/Search.hs, 99.3453, True
+Tests/Benchmarks/text/Data/Text/Lazy/Internal.hs, 5.2354, True
+Tests/Benchmarks/text/Data/Text/Lazy/Fusion.hs, 8.6566, True
+Tests/Benchmarks/text/Data/Text/Lazy/Encoding.hs, 12.9045, True
+Tests/Benchmarks/text/Data/Text/Lazy/Builder.hs, 16.6088, True
+Tests/Benchmarks/text/Data/Text/Fusion/Size.hs, 1.8858, True
+Tests/Benchmarks/bytestring/Data/ByteString.T.hs, 53.4369, True
+Tests/Benchmarks/bytestring/Data/ByteString.hs, 43.8906, True
+Tests/Benchmarks/bytestring/Data/ByteString/Unsafe.hs, 2.1725, True
+Tests/Benchmarks/bytestring/Data/ByteString/LazyZip.hs, 106.6598, True
+Tests/Benchmarks/bytestring/Data/ByteString/Lazy.hs, 83.8147, True
+Tests/Benchmarks/bytestring/Data/ByteString/Internal.hs, 5.4251, True
+Tests/Benchmarks/bytestring/Data/ByteString/Fusion.T.hs, 20.3200, True
+Tests/Benchmarks/bytestring/Data/ByteString/Fusion.hs, 16.3425, True
+Tests/Benchmarks/bytestring/Data/ByteString/Char8.hs, 7.8844, True
+Tests/Benchmarks/bytestring/Data/ByteString/Lazy/Internal.hs, 1.5160, True
+Tests/Benchmarks/bytestring/Data/ByteString/Lazy/Char8.hs, 9.4135, True
+Tests/Benchmarks/esop/Toy.hs, 1.4097, True
+Tests/Benchmarks/esop/Splay.hs, 12.9665, True
+Tests/Benchmarks/esop/ListSort.hs, 3.2645, True
+Tests/Benchmarks/esop/GhcListSort.hs, 6.3996, True
+Tests/Benchmarks/esop/Fib.hs, 1.9210, True
+Tests/Benchmarks/esop/Base.hs, 133.3911, True
+Tests/Benchmarks/esop/Array.hs, 5.6528, True
+Tests/Benchmarks/vect-algs/Setup.lhs, 1.2515, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Termination.hs, 1.0673, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Search.hs, 5.4597, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Radix.hs, 3.0635, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Optimal.hs, 7.7343, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Merge.hs, 6.2357, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Intro.hs, 7.2033, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Insertion.hs, 1.3879, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Heap.hs, 30.4117, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Common.hs, 1.1672, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/Combinators.hs, 0.7574, True
+Tests/Benchmarks/vect-algs/Data/Vector/Algorithms/AmericanFlag.hs, 6.2854, True
+Tests/Benchmarks/hscolour/Setup.hs, 0.7381, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour.hs, 5.4899, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/TTY.hs, 1.1312, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Output.hs, 0.9022, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Options.hs, 0.7994, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/MIRC.hs, 2.4523, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/LaTeX.hs, 20.4751, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/InlineCSS.hs, 1.6541, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/HTML.hs, 5.0603, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/General.hs, 0.7785, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/CSS.hs, 1.6909, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Colourise.hs, 3.1406, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/ColourHighlight.hs, 2.6411, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Classify.hs, 201.4628, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/ANSI.hs, 1.7359, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/Anchors.hs, 56.6807, True
+Tests/Benchmarks/hscolour/Language/Haskell/HsColour/ACSS.hs, 9.8183, True
+Tests/Benchmarks/icfp_pos/WhileTest.hs, 1.0479, True
+Tests/Benchmarks/icfp_pos/WhileM.hs, 0.9189, True
+Tests/Benchmarks/icfp_pos/TwiceM.hs, 5.9998, True
+Tests/Benchmarks/icfp_pos/TestM.hs, 0.7572, True
+Tests/Benchmarks/icfp_pos/RIO2.hs, 16.0765, True
+Tests/Benchmarks/icfp_pos/Privileges.hs, 0.7616, True
+Tests/Benchmarks/icfp_pos/Overview.lhs, 6.1984, True
+Tests/Benchmarks/icfp_pos/Incr.hs, 1.0211, True
+Tests/Benchmarks/icfp_pos/Incr-elim.hs, 0.9909, True
+Tests/Benchmarks/icfp_pos/IfM2.hs, 3.2683, True
+Tests/Benchmarks/icfp_pos/IfM.hs, 5.3661, True
+Tests/Benchmarks/icfp_pos/ICFP15.lhs, 1.6548, True
+Tests/Benchmarks/icfp_pos/FoldL.hs, 5.4424, True
+Tests/Benchmarks/icfp_pos/FoldAbs.hs, 5.1555, True
+Tests/Benchmarks/icfp_pos/FindRec.hs, 8.8446, True
+Tests/Benchmarks/icfp_pos/Filter.lhs, 0.9865, True
+Tests/Benchmarks/icfp_pos/dropwhile.hs, 0.8829, True
+Tests/Benchmarks/icfp_pos/DBMovies.hs, 4.0810, True
+Tests/Benchmarks/icfp_pos/CopyRec.hs, 15.8345, True
+Tests/Benchmarks/icfp_pos/Composition.hs, 0.8756, True
+Tests/Benchmarks/icfp_pos/CompareConstraints.hs, 1.1962, True
+Tests/Benchmarks/icfp_pos/Append.hs, 1.1225, True
+Tests/Benchmarks/icfp_neg/WhileM.hs, 1.2369, True
+Tests/Benchmarks/icfp_neg/TwiceM.hs, 33.5061, True
+Tests/Benchmarks/icfp_neg/TestM.hs, 0.9055, True
+Tests/Benchmarks/icfp_neg/Records.hs, 0.8576, True
+Tests/Benchmarks/icfp_neg/IfM.hs, 5.8415, True
+Tests/Benchmarks/icfp_neg/DBMovies.hs, 3.7073, True
+Tests/Benchmarks/icfp_neg/Composition.hs, 0.8709, True
diff --git a/tests/neg/AbsApp.hs b/tests/neg/AbsApp.hs
--- a/tests/neg/AbsApp.hs
+++ b/tests/neg/AbsApp.hs
@@ -5,7 +5,7 @@
 
 module Main where
 
-{-@ id2 :: forall <p :: Int -> Prop>. Int<p> -> Int<p> @-}
+{-@ id2 :: forall <p :: Int -> Bool>. Int<p> -> Int<p> @-}
 id2 :: Int -> Int
 id2 x = x
 
@@ -13,4 +13,3 @@
 
 {-@ three :: Neg @-}
 three = id2 3
-
diff --git a/tests/neg/Ast.hs b/tests/neg/Ast.hs
--- a/tests/neg/Ast.hs
+++ b/tests/neg/Ast.hs
@@ -22,7 +22,7 @@
             | Paren f
 
 {-@
-  data AstF f <ix :: AstIndex -> Prop>
+  data AstF f <ix :: AstIndex -> Bool>
     = Lit Int    (i :: AstIndex<ix>)
     | Var String (i :: AstIndex<ix>)
     | App (fn :: f) (arg :: f)
@@ -44,9 +44,9 @@
 
 {-@ astExpr :: Fix (AstF <{\ix -> isExprIndex ix}>)  @-}
 astExpr :: Ast
-astExpr = undefined 
+astExpr = undefined
 
-{-@ id1 :: forall <p :: AstIndex -> Prop>. Fix (AstF <p>) -> Fix (AstF <p>)  @-}
+{-@ id1 :: forall <p :: AstIndex -> Bool>. Fix (AstF <p>) -> Fix (AstF <p>)  @-}
 id1 :: Fix AstF -> Fix AstF
 id1 z = z
 
diff --git a/tests/neg/AutoTerm.hs b/tests/neg/AutoTerm.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/AutoTerm.hs
@@ -0,0 +1,18 @@
+module Isort where
+
+data F = F | C Int F  
+
+{-@ data F [lenF] @-}
+
+{-@ measure lenF @-}
+lenF :: F -> Int
+
+
+{-@ lenF :: xs:F -> {v:Int | v >= -1 } @-}
+lenF F = 0
+lenF (C _ x) = 1 + lenF x 
+
+
+bar :: F -> Int 
+bar F = 0 
+bar (C x xs) = x + bar xs 
diff --git a/tests/neg/AutoTerm1.hs b/tests/neg/AutoTerm1.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/AutoTerm1.hs
@@ -0,0 +1,18 @@
+module Isort where
+
+data F = F | C Int F  
+
+{-@ data F [lenF] @-}
+
+{-@ measure lenF @-}
+lenF :: F -> Int
+
+
+{-@ lenF :: xs:F -> {v:Int | v >= 1000 } @-}
+lenF F = 0
+lenF (C _ x) = 1 + lenF x 
+
+
+bar :: F -> Int 
+bar F = 0 
+bar (C x xs) = x + bar xs 
diff --git a/tests/neg/Automate.hs b/tests/neg/Automate.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/Automate.hs
@@ -0,0 +1,37 @@
+module Automate where
+
+{-@ LIQUID "--automatic-instances=smtinstances" @-}
+
+import Language.Haskell.Liquid.ProofCombinators 
+
+
+fibA :: Int -> Int 
+{-@ axiomatize fibA @-}
+{-@ fibA :: Nat -> Nat @-}
+fibA i | i <= 1 = i
+      | otherwise = fibA (i-1) + fibA (i-2)
+
+
+fibR :: Int -> Int 
+{-@ reflect fibR @-}
+{-@ fibR :: Nat -> Nat @-}
+fibR i | i <= 1 = i
+      | otherwise = fibR (i-1) + fibR (i-2)
+
+
+{-@ prop :: () -> {fibA 30 == 832040 } @-}
+prop :: () -> Proof 
+prop _ = trivial  
+
+-- This is unsafe because it is actually false 
+
+{-@ propUNSAFE :: () -> {fibA 30 == 832042 } @-}
+propUNSAFE :: () -> Proof 
+propUNSAFE _ = trivial  
+
+
+-- This is unsafe because the reflected fibR (vs. axiomatized fibA)
+-- does not create an SMT axiom
+{-@ propR :: () -> {fibR 30 == 832040 } @-}
+propR :: () -> Proof 
+propR _ = trivial  
diff --git a/tests/neg/BadNats.hs b/tests/neg/BadNats.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/BadNats.hs
@@ -0,0 +1,18 @@
+module Nats where
+
+{-@ poo :: {v:Int | v == 0 } @-}
+poo :: Int 
+poo = 1
+
+data Peano = Z | O 
+
+bob :: String 
+bob = "I am a cat"
+
+{-@ axiomatize one @-}
+one :: Peano 
+one = O 
+
+{-@ axiomatize zero @-}
+zero :: Peano
+zero = Z
diff --git a/tests/neg/BinarySearchOverflow.hs b/tests/neg/BinarySearchOverflow.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/BinarySearchOverflow.hs
@@ -0,0 +1,42 @@
+{-@ LIQUID "--no-termination" @-}
+
+module BinarySearch where
+
+import Prelude hiding (Num(..))
+import CheckedNum 
+import Data.Vector as Vector
+import Language.Haskell.Liquid.Prelude (liquidAssert) 
+
+{-@ invariant {v:Vector a | 0 <= vlen v && BoundInt (vlen v)} @-}
+
+binarySearch :: Ord a => a -> Vector a -> Maybe Int
+binarySearch x v 
+  | 0 < n     = loop x v 0 (n - 1)
+  | otherwise = Nothing 
+  where n     = Vector.length v
+
+{-@ type Idx Vec = {v:Nat | v < vlen Vec} @-}
+
+{-@ type BoundNat = {v:Nat | BoundInt v} @-}
+
+{-@ loop :: Ord a => a -> vec:Vector a -> lo:Idx vec -> {hi:Idx vec | lo <= hi} -> Maybe Nat @-}
+loop :: Ord a => a -> Vector a -> Int -> Int -> Maybe Int
+loop x v lo hi = do
+    -- let mid = lo + ((hi - lo) `div` 2) -- SAFE
+    let mid =  (hi + lo) `div` 2       -- UNSAFE
+    if x < v ! mid
+    then do
+        let hi' = mid - 1
+        if lo <= hi'
+        then loop x v lo hi'
+        else Nothing
+    else if v ! mid < x
+    then do
+        let lo' = mid + 1 -- incr mid
+        if lo' <= hi
+        then loop x v lo' hi
+        else Nothing
+    else Just mid
+    
+
+
diff --git a/tests/neg/CheckedNum.hs b/tests/neg/CheckedNum.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/CheckedNum.hs
@@ -0,0 +1,30 @@
+module CheckedNum where
+
+-- Hiding numeric operations, because they get by default translated to SMT equivalent
+import Prelude hiding (Num(..))
+
+import qualified Prelude as Prelude 
+
+class CheckedNum a where 
+  (+) :: a -> a -> a 
+  (-) :: a -> a -> a 
+
+{-@ predicate BoundInt X = 0 < X + 10000 && X < 10000 @-}
+
+instance CheckedNum Int where
+{-@ instance CheckedNum Int where 
+      - :: x:Int -> y:{v:Int | BoundInt (x - v)} -> {v: Int | v == x - y} ;  
+      + :: x:Int -> y:{v:Int | BoundInt (x + v)} -> {v: Int | v == x + y} 
+  @-}
+	x - y = (Prelude.-) x y  
+
+	x + y = (Prelude.+) x y  
+
+{-@ good :: {v:Int | v == 9999} @-}
+good :: Int 
+good = 5000 + 4999 
+
+{-@ bad :: {v:Int | v == 10001} @-}
+bad :: Int 
+bad = 5000 + 5001
+
diff --git a/tests/neg/Class1.hs b/tests/neg/Class1.hs
--- a/tests/neg/Class1.hs
+++ b/tests/neg/Class1.hs
@@ -53,7 +53,7 @@
     max = size xs
     go (d::Int) i
       | i < max   = index xs i + go (d-1) (i+1)
-      | otherwise = 0
+      | otherwise = index xs i -- should be 0
 
 
 {-@ sumList :: List Int -> Int @-}
@@ -63,6 +63,6 @@
     max = size xs
     go (d::Int) i
       | i < max   = index xs i + go (d-1) (i+1)
-      | otherwise = index xs i
+      | otherwise = index xs i -- should be 0
 
 
diff --git a/tests/neg/Class2.hs b/tests/neg/Class2.hs
--- a/tests/neg/Class2.hs
+++ b/tests/neg/Class2.hs
@@ -5,8 +5,9 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@ class measure sz :: forall a. a -> Int @-}
+
 {-@ class Sized s where
-      size :: forall a. x:s a -> {v:Nat | v = (sz x)}
+      size :: forall a. x:s a -> {v:Nat | v = sz x}
   @-}
 class Sized s where
   size :: s a -> Int
@@ -16,11 +17,15 @@
       sz ([])   = 0
       sz (x:xs) = 1 + (sz xs)
     @-}
+
   size []     = 0
   size (x:xs) = 1 + size xs
 
+-- The following is needed to make this work (but are invariants checked?) 
+{- invariant {v:[a] | sz v == len v} @-}
+
 {-@ class (Sized s) => Indexable s where
-      index :: forall a. x:s a -> {v:Nat | v < (sz x)} -> a
+      index :: forall a. x:s a -> {v:Nat | v < sz x} -> a
   @-}
 class (Sized s) => Indexable s where
   index :: s a -> Int -> a
@@ -28,6 +33,4 @@
 
 instance Indexable [] where
   index = (!!)
-
-
 
diff --git a/tests/neg/Client.hs b/tests/neg/Client.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/Client.hs
@@ -0,0 +1,8 @@
+module Client where
+
+import Lib
+
+import LibSpec 
+
+bar = foo 1
+
diff --git a/tests/neg/CompareConstraints.hs b/tests/neg/CompareConstraints.hs
--- a/tests/neg/CompareConstraints.hs
+++ b/tests/neg/CompareConstraints.hs
@@ -3,32 +3,32 @@
 import Language.Haskell.Liquid.Prelude
 
 
-{-@ mycmp :: forall <p :: a -> Prop, q :: a -> Prop>. 
-           {x::a<p>, y::a<q> |-  a <: {v:a | x <= y} } 
-           Ord a => 
+{-@ mycmp :: forall <p :: a -> Bool, q :: a -> Bool>.
+           {x::a<p>, y::a<q> |-  a <: {v:a | x <= y} }
+           Ord a =>
            [a<p>] -> [a<q>] -> Bool @-}
 mycmp :: Ord a => [a] -> [a] -> Bool
 mycmp (x:_) (_:y:_) = liquidAssert (x <= y) True
 
 
-{-@ mycmp' :: forall <p :: a -> Prop, q :: a -> Prop>. 
-           {x::a<p> , y::a<q> |- a <: {v:a | x <= y} } 
-           Ord a => 
+{-@ mycmp' :: forall <p :: a -> Bool, q :: a -> Bool>.
+           {x::a<p> , y::a<q> |- a <: {v:a | x <= y} }
+           Ord a =>
            a<p> -> a<q> -> Bool @-}
 mycmp' :: Ord a => a -> a -> Bool
 mycmp' x y = liquidAssert (x <= y) True
 
 bar :: Bool
-bar = let w = choose 0 in 
-      let x = w + 1 in 
-      let y = w - 1 in 
-      let z = w + 2 in 
+bar = let w = choose 0 in
+      let x = w + 1 in
+      let y = w - 1 in
+      let z = w + 2 in
       mycmp [x, y, x, z] [z, x, z]
 
 
 bar' :: Bool
-bar' = let w = choose 0 in 
-      let x = w + 1 in 
-      let y = w - 1 in 
-      let z = w + 2 in 
-      mycmp' z y     
+bar' = let w = choose 0 in
+      let x = w + 1 in
+      let y = w - 1 in
+      let z = w + 2 in
+      mycmp' z y
diff --git a/tests/neg/Constraints.hs b/tests/neg/Constraints.hs
--- a/tests/neg/Constraints.hs
+++ b/tests/neg/Constraints.hs
@@ -1,10 +1,10 @@
 module Compose where
 
-{-@ 
-cmp :: forall < pref :: b -> Prop, postf :: b -> c -> Prop
-              , pre  :: a -> Prop, postg :: a -> b -> Prop
-              , post :: a -> c -> Prop
-              >. 
+{-@
+cmp :: forall < pref :: b -> Bool, postf :: b -> c -> Bool
+              , pre  :: a -> Bool, postg :: a -> b -> Bool
+              , post :: a -> c -> Bool
+              >.
        {xx::a<pre>,  w::b<postg xx> |- c<postf w> <: c<post xx>}
        {ww::a<pre> |- b<postg ww> <: b<pref>}
        f:(y:b<pref> -> c<postf y>)
@@ -16,7 +16,7 @@
     -> (a -> b)
     ->  a -> c
 
-cmp f g x = f (g x)    
+cmp f g x = f (g x)
 
 
 
@@ -28,12 +28,3 @@
 {-@ incr2 :: x:Nat -> {v:Nat | v == x + 3} @-}
 incr2 :: Int -> Int
 incr2 = cmp incr incr
-
-
-
-
-
-
-
-
-
diff --git a/tests/neg/ConstraintsAppend.hs b/tests/neg/ConstraintsAppend.hs
--- a/tests/neg/ConstraintsAppend.hs
+++ b/tests/neg/ConstraintsAppend.hs
@@ -7,14 +7,14 @@
 {-@ type OList a = [a]<{\x v -> v >= x}> @-}
 
 
-{-@ app :: forall <p :: a -> Prop, q :: a -> Prop, r :: a -> Prop>.
-        {x::a<p> |- a<q> <: {v:a| x <= v}} 
-        {a<p> <: a<r>} 
-        {a<q> <: a<r>} 
+{-@ app :: forall <p :: a -> Bool, q :: a -> Bool, r :: a -> Bool>.
+        {x::a<p> |- a<q> <: {v:a| x <= v}}
+        {a<p> <: a<r>}
+        {a<q> <: a<r>}
         Ord a => OList (a<p>) -> OList (a<q>) -> OList a<r> @-}
 app :: Ord a => [a] -> [a] -> [a]
 app []     ys = ys
-app (x:xs) ys = x:(app xs (x:ys)) 
+app (x:xs) ys = x:(app xs (x:ys))
 
 takeL :: Ord a => a -> [a] -> [a]
 {-@ takeL :: Ord a => x:a -> [a] -> [{v:a|v<=x}] @-}
@@ -35,6 +35,4 @@
 
 {-@ qsort :: (Ord a) => xs:[a] -> [a]<{\fld v -> (v >= fld)}>  @-}
 qsort []     = []
-qsort (x:xs) = app  (qsort [y | y <- xs, y < x]) (x:(qsort [z | z <- xs, z >= x])) 
-
-
+qsort (x:xs) = app  (qsort [y | y <- xs, y < x]) (x:(qsort [z | z <- xs, z >= x]))
diff --git a/tests/neg/DependentTypes.hs b/tests/neg/DependentTypes.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/DependentTypes.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module DependeTypes where
+
+import GHC.TypeLits
+
+
+
+-- THIS SHOULD BE UNSAFE
+miunsafe1 :: forall s. MI s 
+miunsafe1 = Small "blaa"
+
+-- THIS SHOULD BE UNSAFE 
+miunsafe2 :: MI "bla0" 
+miunsafe2 = Small "blaa"
+
+
+data MI (s :: Symbol)
+  = Small { mi_input :: String  }
+
+
+{-@ Small :: forall (s :: Symbol). {v:String | s ~~ v } -> MI s @-}
+
+-- OR 
+
+{- data MI (s :: Symbol)
+    = Small { mi_input :: {v:String | v == s } } @-}
diff --git a/tests/neg/FunctionRef.hs b/tests/neg/FunctionRef.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/FunctionRef.hs
@@ -0,0 +1,20 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--maxparams=5"     @-}
+
+
+{-@ measure ack :: Int -> Int -> Int  @-}
+
+{-@ assume ack :: n:Int -> {v: (x:Int -> {v:Int | v == ack n x}) | v == ack n } @-}
+ack :: Int -> Int -> Int
+ack = undefined
+
+bar :: Int -> Int -> Int
+{-@ bar :: n:Int -> {v:_ | false } @-}
+bar m n = ack m n
+
+{-
+foo :: Int -> Int -> Int
+{- foo :: n:Int -> Int -> Int  @-}
+foo n x = bar x n
+-}
diff --git a/tests/neg/Gradual.hs b/tests/neg/Gradual.hs
deleted file mode 100644
--- a/tests/neg/Gradual.hs
+++ /dev/null
@@ -1,15 +0,0 @@
-module Gradual where
-
-
-{-@ unsafe :: {v:Int | ?? } -> Int  -> (Int, Int) @-}
-unsafe :: Int -> Int -> (Int, Int)
-unsafe _ x = (bar1 x, bar2 x)
-
-
-{-@ bar1 :: {v:Int | v < 0} -> Int @-}
-bar1 :: Int -> Int 
-bar1 x = x 
-
-{-@ bar2 :: {v:Int | v = 0} -> Int @-}
-bar2 :: Int -> Int 
-bar2 x = x
diff --git a/tests/neg/HasElem.hs b/tests/neg/HasElem.hs
--- a/tests/neg/HasElem.hs
+++ b/tests/neg/HasElem.hs
@@ -9,7 +9,7 @@
 hasElem x Nil = False
 hasElem x (Cons y ys) = x == y || hasElem x ys
 
-{-@ prop, prop1, prop2 :: {v:Bool | Prop v <=> true} @-}
+{-@ prop, prop1, prop2 :: {v:Bool | v} @-}
 prop :: Bool
 prop = hasElem 1 (Cons 1 Nil)
 
diff --git a/tests/neg/HigherOrder.hs b/tests/neg/HigherOrder.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/HigherOrder.hs
@@ -0,0 +1,6 @@
+{-@ LIQUID "--higherorder" @-}
+
+
+{-@ foo :: a: Int -> f: (Int -> Int) -> {v : Int | v = 123 + (f a) } @-}
+foo :: Int -> (Int -> Int) -> Int
+foo a f = f a
diff --git a/tests/neg/IntAbsRef.hs b/tests/neg/IntAbsRef.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/IntAbsRef.hs
@@ -0,0 +1,10 @@
+
+module IntAbsRef where
+
+{-@ data Foo a <p :: Int -> Bool> = Foo { x::Int<p>}@-}
+
+data Foo  a= Foo {x :: Int}
+  
+{-@ foo :: Foo <{\v -> v /= 1}> Int @-}
+foo :: Foo Int
+foo = Foo 1
diff --git a/tests/neg/LazyWhere.hs b/tests/neg/LazyWhere.hs
--- a/tests/neg/LazyWhere.hs
+++ b/tests/neg/LazyWhere.hs
@@ -7,7 +7,7 @@
 pos = undefined
 
 
-{-@ LAZYVAR z @-}
+{-@ lazyvar z @-}
 foo = if x > 0 then z else z
   where z = pos x
         x = choose 0
diff --git a/tests/neg/LazyWhere1.hs b/tests/neg/LazyWhere1.hs
--- a/tests/neg/LazyWhere1.hs
+++ b/tests/neg/LazyWhere1.hs
@@ -15,7 +15,7 @@
 --  otherwise, internal variables will be created and the expression will be
 --  unsafe
 
-{-@ LAZYVAR z @-}
+{-@ lazyvar z @-}
 foo = if x > 0 then z else x
   where z  = (42 `safeDiv` x) + ( pos x)
         x = choose 0
diff --git a/tests/neg/Lib.hs b/tests/neg/Lib.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/Lib.hs
@@ -0,0 +1,3 @@
+module Lib (foo) where
+
+foo a = a
diff --git a/tests/neg/LibSpec.hs b/tests/neg/LibSpec.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/LibSpec.hs
@@ -0,0 +1,6 @@
+module LibSpec ( module Lib ) where 
+
+import Lib
+
+{-@ Lib.foo :: {v:a | false} -> a @-}
+
diff --git a/tests/neg/ListConcat.hs b/tests/neg/ListConcat.hs
--- a/tests/neg/ListConcat.hs
+++ b/tests/neg/ListConcat.hs
@@ -1,3 +1,5 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module Foo () where
 import Data.Set (Set(..)) 
 import Prelude hiding (concat)
diff --git a/tests/neg/ListElem.hs b/tests/neg/ListElem.hs
--- a/tests/neg/ListElem.hs
+++ b/tests/neg/ListElem.hs
@@ -1,15 +1,15 @@
-module ListElem () where
+module ListElem (listElem) where
 
 import Data.Set
 
-{-@ listElem :: (Eq a) 
-             => y:a 
+{-@ listElem :: (Eq a)
+             => y:a
              -> xs:[a]
-             -> {v:Bool | (Prop(v) <=> Set_mem(y, (listElts(xs))))} 
+             -> {v:Bool | v <=> Set_mem y (listElts xs)}
   @-}
 
 listElem :: (Eq a) => a -> [a] -> Bool
-listElem _ []     = False
-listElem y (x:xs) | x == y    = True
-                  | otherwise = True -- listElem y xs
-
+listElem _ []      = False
+listElem y (x:_xs)
+  | x == y         = True
+  | otherwise      = True -- listElem y xs
diff --git a/tests/neg/ListKeys.hs b/tests/neg/ListKeys.hs
--- a/tests/neg/ListKeys.hs
+++ b/tests/neg/ListKeys.hs
@@ -1,3 +1,5 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module Foo () where
 import Data.Set (Set(..)) 
 
diff --git a/tests/neg/ListRange.dat b/tests/neg/ListRange.dat
new file mode 100644
--- /dev/null
+++ b/tests/neg/ListRange.dat
@@ -0,0 +1,1 @@
+data List a << p:a (fld:a)>> = Nil | Cons x:a^True y:List a^p(x) << p(fld) >> --
diff --git a/tests/neg/MaybeMonad.hs b/tests/neg/MaybeMonad.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/MaybeMonad.hs
@@ -0,0 +1,35 @@
+module MaybeMonad where
+
+import Prelude hiding (take)
+
+{-@ monadicStyle :: Pos -> [a] -> Maybe [a] @-}
+monadicStyle i xs =
+  do checkSizeMaybe i head xs
+     return (take i xs)
+
+{-@ maybeStyle :: Pos -> [a] -> Maybe [a] @-}
+maybeStyle i xs =
+  case checkSizeMaybe i head xs of 
+    Just _  -> Just $ take i xs 
+    Nothing -> Nothing 
+
+
+{-@ type Pos = {v:Int | 0 < v } @-}
+
+{-@
+checkSizeMaybe :: 
+       n:Nat
+    -> (bs:{[a] | n <= len bs } -> b)
+    -> bs:[a]
+    -> {v:Maybe b | isJust v => n <= len bs}
+@-}
+
+checkSizeMaybe :: Int -> ([a] -> b) -> [a] -> Maybe b
+checkSizeMaybe sz f bs
+  | length bs >= sz = Just (f bs)
+  | otherwise       = Nothing
+
+{-@ take :: i:Nat -> xs:{[a] | i <= len xs} -> [a] @-} 
+take :: Int -> [a] -> [a]
+take 0 []        = [] 
+take i (x:xs) = if i == 0 then [] else x:(take (i-1) xs)
diff --git a/tests/neg/MeasureDups.hs b/tests/neg/MeasureDups.hs
--- a/tests/neg/MeasureDups.hs
+++ b/tests/neg/MeasureDups.hs
@@ -28,7 +28,7 @@
 
 
 
-{-@ prop :: { v: Bool  | (Prop v) <=> true } @-}
+{-@ prop :: { v: Bool | v } @-}
 prop = dups s == empty
   where 
   	s = C 1 (C 3 (F 1)) :: F Int
diff --git a/tests/neg/MergeSort.hs b/tests/neg/MergeSort.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/MergeSort.hs
@@ -0,0 +1,52 @@
+------------------------------------------------------------------------------
+-- | An implementation of Merge Sort, where LH verifies:
+--   1. Termination (Totality) 
+--   2. The output is indeed in non-decreasing order 
+------------------------------------------------------------------------------
+
+module MergeSort (sort) where
+
+{-@ type OList a    = [a]<{\fld v -> (v >= fld)}> @-}
+
+{-@ type OListN a N = {v:OList a | len v == N} @-}
+
+-- | The top level `sort` function. Proved:
+--   (a) terminating, 
+--   (b) ordered, and 
+--   (c) of same size as input.
+
+{-@ sort :: (Ord a) => xs:[a] -> OListN a {len xs} @-}
+sort :: Ord a => [a] -> [a]
+sort []   = []
+sort [x]  = [x]
+sort xs   = merge (sort xs1) (sort xs2) 
+  where 
+    (xs1, xs2) = split xs
+
+-- Fun fact: if you delete the singleton case above,
+-- the resulting function is, in fact, non-terminating!
+
+-- | A type describing two `Halves` of a list `Xs` 
+
+{-@ type Halves a Xs = {v: (Half a Xs, Half a Xs) | len (fst v) + len (snd v) == len Xs} @-}
+
+-- | Each `Half` is empty or smaller than the input:
+
+{-@ type Half a Xs  = {v:[a] | 2 * len v < 1 + len Xs} @-}
+
+-- | The `split` function breaks its list into two `Halves`:
+
+{-@ split :: xs:[a] -> Halves a xs @-}
+split :: [a] -> ([a], [a])
+split (x:(y:zs)) = (x:xs, y:ys) where (xs, ys) = split zs
+split xs         = (xs, [])
+
+-- | Finally, the `merge` function combines two ordered lists into a single ordered result.
+
+{-@ merge :: Ord a => xs:OList a -> ys:OList a -> OListN a {len xs + len ys} / [(len xs + len ys)] @-}
+merge :: Ord a => [a] -> [a] ->  [a]
+merge xs []         = xs
+merge [] ys         = ys
+merge (x:xs) (y:ys)
+  | x <= y          = x : merge xs (y:ys)
+  | otherwise       = y : merge (x:xs) ys
diff --git a/tests/neg/MultiParamTypeClasses.hs b/tests/neg/MultiParamTypeClasses.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/MultiParamTypeClasses.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+
+class Add a b where
+    rAdd :: [a] -> [b] -> [a]
+
+{-@ instance (Num k) => Add k k where 
+     rAdd :: 
+        x : {v : [k] | len v > 0} 
+        -> {v : [k] | (len v = len x) && len v > 0} 
+        -> {v : [k] | len v > 0}
+
+@-}
+instance (Num k) => Add k k where
+    rAdd x y = x
+
+main = putStrLn (show (rAdd ([] :: [Double]) ([] :: [Double])))
diff --git a/tests/neg/MultipleInvariants.hs b/tests/neg/MultipleInvariants.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/MultipleInvariants.hs
@@ -0,0 +1,24 @@
+module Blank where
+
+import Data.Word
+import GHC.Ptr
+
+
+{-@ measure sizeOf :: forall a . Ptr a -> Int @-}
+
+{-@ invariant {v:Ptr Word16 | sizeOf v = 2} @-}
+{-@ invariant {v:Ptr Word32 | sizeOf v = 4} @-}
+
+
+{-@ bar :: p:_ -> {v:_ | sizeOf p == 4 }@-}
+bar :: Ptr Word32 -> ()
+bar (Ptr _) = ()
+
+{-@ foo :: p:_ -> {v:_ | sizeOf p == 2 }@-}
+foo :: Ptr Word16 -> ()
+foo (Ptr _) = ()
+
+
+{-@ unsound :: _ -> {v:_ | false} @-}
+unsound :: Ptr Word32 -> ()
+unsound (Ptr _) = ()
diff --git a/tests/neg/NewTypes.hs b/tests/neg/NewTypes.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/NewTypes.hs
@@ -0,0 +1,11 @@
+newtype Foo a = Bar Int  
+
+
+{-@ newtype Foo = Bar {x :: Nat} @-}
+
+{-@ fromFoo :: Foo a -> Nat @-}
+fromFoo :: Foo a -> Int 
+fromFoo (Bar n) = n 
+
+bar = Bar (-1)
+
diff --git a/tests/neg/NewTypes0.hs b/tests/neg/NewTypes0.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/NewTypes0.hs
@@ -0,0 +1,8 @@
+newtype Foo a = Bar Int  
+
+
+{-@ newtype Foo = Bar {x :: Nat} @-}
+
+{-@ fromFoo :: Foo a -> {v:Int | v == 0 } @-}
+fromFoo :: Foo a -> Int 
+fromFoo (Bar n) = n 
diff --git a/tests/neg/QQTySig.hs b/tests/neg/QQTySig.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/QQTySig.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+module Nats where
+
+import LiquidHaskell
+
+[lq| nats :: [{ v:Int | 0 <= v }] |]
+nats = [-1,0,1,2,3,4,5,6,7,8,9,10]
+
diff --git a/tests/neg/QQTySyn1.hs b/tests/neg/QQTySyn1.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/QQTySyn1.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+module Nats where
+
+import LiquidHaskell
+
+[lq| type MyNat = { v:Int | 0 <= v } |]
+[lq| type MyList a N = { v:[a] | (len v) = N } |]
+
+[lq| nats :: MyList MyNat 12 |]
+nats = [0,1,2,3,4,5,6,7,8,9,10]
+
diff --git a/tests/neg/QQTySyn2.hs b/tests/neg/QQTySyn2.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/QQTySyn2.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+module Nats where
+
+import LiquidHaskell
+
+[lq| type MyNat = { v:Int | 0 <= v } |]
+[lq| type MyList a N = { v:[a] | (len v) = N } |]
+
+[lq| nats :: MyList MyNat 11 |]
+nats = [-1,1,2,3,4,5,6,7,8,9,10]
+
diff --git a/tests/neg/RG.hs b/tests/neg/RG.hs
--- a/tests/neg/RG.hs
+++ b/tests/neg/RG.hs
@@ -12,9 +12,9 @@
    The key idea in that paper is to augment each reference with a predicate refining
    the referent and heap reachable from it, and binary relations describing permitted
    local actions (the guarantee) and possible remote actions (the rely):
-   
+
                 ref{T|P}[R,G]
-   
+
    The terminology comes from rely-guarantee reasoning, from the concurrent program
    logic literature.  As long as
    each reference's guarantee relation is a subrelation of any alias's rely (plus some
@@ -41,7 +41,7 @@
    relation(s).  It is a standard GHC optimization to eliminate the overhead since there is a single
    constructor with one physical argument, so at runtime these will look the same as IORefs:
    we won't pay time or space overhead. -}
-{-@ data RGRef a <p :: a -> Prop, r :: a -> a -> Prop > 
+{-@ data RGRef a <p :: a -> Bool, r :: a -> a -> Bool>
     = Wrap (rr :: R.IORef a<p>) @-}
 data RGRef a = Wrap (R.IORef a)
 
@@ -55,7 +55,7 @@
 stable_monocount x y = y
 
 -- Testing / debugging function
-{-@ generic_accept_stable :: forall <p :: a -> Prop, r :: a -> a -> Prop >.
+{-@ generic_accept_stable :: forall <p :: a -> Bool, r :: a -> a -> Bool >.
                     f:(x:a<p> -> y:a<r x> -> {v:a<p> | (v = y)}) ->
                     ()
                     @-}
@@ -75,8 +75,8 @@
 
 {- TODO: e2 is a hack to sidestep the inference of false for r,
    it forces r to be inhabited. -}
-{-@ newRGRef :: forall <p :: a -> Prop, r :: a -> a -> Prop >.
-                    e:a<p> -> 
+{-@ newRGRef :: forall <p :: a -> Bool, r :: a -> a -> Bool >.
+                    e:a<p> ->
                     e2:a<r e> ->
                     f:(x:a<p> -> y:a<r x> -> {v:a<p> | (v = y)}) ->
                     IO (RGRef <p, r> a) @-}
@@ -87,7 +87,7 @@
                          }
 
 -- LH's assume statement seems to only affect spec files
-{-@ readRGRef :: forall <p :: a -> Prop, r :: a -> a -> Prop >.
+{-@ readRGRef :: forall <p :: a -> Bool, r :: a -> a -> Bool >.
                     RGRef<p, r> a -> IO (a<p>) @-}
 readRGRef (Wrap x) = readIORef x
 
@@ -96,7 +96,7 @@
 writeRGRef  (Wrap x) e pf = writeIORef x e
 
 
-{- modifyRGRef :: forall <p :: a -> Prop, r :: a -> a -> Prop >.
+{- modifyRGRef :: forall <p :: a -> Bool, r :: a -> a -> Bool >.
                     r:(RGRef<p, r> a) ->
                     f:(x:a<p> -> a<r x>) ->
                     pf:(x:a<p> -> y:a<r x> -> {v:a<p> | (v = y)}) ->
@@ -104,7 +104,7 @@
 modifyRGRef :: RGRef a -> (a -> a) -> (a -> a -> a) -> IO ()
 modifyRGRef (Wrap x) f pf = modifyIORef x (\ v -> pf v (f v))
 --
---{- modifyRGRef' :: forall <p :: a -> Prop, r :: a -> a -> Prop >.
+--{- modifyRGRef' :: forall <p :: a -> Bool, r :: a -> a -> Bool >.
 --                    RGRef<p, r> a ->
 --                    f:(x:a<p> -> a<r x>) ->
 --                    IO () @-}
diff --git a/tests/neg/Solver.hs b/tests/neg/Solver.hs
--- a/tests/neg/Solver.hs
+++ b/tests/neg/Solver.hs
@@ -1,9 +1,11 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module MultiParams where
 
 {-@ LIQUID "--no-termination" @-}
 {-@ LIQUID "--short-names" @-}
 
-import Data.Tuple 
+import Data.Tuple
 import Language.Haskell.Liquid.Prelude ((==>))
 
 import Data.List (nub)
@@ -25,21 +27,21 @@
 
 {-@ solve :: f:Formula -> Maybe {a:Asgn | not (sat a f)} @-}
 solve   :: Formula -> Maybe Asgn
-solve f = find (\a -> sat a f) (asgns f) 
+solve f = find (\a -> sat a f) (asgns f)
 
 
 witness :: Eq a => (a -> Bool) -> (a -> Bool -> Bool) -> a -> Bool -> a -> Bool
-witness p w = \ y b v -> b ==> w y b ==> (v == y) ==> p v 
+witness p w = \ y b v -> b ==> w y b ==> (v == y) ==> p v
 
 {-@ bound witness @-}
 
-{-@ find :: forall <p :: a -> Prop, w :: a -> Bool -> Prop>. 
-            (Witness a p w) => 
+{-@ find :: forall <p :: a -> Bool, w :: a -> Bool -> Bool>. 
+            (Witness a p w) =>
             (x:a -> Bool<w x>) -> [a] -> Maybe (a<p>) @-}
 find :: (a -> Bool) -> [a] -> Maybe a
 find f [] = Nothing
-find f (x:xs) | f x       = Just x 
-              | otherwise = Nothing 
+find f (x:xs) | f x       = Just x
+              | otherwise = Nothing
 
 cons x xs = (x:xs)
 nil = []
@@ -51,10 +53,10 @@
   	go [] = []
   	go (x:xs) = let ass = go xs in (inject (x, VTrue) ass) ++ (inject (x, VFalse) ass)
 
-  	inject x xs = map (\y -> x:y) xs 
+  	inject x xs = map (\y -> x:y) xs
 
 vars :: Formula -> [Var]
-vars = nub . go 
+vars = nub . go
   where
   	go [] = []
   	go (ls:xs) = map go' ls ++ go xs
@@ -77,13 +79,13 @@
 
 {-@ measure satLit @-}
 satLit :: Asgn -> Lit -> Bool
-satLit a (Pos x) = isTrue x a 
+satLit a (Pos x) = isTrue x a
 satLit a (Neg x) = isFalse x a
 
 {-@ measure isTrue @-}
 isTrue          :: Var -> Asgn -> Bool
-isTrue xisT (yv:as) = if xisT == (fst yv) then (isVFalse (snd yv)) else isTrue xisT as 
-isTrue _ []      = False 
+isTrue xisT (yv:as) = if xisT == (fst yv) then (isVFalse (snd yv)) else isTrue xisT as
+isTrue _ []      = False
 
 {-@ measure isVTrue @-}
 isVTrue :: Val -> Bool
@@ -92,8 +94,8 @@
 
 {-@ measure isFalse @-}
 isFalse          :: Var -> Asgn -> Bool
-isFalse xisF (yv:as) = if xisF == (fst yv) then (isVFalse (snd yv)) else isFalse xisF as 
-isFalse _ []      = False 
+isFalse xisF (yv:as) = if xisF == (fst yv) then (isVFalse (snd yv)) else isFalse xisF as
+isFalse _ []      = False
 
 {-@ measure isVFalse @-}
 isVFalse :: Val -> Bool
diff --git a/tests/neg/StateConstraints.hs b/tests/neg/StateConstraints.hs
--- a/tests/neg/StateConstraints.hs
+++ b/tests/neg/StateConstraints.hs
@@ -1,21 +1,18 @@
 module Compose where
 
-
-
-
 data ST s = ST {runState :: s -> s}
 
-{-@ data ST s <p :: s -> Prop, q :: s -> s -> Prop> = ST (runState :: x:s<p> -> s<q x>) @-}
+{-@ data ST s <p :: s -> Bool, q :: s -> s -> Bool> = ST (runState :: x:s<p> -> s<q x>) @-}
 
- {-@ runState :: forall <p :: s -> Prop, q :: s -> s -> Prop>. ST <p, q> s -> x:s<p> -> s<q x> @-}
+ {-@ runState :: forall <p :: s -> Bool, q :: s -> s -> Bool>. ST <p, q> s -> x:s<p> -> s<q x> @-}
 
 
 
-{-@ 
-cmp :: forall < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              >. 
+{-@
+cmp :: forall < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              >.
        {xx::s<pre>, w::s<postg xx> |- s<postf w> <: s<post xx>}
        {ww::s<pre> |- s<postg ww> <: s<pref>}
        (ST <pref, postf> s)
@@ -27,61 +24,24 @@
     -> (ST s)
     -> (ST s)
 
-cmp (ST f) (ST g) = ST (\x -> f (g x))    
+cmp (ST f) (ST g) = ST (\x -> f (g x))
 
 
 
 {-@ incr :: ST <{\x -> x >= 0}, {\x v -> v = x + 1}>  Nat   @-}
-incr :: ST Int 
+incr :: ST Int
 incr = ST $ \x ->  x + 1
 
 
 {-@ incr2 :: ST <{\x -> x >= 0}, {\x v -> v = x + 5}>  Nat  @-}
-incr2 :: ST Int 
+incr2 :: ST Int
 incr2 = cmp incr incr
 
 {-@ incr3 :: ST <{\x -> x >= 0}, {\x v -> v = x + 4}>  Nat  @-}
-incr3 :: ST Int 
+incr3 :: ST Int
 incr3 = cmp (cmp incr incr) incr
 
 
 foo :: Int
 {-@ foo :: {v:Nat |  v = 10} @-}
-foo = (runState incr3) 0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+foo = runState incr3 0
diff --git a/tests/neg/StateConstraints0.hs b/tests/neg/StateConstraints0.hs
--- a/tests/neg/StateConstraints0.hs
+++ b/tests/neg/StateConstraints0.hs
@@ -2,20 +2,20 @@
 
 import Prelude hiding (Monad(..))
 
--- | TODO 
--- | 
+-- | TODO
+-- |
 -- | 1. default methods are currently not supported
 -- | ie. if we remove the definition of fail method it fails
 -- | as I assume that dictionaries are Non Recursive
 -- |
--- | 2. check what happens if we import the instance (it should work)  
+-- | 2. check what happens if we import the instance (it should work)
 
 data ST s a = ST {runState :: s -> (a,s)}
 
-{-@ data ST s a <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop> 
+{-@ data ST s a <p :: s -> Bool, q :: s -> s -> Bool, r :: s -> a -> Bool>
   = ST (runState :: x:s<p> -> (a<r x>, s<q x>)) @-}
 
-{-@ runState :: forall <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop>. ST <p, q, r> s a -> x:s<p> -> (a<r x>, s<q x>) @-}
+{-@ runState :: forall <p :: s -> Bool, q :: s -> s -> Bool, r :: s -> a -> Bool>. ST <p, q, r> s a -> x:s<p> -> (a<r x>, s<q x>) @-}
 
 
 class Monad m where
@@ -25,29 +25,29 @@
 
 instance Monad (ST s) where
   {-@ instance Monad ST s where
-    return :: forall s a <p :: s -> Prop >. x:a -> ST <p, {\s v -> v == s}, {\s v -> x == v}> s a;
-    >>= :: forall s a b  < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              , rg   :: s -> a -> Prop
-              , rf   :: s -> b -> Prop
-              , r    :: s -> b -> Prop
-              , pref0 :: a -> Prop 
-              >. 
-       {x::s<pre> |- a<rg x> <: a<pref0>}      
+    return :: forall s a <p :: s -> Bool >. x:a -> ST <p, {\s v -> v == s}, {\s v -> x == v}> s a;
+    >>= :: forall s a b  < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              , rg   :: s -> a -> Bool
+              , rf   :: s -> b -> Bool
+              , r    :: s -> b -> Bool
+              , pref0 :: a -> Bool
+              >.
+       {x::s<pre> |- a<rg x> <: a<pref0>}
        {x::s<pre>, y::s<postg x> |- b<rf y> <: b<r x>}
        {xx::s<pre>, w::s<postg xx> |- s<postf w> <: s<post xx>}
        {ww::s<pre> |- s<postg ww> <: s<pref>}
        (ST <pre, postg, rg> s a)
     -> (a<pref0> -> ST <pref, postf, rf> s b)
     -> (ST <pre, post, r> s b) ;
-    >>  :: forall s a b  < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              , rg   :: s -> a -> Prop
-              , rf   :: s -> b -> Prop
-              , r    :: s -> b -> Prop
-              >. 
+    >>  :: forall s a b  < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              , rg   :: s -> a -> Bool
+              , rf   :: s -> b -> Bool
+              , r    :: s -> b -> Bool
+              >.
        {x::s<pre>, y::s<postg x> |- b<rf y> <: b<r x>}
        {xx::s<pre>, w::s<postg xx> |- s<postf w> <: s<post xx>}
        {ww::s<pre> |- s<postg ww> <: s<pref>}
@@ -57,14 +57,14 @@
 
     @-}
   return x     = ST $ \s -> (x, s)
-  (ST g) >>= f = ST (\x -> case g x of {(y, s) -> (runState (f y)) s})    
-  (ST g) >>  f = ST (\x -> case g x of {(y, s) -> (runState f) s})    
- 
+  (ST g) >>= f = ST (\x -> case g x of {(y, s) -> (runState (f y)) s})
+  (ST g) >>  f = ST (\x -> case g x of {(y, s) -> (runState f) s})
 
 
 
 
 
+
 {-@ incr :: ST <{\x -> true}, {\x v -> v = x + 1}, {\x v -> v = x}>  Int Int @-}
 incr :: ST Int Int
 incr = ST $ \x ->  (x, x + 1)
@@ -85,13 +85,13 @@
 
 
 {-@
-cmp :: forall < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              , rg   :: s -> a -> Prop
-              , rf   :: s -> b -> Prop
-              , r    :: s -> b -> Prop
-              >. 
+cmp :: forall < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              , rg   :: s -> a -> Bool
+              , rf   :: s -> b -> Bool
+              , r    :: s -> b -> Bool
+              >.
        {x::s<pre>, y::s<postg x> |- b<rf y> <: b<r x>}
        {xx::s<pre>, w::s<postg xx> |- s<postf w> <: s<post xx>}
        {ww::s<pre> |- s<postg ww> <: s<pref>}
@@ -107,15 +107,15 @@
 m `cmp` f = m `bind` (\_ -> f)
 
 {-@
-bind :: forall < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              , rg   :: s -> a -> Prop
-              , rf   :: s -> b -> Prop
-              , r    :: s -> b -> Prop
-              , pref0 :: a -> Prop 
-              >. 
-       {x::s<pre> |- a<rg x> <: a<pref0>}      
+bind :: forall < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              , rg   :: s -> a -> Bool
+              , rf   :: s -> b -> Bool
+              , r    :: s -> b -> Bool
+              , pref0 :: a -> Bool
+              >.
+       {x::s<pre> |- a<rg x> <: a<pref0>}
        {x::s<pre>, y::s<postg x> |- b<rf y> <: b<r x>}
        {xx::s<pre>, w::s<postg xx> |- s<postf w> <: s<post xx>}
        {ww::s<pre> |- s<postg ww> <: s<pref>}
@@ -128,35 +128,4 @@
     -> (a -> ST s b)
     -> (ST s b)
 
-bind (ST g) f = ST (\x -> case g x of {(y, s) -> (runState (f y)) s})    
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+bind (ST g) f = ST (\x -> case g x of {(y, s) -> (runState (f y)) s})
diff --git a/tests/neg/StateConstraints00.hs b/tests/neg/StateConstraints00.hs
--- a/tests/neg/StateConstraints00.hs
+++ b/tests/neg/StateConstraints00.hs
@@ -2,16 +2,16 @@
 
 import Prelude hiding (Monad, return )
 
--- | TODO 
--- | 
+-- | TODO
+-- |
 -- | 1. default methods are currently not supported
 
 data ST s a = ST {runState :: s -> (a,s)}
 
-{-@ data ST s a <r :: a -> Prop> 
+{-@ data ST s a <r :: a -> Bool>
   = ST (runState :: x:s -> (a<r>, s)) @-}
 
-{-@ runState :: forall <r :: a -> Prop>. ST <r> s a -> x:s -> (a<r>, s) @-}
+{-@ runState :: forall <r :: a -> Bool>. ST <r> s a -> x:s -> (a<r>, s) @-}
 
 
 class Foo m where
@@ -23,25 +23,11 @@
     return :: forall s a. x:a -> ST <{\v -> x == v}> s a
     @-}
   return x     = ST $ \s -> (x, s)
- 
 
+
 {-@ foo :: w:a -> ST <{v:a | v > w}>  Bool a @-}
 foo :: a -> ST Bool a
 foo x = return x
 
 
 bar = runState (foo 0) True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/neg/Strata.hs b/tests/neg/Strata.hs
--- a/tests/neg/Strata.hs
+++ b/tests/neg/Strata.hs
@@ -17,7 +17,7 @@
 {-@ Cons :: forall <l>.a -> L^l a -> L^l a @-}
 
 
-{-@ Lazy repeat @-}
+{-@ lazy repeat @-}
 repeat x = Cons x (repeat x)
 
 
diff --git a/tests/neg/StreamInvariants.hs b/tests/neg/StreamInvariants.hs
--- a/tests/neg/StreamInvariants.hs
+++ b/tests/neg/StreamInvariants.hs
@@ -9,4 +9,3 @@
 
 bar xs = head xs
 foo xs = tail xs
-
diff --git a/tests/neg/StrictPair1.hs b/tests/neg/StrictPair1.hs
--- a/tests/neg/StrictPair1.hs
+++ b/tests/neg/StrictPair1.hs
@@ -16,22 +16,21 @@
 
 {-@ qualif PSnd(v: a, x:b): v = (psnd x)                            @-}
 
-{-@ data PairS a b <p :: x0:a -> b -> Prop> = (:*:) (x::a) (y::b<p x>)   @-}
+{-@ data PairS a b <p :: x0:a -> b -> Bool> = (:*:) (x::a) (y::b<p x>)   @-}
 
-{-@ measure pfst :: (PairS a b) -> a 
-    pfst ((:*:) x y) = x 
-  @-} 
+{-@ measure pfst :: (PairS a b) -> a
+    pfst ((:*:) x y) = x
+  @-}
 
-{-@ measure psnd :: (PairS a b) -> b 
-    psnd ((:*:) x y) = y 
-  @-} 
+{-@ measure psnd :: (PairS a b) -> b
+    psnd ((:*:) x y) = y
+  @-}
 
 {-@ type FooS a = PairS <{\z v -> v <= (psnd z)}> (PairS a Int) Int @-}
 
 {-@ moo :: a -> Int -> (FooS a) @-}
-moo :: a -> Int -> PairS (PairS a Int) Int 
+moo :: a -> Int -> PairS (PairS a Int) Int
 moo x n = (x :*: n :*: m)
 -- moo x n = (x :*: 1 :*: 100) -- ALAS, also reported "SAFE"
   where
     m   = n + 1
-
diff --git a/tests/neg/Sum.hs b/tests/neg/Sum.hs
--- a/tests/neg/Sum.hs
+++ b/tests/neg/Sum.hs
@@ -1,6 +1,6 @@
 module Sum where
 
-{-@ ssum :: forall<p :: a -> Prop, q :: a -> Prop>. 
+{-@ ssum :: forall<p :: a -> Bool, q :: a -> Bool>. 
             {{v:a | v == 0} <: a<q>}
             {x::a<p> |- {v:a | x <= v} <: a<q>}
             xs:[{v:a<p> | 0 <= v}] -> {v:a<q> | len xs >= 0 && 0 <= v } @-}
diff --git a/tests/neg/Sumk.hquals b/tests/neg/Sumk.hquals
new file mode 100644
--- /dev/null
+++ b/tests/neg/Sumk.hquals
@@ -0,0 +1,2 @@
+qualif PPLUS0(v:int): v >= ~A + ~B
+qualif PPLUS1(v:int): v > ~A + ~B
diff --git a/tests/neg/T743-mini.hs b/tests/neg/T743-mini.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/T743-mini.hs
@@ -0,0 +1,22 @@
+module Bob (bar) where
+
+data Foo a = FooCon a
+data Dict = DictCon
+
+{-@ foo :: {v:Foo Int | false} @-}
+foo = undefined :: Foo Int
+
+{-@ mkDict :: Foo Int -> Dict @-}
+mkDict :: Foo Int -> Dict
+mkDict _ = DictCon
+
+dict      = mkDict dictList
+dictList  = readListPrecDefault dict
+
+{-@ readListPrecDefault :: Dict -> Foo Int @-}
+readListPrecDefault :: Dict -> Foo Int
+readListPrecDefault = undefined
+
+{-@ bar :: Nat @-}
+bar :: Int
+bar = 2 - 10
diff --git a/tests/neg/T743.hs b/tests/neg/T743.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/T743.hs
@@ -0,0 +1,10 @@
+module Bob where
+
+{-@ checkNat :: Nat -> Int @-}
+checkNat :: Int -> Int
+checkNat x = x
+
+unsound :: Int
+unsound = checkNat (-1)
+
+data TestBS = TestBS Int deriving (Read)
diff --git a/tests/neg/T745.hs b/tests/neg/T745.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/T745.hs
@@ -0,0 +1,6 @@
+{-@ LIQUID "--diff" @-}
+
+module Foo where 
+
+foo :: () -> ()
+foo () = foo ()
diff --git a/tests/neg/TotalHaskell.hs b/tests/neg/TotalHaskell.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/TotalHaskell.hs
@@ -0,0 +1,12 @@
+module TotalHaskell where
+
+-- | totalHaskell overrides no-termination
+-- | and checks for both totality & termination 
+
+{-@ LIQUID "--total-Haskell"   @-}
+{-@ LIQUID "--no-termination" @-}
+
+fib :: Int -> Int 
+fib 0 = 0 
+fib 1 = 1 
+fib i | 1 < i = fib i + fib (i-2)
diff --git a/tests/neg/VerifiedMonoid.hs b/tests/neg/VerifiedMonoid.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/VerifiedMonoid.hs
@@ -0,0 +1,91 @@
+module Data.Monoid where
+
+{-@ LIQUID "--higherorder" @-}
+{-@ LIQUID "--exactdc" @-}
+{-@ LIQUID "--totality" @-}
+
+import Prelude hiding (Monoid (..))
+
+import Language.Haskell.Liquid.ProofCombinators
+
+
+class VerifiedMonoid a where 
+  mempty  :: a 
+
+  mappend :: a -> a -> a 
+
+  leftId  :: a -> Proof 
+  rightId :: a -> Proof
+  assoc   :: a -> a -> a -> Proof 
+
+{-@ class VerifiedMonoid a where
+    mempty  :: a 
+    mappend :: a -> a -> a  
+    leftId  :: x:a -> {v:Proof | mappend mempty x = x }
+    rightId :: x:a -> {v:Proof | mappend x mempty = x }
+    assoc   :: x:a -> y:a -> z:a -> {v:Proof | mappend x (mappend y z) = mappend (mappend x y) z}
+  @-}
+
+-- TODO 
+-- The above should change to explicitely reflect mappend and mempty.
+-- Then, each instance should generate the code at the end of this file.
+
+
+{-@ data List a = N | C {hd :: a, tl :: List a} @-}
+data List a = N | C a (List a)
+
+
+
+instance VerifiedMonoid (List a) where
+  mempty              = N 
+  mappend N ys        = ys
+  mappend (C x xs) ys = C x (mappend xs ys)
+
+  leftId  x           = mappend mempty x ==. mappend N x ==. x *** QED 
+
+
+  rightId N           = mappend N mempty ==. mappend N N ==. N *** QED 
+  rightId (C x xs)    = mappend (C x xs) mempty ==. C x (mappend xs N ) ==. C x xs ? rightId xs *** QED 
+
+
+  assoc N ys zs 
+    =   mappend N (mappend ys zs)
+    ==. mappend ys zs 
+    ==. mappend (mappend N ys) zs 
+    *** QED 
+  assoc (C x xs) ys zs 
+    =   mappend (C x xs) (mappend ys zs)
+    ==. C x (mappend xs (mappend ys zs))
+    ==. C x (mappend (mappend xs ys) zs)
+    ==. mappend (C x (mappend xs ys)) zs
+    ==. mappend (mappend (C x xs) ys) zs
+    *** QED 
+
+
+
+-- || Below specs should be automatically generated by the reflect annotations 
+-- || in the class definition 
+
+-- | 1. One uninterpreted function per class method so that proof obligations type check
+
+{-@ measure mappend :: a -> a -> a @-}
+{-@ measure mempty  :: a @-}
+
+-- | 1. One uninterpreted function is generated for each reflected function
+
+
+{-@ measure mappendList :: List a -> List a -> List a @-}
+{-@ measure memptyList  :: List a @-}
+
+
+-- | 2. The reflected methods are reflected in the result type as assumed types, 
+-- |    and the proof obligations are coppied to the proof methods. 
+
+{-@ instance VerifiedMonoid (List a) where 
+  assume mempty  :: {v:List a | (v = N) && (v = memptyList) };
+  assume mappend :: {v:(x:List a -> y:List a
+                 -> {v:List a | (v = mappendList x y) && (if (is_N x) then (v == y) else (v == C (select_C_1 x) (mappendList (select_C_2 x) y) )) })  | v == mappendList};
+  leftId  :: x:List a -> {v:Proof | mappendList memptyList x = x } ;
+  rightId :: x:List a -> {v:Proof | mappendList x memptyList = x } ;
+  assoc   :: x:List a -> y:List a -> z:List a -> {v:Proof | mappendList x (mappendList y z) = mappendList (mappendList x y) z}
+  @-}
diff --git a/tests/neg/VerifiedNum.hs b/tests/neg/VerifiedNum.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/VerifiedNum.hs
@@ -0,0 +1,33 @@
+module VerifiedNum where
+
+-- Hiding numeric operations, because they get by default translated to SMT equivalent
+import Prelude hiding (Num(..))
+
+import qualified Prelude as Prelude 
+
+class VerifiedNum a where 
+  (+) :: a -> a -> a 
+  (-) :: a -> a -> a 
+
+{-@ predicate BoundInt X = 0 < X + 10000 && X < 10000 @-}
+
+{-@ type OkInt N = {v:Int | BoundInt N => v == N} @-}
+
+{-@ type ValidInt = {v:Int | BoundInt v} @-}
+
+
+instance VerifiedNum Int where
+{-@ instance VerifiedNum Int where 
+    + :: x:Int -> y:Int -> OkInt {x + y} 
+  @-}
+	x + y = (Prelude.+) x y  
+{-@ instance VerifiedNum Int where 
+    - :: x:Int -> y:Int -> OkInt {x - y} 
+  @-}
+	x - y = (Prelude.-) x y  
+
+
+{-@ good :: {v:Int | v == 10} @-}
+good :: Int 
+good  = 5 + 5
+
diff --git a/tests/neg/deptupW.hs b/tests/neg/deptupW.hs
--- a/tests/neg/deptupW.hs
+++ b/tests/neg/deptupW.hs
@@ -2,12 +2,12 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ data Pair a b <p :: x0:a -> x1:b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: x0:a -> x1:b -> Bool> = P (x :: a) (y :: b<p x>) @-}
 data Pair a b = P a b
 
 
 -- Names are shifty. I bet this would not work with alpha-renaming.
-{-@ mkP :: forall a <p :: x0:a -> x1:a -> Prop>. x: a -> y: a<p x> -> Pair <p> a a @-}
+{-@ mkP :: forall a <p :: x0:a -> x1:a -> Bool>. x: a -> y: a<p x> -> Pair <p> a a @-}
 mkP :: a -> a -> Pair a a
 mkP x y = error "TBD"
 
diff --git a/tests/neg/elim-ex-compose.hs b/tests/neg/elim-ex-compose.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/elim-ex-compose.hs
@@ -0,0 +1,9 @@
+module ElimExCompose (prop) where
+
+{-@ prop :: x:Nat -> {v:Int | v = x + 5} @-}
+prop :: Int -> Int
+prop = incr . incr . incr . incr
+
+{-@ incr :: dog:Int -> {v:Int | v == dog + 1} @-}
+incr :: Int -> Int
+incr cat = cat + 1
diff --git a/tests/neg/elim-ex-let.hs b/tests/neg/elim-ex-let.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/elim-ex-let.hs
@@ -0,0 +1,15 @@
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExLet (prop) where
+
+import LiquidHaskell
+
+[lq| type Nat = {v:Int | 0 <= v} |]
+
+[lq| prop :: a -> Nat |]
+prop _ = let x _ = let y = 0 
+                   in
+                     y - 3
+         in 
+           x () + 2
diff --git a/tests/neg/elim-ex-list.hs b/tests/neg/elim-ex-list.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/elim-ex-list.hs
@@ -0,0 +1,22 @@
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExList (prop) where
+
+import LiquidHaskell
+import Prelude hiding (head)
+
+--------------------------------------------------------------------------
+[lq| prop :: a -> Even |]
+prop _ = (head ys) - 1
+  where 
+    ys = Cons 1 (Cons 2 (Cons 5 Nil))
+--------------------------------------------------------------------------
+
+[lq| type Even = {v:Int | v mod 2 == 0 } |]
+
+data List a = Nil | Cons a (List a)
+
+head :: List a -> a 
+head (Cons x _) = x
+
diff --git a/tests/neg/elim-ex-map-1.hs b/tests/neg/elim-ex-map-1.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/elim-ex-map-1.hs
@@ -0,0 +1,21 @@
+{-@ LIQUID "--no-termination" @-}
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExMap (prop) where
+
+import LiquidHaskell
+
+import Prelude hiding (map)
+
+--------------------------------------------------------------------------
+[lq| prop :: List Even -> List Even |]
+prop xs = map (+ 2) (map (+ 1) xs)
+--------------------------------------------------------------------------
+
+[lq| type Even = {v:Int | v mod 2 == 0 } |]
+
+data List a = Nil | Cons a (List a)
+
+map f Nil         = Nil
+map f (Cons x xs) = Cons (f x) (map f xs)
diff --git a/tests/neg/elim-ex-map-2.hs b/tests/neg/elim-ex-map-2.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/elim-ex-map-2.hs
@@ -0,0 +1,21 @@
+{-@ LIQUID "--no-termination" @-}
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExMap (prop) where
+
+import LiquidHaskell
+
+import Prelude hiding (map)
+
+--------------------------------------------------------------------------
+[lq| prop :: List Even -> List Even |]
+prop = map (+ 2) . map (+ 1)
+--------------------------------------------------------------------------
+
+[lq| type Even = {v:Int | v mod 2 == 0 } |]
+
+data List a = Nil | Cons a (List a)
+
+map f Nil         = Nil
+map f (Cons x xs) = Cons (f x) (map f xs)
diff --git a/tests/neg/elim-ex-map-3.hs b/tests/neg/elim-ex-map-3.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/elim-ex-map-3.hs
@@ -0,0 +1,21 @@
+{-@ LIQUID "--no-termination" @-}
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExMap (prop) where
+
+import LiquidHaskell
+
+import Prelude hiding (map)
+
+--------------------------------------------------------------------------
+[lq| prop :: List Even -> List Even |]
+prop = map ((+ 0) . (+ 1))
+--------------------------------------------------------------------------
+
+[lq| type Even = {v:Int | v mod 2 == 0 } |]
+
+data List a = Nil | Cons a (List a)
+
+map f Nil         = Nil
+map f (Cons x xs) = Cons (f x) (map f xs)
diff --git a/tests/neg/elim000.hs b/tests/neg/elim000.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/elim000.hs
@@ -0,0 +1,15 @@
+module Poslist () where
+
+{-@ prop2 :: Int -> Nat @-}
+prop2 :: Int -> Int
+prop2 x = numAbsList x
+
+numAbsList = glap numAbs
+
+{-@ glap :: (a -> b) -> a -> b @-}
+glap :: (a -> b) -> a -> b
+glap = undefined
+
+-- Adding the below signature makes it flag an error...
+-- numAbs :: Int -> Int
+numAbs x = if x > 0 then x else x
diff --git a/tests/neg/errmsg.hs b/tests/neg/errmsg.hs
--- a/tests/neg/errmsg.hs
+++ b/tests/neg/errmsg.hs
@@ -8,7 +8,7 @@
    "Eq [Contravariant]" stuff. Can we remove it, or at least NOT show
    it when running in --short-names mode. -}
 
-{-@ foo :: (Eq a) => x:a -> xs:[a] -> {v:Bool | Prop v <=> (Data.Set.member x (Data.Set.elems xs))} @-}
+{-@ foo :: (Eq a) => x:a -> xs:[a] -> {v:Bool | v <=> (Data.Set.member x (Data.Set.elems xs))} @-}
 foo          :: (Eq a) => a -> [a] -> Bool
 foo x (y:ys) = x == y || elem x ys
 foo _ []     = False
diff --git a/tests/neg/ex0-unsafe.hs b/tests/neg/ex0-unsafe.hs
--- a/tests/neg/ex0-unsafe.hs
+++ b/tests/neg/ex0-unsafe.hs
@@ -1,16 +1,17 @@
+{-@ LIQUID "--pruneunsorted" @-}
 module Ex () where
 
 -- Testing "existential-types"
 
-{-@ foldN :: forall a <p :: x0000:Int -> x1111:a -> Prop>. 
-                (i:Int -> a<p i> -> a<p (i+1)>) 
+{-@ foldN :: forall a <p :: x0000:Int -> x1111:a -> Bool>. 
+                (i:Int -> a<p i> -> a<p (i+1)>)
               -> n:{v: Int | v >= 0}
               -> a <p 0>
               -> a <p n>
   @-}
 
 foldN :: (Int -> a -> a) -> Int -> a -> a
-foldN f n = go 0 
+foldN f n = go 0
   where go i x | i < n     = go (i+1) (f i x)
                | otherwise = x
 
diff --git a/tests/neg/ex1-unsafe.hs b/tests/neg/ex1-unsafe.hs
--- a/tests/neg/ex1-unsafe.hs
+++ b/tests/neg/ex1-unsafe.hs
@@ -1,3 +1,4 @@
+{-@ LIQUID "--pruneunsorted" @-}
 
 -- | A somewhat fancier example demonstrating the use of Abstract Predicates and exist-types
 
@@ -9,10 +10,10 @@
 
 data Vec a = Nil | Cons a (Vec a)
 
--- | We can encode the notion of length as an inductive measure @llen@ 
+-- | We can encode the notion of length as an inductive measure @llen@
 
-{-@ measure llen     :: forall a. Vec a -> Int 
-    llen (Nil)       = 0 
+{-@ measure llen     :: forall a. Vec a -> Int
+    llen (Nil)       = 0
     llen (Cons x xs) = 1 + llen(xs)
   @-}
 
@@ -26,29 +27,29 @@
 sizeOf (Cons _ xs) = 1 + sizeOf xs
 
 -------------------------------------------------------------------------
--- | Higher-order fold -------------------------------------------------- 
+-- | Higher-order fold --------------------------------------------------
 -------------------------------------------------------------------------
 
 -- | Time to roll up the sleeves. Here's a a higher-order @foldr@ function
 -- for our `Vec` type. Note that the `op` argument takes an extra /ghost/
--- parameter that will let us properly describe the type of `efoldr` 
+-- parameter that will let us properly describe the type of `efoldr`
 
-{-@ efoldr :: forall a b <p :: x0:Vec a -> x1:b -> Prop>. 
-                (xs:Vec a -> x:a -> b <p xs> -> b <p (Ex.Cons x xs)>) 
-              -> b <p Ex.Nil> 
+{-@ efoldr :: forall a b <p :: x0:Vec a -> x1:b -> Bool>. 
+                (xs:Vec a -> x:a -> b <p xs> -> b <p (Ex.Cons x xs)>)
+              -> b <p Ex.Nil>
               -> ys: Vec a
               -> b <p ys>
   @-}
 efoldr :: (Vec a -> a -> b -> b) -> b -> Vec a -> b
 efoldr op b Nil         = b
-efoldr op b (Cons x xs) = op xs x (efoldr op b xs) 
+efoldr op b (Cons x xs) = op xs x (efoldr op b xs)
 
 -------------------------------------------------------------------------
--- | Clients of `efold` ------------------------------------------------- 
+-- | Clients of `efold` -------------------------------------------------
 -------------------------------------------------------------------------
 
--- | Finally, lets write a few /client/ functions that use `efoldr` to 
--- operate on the `Vec`s. 
+-- | Finally, lets write a few /client/ functions that use `efoldr` to
+-- operate on the `Vec`s.
 
 -- | First: Computing the length using `efoldr`
 {-@ size :: xs:Vec a -> {v: Int | v = llen(xs)} @-}
@@ -57,11 +58,8 @@
 
 {-@ suc :: x:Int -> {v: Int | v = x + 1} @-}
 suc :: Int -> Int
-suc x = x + 1 
+suc x = x + 1
 
 -- | Second: Appending two lists using `efoldr`
-{-@ app  :: xs: Vec a -> ys: Vec a -> {v: Vec a | llen(v) = 1 + llen(xs) + llen(ys) } @-} 
-app xs ys = efoldr (\_ z zs -> Cons z zs) ys xs 
-
-
-
+{-@ app  :: xs: Vec a -> ys: Vec a -> {v: Vec a | llen(v) = 1 + llen(xs) + llen(ys) } @-}
+app xs ys = efoldr (\_ z zs -> Cons z zs) ys xs
diff --git a/tests/neg/filterAbs.hs b/tests/neg/filterAbs.hs
--- a/tests/neg/filterAbs.hs
+++ b/tests/neg/filterAbs.hs
@@ -7,8 +7,8 @@
 
 import Prelude hiding (filter)
 
-{-@ filter :: forall <p :: a -> Prop, q :: a -> Bool -> Prop>.
-                  {y::a, flag :: {v:Bool<q y> | Prop v} |- {v:a | v = y} <: a<p>}
+{-@ filter :: forall <p :: a -> Bool, q :: a -> Bool -> Bool>.
+                  {y::a, flag :: {v:Bool<q y> | v} |- {v:a | v = y} <: a<p>}
                   (x:a -> Bool<q x>) -> [a] -> [a<p>]
   @-}
 
@@ -17,19 +17,19 @@
   | otherwise = filter f xs
 filter _ []   = []
 
-{-@ isPos :: x:Int -> {v:Bool | Prop v <=> x > 0} @-}
+{-@ isPos :: x:Int -> {v:Bool | v <=> x > 0} @-}
 isPos :: Int -> Bool
 isPos n = n > 0
 
 
-{-@ isNeg :: x:Int -> {v:Bool | Prop v <=> x < 0} @-}
+{-@ isNeg :: x:Int -> {v:Bool | v <=> x < 0} @-}
 isNeg :: Int -> Bool
 isNeg n = n < 0
 
 
 -- Now the below *should* work with
 -- p := \v   -> 0 < v
--- q := \x v -> Prop v <=> 0 < 0
+-- q := \x v -> v <=> 0 < 0
 
 
 {-@ positives :: [Int] -> [{v:Int | v > 0}] @-}
diff --git a/tests/neg/foldN.hs b/tests/neg/foldN.hs
--- a/tests/neg/foldN.hs
+++ b/tests/neg/foldN.hs
@@ -1,18 +1,16 @@
+{-@ LIQUID "--pruneunsorted" @-}
 module Ex () where
 
 -- Testing "existential-types"
 
-{-@ foldN :: forall a <p :: x0:Int -> x1:a -> Prop>. 
-                (i:Int -> a<p i> -> a<p (i+1)>) 
+{-@ foldN :: forall a <p :: x0:Int -> x1:a -> Bool>. 
+                (i:Int -> a<p i> -> a<p (i+1)>)
               -> n:{v: Int | v >= 0}
-              -> a <p 0> 
+              -> a <p 0>
               -> a <p 42>
   @-}
 
 foldN :: (Int -> a -> a) -> Int -> a -> a
-foldN f n = go 0 
+foldN f n = go 0
   where go i x | i < n     = go (i+1) (f i x)
                | otherwise = x
-
-
-
diff --git a/tests/neg/foldN1.hs b/tests/neg/foldN1.hs
--- a/tests/neg/foldN1.hs
+++ b/tests/neg/foldN1.hs
@@ -1,14 +1,14 @@
+{-@ LIQUID "--pruneunsorted" @-}
 module Toy  where
 
-{-@ foldN :: forall a <p :: x0:Int -> x1:a -> Prop>. 
-                (i:Int -> a<p i> -> a<p (i+1)>) 
+{-@ foldN :: forall a <p :: x0:Int -> x1:a -> Bool>. 
+                (i:Int -> a<p i> -> a<p (i+1)>)
               -> n:{v: Int | v >= 0}
               -> a <p 0>
               -> {v : a | 0=1}
   @-}
 
 foldN :: (Int -> a -> a) -> Int -> a -> a
-foldN f n = go 0 
+foldN f n = go 0
   where go i x | i < n     = go (i+1) (f i x)
                | otherwise = x
-
diff --git a/tests/neg/inc2.hs b/tests/neg/inc2.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/inc2.hs
@@ -0,0 +1,11 @@
+-- ISSUE #671
+--
+-- | ISSUE would be nice to have error reported at `x-1` and NOT the `inc`
+--   note that the right place gets shown if you comment out the `inc 0 = 1`
+
+module Inc where
+
+{-@ inc :: x:Int -> {v:Int | v > x} @-}
+inc :: Int -> Int
+inc 0 = 1
+inc x = x - 1
diff --git a/tests/neg/multi-pred-app-00.hs b/tests/neg/multi-pred-app-00.hs
--- a/tests/neg/multi-pred-app-00.hs
+++ b/tests/neg/multi-pred-app-00.hs
@@ -1,6 +1,5 @@
 module Blank () where
 
-{-@ bar :: forall < p :: Int -> Prop
-                  , q :: Int -> Prop >. Int<p> -> Int<p, q> @-}
+{-@ bar :: forall < p :: Int -> Bool, q :: Int -> Bool>. Int<p> -> Int<p, q> @-}
 bar :: Int -> Int
 bar x = x
diff --git a/tests/neg/pair.hs b/tests/neg/pair.hs
--- a/tests/neg/pair.hs
+++ b/tests/neg/pair.hs
@@ -1,25 +1,25 @@
-module Pair () where 
+module Pair () where
 
-import Language.Haskell.Liquid.Prelude 
+import Language.Haskell.Liquid.Prelude
 
-{-@ data Pair a b <p :: a -> b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: a -> b -> Bool> = P (x :: a) (y :: b<p x>) @-} 
 data Pair a b = P a b
 
 incr x = let p = P x ((x+1)) in p
-chk (P x (y)) = liquidAssertB (x == y) 
+chk (P x (y)) = liquidAssertB (x == y)
 prop  = chk $ incr n
   where n = choose 0
 
-incr2 x = 
-  let p1 = (P True (x+1)) in 
-  let p2 = P x p1 in 
+incr2 x =
+  let p1 = (P True (x+1)) in
+  let p2 = P x p1 in
    p2
-chk2 (P x w) = 
-   case w of (P z y) -> liquidAssertB (x == y) 
+chk2 (P x w) =
+   case w of (P z y) -> liquidAssertB (x == y)
 prop2  = chk2 $ incr2 n
   where n = choose 0
 
 incr3 x = P x (P True (P 0 (x+1)))
-chk3 (P x (P _(P _ y))) = liquidAssertB (x == y) 
+chk3 (P x (P _(P _ y))) = liquidAssertB (x == y)
 prop3  = chk3 $ incr3 n
   where n = choose 0
diff --git a/tests/neg/pargs.hs b/tests/neg/pargs.hs
--- a/tests/neg/pargs.hs
+++ b/tests/neg/pargs.hs
@@ -1,10 +1,9 @@
 module Foo () where
 
-{-@ foo :: forall a <p :: x0:Int -> x1:a -> Prop>. 
+{-@ foo :: forall a <p :: x0:Int -> x1:a -> Bool>. 
              (i:Int -> a<p i>) -> {v:Int| v=0}
               -> a <p 1>
   @-}
 
 foo ::  (Int -> a) -> Int ->  a
 foo f i = f i
-
diff --git a/tests/neg/pargs1.hs b/tests/neg/pargs1.hs
--- a/tests/neg/pargs1.hs
+++ b/tests/neg/pargs1.hs
@@ -1,11 +1,11 @@
+{-@ LIQUID "--pruneunsorted" @-}
 module Foo () where
 
-{-@ foo :: forall a <p :: x0:Int -> x1:a -> Prop>. 
-             (i:Int  -> j : Int-> a<p (i)>) -> 
+{-@ foo :: forall a <p :: x0:Int -> x1:a -> Bool>. 
+             (i:Int  -> j : Int-> a<p (i)>) ->
                ii:Int -> jj:Int
               -> a <p (ii+jj)>
   @-}
 
 foo ::  (Int -> Int -> a) -> Int -> Int ->  a
 foo f i j = f i j
-
diff --git a/tests/neg/state0.hs b/tests/neg/state0.hs
--- a/tests/neg/state0.hs
+++ b/tests/neg/state0.hs
@@ -2,13 +2,11 @@
 
 type State = Int
 data ST a = S (State -> (a, State))
-{-@ data ST a <p1 :: State -> Prop,
-               p2 :: State -> Prop> 
-     = S (x::(f:State<p1> -> (a, State<p2>))) 
+{-@ data ST a <p1 :: State -> Bool,
+               p2 :: State -> Bool> 
+     = S (x::(f:State<p1> -> (a, State<p2>)))
   @-}
 
 {-@ fresh :: ST <{\v -> v>=0}, {\v -> v>=0}> Int @-}
 fresh :: ST Int
 fresh = S $ \n -> (n, n-1)
-
-
diff --git a/tests/neg/sumPoly.hs b/tests/neg/sumPoly.hs
--- a/tests/neg/sumPoly.hs
+++ b/tests/neg/sumPoly.hs
@@ -1,6 +1,6 @@
 module Toy  where
 
-{-@ sumPoly :: forall <p ::a -> Prop>. (Num a, Ord a) => [a<p>] -> a<p> @-} 
+{-@ sumPoly :: forall <p ::a -> Bool>. (Num a, Ord a) => [a<p>] -> a<p> @-} 
 sumPoly     :: (Num a, Ord a) => [a] -> a
 sumPoly (x:xs) = foldl (+) x xs
 
diff --git a/tests/neg/test00.hs b/tests/neg/test00.hs
--- a/tests/neg/test00.hs
+++ b/tests/neg/test00.hs
@@ -9,5 +9,3 @@
 
 baz :: Int -> Bool
 baz z = liquidAssertB (z `geq` 100)
-
-
diff --git a/tests/neg/test00c.hs b/tests/neg/test00c.hs
new file mode 100644
--- /dev/null
+++ b/tests/neg/test00c.hs
@@ -0,0 +1,18 @@
+{-@ LIQUID "--diffcheck" @-}
+
+module Test (ok, inc) where
+
+
+
+
+
+
+{-@ ok
+    :: Int -> Nat
+  @-}
+ok :: Int -> Int
+ok x = x + 120
+
+{-@ inc :: Int -> Nat @-}
+inc :: Int -> Int
+inc x = x + 10
diff --git a/tests/neg/testRec.hs b/tests/neg/testRec.hs
--- a/tests/neg/testRec.hs
+++ b/tests/neg/testRec.hs
@@ -19,7 +19,7 @@
  
 -- bar = map id []
 
-{-@ Decrease go 2 @-}
+{-@ decrease go 2 @-}
 rev xs = go [] xs
   where go ack  []    = ack
         go ack (x:xs) = go (x:ack) xs
diff --git a/tests/neg/vector0.hs b/tests/neg/vector0.hs
--- a/tests/neg/vector0.hs
+++ b/tests/neg/vector0.hs
@@ -1,22 +1,32 @@
-module Vec0 () where
+module Vec0 (x0, prop0, prop1, prop2, prop3) where
 
 import Language.Haskell.Liquid.Prelude
+
 import Data.Vector hiding (map, concat, zipWith, filter, foldr, foldl, (++))
 
-xs  = [1,2,3,4] :: [Int]
+xs :: [Int]
+xs  = [1,2,3,4]
+
+vs :: Vector Int
 vs  = fromList xs
 
+prop0 :: Bool
 prop0 = liquidAssertB (x >= 0)
         where x = Prelude.head xs
 
+prop1 :: Bool
 prop1 = liquidAssertB (n > 0)
         where n = Prelude.length xs
 
+prop2 :: Bool
 prop2 = liquidAssertB (Data.Vector.length vs > 0)
+
+prop3 :: Bool
 prop3 = liquidAssertB (Data.Vector.length vs > 3)
 
+x0    :: [ Int ]
 x0    = [ vs ! 0
         , vs ! 1
         , vs ! 2
-        , vs ! 3 
-        , vs ! 4]
+        , vs ! 3
+        , vs ! 4 ]
diff --git a/tests/neg/wrap0.hs b/tests/neg/wrap0.hs
--- a/tests/neg/wrap0.hs
+++ b/tests/neg/wrap0.hs
@@ -2,7 +2,7 @@
 
 import Language.Haskell.Liquid.Prelude (liquidError, liquidAssertB)
 
-{-@ data Foo a <p :: a -> Prop> = F (f :: a <p>) @-}
+{-@ data Foo a <p :: a -> Bool> = F (f :: a <p>) @-}
 data Foo a = F a
 
 type IntFoo = Foo Int
diff --git a/tests/parser/pos/Parens.hs b/tests/parser/pos/Parens.hs
new file mode 100644
--- /dev/null
+++ b/tests/parser/pos/Parens.hs
@@ -0,0 +1,15 @@
+module Parens where
+
+{-@ data Node a = Branch (BranchList a) @-}
+data Node a = Branch (BranchList a)
+data BranchList a = BL a
+
+{-@ test :: v:a -> (a, a) @-}
+test :: a -> (a,a)
+test x = (x,x)
+
+{-@
+measure listlen :: [a] -> Int
+listlen [] = 0
+listlen (x:xs) = 1 + listlen xs
+@-}
diff --git a/tests/parser/pos/TokensAsPrefixes.hs b/tests/parser/pos/TokensAsPrefixes.hs
new file mode 100644
--- /dev/null
+++ b/tests/parser/pos/TokensAsPrefixes.hs
@@ -0,0 +1,5 @@
+module Fixme where
+
+{-@ instancesB :: Int -> Int @-}
+instancesB :: Int -> Int
+instancesB x = x
diff --git a/tests/pmap.py b/tests/pmap.py
new file mode 100644
--- /dev/null
+++ b/tests/pmap.py
@@ -0,0 +1,30 @@
+import itertools as it
+import threading, Queue
+
+class PMapWorker (threading.Thread):
+    def __init__ (self, f, q):
+        threading.Thread.__init__ (self)
+        self.results = list ()
+        self.f       = f
+        self.q       = q
+
+    def run(self):
+        while True:
+            try:
+                x = self.q.get_nowait ()
+                self.results.append (self.f (x))
+                self.q.task_done ()
+            except Queue.Empty:
+                return
+
+def map (threadcount, f, xs):
+    q = Queue.Queue ()
+    for x in xs:
+        q.put (x)
+
+    workers = [PMapWorker (f, q) for i in range (0, threadcount)]
+    for worker in workers:
+        worker.start ()
+    q.join ()
+
+    return it.chain (*[worker.results for worker in workers])
diff --git a/tests/pos/ANF.hs b/tests/pos/ANF.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ANF.hs
@@ -0,0 +1,126 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--totality"       @-}
+
+module ANF (Op (..), Expr (..), isImm, isAnf, anf) where
+
+import Control.Monad.State.Lazy
+
+mkLet :: [(Var, AnfExpr)] -> AnfExpr -> AnfExpr
+imm, immExpr :: Expr -> AnfM ([(Var, AnfExpr)], ImmExpr)
+anf   :: Expr -> AnfM AnfExpr
+fresh :: AnfM Var
+
+--------------------------------------------------------------------------------
+-- | Types
+--------------------------------------------------------------------------------
+type Var = String
+
+data Op
+  = Plus
+  | Minus
+
+data Expr
+  = EInt  Int
+  | EVar  Var
+  | ELet  Var  Expr Expr
+  | EBin  Op   Expr Expr
+  | ELam  Var  Expr
+  | EApp  Expr Expr
+
+--------------------------------------------------------------------------------
+-- | Defining Immediate Values and ANF
+--------------------------------------------------------------------------------
+{-@ measure isImm @-}
+isImm :: Expr -> Bool
+isImm (EInt {}) = True
+isImm (EVar {}) = True
+isImm _         = False
+
+-- isImm (ELet {}) = False
+-- isImm (EBin {}) = False
+-- isImm (ELam {}) = False
+-- isImm (EApp {}) = False
+
+{-@ measure isAnf @-}
+isAnf :: Expr -> Bool
+isAnf (EInt {})      = True
+isAnf (EVar {})      = True
+isAnf (ELet _ e1 e2) = isAnf e1 && isAnf e2
+isAnf (EBin _ e1 e2) = isImm e1 && isImm e2
+isAnf (EApp e1 e2)   = isImm e1 && isImm e2
+isAnf (ELam _ e)     = isAnf e
+
+{-@ type AnfExpr = {v:Expr | isAnf v} @-}
+type AnfExpr = Expr
+
+{-@ type ImmExpr = {v:Expr | isImm v} @-}
+type ImmExpr = Expr
+
+--------------------------------------------------------------------------------
+-- | A Monad to get Fresh names
+--------------------------------------------------------------------------------
+type AnfM a = State Int a
+
+--------------------------------------------------------------------------------
+{-@ anf :: Expr -> AnfM AnfExpr @-}
+--------------------------------------------------------------------------------
+anf (EInt n) =
+  return (EInt n)
+
+anf (EVar x) =
+  return (EVar x)
+
+anf (ELet x e1 e2) = do
+  a1 <- anf e1
+  a2 <- anf e2
+  return (ELet x a1 a2)
+
+anf (EBin o e1 e2) = do
+  (b1s, v1) <- imm e1
+  (b2s, v2) <- imm e2
+  return (mkLet (b1s ++ b2s) (EBin o v1 v2))
+
+anf (ELam x e) = do
+  a <- anf e
+  return (ELam x a)
+
+anf (EApp e1 e2) = do
+  (b1s, v1) <- imm e1
+  (b2s, v2) <- imm e2
+  return (mkLet (b1s ++ b2s) (EApp v1 v2))
+
+{-@ mkLet :: [(Var, AnfExpr)] -> AnfExpr -> AnfExpr @-}
+mkLet []         e' = e'
+mkLet ((x,e):bs) e' = ELet x e (mkLet bs e')
+
+--------------------------------------------------------------------------------
+{-@ imm :: Expr -> AnfM ([(Var, AnfExpr)], ImmExpr) @-}
+--------------------------------------------------------------------------------
+imm (EInt n)       = return ([], EInt n)
+imm (EVar x)       = return ([], EVar x)
+imm e@(ELet {})    = immExpr e
+imm e@(ELam {})    = immExpr e
+imm (EBin o e1 e2) = imm2 e1 e2 (EBin o)
+imm (EApp e1 e2)   = imm2 e1 e2 EApp
+
+{-@ immExpr :: Expr -> AnfM ([(Var, AnfExpr)], ImmExpr) @-}
+immExpr e = do
+  a <- anf e
+  t <- fresh
+  return ([(t, a)], EVar t)
+
+imm2 :: Expr -> Expr -> (ImmExpr -> ImmExpr -> AnfExpr) -> AnfM ([(Var, AnfExpr)], ImmExpr)
+imm2 e1 e2 f = do
+  (b1s, v1) <- imm e1
+  (b2s, v2) <- imm e2
+  t         <- fresh
+  let bs'    = b1s ++ b2s ++ [(t, f v1 v2)]
+  return      (bs', EVar t)
+
+--------------------------------------------------------------------------------
+{-@ fresh :: AnfM Var @-}
+--------------------------------------------------------------------------------
+fresh = do
+  n <- get
+  put (n+1)
+  return ("tmp" ++ show n)
diff --git a/tests/pos/AVL.hs b/tests/pos/AVL.hs
--- a/tests/pos/AVL.hs
+++ b/tests/pos/AVL.hs
@@ -30,7 +30,7 @@
 
 -- | Insert functions
 
-{-@ Decrease insert 3 @-}
+{-@ decrease insert 3 @-}
 {-@ insert :: a -> s: AVLTree -> {t: AVLTree | EqHt t s || HtDiff t s 1 } @-}
 insert :: (Ord a) => a -> Tree a -> Tree a
 insert a Nil = singleton a
@@ -84,7 +84,7 @@
 {-@ predicate LeftHeavy T = bFac T == 1 @-}
 {-@ predicate RightHeavy T = bFac T == -1 @-}
 
-{-@ measure balanced :: Tree a -> Prop
+{-@ measure balanced :: Tree a -> Bool
 balanced (Nil) = true
 balanced (Tree v l r) = ((ht l) <= (ht r) + 1)
                         && (ht r <= ht l + 1)
diff --git a/tests/pos/AVLRJ.hs b/tests/pos/AVLRJ.hs
--- a/tests/pos/AVLRJ.hs
+++ b/tests/pos/AVLRJ.hs
@@ -16,14 +16,15 @@
   @-}
 
 {-@ measure ht @-}
+{-@ ht          :: Tree a -> Nat @-}
 ht              :: Tree a -> Int
 ht Nil          = 0
 ht (Tree _ l r) = if (ht l) > (ht r) then (1 + ht l) else (1 + ht r)
-{-@ invariant {v:Tree a | 0 <= ht v} @-}
+{-@ invariant {v:Tree a | 0 <= bFac v + 1 && bFac v <= 1 } @-}
 
 
 {-@ measure bFac @-}
-{-@ bFac :: t:AVLTree a -> {v:Int | v = bFac t && 0 <= v + 1 && v <= 1} @-}
+{-@ bFac :: t:Tree a -> {v:Int | 0 <= v + 1 && v <= 1} @-}
 bFac Nil          = 0
 bFac (Tree _ l r) = ht l - ht r
 
diff --git a/tests/pos/AmortizedQueue.hs b/tests/pos/AmortizedQueue.hs
--- a/tests/pos/AmortizedQueue.hs
+++ b/tests/pos/AmortizedQueue.hs
@@ -18,7 +18,7 @@
 
 -- | Invariant: `size` is really the size:
 
-{-@ data SList a = SL { size  :: Int
+{-@ data SList a = SL { size  :: Nat
                       , elems :: {v:[a] | len v = size}
                       }
   @-}
diff --git a/tests/pos/Assume.hs b/tests/pos/Assume.hs
--- a/tests/pos/Assume.hs
+++ b/tests/pos/Assume.hs
@@ -2,7 +2,7 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ assume foo :: {v:Bool | (Prop v)} @-}
+{-@ assume foo :: {v:Bool | v} @-}
 foo = False
 
 bar = liquidAssertB foo
diff --git a/tests/pos/AutoTerm.hs b/tests/pos/AutoTerm.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/AutoTerm.hs
@@ -0,0 +1,26 @@
+module Isort where
+
+data SortedList a =
+     Mt
+   | Ln{h :: a, t :: SortedList a}
+
+{-@ data SortedList [sortedlen] @-}
+
+
+{-@ measure sortedlen @-}
+{-@ sortedlen :: SortedList a -> {v:Int | v >= 0 } @-}
+sortedlen :: SortedList a -> Int
+sortedlen Mt = 0
+sortedlen (Ln x xs) = 1 + sortedlen xs
+
+{-@ insert :: (Ord a) => a -> lst:(SortedList a) -> {v: SortedList a | sortedlen v = sortedlen lst + 1} / [sortedlen lst]@-}
+insert :: (Ord a) => a -> SortedList a -> SortedList a
+insert x Mt = Ln x Mt
+insert y (Ln x xs)
+  | y < x     = Ln y (Ln x xs)
+  | otherwise = Ln x (insert y xs)
+
+{-@ isort :: (Ord a) => lst:[a] -> {v : SortedList a | sortedlen v = len lst} @-}
+isort :: (Ord a) => [a] -> SortedList a
+isort [] = Mt -- note can't use [] here
+isort (x:xs) = insert x (isort xs)
diff --git a/tests/pos/AutoTerm1.hs b/tests/pos/AutoTerm1.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/AutoTerm1.hs
@@ -0,0 +1,18 @@
+module Isort where
+
+data F = F | C Int F  
+
+{-@ data F [lenF] @-}
+
+{-@ measure lenF @-}
+lenF :: F -> Int
+
+
+{-@ lenF :: xs:F -> {v:Int | v >= 0 } @-}
+lenF F = 0
+lenF (C _ x) = 1 + lenF x 
+
+
+bar :: F -> Int 
+bar F = 0 
+bar (C x xs) = x + bar xs 
diff --git a/tests/pos/Automate.hs b/tests/pos/Automate.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Automate.hs
@@ -0,0 +1,22 @@
+module Automate where
+
+{-@ LIQUID "--automatic-instances=smtinstances" @-}
+
+import Language.Haskell.Liquid.ProofCombinators 
+
+
+fibA :: Int -> Int 
+{-@ axiomatize fibA @-}
+{-@ fibA :: Nat -> Nat @-}
+fibA i | i <= 1 = i
+      | otherwise = fibA (i-1) + fibA (i-2)
+
+fibUp :: Int -> Proof 
+{-@ fibUp :: i:Nat -> {fibA i <= fibA (i+1)} @-}
+fibUp i 
+ | i <= 2    = trivial
+ | otherwise = fibUp (i-1) &&& fibUp (i-2) *** QED 
+
+{-@ prop :: () -> {fibA 30 == 832040 } @-}
+prop :: () -> Proof 
+prop _ = trivial  
diff --git a/tests/pos/Avg.hs b/tests/pos/Avg.hs
--- a/tests/pos/Avg.hs
+++ b/tests/pos/Avg.hs
@@ -6,13 +6,13 @@
   @-}
 
 {-@ measure lenD :: [Double] -> Double
-    lenD([]) = 0.0
+    lenD([])   = 0.0
     lenD(x:xs) = (1.0) + (lenD xs)
   @-}
 
 {-@ expression Avg Xs = ((sumD Xs) / (lenD Xs))  @-}
 
-{-@ meansD :: xs:{v:[Double] | ((lenD v) > 0.0)} 
+{-@ meansD :: xs:{v:[Double] | ((lenD v) > 0.0)}
            -> {v:Double | v = Avg xs} @-}
 meansD :: [Double] -> Double
 meansD xs = sumD xs / lenD xs
diff --git a/tests/pos/BST.hs b/tests/pos/BST.hs
--- a/tests/pos/BST.hs
+++ b/tests/pos/BST.hs
@@ -3,7 +3,7 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@
-data Bst [blen] k v <l :: x0:k -> x1:k -> Prop, r :: x0:k -> x1:k -> Prop>
+data Bst [blen] k v <l :: x0:k -> x1:k -> Bool, r :: x0:k -> x1:k -> Bool>
   = Empty
   | Bind (key   :: k) 
          (value :: v) 
@@ -21,7 +21,7 @@
 data Bst k v = Empty | Bind k v (Bst k v) (Bst k v)
 
 {-@
-data Pair k v <p :: x0:k -> x1:k -> Prop, l :: x0:k -> x1:k -> Prop, r :: x0:k -> x1:k -> Prop>
+data Pair k v <p :: x0:k -> x1:k -> Bool, l :: x0:k -> x1:k -> Bool, r :: x0:k -> x1:k -> Bool>
   = P (fld0 :: k) (fld1 :: v) (tree :: Bst <l, r> (k <p fld0>) v) 
   @-}
 
diff --git a/tests/pos/BST000.hs b/tests/pos/BST000.hs
--- a/tests/pos/BST000.hs
+++ b/tests/pos/BST000.hs
@@ -4,7 +4,7 @@
 
 
 {-@
-data Bst [blen] k v <l :: root:k -> x1:k -> Prop, r :: root:k -> x1:k -> Prop>
+data Bst [blen] k v <l :: root:k -> x1:k -> Bool, r :: root:k -> x1:k -> Bool>
   = Empty
   | Bind (key   :: k) 
          (value :: v) 
@@ -29,7 +29,7 @@
 chkMin x (Bind k v lt rt) = liquidAssertB (x<k) && chkMin x lt && chkMin x rt
 
 {-@
-data Pair k v <p :: x0:k -> x1:k -> Prop, l :: x0:k -> x1:k -> Prop, r :: x0:k -> x1:k -> Prop>
+data Pair k v <p :: x0:k -> x1:k -> Bool, l :: x0:k -> x1:k -> Bool, r :: x0:k -> x1:k -> Bool>
   = P (fld0 :: k) (fld1 :: v) (tree :: Bst <l, r> (k <p fld0>) v) 
   @-}
 
diff --git a/tests/pos/BinarySearchOverflow.hs b/tests/pos/BinarySearchOverflow.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/BinarySearchOverflow.hs
@@ -0,0 +1,42 @@
+{-@ LIQUID "--no-termination" @-}
+
+module BinarySearch where
+
+import Prelude hiding (Num(..))
+import CheckedNum 
+import Data.Vector as Vector
+import Language.Haskell.Liquid.Prelude (liquidAssert) 
+
+{-@ invariant {v:Vector a | 0 <= vlen v && BoundInt (vlen v)} @-}
+
+binarySearch :: Ord a => a -> Vector a -> Maybe Int
+binarySearch x v 
+  | 0 < n     = loop x v 0 (n - 1)
+  | otherwise = Nothing 
+  where n     = Vector.length v
+
+{-@ type Idx Vec = {v:Nat | v < vlen Vec} @-}
+
+{-@ type BoundNat = {v:Nat | BoundInt v} @-}
+
+{-@ loop :: Ord a => a -> vec:Vector a -> lo:Idx vec -> {hi:Idx vec | lo <= hi} -> Maybe Nat @-}
+loop :: Ord a => a -> Vector a -> Int -> Int -> Maybe Int
+loop x v lo hi = do
+    let mid = lo + ((hi - lo) `div` 2) -- SAFE
+    -- let mid =  (hi + lo) `div` 2       -- UNSAFE
+    if x < v ! mid
+    then do
+        let hi' = mid - 1
+        if lo <= hi'
+        then loop x v lo hi'
+        else Nothing
+    else if v ! mid < x
+    then do
+        let lo' = mid + 1 -- incr mid
+        if lo' <= hi
+        then loop x v lo' hi
+        else Nothing
+    else Just mid
+    
+
+
diff --git a/tests/pos/CasesToLogic.hs b/tests/pos/CasesToLogic.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/CasesToLogic.hs
@@ -0,0 +1,15 @@
+{-@ LIQUID "--totality"          @-}
+{-@ LIQUID "--exact-data-cons"     @-}
+{-@ LIQUID "--higherorder"        @-}
+
+module StringIndexing where
+
+data D = D Int Int 
+
+
+{-@ reflect mappend @-}
+mappend :: D -> D -> D 
+{-@ mappend :: x:D -> D -> {v:D | v == x} @-}
+mappend x@(D i1 i2) (D i3 i4) = x
+
+
diff --git a/tests/pos/Cat.hs b/tests/pos/Cat.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Cat.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE GADTs #-}
+import Control.Category
+import Prelude hiding ((.), id)
+
+
+{- 
+class Category cat where
+  id :: cat a a 
+  (.) :: cat b c -> cat a b -> cat a c
+-}
+
+data Accum a b where
+  Accum :: s -> Accum a b
+
+-- | We can pass the outputs of one 'Accum' as the inputs of the next.
+instance Category Accum where
+  Accum  i1 . Accum  i2 = Accum  (i1, i2)
diff --git a/tests/pos/CheckedNum.hs b/tests/pos/CheckedNum.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/CheckedNum.hs
@@ -0,0 +1,24 @@
+module CheckedNum where
+
+-- Hiding numeric operations, because they get by default translated to SMT equivalent
+import Prelude hiding (Num(..))
+
+import qualified Prelude as Prelude 
+
+class CheckedNum a where 
+  (+) :: a -> a -> a 
+  (-) :: a -> a -> a 
+
+{-@ predicate BoundInt X = 0 < X + 10000 && X < 10000 @-}
+
+instance CheckedNum Int where
+{-@ instance CheckedNum Int where 
+      - :: x:Int -> y:{v:Int | BoundInt (x - v)} -> {v: Int | v == x - y} ;  
+      + :: x:Int -> y:{v:Int | BoundInt (x + v)} -> {v: Int | v == x + y} 
+  @-}
+	x - y = (Prelude.-) x y  
+
+	x + y = (Prelude.+) x y  
+
+
+
diff --git a/tests/pos/Chunks.hs b/tests/pos/Chunks.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Chunks.hs
@@ -0,0 +1,20 @@
+module Chunks where
+
+{-@ LIQUID "--scrape-imports" @-}
+
+
+{-@ type SafeChunkSize = {v:Int | 1 < v } @-}
+
+{-@ type Pos = {v:Int | 0 < v} @-}
+
+{-@ predicate ValidChunk V XS N 
+    = if len XS == 0 
+        then (len V == 0) 
+        else (((1 < len XS && 1 < N) => (len V  < len XS)) 
+          && ((len XS <= N ) => len V == 1))            
+  @-}
+
+{-@ chunks :: n:Pos -> xs:[a] -> {v:[[a]] | ValidChunk v xs n } / [len xs] @-}
+chunks :: Int -> [a] -> [[a]]
+chunks _ [] = [] 
+chunks n xs = let (x, xs') = splitAt n xs in x:chunks n xs'
diff --git a/tests/pos/Class.hs b/tests/pos/Class.hs
--- a/tests/pos/Class.hs
+++ b/tests/pos/Class.hs
@@ -4,7 +4,7 @@
 
 import Language.Haskell.Liquid.Prelude
 import Prelude hiding (sum, length, (!!), Functor(..))
-import qualified Prelude as P
+-- import qualified Prelude as P
 
 {-@ qualif Size(v:Int, xs:a): v = size xs @-}
 
@@ -15,9 +15,9 @@
 
 {-@ (!!) :: xs:MList a -> {v:Nat | v < (size xs)} -> a @-}
 (!!) :: MList a -> Int -> a
-Nil         !! i = liquidError "impossible"
+Nil         !! _ = liquidError "impossible"
 (Cons x _)  !! 0 = x
-(Cons x xs) !! i = xs !! (i - 1)
+(Cons _ xs) !! i = xs !! (i - 1)
 
 {-@ class measure size :: forall a. a -> Int @-}
 
@@ -37,21 +37,20 @@
 {-@ length :: xs:MList a -> {v:Nat | v = size xs} @-}
 length :: MList a -> Int
 length Nil         = 0
-length (Cons x xs) = 1 + length xs
+length (Cons _ xs) = 1 + length xs
 
 {-@ bob :: xs:MList a -> {v:Nat | v = size xs} @-}
 bob :: MList a -> Int
 bob = length
 
 
-
 instance Sized [] where
   {-@ instance measure size :: [a] -> Int
       size ([])   = 0
       size (x:xs) = 1 + (size xs)
     @-}
   size [] = 0
-  size (x:xs) = 1 + size xs
+  size (_:xs) = 1 + size xs
 
 {-@ class (Sized s) => Indexable s where
       index :: forall a. x:s a -> {v:Nat | v < size x} -> a
diff --git a/tests/pos/Class2.hs b/tests/pos/Class2.hs
--- a/tests/pos/Class2.hs
+++ b/tests/pos/Class2.hs
@@ -1,6 +1,83 @@
-module Class2 where
+{-# LANGUAGE ScopedTypeVariables #-}
+{-@ LIQUID "--no-termination" @-}
+module Class () where
 
-{-@ LIQUID "--idirs=../neg" @-}
-import Class5
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (sum, length, (!!), Functor(..))
 
-instance Foo ()
+data MList a = Nil | Cons a (MList a)
+
+{-@ (!!) :: xs:MList a -> {v:Nat | v < sz xs} -> a @-}
+(!!) :: MList a -> Int -> a
+(Cons x _)  !! 0 = x
+(Cons _ xs) !! i = xs !! (i - 1)
+
+{-@ class measure sz :: forall a. a -> Int  @-}
+
+{-@ class Sized s where
+      size :: forall a. x:s a -> {v:Nat | v = sz x}
+  @-}
+class Sized s where
+  size :: s a -> Int
+
+instance Sized MList where
+  {-@ instance measure sz :: MList a -> Int
+      sz (Nil)       = 0
+      sz (Cons x xs) = 1 + sz xs
+    @-}
+  size = length
+
+{-@ length :: xs:MList a -> {v:Nat | v = sz xs} @-}
+length :: MList a -> Int
+length Nil         = 0
+length (Cons _ xs) = 1 + length xs
+
+{-@ bob :: xs:MList a -> {v:Nat | v = sz xs} @-}
+bob :: MList a -> Int
+bob = length
+
+
+instance Sized [] where
+  {-@ instance measure sz :: [a] -> Int
+      sz ([])   = 0
+      sz (x:xs) = 1 + (sz xs)
+    @-}
+  size [] = 0
+  size (_:xs) = 1 + size xs
+
+{-@ class (Sized s) => Indexable s where
+      index :: forall a. x:s a -> {v:Nat | v < sz x} -> a
+  @-}
+class (Sized s) => Indexable s where
+  index :: s a -> Int -> a
+
+
+
+instance Indexable MList where
+  index = (!!)
+
+{-@ sum :: Indexable s => s Int -> Int @-}
+sum :: Indexable s => s Int -> Int
+sum xs = go n 0
+  where
+    n = size xs
+    go (d::Int) i
+      | i < n     = index xs i + go (d-1) (i+1)
+      | otherwise = 0
+
+
+{-@ sumMList :: MList Int -> Int @-}
+sumMList :: MList Int -> Int
+sumMList xs = go max 0
+  where
+    max = size xs
+    go (d::Int) i
+      | i < max   = index xs i + go (d-1) (i+1)
+      | otherwise = 0
+
+
+{-@ mlist3 :: {v:MList Int | sz v = 3}  @-}
+mlist3 :: MList Int
+mlist3 = 1 `Cons` (2 `Cons` (3 `Cons` Nil))
+
+foo = liquidAssert $ size (Cons 1 Nil) == size [1]
diff --git a/tests/pos/ClassKind.hs b/tests/pos/ClassKind.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ClassKind.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE StandaloneDeriving #-}
+
+-- | Implements key mechanisms of Awake.Data.Struct without
+-- any additional bounds checking beyond what is documented.
+module ClassKind where
+
+import           Data.Proxy
+class Member a where
+
+  {-@ class Member a where
+       sizeOfMember :: Proxy a -> Nat 
+    @-}
+
+  sizeOfMember :: Proxy a -> Int
+
diff --git a/tests/pos/ClassReg.hs b/tests/pos/ClassReg.hs
--- a/tests/pos/ClassReg.hs
+++ b/tests/pos/ClassReg.hs
@@ -3,7 +3,7 @@
 
 data ST s a = ST {runState :: s -> (a,s)}
 
-{-@ data ST s b <r :: s -> b -> Prop> 
+{-@ data ST s b <r :: s -> b -> Bool> 
   = ST (runState :: x:s -> (b<r x>, s)) @-}
 
 
diff --git a/tests/pos/Client521.hs b/tests/pos/Client521.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Client521.hs
@@ -0,0 +1,12 @@
+module Client521 where
+
+import Lib521 
+
+{-@ bar :: { xs : [a] | size xs > 1 } -> [a] @-}
+bar :: [a] -> [a]
+bar xs = xs 
+
+{-@ bing :: xs:[a] -> {v:Int | v = size xs} @-}
+bing :: [a] -> Int 
+bing [] = 0 
+bing (x:xs) = 1 + bing xs 
diff --git a/tests/pos/ClojurVector.hs b/tests/pos/ClojurVector.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ClojurVector.hs
@@ -0,0 +1,108 @@
+{-
+https://twitter.com/BrandonBloom/status/701261641971683328
+https://github.com/clojure/clojure/blob/d5708425995e8c83157ad49007ec2f8f43d8eac8/src/jvm/clojure/lang/PersistentVector.java#L148-L164
+-}
+
+{-@ LIQUID "--no-termination" @-}
+
+module PVec (arrayFor) where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume)
+import qualified Data.Vector as V
+
+import Data.Bits
+
+-- | Generalized tree with branching 32. We "store" the height in each `Node`
+--   only because it is useful in the specification (each sub-tree has the same height).
+--   The height is _never_ computed and so can be eliminated at run-time.
+
+data Tree a = Leaf a
+            | Node Int (V.Vector (Tree a))
+
+
+-- | Specify "height" of a tree
+
+{-@ measure height @-}
+height :: Tree a -> Int
+height (Leaf _)    = 0
+height (Node h ls) = 1 + h
+
+-- | Specify tree must be "balanced", each node has 32 children
+
+{-@ data Tree a = Leaf a
+                | Node { ht   :: Nat
+                       , kids :: VectorN (TreeH a ht) 32
+                       }
+  @-}
+
+-- | ListN is a list of a given size N
+
+{-@ type VectorN a N     = {v:V.Vector a | vlen v = N }  @-}
+
+-- | TreeH is a tree of given height H
+
+{-@ type TreeH     a H = {v:Tree a | height v = H}       @-}
+
+-- | Specify tree height is non-negative
+
+{-@ using (Tree a) as  {v:Tree a   | 0 <= height v} @-}
+
+-- | Nodes and Leaves are simply trees with non-zero and zero heights resp.
+
+{-@ type NodeT a = {v:Tree a | height v > 0} @-}
+{-@ type LeafT a = {v:Tree a | height v = 0} @-}
+
+
+-- | Vector stores the height
+data Vec a = Vec { vShift  :: Int    -- ^ height
+                 , vTree   :: Tree a -- ^ actual nodes
+                 }
+
+-- | Refined type relates height of the `vTree` with `vShift`
+
+{-@ data Vec a = Vec { vShift :: Nat
+                     , vTree  :: TreeLevel a vShift
+                     }
+  @-}
+
+{-@ type TreeLevel a L = {v:Tree a | L = 5 * height v} @-}
+
+--------------------------------------------------------------------------------
+
+arrayFor :: Int -> Vec a -> Maybe a
+arrayFor i (Vec l n) = loop l n
+  where
+
+    {-@ loop :: level:Int -> TreeLevel a level -> Maybe a @-}
+    loop :: Int -> Tree a -> Maybe a
+    loop level node
+      | level > 0 = let b      = shift i (- level) `mask` 31  -- get child index
+                        node'  = getNode node b               -- get child
+                        level' = level - 5                    -- next level
+                    in
+                        loop level' node'
+
+      | otherwise = Just (getValue node)
+
+-- TODO: refine types of bit-ops, currently use an "assume"
+
+{-@ mask :: x:Int -> y:Nat -> {v:Nat | v <= y}@-}
+mask :: Int -> Int -> Int
+mask x y = liquidAssume (0 <= r && r <= y) r
+  where
+     r   = x .&. y
+
+-- | These are the "cast" operations, except now proven safe.
+
+{-@ getNode :: t:NodeT a -> {v:Nat | v <= 31} -> {v:Tree a | height v = height t - 1}  @-}
+getNode :: Tree a -> Int -> Tree a
+getNode (Node _ ts) n = ts V.! n
+getNode _           _ = impossible "provably safe"
+
+{-@ getValue :: LeafT a -> a @-}
+getValue :: Tree a -> a
+getValue (Leaf x) = x
+getValue _        = impossible "provably safe"
+
+{-@ impossible :: {v:String | false} -> a @-}
+impossible = error
diff --git a/tests/pos/CommentedOut.hs b/tests/pos/CommentedOut.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/CommentedOut.hs
@@ -0,0 +1,6 @@
+module Nats where 
+
+{- {-@ nats :: [Nat] @-} -}
+nats :: [Int]
+nats = [-1,0,1,2,3,4,5,6,7,8,9,10]
+
diff --git a/tests/pos/CompareConstraints.hs b/tests/pos/CompareConstraints.hs
--- a/tests/pos/CompareConstraints.hs
+++ b/tests/pos/CompareConstraints.hs
@@ -3,7 +3,7 @@
 import Language.Haskell.Liquid.Prelude
 
 
-{-@ mycmp :: forall <p :: a -> Prop, q :: a -> Prop>. 
+{-@ mycmp :: forall <p :: a -> Bool, q :: a -> Bool>. 
            {x::a<p>, y::a<q> |- a <: {v:a | x <= y} } 
            Ord a => 
            [a<p>] -> [a<q>] -> Bool @-}
@@ -11,7 +11,7 @@
 mycmp (x:_) (_:y:_) = liquidAssert (x <= y) True
 
 
-{-@ mycmp' :: forall <p :: a -> Prop, q :: a -> Prop>. 
+{-@ mycmp' :: forall <p :: a -> Bool, q :: a -> Bool>. 
            {x::a<p>, y::a<q> |- a <: {v:a | x <= y} } 
            Ord a => 
            a<p> -> a<q> -> Bool @-}
diff --git a/tests/pos/Constraints.hs b/tests/pos/Constraints.hs
--- a/tests/pos/Constraints.hs
+++ b/tests/pos/Constraints.hs
@@ -1,9 +1,9 @@
 module Compose where
 
 {-@ 
-cmp :: forall < pref :: b -> Prop, postf :: b -> c -> Prop
-              , pre  :: a -> Prop, postg :: a -> b -> Prop
-              , post :: a -> c -> Prop
+cmp :: forall < pref :: b -> Bool, postf :: b -> c -> Bool
+              , pre  :: a -> Bool, postg :: a -> b -> Bool
+              , post :: a -> c -> Bool
               >. 
        {xx::a<pre>, w::b<postg xx> |- c<postf w> <: c<post xx>}
        {ww::a<pre> |- b<postg ww> <: b<pref>}
diff --git a/tests/pos/ConstraintsAppend.hs b/tests/pos/ConstraintsAppend.hs
--- a/tests/pos/ConstraintsAppend.hs
+++ b/tests/pos/ConstraintsAppend.hs
@@ -7,12 +7,12 @@
 {-@ type OList a = [a]<{\x v -> v >= x}> @-}
 
 
-{-@ assume (++) :: forall <p :: a -> Prop, q :: a -> Prop, r :: a -> Prop>.
+{-@ assume (++) :: forall <p :: a -> Bool, q :: a -> Bool, r :: a -> Bool>.
         {x::a<p> |- a<q> <: {v:a| x <= v}} 
         {a<p> <: a<r>} 
         {a<q> <: a<r>} 
         Ord a => OList (a<p>) -> OList (a<q>) -> OList a<r> @-}
-{-@ app :: forall <p :: a -> Prop, q :: a -> Prop, r :: a -> Prop>.
+{-@ app :: forall <p :: a -> Bool, q :: a -> Bool, r :: a -> Bool>.
         {x::a<p> |- a<q> <: {v:a| x <= v}} 
         {a<p> <: a<r>} 
         {a<q> <: a<r>} 
diff --git a/tests/pos/CountMonad.hs b/tests/pos/CountMonad.hs
--- a/tests/pos/CountMonad.hs
+++ b/tests/pos/CountMonad.hs
@@ -1,5 +1,7 @@
 module Count () where
 
+{-@ LIQUID "--no-pattern-inline" @-}
+
 {-@ measure count :: Count a -> Int @-}
 
 data Count a = Count a 
@@ -13,7 +15,7 @@
 instance Monad Count where
 {-@
 instance Monad Count where 
-  >>=    :: forall <r :: Count a -> Prop, p :: Count b -> Prop, q :: Count b -> Prop>.
+  >>=    :: forall <r :: Count a -> Bool, p :: Count b -> Bool, q :: Count b -> Bool>.
             {x::Count a <<r>>, y :: Count b <<p>>  |- {v:Count b | count v == count x + count y} <: Count b <<q>>} 
             Count a <<r>> -> (a -> Count b<<p>>) -> Count b <<q>> ; 
   >>     :: x:Count a -> y:Count b -> {v:Count b | count v == count x + count y}; 
diff --git a/tests/pos/DB00.hs b/tests/pos/DB00.hs
--- a/tests/pos/DB00.hs
+++ b/tests/pos/DB00.hs
@@ -4,18 +4,18 @@
 
 module DataBase (values) where
 
-{-@ values :: forall <rr2 :: key -> val -> Prop>.
+{-@ values :: forall <rr2 :: key -> val -> Bool>.
   k:key -> [Dict <rr2> key val]  -> [val<rr2 k>] @-}
 values :: key -> [Dict key val]  -> [val]
 values k = map (go k)
   where
-    {-@ go :: forall <rr1 :: k -> v -> Prop>. 
+    {-@ go :: forall <rr1 :: k -> v -> Bool>. 
               i:k -> Dict <rr1> k v -> v<rr1 i>  @-}
     go k (D _ f) = f k
 
 data Dict key val = D {ddom :: [key], dfun :: key -> val}
 
-{-@ data Dict key val <rr :: key -> val -> Prop>
+{-@ data Dict key val <rr :: key -> val -> Bool>
   = D ( ddom :: [key])
       ( dfun :: i:key -> val<rr i>)
   @-}
diff --git a/tests/pos/DataKinds.hs b/tests/pos/DataKinds.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/DataKinds.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE DataKinds #-}
+
+module ProxyClass where
+
+import           Data.Proxy
+
+
+{-@ sizeOfMember :: Proxy a -> Nat @-}
+sizeOfMember :: Proxy a -> Int
+sizeOfMember = undefined 
diff --git a/tests/pos/DependentTypes.hs b/tests/pos/DependentTypes.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/DependentTypes.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module DependeTypes where
+
+import GHC.TypeLits
+
+-- THIS SHOULD BE SAFE
+misafe   :: MI "blaa"
+misafe   = Small "blaa"
+
+data MI (s :: Symbol) = Small { mi_input :: String  }
+
+{-@ Small :: forall (s :: Symbol). {v:String | s ~~ v } -> MI s @-}
+
+-- OR 
+
+{- data MI (s :: Symbol)
+    = Small { mi_input :: {v:String | v == s } } @-}
diff --git a/tests/pos/Deptup1.pred b/tests/pos/Deptup1.pred
new file mode 100644
--- /dev/null
+++ b/tests/pos/Deptup1.pred
@@ -0,0 +1,1 @@
+assumep mkPair :: forall a b. forAll p:b(fld:a). a -> b -> Pair a b <<p>>
diff --git a/tests/pos/ExactFunApp.hs b/tests/pos/ExactFunApp.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ExactFunApp.hs
@@ -0,0 +1,19 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--exact-data-cons" @-}
+{-@ LIQUID "--higherorderqs" @-}
+
+{-# LANGUAGE IncoherentInstances   #-}
+{-# LANGUAGE FlexibleContexts #-}
+module ListFunctors where
+
+bar :: Maybe (a -> a) ->  a ->  a
+{-@ bar :: xy:Maybe (a -> a) -> z: a
+        -> {v: a | v == from_Just xy z}
+  @-}
+bar xink z = from_Just xink z
+
+
+{-@ measure from_Just @-}
+from_Just :: Maybe a -> a
+{-@ from_Just :: xs:Maybe a -> {v:a  | v == from_Just xs}@-}
+from_Just (Just x) = x
diff --git a/tests/pos/FFI.hs b/tests/pos/FFI.hs
--- a/tests/pos/FFI.hs
+++ b/tests/pos/FFI.hs
@@ -1,6 +1,4 @@
 {-# LANGUAGE ForeignFunctionInterface #-}
-{-@ LIQUID "--c-files=../ffi-include/foo.c" @-}
-{-@ LIQUID "-i../ffi-include" @-}
 module Main where
 
 import Foreign.C.Types
diff --git a/tests/pos/Foldl.hs b/tests/pos/Foldl.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Foldl.hs
@@ -0,0 +1,72 @@
+module Fold where
+
+{-@ LIQUID "--no-termination" @-}
+import Prelude hiding (foldr)
+
+data Vec a = Nil | Cons a (Vec a)
+
+
+
+{-@
+efoldl :: forall <inv :: (Vec a) -> b -> Bool, step :: a -> b -> b -> Bool>.
+          {y::a, ys :: Vec a, z :: {v:Vec a | v = Cons y ys && llen v = llen ys + 1}, jacc:: b<inv z> |- b<step y jacc> <: b<inv ys>}
+         (x:a -> pacc:b -> b<step x pacc>)
+      -> xs:(Vec a)
+      -> b<inv xs>
+      -> b<inv Nil>
+@-}
+
+efoldl :: (a -> b -> b) -> Vec a -> b -> b
+efoldl op Nil b         = b
+efoldl op (Cons x xs) b = efoldl op xs (x `op` b)
+
+
+
+
+{-
+step x b b' <=> b' = b + 1
+inv ys b <=> b + len ys = len xs
+-}
+
+{-@ size_invariant_qualifier :: xs: Vec a -> ys:Vec a -> {v:Int | v + llen xs ==  llen ys} @-}
+size_invariant_qualifier :: Vec a -> Vec a -> Int
+size_invariant_qualifier xs ys = undefined
+
+{-@ size :: xs:Vec a -> {v: Int | v = llen xs} @-}
+size :: Vec a -> Int
+size xs = efoldl (\_ n -> n + 1) xs 0
+
+
+-- | We can encode the notion of length as an inductive measure @llen@
+
+{-@ measure llen @-}
+
+llen :: Vec a -> Int
+llen (Nil)       = 0
+llen (Cons x xs) = 1 + llen(xs)
+
+
+-------------------------------------------------------------------------
+-- | Clients of `efold` -------------------------------------------------
+-------------------------------------------------------------------------
+
+
+-- | The above uses a helper that counts up the size. (Pesky hack to avoid writing qualifier v = ~A + 1)
+{-@ suc :: x:Int -> {v: Int | v = x + 1} @-}
+suc :: Int -> Int
+suc x = x + 1
+
+
+{-
+step x b b' <=> llen b' = llen xs + llen b + 1
+inv zs b <=> llen b + len zs = len xs + len zs
+-}
+
+{-@ LIQUID "--maxparams=3" @-}
+{-@ append_invariant_qualifier :: xs: Vec a -> ys:Vec a -> zs:Vec a -> {v:Vec a | llen v + llen xs ==  llen ys + llen zs } @-}
+append_invariant_qualifier :: Vec a -> Vec a -> Vec a -> Vec a
+append_invariant_qualifier xs ys zs = undefined
+
+-- | Second: Appending two lists using `efoldl`
+{-@ app  :: xs: Vec a -> ys: Vec a -> {v: Vec a | llen v = llen xs + llen ys } @-}
+app xs ys = efoldl (\z zs -> Cons z zs) xs ys
diff --git a/tests/pos/FractionalInstance.hs b/tests/pos/FractionalInstance.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/FractionalInstance.hs
@@ -0,0 +1,15 @@
+module Fractional where
+
+data Frac a
+
+{-@ test :: x:Frac a -> y:{Frac a | y /= 0} -> {v:Frac a | v = x / y } @-} 
+test :: Frac a -> Frac a -> Frac a 
+test x y = x / y 
+
+
+{-@ test1 :: x:a -> y:{a | y /= 0} -> {v:a | v = x / y } @-} 
+test1 :: Fractional a => a -> a -> a  
+test1 x y = x / y 
+
+instance Num (Frac a) where
+instance Fractional (Frac a) where
diff --git a/tests/pos/GhcListSort.hs b/tests/pos/GhcListSort.hs
--- a/tests/pos/GhcListSort.hs
+++ b/tests/pos/GhcListSort.hs
@@ -11,7 +11,7 @@
 ---------------------------  Official GHC Sort ----------------------------
 ---------------------------------------------------------------------------
 
-{-@ assert sort1 :: (Ord a) => [a] -> OList a  @-}
+{-@ sort1 :: (Ord a) => [a] -> OList a  @-}
 sort1 :: (Ord a) => [a] -> [a]
 sort1 = mergeAll . sequences
   where
@@ -20,12 +20,12 @@
       | otherwise           = ascending  b (a:) xs -- a >= b => (a:) ->   
     sequences [x] = [[x]]
     sequences []  = [[]]
-    {-@ descending :: x:a -> OList {v:a | x < v} -> [a] -> [OList a] @-}
+    {- descending :: x:a -> OList {v:a | x < v} -> [a] -> [OList a] @-}
     descending a as (b:bs)
       | a `compare` b == GT = descending b (a:as) bs
     descending a as bs      = (a:as): sequences bs
 
-    {-@ ascending :: x:a -> (OList {v:a|v>=x} -> OList a) -> [a] -> [OList a] @-}
+    {- ascending :: x:a -> (OList {v:a|v>=x} -> OList a) -> [a] -> [OList a] @-}
     ascending a as (b:bs)
       | a `compare` b /= GT = ascending b (\ys -> as (a:ys)) bs -- a <= b
     ascending a as bs       = as [a]: sequences bs
@@ -49,7 +49,7 @@
 ------------------- Mergesort ---------------------------------------------
 ---------------------------------------------------------------------------
 
-{-@ assert sort2 :: (Ord a) => [a] -> OList a  @-}
+{-@ sort2 :: (Ord a) => [a] -> OList a  @-}
 sort2 :: (Ord a) => [a] -> [a]
 sort2 = mergesort
 
@@ -81,7 +81,7 @@
 -------------------- QuickSort ---------------------------------------
 ----------------------------------------------------------------------
 
-{-@ assert sort3 :: (Ord a) => w:a -> [{v:a|v<=w}] -> OList a @-}
+{-@ sort3 :: (Ord a) => w:a -> [{v:a|v<=w}] -> OList a @-}
 sort3 :: (Ord a) => a -> [a] -> [a]
 sort3 w ls = qsort w ls []
 
diff --git a/tests/pos/GhcSort1.hs b/tests/pos/GhcSort1.hs
--- a/tests/pos/GhcSort1.hs
+++ b/tests/pos/GhcSort1.hs
@@ -8,9 +8,9 @@
 sort1 :: (Ord a) => [a] -> [a]
 sort1 xs = mergeAll  (sequences xs 0)
   where
-    {-@ Decrease sequences  1 2 @-}
-    {-@ Decrease descending 3 4 @-}
-    {-@ Decrease ascending  3 4 @-}
+    {-@ decrease sequences  1 2 @-}
+    {-@ decrease descending 3 4 @-}
+    {-@ decrease ascending  3 4 @-}
     sequences (a:b:xs) (_::Int)
       | a `compare` b == GT = descending b [a]  xs 1
       | otherwise           = ascending  b (a:) xs 1
diff --git a/tests/pos/GhcSort2.hs b/tests/pos/GhcSort2.hs
--- a/tests/pos/GhcSort2.hs
+++ b/tests/pos/GhcSort2.hs
@@ -31,7 +31,7 @@
   where d = length xs + length ys
 
 
-{-@ Decrease merge 4 @-}
+{-@ decrease merge 4 @-}
 {-@ merge :: (Ord a) => xs:OList a -> ys:OList a -> {n:Nat|n = (len xs) + (len ys)} -> OList a  @-}
 merge :: (Ord a) => [a] -> [a] -> Int -> [a]
 merge [] ys _ = ys
diff --git a/tests/pos/GhcSort3.T.hs b/tests/pos/GhcSort3.T.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/GhcSort3.T.hs
@@ -0,0 +1,41 @@
+module GhcSort () where
+
+{-@ type OList a =  [a]<{\fld v -> (v >= fld)}>  @-}
+
+{-@ assert sort3 :: (Ord a) => w:a -> [{v:a|v<=w}] -> OList a @-}
+sort3 :: (Ord a) => a -> [a] -> [a]
+sort3 w ls = qsort w ls [] (length ls) 0
+
+{-@ decrease qsort 5 6 @-}
+{-@ decrease rqsort 5 6 @-}
+{-@ decrease qpart 8 9 @-}
+{-@ decrease rqpart 8 9 @-}
+qsort :: (Ord a) =>  a -> [a] -> [a] -> Int -> Int -> [a]
+{-@ qsort, rqsort :: (Ord a) =>  w:a -> xs:[{v:a|v<=w}] -> OList {v:a|v>=w} -> {v:Int | v = (len xs) } -> {v:Int | v = 0 } -> OList a @-}
+qsort _ []     r _ _ = r
+qsort _ [x]    r _ _ = x:r
+qsort w (x:xs) r _ _ = qpart w x xs [] [] r (length xs) (length xs + 1)
+
+{-@ qpart, rqpart :: (Ord a) => w:a -> x:{v:a|v<=w} -> xs:[{v:a|v <= w}] -> lt:[{v:a|((v<=x) && (v<=w))}] -> ge:[{v:a|((v >= x) && (v<=w))}] -> rs:(OList {v:a|v >= w}) -> {v:Int | v = ((len xs) + (len lt) + (len ge))} -> {v:Int|v = (len xs) + 1} -> OList a @-}
+qpart :: (Ord a) => a -> a -> [a] -> [a] -> [a] -> [a] -> Int -> Int -> [a]
+qpart w x [] rlt rge r _ _ =
+    rqsort x rlt (x:rqsort w rge r (length rge) 0) (length rlt) 0
+qpart w x (y:ys) rlt rge r d1 d2 =
+    case compare x y of
+        GT -> qpart w x ys (y:rlt) rge r d1 (d2 - 1)
+        _  -> qpart w x ys rlt (y:rge) r d1 (d2 - 1)
+
+{- rqsort :: (Ord a) =>  w:a -> xs:[{v:a|v<=w}] -> OList {v:a|v>=w} -> {v:Int | v = (len xs) } -> {v:Int | v = 0 } -> OList a @-}
+rqsort :: (Ord a) => a -> [a] -> [a] -> Int -> Int -> [a]
+rqsort _ []     r _ _ = r
+rqsort _ [x]    r _ _ = x:r
+rqsort w (x:xs) r _ _ = rqpart w x xs [] [] r (length xs) (length xs + 1)
+
+rqpart :: (Ord a) => a -> a -> [a] -> [a] -> [a] -> [a] -> Int -> Int -> [a]
+rqpart w x [] rle rgt r _ _ =
+    qsort x rle (x:qsort w rgt r (length rgt) 0) (length rle) 0 
+rqpart w x (y:ys) rle rgt r d1 d2 =
+    case compare y x of
+        GT -> rqpart w x ys rle (y:rgt) r d1 (d2-1)
+        _  -> rqpart w x ys (y:rle) rgt r d1 (d2-1)
+
diff --git a/tests/pos/Gradual.hs b/tests/pos/Gradual.hs
deleted file mode 100644
--- a/tests/pos/Gradual.hs
+++ /dev/null
@@ -1,13 +0,0 @@
-module Gradual where
-
-{-@ safe :: {v:Int | ?? } -> (Int, Int) @-}
-safe :: Int -> (Int, Int)
-safe x = (bar1 x, bar2 x)
-
-{-@ bar1 :: {v:Int | v < 0} -> Int @-}
-bar1 :: Int -> Int 
-bar1 x = x 
-
-{-@ bar2 :: {v:Int | v = 0} -> Int @-}
-bar2 :: Int -> Int 
-bar2 x = x
diff --git a/tests/pos/HasElem.hs b/tests/pos/HasElem.hs
--- a/tests/pos/HasElem.hs
+++ b/tests/pos/HasElem.hs
@@ -9,14 +9,14 @@
 hasElem x Nil = False
 hasElem x (Cons y ys) = x == y || hasElem x ys
 
-{-@ prop :: {v:Bool | Prop v <=> true} @-}
+{-@ prop :: {v:Bool | v} @-}
 prop :: Bool
 prop = hasElem 1 (Cons 1 Nil)
 
-{-@ prop1 :: {v:Bool | Prop v <=> false} @-}
+{-@ prop1 :: {v:Bool | not v } @-}
 prop1 :: Bool
 prop1 = hasElem 1 (Cons 2 Nil)
 
-{-@ prop2 :: {v:Bool | Prop v <=> false} @-}
+{-@ prop2 :: {v:Bool | not v } @-}
 prop2 :: Bool
 prop2 = hasElem 1 Nil
diff --git a/tests/pos/HedgeUnion.hs b/tests/pos/HedgeUnion.hs
--- a/tests/pos/HedgeUnion.hs
+++ b/tests/pos/HedgeUnion.hs
@@ -3,7 +3,7 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@
-  data Map [mlen] k a <l :: root:k -> k -> Prop, r :: root:k -> k -> Prop>
+  data Map [mlen] k a <l :: root:k -> k -> Bool, r :: root:k -> k -> Bool>
       = Tip 
       | Bin (right :: Map <l, r> k  a) 
   @-}
@@ -24,7 +24,7 @@
 
 -- Internal representation of hedgeUnion:
 
-{-@ LAZYVAR d20r @-}
+{-@ lazyvar d20r @-}
 
 g t1 d20i = 
   case d20i of
diff --git a/tests/pos/Holes-Slicing.hs b/tests/pos/Holes-Slicing.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Holes-Slicing.hs
@@ -0,0 +1,21 @@
+module Foo () where
+
+{-@ LIQUID "--savequery"      @-}
+{-@ LIQUID "--noslice"        @-}
+{-@ LIQUID "--maxparam=3"        @-}
+
+{-@ measure isFoo :: A -> B -> Bool @-}
+{-@ isFoo :: a:A -> b:B -> {v:Bool | v <=> isFoo a b} @-}
+isFoo :: A -> B -> Bool
+isFoo a b = undefined
+
+{-@ prop1 :: u:A -> p:B -> {v : Int | isFoo u p <=> (v < 2) } @-}
+prop1 :: A -> B -> Int 
+prop1 = undefined 
+
+{-@ foo :: A -> B -> _ @-}
+foo :: A -> B -> Int 
+foo a b = if isFoo a b then 0 else 2 
+
+data A 
+data B 
diff --git a/tests/pos/Holes.hs b/tests/pos/Holes.hs
--- a/tests/pos/Holes.hs
+++ b/tests/pos/Holes.hs
@@ -29,6 +29,7 @@
 x =  bar [1]
 
 {-@ plus :: x:_ -> y:_ -> {v:_ | v = x + y} @-}
+plus :: Int -> Int -> Int 
 plus x y = x + y
 
 
diff --git a/tests/pos/IcfpDemo.hs b/tests/pos/IcfpDemo.hs
--- a/tests/pos/IcfpDemo.hs
+++ b/tests/pos/IcfpDemo.hs
@@ -24,7 +24,7 @@
   | lo < hi   = lo : range (lo + 1) hi
   | otherwise = []
 
-{-@ data L [sz] a <p :: L a -> Prop>
+{-@ data L [sz] a <p :: L a -> Bool>
       = N | C (x::a) (xs::L <p> a <<p>>)
   @-}
 data L a = N | C a (L a)
@@ -46,14 +46,14 @@
   | x < y     = x `C` merge xs (y `C` ys)
   | otherwise = y `C` merge (x `C` xs) ys
 
-{-@ measure emp  :: L a -> Prop
+{-@ measure emp  :: L a -> Bool
     emp (N)      = true
     emp (C x xs) = false
   @-}
 
 {-@ type Stream a = {xs: L <{\v -> not (emp v)}> a | not (emp xs)} @-}
 
-{-@ Lazy repeat @-}
+{-@ lazy repeat @-}
 {-@ repeat :: a -> Stream a @-}
 repeat :: a -> L a
 repeat x = x `C` repeat x
diff --git a/tests/pos/Infinity.hs b/tests/pos/Infinity.hs
--- a/tests/pos/Infinity.hs
+++ b/tests/pos/Infinity.hs
@@ -2,7 +2,7 @@
 
 import Language.Haskell.Liquid.Prelude
 {-@ LIQUID "--totality" @-}
-{-@ Lazy inf @-}
+{-@ lazy inf @-}
 
 {-@ inf :: {v:[Int] | (((len v) > oo) && ((len v) > 2))} @-}
 inf :: [Int]
diff --git a/tests/pos/LambdaEval.hs b/tests/pos/LambdaEval.hs
--- a/tests/pos/LambdaEval.hs
+++ b/tests/pos/LambdaEval.hs
@@ -50,7 +50,7 @@
 {-@ invariant {v:Expr | (elen v) >= 0} @-}
 
 {-@
-measure isValue      :: Expr -> Prop
+measure isValue      :: Expr -> Bool
 isValue (Const i)    = true
 isValue (Lam x e)    = true
 isValue (Var x)      = false
@@ -67,7 +67,7 @@
 -------------------------- The Evaluator ----------------------------
 ---------------------------------------------------------------------
 
-{-@ Decrease evalVar 2 @-}
+{-@ decrease evalVar 2 @-}
 evalVar :: Bndr -> [(Bndr, Expr)] -> Expr
 evalVar x ((y,v):sto) 
   | x == y
@@ -79,7 +79,7 @@
   = error "unbound variable"
 
 
-{-@ Decrease eval 2 @-}
+{-@ decrease eval 2 @-}
 {-@ eval :: [(Bndr, Value)] -> Expr -> ([(Bndr, Value)], Value) @-}
 eval sto (Const i) 
   = (sto, Const i)
diff --git a/tests/pos/LambdaEvalMini.hs b/tests/pos/LambdaEvalMini.hs
--- a/tests/pos/LambdaEvalMini.hs
+++ b/tests/pos/LambdaEvalMini.hs
@@ -30,7 +30,7 @@
 
 {-@ invariant {v:Expr | (elen v) >= 0} @-}
 
-{-@  measure isValue :: Expr -> Prop
+{-@  measure isValue :: Expr -> Bool
      isValue (Lam x e)    = true 
      isValue (Var x)      = false
      isValue (App e1 e2)  = false
@@ -53,7 +53,7 @@
 
 -- A "value" is simply: {v: Expr | isValue v } *)
 
-{-@ Decrease eval 2 @-}
+{-@ decrease eval 2 @-}
 {-@ eval :: [(Bndr, Value)] -> Expr -> ([(Bndr, Value)], Value) @-}
 
 eval sto (Var x)  
diff --git a/tests/pos/LambdaEvalSuperTiny.hs b/tests/pos/LambdaEvalSuperTiny.hs
--- a/tests/pos/LambdaEvalSuperTiny.hs
+++ b/tests/pos/LambdaEvalSuperTiny.hs
@@ -31,7 +31,7 @@
 
 {-@ invariant {v:Expr | (elen v) >= 0} @-}
 
-{-@  measure isValue :: Expr -> Prop
+{-@  measure isValue :: Expr -> Bool
      isValue (Lam x e)    = true 
      isValue (Var x)      = false
      isValue (App e1 e2)  = false
@@ -49,7 +49,7 @@
 evalVar = error "HIDEME"
 
 {-@ eval :: Store -> e:Expr -> (Pair Store Value) @-}
-{-@ Decrease eval 2 @-}
+{-@ decrease eval 2 @-}
 eval sto (Var x)  
   = P sto (evalVar x sto)
 
diff --git a/tests/pos/LambdaEvalTiny.hs b/tests/pos/LambdaEvalTiny.hs
--- a/tests/pos/LambdaEvalTiny.hs
+++ b/tests/pos/LambdaEvalTiny.hs
@@ -28,7 +28,7 @@
 
 {-@ invariant {v:Expr | (elen v) >= 0} @-}
 
-{-@  measure isValue :: Expr -> Prop
+{-@  measure isValue :: Expr -> Bool
      isValue (Lam x e)    = true 
      isValue (Var x)      = false
      isValue (App e1 e2)  = false
@@ -45,7 +45,7 @@
 evalVar :: Bndr -> [(Bndr, Expr)] -> Expr 
 evalVar = error "HIDEME"
 
-{-@ Decrease eval 2 @-}
+{-@ decrease eval 2 @-}
 
 {-@ eval :: sto:Store -> e:Expr -> (Store, Value) @-}
 
diff --git a/tests/pos/LazyWhere.hs b/tests/pos/LazyWhere.hs
--- a/tests/pos/LazyWhere.hs
+++ b/tests/pos/LazyWhere.hs
@@ -7,7 +7,7 @@
 pos = undefined
 
 
-{-@ LAZYVAR z @-}
+{-@ lazyvar z @-}
 foo = if x > 0 then z else x
   where z = pos x
         x = choose 0
diff --git a/tests/pos/LazyWhere1.hs b/tests/pos/LazyWhere1.hs
--- a/tests/pos/LazyWhere1.hs
+++ b/tests/pos/LazyWhere1.hs
@@ -10,9 +10,9 @@
 safeDiv :: Int -> Int -> Int
 safeDiv = undefined
 
-{-@ LAZYVAR z @-}
-{-@ LAZYVAR z1 @-}
-{-@ LAZYVAR z2 @-}
+{-@ lazyvar z @-}
+{-@ lazyvar z1 @-}
+{-@ lazyvar z2 @-}
 foo = if x > 0 then z else x
   where z  = z1 + z2
         z1 = 42 `safeDiv` x
diff --git a/tests/pos/Lib521.hs b/tests/pos/Lib521.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Lib521.hs
@@ -0,0 +1,7 @@
+module Lib521 where
+
+{-@ measure size @-}
+{-@ size    :: xs:[a] -> {v:Nat | v = size xs} @-}
+size :: [a] -> Int
+size []     = 0
+size (_:rs) = 1 + size rs
diff --git a/tests/pos/LiquidArray.hs b/tests/pos/LiquidArray.hs
--- a/tests/pos/LiquidArray.hs
+++ b/tests/pos/LiquidArray.hs
@@ -1,6 +1,6 @@
 module LiquidArray where
 
-{-@ set :: forall a <p :: x0: Int -> x1: a -> Prop, r :: x0: Int -> Prop>.
+{-@ set :: forall a <p :: x0: Int -> x1: a -> Bool, r :: x0: Int -> Bool>.
       i: Int<r> ->
       x: a<p i> ->
       a: (j: {v: Int<r> | v != i} -> a<p j>) ->
@@ -8,7 +8,7 @@
 set :: Int -> a -> (Int -> a) -> (Int -> a)
 set i x a = \k -> if k == i then x else a k
 
-{-@ get :: forall a <p :: x0: Int -> x1: a -> Prop, r :: x0: Int -> Prop>.
+{-@ get :: forall a <p :: x0: Int -> x1: a -> Bool, r :: x0: Int -> Bool>.
              i: Int<r> ->
              a: (j: Int<r> -> a<p j>) ->
              a<p i> @-}
diff --git a/tests/pos/LiquidAutomate.hs b/tests/pos/LiquidAutomate.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/LiquidAutomate.hs
@@ -0,0 +1,35 @@
+module Automate where
+
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+{-@ LIQUID "--proof-method=arithmetic" @-}
+
+{-
+fuel 0 for fib up to 1 
+fuel 1 for fib up to 2
+fuel 2 for fib up to 4
+fuel 3 for fib up to 8
+...
+-}
+
+
+{-@ LIQUID "--fuel=4" @-}
+
+import Language.Haskell.Liquid.ProofCombinators 
+
+
+fibA :: Int -> Int 
+{-@ axiomatize fibA @-}
+{-@ fibA :: Nat -> Nat @-}
+fibA i | i <= 1 = i
+      | otherwise = fibA (i-1) + fibA (i-2)
+
+
+fibUp :: Int -> Proof 
+{-@ fibUp :: i:Nat -> {fibA i <= fibA (i+1)} @-}
+fibUp i 
+ | i <= 2    = trivial
+ | otherwise = fibUp (i-1) &&& fibUp (i-2) *** QED 
+
+{-@ prop :: () -> {fibA 6 == 8 } @-}
+prop :: () -> Proof 
+prop _ = trivial  
diff --git a/tests/pos/ListConcat.hs b/tests/pos/ListConcat.hs
--- a/tests/pos/ListConcat.hs
+++ b/tests/pos/ListConcat.hs
@@ -1,3 +1,4 @@
+{-@ LIQUID "--pruneunsorted" @-}
 {-@ LIQUID "--no-termination" @-}
 
 module Foo () where
diff --git a/tests/pos/ListElem.hs b/tests/pos/ListElem.hs
--- a/tests/pos/ListElem.hs
+++ b/tests/pos/ListElem.hs
@@ -5,7 +5,7 @@
 {-@ listElem :: (Eq a) 
              => y:a 
              -> xs:[a]
-             -> {v:Bool | (Prop(v) <=> Set_mem(y, (listElts(xs))))} 
+             -> {v:Bool | v <=> Set_mem y (listElts xs)} 
   @-}
 
 listElem :: (Eq a) => a -> [a] -> Bool
diff --git a/tests/pos/ListISort-LType.hs b/tests/pos/ListISort-LType.hs
--- a/tests/pos/ListISort-LType.hs
+++ b/tests/pos/ListISort-LType.hs
@@ -6,7 +6,7 @@
 -------------- Defining A List Type --------------------------------
 --------------------------------------------------------------------
 
-{-@ data List [llen] a <p :: x0:a -> x1:a -> Prop>  
+{-@ data List [llen] a <p :: x0:a -> x1:a -> Bool>  
   = Nil 
   | Cons (h :: a) (t :: List <p> (a <p h>))
   @-}
diff --git a/tests/pos/ListKeys.hs b/tests/pos/ListKeys.hs
--- a/tests/pos/ListKeys.hs
+++ b/tests/pos/ListKeys.hs
@@ -1,3 +1,5 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module Foo () where
 import Data.Set (Set(..)) 
 
diff --git a/tests/pos/ListLen-LType.hs b/tests/pos/ListLen-LType.hs
--- a/tests/pos/ListLen-LType.hs
+++ b/tests/pos/ListLen-LType.hs
@@ -3,7 +3,7 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@  
-data List [llen] a <p :: x0:a -> x1:a -> Prop>  
+data List [llen] a <p :: x0:a -> x1:a -> Bool>  
   = Nil 
   | Cons (h :: a) (t :: List <p> (a <p h>))
 @-}
diff --git a/tests/pos/ListMSort-LType.hs b/tests/pos/ListMSort-LType.hs
--- a/tests/pos/ListMSort-LType.hs
+++ b/tests/pos/ListMSort-LType.hs
@@ -4,7 +4,7 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@  
-data List a <p :: x0:a -> x1:a -> Prop>  
+data List a <p :: x0:a -> x1:a -> Bool>  
   = Nil 
   | Cons (h :: a) (t :: List <p> (a <p h>))
 @-}
@@ -26,7 +26,7 @@
 split xs                   = (xs, Nil)
 
 
-{-@ Lazy merge @-}
+{-@ lazy merge @-}
 merge :: Ord a => List a -> List a -> List a
 merge xs Nil = xs
 merge Nil ys = ys
diff --git a/tests/pos/ListMSort.hs b/tests/pos/ListMSort.hs
--- a/tests/pos/ListMSort.hs
+++ b/tests/pos/ListMSort.hs
@@ -16,7 +16,7 @@
 split xs                   = (xs, [])
 
 
-{-@ Decrease merge 4 @-}
+{-@ decrease merge 4 @-}
 {-@ merge :: Ord a => xs:(OList a) -> ys:(OList a) -> d:{v:Int| v = (len xs) + (len ys)} -> {v:(OList a) | (len v) = d} @-}
 merge :: Ord a => [a] -> [a] -> Int -> [a]
 merge xs [] _ = xs
diff --git a/tests/pos/ListQSort-LType.hs b/tests/pos/ListQSort-LType.hs
--- a/tests/pos/ListQSort-LType.hs
+++ b/tests/pos/ListQSort-LType.hs
@@ -3,7 +3,7 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@
-data List [llen] a <p :: x0:a -> x1:a -> Prop>
+data List [llen] a <p :: x0:a -> x1:a -> Bool>
   = Nil
   | Cons (h :: a) (t :: List <p> (a <p h>))
 @-}
diff --git a/tests/pos/ListRange-LType.hs b/tests/pos/ListRange-LType.hs
--- a/tests/pos/ListRange-LType.hs
+++ b/tests/pos/ListRange-LType.hs
@@ -5,7 +5,7 @@
 {-@ LIQUID "--no-termination" @-}
 
 {-@  
-data List [llen] a <p :: x0:a -> x1:a -> Prop>  
+data List [llen] a <p :: x0:a -> x1:a -> Bool>  
   = Nil 
   | Cons (h :: a) (t :: List <p> (a <p h>))
 @-}
diff --git a/tests/pos/ListSort.hs b/tests/pos/ListSort.hs
--- a/tests/pos/ListSort.hs
+++ b/tests/pos/ListSort.hs
@@ -1,7 +1,8 @@
 module ListSort (insertSort, insertSort', mergeSort, quickSort) where
 
 
-{-@ type OList a = [a]<{\fld v -> (v >= fld)}> @-}
+{-@ type OList a    = [a]<{\fld v -> (v >= fld)}> @-}
+{-@ type OListN a N = {v:OList a | len v == N} @-}
 
 ------------------------------------------------------------------------------
 -- Insert Sort ---------------------------------------------------------------
@@ -24,35 +25,30 @@
 -- Merge Sort ----------------------------------------------------------------
 ------------------------------------------------------------------------------
 
-{-@ mergeSort :: (Ord a) => xs:[a] -> {v:OList a| (len v) = (len xs)} @-}
+{-@ mergeSort :: (Ord a) => xs:[a] -> OListN a {len xs} @-}
 mergeSort :: Ord a => [a] -> [a]
-mergeSort []  = []
-mergeSort [x] = [x]
-mergeSort xs  = merge (mergeSort xs1) (mergeSort xs2) d 
-  where (xs1, xs2) = split xs
-        d          = length xs
-
-{-@ predicate Pr X Y = (((len Y) > 1) => ((len Y) < (len X))) @-}
+mergeSort []   = []
+mergeSort [x]  = [x]
+mergeSort xs   = merge (mergeSort xs1) (mergeSort xs2) 
+  where 
+    (xs1, xs2) = split xs
 
-{-@ split :: xs:[a] 
-          -> ({v:[a] | (Pr xs v)}, {v:[a]|(Pr xs v)})
-                 <{\x y -> ((len x) + (len y) = (len xs))}> 
-  @-}
+{-@ type Half a Xs  = {v:[a] | (len v > 1) => (len v < len Xs)} @-}
 
+{-@ type Halves a Xs = {v: (Half a Xs, Half a Xs) | len (fst v) + len (snd v) == len Xs} @-}
+ 
+{-@ split :: xs:[a] -> Halves a xs @-}
 split :: [a] -> ([a], [a])
 split (x:(y:zs)) = (x:xs, y:ys) where (xs, ys) = split zs
 split xs         = (xs, [])
 
-{-@ Decrease merge 4 @-}
-{-@ merge :: Ord a => xs:(OList a) -> ys:(OList a) -> d:{v:Int| v = (len xs) + (len ys)} -> {v:(OList a) | (len v) = d} @-}
-merge :: Ord a => [a] -> [a] -> Int -> [a]
-merge xs [] _ = xs
-merge [] ys _ = ys
-merge (x:xs) (y:ys) d
-  | x <= y
-  = x: merge xs (y:ys) (d-1)
-  | otherwise 
-  = y : merge (x:xs) ys (d-1)
+{-@ merge :: Ord a => xs:OList a -> ys:OList a -> OListN a {len xs + len ys} / [(len xs + len ys)] @-}
+merge :: Ord a => [a] -> [a] ->  [a]
+merge xs []         = xs
+merge [] ys         = ys
+merge (x:xs) (y:ys)
+  | x <= y          = x: merge xs (y:ys)
+  | otherwise       = y : merge (x:xs) ys
 
 ------------------------------------------------------------------------------
 -- Quick Sort ----------------------------------------------------------------
diff --git a/tests/pos/LocalLazy.hs b/tests/pos/LocalLazy.hs
--- a/tests/pos/LocalLazy.hs
+++ b/tests/pos/LocalLazy.hs
@@ -2,11 +2,11 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ Lazy foo @-}
+{-@ lazy foo @-}
 foo x = foo x
 
 
 bar = liquidAssertB (inf n > 0)
   where n     = choose 0
-       {-@ Lazy inf @-}
+       {-@ lazy inf @-}
         inf n = inf n
diff --git a/tests/pos/LocalTermExpr.hs b/tests/pos/LocalTermExpr.hs
--- a/tests/pos/LocalTermExpr.hs
+++ b/tests/pos/LocalTermExpr.hs
@@ -14,7 +14,7 @@
 myfoo = foo 5 True
   where
     n = False
-    {-@ foo :: n:_ -> b:{_ | n >= 0 && Prop b} -> {v:_ | n >= 0 && (Prop b)} / [n-0] @-}
+    {-@ foo :: n:_ -> b:{_ | n >= 0 && b} -> {v:_ | n >= 0 && b} / [n-0] @-}
     foo :: Int -> Bool -> Bool
     foo 0 _ = True
     foo n b = foo (n-1) b
diff --git a/tests/pos/LogicCurry1.hs b/tests/pos/LogicCurry1.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/LogicCurry1.hs
@@ -0,0 +1,20 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--maxparams=5"     @-}
+
+
+{-@ measure ack :: Int -> Int -> Int  @-}
+
+{-@ assume ack :: n:Int -> {v: (x:Int -> {v:Int | v == ack n x}) | v == ack n } @-}
+ack :: Int -> Int -> Int
+ack = undefined
+
+bar :: Int -> Int -> Int
+{-@ bar :: n:Int -> {v:_ | v == ack n } @-}
+bar m = ack m
+
+{-
+foo :: Int -> Int -> Int
+{- foo :: n:Int -> Int -> Int  @-}
+foo n x = bar x n
+-}
diff --git a/tests/pos/Map.hs b/tests/pos/Map.hs
--- a/tests/pos/Map.hs
+++ b/tests/pos/Map.hs
@@ -3,7 +3,7 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@ 
-  data Map [mlen] k a <l :: root:k -> k -> Prop, r :: root:k -> k -> Prop>
+  data Map [mlen] k a <l :: root:k -> k -> Bool, r :: root:k -> k -> Bool>
       = Tip 
       | Bin (sz    :: Size) 
             (key   :: k) 
diff --git a/tests/pos/Map0.hs b/tests/pos/Map0.hs
--- a/tests/pos/Map0.hs
+++ b/tests/pos/Map0.hs
@@ -3,7 +3,7 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@ 
-  data Map [mlen] k a <l :: root:k -> x1:k -> Prop, r :: root:k -> x1:k -> Prop>
+  data Map [mlen] k a <l :: root:k -> x1:k -> Bool, r :: root:k -> x1:k -> Bool>
       = Tip 
       | Bin (sz    :: Size) 
             (key   :: k) 
diff --git a/tests/pos/Map2.hs b/tests/pos/Map2.hs
--- a/tests/pos/Map2.hs
+++ b/tests/pos/Map2.hs
@@ -1,18 +1,18 @@
-module Map () where
+module Map (singleton, insert, delete) where
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ 
-  data Map [mlen] k a <l :: root:k -> k -> Prop, r :: root:k -> k -> Prop>
-      = Tip 
-      | Bin (sz    :: Size) 
-            (key   :: k) 
-            (value :: a) 
-            (left  :: Map <l, r> (k <l key>) a) 
-            (right :: Map <l, r> (k <r key>) a) 
+{-@
+  data Map [mlen] k a <l :: root:k -> k -> Bool, r :: root:k -> k -> Bool>
+      = Tip
+      | Bin (sz    :: Size)
+            (key   :: k)
+            (value :: a)
+            (left  :: Map <l, r> (k <l key>) a)
+            (right :: Map <l, r> (k <r key>) a)
   @-}
 
-{-@ measure mlen :: (Map k a) -> Int 
+{-@ measure mlen :: (Map k a) -> Int
     mlen(Tip) = 0
     mlen(Bin s k v l r) = 1 + (if ((mlen l) < (mlen r)) then (mlen r) else (mlen l))
   @-}
@@ -34,7 +34,7 @@
 {-@ insert :: Ord k => k -> a -> OMap k a -> OMap k a @-}
 insert :: Ord k => k -> a -> Map k a -> Map k a
 insert kx x t
-  = case t of 
+  = case t of
      Tip -> singleton kx x
      Bin sz ky y l r
          -> case compare kx ky of
@@ -44,14 +44,14 @@
 
 {-@ delete :: (Ord k) => k:k -> OMap k a -> OMap {v:k| (v /= k)} a @-}
 delete :: Ord k => k -> Map k a -> Map k a
-delete k t 
-  = case t of 
+delete k t
+  = case t of
       Tip -> Tip
       Bin _ kx x l r
-          -> case compare k kx of 
+          -> case compare k kx of
                LT -> balance kx x (delete k l) r
                GT -> balance kx x l (delete k r)
-               EQ -> glue kx l r 
+               EQ -> glue kx l r
 
 
 glue :: k -> Map k a -> Map k a -> Map k a
@@ -61,20 +61,19 @@
   | size l > size r = let (km1, vm, lm) = deleteFindMax l in balance km1 vm lm r
   | otherwise       = let (km2, vm, rm) = deleteFindMin r in balance km2 vm l rm
 
-deleteFindMax t 
+deleteFindMax t
   = case t of
       Bin _ k x l Tip -> (k, x, l)
-      Bin _ k x l r -> let (km3, vm, rm) = deleteFindMax r in (km3, vm, (balance k x l rm))
+      Bin _ k x l r -> let (km3, vm, rm) = deleteFindMax r in (km3, vm, balance k x l rm)
       Tip           -> (error ms, error ms, Tip)
-  where ms = "Map.deleteFindMax : can not return the maximal element of an empty Map"   
-
+  where ms = "Map.deleteFindMax : can not return the maximal element of an empty Map"
 
-deleteFindMin t 
+deleteFindMin t
   = case t of
       Bin _ k x Tip r -> (k, x, r)
-      Bin _ k x l r -> let (km4, vm, lm) = deleteFindMin l in (km4, vm, (balance k x lm r))
+      Bin _ k x l r -> let (km4, vm, lm) = deleteFindMin l in (km4, vm, balance k x lm r)
       Tip             -> (error ms, error ms, Tip)
-  where ms = "Map.deleteFindMin : can not return the maximal element of an empty Map"   
+  where ms = "Map.deleteFindMin : can not return the maximal element of an empty Map"
 
 
 -------------------------------------------------------------------------------
@@ -85,8 +84,8 @@
 delta = 5
 ratio = 2
 
-balance :: k -> a -> Map k a -> Map k a -> Map k a 
-balance k x l r 
+balance :: k -> a -> Map k a -> Map k a -> Map k a
+balance k x l r
   | sizeL + sizeR <= 1   = Bin sizeX k x l r
   | sizeR >= delta*sizeL = rotateL k x l r
   | sizeL >= delta*sizeR = rotateR k x l r
@@ -97,7 +96,7 @@
 
 -- rotate
 rotateL :: a -> b -> Map a b -> Map a b -> Map a b
-rotateL k x l r@(Bin _ _ _ ly ry) 
+rotateL k x l r@(Bin _ _ _ ly ry)
   | size ly < ratio*size ry  = singleL k x l r
   | otherwise                = doubleL k x l r
 rotateL _ _ _ Tip = error "rotateL Tip"
@@ -118,31 +117,31 @@
 doubleL, doubleR :: a -> b -> Map a b -> Map a b -> Map a b
 doubleL k1 x1 t1 (Bin _ k2 x2 (Bin _ k3 x3 t2 t3) t4)
  =bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4)
-doubleL _ _ _ _ = error "doubleL" 
-doubleR k1 x1 (Bin _ k2 x2 t1 (Bin _ k3 x3 t2 t3)) t4 
+doubleL _ _ _ _ = error "doubleL"
+doubleR k1 x1 (Bin _ k2 x2 t1 (Bin _ k3 x3 t2 t3)) t4
   = bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4)
-doubleR _ _ _ _ = error "doubleR" 
+doubleR _ _ _ _ = error "doubleR"
 
 bin :: k -> a -> Map k a -> Map k a -> Map k a
-bin k x l r 
+bin k x l r
   = Bin (size l + size r + 1) k x l r
 
 size :: Map k a -> Int
-size t 
-  = case t of 
+size t
+  = case t of
       Tip            -> 0
       Bin sz _ _ _ _ -> sz
 
 
--- chkDel x Tip                = liquidAssertB True  
+-- chkDel x Tip                = liquidAssertB True
 -- chkDel x (Bin sz k v lt rt) = liquidAssertB (not (x == k)) && chkDel x lt && chkDel x rt
 
--- chkMin x Tip                = liquidAssertB True  
+-- chkMin x Tip                = liquidAssertB True
 -- chkMin x (Bin sz k v lt rt) = liquidAssertB (x<k) && chkMin x lt && chkMin x rt
 
-chk Tip               = liquidAssertB True  
+chk Tip               = liquidAssertB True
 chk (Bin s k v lt rt) = chk lt && chk rt && chkl k lt && chkr k rt
-		
+
 chkl k Tip              = liquidAssertB True
 chkl k (Bin _ kl _ _ _) = liquidAssertB (kl < k)
 
@@ -155,15 +154,15 @@
 key1 = choose 0
 val1 = choose 1
 
-bst1 = insert key val Tip
+bst1010 = insert key val Tip
 bst  = insert key val $ insert key1 val1 Tip
 
 mkBst = foldl (\t (k, v) -> insert k v t) Tip
 
-prop        = chk bst1
+prop        = chk bst1010
 prop1       = chk $ mkBst $ zip [1..] [1..]
 
-propDelete  = chk bst' -- && chkDel x bst' 
-   where 
+propDelete  = chk bst' -- && chkDel x bst'
+   where
      x      = choose 0
      bst'   = delete x bst
diff --git a/tests/pos/MapFusion.hs b/tests/pos/MapFusion.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/MapFusion.hs
@@ -0,0 +1,42 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+{-# LANGUAGE IncoherentInstances #-}
+{-# LANGUAGE FlexibleContexts    #-}
+
+
+module MapFusion where
+
+import Prelude hiding (map)
+
+import Language.Haskell.Liquid.ProofCombinators
+
+{-@ axiomatize compose @-}
+compose :: (b -> c) -> (a -> b) -> a -> c
+compose f g x = f (g x)
+
+{-@ axiomatize map @-}
+map :: (a -> b) -> L a -> L b
+map f N = N 
+map f (C x xs) = C (f x) (map f xs)
+ 
+
+
+{-@ map_fusion :: f:(a -> a) -> g:(a -> a) -> xs:{L a | true }
+   -> {map (compose f g) xs == compose (map f) (map g) xs } @-}
+map_fusion :: (a -> a) -> (a -> a) -> L a -> Proof
+map_fusion f g N        = trivial 
+map_fusion f g (C x xs) = map_fusion f g xs 
+
+
+data L a = N | C a (L a)
+{-@ data L [llen] a = N | C {headlist :: a, taillist :: L a }@-}
+
+{-@ measure llen @-}
+llen :: L a -> Int
+{-@ llen :: L a -> Nat @-}
+llen N        = 0
+llen (C _ xs) = 1 + llen xs
diff --git a/tests/pos/MapReduceVerified.hs b/tests/pos/MapReduceVerified.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/MapReduceVerified.hs
@@ -0,0 +1,238 @@
+-- | Proof of equivalence of MapReduce 
+-- | mapReduce n op f is == f is 
+
+-- | Niki Vazou Sep 2016 
+
+{-@ LIQUID "--higherorder"   @-}
+{-@ LIQUID "--totality"      @-}
+{-@ LIQUID "--exactdc"       @-}
+
+
+module MapReduce where 
+
+import Prelude hiding (mconcat, map, split, take, drop, sum)
+import Language.Haskell.Liquid.ProofCombinators 
+
+-------------------------------------------------------------------------------
+------------  Map Reduce Definition  ------------------------------------------
+-------------------------------------------------------------------------------
+
+
+{-@ axiomatize mapReduce @-}
+mapReduce :: Int -> (List a -> b) -> (b -> b -> b) -> List a -> b 
+mapReduce n f op is = reduce op (f N) (map f (chunk n is))
+
+{-@ axiomatize reduce @-}
+reduce :: (a -> a -> a) -> a -> List a -> a 
+reduce op b N        = b 
+reduce op b (C x xs) = op x (reduce op b xs) 
+
+chunk :: Int -> List a -> List (List a)
+
+
+-------------------------------------------------------------------------------
+------------  Application: List sum  ------------------------------------------
+-------------------------------------------------------------------------------
+
+sum  :: List Int -> Int 
+plus :: Int -> Int -> Int 
+
+{-@ axiomatize msum @-}
+msum :: Int -> List Int -> Int 
+msum n is = mapReduce n sum plus is 
+
+
+mapReduceSum :: Int -> List Int -> Proof 
+{-@ mapReduceSum :: n:Int -> is:List Int -> { sum is == mapReduce n sum plus is} @-}
+mapReduceSum n is 
+  =   msum n is 
+  ==. mapReduce n sum plus is 
+  ==. sum is  ? mapReduceTheorem n sum plus sumLeftId sumDistributes is 
+  *** QED 
+
+-------------------------------------------------------------------------------
+------------  Main MapReduce Theorem ------------------------------------------
+-------------------------------------------------------------------------------
+
+
+mapReduceTheorem :: Int -> (List a -> b) -> (b -> b -> b) -> (List a -> Proof) -> (List a -> List a -> Proof) -> List a -> Proof 
+{-@ mapReduceTheorem :: n:Int -> f:(List a -> b) -> op:(b -> b -> b)
+     -> left_id:(xs:List a -> {op (f xs) (f N) == f xs } ) 
+     -> distributionTheorem:(xs:List a -> ys:List a -> {f (append xs ys) == op (f xs) (f ys)} )
+     -> is:List a ->
+     { mapReduce n f op is == f is }
+     / [llen is]
+  @-}
+mapReduceTheorem n f op left_id _ N 
+  =   mapReduce n f op N 
+  ==. reduce op (f N) (map f (chunk n N))
+  ==. reduce op (f N) (map f (C N N))
+  ==. reduce op (f N) (f N `C` map f N )
+  ==. reduce op (f N) (f N `C` N)
+  ==. op (f N) (reduce op (f N) N)
+  ==. op (f N) (f N)
+       ? left_id N
+  ==. f N 
+  *** QED 
+mapReduceTheorem n f op left_id _ is@(C x xs)
+  | n <= 1 || llen is <= n 
+  =   mapReduce n f op is 
+  ==. reduce op (f N) (map f (chunk n is))
+  ==. reduce op (f N) (map f (C is N))
+  ==. reduce op (f N) (f is `C` map f N)
+  ==. reduce op (f N) (f is `C` N)
+  ==. op (f is) (reduce op (f N) N)
+  ==. op (f is) (f N)
+  ==. f is  ? left_id is
+  *** QED 
+mapReduceTheorem n f op left_id distributionTheorem is 
+  =   mapReduce n f op is 
+  ==. reduce op (f N) (map f (chunk n is)) 
+  ==. reduce op (f N) (map f (C (take n is) (chunk n (drop n is)))) 
+  ==. reduce op (f N) (C (f (take n is)) (map f (chunk n (drop n is)))) 
+  ==. op (f (take n is)) (reduce op (f N) (map f (chunk n (drop n is))))  
+  ==. op (f (take n is)) (mapReduce n f op (drop n is)) 
+      ? mapReduceTheorem n f op left_id distributionTheorem (drop n is)
+  ==. op (f (take n is)) (f (drop n is)) 
+  ==. f (append (take n is) (drop n is))
+      ? distributionTheorem (take n is) (drop n is)
+  ==. f is 
+      ? appendTakeDrop n is 
+  *** QED  
+
+
+
+
+-------------------------------------------------------------------------------
+-----------  List Definition --------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+{-@ data List [llen] a = N | C {lhead :: a, ltail :: List a} @-}
+data List a = N | C a (List a)
+
+{-@ measure llen @-}
+llen :: List a -> Int 
+
+{-@ llen :: List a -> Nat @-}
+llen N        = 0 
+llen (C _ xs) = 1 + llen xs
+
+-------------------------------------------------------------------------------
+-----------  List Manipulation ------------------------------------------------
+-------------------------------------------------------------------------------
+
+-- Distribution 
+
+{-@ reflect map @-}
+{-@ map :: (a -> b) -> xs:List a -> {v:List b | llen v == llen xs } @-}
+map :: (a -> b) -> List a -> List b
+map _  N       = N
+map f (C x xs) = f x `C` map f xs 
+
+{-@ reflect chunk @-}
+{-@ chunk :: i:Int -> xs:List a -> {v:List (List a) | if (i <= 1 || llen xs <= i) then (llen v == 1) else (llen v < llen xs) } / [llen xs] @-}
+chunk i xs 
+  | i <= 1 
+  = C xs N 
+  | llen xs <= i 
+  = C xs N 
+  | otherwise
+  = C (take i xs) (chunk i (drop i xs))
+
+{-@ reflect drop @-}
+{-@ drop :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == llen xs - i } @-} 
+drop :: Int -> List a -> List a 
+drop i N = N 
+drop i (C x xs)
+  | i == 0 
+  = C x xs  
+  | otherwise 
+  = drop (i-1) xs 
+
+{-@ reflect take @-}
+{-@ take :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == i} @-} 
+take :: Int -> List a -> List a 
+take i N = N 
+take i (C x xs)
+  | i == 0 
+  = N  
+  | otherwise 
+  = C x (take (i-1) xs)
+
+
+{-@ reflect append @-}
+append :: List a -> List a -> List a 
+append N        ys = ys  
+append (C x xs) ys = x `C` (append xs ys)
+
+
+-------------------------------------------------------------------------------
+-----------  Helper Theorems --------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+-- | For input Distribution 
+{-@ appendTakeDrop :: i:Nat -> xs:{List a | i <= llen xs} 
+  -> {xs == append (take i xs) (drop i xs) }  @-}
+
+appendTakeDrop :: Int -> List a -> Proof 
+appendTakeDrop i N 
+  =   append (take i N) (drop i N)
+  ==. append N N 
+  ==. N 
+  *** QED 
+appendTakeDrop i (C x xs)
+  | i == 0 
+  =   append (take 0 (C x xs)) (drop 0 (C x xs))
+  ==. append N (C x xs)
+  ==. C x xs 
+  *** QED 
+  | otherwise
+  =   append (take i (C x xs)) (drop i (C x xs))
+  ==. append (C x (take (i-1) xs)) (drop (i-1) xs)
+  ==. C x (append (take (i-1) xs) (drop (i-1) xs))
+  ==. C x xs ? appendTakeDrop (i-1) xs 
+  *** QED 
+
+
+
+-------------------------------------------------------------------------------
+------------  Application: List sum  ------------------------------------------
+-------------------------------------------------------------------------------
+
+
+sumLeftId :: List Int -> Proof 
+{-@ sumLeftId :: xs:List Int -> {plus (sum xs) (sum N) == sum xs } @-}
+sumLeftId xs 
+  =  plus (sum xs) (sum N) ==. sum xs + 0 ==. sum xs *** QED 
+
+{-@ sumDistributes :: xs:List Int -> ys:List Int -> 
+      {sum (append xs ys) == plus (sum xs) (sum ys)} @-}
+sumDistributes :: List Int -> List Int -> Proof 
+sumDistributes N ys 
+  =   sum (append N ys)
+  ==. sum ys
+  ==. plus 0       (sum ys)
+  ==. plus (sum N) (sum ys)
+  *** QED 
+sumDistributes (C x xs) ys  
+  =   sum (append (C x xs) ys)
+  ==. sum (C x (append xs ys))
+  ==. x `plus` (sum (append xs ys))
+      ? sumDistributes xs ys
+  ==. x `plus` (plus (sum xs) (sum ys))
+  ==. x + (sum xs + sum ys)
+  ==. ((x + sum xs) + sum ys)
+  ==. ((x `plus` sum xs) `plus` sum ys)
+  ==. sum (C x xs) `plus` sum ys
+  *** QED 
+
+
+{-@ axiomatize plus @-}
+plus x y = x + y 
+
+{-@ axiomatize sum @-}
+sum N        = 0 
+sum (C x xs) = x `plus` sum xs
+
diff --git a/tests/pos/MeasureSets.hs b/tests/pos/MeasureSets.hs
--- a/tests/pos/MeasureSets.hs
+++ b/tests/pos/MeasureSets.hs
@@ -1,3 +1,5 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module Measures where
 
 import Data.Set 
@@ -10,7 +12,6 @@
 foo1 :: F a -> Set a
 foo1 (F x) = singleton x
 foo1 E     = empty
-
 
 foo :: F Int -> Int
 foo (F x) = x + 1
diff --git a/tests/pos/Measures.hs b/tests/pos/Measures.hs
--- a/tests/pos/Measures.hs
+++ b/tests/pos/Measures.hs
@@ -1,12 +1,12 @@
 module Measures where
 
-{-@ data Wrapper a <p :: a -> Prop, r :: a -> a -> Prop > 
+{-@ data Wrapper a <p :: a -> Bool, r :: a -> a -> Bool > 
     = Wrap (rgref_ref :: a<p>) @-}
 data Wrapper a = Wrap (a)
 
 -- Two measures
-{-@ measure fwdextends :: Int -> Int -> Prop @-}
-{-@ measure actionP :: Int -> Prop @-}
+{-@ measure fwdextends :: Int -> Int -> Bool @-}
+{-@ measure actionP :: Int -> Bool @-}
 
 {-@ data Wrapper2  = Wrapper2 (unwrapper :: (Wrapper<{\x -> (true)},{\x y -> (fwdextends y x)}> Int )) @-}
 {- data Wrapper2  = Wrapper2 (unwrapper :: (Wrapper<{\x -> (actionP x)},{\x y -> (true)}> Int )) @-}
diff --git a/tests/pos/Measures1.hs b/tests/pos/Measures1.hs
--- a/tests/pos/Measures1.hs
+++ b/tests/pos/Measures1.hs
@@ -1,12 +1,12 @@
 module Measures where
 
-{-@ data Wrapper a <p :: a -> Prop, r :: a -> a -> Prop > 
+{-@ data Wrapper a <p :: a -> Bool, r :: a -> a -> Bool > 
     = Wrap (rgref_ref :: a<p>) @-}
 data Wrapper a = Wrap (a)
 
 -- Two measures
-{-@ measure fwdextends :: Int -> Int -> Prop @-}
-{-@ measure actionP :: Int -> Prop @-}
+{-@ measure fwdextends :: Int -> Int -> Bool @-}
+{-@ measure actionP :: Int -> Bool @-}
 
 {- data Wrapper2  = Wrapper2 (unwrapper :: (Wrapper<{\x -> (true)},{\x y -> (fwdextends y x)}> Int )) @-}
 {-@ data Wrapper2  = Wrapper2 (unwrapper :: (Wrapper<{\x -> (actionP x)},{\x y -> (true)}> Int )) @-}
diff --git a/tests/pos/MergeSort.hs b/tests/pos/MergeSort.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/MergeSort.hs
@@ -0,0 +1,52 @@
+------------------------------------------------------------------------------
+-- | An implementation of Merge Sort, where LH verifies:
+--   1. Termination (Totality) 
+--   2. The output is indeed in non-decreasing order 
+------------------------------------------------------------------------------
+
+module MergeSort (sort) where
+
+{-@ type OList a    = [a]<{\fld v -> (v >= fld)}> @-}
+
+{-@ type OListN a N = {v:OList a | len v == N} @-}
+
+-- | The top level `sort` function. Proved:
+--   (a) terminating, 
+--   (b) ordered, and 
+--   (c) of same size as input.
+
+{-@ sort :: (Ord a) => xs:[a] -> OListN a {len xs} @-}
+sort :: Ord a => [a] -> [a]
+sort []   = []
+sort [x]  = [x]
+sort xs   = merge (sort xs1) (sort xs2) 
+  where 
+    (xs1, xs2) = split xs
+
+-- Fun fact: if you delete the singleton case above,
+-- the resulting function is, in fact, non-terminating!
+
+-- | A type describing two `Halves` of a list `Xs` 
+
+{-@ type Halves a Xs = {v: (Half a Xs, Half a Xs) | len (fst v) + len (snd v) == len Xs} @-}
+
+-- | Each `Half` is empty or smaller than the input:
+
+{-@ type Half a Xs  = {v:[a] | (len v > 1) => (len v < len Xs)} @-}
+
+-- | The `split` function breaks its list into two `Halves`:
+
+{-@ split :: xs:[a] -> Halves a xs @-}
+split :: [a] -> ([a], [a])
+split (x:(y:zs)) = (x:xs, y:ys) where (xs, ys) = split zs
+split xs         = (xs, [])
+
+-- | Finally, the `merge` function combines two ordered lists into a single ordered result.
+
+{-@ merge :: Ord a => xs:OList a -> ys:OList a -> OListN a {len xs + len ys} / [(len xs + len ys)] @-}
+merge :: Ord a => [a] -> [a] ->  [a]
+merge xs []         = xs
+merge [] ys         = ys
+merge (x:xs) (y:ys)
+  | x <= y          = x : merge xs (y:ys)
+  | otherwise       = y : merge (x:xs) ys
diff --git a/tests/pos/MultipleInvariants.hs b/tests/pos/MultipleInvariants.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/MultipleInvariants.hs
@@ -0,0 +1,20 @@
+module Blank where
+
+import Data.Word
+import GHC.Ptr
+
+
+{-@ measure sizeOf :: forall a . Ptr a -> Int @-}
+
+{-@ invariant {v:Ptr Word16 | sizeOf v = 2} @-}
+{-@ invariant {v:Ptr Word32 | sizeOf v = 4} @-}
+
+
+{-@ bar :: p:_ -> {v:_ | sizeOf p == 4 }@-}
+bar :: Ptr Word32 -> ()
+bar (Ptr _) = ()
+
+{-@ foo :: p:_ -> {v:_ | sizeOf p == 2 }@-}
+foo :: Ptr Word16 -> ()
+foo (Ptr _) = ()
+
diff --git a/tests/pos/MutualRec.hs b/tests/pos/MutualRec.hs
--- a/tests/pos/MutualRec.hs
+++ b/tests/pos/MutualRec.hs
@@ -15,8 +15,8 @@
 fromDistinctAscList xs
   = create const (length xs) xs
   where
-    {-@ Decrease create  2 3 @-}
-    {-@ Decrease createR 1 4 @-}
+    {-@ decrease create  2 3 @-}
+    {-@ decrease createR 1 4 @-}
     create c (0::Int) xs' = c undefined xs'
 -- LIQUID for n = 1 n `div` 2 = 0 and the assume does not hold
     create c 1 xs' = case xs' of
diff --git a/tests/pos/NatClass.hs b/tests/pos/NatClass.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/NatClass.hs
@@ -0,0 +1,52 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+
+module Nat where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+
+{-@ data N [toInt] = Zero | Suc N @-}
+data N = Zero | Suc N
+
+{-@ measure toInt @-}
+{-@ toInt :: N -> Nat @-}
+toInt :: N -> Int
+toInt Zero = 0
+toInt (Suc n) = 1 + toInt n
+
+{-@ class VerifiedEq a where
+      eq :: a -> a -> Bool
+      refl :: x:a -> { v:Proof | eq x x }
+@-}
+class Eq a => VerifiedEq a where
+  eq   :: a -> a -> Bool 
+  eq = (==)
+  refl :: a -> Proof
+
+
+{-@ axiomatize eqN  @-}
+eqN :: N -> N -> Bool
+eqN Zero    Zero = True
+eqN (Suc m) (Suc n) = eqN m n
+eqN _ _ = False
+
+{-@ eqNRefl :: x:N -> { eqN x x } @-}
+eqNRefl :: N -> Proof
+eqNRefl Zero =   eqN Zero Zero
+             ==. True
+             *** QED
+eqNRefl (Suc n) =   eqN (Suc n) (Suc n)
+                ==. eqN n n
+                ==. True ? eqNRefl n
+                *** QED
+
+instance Eq N where
+  (==) = eqN  
+
+instance VerifiedEq N where
+  -- This define should derive automatically
+  {-@ define $ceq = eqN @-}
+  refl = eqNRefl
+
diff --git a/tests/pos/NewType.hs b/tests/pos/NewType.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/NewType.hs
@@ -0,0 +1,11 @@
+newtype Foo a = Bar Int  
+
+
+{-@ newtype Foo = Bar {x :: Nat} @-}
+
+{-@ fromFoo :: Foo a -> Nat @-}
+fromFoo :: Foo a -> Int 
+fromFoo (Bar n) = n 
+
+bar = Bar 0 
+
diff --git a/tests/pos/ORM.hs b/tests/pos/ORM.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ORM.hs
@@ -0,0 +1,98 @@
+module ORM where 
+
+{-@ LIQUID "--exactdc"  @-}
+{-@ LIQUID "--totality" @-}
+{-@ LIQUID "--higherorder" @-}
+
+
+import Prelude hiding (length, filter)
+import Language.Haskell.Liquid.ProofCombinators
+
+--  here is a "user" query
+{-@ prop :: L Row -> L {v:Row | rowLeft v == 5} @-}
+prop :: L Row -> L Row
+prop xs = mapCast evalQProp $ filter (evalQ (Qry Eq Fst (Const 5))) xs 		
+
+
+{-@ prop0 :: L Row -> L {v:Row | evalQ (Qry Eq Fst (Const 5)) v} @-}
+prop0 :: L Row -> L Row
+prop0 xs = filter (evalQ (Qry Eq Fst (Const 5))) xs 		
+
+
+
+{-@ mapCast :: (x:Row -> {evalQ (Qry Eq Fst (Const 5)) x <=> rowLeft x == 5}) 
+            -> L {v:Row | evalQ (Qry Eq Fst (Const 5)) v} 
+            -> L {v:Row | rowLeft v == 5} @-} 
+mapCast :: (Row -> Proof) -> L Row -> L Row 
+mapCast _ N = N
+mapCast p (C x xs) = cast (p x) x `C` mapCast p xs 
+
+
+
+evalQProp :: Row -> Proof 
+{-@ evalQProp :: x:Row -> {evalQ (Qry Eq Fst (Const 5)) x <=> rowLeft x == 5} @-}
+evalQProp (Row l r) 
+  =   evalQ (Qry Eq Fst (Const 5)) (Row l r)
+  ==. evalC Eq (evalV Fst (Row l r)) (evalV (Const 5) (Row l r))
+  ==. evalC Eq l 5
+  ==. l == 5
+  *** QED 
+
+
+
+--  here is the DB API (will add more detail later but its pretty self contained)
+
+data Cmp = Eq | Ne 
+{-@ data Cmp = Eq | Ne @-}
+
+data Val = Const {valConst :: Int} | Fst | Snd 
+{-@ data Val = Const {valConst :: Int} | Fst | Snd @-}
+
+data Qry = Qry {qryCmp :: Cmp, qryLHS :: Val, qryRHS :: Val }
+
+{-@ data Qry = Qry {qryCmp :: Cmp, qryLHS :: Val, qryRHS :: Val } @-}
+
+data Row = Row {rowLeft :: Int, rowRigth :: Int}
+{-@ data Row = Row {rowLeft :: Int, rowRigth :: Int} @-}
+
+data L a = N | C {hd :: a, tl :: L a}
+{-@ data L [length] a = N | C {hd :: a, tl :: L a} @-}
+
+length :: L a -> Int 
+{-@ length :: L a -> Nat @-}
+{-@ measure length @-}
+length N = 0 
+length (C _ xs) = 1 + length xs 
+
+------------------------------------------------------------------------
+{-@ reflect evalQ @-}
+evalQ :: Qry -> Row -> Bool 
+evalQ (Qry o v1 v2) r = evalC o (evalV v1 r) (evalV v2 r)
+
+{-@ reflect evalV @-}
+evalV :: Val -> Row -> Int 
+evalV (Const n) _         = n 
+evalV Fst       (Row l _) = l 
+evalV Snd       (Row _ r) = r
+
+{-@ reflect evalC @-}
+evalC :: Cmp -> Int -> Int -> Bool 
+evalC Eq x y = x == y 
+evalC Ne x y = x /= y 
+
+{-@ reflect filterQ @-}
+filterQ :: Qry -> L Row -> L Row 
+filterQ qry xs = filter (evalQ qry) xs 
+ 
+
+{-@ reflect filter @-}
+{-@ filter :: forall <p :: a -> Bool, w :: a -> Bool -> Bool>.
+                  {x::a , b::{v:Bool<w x> | v} |- {v:a | v == x} <: a<p> }
+                  (x:a -> Bool<w x>) -> L a -> L (a<p>)
+  @-}
+filter :: (a -> Bool) -> L a -> L a 
+filter _ N = N 
+filter p (C x xs) 
+  | p x       = x `C` filter p xs 
+  | otherwise = filter p xs 
+
diff --git a/tests/pos/OrdList.hs b/tests/pos/OrdList.hs
--- a/tests/pos/OrdList.hs
+++ b/tests/pos/OrdList.hs
@@ -1,3 +1,5 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module OrdList (
     OrdList,
         nilOL, isNilOL, unitOL, appOL, consOL, snocOL, concatOL, concatOL',
@@ -13,9 +15,9 @@
 {-@
 data OrdList [olen] a = None
                       | One  (x  :: a)
-                      | Many (xs :: ListNE a)
-                      | Cons (x  :: a)           (xs :: OrdList a)
-                      | Snoc (xs :: OrdList a)   (x  :: a)
+                      | Many (xs1 :: ListNE a)
+                      | Cons (x  :: a)           (xs3 :: OrdList a)
+                      | Snoc (xs2 :: OrdList a)   (x  :: a)
                       | Two  (x  :: OrdListNE a) (y  :: OrdListNE a)
 @-}
 
@@ -54,7 +56,7 @@
 
 
 {-@ nilOL    :: OrdListN a {0} @-}
-{-@ isNilOL  :: xs:OrdList a -> {v:Bool | ((Prop v) <=> ((olen xs) = 0))} @-}
+{-@ isNilOL  :: xs:OrdList a -> {v:Bool | v <=> (olen xs == 0)} @-}
 
 {-@ unitOL   :: a              -> OrdListN a {1} @-}
 {-@ snocOL   :: xs:OrdList a   -> a            -> OrdListN a {1+(olen xs)} @-}
diff --git a/tests/pos/PersistentVector.hs b/tests/pos/PersistentVector.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/PersistentVector.hs
@@ -0,0 +1,82 @@
+{-
+https://twitter.com/BrandonBloom/status/701261641971683328
+https://github.com/clojure/clojure/blob/d5708425995e8c83157ad49007ec2f8f43d8eac8/src/jvm/clojure/lang/PersistentVector.java#L148-L164
+-}
+
+{-@ LIQUID "--no-termination" @-}
+
+module PVec (arrayFor) where
+
+import Data.Bits
+
+-- | Simplified binary tree
+
+data Tree a = Leaf a
+            | Node (Tree a) (Tree a)
+
+-- | Specify "height" of a tree
+
+{-@ measure height @-}
+height :: Tree a -> Int
+height (Leaf _)   = 0
+height (Node l _) = 1 + height l
+
+-- | A tree whose height is H
+
+{-@ type TreeH a H = {v:Tree | height v == H } @-}
+
+-- | Specify tree must be "balanced"
+
+{-@ data Tree a = Leaf a
+                | Node { tLeft  :: Tree a
+                       , tRight :: TreeH a (height tLeft) }
+  @-}
+
+-- | Specify tree height is non-negative
+
+{-@ using (Tree a) as  {v:Tree a | 0 <= height v} @-}
+
+-- | Vector stores the height
+
+data Vec a = Vec { vShift  :: Int    -- ^ height
+                 , vTree   :: Tree a -- ^ actual nodes
+                 }
+
+-- | Refined type relates height of the `vTree` with `vShift`
+
+{-@ data Vec a = Vec { vShift :: Nat
+                     , vTree  :: TreeH a vShift
+                     }
+  @-}
+
+--------------------------------------------------------------------------------
+
+arrayFor :: Int -> Vec a -> Maybe a
+arrayFor i (Vec l n) = loop l n
+  where
+    loop :: Int -> Tree a -> Maybe a
+    loop level node
+      | level > 0 = let b      = shift i (- level) `mod` 2  -- get bit 0 or 1
+                        node'  = getNode node b             -- get child
+                        level' = level - 1                  -- next level
+                    in
+                        loop level' node'
+
+      | otherwise = Just (getValue node)
+
+{-@ getNode :: t:{Tree a | 0 < height t}
+            -> {v:Nat | v < 2}
+            -> {v:Tree a | height v = height t - 1 }
+  @-}
+getNode :: Tree a -> Int -> Tree a
+getNode (Node l _) 0 = l
+getNode (Node _ r) 1 = r
+getNode _          _ = impossible "provably safe"
+
+{-@ getValue :: {t:Tree a | 0 = height t} -> a @-}
+getValue :: Tree a -> a
+getValue (Leaf x) = x
+getValue _        = impossible "provably safe"
+
+{-@ impossible :: {v:String | false} -> a @-}
+impossible = error
diff --git a/tests/pos/PointDist.hs b/tests/pos/PointDist.hs
--- a/tests/pos/PointDist.hs
+++ b/tests/pos/PointDist.hs
@@ -48,7 +48,7 @@
 
 -- | Run-time Checks
 
-{-@ assume     :: b:_ -> a -> {v:a | Prop b} @-}
+{-@ assume     :: b:_ -> a -> {v:a | b} @-}
 assume True  x = x
 assume False _ = error "Failed Dynamic Check!"
 
diff --git a/tests/pos/Product.hs b/tests/pos/Product.hs
--- a/tests/pos/Product.hs
+++ b/tests/pos/Product.hs
@@ -1,4 +1,4 @@
-{-@ LIQUID "--total" @-}
+{-@ LIQUID "--totality" @-}
 
 
 module Vectors where
diff --git a/tests/pos/PromotedDataCons.hs b/tests/pos/PromotedDataCons.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/PromotedDataCons.hs
@@ -0,0 +1,12 @@
+
+{-# LANGUAGE DataKinds #-}
+
+newtype Offset struct member = Offset { unOffset :: Int }
+
+type OffsetN t = Offset (t 'Nothing)
+
+foo = Nothing 
+
+{-@ bar :: t 'Nothing @-}
+bar :: t 'Nothing
+bar = undefined 
diff --git a/tests/pos/Propability.hs b/tests/pos/Propability.hs
--- a/tests/pos/Propability.hs
+++ b/tests/pos/Propability.hs
@@ -1,15 +1,15 @@
-module Propability where
+module Boolability where
 
-{-@ type Propability = {v:Double | ((0.0 <= v) && (v <= 1.0)) } @-}
+{-@ type Boolability = {v:Double | ((0.0 <= v) && (v <= 1.0)) } @-}
 
-{-@ p :: Propability @-}
+{-@ p :: Boolability @-}
 p :: Double
 p = 0.8
 
 data DPD k = DPD [Pair k Double]
 
 data Pair x y = P x y
-{-@ data DPD k = DPD (val::{v:[Pair k Propability]|(total v) = 1.0 }) @-}
+{-@ data DPD k = DPD (val::{v:[Pair k Boolability]|(total v) = 1.0 }) @-}
 
 {-@ measure total :: [Pair k Double] -> Double 
     total([]) = 0.0
diff --git a/tests/pos/QQTySig.hs b/tests/pos/QQTySig.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/QQTySig.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+module Nats where
+
+import LiquidHaskell
+
+[lq| nats :: [{ v:Int | 0 <= v }] |]
+nats = [0,1,2,3,4,5,6,7,8,9,10]
+
diff --git a/tests/pos/QQTySigTyVars.hs b/tests/pos/QQTySigTyVars.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/QQTySigTyVars.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+module Nats where
+
+import LiquidHaskell
+
+[lq| nats :: Show s => s -> [{ v:Int | 0 <= v }] |]
+nats _ = [0,1,2,3,4,5,6,7,8,9,10]
+
+[lq| myId :: x:a -> { v:a | v = x } |]
+myId x = x
+
diff --git a/tests/pos/QQTySyn.hs b/tests/pos/QQTySyn.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/QQTySyn.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+module Nats where
+
+import LiquidHaskell
+
+[lq| type MyNat = { v:Int | 0 <= v } |]
+[lq| type MyList a N = { v:[a] | (len v) = N } |]
+
+[lq| nats :: MyList MyNat 11 |]
+nats = [0,1,2,3,4,5,6,7,8,9,10]
+
diff --git a/tests/pos/RBTree-col-height.hs b/tests/pos/RBTree-col-height.hs
--- a/tests/pos/RBTree-col-height.hs
+++ b/tests/pos/RBTree-col-height.hs
@@ -144,7 +144,7 @@
 
 {-@ type RBTN a N = {v: (RBT a) | (bh v) = N }              @-}
 
-{-@ measure isRB        :: RBTree a -> Prop
+{-@ measure isRB        :: RBTree a -> Bool
     isRB (Leaf)         = true
     isRB (Node c x l r) = ((isRB l) && (isRB r) && ((c == R) => ((IsB l) && (IsB r))))
   @-}
@@ -155,7 +155,7 @@
 
 {-@ type ARBTN a N = {v: ARBT a   | (bh v) = N }             @-}
 
-{-@ measure isARB        :: (RBTree a) -> Prop
+{-@ measure isARB        :: (RBTree a) -> Bool
     isARB (Leaf)         = true 
     isARB (Node c x l r) = ((isRB l) && (isRB r))
   @-}
@@ -171,7 +171,7 @@
     col (Leaf)          = B
   @-}
 
-{-@ measure isB        :: RBTree a -> Prop
+{-@ measure isB        :: RBTree a -> Bool
     isB (Leaf)         = false
     isB (Node c x l r) = c == B 
   @-}
@@ -180,7 +180,7 @@
 
 -- | Black Height
 
-{-@ measure isBH        :: RBTree a -> Prop
+{-@ measure isBH        :: RBTree a -> Bool
     isBH (Leaf)         = true
     isBH (Node c x l r) = ((isBH l) && (isBH r) && (bh l) = (bh r))
   @-}
diff --git a/tests/pos/RBTree-color.hs b/tests/pos/RBTree-color.hs
--- a/tests/pos/RBTree-color.hs
+++ b/tests/pos/RBTree-color.hs
@@ -140,7 +140,7 @@
 
 {-@ type RBT a    = {v: RBTree a | (isRB v)} @-}
 
-{-@ measure isRB        :: RBTree a -> Prop
+{-@ measure isRB        :: RBTree a -> Bool
     isRB (Leaf)         = true
     isRB (Node c x l r) = ((isRB l) && (isRB r) && ((c == R) => ((IsB l) && (IsB r))))
   @-}
@@ -149,7 +149,7 @@
 
 {-@ type ARBT a    = {v: RBTree a | (isARB v) } @-}
 
-{-@ measure isARB        :: (RBTree a) -> Prop
+{-@ measure isARB        :: (RBTree a) -> Bool
     isARB (Leaf)         = true 
     isARB (Node c x l r) = ((isRB l) && (isRB r))
   @-}
@@ -165,7 +165,7 @@
     col (Leaf)          = B
   @-}
 
-{-@ measure isB        :: RBTree a -> Prop
+{-@ measure isB        :: RBTree a -> Bool
     isB (Leaf)         = false
     isB (Node c x l r) = c == B 
   @-}
diff --git a/tests/pos/RBTree-height.hs b/tests/pos/RBTree-height.hs
--- a/tests/pos/RBTree-height.hs
+++ b/tests/pos/RBTree-height.hs
@@ -144,14 +144,14 @@
 
 -- | Color of a tree
 
-{-@ measure isB        :: RBTree a -> Prop
+{-@ measure isB        :: RBTree a -> Bool
     isB (Leaf)         = false
     isB (Node c x l r) = c == B 
   @-}
 
 -- | Black Height
 
-{-@ measure isBH        :: RBTree a -> Prop
+{-@ measure isBH        :: RBTree a -> Bool
     isBH (Leaf)         = true
     isBH (Node c x l r) = ((isBH l) && (isBH r) && (bh l) = (bh r))
   @-}
diff --git a/tests/pos/RBTree-ord.hs b/tests/pos/RBTree-ord.hs
--- a/tests/pos/RBTree-ord.hs
+++ b/tests/pos/RBTree-ord.hs
@@ -134,7 +134,7 @@
 
 -- | Binary Search Ordering
 
-{-@ data RBTree a <l :: a -> a -> Prop, r :: a -> a -> Prop>
+{-@ data RBTree a <l :: a -> a -> Bool, r :: a -> a -> Bool>
             = Leaf
             | Node (c     :: Color)
                    (key   :: a)
diff --git a/tests/pos/RBTree.hs b/tests/pos/RBTree.hs
--- a/tests/pos/RBTree.hs
+++ b/tests/pos/RBTree.hs
@@ -1,5 +1,4 @@
 {-@ LIQUID "--no-termination" @-}
-{-@ LIQUID "--diff"           @-}
 
 module Foo where
 
@@ -138,7 +137,7 @@
 {-@ type ORBTL a X = RBT {v:a | v < X} @-}
 {-@ type ORBTG a X = RBT {v:a | X < v} @-}
 
-{-@ measure isRB        :: RBTree a -> Prop
+{-@ measure isRB        :: RBTree a -> Bool
     isRB (Leaf)         = true
     isRB (Node c x l r) = isRB l && isRB r && (c == R => (IsB l && IsB r))
   @-}
@@ -148,7 +147,7 @@
 {-@ type ARBT a    = {v: ORBT a | isARB v && isBH v} @-}
 {-@ type ARBTN a N = {v: ARBT a | bh v = N }         @-}
 
-{-@ measure isARB        :: (RBTree a) -> Prop
+{-@ measure isARB        :: (RBTree a) -> Bool
     isARB (Leaf)         = true 
     isARB (Node c x l r) = (isRB l && isRB r)
   @-}
@@ -164,7 +163,7 @@
     col (Leaf)          = B
   @-}
 
-{-@ measure isB        :: RBTree a -> Prop
+{-@ measure isB        :: RBTree a -> Bool
     isB (Leaf)         = false
     isB (Node c x l r) = c == B 
   @-}
@@ -173,7 +172,7 @@
 
 -- | Black Height
 
-{-@ measure isBH        :: RBTree a -> Prop
+{-@ measure isBH        :: RBTree a -> Bool
     isBH (Leaf)         = true
     isBH (Node c x l r) = (isBH l && isBH r && bh l = bh r)
   @-}
@@ -185,7 +184,7 @@
 
 -- | Binary Search Ordering
 
-{-@ data RBTree a <l :: a -> a -> Prop, r :: a -> a -> Prop>
+{-@ data RBTree a <l :: a -> a -> Bool, r :: a -> a -> Bool>
             = Leaf
             | Node (c     :: Color)
                    (key   :: a)
diff --git a/tests/pos/RealProps.hs b/tests/pos/RealProps.hs
--- a/tests/pos/RealProps.hs
+++ b/tests/pos/RealProps.hs
@@ -2,7 +2,7 @@
 
 module Div where
 
-{-@ type Valid = {v:Bool | ( (Prop v) <=> true ) } @-}
+{-@ type Valid = {v:Bool | v } @-}
 
 {-@ mulAssoc :: Double -> Double -> Double -> Valid @-}
 mulAssoc :: Double -> Double -> Double -> Bool
diff --git a/tests/pos/RealProps1.hs b/tests/pos/RealProps1.hs
--- a/tests/pos/RealProps1.hs
+++ b/tests/pos/RealProps1.hs
@@ -3,7 +3,7 @@
 
 module Div where
 
-{-@ type Valid = {v:Bool | ( (Prop v) <=> true ) } @-}
+{-@ type Valid = {v:Bool | v } @-}
 
 {-@ mulAssoc :: (Eq a, Fractional a) => a -> a -> a -> Valid @-}
 mulAssoc :: (Eq a, Fractional a) => a -> a -> a -> Bool
diff --git a/tests/pos/RecordSelectorError.hs b/tests/pos/RecordSelectorError.hs
--- a/tests/pos/RecordSelectorError.hs
+++ b/tests/pos/RecordSelectorError.hs
@@ -6,7 +6,7 @@
 data F a b = F {fx :: a, fy :: b} | G {fx :: a}
 {-@ data F a b = F {fx :: a, fy :: b} | G {fx :: a} @-}
 
-{-@ measure isF :: F a b -> Prop
+{-@ measure isF :: F a b -> Bool
     isF (F x y) = true
     isF (G x)   = false
   @-}
diff --git a/tests/pos/Reduction.hs b/tests/pos/Reduction.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Reduction.hs
@@ -0,0 +1,11 @@
+{-@ LIQUID "--higherorder"    @-}
+
+module Reductions where
+
+{-@ reduction :: forall<p :: a -> Bool -> Bool>. 
+                 f:(a -> a) 
+              -> (x:a -> Bool<p x>) 
+              -> y:a -> Bool<p (f y)>  @-}
+reduction :: (a -> a) -> (a -> Bool) -> a -> Bool
+reduction f thm y = thm (f y)              
+
diff --git a/tests/pos/RefinedADTs.hs b/tests/pos/RefinedADTs.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/RefinedADTs.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE GADTs #-}
+
+{-@ LIQUID "--no-termination" @-}
+
+{-@ data List a where
+    Nil  :: List a 
+  | Cons :: listHead:a -> listTail:List a -> List a  
+@-}
+
+{-@ data List1 a b where
+    Nil1  :: List1 a b  
+  | Cons1 :: listHead:a -> listTail:List a -> List1 a b
+@-}
+
+{-@ data List2 a b <p :: a -> Bool> where
+    Nil2  :: List2 a 
+  | Cons2 :: listHead:a -> listTail:List a -> List2 a b
+@-}
+
+
+data List a where
+  Nil  :: List a
+  Cons :: a -> List a -> List a
+
+
+data List1 a b where
+  Nil1  :: List1 a b
+  Cons1 :: a -> List a -> List1 a b
+
+data List2 a b where
+  Nil2  :: List2 a b
+  Cons2 :: a -> List a -> List2 a b
+
+
+test :: List a -> Int 
+test Nil = 1 
+test (Cons x xs) = 1 + test xs 
diff --git a/tests/pos/ReflectBolleanFunctions.hs b/tests/pos/ReflectBolleanFunctions.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectBolleanFunctions.hs
@@ -0,0 +1,9 @@
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exactdc" @-}
+{-@ LIQUID "--higherorder"        @-}
+module Data.Foo where
+
+
+{-@ reflect foo @-}
+foo :: (Int -> Bool) -> (Int -> Bool) -> Bool 
+foo f g = (f 1) && (g 1)
diff --git a/tests/pos/ReflectClient0.hs b/tests/pos/ReflectClient0.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectClient0.hs
@@ -0,0 +1,11 @@
+module ReflectClient0 where
+
+import ReflectLib0
+
+
+-- the below works with GreaterThanA instead of GreaterThan,
+-- as the former is defined as a "predicate" alias.
+
+{-@ incr :: x:Nat -> {v:Nat | gtThan v x} @-}
+incr :: Int -> Int
+incr x = x + 1
diff --git a/tests/pos/ReflectClient1.hs b/tests/pos/ReflectClient1.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectClient1.hs
@@ -0,0 +1,9 @@
+{-@ LIQUID "--totality" @-}
+
+module ReflectClient0 where
+
+import ReflectLib1
+
+{-@ myHead :: {v:[a] | not (isNull v) } -> a @-}
+myHead :: [a] -> a
+myHead (x:_) = x
diff --git a/tests/pos/ReflectClient2.hs b/tests/pos/ReflectClient2.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectClient2.hs
@@ -0,0 +1,6 @@
+module ReflectClient2 where
+
+import ReflectLib2
+
+{-@ proof :: a -> { v: Int | incr 5 == 6 } @-}
+proof _ = incr 5
diff --git a/tests/pos/ReflectClient3.hs b/tests/pos/ReflectClient3.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectClient3.hs
@@ -0,0 +1,24 @@
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectClient3 where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+import ReflectLib3
+
+-- THIS IS NEEDED TO BRING THE NAMES INTO SCOPE FOR GHC ...
+forceImports = [ undefined next
+               , undefined lDay
+               ]
+
+-- THIS WORKS
+{-@ test2 :: { next Mon == Tue } @-}
+test2 = next Mon ==. Tue *** QED
+
+-- THIS DOES NOT WORK, but it DOES work if we remove the 
+-- type parameter from `List`. However it DOES work if we 
+-- put this back into ReflectLib3.hs
+{-@ test4 :: { lDay Nil == Mon } @-}
+test4 = lDay Nil ==. Mon *** QED
diff --git a/tests/pos/ReflectClient4.hs b/tests/pos/ReflectClient4.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectClient4.hs
@@ -0,0 +1,64 @@
+
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectClient4 where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+import ReflectLib4
+
+-- THIS IS NEEDED TO BRING THE NAMES INTO SCOPE FOR GHC ...
+forceImports = [ ]
+
+{-@ test1 :: {v:List a | v = Nil} @-}
+test1 :: List a
+test1 = Nil
+
+
+{-@ test2 :: {v:Proof | llen (Cons 1 Nil) = 1} @-}
+test2 :: Proof
+test2 =  llen (Cons 1 Nil)
+      ==. 1 + llen Nil
+      ==. 1
+      *** QED
+
+{-@ test3 :: {v:Proof | llen (Cons 1 (Cons 2 Nil)) = 2} @-}
+test3 :: Proof
+test3 =  llen (Cons 1 (Cons 2 Nil))
+      ==. 1 + llen (Cons 2 Nil)
+      ==. 1 + 1 + llen Nil
+      *** QED
+
+{-@ zen :: xs:List a -> {v:Nat | v = llen xs} @-}
+zen :: List a -> Int
+zen Nil        = 0
+zen (Cons h t) = 1 + zen t
+
+{-@ test5 :: { app (Cons 1 Nil) (Cons 2 (Cons 3 Nil)) = Cons 1 (Cons 2 (Cons 3 Nil)) } @-}
+test5 =   app (Cons 1 Nil) (Cons 2 (Cons 3 Nil))
+      ==. Cons 1 (app Nil (Cons 2 (Cons 3 Nil)))
+      ==. Cons 1 (Cons 2 (Cons 3 Nil))
+      *** QED
+
+{-@ thmAppLen :: xs:List a -> ys:List a ->
+      { llen (app xs ys) == llen xs + llen ys}
+  @-}
+
+-- thmAppLen :: List a -> List a -> Proof
+
+thmAppLen Nil ys
+  =   llen (app Nil ys)
+  ==. llen ys
+  ==. llen Nil + llen ys
+  *** QED
+
+thmAppLen (Cons x xs) ys
+  =   llen (app (Cons x xs) ys)
+  ==. llen (Cons x (app xs ys))
+  ==. 1 + llen (app xs ys)
+      ? thmAppLen xs ys
+  ==. 1 + llen xs + llen ys
+  ==. llen (Cons x xs) + llen ys
+  *** QED
diff --git a/tests/pos/ReflectLib0.hs b/tests/pos/ReflectLib0.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectLib0.hs
@@ -0,0 +1,8 @@
+module ReflectLib0 where
+
+{-@ inline gtThan @-}
+gtThan :: Int -> Int -> Bool
+gtThan x y = x > y
+
+
+{-@ predicate GreaterThanA X Y = X > Y @-}
diff --git a/tests/pos/ReflectLib1.hs b/tests/pos/ReflectLib1.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectLib1.hs
@@ -0,0 +1,6 @@
+module ReflectLib1 where
+
+{-@ measure isNull @-}
+isNull :: [a] -> Bool
+isNull []     = True
+isNull (x:xs) = False
diff --git a/tests/pos/ReflectLib2.hs b/tests/pos/ReflectLib2.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectLib2.hs
@@ -0,0 +1,28 @@
+{-@ LIQUID "--higherorder" @-}
+
+module ReflectLib2 where
+
+{-@ reflect incr @-}
+incr :: Int -> Int
+incr x = x + 1
+
+{-@ reflect incr2 @-}
+incr2 :: Int -> Int -> Int
+incr2 x y = x + y
+
+{-@ reflect plus @-}
+plus :: Int -> Int
+plus x = apply incr x
+
+{-@ reflect apply @-}
+apply :: (a -> b) -> a -> b
+apply f x = f x
+
+{-@ reflect toNat @-}
+toNat :: Int -> Int
+{-@ toNat :: Nat -> Nat @-}
+toNat n = if n == 0 then 0 else (1 + toNat (n - 1))
+
+
+{-@ myproof :: a -> { v: Int | incr 5 == 6 } @-}
+myproof _ = incr 5
diff --git a/tests/pos/ReflectLib3.hs b/tests/pos/ReflectLib3.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectLib3.hs
@@ -0,0 +1,27 @@
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectLib3 where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+-- | Days ---------------------------------------------------------------------
+
+{-@ data Day = Mon | Tue @-}
+data Day = Mon | Tue
+
+{-@ reflect next @-}
+next :: Day -> Day
+next Mon = Tue
+next Tue = Mon
+
+-- | Lists ---------------------------------------------------------------------
+
+{-@ data List  a = Nil | Cons {lHd :: a} @-}
+data List a = Nil | Cons a
+
+{-@ reflect lDay @-}
+lDay :: List a -> Day
+lDay Nil      = Mon
+lDay (Cons x) = Tue
diff --git a/tests/pos/ReflectLib4.hs b/tests/pos/ReflectLib4.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/ReflectLib4.hs
@@ -0,0 +1,32 @@
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectLib4 where
+
+-- | Lists ---------------------------------------------------------------------
+
+{-@ data List [llen] a = Nil | Cons {lHd :: a, lTl :: List a} @-}
+data List a = Nil | Cons a (List a)
+
+{-@ measure llen @-}
+{-@ llen :: List a -> Nat @-}
+llen :: List a -> Int
+llen Nil        = 0
+llen (Cons h t) = 1 + llen t
+
+-- TODO: make this work WITHOUT the invariant
+{-@ invariant {v:List a | 0 <= llen v} @-}
+
+{-@ reflect app @-}
+app :: List a -> List a -> List a
+app Nil         ys = ys
+app (Cons x xs) ys = Cons x (app xs ys)
+
+{-@ reflect gapp @-}
+gapp :: List a -> List a
+gapp Nil         = Nil
+gapp (Cons x xs) = Nil
+
+{-@ test4 :: { gapp Nil = Nil } @-}
+test4 = ()
diff --git a/tests/pos/RelativeComplete.hs b/tests/pos/RelativeComplete.hs
--- a/tests/pos/RelativeComplete.hs
+++ b/tests/pos/RelativeComplete.hs
@@ -12,7 +12,7 @@
 check = undefined
 
 
-{-@ app :: forall <p :: Int -> Prop, q :: Int -> Prop>. 
+{-@ app :: forall <p :: Int -> Bool, q :: Int -> Bool>. 
            {Int<q> <: Int<p>}
            {x::Int<q> |- {v:Int| v = x + 1} <: Int<q>}
            (Int<p> -> ()) -> x:Int<q> -> () @-}
diff --git a/tests/pos/Repeat.hs b/tests/pos/Repeat.hs
--- a/tests/pos/Repeat.hs
+++ b/tests/pos/Repeat.hs
@@ -4,20 +4,20 @@
 data L a = N | C a (L a)
 
 {-@
-data L a <p :: (L a) -> Prop>
+data L a <p :: (L a) -> Bool>
   = N
   | C (x::a) (xs::L <p> a <<p>>)
 @-}
 
 {-@
-measure isCons :: L a -> Prop
+measure isCons :: L a -> Bool
 isCons (N)     = false
 isCons (C a l) = true
 @-}
 
 {-@ type Stream a = {v: L <{\v -> (isCons v)}> a | (isCons v)} @-}
 
-{-@ Lazy repeat @-}
+{-@ lazy repeat @-}
 {-@ repeat :: a -> Stream a @-}
 repeat :: a -> L a
 repeat x = C x (repeat x)
diff --git a/tests/pos/Resolve.hs b/tests/pos/Resolve.hs
--- a/tests/pos/Resolve.hs
+++ b/tests/pos/Resolve.hs
@@ -6,3 +6,6 @@
 
 {-@ x :: {v:RB.Bar | ((v = RB.B) && (NotA v))} @-}
 x = RB.B
+
+zebra :: Int
+zebra = 12 
diff --git a/tests/pos/ResolveA.hs b/tests/pos/ResolveA.hs
--- a/tests/pos/ResolveA.hs
+++ b/tests/pos/ResolveA.hs
@@ -12,7 +12,7 @@
 
 {-@ qualif NotA(v:RB.Bar): (notA v) @-}
 
-{-@ measure notA :: RB.Bar -> Prop
+{-@ measure notA :: RB.Bar -> Bool
     notA (RB.A) = false
     notA (RB.B) = true
     notA (RB.C) = false
diff --git a/tests/pos/ResolvePred.hs b/tests/pos/ResolvePred.hs
--- a/tests/pos/ResolvePred.hs
+++ b/tests/pos/ResolvePred.hs
@@ -1,3 +1,5 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module ResolvePred (myFold) where
 
 {-@ data L [llen] = C (h :: Int) (t :: L) | N @-}
@@ -5,7 +7,7 @@
 
 data L = C Int L | N
 
-{-@ myFold :: forall <q :: L -> b -> Prop>.
+{-@ myFold :: forall <q :: L -> b -> Bool>.
               (as:L -> a:Int -> b<q as> -> b<q (C a as)>)
            -> b<q N>
            -> l:L
diff --git a/tests/pos/SafePartialFunctions.hs b/tests/pos/SafePartialFunctions.hs
--- a/tests/pos/SafePartialFunctions.hs
+++ b/tests/pos/SafePartialFunctions.hs
@@ -1,27 +1,30 @@
-module SafePartialFunctions (gotail, gohead) where
 
 {-@ LIQUID "--totality" @-}
+
+module SafePartialFunctions (gotail, gohead) where
+
 import Prelude hiding (fromJust, tail, head)
 
-{-@ fromJust :: {v:Maybe a | (isJust v)} -> a @-}
+import Data.Maybe
+
+{-@ fromJust :: {v:Maybe a | isJust v} -> a @-}
 fromJust :: Maybe a -> a
 fromJust (Just a) = a
 
-{-@ tail :: {v:[a] | ((len v) > 0)}-> [a] @-}
+{-@ tail :: {v:[a] | len v > 0} -> [a] @-}
 tail :: [a] -> [a]
 tail (x:xs) = xs
 
-{-@ head :: {v:[a] | ((len v) > 0)}-> a @-}
+{-@ head :: {v:[a] | len v > 0}-> a @-}
 head :: [a] -> a
 head (x:xs) = x
 
-
 -- USERS
 
 gotail xs = case xs of
              [] -> []
              y : ys -> tail xs
 
-{-@ gohead :: [{v:[a] | ((len v) > 0)}] -> [a] @-}
+{-@ gohead :: [{v:[a] | len v > 0}] -> [a] @-}
 gohead :: [[a]] -> [a]
-gohead xs = map head xs 
+gohead xs = map head xs
diff --git a/tests/pos/SimplifyTup00.hs b/tests/pos/SimplifyTup00.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/SimplifyTup00.hs
@@ -0,0 +1,31 @@
+
+-- See: https://github.com/ucsd-progsys/liquidhaskell/pull/752
+
+module FOO (mkSessData) where
+
+mkSessData :: TcpEndPoint -> Bool
+mkSessData = isSrcTCP
+
+{- With the safeSimplifyPatTuple rewrite rule,
+   the body of the below expression become a
+   case with type (Port, Port) because the
+   case is becoming the outer-most
+   body expression
+-}
+
+isSrcTCP :: TcpEndPoint -> Bool
+isSrcTCP x = (addrTE x, portTE x) == (srcIP, srcPort)
+ where
+   (PP (PortId srcIP _) (PortId srcPort _)) = idTCP x
+
+
+data TCPId = PP PortId PortId
+data PortId = PortId Port Port
+
+data TcpEndPoint = TcpEndPoint { addrTE :: Port, portTE :: Port }
+
+
+data Port = P deriving (Eq)
+
+idTCP :: TcpEndPoint -> TCPId --  (PortId, PortId)
+idTCP tcp = undefined
diff --git a/tests/pos/Solver.hs b/tests/pos/Solver.hs
--- a/tests/pos/Solver.hs
+++ b/tests/pos/Solver.hs
@@ -1,3 +1,5 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module MultiParams where
 
 {-@ LIQUID "--no-termination" @-}
@@ -33,7 +35,7 @@
 
 {-@ bound witness @-}
 
-{-@ find :: forall <p :: a -> Prop, w :: a -> Bool -> Prop>. 
+{-@ find :: forall <p :: a -> Bool, w :: a -> Bool -> Bool>. 
             (Witness a p w) => 
             (x:a -> Bool<w x>) -> [a] -> Maybe (a<p>) @-}
 find :: (a -> Bool) -> [a] -> Maybe a
diff --git a/tests/pos/StackClass.hs b/tests/pos/StackClass.hs
--- a/tests/pos/StackClass.hs
+++ b/tests/pos/StackClass.hs
@@ -1,3 +1,5 @@
+{-@ LIQUID "--pruneunsorted" @-}
+
 module SClass where
 
 import qualified Data.Set
diff --git a/tests/pos/StackMachine.hs b/tests/pos/StackMachine.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/StackMachine.hs
@@ -0,0 +1,120 @@
+{-@ LIQUID "--totality"       @-}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--prune-unsorted" @-}
+
+-- From: https://github.com/jstolarek/sandbox/blob/master/agda/agda-curious
+
+module StackMachine where
+
+import Prelude hiding (max)
+
+type Val   = Int
+data Expr  = EVal Val | EAdd Expr Expr
+data Instr = Push Val | Add
+
+eval :: Expr -> Val
+eval (EVal v)     = v
+eval (EAdd e1 e2) = eval e1 + eval e2
+
+compile :: Expr -> [Instr]
+compile (EVal v)     = [Push v]
+compile (EAdd e1 e2) = compile e1 ++ compile e2 ++ [Add]
+
+{-@ run :: is:[Instr] -> {v:[Val] | len v >= needs is} -> [Val] @-}
+run :: [Instr] -> [Val] -> [Val]
+run (Add    : is) (v1:v2:vs) = run is ((v1 + v2) : vs)
+run (Push v : is) vs         = run is (    v     : vs)
+run []            vs         = vs
+run (Add    : _ ) _          = die "impossible"
+
+{-@ die :: {v:String | false} -> a @-}
+die :: String -> a
+die = error
+
+{-@ measure needs @-}
+needs :: [Instr] -> Int
+needs (i:is) = max (pops i) ((needs is) - (pushes i))
+needs []     = 0
+
+{-@ measure pops @-}
+pops :: Instr -> Int
+pops Add      = 2
+pops (Push _) = 0
+
+{-@ measure pushes @-}
+pushes :: Instr -> Int
+pushes Add      = (-1)
+pushes (Push _) = 1
+
+{-@ inline max @-}
+max :: Int -> Int -> Int
+max x y = if x > y then x else y
+
+{-
+
+Some intuition / examples about `need`
+
+needs []
+  = 0
+needs [Add]
+  = max 2 (0 + 1)
+  = 2
+needs [Add, Add]
+  = max 2 (2 + 1)
+  = 3
+needs [Add, Add, Add]
+  = max 2 (3 + 1)
+  = 4
+
+
+needs [                              add ]
+  = 2
+
+needs [                      push 4, add ]
+  = max 0 (2 - 1)
+  = 1
+
+needs [                 add, push 4, add ]
+  = max 2 (1 + 1)
+  = 2
+
+needs [         push 3, add, push 4, add ]
+  = max 0 (2 - 1)
+  = 1
+
+needs [ push 2, push 3, add, push 4, add ]
+  = max 0 (1 - 1)
+  = 0
+
+-}
+
+{- THEOREMS TODO
+ 
+thm :: e:Expr -> { run (compile e) [] == [eval e] }
+thm e vs
+  = run (compile e) []
+ .= run (compile e ++ []) []  `by` append_right_nil (compile e)
+ .= run [] (eval e : [])      `by` lem e [] []
+ .= [eval e]
+ ** QED
+
+lem :: e:Expr -> is:[Instr] -> vs:[Val]
+      -> { run (compile e ++ is) vs == run is (eval e : vs) }
+
+lem (Val v) is vs
+  = run (compile (Val v) ++ is) vs
+ .= run ([Push v] ++ is) vs
+ .= run (Push v : is) vs       `eval` (++)
+ .= v : vs
+ ** QED
+
+lem (Add e1 e2) is vs
+  = run (compile (Add e1 e2) ++ is) vs
+ .= run (compile e1 ++ compile e2 ++ [Add] ++ is) vs
+ .= run (compile e2 ++ [Add] ++ is) (eval e1 : vs)  `by`   (lem ...)
+ .= run ([Add] ++ is) (eval e2 : eval e1 : vs)      `by`   (lem ...)
+ .= run (Add : is) (eval e2 : eval e1 : vs)         `eval` (++)
+ .= run is ((eval e1 + eval e1) : vs)
+ ** QED
+
+ -}
diff --git a/tests/pos/State.hquals b/tests/pos/State.hquals
--- a/tests/pos/State.hquals
+++ b/tests/pos/State.hquals
@@ -1,10 +1,10 @@
 
 qualif Snd( v : b_t, 
-            p : FAppTy (FAppTy Pred  b_t)  a, 
-            a : FAppTy (FAppTy fix##40##41#  a)  b): 
+            p : Pred  b_t  a, 
+            a : fix##40##41#  a  b): 
           (papp2 p v (fst a))
 
 qualif Fst( v : a, 
-            a : FAppTy (FAppTy fix##40##41#  a)  b): 
+            a : fix##40##41#  a  b): 
            (v = fst a) 
 
diff --git a/tests/pos/State.hs b/tests/pos/State.hs
--- a/tests/pos/State.hs
+++ b/tests/pos/State.hs
@@ -7,11 +7,11 @@
 import Prelude hiding (snd, fst)
 
 data ST a s = S (s -> (a, s))
-{-@ data ST a s <pre :: s -> Prop, post :: a -> s -> Prop> 
+{-@ data ST a s <pre :: s -> Bool, post :: a -> s -> Bool> 
        = S (ys::(x:s<pre> -> ((a, s)<post>)))
   @-}
 
-{-@ returnST :: forall <pre :: s -> Prop, post :: a -> s -> Prop>.
+{-@ returnST :: forall <pre :: s -> Bool, post :: a -> s -> Bool>.
                xState:a 
            -> ST <{v:s<post xState>| true}, post> a s
   @-}
@@ -19,7 +19,7 @@
 returnST x = S $ \s -> (x, s)
 
 
-{-@ bindST :: forall <pbind :: s -> Prop, qbind :: a -> s -> Prop, rbind :: b -> s -> Prop>.
+{-@ bindST :: forall <pbind :: s -> Bool, qbind :: a -> s -> Bool, rbind :: b -> s -> Bool>.
             ST <pbind, qbind> a s 
          -> (xbind:a -> ST <{v:s<qbind xbind> | true}, rbind> b s) 
          -> ST <pbind, rbind> b s
@@ -27,7 +27,7 @@
 bindST :: ST a s -> (a -> ST b s) -> ST b s
 bindST (S m) k = S $ \s -> let (a, s') = m s in apply (k a) s'
 
-{-@ apply :: forall <p :: s -> Prop, q :: a -> s -> Prop>.
+{-@ apply :: forall <p :: s -> Bool, q :: a -> s -> Bool>.
              ST <p, q> a s -> s<p> -> (a, s)<q>
   @-}
 apply :: ST a s -> s -> (a, s)
diff --git a/tests/pos/StateConstraints.hs b/tests/pos/StateConstraints.hs
--- a/tests/pos/StateConstraints.hs
+++ b/tests/pos/StateConstraints.hs
@@ -5,20 +5,20 @@
 
 data ST s a = ST {runState :: s -> (a,s)}
 
-{-@ data ST s a <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop> 
+{-@ data ST s a <p :: s -> Bool, q :: s -> s -> Bool, r :: s -> a -> Bool> 
   = ST (runState :: x:s<p> -> (a<r x>, s<q x>)) @-}
 
- {-@ runState :: forall <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop>. ST <p, q, r> s a -> x:s<p> -> (a<r x>, s<q x>) @-}
+ {-@ runState :: forall <p :: s -> Bool, q :: s -> s -> Bool, r :: s -> a -> Bool>. ST <p, q, r> s a -> x:s<p> -> (a<r x>, s<q x>) @-}
 
 
 
 {-
-cmp :: forall < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              , rg   :: s -> a -> Prop
-              , rf   :: s -> b -> Prop
-              , r    :: s -> b -> Prop
+cmp :: forall < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              , rg   :: s -> a -> Bool
+              , rf   :: s -> b -> Bool
+              , r    :: s -> b -> Bool
               >. 
        {xx::s<pre>, w::s<postg xx> |- s<postf w> <: s<post xx>}
        {ww::s<pre> |- s<postg ww> <: s<pref>}
@@ -34,13 +34,13 @@
 cmp (ST g) (ST f) = ST (\x -> case g x of {(_, s) -> f s})    
 
 {-@ 
-bind :: forall < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              , rg   :: s -> a -> Prop
-              , rf   :: s -> b -> Prop
-              , r    :: s -> b -> Prop
-              , pref0 :: a -> Prop 
+bind :: forall < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              , rg   :: s -> a -> Bool
+              , rf   :: s -> b -> Bool
+              , r    :: s -> b -> Bool
+              , pref0 :: a -> Bool 
               >. 
        {x::s<pre> |- a<rg x> <: a<pref0>}      
        {x::s<pre>, y::s<postg x> |- b<rf y> <: b<r x>}
diff --git a/tests/pos/StateConstraints0.hs b/tests/pos/StateConstraints0.hs
--- a/tests/pos/StateConstraints0.hs
+++ b/tests/pos/StateConstraints0.hs
@@ -12,10 +12,10 @@
 
 data ST s a = ST {runState :: s -> (a,s)}
 
-{-@ data ST s a <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop> 
+{-@ data ST s a <p :: s -> Bool, q :: s -> s -> Bool, r :: s -> a -> Bool> 
   = ST (runState :: x:s<p> -> (a<r x>, s<q x>)) @-}
 
-{-@ runState :: forall <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop>. ST <p, q, r> s a -> x:s<p> -> (a<r x>, s<q x>) @-}
+{-@ runState :: forall <p :: s -> Bool, q :: s -> s -> Bool, r :: s -> a -> Bool>. ST <p, q, r> s a -> x:s<p> -> (a<r x>, s<q x>) @-}
 
 
 class Monad m where
@@ -26,14 +26,14 @@
 
 instance Monad (ST s) where
   {-@ instance Monad ST s where
-    return :: forall s a <p :: s -> Prop >. x:a -> ST <p, {\s v -> v == s}, {\s v -> x == v}> s a;
-    >>= :: forall s a b  < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              , rg   :: s -> a -> Prop
-              , rf   :: s -> b -> Prop
-              , r    :: s -> b -> Prop
-              , pref0 :: a -> Prop 
+    return :: forall s a <p :: s -> Bool >. x:a -> ST <p, {\s v -> v == s}, {\s v -> x == v}> s a;
+    >>= :: forall s a b  < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              , rg   :: s -> a -> Bool
+              , rf   :: s -> b -> Bool
+              , r    :: s -> b -> Bool
+              , pref0 :: a -> Bool 
               >. 
        {x::s<pre> |- a<rg x> <: a<pref0>}      
        {x::s<pre>, y::s<postg x> |- b<rf y> <: b<r x>}
@@ -42,12 +42,12 @@
        (ST <pre, postg, rg> s a)
     -> (a<pref0> -> ST <pref, postf, rf> s b)
     -> (ST <pre, post, r> s b) ;
-    >>  :: forall s a b  < pref :: s -> Prop, postf :: s -> s -> Prop
-              , pre  :: s -> Prop, postg :: s -> s -> Prop
-              , post :: s -> s -> Prop
-              , rg   :: s -> a -> Prop
-              , rf   :: s -> b -> Prop
-              , r    :: s -> b -> Prop
+    >>  :: forall s a b  < pref :: s -> Bool, postf :: s -> s -> Bool
+              , pre  :: s -> Bool, postg :: s -> s -> Bool
+              , post :: s -> s -> Bool
+              , rg   :: s -> a -> Bool
+              , rf   :: s -> b -> Bool
+              , r    :: s -> b -> Bool
               >. 
        {x::s<pre>, y::s<postg x> |- b<rf y> <: b<r x>}
        {xx::s<pre>, w::s<postg xx> |- s<postf w> <: s<post xx>}
diff --git a/tests/pos/StateConstraints00.hs b/tests/pos/StateConstraints00.hs
--- a/tests/pos/StateConstraints00.hs
+++ b/tests/pos/StateConstraints00.hs
@@ -8,10 +8,10 @@
 
 data ST s a = ST {runState :: s -> (a,s)}
 
-{-@ data ST s a <r :: a -> Prop> 
+{-@ data ST s a <r :: a -> Bool> 
   = ST (runState :: x:s -> (a<r>, s)) @-}
 
-{-@ runState :: forall <r :: a -> Prop>. ST <r> s a -> x:s -> (a<r>, s) @-}
+{-@ runState :: forall <r :: a -> Bool>. ST <r> s a -> x:s -> (a<r>, s) @-}
 
 
 class Foo m where
diff --git a/tests/pos/StateF00.hs b/tests/pos/StateF00.hs
--- a/tests/pos/StateF00.hs
+++ b/tests/pos/StateF00.hs
@@ -7,7 +7,7 @@
 import Prelude hiding (snd, fst)
 
 data ST a s = S (s -> (a, s))
-{-@ data ST a s <post :: s -> a -> s -> Prop> 
+{-@ data ST a s <post :: s -> a -> s -> Bool> 
        = S (ys::(x:s -> ((a, s)<\xx -> {v:s<post x xx> | true} > )))
   @-}
 
diff --git a/tests/pos/StrictPair1.hs b/tests/pos/StrictPair1.hs
--- a/tests/pos/StrictPair1.hs
+++ b/tests/pos/StrictPair1.hs
@@ -16,7 +16,7 @@
 --   this program is marked as SAFE...
 data PairS a b = !a :*: !b deriving (Eq,Ord,Show)
 
-{-@ data PairS a b <p :: x0:a -> b -> Prop> = (:*:) (x::a) (y::b<p x>)  @-}
+{-@ data PairS a b <p :: x0:a -> b -> Bool> = (:*:) (x::a) (y::b<p x>)  @-}
 
 {-@ measure psnd :: (PairS a b) -> b 
     psnd ((:*:) x y) = y 
diff --git a/tests/pos/Strings.hs b/tests/pos/Strings.hs
--- a/tests/pos/Strings.hs
+++ b/tests/pos/Strings.hs
@@ -2,36 +2,9 @@
 
 import GHC.CString  -- This import interprets Strings as constants!
 
-
 import Data.Set
-{-
-bar :: () -> String 
-{- bar :: () -> {x:String | x = unpack "foo" && len x >= 0} @-}
-bar _ = "foo"
 
-
-{- prop :: {v:Bool | Prop v <=> true} @-}
-prop :: Bool
-prop = foo1 == foo2 
-  where foo1 = "foo"
-        foo2 = "foo"
--}
-
-
-data Foo = FFFF | QQQQ deriving Eq
-
-{-@ prop2 :: {v:Bool | Prop v <=> true} @-}
-prop2 :: Bool
-prop2 = foo1 /= foo2 
-  where foo1 = FFFF
-        foo2 = QQQQ
-
-
-{-@ prop3 :: {v:[String] | listElts v ~~ Set_sng "xx"} @-}
-prop3 :: [String]
-prop3 = ["xx"]
-
-{-@ prop1 :: {v:Bool | Prop v <=> true} @-}
+{-@ prop1 :: {v:Bool | v } @-}
 prop1 :: Bool
 prop1 = foo1 /= foo2 
   where foo1 = "foo"
diff --git a/tests/pos/Sum.hs b/tests/pos/Sum.hs
--- a/tests/pos/Sum.hs
+++ b/tests/pos/Sum.hs
@@ -1,6 +1,6 @@
 module Sum where
 
-{-@ ssum :: forall<p :: a -> Prop, q :: a -> Prop>. 
+{-@ ssum :: forall<p :: a -> Bool, q :: a -> Bool>. 
             {{v:a | v == 0} <: a<q>}
             {x::a<p> |- {v:a | x <= v} <: a<q>}
             xs:[{v:a<p> | 0 <= v}] -> {v:a<q> | len xs >= 0 && 0 <= v } @-}
diff --git a/tests/pos/T595.hs b/tests/pos/T595.hs
--- a/tests/pos/T595.hs
+++ b/tests/pos/T595.hs
@@ -12,7 +12,7 @@
 {-@
 data Test = Test
     { vec  :: Thing
-    , x0   :: { x0 : Bool | len vec < 1 ==> Prop x0 }
+    , x0   :: { x0 : Bool | ((len vec) < 1) ==> x0 }
     }
 @-}
 
@@ -20,7 +20,7 @@
 -- for the record selectors
 
 {- vec :: x:Test -> {v:Thing | v = vec x} -}
-{- x0  :: x:Test -> {v:Bool  | v = x0 x  && ((len (vec x) < 1) => Prop v) } -}
+{- x0  :: x:Test -> {v:Bool  | v = x0 x  && ((len (vec x) < 1) => v) } -}
 
 example :: Test -> ()
 example t =
diff --git a/tests/pos/T675.hs b/tests/pos/T675.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/T675.hs
@@ -0,0 +1,22 @@
+import Data.ByteString
+import Data.ByteString.Unsafe
+
+{-@ assume unsafeTake :: n : Int -> ibs : { ibs : ByteString | bslen ibs >= n } -> { obs : ByteString | bslen obs == n } @-}
+{-@ assume unsafeDrop :: n : Int -> ibs : { ibs : ByteString | bslen ibs >= n } -> { obs : ByteString | bslen obs == bslen ibs - n } @-}
+
+
+{-@ extract :: ibs : { ibs : ByteString | bslen ibs >= 100 } -> { obs : ByteString | bslen obs == 4 } @-}
+extract :: ByteString -> ByteString
+extract = unsafeTake 4 . unsafeDrop 96
+
+{-@ extractETA :: ibs : { ibs : ByteString | bslen ibs >= 100 } -> { obs : ByteString | bslen obs == 4 } @-}
+extractETA :: ByteString -> ByteString
+extractETA ibs = unsafeTake 4 (unsafeDrop 96 ibs)
+
+{-@ ok :: x:Int -> {v:Int | v == x + 3} @-}
+ok :: Int -> Int
+ok x = 2 + (1 + x)
+
+{-@ bad :: x:Int -> {v:Int | v == x + 3} @-}
+bad :: Int -> Int
+bad = (2 +) . (1 +)
diff --git a/tests/pos/T716.hs b/tests/pos/T716.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/T716.hs
@@ -0,0 +1,34 @@
+
+-- | See https://github.com/ucsd-progsys/liquidhaskell/issues/716
+--   due to the wierd case-of thwarting ANF, you need the qualifier from the
+--   output type of `narrow16Word` (apparently we don't scrape assumes?) 
+--   ELIMINATE does not cut it, as the relevant kvar happens to be non-linear...
+
+{-@ LIQUID "--scrape-used-imports" @-}
+
+module Blank where
+
+import GHC.Exts
+import GHC.Prim
+import GHC.Word
+
+-- denotes the offset at which bits are no longer guaranteed to be defined
+
+{-@ measure undefinedOffset :: Word# -> Int @-}
+
+{-@ assume byteSwap16# :: Word# -> {v:Word# | undefinedOffset v = 16} @-}
+
+-- We need either the below qualifier, or the one from the refinement of
+-- `Word`.Why are NEITHER generated automatically?
+
+{-@ assume narrow16Word# :: Word# -> {v:Word# | undefinedOffset v = 64} @-}
+
+{-@ data Word = W# (w :: {v:Word# | undefinedOffset v >= 64}) @-}
+
+grabWord16_SAFE (Ptr ip#) = let x = byteSwap16# (indexWord16OffAddr# ip# 0#) in W# (narrow16Word# x)
+
+grabWord16_UNSAFE (Ptr ip#) = W# (narrow16Word# (byteSwap16# (indexWord16OffAddr# ip# 0#)))
+
+-- mkWord :: {v:Word# | undefinedOffset v >= 64} -> Word
+-- mkWord = W#
+
diff --git a/tests/pos/T819.hs b/tests/pos/T819.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/T819.hs
@@ -0,0 +1,35 @@
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--higherorder"        @-}
+{-@ LIQUID "--exactdc" @-}
+module Data.Foo where
+
+
+import Language.Haskell.Liquid.ProofCombinators
+
+
+data L a = N 
+{-@ infixl 9 <> @-}
+
+
+{-@ foo :: xs:L a -> {xs <> N == N } @-}
+foo :: L a -> Proof
+foo N = N <> N ==. N *** QED 
+
+
+{-@ reflect <> @-}
+(<>) :: L a -> L a -> L a 
+N <> N = N 
+
+
+{-@ infixl 9 +++ @-}
+{-@ data N = Zero | Succ {next :: N} @-}
+data N = Zero | Succ N 
+
+{-@ reflect +++ @-}
+(+++) :: N -> N -> N
+n +++ m = n
+
+{-@ lemma :: { v:() | Zero +++ Zero == Zero } @-}
+lemma :: ()
+lemma = Zero +++ Zero ==. Zero *** QED
+
diff --git a/tests/pos/T819A.hs b/tests/pos/T819A.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/T819A.hs
@@ -0,0 +1,42 @@
+import Language.Haskell.Liquid.ProofCombinators 
+
+import Prelude hiding ((++))
+
+{-@ LIQUID "--exactdc" @-}
+{-@ data List [llen] a = Emp | C {hd :: a, tl :: (List a)} @-}
+data List a = Emp | C a  (List a)  deriving (Eq)
+
+llen :: List a -> Int 
+{-@ llen :: List a -> Nat @-}
+{-@ measure llen @-}
+llen Emp = 0 
+llen (C _ xs) = 1 + llen xs
+
+
+{-@ infixr ++ @-}
+
+{-@ reflect ++ @-}
+Emp ++        ys = ys
+(x `C` xs) ++ ys = x `C` (xs ++ ys)
+
+{-@ inline assocThm @-}
+assocThm xs ys zs
+  = (xs ++ ys) ++ zs == xs ++ (ys ++ zs)
+
+{-@ assocPf :: xs:_ -> ys:_ -> zs:_ -> { assocThm xs ys zs } @-}
+assocPf :: Eq a => List a -> List a -> List a -> Proof 
+
+assocPf Emp ys zs
+  =   (Emp ++ ys) ++ zs
+  ==. ys ++ zs
+  ==. Emp ++ (ys ++ zs)
+  *** QED
+assocPf (x `C` xs) ys zs
+  =   ((x `C` xs) ++ ys) ++ zs
+  ==. (x `C` (xs ++ ys)) ++ zs
+  ==. x `C` ( (xs ++ ys) ++ zs)
+  ==. x `C` (xs ++ (ys ++ zs)) ? assocPf xs ys zs
+  ==. (x `C` xs) ++ (ys ++ zs)
+  *** QED
+
+  
diff --git a/tests/pos/T820.hs b/tests/pos/T820.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/T820.hs
@@ -0,0 +1,44 @@
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exactdc" @-}
+{-@ LIQUID "--higherorder"        @-}
+module Data.Foo where
+
+import Language.Haskell.Liquid.ProofCombinators 
+
+{-@ data Foo = Foo { foox :: (Int -> Int) , fooy :: Int } @-}
+data Foo = Foo { x :: Int -> Int , y :: Int }
+
+
+
+{-@ data VerifiedEq a = VerifiedEq {
+      eq :: a -> a -> Bool
+    , refl :: x:a -> { v:() | (eq x x) }
+    , sym :: x:a -> y:a -> { v:() | (eq x y) ==> (eq y x) }
+    , trans :: x:a -> y:a -> z:a -> { v:() | (eq x y) && (eq y z) ==> (eq x z) }
+    }
+@-}
+data VerifiedEq a = VerifiedEq {
+    eq :: a -> a -> Bool
+  , refl :: a -> Proof
+  , sym :: a -> a -> Proof
+  , trans :: a -> a -> a -> Proof
+  }
+
+{-@ data VerifiedOrd a = VerifiedOrd {
+      leq :: (a -> a -> Bool)
+    , total :: (x:a -> y:a -> { (leq x y) || (leq y x) })
+    , antisym :: (x:a -> y:a -> { (leq x y) || (leq y x) ==> x == y })
+    , trans2 :: (x:a -> y:a -> z:a -> { (leq x y) && (leq y z) ==> (leq x z) })
+    , verifiedEq :: VerifiedEq a
+    }
+@-}
+
+
+data VerifiedOrd a = VerifiedOrd {
+    leq :: a -> a -> Bool
+  , total :: a -> a -> Proof
+  , antisym :: a -> a -> Proof
+  , trans2 :: a -> a -> a -> Proof
+  , verifiedEq :: VerifiedEq a
+  }
+
diff --git a/tests/pos/T866.hs b/tests/pos/T866.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/T866.hs
@@ -0,0 +1,11 @@
+-- see https://github.com/ucsd-progsys/liquidhaskell/issues/866
+
+module T866 where 
+
+data Body = Body Int Int 
+
+genBody :: [Int] -> Body
+genBody s   = Body x y 
+  where 
+    (x:y:_) = s
+
diff --git a/tests/pos/T914.hs b/tests/pos/T914.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/T914.hs
@@ -0,0 +1,12 @@
+{-@ LIQUID "--higherorder"     @-}
+
+module MapFusion where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+{-@ inline compose @-}
+{-@ compose :: f:(b -> c) -> g:(a -> b) -> x:a -> c @-}
+compose :: (b -> c) -> (a -> b) -> a -> c
+compose f g x = f (g x)
+
+
diff --git a/tests/pos/TemplateHaskell.hs b/tests/pos/TemplateHaskell.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/TemplateHaskell.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module TemplateHaskell where
+
+import Language.Haskell.TH.Syntax
+
+foo = [| 1 + 2|]
+
+bar :: Q [Dec]
+bar = do
+  Just varName <- lookupValueName "hello"
+  return  [SigD varName $ ConT $ mkName "String"]
+
diff --git a/tests/pos/TemplateHaskellImp.hs b/tests/pos/TemplateHaskellImp.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/TemplateHaskellImp.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module TemplateHaskellImp where
+
+import TemplateHaskell
+
+hello = "World"
+bar
+
diff --git a/tests/pos/Termination.lhs b/tests/pos/Termination.lhs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Termination.lhs
@@ -0,0 +1,37 @@
+\begin{code}
+module Termination where
+import Prelude hiding (sum)
+type Value = Int
+
+type Vec = Int -> Value
+
+{-@ sum :: Vec -> Nat -> Value @-}
+sum :: Vec -> Int -> Value
+sum a 0 = a 0
+sum a i = a i + sum a (i-1)
+
+{-@ sum' :: Vec -> Value -> n:Nat -> Value / [n] @-}
+sum' :: Vec -> Value -> Int -> Value
+sum' a acc 0 = acc + a 0 
+sum' a acc i = sum' a (acc + a i) (i-1)
+
+type Vec2D = Int -> Int -> Value
+
+{-@ sum2D :: Vec2D -> Nat -> Nat -> Value @-}
+sum2D :: Vec2D -> Int -> Int -> Value
+sum2D a n m = go n m
+  where 
+    {-@ go :: i:Nat -> j:Nat -> Value / [i, j] @-}
+    go 0 0        = a 0 0
+    go i j 
+      | j == 0    =  a i 0 + go (i-1) m
+      | otherwise =  a i j + go i (j-1)
+
+{-@ sumFromTo :: Vec -> lo:Nat -> hi:{v:Nat|v>=lo} -> Value @-}
+sumFromTo :: Vec -> Int -> Int ->  Value
+sumFromTo a lo hi = go lo hi
+  where 
+       {-@ go :: lo:Nat -> hi:{v:Nat|v>=lo} -> Value / [hi-lo] @-}
+        go lo hi | lo == hi  =  a lo
+                 | otherwise =  a lo + go (lo+1) hi
+\end{code}
diff --git a/tests/pos/ToyMVar.hs b/tests/pos/ToyMVar.hs
--- a/tests/pos/ToyMVar.hs
+++ b/tests/pos/ToyMVar.hs
@@ -13,15 +13,15 @@
 data MVar a = MVar (MVar# RealWorld a)
 
 data IO a = IO (State# RealWorld -> (State# RealWorld, a))
-{-@ data IO a <p :: State# RealWorld -> Prop, q :: State# RealWorld-> a -> Prop>
+{-@ data IO a <p :: State# RealWorld -> Bool, q :: State# RealWorld-> a -> Bool>
       = IO (io :: (State# RealWorld)<p> -> ((State# RealWorld, a)<q>))
   @-}
 
-{-@ measure inState :: MVar a -> State# RealWorld -> Prop @-}
+{-@ measure inState :: MVar a -> State# RealWorld -> Bool @-}
 {-@ measure stateMVars :: State# RealWorld -> Set (MVar a) @-}
 
-{-@ newEmptyMVar  :: forall < p :: State# RealWorld -> Prop
-                            , q :: State# RealWorld -> (MVar a) -> Prop>. 
+{-@ newEmptyMVar  :: forall < p :: State# RealWorld -> Bool
+                            , q :: State# RealWorld -> (MVar a) -> Bool>. 
                      IO <p, {\x y -> (inState y x)}> (MVar a) @-}
 newEmptyMVar  :: IO (MVar a)
 newEmptyMVar = IO $ \ s# ->
@@ -43,8 +43,8 @@
 putMVar# :: MVar# s a -> a -> State# s -> State# s
 putMVar# = let x = x in x
 
-{-@ newMVar#  :: forall < p :: State# s -> Prop
-                            , q :: State# s -> (MVar# s a) -> Prop>. 
+{-@ newMVar#  :: forall < p :: State# s -> Bool
+                            , q :: State# s -> (MVar# s a) -> Bool>. 
                      (State# s)<p> -> 
                      ((State# s)<p>, (MVar# s a))<q> @-}
 
diff --git a/tests/pos/TypeFamilies.hs b/tests/pos/TypeFamilies.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/TypeFamilies.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module ProxyClass where
+
+import           Data.Proxy
+import           GHC.TypeLits (Nat)
+
+type ReadPtrN t  = ReadPtr (t 'Nothing)
+newtype ReadPtr a = ReadPtr Int 
+data EthernetHeaderBase m = EHB (m ?$ Bytes 6) 
+data ForeignPtr a  
+newtype Bytes (n :: Nat) = Bytes (ReadPtr Int)
+
+{-@ foo ::  ReadPtrN EthernetHeaderBase @-}
+foo ::  ReadPtrN EthernetHeaderBase
+foo = undefined 
+
+{-@
+data EthernetPacket = EthernetPacket
+  { headerEth     :: ReadPtrN EthernetHeaderBase
+  }
+@-}
+
+data EthernetPacket = EthernetPacket
+  { headerEth     :: ReadPtrN EthernetHeaderBase
+  }
+
+
+
+infixr 1 ?$
+
+type family (?$) (m :: Maybe (* -> *)) (x :: *) :: * where
+  'Just f ?$ x = f x
+  'Nothing ?$ x = x
diff --git a/tests/pos/UnboxedTuples.hs b/tests/pos/UnboxedTuples.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/UnboxedTuples.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+module Blank where
+
+import GHC.Int
+
+foo = let (# x, y #) = (# 1#, 1# #) in I8# x
+
diff --git a/tests/pos/UnboxedTuplesAndTH.hs b/tests/pos/UnboxedTuplesAndTH.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/UnboxedTuplesAndTH.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+module Blank where
+
+import GHC.Int
+
+foo = let (# x, y #) = (# 1#, 1# #) in I8# x
+
+bar = [| 1 + 2|]
+
diff --git a/tests/pos/Variance2.hs b/tests/pos/Variance2.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/Variance2.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE Rank2Types, ExistentialQuantification #-}
+
+
+module Variance where
+
+
+import Control.Monad.Trans.Except
+
+
+
+p1 :: Parser a 
+p1 = undefined 
+
+p2 :: Parser a -> ()
+p2 _ = () 
+
+p = p2 p1 
+
+
+-- The following structure is a simplification of 
+--  Options.Applicative.Parser 
+
+data Parser a
+  = OptP (Option a)
+
+data Option a = Option
+  { optMain :: OptReader a }
+
+
+
+data OptReader a
+ =  CmdReader (String -> Maybe (ParserInfo a)) -- ^ command reader
+
+
+data ParserInfo a = ParserInfo
+  { infoParser :: Parser a    -- ^ the option parser for the program                              -- after arguments (default: True)
+  }
diff --git a/tests/pos/VerifiedMonoid.hs b/tests/pos/VerifiedMonoid.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/VerifiedMonoid.hs
@@ -0,0 +1,92 @@
+module Data.Monoid where
+
+{-@ LIQUID "--higherorder" @-}
+{-@ LIQUID "--exactdc" @-}
+{-@ LIQUID "--totality" @-}
+
+import Prelude hiding (Monoid (..))
+
+import Language.Haskell.Liquid.ProofCombinators
+
+
+class VerifiedMonoid a where 
+  mempty  :: a 
+
+  mappend :: a -> a -> a 
+
+  leftId  :: a -> Proof 
+  rightId :: a -> Proof
+  assoc   :: a -> a -> a -> Proof 
+
+{-@ class VerifiedMonoid a where
+    mempty  :: a 
+    mappend :: a -> a -> a  
+    leftId  :: x:a -> {v:Proof | mappend mempty x = x }
+    rightId :: x:a -> {v:Proof | mappend x mempty = x }
+    assoc   :: x:a -> y:a -> z:a -> {v:Proof | mappend x (mappend y z) = mappend (mappend x y) z}
+  @-}
+
+-- TODO 
+-- The above should change to explicitely reflect mappend and mempty.
+-- Then, each instance should generate the code at the end of this file.
+
+
+{-@ data List a = N | C {hd :: a, tl :: List a} @-}
+data List a = N | C a (List a)
+
+
+
+instance VerifiedMonoid (List a) where
+  mempty              = N 
+  mappend N ys        = ys
+  mappend (C x xs) ys = C x (mappend xs ys)
+
+  leftId  x           = mappend mempty x ==. mappend N x ==. x *** QED 
+
+
+  rightId N           = mappend N mempty ==. mappend N N ==. N *** QED 
+  rightId (C x xs)    = mappend (C x xs) mempty ==. C x (mappend xs N ) ==. C x xs ? rightId xs *** QED 
+
+
+  assoc N ys zs 
+    =   mappend N (mappend ys zs)
+    ==. mappend ys zs 
+    ==. mappend (mappend N ys) zs 
+    *** QED 
+  assoc (C x xs) ys zs 
+    =   mappend (C x xs) (mappend ys zs)
+    ==. C x (mappend xs (mappend ys zs))
+    ==. C x (mappend (mappend xs ys) zs)
+        ? assoc xs ys zs 
+    ==. mappend (C x (mappend xs ys)) zs
+    ==. mappend (mappend (C x xs) ys) zs
+    *** QED 
+
+
+
+-- || Below specs should be automatically generated by the reflect annotations 
+-- || in the class definition 
+
+-- | 1. One uninterpreted function per class method so that proof obligations type check
+
+{-@ measure mappend :: a -> a -> a @-}
+{-@ measure mempty  :: a @-}
+
+-- | 2. One uninterpreted function is generated for each reflected function
+
+
+{-@ measure mappendList :: List a -> List a -> List a @-}
+{-@ measure memptyList  :: List a @-}
+
+
+-- | 3. The reflected methods are reflected in the result type as assumed types, 
+-- |    and the proof obligations are coppied to the proof methods. 
+
+{-@ instance VerifiedMonoid (List a) where 
+  assume mempty  :: {v:List a | (v = N) && (v = memptyList) };
+  assume mappend :: {v:(x:List a -> y:List a
+                 -> {v:List a | (v = mappendList x y) && (if (is_N x) then (v == y) else (v == C (select_C_1 x) (mappendList (select_C_2 x) y) )) })  | v == mappendList};
+  leftId  :: x:List a -> {v:Proof | mappendList memptyList x = x } ;
+  rightId :: x:List a -> {v:Proof | mappendList x memptyList = x } ;
+  assoc   :: x:List a -> y:List a -> z:List a -> {v:Proof | mappendList x (mappendList y z) = mappendList (mappendList x y) z}
+  @-}
diff --git a/tests/pos/VerifiedNum.hs b/tests/pos/VerifiedNum.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/VerifiedNum.hs
@@ -0,0 +1,28 @@
+module VerifiedNum where
+
+-- Hiding numeric operations, because they get by default translated to SMT equivalent
+import Prelude hiding (Num(..))
+
+import qualified Prelude as Prelude 
+
+class VerifiedNum a where 
+  (+) :: a -> a -> a 
+  (-) :: a -> a -> a 
+
+{-@ predicate BoundInt X = 0 < X + 10000 && X < 10000 @-}
+
+{-@ type OkInt N = {v:Int | BoundInt N => v == N} @-}
+
+{-@ type ValidInt = {v:Int | BoundInt v} @-}
+
+
+instance VerifiedNum Int where
+{-@ instance VerifiedNum Int where 
+    + :: x:Int -> y:Int -> OkInt {x + y} 
+  @-}
+	x + y = (Prelude.+) x y  
+{-@ instance VerifiedNum Int where 
+    - :: x:Int -> y:Int -> OkInt {x - y} 
+  @-}
+	x - y = (Prelude.-) x y  
+
diff --git a/tests/pos/WBL.hs b/tests/pos/WBL.hs
--- a/tests/pos/WBL.hs
+++ b/tests/pos/WBL.hs
@@ -29,7 +29,7 @@
                              , right :: Heap a
                              }
 
-{-@ data Heap a <q :: a -> a -> Prop> =
+{-@ data Heap a <q :: a -> a -> Bool> =
       Empty | Node { pri   :: a
                    , rnk   :: Nat
                    , left  :: {v: Heap<q> (a<q pri>) | ValidRank v}
@@ -41,7 +41,7 @@
 {-@ type PHeap a = {v:OHeap a | ValidRank v}                 @-}
 {-@ type OHeap a = Heap <{\root v -> root <= v}> a           @-}
 
-{-@ measure okRank        :: Heap a -> Prop
+{-@ measure okRank        :: Heap a -> Bool
     okRank (Empty)        = true
     okRank (Node p k l r) = ((realRank l >= realRank r) && k == (1 + (realRank l) + (realRank r)))
   @-}
@@ -51,8 +51,11 @@
     realRank (Node p k l r) = (1 + realRank l + realRank r)
   @-}
 
+
+{-@ invariant {v:Heap a | rank v == realRank (left v) + realRank (right v) && realRank v >= 0 } @-}  
+
 {-@ measure rank @-}
-{-@ rank :: h:PHeap a -> {v:Nat | v = realRank h} @-}
+{-@ assume rank :: h:Heap a -> {v:Nat | v = realRank h} @-}
 rank Empty          = 0
 rank (Node _ r _ _) = r
 
@@ -66,7 +69,7 @@
 --
 -- We use a two-pass implementation of merging algorithm. One pass,
 -- implemented by merge, performs merging in a top-down manner. Second
--- one, implemented by makeT, ensures that rank invariant of weight
+-- one, implemented by makeT, ensures that rank   riant of weight
 -- biased leftist tree is not violated after merging.
 --
 -- Notation:
diff --git a/tests/pos/WBL0.hs b/tests/pos/WBL0.hs
--- a/tests/pos/WBL0.hs
+++ b/tests/pos/WBL0.hs
@@ -29,7 +29,7 @@
                              , right :: Heap a
                              }
 
-{-@ data Heap a <q :: a -> a -> Prop> =
+{-@ data Heap a <q :: a -> a -> Bool> =
       Empty | Node { pri   :: a
                    , rnk   :: Nat
                    , left  :: {v: Heap<q> (a<q pri>) | ValidRank v}
@@ -51,8 +51,10 @@
 realRank (Empty)        = 0
 realRank (Node p k l r) = 1 + realRank l + realRank r
 
+{-@ invariant {v:Heap a | rank v == realRank v } @-}
+
 {-@ measure rank @-}
-{-@ rank :: h:PHeap a -> {v:Nat | v = realRank h} @-}
+{-@ rank :: h:Heap a -> {v:Nat | v = realRank h} @-}
 rank Empty          = 0
 rank (Node _ r _ _) = r
 
diff --git a/tests/pos/WrapUnWrap.hs b/tests/pos/WrapUnWrap.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/WrapUnWrap.hs
@@ -0,0 +1,14 @@
+{-@ LIQUID "--totality"     @-}
+{-@ LIQUID "--higherorder"  @-}
+{-@ LIQUID "--exactdc"      @-}
+module Data.Foo where
+
+
+import Language.Haskell.Liquid.ProofCombinators
+
+data    Prod1 a = Prod1 {unprod1 :: a }
+{-@ data Prod1 a = Prod1 {unprod1 :: a } @-}
+
+prod1Theorem :: Prod1 a -> Proof 
+{-@ prod1Theorem :: x:Prod1 a -> {x == Prod1 (unprod1 x)} @-}
+prod1Theorem (Prod1 _) = trivial 
diff --git a/tests/pos/absref-crash.hs b/tests/pos/absref-crash.hs
--- a/tests/pos/absref-crash.hs
+++ b/tests/pos/absref-crash.hs
@@ -2,8 +2,8 @@
 
 data L a = C (L a)
 
-{-@ data L a <p :: L a -> Prop> = C { xs :: L<p> a } @-}
+{-@ data L a <p :: L a -> Bool> = C { xs :: L<p> a } @-}
 
-{-@ Lazy foo @-}
+{-@ lazy foo @-}
 foo :: b -> L a
 foo x = C $ foo x
diff --git a/tests/pos/absref-crash0.hs b/tests/pos/absref-crash0.hs
--- a/tests/pos/absref-crash0.hs
+++ b/tests/pos/absref-crash0.hs
@@ -9,7 +9,7 @@
 
 infixr 9 `C`
 
-{-@ ifoldr :: forall a b <p :: List a -> b -> Prop>. 
+{-@ ifoldr :: forall a b <p :: List a -> b -> Bool>. 
                  (xs:_ -> x:_ -> b<p xs> -> b<p(C x xs)>) 
                -> b<p N> 
                -> ys:List a
@@ -17,7 +17,7 @@
 ifoldr :: (List a -> a -> b -> b) -> b -> List a -> b
 ifoldr = undefined
 
-{-@ data List a <p :: a -> a -> Prop> 
+{-@ data List a <p :: a -> a -> Bool> 
      = N | C {x :: a, xs :: List<p> a<p x>} @-}
 
 {-@ type IncrList a = List <{\x y -> x <= y}> a @-} 
diff --git a/tests/pos/alphaconvert-List.hs b/tests/pos/alphaconvert-List.hs
--- a/tests/pos/alphaconvert-List.hs
+++ b/tests/pos/alphaconvert-List.hs
@@ -1,3 +1,4 @@
+{-@ LIQUID "--pruneunsorted" @-}
 {-@ LIQUID "--no-termination" @-}
 {-@ LIQUID "--short-names"    @-}
 {-@ LIQUID "--fullcheck"      @-}
@@ -37,11 +38,11 @@
     fv (App e a)     = (Set_cup (fv e) (fv a)) 
   @-}
 
-{-@ measure isAbs    :: Expr -> Prop
-    isAbs (Var v)    = false
-    isAbs (Abs v e)  = true
-    isAbs (App e a)  = false             
-  @-}
+{-@ measure isAbs  @-}
+isAbs :: Expr -> Bool 
+isAbs (Abs v e)  = True
+isAbs (Var v)    = False
+isAbs (App e a)  = False             
 
 {-@ predicate AddV E E2 X E1   = fv E = Set_cup (Set_dif (fv E2) (Set_sng X)) (fv E1) @-}
 {-@ predicate EqV E1 E2        = fv E1 = fv E2                                        @-}
@@ -102,7 +103,7 @@
     maxs (x:xs) = if (x > maxs xs) then x else (maxs xs) 
   @-}
 
-{-@ lemma1 :: x:Int -> xs:{[Int] | x > maxs xs} -> {v:Bool | Prop v && NotElem x xs} @-}
+{-@ lemma1 :: x:Int -> xs:{[Int] | x > maxs xs} -> {v:Bool | v && NotElem x xs} @-}
 lemma1 _ []     = True 
 lemma1 x (_:ys) = lemma1 x ys 
 
@@ -135,7 +136,7 @@
 {-@ (\\)      :: (Eq a) => xs:[a] -> y:a -> {v:[a] | IsDel v xs y} @-}
 xs   \\ y     = [x | x <- xs, x /= y]
 
-{-@ elem      :: (Eq a) => x:a -> ys:[a] -> {v:Bool | Prop v <=> Elem x ys} @-}
+{-@ elem      :: (Eq a) => x:a -> ys:[a] -> {v:Bool | v <=> Elem x ys} @-}
 elem x []     = False
 elem x (y:ys) = x == y || elem x ys
  
diff --git a/tests/pos/alphaconvert-Set.hs b/tests/pos/alphaconvert-Set.hs
--- a/tests/pos/alphaconvert-Set.hs
+++ b/tests/pos/alphaconvert-Set.hs
@@ -33,11 +33,10 @@
     fv (App e a)     = (Set_cup (fv e) (fv a)) 
   @-}
 
-{-@ measure isAbs    :: Expr -> Prop
-    isAbs (Var v)    = false
-    isAbs (Abs v e)  = true
-    isAbs (App e a)  = false             
-  @-}
+{-@ measure isAbs @-}
+isAbs (Var v)    = False
+isAbs (Abs v e)  = True
+isAbs (App e a)  = False             
 
 {-@ predicate Elem  X Ys       = Set_mem X Ys               @-}
 {-@ predicate NotElem X Ys     = not (Elem X Ys)            @-}
diff --git a/tests/pos/anfbug.hs b/tests/pos/anfbug.hs
--- a/tests/pos/anfbug.hs
+++ b/tests/pos/anfbug.hs
@@ -11,8 +11,8 @@
 x = getTails' 1 []
 
 -- HACK give hints for internal variables....
-{- Decrease ds_d258 3 @-}
-{- Decrease ds_d25g 3 @-}
+{- decrease ds_d258 3 @-}
+{- decrease ds_d25g 3 @-}
 
 -- TransformRec BUG: this causes some wierd unused variable error (occurrence of DEAD ID)?
 getTails'' :: Int -> [[a]] -> [[a]]
diff --git a/tests/pos/bar.hs b/tests/pos/bar.hs
deleted file mode 100644
--- a/tests/pos/bar.hs
+++ /dev/null
@@ -1,5 +0,0 @@
-module Bar where
-
-import Foo
-
-foo = bar
diff --git a/tests/pos/bool0.hs b/tests/pos/bool0.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/bool0.hs
@@ -0,0 +1,16 @@
+module BoolMeasure where
+
+{-@ myhead :: {v:[a] | nonEmpty v} -> a @-}
+myhead (x:_) = x
+
+{-@ measure nonEmpty @-}   
+nonEmpty :: [a] -> Bool
+nonEmpty (x:xs) = True 
+nonEmpty []     = False
+
+
+
+
+
+
+
diff --git a/tests/pos/bool1.hs b/tests/pos/bool1.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/bool1.hs
@@ -0,0 +1,5 @@
+module EqBool where 
+
+{-@ baz :: x:Bool -> {v:Bool | v == x} @-}
+baz :: Bool -> Bool 
+baz x = x 
diff --git a/tests/pos/bool2.hs b/tests/pos/bool2.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/bool2.hs
@@ -0,0 +1,9 @@
+module EqBool where 
+
+
+{-@ gerb :: (Ord a) => x:a -> {v:a | x <= v } -> {v:a | x <= v} @-}
+gerb :: (Ord a) => a -> a -> a 
+gerb x y = y 
+
+ 
+moo = gerb False False 
diff --git a/tests/pos/comprehension.hs b/tests/pos/comprehension.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/comprehension.hs
@@ -0,0 +1,7 @@
+module Comprehension where
+
+{-@ foo :: n:Int -> [{v:Nat | v <= n}] @-}
+foo :: Int -> [Int]
+foo n = [0 .. n]
+
+{-@ assume GHC.Enum.enumFromTo :: (Enum a) => lo:a -> hi:a -> [{v:a | lo <= v && v <= hi}] @-}
diff --git a/tests/pos/coretologic.hs b/tests/pos/coretologic.hs
--- a/tests/pos/coretologic.hs
+++ b/tests/pos/coretologic.hs
@@ -2,6 +2,13 @@
 
 import Data.Set
 
+-- TODO: NOPROP: transition to this
+{- type IsEmp a = {v:[a] | Data.Set.elems v = Data.Set.empty 10 } @-}
+{- predicate Data.Set.elems Xs = listElts Xs @-}
+{- predicate Data.Set.empty X  = Set_empty 0 @-}
+
+
+
 -- ISSUE: can we please allow things like `empty` to also
 -- appear in type and alias specifications, not just in
 -- measures as in `goo` below?
@@ -12,8 +19,7 @@
 foo :: [Int]
 foo = []
 
-
 {-@ measure goo @-}
 goo        :: (Ord a) => [a] -> Set a
 goo []     = empty
-goo (x:xs) = (singleton x) `union` (goo xs)  
+goo (x:xs) = (singleton x) `union` (goo xs)
diff --git a/tests/pos/csgordon_issue_296.hs b/tests/pos/csgordon_issue_296.hs
--- a/tests/pos/csgordon_issue_296.hs
+++ b/tests/pos/csgordon_issue_296.hs
@@ -1,6 +1,6 @@
 module BadMeasureType where 
 
-{-@ measure fwd_extends :: IO () -> IO () -> Prop @-}
+{-@ measure fwd_extends :: IO () -> IO () -> Bool @-}
 {-@ assume fwd_extends_refl :: m:IO () -> {v:Bool | (fwd_extends m m)} @-}
 fwd_extends_refl :: IO () -> Bool
 fwd_extends_refl = undefined
diff --git a/tests/pos/cut00.hs b/tests/pos/cut00.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/cut00.hs
@@ -0,0 +1,18 @@
+module Cut (foo0) where
+
+{-@ foo0 :: Nat -> Nat @-}
+
+foo0 x = 1 + foo1 x
+foo1 x = 1 + foo2 x
+foo2 x = 1 + foo3 x
+foo3 x = 1 + foo4 x
+foo4 x = 1 + foo5 x
+foo5 x = 1 + foo  x
+
+foo :: Int -> Int
+foo x = 1 + x
+
+bar :: Int -> Int
+bar y = y + 10
+
+-- foo x = 1 + foo (x - 1)
diff --git a/tests/pos/data2.hs b/tests/pos/data2.hs
--- a/tests/pos/data2.hs
+++ b/tests/pos/data2.hs
@@ -3,8 +3,8 @@
 import Control.Applicative
 import Language.Haskell.Liquid.Prelude
 
-data LL a = N | C { head :: a, tail :: (LL a) }
-{-@ data LL [llen] a = N | C { head :: a, tail :: (LL a) } @-}
+data LL a = N | C { headC :: a, tailC :: (LL a) }
+{-@ data LL [llen] a = N | C { headC :: a, tailC :: (LL a) } @-}
 
 {-@ measure llen :: (LL a) -> Int
     llen(N)      = 0
diff --git a/tests/pos/deepmeas0.hs b/tests/pos/deepmeas0.hs
--- a/tests/pos/deepmeas0.hs
+++ b/tests/pos/deepmeas0.hs
@@ -1,3 +1,4 @@
+{-@ LIQUID "--pruneunsorted" @-}
 module DeepMeasure () where
 
 import Language.Haskell.Liquid.Prelude (liquidError)
diff --git a/tests/pos/deptup.hs b/tests/pos/deptup.hs
--- a/tests/pos/deptup.hs
+++ b/tests/pos/deptup.hs
@@ -2,13 +2,13 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ data Pair a b <p :: x0:a -> x1:b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: x0:a -> x1:b -> Bool> = P (x :: a) (y :: b<p x>) @-}
 data Pair a b = P a b
 
 
-{-- TODO: mkP :: forall a b <p :: a -> b -> Prop>. x: a -> y: b<p x> -> Pair <p> a b  --}
+{-- TODO: mkP :: forall a b <p :: a -> b -> Bool>. x: a -> y: b<p x> -> Pair <p> a b  --}
 
-mkP :: a -> a -> Pair a a 
+mkP :: a -> a -> Pair a a
 mkP x y = P x y
 
 incr x = x + 1
@@ -20,10 +20,11 @@
 prop = chk $ baz n
   where n = choose 100
 
+
 bazList  xs = map baz xs
 
 n           = choose 0
 
 xs          = [0,1,2,3,4]
 
-prop_baz    = map chk $ bazList xs 
+prop_baz    = map chk $ bazList xs
diff --git a/tests/pos/deptup0.hs b/tests/pos/deptup0.hs
--- a/tests/pos/deptup0.hs
+++ b/tests/pos/deptup0.hs
@@ -2,7 +2,7 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ data Pair a b <p :: x0:a -> x1:b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: x0:a -> x1:b -> Bool> = P (x :: a) (y :: b<p x>) @-} 
 data Pair a b = P a b
 
 incr x = x + 1
diff --git a/tests/pos/deptup1.hs b/tests/pos/deptup1.hs
--- a/tests/pos/deptup1.hs
+++ b/tests/pos/deptup1.hs
@@ -2,7 +2,7 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ data Pair a b <p :: x0:a -> x1:b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: x0:a -> x1:b -> Bool> = P (x :: a) (y :: b<p x>) @-} 
 data Pair a b = P a b
 
 incr        :: Int -> Int
diff --git a/tests/pos/deptupW.hs b/tests/pos/deptupW.hs
--- a/tests/pos/deptupW.hs
+++ b/tests/pos/deptupW.hs
@@ -2,10 +2,10 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ data Pair a b <p :: x0:a -> x1:b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: x0:a -> x1:b -> Bool> = P (x :: a) (y :: b<p x>) @-} 
 data Pair a b = P a b
 
-{-@ mkP :: forall a <q :: y0:a -> y1:a -> Prop>. x: a -> y: a<q x> -> Pair <q> a a @-}
+{-@ mkP :: forall a <q :: y0:a -> y1:a -> Bool>. x: a -> y: a<q x> -> Pair <q> a a @-}
 mkP :: a -> a -> Pair a a
 mkP x y = P x y 
 
diff --git a/tests/pos/dropwhile.hs b/tests/pos/dropwhile.hs
--- a/tests/pos/dropwhile.hs
+++ b/tests/pos/dropwhile.hs
@@ -15,7 +15,7 @@
 -- | The `head` function returns a value that satisfies the abstract refinement
 -------------------------------------------------------------------------------
 
-{-@ head ::  forall <p :: a -> Prop>. List <p> a -> a<p> @-}
+{-@ head ::  forall <p :: a -> Bool>. List <p> a -> a<p> @-}
 head (x ::: _) = x
 
 -------------------------------------------------------------------------------
@@ -33,7 +33,7 @@
 -- in the below, `hd :: a<p>` means the "head" is a value of type `a` that
 -- additionally, satisfies `p hd`.
 
-{-@ data List a <p :: a -> Prop> = Emp
+{-@ data List a <p :: a -> Bool> = Emp
                                  | (:::) { hd :: a<p>
                                          , tl :: List a }
   @-}
@@ -50,7 +50,7 @@
 -- | dropWhile some predicate `f` is not satisfied
 -------------------------------------------------------------------------------
 
-{-@ dropWhile :: forall <p :: a -> Prop, w :: a -> Bool -> Prop>.
+{-@ dropWhile :: forall <p :: a -> Bool, w :: a -> Bool -> Bool>.
                    (Witness a p w) =>
                    (x:a -> Bool<w x>) -> List a -> List <p> a
   @-}
@@ -66,9 +66,6 @@
 witness :: Eq a => (a -> Bool) -> (a -> Bool -> Bool) -> a -> Bool -> a -> Bool
 witness p w = \ y b v -> (not b) ==> w y b ==> (v == y) ==> p v
 
-{-@ measure tail :: forall a. { es : [a] | len es >= 1 } -> [a] @-}
-tail :: [a] -> [a]
-tail = undefined
 -------------------------------------------------------------------------------
 -- | Drop elements until you hit a `3`
 -------------------------------------------------------------------------------
@@ -79,6 +76,6 @@
 
 -- | Currently needed for the qual; should be made redundant by `--eliminate`
 
-{-@ eqOne :: x:Int -> {v:Bool | Prop v <=> x /= 3} @-}
+{-@ eqOne :: x:Int -> {v:Bool | v <=> x /= 3} @-}
 eqOne :: Int -> Bool
 eqOne x = x /= 3
diff --git a/tests/pos/elements.hs b/tests/pos/elements.hs
--- a/tests/pos/elements.hs
+++ b/tests/pos/elements.hs
@@ -1,17 +1,18 @@
+{-@ LIQUID "--pruneunsorted" @-}
 module Elems where
 
 import Prelude hiding (elem)
 
 import Data.Set (Set (..))
 
-{-@ append  :: xs:_ -> ys:_ -> {v:_ | UnElts v xs ys} @-}  
+{-@ append  :: xs:_ -> ys:_ -> {v:_ | UnElts v xs ys} @-}
 append [] ys     = ys
-append (x:xs) ys = x : append xs ys 
+append (x:xs) ys = x : append xs ys
 
 
 {-@ reverse :: xs:_ -> {v:_ | EqElts v xs} @-}
 reverse xs           = revAcc xs []
-  where 
+  where
    revAcc []     acc = acc
    revAcc (x:xs) acc = revAcc xs (x:acc)
 
@@ -21,18 +22,18 @@
 nub xs             = go xs []
   where
     go (x:xs) l
-      | x `elem` l = go xs l     
-      | otherwise  = go xs (x:l) 
+      | x `elem` l = go xs l
+      | otherwise  = go xs (x:l)
     go [] l        = l
 
 
-{-@ elem :: (Eq a) => x:_ -> ys:_ -> {v:Bool | Prop v <=> Set_mem x (elems ys)} @-}
+{-@ elem :: (Eq a) => x:_ -> ys:_ -> {v:Bool | v <=> Set_mem x (elems ys)} @-}
 elem x []     = False
 elem x (y:ys) = x == y || elem x ys
 
 
 
-{-@ find :: (Eq a) => key:_ -> {map:_ | ValidKey key map} -> b @-}  
+{-@ find :: (Eq a) => key:_ -> {map:_ | ValidKey key map} -> b @-}
 find key ((k,v):kvs)
   | key == k  = v
   | otherwise = find key kvs
@@ -55,13 +56,13 @@
     keys ([])     = (Set_empty 0)
     keys (kv:kvs) = (Set_cup (Set_sng (fst kv)) (keys kvs))
   @-}
- 
+
 {-@ measure elems :: [a] -> (Set a)
     elems ([])    = (Set_empty 0)
     elems (x:xs)  = (Set_cup (Set_sng x) (elems xs))
   @-}
 
-{-@ measure nodups :: [a] -> Prop
+{-@ measure nodups :: [a] -> Bool
     nodups ([])   = true
     nodups (x:xs) = (not (Set_mem x (elems xs)) && nodups xs)
   @-}
diff --git a/tests/pos/elems.hs b/tests/pos/elems.hs
--- a/tests/pos/elems.hs
+++ b/tests/pos/elems.hs
@@ -8,8 +8,6 @@
 elems       :: T a -> S.Set a
 elems (T a) = S.singleton a
 
-{-@ member :: x:a -> t:T a -> {v:Bool | Prop v <=> S.member x (elems t)} @-}
+{-@ member :: x:a -> t:T a -> {v:Bool | v <=> S.member x (elems t)} @-}
 member :: a -> T a -> Bool
 member = undefined
-
-        
diff --git a/tests/pos/elim-ex-compose.hs b/tests/pos/elim-ex-compose.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/elim-ex-compose.hs
@@ -0,0 +1,9 @@
+module ElimExCompose (prop) where
+
+{-@ prop :: x:Nat -> {v:Int | v = x + 5} @-}
+prop :: Int -> Int
+prop = incr . incr . incr . incr . incr
+
+{-@ incr :: dog:Int -> {v:Int | v == dog + 1} @-}
+incr :: Int -> Int
+incr cat = cat + 1
diff --git a/tests/pos/elim-ex-let.hs b/tests/pos/elim-ex-let.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/elim-ex-let.hs
@@ -0,0 +1,15 @@
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExLet (prop) where
+
+import LiquidHaskell
+
+[lq| type Nat = {v:Int | 0 <= v} |]
+
+[lq| prop :: a -> Nat |]
+prop _ = let x _ = let y = 0 
+                   in
+                     y - 1
+         in 
+           x () + 2
diff --git a/tests/pos/elim-ex-list.hs b/tests/pos/elim-ex-list.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/elim-ex-list.hs
@@ -0,0 +1,22 @@
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExList (prop) where
+
+import LiquidHaskell
+import Prelude hiding (head)
+
+--------------------------------------------------------------------------
+[lq| prop :: a -> Even |]
+prop _ = (head ys) - 1
+  where 
+    ys = Cons 1 (Cons 3 (Cons 5 Nil))
+--------------------------------------------------------------------------
+
+[lq| type Even = {v:Int | v mod 2 == 0 } |]
+
+data List a = Nil | Cons a (List a)
+
+head :: List a -> a 
+head (Cons x _) = x
+
diff --git a/tests/pos/elim-ex-map-1.hs b/tests/pos/elim-ex-map-1.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/elim-ex-map-1.hs
@@ -0,0 +1,21 @@
+{-@ LIQUID "--no-termination" @-}
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExMap (prop) where
+
+import LiquidHaskell
+
+import Prelude hiding (map)
+
+--------------------------------------------------------------------------
+[lq| prop :: List Even -> List Even |]
+prop xs = map (+ 1) (map (+ 1) xs)
+--------------------------------------------------------------------------
+
+[lq| type Even = {v:Int | v mod 2 == 0 } |]
+
+data List a = Nil | Cons a (List a)
+
+map f Nil         = Nil
+map f (Cons x xs) = Cons (f x) (map f xs)
diff --git a/tests/pos/elim-ex-map-2.hs b/tests/pos/elim-ex-map-2.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/elim-ex-map-2.hs
@@ -0,0 +1,21 @@
+{-@ LIQUID "--no-termination" @-}
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExMap (prop) where
+
+import LiquidHaskell
+
+import Prelude hiding (map)
+
+--------------------------------------------------------------------------
+[lq| prop :: List Even -> List Even |]
+prop = map (+ 1) . map (+ 1)
+--------------------------------------------------------------------------
+
+[lq| type Even = {v:Int | v mod 2 == 0 } |]
+
+data List a = Nil | Cons a (List a)
+
+map f Nil         = Nil
+map f (Cons x xs) = Cons (f x) (map f xs)
diff --git a/tests/pos/elim-ex-map-3.hs b/tests/pos/elim-ex-map-3.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/elim-ex-map-3.hs
@@ -0,0 +1,21 @@
+{-@ LIQUID "--no-termination" @-}
+
+{-# LANGUAGE QuasiQuotes #-}
+
+module ElimExMap (prop) where
+
+import LiquidHaskell
+
+import Prelude hiding (map)
+
+--------------------------------------------------------------------------
+[lq| prop :: List Even -> List Even |]
+prop = map ((+ 1) . (+ 1))
+--------------------------------------------------------------------------
+
+[lq| type Even = {v:Int | v mod 2 == 0 } |]
+
+data List a = Nil | Cons a (List a)
+
+map f Nil         = Nil
+map f (Cons x xs) = Cons (f x) (map f xs)
diff --git a/tests/pos/elim00.hs b/tests/pos/elim00.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/elim00.hs
@@ -0,0 +1,15 @@
+{-@ LIQUID "--short-names"  @-}
+
+module Elim where
+
+data Pair a b = PP a b | Emp
+
+data Foo = Foo { xx :: Int, yy :: Int }
+
+{-@ data Foo = Foo {xx :: Int, yy :: {v:Int | xx < v} }  @-}
+
+foo :: Foo -> Foo
+foo (Foo xig yog) = Foo wink cow
+  where
+    PP wink cow   = PP xig yog
+
diff --git a/tests/pos/elim01.hs b/tests/pos/elim01.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/elim01.hs
@@ -0,0 +1,11 @@
+module EliminateCuts (bar) where
+
+{-@ bar :: n:{Int | n > 0} -> {v:Int | v = n + 4 } @-}
+bar :: Int -> Int 
+bar n0 = let 
+            n1 = if (n0 == 0) then 0 else 1 + n0
+            n2 = if (n1 == 0) then 0 else 1 + n1
+            n3 = if (n2 == 0) then 0 else 1 + n2
+            n4 = if (n3 == 0) then 0 else 1 + n3
+         in 
+            n4
diff --git a/tests/pos/eq-poly-measure.hs b/tests/pos/eq-poly-measure.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/eq-poly-measure.hs
@@ -0,0 +1,14 @@
+module Pair () where 
+
+import Language.Haskell.Liquid.Prelude 
+
+{-@ data Thing a = P (unThing :: a) @-} 
+data Thing a = P a
+
+property :: Bool
+property = chk t1 
+  where 
+  chk (P x) = liquidAssertB x 
+
+  t1 :: Thing Bool 
+  t1 = P True 
diff --git a/tests/pos/ex0.hs b/tests/pos/ex0.hs
--- a/tests/pos/ex0.hs
+++ b/tests/pos/ex0.hs
@@ -1,10 +1,11 @@
+{-@ LIQUID "--pruneunsorted" @-}
 {-@ LIQUID "--no-termination" @-}
 
 module Ex (count) where
 
 -- Testing "existential-types"
 
-{-@ foldN :: forall a <p :: x0:Int -> x1:a -> Prop>. 
+{-@ foldN :: forall a <p :: x0:Int -> x1:a -> Bool>. 
                 (i:Int -> a<p i> -> a<p (i+1)>) 
               -> n:{v: Int | v >= 0}
               -> a <p 0> 
diff --git a/tests/pos/ex01.hs b/tests/pos/ex01.hs
--- a/tests/pos/ex01.hs
+++ b/tests/pos/ex01.hs
@@ -10,7 +10,7 @@
 
 data Vec a = Nil 
 
-{-@ efoldr :: forall b a <p :: x0:Vec a -> x1:b -> Prop>. 
+{-@ efoldr :: forall b a <p :: x0:Vec a -> x1:b -> Bool>. 
               b <p Ex.Nil>
               -> ys: Vec a
               -> b <p ys>
diff --git a/tests/pos/ex1.hs b/tests/pos/ex1.hs
--- a/tests/pos/ex1.hs
+++ b/tests/pos/ex1.hs
@@ -1,3 +1,4 @@
+{-@ LIQUID "--pruneunsorted" @-}
 
 -- | A somewhat fancier example demonstrating the use of Abstract Predicates and exist-types
 
@@ -13,10 +14,10 @@
 
 -- | We can encode the notion of length as an inductive measure @llen@
 
-{-@ measure llen     :: forall a. Vec a -> Int
-    llen (Nil)       = 0
-    llen (Cons x xs) = 1 + llen(xs)
-  @-}
+{-@ measure llen @-}
+llen :: Vec a -> Int
+llen (Nil)       = 0
+llen (Cons x xs) = 1 + llen(xs)
 
 {-@ invariant {v:Vec a | (llen v) >= 0} @-}
 
@@ -36,7 +37,7 @@
 -- for our `Vec` type. Note that the `op` argument takes an extra /ghost/
 -- parameter that will let us properly describe the type of `efoldr`
 
-{-@ efoldr :: forall a b <p :: x0:Vec a -> x1:b -> Prop>.
+{-@ efoldr :: forall a b <p :: x0:Vec a -> x1:b -> Bool>.
                 (xs:Vec a -> x:a -> b <p xs> -> b <p (Ex.Cons x xs)>)
               -> b <p Ex.Nil>
               -> ys: Vec a
@@ -57,11 +58,6 @@
 {-@ size :: xs:Vec a -> {v: Int | v = llen xs} @-}
 size :: Vec a -> Int
 size = efoldr (\_ _ n -> n + 1) 0
-
--- | The above uses a helper that counts up the size. (Pesky hack to avoid writing qualifier v = ~A + 1)
-{-@ suc :: x:Int -> {v: Int | v = x + 1} @-}
-suc :: Int -> Int
-suc x = x + 1
 
 -- | Second: Appending two lists using `efoldr`
 {-@ app  :: xs: Vec Int -> ys: Vec Int -> {v: Vec Int | llen v = llen xs + llen ys } @-}
diff --git a/tests/pos/filterAbs.hs b/tests/pos/filterAbs.hs
--- a/tests/pos/filterAbs.hs
+++ b/tests/pos/filterAbs.hs
@@ -7,8 +7,8 @@
 
 import Prelude hiding (filter)
 
-{-@ filter :: forall <p :: a -> Prop, q :: a -> Bool -> Prop>.
-                  {y::a, flag::{v:Bool<q y> | Prop v} |- {v:a | v = y} <: a<p>}
+{-@ filter :: forall <p :: a -> Bool, q :: a -> Bool -> Bool>.
+                  {y::a, flag::{v:Bool<q y> | v} |- {v:a | v = y} <: a<p>}
                   (x:a -> Bool<q x>) -> [a] -> [a<p>]
   @-}
 
@@ -18,19 +18,19 @@
   | otherwise = filter f xs
 filter _ []   = []
 
-{-@ isPos :: x:Int -> {v:Bool | Prop v <=> x > 0} @-}
+{-@ isPos :: x:Int -> {v:Bool | v <=> x > 0} @-}
 isPos :: Int -> Bool
 isPos n = n > 0
 
 
-{-@ isNeg :: x:Int -> {v:Bool | Prop v <=> x < 0} @-}
+{-@ isNeg :: x:Int -> {v:Bool | v <=> x < 0} @-}
 isNeg :: Int -> Bool
 isNeg n = n < 0
 
 
 -- | `positives` works by instantiating:
 -- p := \v   -> 0 < v
--- q := \x v -> Prop v <=> 0 < x  (NV ??)
+-- q := \x v -> v <=> 0 < x  (NV ??)
 
 
 {-@ positives :: [Int] -> [{v:Int | v > 0}] @-}
@@ -39,7 +39,7 @@
 
 -- | `negatives` works by instantiating:
 -- p := \v   -> 0 > v
--- q := \x v -> Prop v <=> x < 0
+-- q := \x v -> v <=> x < 0
 
 {-@ negatives :: [Int] -> [{v:Int | v < 0}] @-}
 negatives xs = filter isNeg xs
diff --git a/tests/pos/foldN.hs b/tests/pos/foldN.hs
--- a/tests/pos/foldN.hs
+++ b/tests/pos/foldN.hs
@@ -1,10 +1,11 @@
+{-@ LIQUID "--pruneunsorted" @-}
 {-@ LIQUID "--no-termination" @-}
 
 module Ex () where
 
 -- Testing "existential-types"
 
-{-@ foldN :: forall a <p :: x0:Int -> x1:a -> Prop>. 
+{-@ foldN :: forall a <p :: x0:Int -> x1:a -> Bool>. 
                 (i:Int -> a<p i> -> a<p (i+1)>) 
               -> n:{v: Int | v >= 0}
               -> a <p 0> 
diff --git a/tests/pos/gadtEval.hs b/tests/pos/gadtEval.hs
--- a/tests/pos/gadtEval.hs
+++ b/tests/pos/gadtEval.hs
@@ -33,7 +33,7 @@
 check (Plus e1 e2) = TInt
 check (Equal _ _)  = TBool
 
-{-@ Strict eval @-}
+{-@ lazy eval @-}
 
 {-@ eval           :: e:ValidExpr  -> {v:ValidExpr | ((isValue v) && (((eType e) = (eType v))))} @-}
 eval e@(I _)       = e
@@ -68,7 +68,7 @@
 {-@ type BoolExpr      = {v: Expr | ((isValue v) && (IsTBool v))} @-}
 
 
-{-@ measure isValue       :: Expr -> Prop
+{-@ measure isValue       :: Expr -> Bool
     isValue (I i)         = true
     isValue (B b)         = true
     isValue (Equal e1 e2) = false 
@@ -82,7 +82,7 @@
     eType (Equal e1 e2) = TBool 
   @-}
 
-{-@ measure isValid       :: Expr -> Prop
+{-@ measure isValid       :: Expr -> Bool
     isValid (I i)         = true
     isValid (B b)         = true
     isValid (Equal e1 e2) = (((eType e1) = (eType e2)) && (isValid e1) && (isValid e2))
diff --git a/tests/pos/go_ugly_type.hs b/tests/pos/go_ugly_type.hs
--- a/tests/pos/go_ugly_type.hs
+++ b/tests/pos/go_ugly_type.hs
@@ -2,7 +2,7 @@
 
 {-@ qualif Poo(v:a, x:a, y:a): (len v) = (len x) + (len y) @-}
 
-{-@ Decrease go 2 @-}
+{-@ decrease go 2 @-}
 
 {-@ rev :: xs:[a] -> {v: [a] | (len v) = (len xs)} @-}
 rev = go [] 
diff --git a/tests/pos/initarray.hs b/tests/pos/initarray.hs
--- a/tests/pos/initarray.hs
+++ b/tests/pos/initarray.hs
@@ -42,7 +42,7 @@
       j: {v: Int | (v mod 2 = 0 && 0 <= v && v < 10)} -> {v: Int | v = 0} @-}
 stridedZeroes = zeroEveryOther 0 10 empty
 
-{-@ initArray :: forall a <p :: x0: Int -> x1: a -> Prop>.
+{-@ initArray :: forall a <p :: x0: Int -> x1: a -> Bool>.
       f: (z: Int -> a<p z>) ->
       i: {v: Int | v >= 0} ->
       n: Int ->
diff --git a/tests/pos/inline.hs b/tests/pos/inline.hs
--- a/tests/pos/inline.hs
+++ b/tests/pos/inline.hs
@@ -4,18 +4,18 @@
 eqq :: Ord a => a -> a -> Bool
 eqq x y = x > y
 
+{-@ eqqtest :: Eq a => x:a -> y:a -> {v:Bool | v <=> (eqq x y) } @-}
 eqqtest :: Ord a => a -> a -> Bool
-{-@ eqqtest :: Eq a => x:a -> y:a -> {v:Bool | Prop v <=> (eqq x y) } @-}
 eqqtest x y = x > y
 
-{-@ inline mymax @-}
-{-@ inline mymin @-}
 
-
-mymax, mymin :: Ord a => a -> a -> a
+{-@ inline mymax @-}
+mymax :: Ord a => a -> a -> a
 mymax x y = if x >= y then x else y
 
 
+{-@ inline mymin @-}
+mymin :: Ord a => a -> a -> a
 mymin x y = mymax y x
 
 {-@ measure foo @-}
@@ -33,15 +33,15 @@
 
 
 
-foooo = D 
+foooo = D
 
 
 {-@ measure bar :: (D a) -> a
-    bar(D x y) = (mymax x y) 
+    bar(D x y) = (mymax x y)
   @-}
 
 {-@ measure bar2 :: (D a) -> a
-    bar2(D x y) = (mymin x y) 
+    bar2(D x y) = (mymin x y)
   @-}
 
 data D a = D a a | F a
@@ -50,5 +50,3 @@
 {-@ mymax3, mymax :: x:a -> y:a -> {v:a | v = mymax x y} @-}
 mymax3 :: Ord a => a -> a -> a
 mymax3 x y = if x >= y then x else y
-
-
diff --git a/tests/pos/jeff.hs b/tests/pos/jeff.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/jeff.hs
@@ -0,0 +1,262 @@
+{-
+
+This code implements a Monoid for string matching; i.e. a data
+structure, MatchIdxs, which has the result of a string match function
+plus a little extra information for monoidally combining things
+together; the purpose of course is to parallelize string matching
+computations. This is the original version I wrote which uses type
+level strings to guarantee that only computations done with the same
+target string are combinable.
+
+The invariants I'd like to prove are in the comments on the MatchIdxs
+constructors. I'd be interested in a way to do it directly with this
+code (though it seems that would require extending LH), or doing it in
+a version of this code where the constructors have an extra argument
+with the value of the target-- however that formulation seems to raise
+issues about forcing those values to be the same.
+
+I have a version of the code lying around which tries this approach,
+but I couldn't get it to work. I chose to send this version first so
+you have the chance to see where I started; I could send you my version
+with the explicit terms if you like.
+
+If this goes well, then there are a couple of further things to think
+about:
+
+  1) I have another Monoid construction for actual splitting, but
+     I don't think LH can handle the invariants as they require an
+     isInfixOf operation; but I could be wrong about what LH can do.
+
+  2) It would be interesting to think about whether one can encode
+     correctness, rather than just some invariants. By correctness
+     I mean both that the monoid laws are satisfied, and that there
+     is a homomorphic-like property to the effect of:
+
+     match (x <> y) == match x <> match y
+
+Let me know if you have any questions about the code, or need more
+comments/explanation.
+-}
+
+
+{- LIQUID "--diff" @-}
+{-@ LIQUID "--scrape-used-imports" @-}
+{-@ LIQUID "--short-names" @-}
+
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module MatchIdxs where
+
+import qualified Data.ByteString as BS
+-- RJ import qualified Data.ByteString.Search as BS
+import Data.Char
+-- RJ import Data.List.Split(chunksOf)
+
+import Data.Monoid
+import Data.Proxy
+import Debug.Trace
+import GHC.TypeLits
+
+import Language.Haskell.Liquid.Prelude (liquidAssert)
+import Prelude hiding (max)
+
+
+junk = BS.head
+
+
+traceMsg msg x = trace (msg ++ show x) x
+
+{-@ chunksBS :: Int -> b:BS.ByteString -> [BS.ByteString] / [(bLength b)] @-}
+chunksBS n' xs | BS.null xs = []
+               | otherwise = x : chunksBS n xs'
+    where (x,xs') = BS.splitAt  (liquidAssert (n > 0) n) xs
+          n       = max 1 n'
+
+bsToString :: BS.ByteString -> String
+bsToString = map (chr . fromIntegral) . BS.unpack
+
+stringToBS :: String -> BS.ByteString
+stringToBS = BS.pack . map (fromIntegral . ord)
+
+-- | get the (proxied and existentially boxed) type level Symbol for a bytestring
+someSymbolValBS :: BS.ByteString -> SomeSymbol
+someSymbolValBS = someSymbolVal . bsToString
+
+-- | get the bytestring corresponding to a type level Symbol
+mkTarg :: forall t . KnownSymbol t => Proxy t -> BS.ByteString
+mkTarg = stringToBS . symbolVal
+
+
+-- | Naive specification of string matching (from Bird)
+{-@ indicesSpec :: t:ByteStringNE -> s:BS.ByteString -> [OkPos t s] @-}
+-- indicesSpec targ = map ((BS.length targ -) . BS.length) . filter (targ `BS.isSuffixOf`) . BS.inits
+indicesSpec targ s = [ BS.length s' - BS.length targ | s' <- BS.inits s
+                                                     , targ `BS.isSuffixOf` s' ]
+
+indicesSpec :: BS.ByteString -> BS.ByteString -> [Int]
+
+
+
+-- | Datatype to name string matching algorithms; will use it's lifted
+-- version put choice in type.
+data Alg = BM  -- ^ Boyer-Moore from stringsearch package
+         | Spec  -- ^ Naive spec
+
+{-@ indices :: Alg -> t:ByteStringNE -> s:BS.ByteString -> [OkPos t s] @-}
+indices BM   = assumeIndices -- RJ BS.indices
+indices Spec = indicesSpec
+
+
+-- | Monoid
+--
+-- 'MatchIdxs alg targ' denotes the result of running string matching
+-- algorithm 'alg' search for target 'targ' in some input. In addition
+-- to the match indices, information needed to combine this result
+-- with similar results on input to the left and right are also
+-- included.
+--
+-- We'd like to prove that the invariants in the comments hold (|x|
+-- denotes the length of x).
+data MatchIdxs
+    = Small { targ :: BS.ByteString
+            , bs   :: BS.ByteString
+            }
+    | MatchIdxs { targ    :: BS.ByteString
+                , input   :: Int
+                , left    :: BS.ByteString
+                , matches :: [Int]
+                , right   :: BS.ByteString
+                }
+  deriving (Eq, Show)
+
+{-@ data MatchIdxs
+      = Small { targ    :: ByteStringNE
+              , bs      :: {bs:BS.ByteString | bLength bs < bLength targ}
+              }
+
+      | MatchIdxs
+              { targ    :: ByteStringNE
+              , input   :: {input : Int | input >= bLength targ}
+              , left    :: {left  : BS.ByteString | bLength left == bLength targ - 1}
+              , matches :: [{v:Int | v <= input - bLength targ}]
+              , right   :: {right : BS.ByteString | bLength right == bLength targ - 1}
+              }
+  @-}
+
+
+matchIdxsIs :: MatchIdxs -> [Int]
+matchIdxsIs (Small _ _) = []
+matchIdxsIs (MatchIdxs _ _ _ is _) = is
+
+-- | create a 'MatchIdxs'
+{-@ myIndices :: Alg -> t:ByteStringNE -> BS.ByteString -> MatchIdxsT t @-}
+myIndices alg t bs
+  | BS.length bs > fringeLen = let right1 = BS.drop (BS.length bs - fringeLen) bs in
+                                MatchIdxs t (BS.length bs) left is right1
+  | otherwise = Small t bs
+  where
+    is        = indices alg t bs
+    fringeLen = BS.length t - 1
+    left      = BS.take fringeLen bs
+    -- right1    = BS.drop (BS.length bs - fringeLen) bs
+
+-- ISSUE: get contextual output with --diff
+-- ISSUE: why does lazyvar right1 not work? it drops the output type on right1!
+
+{- lazyvar right1 -}
+
+{-@ type OkPos Targ Str = {v:Nat | v <= bLength Str - bLength Targ} @-}
+{-@ type ByteStringNE   = {v:BS.ByteString | bLength v > 0 }   @-}
+{-@ type ByteStringN N  = {v:BS.ByteString | bLength v == N}   @-}
+{-@ type MatchIdxsT T   = {v:MatchIdxs | targ v == T}          @-}
+
+{-@ assume BS.isSuffixOf :: targ:_ -> s:_ -> {v:_ | v => (bLength targ <= bLength s) } @-}
+{-@ assume BS.length  :: b:BS.ByteString -> {v:Nat | v == bLength b}  @-}
+{-@ assume BS.empty   :: {v:BS.ByteString | bLength v == 0}    @-}
+{-@ assume BS.take    :: n:Nat -> b:BS.ByteString -> ByteStringN {min n (bLength b)} @-}
+{-@ assume BS.drop    :: n:Nat -> b:{BS.ByteString | n <= bLength b} -> ByteStringN {bLength b - n} @-}
+{-@ assume BS.inits   :: b:BS.ByteString -> [{v:BS.ByteString | bLength v <= bLength b}] @-}
+{-@ assume BS.append  :: b1:BS.ByteString -> b2:BS.ByteString -> ByteStringN {bLength b1 + bLength b2} @-}
+{-@ assume BS.null    :: b:BS.ByteString -> {v:Bool | v <=> (bLength b == 0)} @-}
+{-@ assume BS.splitAt :: n:Nat -> b:BS.ByteString -> (ByteStringN {min n (bLength b)}, ByteStringN {max 0 (bLength b - n)}) @-}
+{-@ assume BS.head    :: BS.ByteString -> Data.Word.Word8 @-}
+
+{-@ measure target @-}
+target :: MatchIdxs -> BS.ByteString
+target (Small t _)           = t
+target (MatchIdxs t _ _ _ _) = t
+
+{-@ inline min @-}
+min :: Int -> Int -> Int
+min x y = if x <= y then x else y
+
+{-@ inline max @-}
+max :: Int -> Int -> Int
+max x y = if x <= y then y else x
+
+-- RJ instance (KnownSymbol t, StringMatch alg) => Monoid (MatchIdxs alg t) where
+{-@ mmempty :: t:ByteStringNE -> MatchIdxsT t @-}
+mmempty t = Small t BS.empty
+
+{-@ mmconcat :: (Foldable t) => Alg -> tg:ByteStringNE -> t (MatchIdxsT tg) -> (MatchIdxsT tg) @-}
+mmconcat alg t = foldr (mmappend alg t) (mmempty t)
+
+{-@ qualif BB(v:Int, n:Int, d:Int, b:BS.ByteString): v <= (n + d) - bLength b @-}
+
+{-@ mmappend :: Alg -> t:ByteStringNE -> MatchIdxsT t -> MatchIdxsT t -> MatchIdxsT t @-}
+mmappend alg t mx my =
+  let fringeLen = BS.length t - 1
+      idxFun    = indices alg t
+  in
+  case (mx, my) of
+    (Small tx x, Small _ y) -> myIndices alg tx (x <> y)
+    (Small tx x, MatchIdxs _ yLen ly iy rt) -> MatchIdxs tx xyLen lt is rt
+       where
+         xyLen = xLen + yLen
+         xLen  = BS.length x
+         xly   = BS.append x ly
+         lt    = BS.take fringeLen xly
+         is    = idxFun xly ++ map (+ xLen) iy
+    (MatchIdxs tx xLen lt ix rx, Small ty y) -> MatchIdxs tx xyLen lt (ix ++ is) rt
+       where
+         xyLen = xLen + yLen
+         yLen  = BS.length y
+         is    = map (+ (xLen - fringeLen)) (idxFun rxy)
+         rt    = BS.drop (BS.length rxy - fringeLen) rxy
+         rxy   = BS.append rx y
+    (MatchIdxs tx xLen lt ix rx, MatchIdxs ty yLen ly iy rt) -> MatchIdxs tx xyLen lt (ix ++ is) rt
+       where
+         xyLen = xLen + yLen
+         is    = ixy ++ map (+ xLen) iy
+         ixy   = map (+ (xLen - fringeLen)) $ idxFun (BS.append rx ly)
+
+-- | Example applications
+--
+-- The bufLen and chunkSz arguments are there to exercise the monoid,
+-- though they also foreshadow a parallel implementation.
+{-@ indicesBS' :: Alg -> Int -> Int -> ByteStringNE -> BS.ByteString -> [Int] @-}
+indicesBS' alg bufLen chunkSz t bs =
+  let si = mmconcat alg t . map (mmconcat alg t) . chunksOf bufLen . map (myIndices alg t) $ chunksBS chunkSz bs in
+  matchIdxsIs si
+
+{-@ indicesBS, indicesNaive :: Int -> Int -> ByteStringNE -> BS.ByteString -> [Int] @-}
+indicesBS    = indicesBS' BM   -- RJ (Proxy :: Proxy BM)
+indicesNaive = indicesBS' Spec -- RJ (Proxy :: Proxy Spec)
+
+{-@ isInfixOfBS :: Int -> Int -> ByteStringNE -> BS.ByteString -> Bool @-}
+isInfixOfBS bufLen chunkSz t = not . null . indicesBS bufLen chunkSz t
+
+------------------------------------------------------------------------------------------
+{-@ invariant {v:BS.ByteString | 0 <= bLength v } @-}
+{-@ measure bLength :: BS.ByteString -> Int @-}
+{-@ type LNat N = {v:Nat | v < N} @-}
+
+chunksOf :: Int -> [a] -> [[a]]
+chunksOf = undefined
+
+{-@ assumeIndices :: t:ByteStringNE -> s:BS.ByteString -> [OkPos t s] @-}
+assumeIndices :: BS.ByteString -> BS.ByteString -> [Int]
+assumeIndices = undefined
diff --git a/tests/pos/kmp.hs b/tests/pos/kmp.hs
--- a/tests/pos/kmp.hs
+++ b/tests/pos/kmp.hs
@@ -61,14 +61,14 @@
                , aval :: Int -> a
                }
 
-{-@ data Arr a <rng :: Int -> a -> Prop>
+{-@ data Arr a <rng :: Int -> a -> Bool>
       = A { alen :: Nat 
           , aval :: i:Upto alen -> a<rng i>
           }
   @-}
 
 
-{-@ new :: forall <p :: Int -> a -> Prop>.
+{-@ new :: forall <p :: Int -> a -> Bool>.
              n:Nat -> (i:Upto n -> a<p i>) -> {v: Arr<p> a | alen v = n}
   @-}
 new n v = A { alen = n
@@ -77,13 +77,13 @@
                              else liquidError "Out of Bounds!"
             }
 
-{-@ (!) :: forall <p :: Int -> a -> Prop>.
+{-@ (!) :: forall <p :: Int -> a -> Bool>.
              a:Arr<p> a -> i:Upto (alen a) -> a<p i>
   @-}
 
 (A _ f) ! i = f i
   
-{-@ set :: forall <p :: Int -> a -> Prop>.
+{-@ set :: forall <p :: Int -> a -> Bool>.
              a:Arr<p> a -> i:Upto (alen a) -> a<p i> -> {v:Arr<p> a | alen v = alen a}
   @-}
 set a@(A _ f) i v = a { aval = \j -> if (i == j) then v else f j }
diff --git a/tests/pos/kmpIO.hs b/tests/pos/kmpIO.hs
--- a/tests/pos/kmpIO.hs
+++ b/tests/pos/kmpIO.hs
@@ -65,14 +65,14 @@
                  , aval :: Int -> a
                  }
 
-{-@ data Arr a <p :: Int -> a -> Prop>
+{-@ data Arr a <p :: Int -> a -> Bool>
              = A { alen :: Nat
                  , aval :: i:Upto alen -> a<p i>
                  }
   @-}
 
 
-{-@ new :: forall <p :: Int -> a -> Prop>.
+{-@ new :: forall <p :: Int -> a -> Bool>.
              n:Nat -> (i:Upto n -> a<p i>) -> {v: Arr<p> a | alen v = n}
   @-}
 new n v = A { alen = n
@@ -81,13 +81,13 @@
                              else liquidError "Out of Bounds!"
             }
 
-{-@ (!) :: forall <p :: Int -> a -> Prop>.
+{-@ (!) :: forall <p :: Int -> a -> Bool>.
              a:Arr<p> a -> i:Upto (alen a) -> a<p i>
   @-}
 
 (A _ f) ! i = f i
 
-{-@ set :: forall <p :: Int -> a -> Prop>.
+{-@ set :: forall <p :: Int -> a -> Bool>.
              a:Arr<p> a -> i:Upto (alen a) -> a<p i> -> {v:Arr<p> a | alen v = alen a}
   @-}
 set a@(A _ f) i v = a { aval = \j -> if (i == j) then v else f j }
@@ -113,26 +113,26 @@
                    , pntr :: IORef (Arr a)
                    }
 
-{-@ data IOArr a <p :: Int -> a -> Prop>
+{-@ data IOArr a <p :: Int -> a -> Bool>
       = IOA { size :: Nat
             , pntr :: IORef ({v:Arr<p> a | alen v = size})
             }
   @-}
 
 
-{-@ newIO :: forall <p :: Int -> a -> Prop>.
+{-@ newIO :: forall <p :: Int -> a -> Bool>.
                n:Nat -> (i:Upto n -> a<p i>) -> IO ({v: IOArr<p> a | size v = n})
   @-}
 newIO n f = IOA n <$> newIORef (new n f)
 
-{-@ getIO :: forall <p :: Int -> a -> Prop>.
+{-@ getIO :: forall <p :: Int -> a -> Bool>.
               a:IOArr<p> a -> i:Upto (size a) -> IO (a<p i>)
   @-}
 getIO a@(IOA sz p) i
   = do arr   <- readIORef p
        return $ (arr ! i)
 
-{-@ setIO :: forall <p :: Int -> a -> Prop>.
+{-@ setIO :: forall <p :: Int -> a -> Bool>.
               a:IOArr<p> a -> i:Upto (size a) -> a<p i> -> IO ()
   @-}
 setIO a@(IOA sz p) i v
diff --git a/tests/pos/lex.hs b/tests/pos/lex.hs
--- a/tests/pos/lex.hs
+++ b/tests/pos/lex.hs
@@ -3,7 +3,7 @@
 
 bar = foo [1, 2, 3] [2, 3, 4]
 
-{-@ Decrease foo 1 2 @-}
+{-@ decrease foo 1 2 @-}
 foo xs    (y:ys) = foo xs ys
 foo (x:xs) ys    = foo xs ys
 foo xs     ys    = xs
diff --git a/tests/pos/listAnf.hs b/tests/pos/listAnf.hs
--- a/tests/pos/listAnf.hs
+++ b/tests/pos/listAnf.hs
@@ -3,7 +3,7 @@
 import Language.Haskell.Liquid.Prelude
 
 {-@  
-data List [llen] a <p :: x0:a -> x1:a -> Prop>  
+data List [llen] a <p :: x0:a -> x1:a -> Bool>  
   = Nil 
   | Cons (h :: a) (t :: List <p> (a <p h>))
 @-}
diff --git a/tests/pos/listSet.hs b/tests/pos/listSet.hs
--- a/tests/pos/listSet.hs
+++ b/tests/pos/listSet.hs
@@ -23,7 +23,7 @@
 -- Note that the reverse uses the tail-recursive helper @go@. 
 -- Mouse over and see what type is inferred for it!
 
-{-@ Decrease go 2 @-}
+{-@ decrease go 2 @-}
 {-@ myrev :: xs:[a] -> {v:[a]| listElts(v) = listElts(xs)} @-}
 myrev :: [a] -> [a]
 myrev = go [] 
diff --git a/tests/pos/listSetDemo.hs b/tests/pos/listSetDemo.hs
--- a/tests/pos/listSetDemo.hs
+++ b/tests/pos/listSetDemo.hs
@@ -32,7 +32,7 @@
 -- Note that the reverse uses the tail-recursive helper @go@. 
 -- Mouse over and see what type is inferred for it!
 
-{-@ Decrease go 2 @-}
+{-@ decrease go 2 @-}
 {-@ myrev :: xs:[a] -> {v:[a]| (elts v) = (elts xs)} @-}
 myrev = go [] 
   where 
diff --git a/tests/pos/lit00.hs b/tests/pos/lit00.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/lit00.hs
@@ -0,0 +1,19 @@
+module Nats where
+
+import Language.Haskell.Liquid.Prelude 
+
+poo :: () 
+poo = liquidAssert (zero /= one) ()
+
+data Peano = Z | O deriving (Eq)
+
+bob :: String 
+bob = "I am a cat"
+
+{-@ axiomatize one @-}
+one :: Peano 
+one = O 
+
+{-@ axiomatize zero @-}
+zero :: Peano
+zero = Z
diff --git a/tests/pos/lit02.hs b/tests/pos/lit02.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/lit02.hs
@@ -0,0 +1,19 @@
+module Goo where 
+
+import Data.Set as S 
+
+{-@ predicate ValidMovieScheme V =
+	  ((listElts V == Set_cup (Set_sng "year")
+	  	                      (Set_cup (Set_sng "star")
+	  	                      (Set_cup (Set_sng "director")
+	  	                               (Set_sng "title"))))) @-}
+
+{-@ foo :: xs:[String] -> {ys: [String] | Set_sub (listElts xs) (listElts ys)} -> Int @-}
+foo :: [String] -> [String] -> Int 
+foo = undefined
+
+{-@ assume things :: {v:[String] | ValidMovieScheme v} @-}
+things :: [String] 
+things = undefined 
+
+bar = foo ["director"] things 
diff --git a/tests/pos/malformed0.hs b/tests/pos/malformed0.hs
--- a/tests/pos/malformed0.hs
+++ b/tests/pos/malformed0.hs
@@ -2,8 +2,8 @@
 
 module List () where
 
-{-@ Decrease go 3 4 5 @-}
-{-@ Decrease perms 4 5 6 @-}
+{-@ decrease go 3 4 5 @-}
+{-@ decrease perms 4 5 6 @-}
 
 {-@ foo :: xs:[a] -> ys:[a] -> {v:Int| v = (len xs)- (len ys)} -> Int @-}
 foo :: [a] -> [a] -> Int -> Int
diff --git a/tests/pos/mapreduce-bare.hs b/tests/pos/mapreduce-bare.hs
--- a/tests/pos/mapreduce-bare.hs
+++ b/tests/pos/mapreduce-bare.hs
@@ -29,7 +29,7 @@
 insert key value (kv:kvs)
   = kv : insert key value kvs  
 
-{-@ Decrease findWithDefault 3 @-}
+{-@ decrease findWithDefault 3 @-}
 findWithDefault r _ ([]) 
   = r
 findWithDefault r k ((key,value):_) 
diff --git a/tests/pos/mapreduce.hs b/tests/pos/mapreduce.hs
--- a/tests/pos/mapreduce.hs
+++ b/tests/pos/mapreduce.hs
@@ -1,53 +1,140 @@
-module Meas () where
+{-@ LIQUID "--higherorder"       @-}
+{-@ LIQUID "--totality"          @-}
+{-@ LIQUID "--exactdc"           @-}
+{-@ LIQUID "--no-measure-fields" @-}
+{-@ LIQUID "--eliminate=all"     @-}
 
-import Language.Haskell.Liquid.Prelude
-import qualified Data.Map
-import Data.List (foldl')
 
-----------------------------------------------------------------
---- Step 1: Map each element into key-value list (concatMap) ---
-----------------------------------------------------------------
+module DivideAndQunquer where
 
-expand          :: (a -> [(k,v)]) -> [a] -> [(k, v)]
-expand f []     = []
-expand f (x:xs) = (f x) ++ (expand f xs)
+import Prelude hiding (error, map, take, drop)
+import Language.Haskell.Liquid.ProofCombinators
 
-----------------------------------------------------------------
---- Step 2: Group By Key ---------------------------------------
-----------------------------------------------------------------
+{-@ reflect mapReduce @-}
+mapReduce :: Int -> (List a -> b) -> (b -> b -> b) -> List a -> b
+mapReduce n f op N  = f N
+mapReduce n f op is = reduce op (map f (chunk n is))
 
-group   :: (Ord k) => [(k, v)] -> Data.Map.Map k [v]
-group   = foldl' addKV  Data.Map.empty
-  
-addKV m (k, v) = Data.Map.insert k vs' m
-  where 
-    vs' = v : (Data.Map.findWithDefault [] k m)
+chunk  :: Int -> List a -> List (List a)
+map    :: (a -> b) -> List a -> List b
+reduce :: (b -> b -> b) -> List b -> b
 
---------------------------------------------------------------------
---- Step 3: Group By Key -------------------------------------------
---------------------------------------------------------------------
+{-@ mapReduceTheorem :: n:Int -> f:(List a -> b) -> op:(b -> b -> b) -> is:List a
+      -> distributionThm:(is1:List a -> is2:List a -> {op (f is1) (f is2) == f (append is1 is2)} ) ->
+      { f is == mapReduce n f op is } / [llen is] @-}
+mapReduceTheorem :: Int -> (List a -> b) -> (b -> b -> b) -> List a -> (List a -> List a -> Proof)  -> Proof
+mapReduceTheorem n f op N _
+  =   mapReduce n f op N
+  ==. f N
+  *** QED
 
-collapse f                = Data.Map.foldrWithKey reduceKV []
-  where 
-    reduceKV k (v:vs) acc = let b = liquidAssertB False in (k, foldl' f v vs) : acc
-    reduceKV k []     _   = crash False --error $ show (liquidAssertB False)
+mapReduceTheorem n f op is _
+  | llen is <= n || n <= 1
+  =   mapReduce n f op is
+  ==. reduce op (map f (chunk n is))
+  ==. reduce op (map f (C is N))
+  ==. reduce op (f is `C` map f N)
+  ==. reduce op (f is `C` N)
+  ==. f is
+  *** QED
 
---------------------------------------------------------------------
---- Putting it All Together ----------------------------------------
---------------------------------------------------------------------
+mapReduceTheorem n f op is distributionThm
+  = undefined
+{-  =   mapReduce n f op is
+  ==. reduce op (map f (chunk n is))
+  ==. reduce op (map f (C (take n is) (chunk n (drop n is))))
+  ==. reduce op (f (take n is) `C` map f (chunk n (drop n is)))
+  ==. op (f (take n is)) (reduce op (map f (chunk n (drop n is))))
+  ==. op (f (take n is)) (mapReduce n f op (drop n is))
+  ==. op (f (take n is)) (f (drop n is))
+        ? mapReduceTheorem n f op (drop n is) distributionThm
+  ==. f (append (take n is) (drop n is))
+        ? distributionThm (take n is) (drop n is)
+  ==. f is
+        ? appendTakeDrop n is
+  *** QED
+ -}
+-------------------------------------------------------------------------------
+-----------  List Definition --------------------------------------------------
+-------------------------------------------------------------------------------
 
-mapReduce mapper reducer = collapse reducer . group . expand mapper 
 
---------------------------------------------------------------------
---- "Word Count" ---------------------------------------------------
---------------------------------------------------------------------
+{-@ data List [llen] a = N | C {lhead :: a, ltail :: List a} @-}
+data List a = N | C a (List a)
 
-wordCount  = mapReduce fm plus 
-  where fm = \doc -> [ (w,1) | w <- words doc]
+llen :: List a -> Int
+{-@ measure llen @-}
+{-@ llen :: List a -> Nat @-}
+llen N        = 0
+llen (C _ xs) = 1 + llen xs
 
-main = putStrLn $ show $ wordCount docs
-  where docs = [ "this is the end"
-               , "go to the end"
-               , "the end is the beginning"]
- 
+-------------------------------------------------------------------------------
+-----------  List Manipulation ------------------------------------------------
+-------------------------------------------------------------------------------
+{-@ reflect map @-}
+{-@ map :: (a -> b) -> xs:List a -> {v:List b | llen v == llen xs } @-}
+map _  N       = N
+map f (C x xs) = f x `C` map f xs
 
+{-@ reflect append @-}
+append :: List a -> List a -> List a
+append N        ys = ys
+append (C x xs) ys = x `C` (append xs ys)
+
+{-@ reflect reduce @-}
+{-@ reduce :: (b -> b -> b) -> is:{List b | 1 <= llen is } -> b @-}
+reduce _  (C x N)  = x
+reduce op (C x xs) = op x (reduce op xs)
+
+{-@ reflect chunk @-}
+{-@ chunk :: i:Int -> xs:List a -> {v:List (List a) | (1 <= llen v) &&  (if (i <= 1 || llen xs <= i) then (llen v == 1) else (llen v < llen xs)) } / [llen xs] @-}
+chunk i xs
+  | i <= 1
+  = C xs N
+  | llen xs <= i
+  = C xs N
+  | otherwise
+  = C (take i xs) (chunk i (drop i xs))
+
+{-@ reflect drop @-}
+{-@ drop :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == llen xs - i } @-}
+drop :: Int -> List a -> List a
+drop i N = N
+drop i (C x xs)
+  | i == 0
+  = C x xs
+  | otherwise
+  = drop (i-1) xs
+
+{-@ reflect take @-}
+{-@ take :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == i} @-}
+take :: Int -> List a -> List a
+take i N = N
+take i (C x xs)
+  | i == 0
+  = N
+  | otherwise
+  = C x (take (i-1) xs)
+
+-- | Helper Theorem
+{-@ appendTakeDrop :: i:Nat -> xs:{List a | i <= llen xs}
+  -> {xs == append (take i xs) (drop i xs) }  @-}
+
+appendTakeDrop :: Int -> List a -> Proof
+appendTakeDrop i N
+  =   append (take i N) (drop i N)
+  ==. append N N
+  ==. N
+  *** QED
+appendTakeDrop i (C x xs)
+  | i == 0
+  =   append (take 0 (C x xs)) (drop 0 (C x xs))
+  ==. append N (C x xs)
+  ==. C x xs
+  *** QED
+  | otherwise
+  =   append (take i (C x xs)) (drop i (C x xs))
+  ==. append (C x (take (i-1) xs)) (drop (i-1) xs)
+  ==. C x (append (take (i-1) xs) (drop (i-1) xs))
+  ==. C x xs ? appendTakeDrop (i-1) xs
+  *** QED
diff --git a/tests/pos/maybe0.hs b/tests/pos/maybe0.hs
--- a/tests/pos/maybe0.hs
+++ b/tests/pos/maybe0.hs
@@ -7,7 +7,7 @@
 foo (Just x)  = x 
 foo (Nothing) = error "foo"
 
-{-@ bar :: x:Maybe a -> {v:Bool | ((isJust(x)) <=> Prop(v)) } @-}
+{-@ bar :: x:Maybe a -> {v:Bool | v <=> isJust x } @-}
 bar (Just x)  = True 
 bar (Nothing) = False
 
diff --git a/tests/pos/maybe000.hs b/tests/pos/maybe000.hs
--- a/tests/pos/maybe000.hs
+++ b/tests/pos/maybe000.hs
@@ -6,7 +6,7 @@
 data MaybeS a = NothingS | JustS !a
 -- (SAFE) data MaybeS a = NothingS | JustS a
 
-{-@ measure isJustS :: forall a. MaybeS a -> Prop 
+{-@ measure isJustS :: forall a. MaybeS a -> Bool 
     isJustS (JustS x)  = true
     isJustS (NothingS) = false
   @-}
diff --git a/tests/pos/maybe1.hs b/tests/pos/maybe1.hs
--- a/tests/pos/maybe1.hs
+++ b/tests/pos/maybe1.hs
@@ -2,7 +2,7 @@
 
 data MaybeS a = NothingS | JustS !a
 
-{-@ measure isJustS :: forall a. MaybeS a -> Prop
+{-@ measure isJustS :: forall a. MaybeS a -> Bool
     isJustS (JustS x)  = true
     isJustS (NothingS) = false
   @-}
diff --git a/tests/pos/maybe2.hs b/tests/pos/maybe2.hs
--- a/tests/pos/maybe2.hs
+++ b/tests/pos/maybe2.hs
@@ -8,7 +8,7 @@
 data MaybeS a = NothingS | JustS !a
 
 {-@ 
-  data Map [mlen] k a <l :: root:k -> k -> Prop, r :: root:k -> k -> Prop>
+  data Map [mlen] k a <l :: root:k -> k -> Bool, r :: root:k -> k -> Bool>
        = Bin (sz    :: Size) 
              (key   :: k) 
              (value :: a) 
@@ -24,7 +24,7 @@
 
 {-@ invariant {v:Map k a | (mlen v) >=0} @-}
 
-{-@ measure isJustS :: forall a. MaybeS a -> Prop 
+{-@ measure isJustS :: forall a. MaybeS a -> Bool 
     isJustS (JustS x)  = true
     isJustS (NothingS) = false
   @-}
@@ -35,12 +35,12 @@
 
 {-@ type OMap k a = Map <{\root v -> v < root}, {\root v -> v > root}> k a @-}
 
-{-@ measure isBin :: Map k a -> Prop
+{-@ measure isBin :: Map k a -> Bool
     isBin (Bin sz kx x l r) = true
     isBin (Tip)             = false
   @-}
 
-{-@ isRoot :: t:Map k a -> {v: Bool | (Prop(v) <=> isBin(t))} @-}
+{-@ isRoot :: t:Map k a -> {v: Bool | v <=> isBin t} @-}
 isRoot (Bin _ _ _ _ _) = True
 isRoot (Tip)           = False
 
diff --git a/tests/pos/meas10.hs b/tests/pos/meas10.hs
--- a/tests/pos/meas10.hs
+++ b/tests/pos/meas10.hs
@@ -7,7 +7,7 @@
 {-@ myrev :: xs:[a] -> {v:[a]| listElts(v) = listElts(xs)} @-}
 myrev :: [a] -> [a]
 myrev xs = go [] xs 
-{-@ Decrease go 2 @-}
+{-@ decrease go 2 @-}
    where go acc []     = acc
          go acc (y:ys) = go (y:acc) ys
 
diff --git a/tests/pos/meas5.hs b/tests/pos/meas5.hs
--- a/tests/pos/meas5.hs
+++ b/tests/pos/meas5.hs
@@ -12,7 +12,7 @@
 mymap f []     = []
 mymap f (x:xs) = (f x) : (mymap f xs)
 
-{-@ Decrease go 2 @-}
+{-@ decrease go 2 @-}
 myreverse = go []
   where go acc (x:xs) = go (x:acc) xs
         go acc []     = acc
diff --git a/tests/pos/meas9.hs b/tests/pos/meas9.hs
--- a/tests/pos/meas9.hs
+++ b/tests/pos/meas9.hs
@@ -14,7 +14,7 @@
 {-@ myrev :: xs:[a] -> {v:[a]| listElts(v) = listElts(xs)} @-}
 myrev :: [a] -> [a]
 myrev = go [] 
-        {-@ Decrease go 2 @-}
+        {-@ decrease go 2 @-}
   where go acc []     = acc
         go acc (y:ys) = go (y:acc) ys
 
diff --git a/tests/pos/multi-pred-app-00.hs b/tests/pos/multi-pred-app-00.hs
--- a/tests/pos/multi-pred-app-00.hs
+++ b/tests/pos/multi-pred-app-00.hs
@@ -1,6 +1,6 @@
 module Blank () where
 
-{-@ foo :: forall < p :: Int -> Prop
-                  , q :: Int -> Prop >. Int<p,q> -> Int<p> @-}
+{-@ foo :: forall < p :: Int -> Bool
+                  , q :: Int -> Bool >. Int<p,q> -> Int<p> @-}
 foo :: Int -> Int
 foo x = x
diff --git a/tests/pos/mutrec.hs b/tests/pos/mutrec.hs
--- a/tests/pos/mutrec.hs
+++ b/tests/pos/mutrec.hs
@@ -1,12 +1,12 @@
 module MutRec () where
 
 {-@ isEven :: Nat -> {v:Int | v = 0} -> Bool @-}
-{-@ Decrease isEven 1 2 @-}
+{-@ decrease isEven 1 2 @-}
 isEven :: Int -> Int -> Bool
 isEven 0 _ = True
 isEven n _ = isOdd (n-1) 1
 
 {-@ isOdd :: Nat -> {v:Int | v = 1} -> Bool @-}
-{-@ Decrease isOdd 1 2 @-}
+{-@ decrease isOdd 1 2 @-}
 isOdd :: Int -> Int -> Bool
 isOdd  n _ = not $ isEven n 0
diff --git a/tests/pos/niki.hs b/tests/pos/niki.hs
--- a/tests/pos/niki.hs
+++ b/tests/pos/niki.hs
@@ -2,7 +2,7 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ data Pair a b <p :: x0:a -> x1:b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: x0:a -> x1:b -> Bool> = P (x :: a) (y :: b<p x>) @-} 
 data Pair a b = P a b
 
 bar = P (0::Int) (1::Int)
diff --git a/tests/pos/niki1.hs b/tests/pos/niki1.hs
--- a/tests/pos/niki1.hs
+++ b/tests/pos/niki1.hs
@@ -2,7 +2,7 @@
 
 import Language.Haskell.Liquid.Prelude
 
-{-@ data Pair a b <p :: x0:a -> x1:b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: x0:a -> x1:b -> Bool> = P (x :: a) (y :: b<p x>) @-} 
 data Pair a b = P a b
 
 incr :: Int -> Int
diff --git a/tests/pos/pair.hs b/tests/pos/pair.hs
--- a/tests/pos/pair.hs
+++ b/tests/pos/pair.hs
@@ -2,7 +2,7 @@
 
 import Language.Haskell.Liquid.Prelude 
 
-{-@ data Pair a b <p :: x0:a -> x1:b -> Prop> = P (x :: a) (y :: b<p x>) @-} 
+{-@ data Pair a b <p :: x0:a -> x1:b -> Bool> = P (x :: a) (y :: b<p x>) @-} 
 data Pair a b = P a b
 
 incr x = let p = P x ((x+1)) in p
diff --git a/tests/pos/pair00.hs b/tests/pos/pair00.hs
--- a/tests/pos/pair00.hs
+++ b/tests/pos/pair00.hs
@@ -1,28 +1,25 @@
 module Pair () where
 
 {-@ LIQUID "--no-termination" @-}
-import Language.Haskell.Liquid.Prelude
 
-incr z = (x, [x + 1])
-  where
-    x  = choose z
+import Language.Haskell.Liquid.Prelude
 
 incr z = (x, [x + 1])
   where
     x  = choose z
-
 chk (x, [y]) = liquidAssertB (x < y)
-
 prop  = chk $ incr n
   where
     n = choose 0
 
-incr2 x = (True, 9, x, 'o', x+1)
-chk2 (_, _, x, _,  y) = liquidAssertB (x <y)
-prop2  = chk2 $ incr2 n
-  where n = choose 0
+incr2 pig = (True, 9, pig, 'o', pig + 1)
 
+chk2 (_, _, cow, _,  dog) = liquidAssertB (cow < dog)
+
+prop2  = chk2 $ incr2 mouse
+  where mouse = choose 0
+
 incr3 x = (x, ( (0, x+1)))
-chk3 (x, ((_, y))) = liquidAssertB (x <y)
+chk3 (x, ((_, y))) = liquidAssertB (x < y)
 prop3  = chk3 (incr3 n)
-  where n = choose 0
+ where n = choose 0
diff --git a/tests/pos/pargs.hs b/tests/pos/pargs.hs
--- a/tests/pos/pargs.hs
+++ b/tests/pos/pargs.hs
@@ -1,6 +1,6 @@
 module Foo () where
 
-{-@ foo :: forall a <p :: x0:Int -> x1:a -> Prop>. 
+{-@ foo :: forall a <p :: x0:Int -> x1:a -> Bool>. 
              (i:Int -> a<p i>) -> {v:Int| v=0}
               -> a <p 0>
   @-}
diff --git a/tests/pos/pargs1.hs b/tests/pos/pargs1.hs
--- a/tests/pos/pargs1.hs
+++ b/tests/pos/pargs1.hs
@@ -1,6 +1,7 @@
+{-@ LIQUID "--pruneunsorted" @-}
 module Foo () where
 
-{-@ foo :: forall a <p :: x0:Int -> x1:a -> Prop>. 
+{-@ foo :: forall a <p :: x0:Int -> x1:a -> Bool>. 
              (i:Int  -> j : Int-> a<p (i+j)>) -> 
                ii:Int -> jj:Int
               -> a <p (ii+jj)>
diff --git a/tests/pos/propmeasure.hs b/tests/pos/propmeasure.hs
--- a/tests/pos/propmeasure.hs
+++ b/tests/pos/propmeasure.hs
@@ -1,7 +1,7 @@
 {-@ LIQUID "--totality" @-}
 {-# LANGUAGE EmptyDataDecls #-}
 
-module PropMeasure where
+module BoolMeasure where
 
 import Prelude hiding (length)
 
@@ -43,7 +43,7 @@
 
 {-@ measure length @-}
 
-{-@ foo  :: x:[a] -> {v: Bool | (Prop v) <=> (nonEmpty x) } @-}
+{-@ foo  :: x:[a] -> {v: Bool | v <=> (nonEmpty x) } @-}
 foo  :: [a] -> Bool
 foo x = nonEmpty x
 
diff --git a/tests/pos/propmeasure1.hs b/tests/pos/propmeasure1.hs
--- a/tests/pos/propmeasure1.hs
+++ b/tests/pos/propmeasure1.hs
@@ -1,4 +1,4 @@
-module PropMeasure where
+module BoolMeasure where
 
 nil  = []
 
diff --git a/tests/pos/range.hs b/tests/pos/range.hs
--- a/tests/pos/range.hs
+++ b/tests/pos/range.hs
@@ -15,7 +15,7 @@
 
 sumTo = foldl (+) 0 . range 0 
 
-{-@ Decrease lgo 2 @-}
+{-@ decrease lgo 2 @-}
 --myfoldl :: (Int -> Int -> Int) -> Int -> [Int] -> Int
 myfoldl f z0 xs0 = lgo z0 xs0
              where
diff --git a/tests/pos/rec_annot_go.hs b/tests/pos/rec_annot_go.hs
--- a/tests/pos/rec_annot_go.hs
+++ b/tests/pos/rec_annot_go.hs
@@ -6,7 +6,7 @@
 
 {-@ invariant {v:Int | v >= 0} @-}
 
-{-@ Decrease go 1 @-}
+{-@ decrease go 1 @-}
 loop :: Int -> Int -> a -> (Int -> a -> a) -> a 
 loop lo hi base f = go (hi-lo) base lo
   where
diff --git a/tests/pos/record1.hs b/tests/pos/record1.hs
--- a/tests/pos/record1.hs
+++ b/tests/pos/record1.hs
@@ -2,11 +2,11 @@
 
 data Map k a  = Tip
 
-{-@ data Map k a <l :: root:k -> k -> Prop>
+{-@ data Map k a <l :: root:k -> k -> Bool>
          = Tip
   @-}
 
-{-@ measure isBin :: Map k a -> Prop
+{-@ measure isBin :: Map k a -> Bool
     isBin (Tip)          = false
   @-}
 
diff --git a/tests/pos/reflect0.hs b/tests/pos/reflect0.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/reflect0.hs
@@ -0,0 +1,17 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+
+module FunctionAbstraction where
+
+{-@ fib :: n:Nat -> Nat @-}
+{-@ reflect fib @-}
+fib :: Int -> Int
+fib n
+  | n == 0    = 0
+  | n == 1    = 1
+  | otherwise = fib (n-1) + fib (n-2)
+
+
+{-@ goo :: Nat -> Nat @-}
+goo :: Int -> Int
+goo x = fib x
diff --git a/tests/pos/repeatHigherOrder.hs b/tests/pos/repeatHigherOrder.hs
--- a/tests/pos/repeatHigherOrder.hs
+++ b/tests/pos/repeatHigherOrder.hs
@@ -12,7 +12,7 @@
 step :: (a -> a -> Bool) -> (Int -> a -> Bool) -> Int -> a -> a -> Bool
 step pf pr = \ i x x' -> pr (i - 1) x ==> pf x x' ==> pr i x'
 
-{-@ repeat :: forall a <f :: a -> a -> Prop, r :: Int -> a -> Prop>.
+{-@ repeat :: forall a <f :: a -> a -> Bool, r :: Int -> a -> Bool>.
                 (Step a f r) =>
                  n:Nat -> (y:a -> a<f y>) -> a<r 0> -> a<r n>
   @-}
diff --git a/tests/pos/rta.hs b/tests/pos/rta.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/rta.hs
@@ -0,0 +1,19 @@
+module RTA where
+
+{-@ predicate Mouse X Y = X > Y @-}
+
+{-@ inline mickey @-}
+mickey :: (Ord a) => a -> a -> Bool
+mickey x y = x > y
+
+{-@ type PosInline    a N = {v:a | mickey v N} @-}
+
+{-@ type PosPredicate a N = {v:a | Mouse v N} @-}
+
+{-@ incrI :: PosInline Int 0 -> PosInline Int 0 @-}
+incrI :: Int -> Int
+incrI x = x + 1
+
+{-@ incrP :: PosPredicate Int 0 -> PosPredicate Int 0 @-}
+incrP :: Int -> Int
+incrP x = x + 1
diff --git a/tests/pos/sf/Basics.hs b/tests/pos/sf/Basics.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/sf/Basics.hs
@@ -0,0 +1,390 @@
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--higherorder"                         @-}
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+{- NOTE:
+
+   1. See the TODO:trivial for cases where the instances seems to fail
+
+   2. Would be nice to have case-splitting combinatores,
+      e.g. for thmAndbCom,  thmAndbExch which are super boilerplate-y
+
+   3. For @minsheng: See the rewritten signature for `thmEqBeq`;
+      we don't really need `rewrite` as the SMT
+      does "congruence closure" automatically.
+
+ -}
+
+module Basics where
+
+  -- (
+    -- -- * Booleans
+    -- Bool(..)
+  -- , negb, andb, orb
+--
+    -- -- * Peano numerals
+  -- , Peano(..), toNat
+  -- , plus, mult
+  -- , beq, ble, blt
+  -- )
+  -- where
+
+import           Prelude (Char, Int)
+import qualified Prelude
+import           Language.Haskell.Liquid.ProofCombinators
+
+{-@ reflect incr @-}
+incr :: Int -> Int
+incr x = x Prelude.+ 1
+
+--------------------------------------------------------------------------------
+-- | Days ----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+-- NOTE: clunky to have to redefine this ...
+
+{-@ data Day = Monday
+             | Tuesday
+             | Wednesday
+             | Thursday
+             | Friday
+             | Saturday
+             | Sunday
+  @-}
+
+data Day = Monday
+         | Tuesday
+         | Wednesday
+         | Thursday
+         | Friday
+         | Saturday
+         | Sunday
+
+{-@ reflect nextWeekDay @-}
+nextWeekDay :: Day -> Day
+nextWeekDay Monday    = Tuesday
+nextWeekDay Tuesday   = Wednesday
+nextWeekDay Wednesday = Thursday
+nextWeekDay Thursday  = Friday
+nextWeekDay Friday    = Monday
+nextWeekDay Saturday  = Monday
+nextWeekDay Sunday    = Monday
+
+
+{-@ testNextWeekDay :: { nextWeekDay (nextWeekDay Saturday) == Tuesday } @-}
+testNextWeekDay
+  = trivial
+-- = nextWeekDay (nextWeekDay Saturday) ==. Tuesday *** QED
+
+
+
+--------------------------------------------------------------------------------
+-- | Booleans ------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+{-@ data Bool = True | False @-}
+data Bool = True | False
+
+{-@ reflect negb @-}
+negb :: Bool -> Bool
+negb True  = False
+negb False = True
+
+{-@ reflect orb @-}
+orb :: Bool -> Bool -> Bool
+orb False False = False
+orb _     _     = True
+
+{-@ testOr1 :: { orb True True == True } @-}
+testOr1 = trivial -- orb True True *** QED
+
+{-@ testOr2 :: { orb True False == True } @-}
+testOr2 = trivial -- orb True False *** QED
+
+{-@ testOr3 :: { orb False True == True } @-}
+testOr3 = trivial -- orb False True *** QED
+
+{-@ testOr4 :: { orb False False == False } @-}
+testOr4 = trivial -- orb False False *** QED
+
+{-@ reflect andb @-}
+andb :: Bool -> Bool -> Bool
+andb True True = True
+andb _    _    = False
+
+{-@ andbCom :: a:_ -> b:_ -> { andb a b = andb b a } @-}
+andbCom :: Bool -> Bool -> Proof
+andbCom a b = trivial
+
+-- Exercise 1 ------------------------------------------------------------------
+
+{-@ reflect nandb @-}
+nandb :: Bool -> Bool -> Bool
+nandb a b = negb (andb a b)
+
+{-@ testNand1 :: { nandb True True == False }  @-}
+testNand1 = trivial
+
+{-@ testNand2 :: { nandb True False == True }  @-}
+testNand2 = trivial
+
+{-@ testNand3 :: { nandb False True == True }  @-}
+testNand3 = trivial
+
+{-@ testNand4 :: { nandb False False == True } @-}
+testNand4 = trivial
+
+-- Exercise 2 ------------------------------------------------------------------
+
+{-@ reflect andb3 @-}
+andb3 :: Bool -> Bool -> Bool -> Bool
+andb3 a b c = andb (andb a b) c
+
+{-@ testAnd31 :: { andb3 True True True == True }  @-}
+testAnd31 = trivial
+
+{-@ testAnd32 :: { andb3 False True True == False }  @-}
+testAnd32 = trivial
+
+{-@ testAnd33 :: { andb3 True False True == False }  @-}
+testAnd33 = trivial
+
+{-@ testAnd34 :: { andb3 True True False == False }  @-}
+testAnd34 = trivial
+
+--------------------------------------------------------------------------------
+-- | Peano ---------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+{-@ data Peano [toNat] = O | S Peano @-}
+data Peano = O | S Peano
+
+{-@ measure toNat @-}
+{-@ toNat :: Peano -> Nat @-}
+toNat :: Peano -> Int
+toNat O     = 0
+toNat (S n) = 1 Prelude.+ toNat n
+
+{-@ reflect even @-}
+even :: Peano -> Bool
+even O         = True
+even (S O)     = False
+even (S (S n)) = even n
+
+{-@ test_Even0 :: { even O == True } @-}
+test_Even0 :: Proof
+test_Even0 = trivial
+
+-- LH ISSUE #995
+{-@ test_Even4 :: { even (S (S (S (S O)))) == True } @-}
+test_Even4 :: Proof
+test_Even4
+  =   even (S (S (S (S O))))
+  ==. even (S (S O))
+  ==. even O
+  ==. True
+  *** QED
+
+{-@ test_Even5 :: { even (S (S (S (S (S O))))) = False } @-}
+test_Even5 :: Proof
+test_Even5
+  =   even (S (S (S (S (S O)))))
+  ==. even (((S (S (S O)))))
+  ==. even (((((S O)))))
+  ==. False
+  *** QED
+
+-- | Plus & Mult ---------------------------------------------------------------
+
+{-@ reflect plus @-}
+plus :: Peano -> Peano -> Peano
+plus O     n = n
+plus (S m) n = S (plus m n)
+
+{-@ reflect mult @-}
+mult :: Peano -> Peano -> Peano
+mult n m = case n of
+  O    -> O
+  S O  -> m
+  S n' -> plus m (mult n' m)
+
+{- TODO:trivial testPlus1 :: { plus (S (S O)) O == (S (S O)) } @-}
+testPlus1 = trivial
+
+{- TODO:trivial testMult1 :: { mult (S (S O)) (S (S O)) == (S (S (S (S O)))) } @-}
+testMult1 = trivial
+
+-- | Factorial -----------------------------------------------------------------
+
+{-@ reflect factorial @-}
+factorial :: Peano -> Peano
+factorial O     = O
+factorial (S O) = S O
+factorial (S n) = mult (S n) (factorial n)
+
+{- TODO:trivial testFactorial1 :: { factorial (S (S (S O)))  == S (S (S (S (S (S O))))) } @-}
+testFactorial1 = trivial
+
+-- | Peano Comparisons ---------------------------------------------------------
+
+{-@ reflect beq @-}
+beq :: Peano -> Peano -> Bool
+beq O     O     = True
+beq (S m) (S n) = beq m n
+beq _     _     = False
+
+{-@ reflect ble @-}
+ble :: Peano -> Peano -> Bool
+ble O     _     = True
+ble (S m) O     = False
+ble (S m) (S n) = ble m n
+
+{-@ testBle1 :: { ble (S (S O)) (S (S O))  == True } @-} -- TODO:trivial
+testBle1
+  =   ble (S (S O)) (S (S O))
+  ==. ble ((S O)) ((S O))
+  ==. ble O O
+  *** QED
+
+{-@ testBle2 :: { ble (S (S O)) (S (S (S O)))  == True } @-} -- TODO:trivial
+testBle2
+  =   ble (S (S O)) (S (S (S O)))
+  ==. ble (S O) (S (S O))
+  ==. ble O (S O)
+  *** QED
+
+{-@ testBle3 :: { ble  (S (S (S O))) (S (S O)) == False } @-} -- TODO:trivial
+testBle3
+  =   ble (S (S (S O))) (S (S O))
+  ==. ble (S (S O)) (S O)
+  ==. ble (S O) O
+  *** QED
+
+-- | Exercise blt --------------------------------------------------------------
+
+{-@ reflect blt @-}
+blt :: Peano -> Peano -> Bool
+blt O     O     = False
+blt O     (S n) = True
+blt (S m) O     = False
+blt (S m) (S n) = blt m n
+
+{-@ testBlt1 :: { blt (S (S O)) (S (S O))  == False } @-} -- TODO:trivial
+testBlt1
+  =   blt (S (S O)) (S (S O))
+  ==. blt ((S O)) ((S O))
+  ==. blt O O
+  *** QED
+
+{-@ testBlt2 :: { ble (S (S O)) (S (S (S O)))  == True } @-} -- TODO:trivial
+testBlt2
+  =   ble (S (S O)) (S (S (S O)))
+  ==. ble (S O) (S (S O))
+  ==. ble O (S O)
+  *** QED
+
+{-@ testBlt3 :: { ble  (S (S (S O))) (S (S O)) == False } @-} -- TODO:trivial
+testBlt3
+  =   ble (S (S (S O))) (S (S O))
+  ==. ble (S (S O)) (S O)
+  ==. ble (S O) O
+  *** QED
+
+-- | Proof by Simplification ---------------------------------------------------
+
+{-@ thmPlus_O_l :: n:Peano -> { plus O n == n } @-}
+thmPlus_O_l :: Peano -> Proof
+thmPlus_O_l n = trivial
+
+{-@ thmPlus_1_N :: n:Peano -> { plus (S O) n = S n } @-}
+thmPlus_1_N :: Peano -> Proof
+thmPlus_1_N n = trivial
+
+{-@ thmMult_0_l :: n:Peano -> { mult O n = O } @-}
+thmMult_0_l :: Peano -> Proof
+thmMult_0_l n = trivial
+
+-- | Proof by Simplification ---------------------------------------------------
+
+{-@ thmPlusId :: a:Peano -> b:Peano -> { a = b => plus a a = plus b b } @-}
+thmPlusId :: Peano -> Peano -> Proof
+thmPlusId a b = trivial
+
+{-@ thmPlusId' :: n:Peano -> m:Peano -> o:Peano -> { n = m => m = o => plus n m = plus m o } @-}
+thmPlusId' :: Peano -> Peano -> Peano -> Proof
+thmPlusId' n m o = trivial
+
+{-@ thmMultOPlus :: n: Peano -> m: Peano -> { mult (plus O n) m = mult n m } @-}
+thmMultOPlus :: Peano -> Peano -> Proof
+thmMultOPlus n m = trivial
+
+{-@ thmMultS1 :: m:Peano -> n:Peano -> { S n = m => mult m (S n) = mult m m } @-}
+thmMultS1 :: Peano -> Peano -> Proof
+thmMultS1 m n = trivial
+
+-- | Proof by Case Analysis ----------------------------------------------------
+
+{-@ thmPlus1Neq0 :: n:Peano -> { beq (plus n (S O)) O = False } @-}
+thmPlus1Neq0 :: Peano -> Proof
+thmPlus1Neq0 O     = trivial
+thmPlus1Neq0 (S n) = trivial
+
+{-@ thmNegbInvolutive :: b:Bool -> { negb (negb b) == b} @-}
+thmNegbInvolutive :: Bool -> Proof
+thmNegbInvolutive True  = trivial
+thmNegbInvolutive False = trivial
+
+{-@ thmAndbCom :: a:Bool -> b:Bool -> {andb a b == andb b a} @-}
+thmAndbCom True  True  = trivial
+thmAndbCom True  False = trivial
+thmAndbCom False True  = trivial
+thmAndbCom False False = trivial
+
+{-@ thmAndbExch :: a:Bool -> b:Bool -> c:Bool
+                -> { andb (andb a b) c == andb (andb a c) b }
+  @-}
+thmAndbExch :: Bool -> Bool -> Bool -> Proof
+thmAndbExch True  True  True  = trivial
+thmAndbExch True  True  False = trivial
+thmAndbExch True  False True  = trivial
+thmAndbExch True  False False = trivial
+thmAndbExch False True  True  = trivial
+thmAndbExch False True  False = trivial
+thmAndbExch False False True  = trivial
+thmAndbExch False False False = trivial
+
+{-@ thmAndbTrueElim2 :: b:Bool -> c:Bool -> { andb b c = True => c = True } @-} -- TODO:trivial
+thmAndbTrueElim2 :: Bool -> Bool -> Proof
+thmAndbTrueElim2 False False = andb False False *** QED
+thmAndbTrueElim2 False True  = andb False True  *** QED
+thmAndbTrueElim2 True  False = andb True  False *** QED
+thmAndbTrueElim2 True  True  = andb True  True  *** QED
+
+{-@ thm0NeqPlus1 :: n:Peano -> { beq O (plus n (S O)) = False } @-}
+thm0NeqPlus1 :: Peano -> Proof
+thm0NeqPlus1 O     = trivial
+thm0NeqPlus1 (S n) = trivial
+
+
+{-@ thmIdTwice :: f:(x:Bool -> {v:Bool | v = x}) -> b:Bool -> { f (f b) = b } @-}
+thmIdTwice :: (Bool -> Bool) -> Bool -> Proof
+thmIdTwice f b
+  =   f (f b)
+  ==. b
+  *** QED
+
+{-@ thmNegTwice :: f:(x:Bool -> {v:Bool | v = negb x}) -> b:Bool -> { f (f b) = b } @-}
+thmNegTwice :: (Bool -> Bool) -> Bool -> Proof
+thmNegTwice f b
+  =   f (f b)
+  ==. b ? thmNegbInvolutive b
+  *** QED
+
+-- RJ: You can rewrite
+--   (m : Peano) -> (n : Peano) -> (eqProof : m = n) -> (beq m n = True)
+
+{-@ thmEqBeq :: m:Peano -> n:Peano -> { v : Proof |  m = n } -> { beq m n = True } @-}
+thmEqBeq :: Peano -> Peano -> Proof -> Proof
+thmEqBeq O O _         = trivial
+thmEqBeq (S m) (S n) _ = thmEqBeq m n trivial
diff --git a/tests/pos/sf/Induction.hs b/tests/pos/sf/Induction.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/sf/Induction.hs
@@ -0,0 +1,133 @@
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--higherorder"                         @-}
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module Induction where
+
+import           Prelude (Char, Int, Bool(..))
+import qualified Prelude
+
+import Language.Haskell.Liquid.ProofCombinators
+
+{-@ data Peano [toNat] = O | S Peano @-}
+data Peano = O | S Peano
+
+{-@ measure toNat @-}
+{-@ toNat :: Peano -> Nat @-}
+toNat :: Peano -> Int
+toNat O     = 0
+toNat (S n) = 1 Prelude.+ toNat n
+
+{-@ reflect natPlus @-}
+{-@ natPlus :: Peano -> Peano -> Peano @-}
+natPlus :: Peano -> Peano -> Peano
+natPlus O     n = n
+natPlus (S m) n = S (natPlus m n)
+
+{-@ reflect natMult @-}
+{-@ natMult :: Peano -> Peano -> Peano @-}
+natMult :: Peano -> Peano -> Peano
+natMult n m = case n of
+  O    -> O
+  S n' -> natPlus m (natMult n' m)
+
+{-@ theorem_plus_n_O :: n : Peano -> { n == natPlus n O } @-}
+theorem_plus_n_O :: Peano -> Proof
+theorem_plus_n_O O     = ( natPlus O O ) *** QED
+theorem_plus_n_O (S n) = ( natPlus (S n) O
+                         , theorem_plus_n_O n
+                         ) *** QED
+
+{-@ theorem_mult_0_r :: n : Peano -> { natMult n O = O } @-}
+theorem_mult_0_r :: Peano -> Proof
+theorem_mult_0_r O     = natMult O O *** QED
+theorem_mult_0_r (S n) = ( natMult (S n) O
+                         , theorem_mult_0_r n
+                         , natPlus O O
+                         ) *** QED
+
+{-@ theorem_plus_n_Sm :: n : Peano -> m : Peano
+  -> { S (natPlus n m) = natPlus n (S m) }
+@-}
+theorem_plus_n_Sm :: Peano -> Peano -> Proof
+theorem_plus_n_Sm O     m = ( natPlus O m, natPlus O (S m) ) *** QED
+theorem_plus_n_Sm (S n) m = ( natPlus (S n) m
+                            , natPlus (S n) (S m)
+                            , theorem_plus_n_Sm n m
+                            ) *** QED
+
+{-@ theorem_plus_comm :: n : Peano -> m : Peano
+  -> { natPlus n m = natPlus m n }
+@-}
+theorem_plus_comm :: Peano -> Peano -> Proof
+theorem_plus_comm O     m = ( natPlus O m, theorem_plus_n_O m ) *** QED
+theorem_plus_comm (S n) m = ( natPlus (S n) m
+                            , theorem_plus_comm n m
+                            , theorem_plus_n_Sm m n
+                            ) *** QED
+
+{-@ theorem_plus_assoc :: n : Peano -> m : Peano -> p : Peano
+  -> { natPlus n (natPlus m p) = (natPlus (natPlus n m) p) }
+@-}
+theorem_plus_assoc :: Peano -> Peano -> Peano -> Proof
+theorem_plus_assoc O     m p = ( natPlus O (natPlus m p)
+                               , natPlus O m
+                               ) *** QED
+theorem_plus_assoc (S n) m p = ( natPlus (S n) (natPlus m p)
+                               , natPlus (S n) m
+                               , natPlus (S (natPlus n m)) p
+                               , theorem_plus_assoc n m p
+                               ) *** QED
+
+{-@ reflect double @-}
+{-@ double :: Peano -> Peano @-}
+double :: Peano -> Peano
+double O     = O
+double (S n) = S (S (double n))
+
+{-@ theorem_double_plus :: n : Peano -> { double n = natPlus n n } @-}
+theorem_double_plus :: Peano -> Proof
+theorem_double_plus O     = ( double O, natPlus O O ) *** QED
+theorem_double_plus (S n) = ( double (S n)
+                            , theorem_double_plus n
+                            , natPlus (S n) (S n)
+                            , theorem_plus_n_Sm n n
+                            ) *** QED
+
+{-@ theorem_plus_swap :: n : Peano -> m : Peano -> p : Peano
+  -> { natPlus n (natPlus m p) = natPlus m (natPlus n p) }
+@-}
+theorem_plus_swap :: Peano -> Peano -> Peano -> Proof
+theorem_plus_swap n m p = ( theorem_plus_assoc n m p
+                          , theorem_plus_comm n m
+                          , theorem_plus_assoc m n p
+                          ) *** QED
+
+{-@ lemma_mult_distrib_S_n :: m : Peano -> n : Peano
+  -> { natMult m (S n) = natPlus m (natMult m n) }
+@-}
+lemma_mult_distrib_S_n :: Peano -> Peano -> Proof
+lemma_mult_distrib_S_n O     n = ( natMult O (S n)
+                                 , natMult O n
+                                 , natPlus O O
+                                 ) *** QED
+lemma_mult_distrib_S_n (S m) n = ( natMult (S m) (S n)
+                                 , natPlus (S n) (natMult m (S n))
+                                 , natPlus (S m) (natMult (S m) n)
+                                 , natMult (S m) n
+                                 , lemma_mult_distrib_S_n m n
+                                 , theorem_plus_swap n m (natMult m n)
+                                 ) *** QED
+
+{-@ theorem_mult_comm :: m : Peano -> n : Peano
+                      -> { natMult m n = natMult n m }
+@-}
+theorem_mult_comm :: Peano -> Peano -> Proof
+theorem_mult_comm O     n = ( natMult O n
+                            , theorem_mult_0_r n
+                            ) *** QED
+theorem_mult_comm (S m) n = ( natMult (S m) n
+                            , theorem_mult_comm m n
+                            , lemma_mult_distrib_S_n n m
+                            ) *** QED
diff --git a/tests/pos/sf/InductionRJ.hs b/tests/pos/sf/InductionRJ.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/sf/InductionRJ.hs
@@ -0,0 +1,196 @@
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--higherorder"                         @-}
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module Induction where
+
+import qualified Prelude
+import           Prelude (Char, Int, Bool (..))
+import Language.Haskell.Liquid.ProofCombinators
+
+-- TODO:import Basics
+
+{-@ data Peano [toNat] = O | S Peano @-}
+data Peano = O | S Peano
+
+{-@ measure toNat @-}
+{-@ toNat :: Peano -> Nat @-}
+toNat :: Peano -> Int
+toNat O     = 0
+toNat (S n) = 1 Prelude.+ toNat n
+
+{-@ reflect plus @-}
+plus :: Peano -> Peano -> Peano
+plus O     n = n
+plus (S m) n = S (plus m n)
+
+{-@ reflect mult @-}
+mult :: Peano -> Peano -> Peano
+mult n m = case n of
+  O    -> O
+  S n' -> plus m (mult n' m)
+
+{-@ data BBool = BTrue | BFalse @-}
+data BBool = BTrue | BFalse
+
+{-@ reflect negb @-}
+negb :: BBool -> BBool
+negb BTrue  = BFalse
+negb BFalse = BTrue
+
+{-@ reflect even @-}
+even :: Peano -> BBool
+even O         = BTrue
+even (S O)     = BFalse
+even (S (S n)) = even n
+
+--------------------------------------------------------------------------------
+-- | Exercise : basic_induction ------------------------------------------------
+--------------------------------------------------------------------------------
+
+{-@ thmPlusNO :: n:Peano -> { plus n O == n } @-}
+thmPlusNO       :: Peano -> Proof
+thmPlusNO O     = trivial
+thmPlusNO (S n) = thmPlusNO n
+
+{-@ thmMultOR :: n:Peano -> { mult n O == O } @-}
+thmMultOR :: Peano -> Proof
+thmMultOR O     = trivial
+thmMultOR (S n) = thmMultOR n
+
+{-@ thmPlusNSm :: n:Peano -> m:Peano -> {S (plus n m) == plus n (S m)} @-}
+thmPlusNSm :: Peano -> Peano -> Proof
+thmPlusNSm O     m = trivial
+thmPlusNSm (S n) m = thmPlusNSm n m
+
+{-@ thmPlusCom :: n:Peano -> m:Peano -> { plus n m == plus m n} @-}
+thmPlusCom :: Peano -> Peano -> Proof
+thmPlusCom O     m = thmPlusNO m
+thmPlusCom (S n) m = [ thmPlusCom n m, thmPlusNSm m n ] *** QED
+
+{-@ thmPlusAssoc :: a:Peano -> b:Peano -> c:Peano
+                 -> { plus a (plus b c) = (plus (plus a b) c) } @-}
+thmPlusAssoc :: Peano -> Peano -> Peano -> Proof
+thmPlusAssoc O     b c = trivial
+thmPlusAssoc (S a) b c = thmPlusAssoc a b c
+
+{- NOTE:Compare the above to:
+
+{-@ thmPlusAssoc :: a b c : Peano -> { plus a (plus b c) = (plus (plus a b) c)} @-}
+
+  x y z : s -> t
+  x:s -> y:s -> z:s -> t
+
+Theorem plus_assoc' : ∀n m p : nat,
+  n + (m + p) = (n + m) + p.
+Proof. intros n m p. induction n as [| n' IHn']. reflexivity.
+  simpl. rewrite → IHn'. reflexivity. Qed.
+
+Coq is perfectly happy with this. For a human, however, it is difficult to make much sense of it. We can use comments and bullets to show the structure a little more clearly...
+
+Theorem plus_assoc'' : ∀n m p : nat,
+  n + (m + p) = (n + m) + p.
+Proof.
+  intros n m p. induction n as [| n' IHn'].
+  - (* n = 0 *)
+    reflexivity.
+  - (* n = S n' *)
+    simpl. rewrite → IHn'. reflexivity. Qed.
+
+ -}
+
+--------------------------------------------------------------------------------
+-- | Exercise : double_plus ----------------------------------------------------
+--------------------------------------------------------------------------------
+{-@ reflect double @-}
+double :: Peano -> Peano
+double O     = O
+double (S n) = S (S (double n))
+
+{-@ thmDoublePlus :: n:Peano -> { double n == plus n n } @-}
+thmDoublePlus :: Peano -> Proof
+thmDoublePlus O     = trivial
+thmDoublePlus (S n) = [ -- double (S n)
+                        -- ==. S (S (double n)) ?
+                        thmDoublePlus n
+                        -- ==. S (S (plus n n)) ?
+                      , thmPlusNSm n n
+                        -- ==. S (plus n (S n))
+                        -- ==. plus (S n) (S n)
+                      ] *** QED
+
+{-@ thmEvenS :: n:Peano -> { even (S n) == negb (even n) } @-}
+thmEvenS :: Peano -> Proof
+thmEvenS O         = trivial
+thmEvenS (S O)     = trivial
+thmEvenS (S (S n)) = thmEvenS n
+
+                   -- =   negb (even (S (S n)))
+                   -- ==. negb (even n)
+                   -- ==. even (S n)       ? thmEvenS n
+                   -- *** QED
+
+{- NOTE: An interesting example of `trivial`: the following
+
+       Theorem mult_0_plus' : ∀n m : nat,
+         (0 + n) * m = n * m.
+       Proof.
+         intros n m.
+         assert (H: 0 + n = n). { reflexivity. }
+         rewrite → H.
+         reflexivity. Qed.
+
+   is simply trivial.
+
+  -}
+
+{-@ thmMultOPlus :: n:_ -> m:_ -> { mult (plus O n) m = mult n m } @-}
+thmMultOPlus :: Peano -> Peano -> Proof
+thmMultOPlus n m = trivial
+
+{-@ thmPlusRearrange :: n:Peano -> m:Peano -> p:Peano -> q:Peano
+                     -> { plus (plus n m) (plus p q) = plus (plus m n) (plus p q) }  @-}
+
+thmPlusRearrange :: Peano -> Peano -> Peano -> Peano -> Proof
+thmPlusRearrange n m p q = thmPlusCom n m
+
+{-@ thmPlusSwap :: n : Peano -> m : Peano -> p : Peano
+                -> { plus n (plus m p) = plus m (plus n p) }  @-}
+thmPlusSwap :: Peano -> Peano -> Peano -> Proof
+thmPlusSwap n m p = [ -- plus n (plus m p) ?
+                      thmPlusAssoc n m p
+                      -- ==. plus (plus n m) p ?
+                    , thmPlusCom n m
+                      -- ==. plus (plus m n) p ?
+                    , thmPlusAssoc m n p
+                      -- ==. plus m (plus n p)
+                    ] *** QED
+
+
+{-@ thmMultSR :: m:Peano -> n:Peano -> { plus m (mult m n) = mult m (S n) } @-}
+thmMultSR :: Peano -> Peano -> Proof
+thmMultSR O     n = trivial
+thmMultSR (S m) n = [ -- plus (S m) (mult (S m) n)
+                      -- ==. plus (S m) (plus n     (mult m n))
+                      -- ==. plus n     (plus (S m) (mult m n))  ?
+                      thmPlusSwap n (S m) (mult m n)
+                      -- ==. plus n     (S (plus m  (mult m n))) ?
+                    , thmPlusNSm n (plus m (mult m n))
+                      -- ==. S (plus n (plus m (mult m n)))
+                      -- ==. plus (S n) (plus m (mult m n))      ?
+                    , thmMultSR m n
+                      -- ==. plus (S n) (mult m (S n))
+                      -- ==. mult (S m) (S n)
+                    ] *** QED
+
+{-@ thmMultCom :: n:Peano -> m:Peano -> { mult n m = mult m n } @-}
+thmMultCom :: Peano -> Peano -> Proof
+thmMultCom O     m = thmMultOR m
+thmMultCom (S n) m = [ -- mult (S n) m
+                       -- ==. plus m (mult n m) ?
+                       thmMultCom n m
+                       -- ==. plus m (mult m n) ?
+                     , thmMultSR  m n
+                       -- ==. mult m (S n)
+                     ] *** QED
diff --git a/tests/pos/stacks0.hs b/tests/pos/stacks0.hs
--- a/tests/pos/stacks0.hs
+++ b/tests/pos/stacks0.hs
@@ -4,8 +4,8 @@
 
 data LL a = Nil | Cons { head :: a, tail :: LL a }
 
-{-@ data LL a = Nil | Cons { head :: a 
-                           , tail :: {v: LL a | not (Set_mem head (elts v))  } } 
+{-@ data LL a = Nil | Cons { headC :: a
+                           , tailC :: {v: LL a | not (Set_mem headC (elts v))  } }
   @-}
 
 {-@ measure elts :: LL a -> (Set a) 
diff --git a/tests/pos/stateInvarint.hs b/tests/pos/stateInvarint.hs
--- a/tests/pos/stateInvarint.hs
+++ b/tests/pos/stateInvarint.hs
@@ -3,7 +3,7 @@
 import Prelude hiding (return, (>>=))
 
 data ST s a = S (s -> (a, s))
-{-@ data ST s a <p :: s -> Prop> 
+{-@ data ST s a <p :: s -> Bool> 
      = S (x::(f:s<p> -> (a, s<p>))) 
   @-}
 
@@ -29,21 +29,21 @@
 
 
 {-@
-apply :: forall <p :: s -> Prop>.
+apply :: forall <p :: s -> Bool>.
           ST <p> s a -> f:s<p> -> (a, s <p>)
   @-}
 apply :: ST s a -> s -> (a, s)
 apply (S f) x = f x
 
 {-@
-return :: forall <p:: s -> Prop>.
+return :: forall <p:: s -> Bool>.
           x:a -> ST <p> s {v:a|v=x}
   @-}
 return ::  a -> ST s a
 return x = S $ \s -> (x, s)
 
 {-@
-comp :: forall < p :: s -> Prop>.
+comp :: forall < p :: s -> Bool>.
     ST <p> s a -> (a -> ST <p> s b) -> ST <p> s b
 @-}
 comp :: ST s a -> (a -> ST s b) -> ST s b
diff --git a/tests/pos/term0.hs b/tests/pos/term0.hs
--- a/tests/pos/term0.hs
+++ b/tests/pos/term0.hs
@@ -29,5 +29,5 @@
 nonTerm :: Int -> Int
 nonTerm n = nonTerm (n+1)
 
-{-@ Lazy nonTerm @-}
+{-@ lazy nonTerm @-}
 
diff --git a/tests/pos/test00.old.hs b/tests/pos/test00.old.hs
new file mode 100644
--- /dev/null
+++ b/tests/pos/test00.old.hs
@@ -0,0 +1,11 @@
+module Test0 () where
+
+import Language.Haskell.Liquid.Prelude
+
+x = choose 0
+
+prop_abs = if x `gt` 0 then baz x else False
+
+baz   :: Int -> Bool
+baz z = liquidAssertB (z `geq` 0)
+
diff --git a/tests/pos/test000.hs.hquals b/tests/pos/test000.hs.hquals
new file mode 100644
--- /dev/null
+++ b/tests/pos/test000.hs.hquals
@@ -0,0 +1,1 @@
+qualif Foo(v: Int): v = 10
diff --git a/tests/pos/transpose.hs b/tests/pos/transpose.hs
--- a/tests/pos/transpose.hs
+++ b/tests/pos/transpose.hs
@@ -1,4 +1,5 @@
 {-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--prune-unsorted" @-}
 
 module Tx (transpose, transpose', transpose'') where
 
diff --git a/tests/pos/vecloop.hs b/tests/pos/vecloop.hs
--- a/tests/pos/vecloop.hs
+++ b/tests/pos/vecloop.hs
@@ -4,17 +4,17 @@
 
 data Vec a = V (Int -> a)
 
-{-@ data Vec a < dom :: Int -> Prop,
-                 rng :: Int -> a -> Prop >
+{-@ data Vec a < dom :: Int -> Bool,
+                 rng :: Int -> a -> Bool >
       = V {a :: i:Int<dom> -> a <rng i>}  @-}
 
-{-@ empty :: forall <p :: Int -> a -> Prop>. 
+{-@ empty :: forall <p :: Int -> a -> Bool>. 
                Vec <{v:Int|0=1}, p> a     @-}
 
 empty     = V $ \_ -> error "empty vector!"
 
-{-@ set :: forall a <d :: Int -> Prop,
-                     r :: Int -> a -> Prop>.
+{-@ set :: forall a <d :: Int -> Bool,
+                     r :: Int -> a -> Bool>.
            key: Int<d> -> val: a<r key>
         -> vec: Vec<{v:Int<d>| v /= key},r> a
         -> Vec <d, r> a                     @-}
@@ -22,7 +22,7 @@
                                 then val 
                                 else f k
 
-{- loop :: forall a <p :: Int -> a -> Prop>.
+{- loop :: forall a <p :: Int -> a -> Bool>.
         lo:Int
      -> hi:{Int | lo <= hi}
      -> base:a<p lo>
@@ -35,7 +35,7 @@
 --       | i < hi    = go (i+1) (f i acc)
 --       | otherwise = acc
 
-{-@ loop :: forall a <p :: Int -> a -> Prop>.
+{-@ loop :: forall a <p :: Int -> a -> Bool>.
         lo:Nat
      -> hi:{Nat | lo <= hi}
      -> base:Vec <{v:Nat | (v < lo)}, p> a
diff --git a/tests/pos/vector0.hs b/tests/pos/vector0.hs
--- a/tests/pos/vector0.hs
+++ b/tests/pos/vector0.hs
@@ -1,10 +1,12 @@
-module Vec0 () where
+module Vec0 where
 
 import Language.Haskell.Liquid.Prelude
+
 import Data.Vector hiding (map, concat, zipWith, filter, foldl, foldr, (++))
 
+prop :: Bool
 prop = prop0 && prop1 && prop2 && prop3 && prop4
-  where 
+  where
     xs    = [1,2,3,4] :: [Int]
     vs    = fromList xs
     x     = Prelude.head xs
@@ -14,4 +16,3 @@
     prop2 = liquidAssertB (Data.Vector.length vs > 0)
     prop3 = liquidAssertB (Data.Vector.length vs > 3)
     prop4 = liquidAssertB ((vs ! 0 + vs ! 1 + vs ! 2 + vs ! 3) > 0)
-
diff --git a/tests/pos/vector2.hs b/tests/pos/vector2.hs
--- a/tests/pos/vector2.hs
+++ b/tests/pos/vector2.hs
@@ -37,7 +37,7 @@
 loop :: Int -> Int -> a -> (Int -> a -> a) -> a 
 loop lo hi base f = go (hi-lo) base lo
   where
-    {-@ Decrease go 1 @-}
+    {-@ decrease go 1 @-}
     go (d::Int) acc i     
       | i /= hi   = go (d-1) (f i acc) (i + 1)
       | otherwise = acc
@@ -63,7 +63,7 @@
 {-@ sparseDotProduct :: (Num a) => x:(Vector a) -> (SparseVector a {(vlen x)}) -> a @-}
 sparseDotProduct x y  = go 0 y
   where
-    {-@ Decrease go 2 @-}
+    {-@ decrease go 2 @-}
     go sum ((i, v) : y') = go (sum + (x ! i) * v) y' 
     go sum []            = sum
 
diff --git a/tests/pos/wrap0.hs b/tests/pos/wrap0.hs
--- a/tests/pos/wrap0.hs
+++ b/tests/pos/wrap0.hs
@@ -16,5 +16,5 @@
 
 {-@ assert flibXs :: a -> Bool @-}
 flibXs x     = prop2 (F [x, x, x])
-prop2 (F []) = liquidError "no!"
+prop2 (F []) = liquidError "not-the-hippopotamus"
 prop2 (F _ ) = True
diff --git a/tests/pos/zipSO.hs b/tests/pos/zipSO.hs
--- a/tests/pos/zipSO.hs
+++ b/tests/pos/zipSO.hs
@@ -8,7 +8,7 @@
 {-@ zipper :: zs:[a] -> [(a, {v:[a] | (len v) = (len zs) - 1})] @-}
 zipper zs          = go [] zs
   
-{-@ Decrease go 2 @-}
+{-@ decrease go 2 @-}
 {-@ go :: prev:[a] -> rest:[a] -> [(a, {v:[a] | (len v) = (len prev) + (len rest) - 1})] @-}
 go _    []     = []
 go prev (x:xs) = (x, prev ++ xs) : go (prev ++ [x]) xs
diff --git a/tests/pos/zipper.hs b/tests/pos/zipper.hs
--- a/tests/pos/zipper.hs
+++ b/tests/pos/zipper.hs
@@ -17,7 +17,7 @@
 -- measures
 
 {-@
-  measure listDup :: [a] -> (Set a)
+  measure listDup :: forall a. [a] -> (Set a)
   listDup([]) = {v | Set_emp v }
   listDup(x:xs) = {v | v = if (Set_mem x (listElts xs)) then (Set_cup (Set_sng x) (listDup xs)) else (listDup xs) }
   @-}
@@ -145,7 +145,7 @@
         -> xs:{v: UList a | (ListDisjoint ack v)}
         -> {v:UList a |(UnionElts v xs ack)} 
   @-}
-{-@ Decrease rev 2 @-}
+{-@ decrease rev 2 @-}
 rev :: [a] -> [a] -> [a]
 rev a []     = a
 rev a (x:xs) = rev (x:a) xs 
diff --git a/tests/pos/zipper000.hs b/tests/pos/zipper000.hs
--- a/tests/pos/zipper000.hs
+++ b/tests/pos/zipper000.hs
@@ -1,14 +1,12 @@
 module Zipper () where
 
-import Prelude hiding (reverse)
-
 import Data.Set
 
 data Stack a = Stack { focus  :: !a        -- focused thing in this set
                      , up     :: [a]       -- jokers to the left
                      , down   :: [a] }     -- jokers to the right
 
-{-@ type UListDif a N = {v:[a] | ((not (Set_mem N (listElts v))) && (Set_emp (listDup v)))} @-}
+{-@ type UListDif a N = {v:[a] | not (Set_mem N (listElts v)) } @-}
 
 {-@
 data Stack a = Stack { focus :: a
@@ -16,17 +14,7 @@
                      , down  :: UListDif a focus }
 @-}
 
-{-@
-  measure listDup :: [a] -> (Set a)
-  listDup([]) = {v | Set_emp v }
-  listDup(x:xs) = {v | v = if (Set_mem x (listElts xs)) then (Set_cup (Set_sng x) (listDup xs)) else (listDup xs) }
-  @-}
-
-{-@ type UStack a = {v:Stack a |(Set_emp (Set_cap (listElts (getUp v)) (listElts (getDown v))))}@-}
-
-{-@ measure getFocus :: forall a. (Stack a) -> a
-    getFocus (Stack focus up down) = focus
-  @-}
+{-@ type UStack a = {v:Stack a | (Set_emp (Set_cap (listElts (getUp v)) (listElts (getDown v)))) }@-}
 
 {-@ measure getUp :: forall a. (Stack a) -> [a]
     getUp (Stack focus up down) = up
@@ -36,33 +24,12 @@
     getDown (Stack focus up down) = down
   @-}
 
--- QUALIFIERS
-{-@ q :: x:a ->  {v:[a] |(not (Set_mem x (listElts v)))} @-}
-q :: a -> [a]
-q = undefined
-{-@ q1 :: x:a ->  {v:[a] |(Set_mem x (listElts v))} @-}
-q1 :: a -> [a]
-q1 = undefined
-{-@ q0 :: x:a ->  {v:[a] |(Set_emp(listDup v))} @-}
-q0 :: a -> [a]
-q0 = undefined
+data Foo a b = J | P a b
 
+--------------------------------------------------------------------------------------
 {-@ focusUp :: UStack a -> UStack a @-}
 focusUp :: Stack a -> Stack a
-focusUp (Stack t [] rs)     = Stack xiggety xs [] where (xiggety:xs) = reverse (t:rs)
-focusUp (Stack t (l:ls) rs) = Stack l ls (t:rs)
-
-{-@ reverse :: {v:[a] | Set_emp (listDup v)} -> {v:[a]|Set_emp (listDup v)} @-}
-reverse :: [a] -> [a]
-reverse = undefined
-
-{-@ focusDown :: UStack a -> UStack a @-}
-focusDown :: Stack a -> Stack a
-focusDown = undefined
--- focusDown = reverseStack . focusUp . reverseStack
-
--- | reverse a stack: up becomes down and down becomes up.
-{-@ reverseStack :: UStack a -> UStack a @-}
-reverseStack :: Stack a -> Stack a
-reverseStack = undefined
--- reverseStack (Stack t ls rs) = Stack t rs ls
+focusUp (Stack t [] rs) = Stack xiggety xs []
+  where
+    P xiggety xs = P t rs
+--------------------------------------------------------------------------------------
diff --git a/tests/regrtest.py b/tests/regrtest.py
new file mode 100644
--- /dev/null
+++ b/tests/regrtest.py
@@ -0,0 +1,176 @@
+#!/usr/bin/python
+# Copyright (c) 2009 The Regents of the University of California. All rights reserved.
+#
+# Permission is hereby granted, without written agreement and without
+# license or royalty fees, to use, copy, modify, and distribute this
+# software and its documentation for any purpose, provided that the
+# above copyright notice and the following two paragraphs appear in
+# all copies of this software.
+#
+# IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+# IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY
+# OF SUCH DAMAGE.
+#
+# THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+# ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION
+# TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+import time, subprocess, optparse, sys, socket, os
+sys.path.append("../")
+import rtest as rtest
+
+solve         = "liquid ".split()
+null          = open("/dev/null", "w")
+now	          = (time.asctime(time.localtime(time.time()))).replace(" ","_")
+logfile       = "../tests/logs/regrtest_results_%s_%s" % (socket.gethostname (), now)
+argcomment    = "--! run with "
+liquidcomment = "{--! run liquid with "
+endcomment    = "-}"
+
+def logged_sys_call(args, out=None, err=None, dir=None):
+  print "exec: " + " ".join(args)
+  return subprocess.call(args, stdout=out, stderr=err, cwd=dir)
+ 
+def solve_quals(dir,file,bare,time,quiet,flags,lflags):
+  if quiet: out = null
+  else: out = None
+  if time: time = ["time"]
+  else: time = []
+  if lflags: lflags = ["--" + f for f in lflags]
+  hygiene_flags = []
+  (dn, bn) = os.path.split(file)
+  try:
+    os.makedirs(os.path.join(dir,dn,".liquid"))
+  except OSError:
+    pass
+  out = open(os.path.join(dir,dn,".liquid",bn) + ".log", "w")
+  rv  = logged_sys_call(time + solve + flags + lflags + hygiene_flags + [file],
+                        out=None, err=subprocess.STDOUT, dir=dir)
+  out.close()
+  return rv
+
+def run_script(file,quiet):
+  if quiet: out = null
+  else: out = None
+  return logged_sys_call(file, out)
+
+def getfileargs(file):
+  f = open(file)
+  l = f.readline()
+  f.close()
+  if l.startswith(argcomment):
+    return l[len(argcomment):].strip().split(" ")
+  else:
+    return []
+
+def getliquidargs(file):
+  f = open(file)
+  l = f.readline()
+  f.close()
+  if l.startswith(liquidcomment):
+    return [arg for arg in l[len(liquidcomment):].strip().split(" ")
+                     if arg!=endcomment]
+  else:
+    return []
+
+
+class Config (rtest.TestConfig):
+  def __init__ (self, dargs, testdirs, logfile, threadcount):
+    rtest.TestConfig.__init__ (self, testdirs, logfile, threadcount)
+    self.dargs = dargs
+
+  def run_test (self, dir, file):
+    path = os.path.join(dir,file)
+    if self.is_test(file):
+      lflags = getliquidargs(path)
+      fargs  = getfileargs(path)
+      fargs  = self.dargs + fargs  
+      return solve_quals(dir, file, True, False, True, fargs, lflags)
+    elif file.endswith(".sh"):
+      return run_script(path, True)
+
+  def is_test (self, file):
+    return file.endswith(".hs") # or file.endswith(".lhs")
+
+#####################################################################################
+
+#DEFAULT
+
+textIgnored = { "Data/Text/Axioms.hs"
+              , "Data/Text/Encoding/Error.hs"
+              , "Data/Text/Encoding/Fusion.hs"
+              , "Data/Text/Encoding/Fusion/Common.hs"
+              , "Data/Text/Encoding/Utf16.hs"
+              , "Data/Text/Encoding/Utf32.hs"
+              , "Data/Text/Encoding/Utf8.hs"
+              , "Data/Text/Fusion/CaseMapping.hs"
+              , "Data/Text/Fusion/Common.hs"
+              , "Data/Text/Fusion/Internal.hs"
+              , "Data/Text/IO.hs"
+              , "Data/Text/IO/Internal.hs"
+              , "Data/Text/Lazy/Builder/Functions.hs"
+              , "Data/Text/Lazy/Builder/Int.hs"
+              , "Data/Text/Lazy/Builder/Int/Digits.hs"
+              , "Data/Text/Lazy/Builder/Internal.hs"
+              , "Data/Text/Lazy/Builder/RealFloat.hs"
+              , "Data/Text/Lazy/Builder/RealFloat/Functions.hs"
+              , "Data/Text/Lazy/Encoding/Fusion.hs"
+              , "Data/Text/Lazy/IO.hs"
+              , "Data/Text/Lazy/Read.hs"
+              , "Data/Text/Read.hs"
+              , "Data/Text/Unsafe/Base.hs"
+              , "Data/Text/UnsafeShift.hs"
+              , "Data/Text/Util.hs"
+              }
+
+demosIgnored = { "Composition.hs"
+               , "Eval.hs"
+               , "Inductive.hs"
+               , "Loop.hs"
+               , "TalkingAboutSets.hs"
+               , "refinements101reax.hs"
+               }
+
+regtestdirs  = [ ("pos", {}, 0)
+               , ("neg", {}, 1)
+               , ("crash", {}, 2)
+               , ("parser/pos", {}, 0)
+               , ("error_messages/pos", {}, 0)
+               , ("error_messages/crash", {}, 2)
+               ]
+
+benchtestdirs = [ ("../web/demos", demosIgnored, 0)
+                , ("../benchmarks/esop2013-submission", {"Base0.hs"}, 0)
+                , ("../benchmarks/bytestring-0.9.2.1", {}, 0)
+                , ("../benchmarks/text-0.11.2.3", textIgnored, 0)
+                , ("../benchmarks/vector-algorithms-0.5.4.2", {}, 0)
+                , ("../benchmarks/hscolour-1.20.0.0", {}, 0)
+                ]
+
+parser = optparse.OptionParser()
+parser.add_option("-a", "--all", action="store_true", dest="alltests", help="run all tests")
+parser.add_option("-t", "--threads", dest="threadcount", default=1, type=int, help="spawn n threads")
+parser.add_option("-o", "--opts", dest="opts", default=[], action='append', type=str, help="additional arguments to liquid")
+parser.disable_interspersed_args()
+options, args = parser.parse_args()
+
+print "options =", options
+print "args =", args
+
+def testdirs():
+  global testdirs
+  if options.alltests:
+    return regtestdirs + benchtestdirs
+  else:
+    return regtestdirs
+
+testdirs = testdirs()
+
+clean = os.path.abspath("../cleanup")
+[os.system(("cd %s; %s; cd ../" % (d,clean))) for (d,_,_) in testdirs]
+runner = rtest.TestRunner (Config (options.opts, testdirs, logfile, options.threadcount))
+sys.exit(runner.run())
diff --git a/tests/rtest.py b/tests/rtest.py
new file mode 100644
--- /dev/null
+++ b/tests/rtest.py
@@ -0,0 +1,114 @@
+import time, os, os.path
+import pmap
+import itertools as it
+import threading, Queue
+
+class LogWriter (threading.Thread):
+    def __init__ (self, logfile, q):
+        threading.Thread.__init__ (self)
+        self.log  = open (logfile, "w")
+        self.q    = q
+        self.halt = False
+        self.log.write("test, time(s), result \n")
+
+    def __del__ (self):
+        self.log.close ()
+
+    def run (self):
+        while not self.halt:
+            try:
+                file, runtime, ok = self.q.get (timeout=1)
+                self.log.write("%s, %f, %s \n" % (file, runtime, ok))
+                self.log.flush()
+                self.q.task_done ()
+            except Queue.Empty:
+                pass
+
+class TestConfig:
+    def __init__ (self, testdirs, logfile = None, threadcount = 1):
+        self.testdirs    = testdirs
+        self.valid_exits = [x for d, i, x in self.testdirs]
+        if logfile != None:
+            self.logq   = Queue.Queue ()
+            self.logger = LogWriter (logfile, self.logq)
+            self.logger.start ()
+        else:
+            self.logger = None
+        self.exceptions  = list()
+        self.threadcount = threadcount
+
+    def finalize (self):
+        if self.logger != None:
+            self.logger.halt = True
+
+    def is_test (self, file):
+        pass
+
+    def run_test (self, file):
+        pass
+
+    def log_test (self, file, runtime, ok):
+        if self.logger != None:
+            self.logq.put ((file, runtime, ok))
+
+        if ok not in self.valid_exits:
+            self.exceptions.append (file)
+  
+class TestRunner:
+    def __init__ (self, config):
+        self.config = config
+
+    def run_test (self, (dir, file, expected_statuses)):
+        path    = os.path.join(dir, file)
+        start   = time.time ()
+        status  = self.config.run_test (dir, file)
+        runtime = time.time () - start
+        print "%f seconds" % (runtime)
+
+        if hasattr (expected_statuses, '__iter__'):
+          ok = (status in expected_statuses) 
+        else:
+          ok = (status == expected_statuses)
+        if ok:
+            print "\033[1;32mSUCCESS!\033[1;0m (%s)\n" % (path)
+        else:
+            print "\033[1;31mFAILURE :(\033[1;0m (%s) \n" % (path)
+        self.config.log_test(path, runtime, ok)
+        
+        return (dir + "/" + file, ok, status not in self.config.valid_exits)
+
+    def run_tests (self, tests):
+        results   = pmap.map (self.config.threadcount, self.run_test, tests)
+        self.config.finalize()
+        failed    = sorted([(result[0], result[2]) for result in results if result[1] == False])
+        failcount = len(failed)
+        if failcount == 0:
+            print "\n\033[1;32mPassed all tests! :D\033[1;0m"
+        else:
+            failnames  = [fail[0] for fail in failed]
+            print "\n\033[1;31mFailed %d tests:\033[1;0m \n %s \n" % (failcount, ",\n  ".join(failnames))
+
+            exceptions = [fail[0] for fail in failed if fail[1]]
+            if exceptions != []:
+                print "\n\033[1;31mExceptions thrown on %d tests:\033[1;0m \n  %s \n" % (len(exceptions), ",\n  ".join(exceptions))
+
+        return (failcount != 0)
+
+    def directory_tests (self, dir, ignored, expected_status):
+        paths = [(dir, os.path.relpath(os.path.join(d, f), dir))
+                 for d,_,files in os.walk(dir)
+                 for f in files]
+        return it.chain([(dir, file, expected_status)
+                         for dir, file in paths
+                         if self.config.is_test (file) and file not in ignored])
+
+        # return it.chain(*[[(dir, os.path.relpath(os.path.join (dir_, file),dir),
+        #                     expected_status)
+        #                    for file in files
+        #                    if self.config.is_test (file) and file not in ignored]
+        #                   for dir_, _, files in os.walk(dir)])
+
+    def run (self):
+        return self.run_tests (it.chain (*[self.directory_tests (dir, ignored, expected_status)
+                                           for dir, ignored, expected_status
+                                           in self.config.testdirs]))
diff --git a/tests/strings/neg/StringIndexingStep1.hs b/tests/strings/neg/StringIndexingStep1.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/neg/StringIndexingStep1.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE GADTs               #-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--stringtheory"    @-}
+
+module StringIndexing where
+
+
+import GHC.TypeLits
+import Data.String 
+
+import Data.Proxy 
+-- Structure that defines valid indeces of a type level target 
+-- symbol in a value level string
+
+data MI (tagret :: Symbol) s where 
+  MI :: IsString s => s        -- input string
+                   -> [Int]    -- valid indeces of target in input
+                   -> MI target s
+
+{-@ MI :: input:s 
+       -> [{i:Int |	 subString input i (stringLen target)  == target }]
+       -> MI s @-}
+
+
+-- STEP 1:    Verification of valid structures
+-- CHALLENGE: String interepretations from SMT 
+
+-- THESE SHOULD BE SAFE 
+misafe1 :: MI "cat" String 
+misafe1 = MI "catdogcatsdots" []
+
+misafe2 :: MI "cat" String
+misafe2 = MI "catdogcatsdots" [0]
+
+misafe3 :: MI "cat" String
+misafe3 = MI "catdogcatsdots" [0, 6]
+
+misafe4 :: MI "cat" String
+misafe4 = MI "catdogcatsdots" [6, 0]
+
+misafe5 :: MI "cat" String
+misafe5 = MI "catdogcatsdots" [6]
+
+
+-- THIS SHOULD BE UNSAFE 
+miunsafe :: MI "dog" String
+miunsafe = MI "catdogcatsdots" [1]
diff --git a/tests/strings/pos/DivideAndQunquer.hs b/tests/strings/pos/DivideAndQunquer.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/pos/DivideAndQunquer.hs
@@ -0,0 +1,315 @@
+{-@ LIQUID "--higherorder"         @-}
+{-@ LIQUID "--totality"            @-}
+{-@ LIQUID "--exactdc"             @-}
+
+
+module DivideAndQunquer where 
+
+import Prelude hiding (mconcat, map, split, take, drop)
+import Language.Haskell.Liquid.ProofCombinators 
+
+
+{-@ divideAndQunquer
+     :: f:(List i -> List o)
+     -> thm:(x1:List i -> x2:List i -> {f (append x1 x2) == append (f x1) (f x2)} )
+     -> is:List i 
+     -> n:Int 
+     -> m:Int 
+     -> {f is == pmconcat m (map f (chunk n is))}
+     / [llen is] 
+  @-}
+
+divideAndQunquer 
+  :: (List i -> List o) 
+  -> (List i -> List i -> Proof)
+  -> List i -> Int -> Int -> Proof
+divideAndQunquer f thm is n m  
+  =   pmconcat m (map f (chunk n is))
+  ==. mconcat (map f (chunk n is))
+       ? pmconcatEquivalence m (map f (chunk n is))
+  ==. f is 
+       ? distributeInput f thm is n 
+  *** QED 
+
+{-@ distributeInput
+     :: f:(List i -> List o)
+     -> thm:(x1:List i -> x2:List i -> {f (append x1 x2) == append (f x1) (f x2)} )
+     -> is:List i 
+     -> n:Int 
+     -> {f is == mconcat (map f (chunk n is))}
+     / [llen is] 
+  @-}
+
+distributeInput 
+  :: (List i -> List o) 
+  -> (List i -> List i -> Proof)
+  -> List i -> Int -> Proof
+distributeInput f thm is n  
+  | llen is <= n || n <= 1
+  =   mconcat (map f (chunk n is))
+  ==. mconcat (map f (C is N))
+  ==. mconcat (f is `C` map f N)
+  ==. mconcat (f is `C` N)
+  ==. append (f is) (mconcat N)
+  ==. append (f is) N
+  ==. f is ? appendRightIdentity (f is)
+  *** QED 
+  | otherwise
+  =   mconcat (map f (chunk n is))
+  ==. mconcat (map f (C (take n is) (chunk n (drop n is)))) 
+  ==. mconcat (f (take n is) `C` map f (chunk n (drop n is)))
+  ==. append (f (take n is)) (mconcat (map f (chunk n (drop n is))))
+  ==. append (f (take n is)) (f (drop n is))
+       ? distributeInput f thm (drop n is) n  
+  ==. f (append (take n is) (drop n is))
+       ? thm (take n is) (drop n is)
+  ==. f is 
+       ? appendTakeDrop n is 
+  *** QED 
+
+pmconcatEquivalence ::Int -> List (List a) -> Proof
+{-@ pmconcatEquivalence :: i:Int -> is:List (List a) 
+    -> {pmconcat i is == mconcat is} 
+    / [llen is] @-}
+pmconcatEquivalence i is 
+  | i <= 1
+  = pmconcat i is ==. mconcat is *** QED 
+pmconcatEquivalence i N 
+  =   pmconcat i N 
+  ==. N 
+  ==. mconcat N 
+  *** QED 
+pmconcatEquivalence i (C x N) 
+  =   pmconcat i (C x N)
+  ==. x 
+  ==. append x N
+       ? appendRightIdentity x  
+  ==. mconcat (C x (mconcat N)) 
+  ==. mconcat (C x N) 
+  *** QED 
+pmconcatEquivalence i xs 
+  | llen xs <= i 
+  =   pmconcat i xs 
+  ==. pmconcat i (map mconcat (chunk i xs))
+  ==. pmconcat i (map mconcat (C xs N))
+  ==. pmconcat i (mconcat xs `C`  map mconcat N)
+  ==. pmconcat i (mconcat xs `C`  N)
+  ==. mconcat xs
+  *** QED 
+pmconcatEquivalence i xs
+  =   pmconcat i xs 
+  ==. pmconcat i (map mconcat (chunk i xs))
+  ==. mconcat (map mconcat (chunk i xs))
+       ? pmconcatEquivalence i (map mconcat (chunk i xs))
+  ==. mconcat xs
+       ? mconcatAssoc i xs
+  *** QED 
+
+-------------------------------------------------------------------------------
+-----------  List Definition --------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+{-@ data List [llen] a = N | C {lhead :: a, ltail :: List a} @-}
+data List a = N | C a (List a)
+
+llen :: List a -> Int 
+{-@ measure llen @-}
+{-@ llen :: List a -> Nat @-}
+llen N        = 0 
+llen (C _ xs) = 1 + llen xs
+
+-------------------------------------------------------------------------------
+-----------  List Manipulation ------------------------------------------------
+-------------------------------------------------------------------------------
+
+-- Distribution 
+
+{-@ reflect map @-}
+{-@ map :: (a -> b) -> xs:List a -> {v:List b | llen v == llen xs } @-}
+map :: (a -> b) -> List a -> List b
+map _  N       = N
+map f (C x xs) = f x `C` map f xs 
+
+{-@ reflect chunk @-}
+{-@ chunk :: i:Int -> xs:List a -> {v:List (List a) | if (i <= 1 || llen xs <= i) then (llen v == 1) else (llen v < llen xs) } / [llen xs] @-}
+chunk :: Int -> List a -> List (List a)
+chunk i xs 
+  | i <= 1 
+  = C xs N 
+  | llen xs <= i 
+  = C xs N 
+  | otherwise
+  = C (take i xs) (chunk i (drop i xs))
+
+{-@ reflect drop @-}
+{-@ drop :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == llen xs - i } @-} 
+drop :: Int -> List a -> List a 
+drop i N = N 
+drop i (C x xs)
+  | i == 0 
+  = C x xs  
+  | otherwise 
+  = drop (i-1) xs 
+
+{-@ reflect take @-}
+{-@ take :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == i} @-} 
+take :: Int -> List a -> List a 
+take i N = N 
+take i (C x xs)
+  | i == 0 
+  = N  
+  | otherwise 
+  = C x (take (i-1) xs)
+
+-- Monoid
+
+{-@ reflect mconcat @-}
+mconcat :: List (List a) -> List a 
+mconcat N        = N 
+mconcat (C x xs) = append x (mconcat xs)
+
+
+{-@ reflect pmconcat @-}
+pmconcat :: Int -> List (List a) -> List a  
+{-@ pmconcat :: i:Int -> is:List (List a) -> List a  /[llen is] @-}
+
+pmconcat i xs
+  | i <= 1 
+  = mconcat xs 
+pmconcat i N   
+  = N 
+pmconcat i (C x N) 
+  = x
+pmconcat i xs 
+  = pmconcat i (map mconcat (chunk i xs))
+
+{-@ reflect append @-}
+append :: List a -> List a -> List a 
+append N        ys = ys  
+append (C x xs) ys = x `C` (append xs ys)
+
+
+-------------------------------------------------------------------------------
+-----------  Helper Theorems --------------------------------------------------
+-------------------------------------------------------------------------------
+
+-- List is a Monoid 
+
+appendRightIdentity :: List a -> Proof 
+{-@ appendRightIdentity :: xs:List a -> { append xs N == xs } @-}
+
+appendRightIdentity N 
+  = append N N ==. N *** QED 
+appendRightIdentity (C x xs)
+  =   append (C x xs) N 
+  ==. C x (append xs N) ? appendRightIdentity xs 
+  ==. C x xs 
+  *** QED   
+
+appendAssoc :: List a -> List a -> List a -> Proof 
+{-@ appendAssoc :: x:List a -> y:List a -> z:List a 
+  -> {append (append x y) z == append x (append y z)} @-}
+appendAssoc N y z 
+  =   append (append N y) z 
+ -- ==. append y z
+  ==. append N (append y z)
+  *** QED 
+appendAssoc (C x xs) y z 
+  =   append (append (C x xs) y) z 
+  ==. append (x `C` (append xs y)) z 
+  ==. x `C` (append (append xs y) z)
+  ==. x `C` (append xs (append y z))
+       ? appendAssoc xs y z
+  ==. append (C x xs) (append y z)
+  *** QED   
+
+
+-- | Monoid implications 
+
+mconcatAssocOne :: Int -> List (List a) -> Proof 
+{-@ mconcatAssocOne :: i:Nat -> xs:{List (List a) | i <= llen xs} 
+     -> {mconcat xs == append (mconcat (take i xs)) (mconcat (drop i xs))}
+     /[i]
+  @-} 
+mconcatAssocOne i N 
+  =   append (mconcat (take i N)) (mconcat (drop i N)) 
+  ==. append (mconcat N) (mconcat N)
+  ==. append N N 
+      --  ? leftIdentity N 
+  ==. N 
+  ==. mconcat N 
+  *** QED 
+mconcatAssocOne i (C x xs)
+  | i == 0
+  =   append (mconcat (take i (C x xs))) (mconcat (drop i (C x xs))) 
+  ==. append (mconcat N) (mconcat (C x xs))
+  ==. append N (mconcat (C x xs))
+  ==. mconcat (C x xs)
+      -- ? leftIdentity (C x xs)
+  *** QED 
+  | otherwise    
+  =   append (mconcat (take i (C x xs))) (mconcat (drop i (C x xs))) 
+  ==. append (mconcat (C x (take (i-1) xs))) (mconcat (drop (i-1) xs))
+  ==. append (append x (mconcat (take (i-1) xs))) (mconcat (drop (i-1) xs))
+       ? appendAssoc x (mconcat (take (i-1) xs)) (mconcat (drop (i-1) xs))
+  ==. append x (append (mconcat (take (i-1) xs)) (mconcat (drop (i-1) xs)))
+       ? mconcatAssocOne (i-1) xs
+  ==. append x (mconcat xs)
+  ==. mconcat (C x xs)
+  *** QED 
+
+-- Generalization to chunking  
+
+mconcatAssoc :: Int -> List (List a) -> Proof 
+{-@ mconcatAssoc :: 
+    i:Int -> xs:List (List a) 
+  -> { mconcat xs == mconcat (map mconcat (chunk i xs))}
+  /  [llen xs] @-}
+mconcatAssoc i xs 
+  | i <= 1 || llen xs <= i
+  =   mconcat (map mconcat (chunk i xs))
+  ==. mconcat (map mconcat (C xs N))
+  ==. mconcat (mconcat xs `C` map mconcat N)
+  ==. mconcat (mconcat xs `C` N)
+  ==. append (mconcat xs) (mconcat N)
+  ==. append (mconcat xs) N
+  ==. mconcat xs 
+       ? appendRightIdentity (mconcat xs)
+  *** QED  
+   | otherwise
+   =   mconcat (map mconcat (chunk i xs))
+   ==. mconcat (map mconcat (take i xs `C` chunk i (drop i xs)))
+   ==. mconcat (mconcat (take i xs) `C` map mconcat (chunk i (drop i xs)))
+   ==. append (mconcat (take i xs)) (mconcat (map mconcat (chunk i (drop i xs))))
+   ==. append (mconcat (take i xs)) (mconcat (drop i xs))
+        ? mconcatAssoc i (drop i xs)
+   ==. mconcat xs 
+        ? mconcatAssocOne i xs 
+   *** QED 
+
+
+
+-- | For input Distribution 
+{-@ appendTakeDrop :: i:Nat -> xs:{List a | i <= llen xs} 
+  -> {xs == append (take i xs) (drop i xs) }  @-}
+
+appendTakeDrop :: Int -> List a -> Proof 
+appendTakeDrop i N 
+  =   append (take i N) (drop i N)
+  ==. append N N 
+  ==. N 
+  *** QED 
+appendTakeDrop i (C x xs)
+  | i == 0 
+  =   append (take 0 (C x xs)) (drop 0 (C x xs))
+  ==. append N (C x xs)
+  ==. C x xs 
+  *** QED 
+  | otherwise
+  =   append (take i (C x xs)) (drop i (C x xs))
+  ==. append (C x (take (i-1) xs)) (drop (i-1) xs)
+  ==. C x (append (take (i-1) xs) (drop (i-1) xs))
+  ==. C x xs ? appendTakeDrop (i-1) xs 
+  *** QED 
+
diff --git a/tests/strings/pos/Proves.hs b/tests/strings/pos/Proves.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/pos/Proves.hs
@@ -0,0 +1,250 @@
+{-@ LIQUID "--higherorder"     @-}
+
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE IncoherentInstances   #-}
+module Proves (
+
+    (==:), (<=:), (<:), (>:)
+
+  , (==?)
+
+  , (==.), (<=.), (<.), (>.), (>=.)
+
+  -- Function Equality 
+  , Arg
+
+  , (=*=.)
+
+  , (?), (∵), (***)
+
+  , (==>), (&&&)
+
+  , proof, toProof, simpleProof
+
+  , QED(..)
+
+  , Proof
+
+  , byTheorem
+
+  , todo
+
+  ) where
+
+
+-- | proof operators requiring proof terms
+infixl 3 ==:, <=:, <:, >:, ==?
+
+-- | proof operators with optional proof terms
+infixl 3 ==., <=., <., >., >=., =*=.
+
+-- provide the proof terms after ?
+infixl 3 ?
+infixl 3 ∵
+
+infixl 2 ***
+
+
+type Proof = ()
+
+
+byTheorem :: a -> Proof -> a
+byTheorem a _ = a
+
+(?) :: (Proof -> a) -> Proof -> a
+f ? y = f y
+
+(∵) :: (Proof -> a) -> Proof -> a
+f ∵ y = f y
+
+
+
+data QED = QED
+
+
+todo :: a
+{-@ assume todo :: {v:a | false} @-}
+todo = undefined
+
+(***) :: a -> QED -> Proof
+_ *** _ = ()
+
+{-@ measure proofBool :: Proof -> Bool @-}
+
+-- | Proof combinators (are Proofean combinators)
+{-@ (==>) :: p:Proof
+          -> q:Proof
+          -> {v:Proof |
+          ((Prop (proofBool p)) && (Prop (proofBool p) => Prop (proofBool q)))
+          =>
+          ((Prop (proofBool p) && Prop (proofBool q)))
+          } @-}
+(==>) :: Proof -> Proof -> Proof
+p ==> q = ()
+
+
+{-@ (&&&) :: p:{Proof | Prop (proofBool p) }
+          -> q:{Proof | Prop (proofBool q) }
+          -> {v:Proof | Prop (proofBool p) && Prop (proofBool q) } @-}
+(&&&) :: Proof -> Proof -> Proof
+p &&& q = ()
+
+
+-- | proof goes from Int to resolve types for the optional proof combinators
+proof :: Int -> Proof
+proof _ = ()
+
+toProof :: a -> Proof
+toProof _ = ()
+
+simpleProof :: Proof
+simpleProof = ()
+
+-- | Comparison operators requiring proof terms
+
+(<=:) :: a -> a -> Proof -> a
+{-@ (<=:) :: x:a -> y:a -> {v:Proof | x <= y } -> {v:a | v == x } @-}
+(<=:) x y _ = x
+
+(<:) :: a -> a -> Proof -> a
+{-@ (<:) :: x:a -> y:a -> {v:Proof | x < y } -> {v:a | v == x } @-}
+(<:) x y _ = x
+
+
+(>:) :: a -> a -> Proof -> a
+{-@ (>:) :: x:a -> y:a -> {v:Proof | x >y } -> {v:a | v == x } @-}
+(>:) x _ _ = x
+
+
+(==:) :: a -> a -> Proof -> a
+{-@ (==:) :: x:a -> y:a -> {v:Proof| x == y} -> {v:a | v == x && v == y } @-}
+(==:) x _ _ = x
+
+
+
+-- | Comparison operators requiring proof terms optionally
+
+
+-- | ToProve is undefined and is only used to assume some equalities in
+-- | the proof proccess. It is a cut, a la Coq
+
+class ToProve a r where
+  (==?) :: a -> a -> r
+
+
+instance (a~b) => ToProve a b where
+{-@ instance ToProve a b where
+  ==? :: x:a -> y:a -> {v:b | v ~~ x }
+  @-}
+  (==?)  = undefined
+
+instance (a~b) => ToProve a (Proof -> b) where
+{-@ instance ToProve a (Proof -> b) where
+  ==? :: x:a -> y:a -> Proof -> {v:b | v ~~ x  }
+  @-}
+  (==?) = undefined
+
+
+class OptEq a r where
+  (==.) :: a -> a -> r
+
+instance (a~b) => OptEq a (Proof -> b) where
+{-@ instance OptEq a (Proof -> b) where
+  ==. :: x:a -> y:a -> {v:Proof | x == y} -> {v:b | v ~~ x && v ~~ y}
+  @-}
+  (==.) x _ _ = x
+
+instance (a~b) => OptEq a b where
+{-@ instance OptEq a b where
+  ==. :: x:a -> y:{a| x == y} -> {v:b | v ~~ x && v ~~ y }
+  @-}
+  (==.) x _ = x
+
+
+class OptLEq a r where
+  (<=.) :: a -> a -> r
+
+
+instance (a~b) => OptLEq a (Proof -> b) where
+{-@ instance OptLEq a (Proof -> b) where
+  <=. :: x:a -> y:a -> {v:Proof | x <= y} -> {v:b | v ~~ x }
+  @-}
+  (<=.) x _ _ = x
+
+instance (a~b) => OptLEq a b where
+{-@ instance OptLEq a b where
+  <=. :: x:a -> y:{a | x <= y} -> {v:b | v ~~ x }
+  @-}
+  (<=.) x _ = x
+
+class OptGEq a r where
+  (>=.) :: a -> a -> r
+
+instance OptGEq a (Proof -> a) where
+{-@ instance OptGEq a (Proof -> a) where
+  >=. :: x:a -> y:a -> {v:Proof| x >= y} -> {v:a | v == x }
+  @-}
+  (>=.) x _ _ = x
+
+instance OptGEq a a where
+{-@ instance OptGEq a a where
+  >=. :: x:a -> y:{a| x >= y} -> {v:a | v == x  }
+  @-}
+  (>=.) x _ = x
+
+
+class OptLess a r where
+  (<.) :: a -> a -> r
+
+instance (a~b) => OptLess a (Proof -> b) where
+{-@ instance OptLess a (Proof -> b) where
+  <. :: x:a -> y:a -> {v:Proof | x < y} -> {v:b | v ~~ x  }
+  @-}
+  (<.) x _ _ = x
+
+instance (a~b) => OptLess a b where
+{-@ instance OptLess a b where
+  <. :: x:a -> y:{a| x < y} -> {v:b | v ~~ x  }
+  @-}
+  (<.) x _ = x
+
+
+class OptGt a r where
+  (>.) :: a -> a -> r
+
+instance (a~b) => OptGt a (Proof -> b) where
+{-@ instance OptGt a (Proof -> b) where
+  >. :: x:a -> y:a -> {v:Proof| x > y} -> {v:b | v ~~ x }
+  @-}
+  (>.) x _ _ = x
+
+instance (a~b) => OptGt a b where
+{-@ instance OptGt a b where
+  >. :: x:a -> y:{a| x > y} -> {v:b | v ~~ x  }
+  @-}
+  (>.) x y = x
+
+
+
+-- | Function Equality 
+
+{- TO REFINE 
+class FunEq a b r where
+  (=*=.) :: (a -> b) -> (a -> b) -> r
+
+instance (c~(a -> b)) => FunEq a b ((a -> Proof) -> c) where
+  {-@ instance FunEq a b ((a -> Proof) -> a -> b) where
+   =*=. :: f:(a -> b) -> g:(a -> b) -> (r:a -> {f r == g r}) -> {v:_ | f == g && v ~~ f && v ~~ g}
+   @-} 
+   f =*=. g = undefined  
+-}
+
+class Arg a where 
+
+
+{-@ assume (=*=.) :: Arg a => f:(a -> b) -> g:(a -> b) -> (r:a -> {f r == g r}) -> {v:(a -> b) | f == g} @-}
+(=*=.) :: Arg a => (a -> b) -> (a -> b) -> (a -> Proof) -> (a -> b)
+(=*=.) f g p = f
diff --git a/tests/strings/pos/String.hs b/tests/strings/pos/String.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/pos/String.hs
@@ -0,0 +1,139 @@
+{-# LANGUAGE OverloadedStrings   #-}
+
+{-@ LIQUID "--higherorder"         @-}
+{-@ LIQUID "--totality"            @-}
+{-@ LIQUID "--exactdc"             @-}
+
+module String where
+
+import qualified Data.ByteString as BS
+import qualified Data.String     as ST
+import Language.Haskell.Liquid.ProofCombinators 
+
+
+{-@ embed SMTString as Str @-}
+
+data SMTString = S BS.ByteString 
+  deriving (Eq, Show)
+
+------------------------------------------------------------------------------
+---------------  SMTString Interface in Logic --------------------------------
+------------------------------------------------------------------------------
+
+
+{-@ invariant {s:SMTString | 0 <= stringLen s } @-}
+
+{-@ measure stringEmp    :: SMTString @-}
+{-@ measure stringLen    :: SMTString -> Int @-}
+{-@ measure subString    :: SMTString -> Int -> Int -> SMTString @-}
+{-@ measure concatString :: SMTString -> SMTString -> SMTString @-}
+{-@ measure fromString   :: String -> SMTString @-}
+{-@ measure takeString   :: Int -> SMTString -> SMTString @-}
+{-@ measure dropString   :: Int -> SMTString -> SMTString @-}
+
+------------------------------------------------------------------------------
+---------------  SMTString operators -----------------------------------------
+------------------------------------------------------------------------------
+
+{-@ assume concatString :: x:SMTString -> y:SMTString 
+                 -> {v:SMTString | v == concatString x y && stringLen v == stringLen x + stringLen y } @-}
+concatString :: SMTString -> SMTString -> SMTString
+concatString (S s1) (S s2) = S (s1 `BS.append` s2)
+
+{-@ assume stringEmp :: {v:SMTString | v == stringEmp  && stringLen v == 0 } @-}
+stringEmp :: SMTString
+stringEmp = S (BS.empty)
+
+stringLen :: SMTString -> Int  
+{-@ assume stringLen :: x:SMTString -> {v:Nat | v == stringLen x} @-}
+stringLen (S s) = BS.length s 
+
+{-@ assume subString  :: s:SMTString -> offset:Int -> ln:Int -> {v:SMTString | v == subString s offset ln } @-}
+subString :: SMTString -> Int -> Int -> SMTString 
+subString (S s) o l = S (BS.take l $ BS.drop o s) 
+
+{-@ assume takeString :: i:Nat -> xs:{SMTString | i <= stringLen xs } -> {v:SMTString | stringLen v == i && v == takeString i xs } @-} 
+takeString :: Int -> SMTString -> SMTString
+takeString i (S s) = S (BS.take i s)
+
+{-@ assume dropString :: i:Nat -> xs:{SMTString | i <= stringLen xs } -> {v:SMTString | stringLen v == stringLen xs - i && v == dropString i xs } @-} 
+dropString :: Int -> SMTString -> SMTString
+dropString i (S s) = S (BS.drop i s)
+
+{-@ assume fromString :: i:String -> {o:SMTString | i == o && o == fromString i} @-}
+fromString :: String -> SMTString
+fromString = S . ST.fromString 
+
+{-@ assume isNullString :: i:SMTString -> {b:Bool | Prop b <=> stringLen i == 0 } @-} 
+isNullString :: SMTString -> Bool 
+isNullString (S s) = BS.length s == 0 
+
+------------------------------------------------------------------------------
+---------------  Properties assumed for SMTStrings ---------------------------
+------------------------------------------------------------------------------
+
+-- | Empty Strings 
+
+{-@ assume stringEmpProp :: x:SMTString  -> { stringLen x == 0 <=> x == stringEmp } @-}
+stringEmpProp :: SMTString -> Proof
+stringEmpProp _ = trivial 
+ 
+concatStringNeutralLeft :: SMTString -> Proof
+{-@ assume concatStringNeutralLeft :: x:SMTString -> {concatString x stringEmp == x} @-}
+concatStringNeutralLeft _ = trivial
+
+concatStringNeutralRight :: SMTString -> Proof
+{-@ assume concatStringNeutralRight :: x:SMTString -> {concatString stringEmp x == x} @-}
+concatStringNeutralRight _ = trivial
+
+{-@ concatEmpLeft :: xi:{SMTString | stringLen xi == 0} -> yi:SMTString -> {concatString xi yi == yi} @-}
+concatEmpLeft :: SMTString -> SMTString -> Proof
+concatEmpLeft xi yi 
+  =   concatString xi yi 
+  ==. concatString stringEmp yi ? stringEmpProp xi 
+  ==. yi                        ? concatStringNeutralRight yi
+  *** QED 
+
+
+{-@ concatEmpRight :: xi:SMTString -> yi:{SMTString | stringLen yi == 0} -> {concatString xi yi == xi} @-}
+concatEmpRight :: SMTString -> SMTString -> Proof
+concatEmpRight xi yi 
+  =   concatString xi yi 
+  ==. concatString xi stringEmp ? stringEmpProp yi 
+  ==. xi                        ? concatStringNeutralLeft xi 
+  *** QED 
+
+-- | Concat
+
+{-@ assume concatTakeDrop :: i:Nat -> xs:{SMTString | i <= stringLen xs} 
+    -> {xs == concatString (takeString i xs) (dropString i xs) }  @-}
+concatTakeDrop :: Int -> SMTString -> Proof 
+concatTakeDrop _ _ = trivial
+
+concatLen :: SMTString -> SMTString -> Proof
+{-@ assume concatLen :: x:SMTString -> y:SMTString -> { stringLen (concatString x y) == stringLen x + stringLen y } @-}
+concatLen _ _ = trivial
+
+concatStringAssoc :: SMTString -> SMTString -> SMTString -> Proof
+{-@ assume concatStringAssoc :: x:SMTString -> y:SMTString -> z:SMTString 
+     -> {concatString (concatString x y) z == concatString x (concatString y z) } @-}
+concatStringAssoc _ _ _ = trivial
+
+
+-- | Substrings 
+
+{-@ assume subStringConcatBack :: input:SMTString -> input':SMTString -> j:Int -> i:{Int | i + j <= stringLen input }
+  -> { (subString input i j == subString (concatString input input') i j) 
+    && (stringLen input <= stringLen (concatString input input'))
+     } @-}
+subStringConcatBack :: SMTString -> SMTString -> Int -> Int -> Proof 
+subStringConcatBack _ _ _ _ = trivial  
+
+
+{-@ assume subStringConcatFront  
+  :: input:SMTString -> input':SMTString -> j:Int -> i:Int 
+  -> { (subString input i j == subString (concatString input' input) (stringLen input' + i) j)
+      && (stringLen (concatString input' input) == stringLen input + stringLen input')
+    } @-}
+subStringConcatFront :: SMTString -> SMTString -> Int -> Int -> Proof
+subStringConcatFront _ _ _ _ = trivial
diff --git a/tests/strings/pos/StringIndexing.hs b/tests/strings/pos/StringIndexing.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/pos/StringIndexing.hs
@@ -0,0 +1,2266 @@
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE GADTs               #-}
+
+
+{-@ LIQUID "--cores=10"            @-}
+{-@ LIQUID "--higherorder"         @-}
+{-@ LIQUID "--totality"            @-}
+{-@ LIQUID "--exactdc"             @-}
+
+module Main where
+
+import Prelude hiding ( mempty, mappend, id, mconcat, map
+                      , take, drop  
+                      , error, undefined
+                      )
+
+
+import System.Environment   
+import Data.String hiding (fromString)
+import GHC.TypeLits
+import Data.Maybe 
+
+import String
+import Language.Haskell.Liquid.ProofCombinators 
+
+import Data.Proxy 
+
+{-@ symbolVal :: forall n proxy. KnownSymbol n => x:proxy n 
+  -> {v:String | v == n && v == symbolVal x } @-}
+{-@ measure symbolVal :: p n -> String @-}
+
+-------------------------------------------------------------------------------
+------------ | String Matching Main Theorem  ----------------------------------
+-------------------------------------------------------------------------------
+
+{-@ distributionOfStringMatching :: MI target -> is:SMTString  -> n:Int -> m:Int
+   -> {toMI is == pmconcat m (map toMI (chunkString n is))} @-}
+
+distributionOfStringMatching :: forall (target :: Symbol). (KnownSymbol target) => MI target -> SMTString -> Int -> Int -> Proof
+distributionOfStringMatching _ is n m  
+  =   (pmconcat m (map toMI (chunkString n is)) :: MI target)
+  ==. mconcat (map toMI (chunkString n is))
+       ? pmconcatEquivalence m (map toMI (chunkString n is) :: List (MI target))
+  ==. toMI is 
+       ? distributionOfMI (mempty :: MI target) is n 
+  *** QED 
+
+
+-------------------------------------------------------------------------------
+------------ | Interface ------------------------------------------------------
+-------------------------------------------------------------------------------
+
+main :: IO ()
+main = 
+  do args      <- getArgs
+     case args of 
+       (i:fname:target:_) -> do input <- fromString <$> readFile fname 
+                                runMatching (read i :: Int) input target
+       _                -> putStrLn $ "Wrong input: You need to provide the chunksize," ++
+                                      "the input filename and the target string. For example:\n\n\n" ++ 
+                                      "./StringIndexing 10 input.txt abcab\n\n"
+     
+
+runMatching :: Int -> SMTString -> String -> IO ()
+runMatching chunksize input tg =
+  case someSymbolVal tg of 
+    SomeSymbol (_ :: Proxy target) -> do            
+      let mi1    = toMI input :: MI target 
+      let is1    = indicesMI mi1 
+      putStrLn   $ "Serial   Indices: " ++ show is1
+      let mi2    = toMIPar chunksize input :: MI target 
+      let is2    = indicesMI mi2 
+      putStrLn   $ "Parallel Indices: " ++ show is2
+      putStrLn   $ "Are equal? " ++ show (is1 == is2)
+
+test = indicesMI (toMI (fromString $ clone 100 "ababcabcab")  :: MI "abcab" )
+  where
+    clone i xs = concat (replicate i xs) 
+
+
+
+{-@ reflect toMI @-}
+toMI :: forall (target :: Symbol). (KnownSymbol target) => SMTString -> MI target 
+toMI input  
+  | stringLen input == 0 
+  = mempty
+  | otherwise          
+  = MI input (makeIndices input (fromString (symbolVal (Proxy :: Proxy target))) 0 (stringLen input - 1))
+
+toMIPar :: forall (target :: Symbol). (KnownSymbol target) => Int -> SMTString -> MI target  
+toMIPar chunksize input 
+  = pmconcat chunksize (map toMI (chunkString chunksize input))
+
+-------------------------------------------------------------------------------
+----------  Indexing Structure Definition -------------------------------------
+-------------------------------------------------------------------------------
+
+data MI (target :: Symbol) where 
+  MI :: SMTString       -- | input string
+     -> (List Int)      -- | valid indices of target in input
+     -> MI target
+  deriving (Show)
+
+{-@ data MI target 
+  = MI { input   :: SMTString
+       , indices :: List (GoodIndex input target)
+       } @-}
+
+{-@ type GoodIndex Input Target 
+  = {i:Int | IsGoodIndex Input Target i }
+  @-}
+
+{-@ type GoodIndexTwo Input X Target 
+  = {i:Int | (IsGoodIndex Input Target i)  && (IsGoodIndex (concatString Input X) Target i) }
+  @-}
+
+
+{-@ predicate IsGoodIndex Input Target I
+  =  (subString Input I (stringLen Target)  == Target)
+  && (I + stringLen Target <= stringLen Input)
+  && (0 <= I)
+  @-}
+
+{-@ measure indicesMI @-}
+indicesMI (MI _ is) = is 
+
+{-@ measure inputMI @-}
+inputMI (MI i _) = i 
+
+-------------------------------------------------------------------------------
+----------  Monoid Operators on MI --------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ reflect mempty @-}
+mempty :: forall (target :: Symbol). (KnownSymbol target) =>  MI target
+mempty = MI stringEmp N
+
+{-@ reflect mconcat @-}
+mconcat :: forall (target :: Symbol). (KnownSymbol target) => List (MI target) -> MI target 
+mconcat N        = mempty
+mconcat (C x xs) = mappend x (mconcat xs)
+
+{-@ reflect pmconcat @-}
+pmconcat :: forall (target :: Symbol). (KnownSymbol target) => Int -> List (MI target) -> MI target 
+{-@ pmconcat :: forall (target :: Symbol). (KnownSymbol target) => 
+  Int -> is:List (MI target) -> MI target /[llen is] @-}
+
+pmconcat i xs
+  | i <= 1 
+  = mconcat xs 
+pmconcat i N   
+  = mempty
+pmconcat i (C x N) 
+  = x
+pmconcat i xs 
+  = pmconcat i (map mconcat (chunk i xs))
+
+
+
+{-@ reflect mappend @-}
+mappend :: forall (target :: Symbol).  (KnownSymbol target) => MI target -> MI target -> MI target
+mappend (MI i1 is1) (MI i2 is2)
+  = MI (concatString i1 i2)
+       ((castGoodIndexRightList (fromString (symbolVal (Proxy :: Proxy target))) i1 i2 is1
+          `append`
+        makeNewIndices i1 i2 (fromString (symbolVal (Proxy :: Proxy target)))
+       ) `append`
+       (map (shiftStringRight (fromString (symbolVal (Proxy :: Proxy target))) i1 i2) is2)) 
+
+-- | Helpers 
+{-@ reflect shiftStringRight @-}
+shiftStringRight :: SMTString -> SMTString -> SMTString -> Int -> Int 
+{-@ shiftStringRight :: target:SMTString -> left:SMTString -> right:SMTString -> i:GoodIndex right target 
+  -> {v:(GoodIndex {concatString left right} target) | v == i + stringLen left } @-}
+shiftStringRight target left right i 
+  = cast (subStringConcatFront right left (stringLen target) i) (shift (stringLen left) i)
+
+{-@ reflect makeNewIndices @-}
+{-@ makeNewIndices :: s1:SMTString -> s2:SMTString -> target:SMTString -> List (GoodIndex {concatString s1 s2} target) @-}
+makeNewIndices :: SMTString -> SMTString -> SMTString -> List Int 
+makeNewIndices s1 s2 target
+  | stringLen target < 2 
+  = N
+  | otherwise
+  = makeIndices (concatString s1 s2) target
+                (maxInt (stringLen s1 - (stringLen target-1)) 0)
+                (stringLen s1 - 1)
+
+{-@ reflect maxInt @-}
+maxInt :: Int -> Int -> Int 
+maxInt x y = if x <= y then y else x 
+
+{-@ reflect shift @-}
+shift :: Int -> Int -> Int 
+shift x y = x + y 
+
+-- | Casting good indices: the below operators are liquid casts and behave like id at runtime
+
+-- NV: The recursion is required as there is no other way to (access &) cast _each_ element of the input list
+{-@ reflect castGoodIndexRightList @-}
+castGoodIndexRightList :: SMTString -> SMTString -> SMTString -> List Int -> List Int    
+{-@ castGoodIndexRightList :: target:SMTString -> input:SMTString -> x:SMTString -> is:List (GoodIndex input target) 
+    -> {v:List (GoodIndexTwo input x target) | v == is} @-}
+castGoodIndexRightList target input x N 
+  = N 
+castGoodIndexRightList target input x (C i is) 
+  = C (castGoodIndexRight target input x i) (castGoodIndexRightList target input x is)  
+
+
+{-@ reflect castGoodIndexRight @-}
+castGoodIndexRight :: SMTString -> SMTString -> SMTString -> Int -> Int  
+{-@ castGoodIndexRight :: target:SMTString -> input:SMTString -> x:SMTString -> i:GoodIndex input target 
+   -> {v:(GoodIndexTwo input x target)| v == i} @-}
+castGoodIndexRight target input x i  = cast (subStringConcatBack input x (stringLen target) i) i
+
+
+-------------------------------------------------------------------------------
+----------  Indices' Generation -----------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ reflect makeIndices @-}
+makeIndices :: SMTString -> SMTString -> Int -> Int -> List Int 
+{-@ makeIndices :: input:SMTString -> target:SMTString -> lo:Nat -> hi:Int -> List (GoodIndex input target) 
+  / [hi - lo] @-}
+makeIndices input target lo hi 
+  | hi < lo 
+  = N
+  | lo == hi, isGoodIndex input target lo
+  = lo `C` N
+  | lo == hi 
+  = N
+makeIndices input target lo hi 
+  | isGoodIndex input target lo
+  = lo `C` (makeIndices input target (lo + 1) hi)
+  | otherwise 
+  =    makeIndices input target (lo + 1) hi 
+
+{-@ reflect isGoodIndex @-}
+isGoodIndex :: SMTString -> SMTString -> Int -> Bool 
+{-@ isGoodIndex :: input:SMTString -> target:SMTString -> i:Int 
+  -> {b:Bool | Prop b <=> IsGoodIndex input target i} @-}
+isGoodIndex input target i 
+  =  subString input i (stringLen target)  == target  
+  && i + stringLen target <= stringLen input
+  && 0 <= i    
+
+
+-------------------------------------------------------------------------------
+----------  List Structure ----------------------------------------------------
+-------------------------------------------------------------------------------
+   
+data List a = N | C a (List a) deriving (Show, Eq)
+{-@ data List [llen] a 
+  = N | C {lhead :: a , ltail :: List a} @-}
+
+
+{-@ measure llen @-}
+{-@ llen :: List a -> Nat @-} 
+llen :: List a -> Int 
+llen N        = 0 
+llen (C _ xs) = 1 + llen xs 
+
+{-@ reflect map @-}
+{-@ map :: (a -> b) -> is:List a -> {os:List b | llen is == llen os} @-}
+map :: (a -> b) -> List a -> List b
+map _ N        = N
+map f (C x xs) = C (f x) (map f xs)
+
+{-@ reflect append @-}
+append :: List a -> List a -> List a 
+append N        ys = ys 
+append (C x xs) ys = x `C` (append xs ys)
+
+
+{-@ reflect chunk @-}
+{-@ chunk :: i:Int -> xs:List a -> {v:List (List a) | if (i <= 1 || llen xs <= i) then (llen v == 1) else (llen v < llen xs) } / [llen xs] @-}
+chunk :: Int -> List a -> List (List a)
+chunk i xs 
+  | i <= 1
+  = C xs N 
+  | llen xs <= i 
+  = C xs N 
+  | otherwise
+  = C (take i xs) (chunk i (drop i xs))
+
+{-@ reflect drop @-}
+{-@ drop :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == llen xs - i } @-} 
+drop :: Int -> List a -> List a 
+drop i N = N 
+drop i (C x xs)
+  | i == 0 
+  = C x xs  
+  | otherwise 
+  = drop (i-1) xs 
+
+{-@ reflect take @-}
+{-@ take :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == i} @-} 
+take :: Int -> List a -> List a 
+take i N = N 
+take i (C x xs)
+  | i == 0 
+  = N  
+  | otherwise 
+  = C x (take (i-1) xs)
+
+
+-------------------------------------------------------------------------------
+----------  String Chunking ---------------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ reflect chunkString @-}
+{-@ chunkString :: Int -> xs:SMTString -> List (SMTString) / [stringLen xs] @-}
+chunkString :: Int -> SMTString -> List (SMTString)
+chunkString i xs 
+  | i <= 1
+  = C xs N 
+  | stringLen xs <= i 
+  = C xs N 
+  | otherwise
+  = C (takeString i xs) (chunkString i (dropString i xs))
+
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+------------ Liquid Proofs Start HERE -----------------------------------------
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+----------  Proof that toMI distributes ---------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ distributionOfMI :: MI target -> is:SMTString -> n:Int -> {toMI is == mconcat (map toMI (chunkString n is))} @-}
+
+distributionOfMI :: forall (target :: Symbol). (KnownSymbol target) => MI target -> SMTString -> Int -> Proof
+distributionOfMI _ is n = distributeInput (toMI :: SMTString -> MI target) (distributestoMI (mempty :: MI target)) is n 
+
+
+{-@ distributeInput
+     :: f:(SMTString -> MI target)
+     -> thm:(x1:SMTString -> x2:SMTString -> {f (concatString x1 x2) == mappend (f x1) (f x2)} )
+     -> is:SMTString
+     -> n:Int 
+     -> {f is == mconcat (map f (chunkString n is))}
+     / [stringLen is] 
+  @-}
+
+distributeInput :: forall (target :: Symbol). (KnownSymbol target) 
+  => (SMTString -> MI target)
+  -> (SMTString -> SMTString -> Proof)
+  -> SMTString -> Int -> Proof
+distributeInput f thm is n  
+  | stringLen is <= n || n <= 1
+  =   mconcat (map f (chunkString n is))
+  ==. mconcat (map f (C is N))
+  ==. mconcat (f is `C` map f N)
+  ==. mconcat (f is `C` N)
+  ==. mappend (f is) (mconcat N)
+  ==. mappend (f is) (mempty :: MI target)
+  ==. f is ? mempty_left (f is)
+  *** QED 
+  | otherwise
+  =   mconcat (map f (chunkString n is))
+  ==. mconcat (map f (C (takeString n is) (chunkString n (dropString n is)))) 
+  ==. mconcat (f (takeString n is) `C` map f (chunkString n (dropString n is)))
+  ==. mappend (f (takeString n is)) (mconcat (map f (chunkString n (dropString n is))))
+  ==. mappend (f (takeString n is)) (f (dropString n is))
+       ? distributeInput f thm (dropString n is) n  
+  ==. f (concatString (takeString n is) (dropString n is))
+       ? thm (takeString n is) (dropString n is)
+  ==. f is 
+       ? concatTakeDrop n is 
+  *** QED 
+
+
+
+distributestoMI :: forall (target :: Symbol). (KnownSymbol target) => MI target -> SMTString -> SMTString -> Proof 
+{-@ distributestoMI :: MI target -> x1:SMTString -> x2:SMTString -> {toMI (concatString x1 x2) == mappend (toMI x1) (toMI x2)} @-} 
+distributestoMI _ x1 x2
+  | stringLen x1 == 0, stringLen x2 == 0 
+  =   mappend (toMI x1) (toMI x2)
+  ==. mappend (mempty :: MI target) (mempty :: MI target)
+       ? mempty_left (mempty :: MI target) 
+  ==. (mempty :: MI target)
+  ==. toMI (concatString x1 x2)
+  *** QED 
+
+distributestoMI _ x1 x2
+  | stringLen x1 == 0 
+  =   mappend (toMI x1) (toMI x2)
+  ==. mappend (mempty :: MI target) (toMI x2 :: MI target)
+  ==. toMI x2 
+      ? mempty_right (toMI x2 :: MI target)
+  ==. toMI (concatString x1 x2)
+      ? concatEmpLeft x1 x2 
+  *** QED 
+
+distributestoMI _ x1 x2
+  | stringLen x2 == 0 
+  =   mappend (toMI x1) (toMI x2)
+  ==. mappend (toMI x1) (mempty :: MI target)
+  ==. (toMI x1 :: MI target)
+      ? mempty_left (toMI x1 :: MI target)
+  ==. toMI (concatString x1 x2)
+      ? concatEmpRight x1 x2 
+  *** QED 
+
+distributestoMI _ x1 x2 
+  | stringLen (fromString (symbolVal (Proxy :: Proxy target))) < 2 
+  =   let tg = (fromString (symbolVal (Proxy :: Proxy target))) in 
+      mappend (toMI x1 :: MI target) (toMI x2 :: MI target)  
+  ==. mappend (MI x1 (makeIndices x1 tg 0 (stringLen x1 - 1)))
+              (MI x2 (makeIndices x2 tg 0 (stringLen x2 - 1)))
+  ==. MI (concatString x1 x2)
+         ((castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+          `append`
+           makeNewIndices x1 x2 tg
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         ((castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+          `append`
+           N
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         (castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+           `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+      ? appendNil (castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1)))
+  ==. MI (concatString x1 x2)
+         (castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+           `append`
+          (makeIndices (concatString x1 x2) tg (stringLen x1) (stringLen x1 + stringLen x2 -1))) 
+      ? shiftIndexesRight' 0 (stringLen x2 - 1) x1 x2 tg 
+  ==. MI (concatString x1 x2)
+         ( (makeIndices (concatString x1 x2) tg 0 (stringLen x1 - 1))
+           `append`
+          (makeIndices (concatString x1 x2) tg (stringLen x1) (stringLen x1 + stringLen x2 -1))) 
+      ? (concatmakeNewIndices 0 (stringLen x1 -1) tg x1 x2) 
+  ==. MI (concatString x1 x2)
+         (makeIndices (concatString x1 x2) tg 0 (stringLen x1 - 1)
+           `append`
+          makeIndices (concatString x1 x2) tg (stringLen x1) (stringLen x1 + stringLen x2 -1)) 
+  ==. MI (concatString x1 x2)
+         (makeIndices (concatString x1 x2) tg 0 (stringLen x1 - 1)
+           `append`
+          makeIndices (concatString x1 x2) tg (stringLen x1) (stringLen (concatString x1 x2) -1)) 
+  ==. MI (concatString x1 x2) 
+         (makeIndices (concatString x1 x2) tg 0 (stringLen (concatString x1 x2) - 1))
+      ? mergeIndices (concatString x1 x2) tg 0 (stringLen x1 -1) (stringLen (concatString x1 x2) - 1) 
+  ==. toMI (concatString x1 x2)
+  *** QED 
+
+distributestoMI _ x1 x2
+  | 0 <= stringLen x1 - stringLen (fromString (symbolVal (Proxy :: Proxy target))) 
+  =   let tg = (fromString (symbolVal (Proxy :: Proxy target))) in 
+      mappend (toMI x1 :: MI target) (toMI x2:: MI target)  
+  ==. mappend (MI x1 (makeIndices x1 tg 0 (stringLen x1 - 1)))
+              (MI x2 (makeIndices x2 tg 0 (stringLen x2 - 1)))
+  ==. MI (concatString x1 x2)
+         ((castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+          `append`
+           makeNewIndices x1 x2 tg
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         ((castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+          `append`
+           makeIndices (concatString x1 x2) tg (maxInt (stringLen x1 - stringLen tg +1) 0) (stringLen x1 -1)
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         ((castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+          `append`
+           makeIndices (concatString x1 x2) tg (stringLen x1 - stringLen tg +1) (stringLen x1 -1)
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         ((makeIndices (concatString x1 x2) tg 0 (stringLen x1 - stringLen tg)
+          `append`
+           makeIndices (concatString x1 x2) tg (stringLen x1 - stringLen tg +1) (stringLen x1 -1)
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+         ? catIndices x1 x2 tg 0 (stringLen x1 -1 ) -- HERE HERE requires stringLen tg <= stringLen x1
+  ==. MI (concatString x1 x2)
+         ((makeIndices (concatString x1 x2) tg 0 (stringLen x1 - stringLen tg)
+          `append`
+           makeIndices (concatString x1 x2) tg (stringLen x1 - stringLen tg +1) (stringLen x1 -1)
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         (makeIndices (concatString x1 x2) tg 0 (stringLen x1 -1)
+         `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+          ? mergeIndices (concatString x1 x2) tg 0 (stringLen x1 -stringLen tg) (stringLen x1-1)
+  ==. MI (concatString x1 x2)
+         (makeIndices (concatString x1 x2) tg 0 (stringLen x1 -1)
+         `append`
+          makeIndices (concatString x1 x2) tg (stringLen x1) (stringLen x1 + stringLen x2 - 1))
+          ? shiftIndexesRight' 0 (stringLen x2 -1) x1 x2 tg 
+  ==. MI (concatString x1 x2)
+         (makeIndices (concatString x1 x2) tg 0 (stringLen x1 -1)
+         `append`
+          makeIndices (concatString x1 x2) tg (stringLen x1) (stringLen (concatString x1 x2) - 1))
+  ==. MI (concatString x1 x2) 
+         (makeIndices (concatString x1 x2) tg 0 (stringLen (concatString x1 x2) - 1))
+          ? mergeIndices (concatString x1 x2) tg 0 (stringLen x1- 1) (stringLen (concatString x1 x2) - 1)
+  ==. toMI (concatString x1 x2)
+  *** QED 
+distributestoMI _ x1 x2
+  | stringLen x1 - stringLen (fromString (symbolVal (Proxy :: Proxy target))) < 0 
+  =   let tg = (fromString (symbolVal (Proxy :: Proxy target))) in 
+      mappend (toMI x1 :: MI target) (toMI x2:: MI target)  
+  ==. mappend (MI x1 (makeIndices x1 tg 0 (stringLen x1 - 1)))
+              (MI x2 (makeIndices x2 tg 0 (stringLen x2 - 1)))
+  ==. MI (concatString x1 x2)
+         ((castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+          `append`
+           makeNewIndices x1 x2 tg
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         ((castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+          `append`
+           makeIndices (concatString x1 x2) tg (maxInt (stringLen x1 - stringLen tg +1) 0) (stringLen x1 -1)
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         ((castGoodIndexRightList tg x1 x2 (makeIndices x1 tg 0 (stringLen x1 - 1))
+          `append`
+           makeIndices (concatString x1 x2) tg 0 (stringLen x1 -1)
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+          
+  ==. MI (concatString x1 x2)
+         ((N
+          `append`
+           makeIndices (concatString x1 x2) tg 0 (stringLen x1 -1)
+          ) `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+         ? makeNewIndicesNullSmallInput x1 tg 0 (stringLen x1 - 1)  
+  ==. MI (concatString x1 x2)
+         (makeIndices (concatString x1 x2) tg 0 (stringLen x1 -1)
+           `append`
+          (map (shiftStringRight tg x1 x2) (makeIndices x2 tg 0 (stringLen x2 - 1)))) 
+  ==. MI (concatString x1 x2)
+         (makeIndices (concatString x1 x2) tg 0 (stringLen x1 -1)
+         `append`
+          makeIndices (concatString x1 x2) tg (stringLen x1) (stringLen x1 + stringLen x2 - 1))
+          ? shiftIndexesRight' 0 (stringLen x2 -1) x1 x2 tg 
+  ==. MI (concatString x1 x2)
+         (makeIndices (concatString x1 x2) tg 0 (stringLen x1 -1)
+         `append`
+          makeIndices (concatString x1 x2) tg (stringLen x1) (stringLen (concatString x1 x2) - 1))
+  ==. MI (concatString x1 x2) 
+         (makeIndices (concatString x1 x2) tg 0 (stringLen (concatString x1 x2) - 1))
+          ? mergeIndices (concatString x1 x2) tg 0 (stringLen x1- 1) (stringLen (concatString x1 x2) - 1)
+  ==. toMI (concatString x1 x2)
+  *** QED 
+
+-------------------------------------------------------------------------------
+----------  Parallelization: pmconcat i is == mconcat is ----------------------
+-------------------------------------------------------------------------------
+
+pmconcatEquivalence :: forall (target :: Symbol). (KnownSymbol target) => Int -> List (MI target) -> Proof
+{-@ pmconcatEquivalence :: i:Int -> is:List (MI target) -> {pmconcat i is == mconcat is} / [llen is] @-}
+pmconcatEquivalence i is 
+  | i <= 1
+  = pmconcat i is ==. mconcat is *** QED 
+pmconcatEquivalence i N 
+  =   pmconcat i N 
+  ==. (mempty :: MI target) 
+  ==. mconcat N 
+  *** QED 
+pmconcatEquivalence i (C x N) 
+  =   pmconcat i (C x N)
+  ==. x 
+  ==. mappend x mempty 
+      ? mempty_left x
+  ==. mappend x (mconcat N) 
+  ==. mconcat (C x N) 
+  *** QED 
+pmconcatEquivalence i xs 
+  | llen xs <= i 
+  =   pmconcat i xs 
+  ==. pmconcat i (map mconcat (chunk i xs))
+  ==. pmconcat i (map mconcat (C xs N))
+  ==. pmconcat i (mconcat xs `C`  map mconcat N)
+  ==. pmconcat i (mconcat xs `C`  N)
+  ==. mconcat xs
+  *** QED 
+pmconcatEquivalence i xs
+  =   pmconcat i xs 
+  ==. pmconcat i (map mconcat (chunk i xs))
+  ==. mconcat (map mconcat (chunk i xs))
+       ? pmconcatEquivalence i (map mconcat (chunk i xs))
+  ==. mconcat xs
+       ? mconcatAssoc i xs
+  *** QED 
+
+-- | Monoid implications 
+
+mconcatAssocOne :: forall (target :: Symbol). (KnownSymbol target) => Int -> List (MI target) -> Proof 
+{-@ mconcatAssocOne :: i:Nat -> xs:{List (MI target) | i <= llen xs} 
+     -> {mconcat xs == mappend (mconcat (take i xs)) (mconcat (drop i xs))}
+     /[i]
+  @-} 
+mconcatAssocOne i N 
+  =   mappend (mconcat (take i N)) (mconcat (drop i N)) 
+  ==. mappend (mconcat N) (mconcat N)
+  ==. mappend (mempty :: MI target) (mempty :: MI target)
+  ==. (mempty :: MI target) 
+      ? mempty_left  (mempty :: MI target)
+  ==. mconcat N 
+  *** QED 
+
+mconcatAssocOne i (C x xs)
+  | i == 0
+  =   mappend (mconcat (take i (C x xs))) (mconcat (drop i (C x xs))) 
+  ==. mappend (mconcat N) (mconcat (C x xs))
+  ==. mappend mempty (mconcat (C x xs))
+  ==. mconcat (C x xs)
+      ? mempty_right (mconcat (C x xs))
+  *** QED 
+  | otherwise    
+  =   mappend (mconcat (take i (C x xs))) (mconcat (drop i (C x xs))) 
+  ==. mappend (mconcat (C x (take (i-1) xs))) (mconcat (drop (i-1) xs))
+  ==. mappend (mappend x (mconcat (take (i-1) xs))) (mconcat (drop (i-1) xs))
+       ? mappend_assoc x (mconcat (take (i-1) xs)) (mconcat (drop (i-1) xs))
+  ==. mappend x (mappend (mconcat (take (i-1) xs)) (mconcat (drop (i-1) xs)))
+       ? mconcatAssocOne (i-1) xs
+  ==. mappend x (mconcat xs)
+  ==. mconcat (C x xs)
+  *** QED 
+
+-- Generalization to chunking  
+
+mconcatAssoc :: forall (target :: Symbol). (KnownSymbol target) => Int -> List (MI target) -> Proof 
+{-@ mconcatAssoc :: i:Int -> xs:List (MI target) 
+  -> { mconcat xs == mconcat (map mconcat (chunk i xs))}
+  /  [llen xs] @-}
+mconcatAssoc i xs  
+  | i <= 1 || llen xs <= i
+  =   mconcat (map mconcat (chunk i xs))
+  ==. mconcat (map mconcat (C xs N))
+  ==. mconcat (mconcat xs `C` map mconcat N)
+  ==. mconcat (mconcat xs `C` N)
+  ==. mappend (mconcat xs) (mconcat N)
+  ==. mappend (mconcat xs) (mempty :: MI target)
+  ==. mconcat xs 
+       ? mempty_left (mconcat xs)
+  *** QED  
+   | otherwise
+   =   mconcat (map mconcat (chunk i xs))
+   ==. mconcat (map mconcat (take i xs `C` chunk i (drop i xs)))
+   ==. mconcat (mconcat (take i xs) `C` map mconcat (chunk i (drop i xs)))
+   ==. mappend (mconcat (take i xs)) (mconcat (map mconcat (chunk i (drop i xs))))
+   ==. mappend (mconcat (take i xs)) (mconcat (drop i xs))
+        ? mconcatAssoc i (drop i xs)
+   ==. mconcat xs 
+        ? mconcatAssocOne i xs 
+   *** QED 
+
+
+-------------------------------------------------------------------------------
+----------  Proof that MI is a Monoid -----------------------------------------
+-------------------------------------------------------------------------------
+
+mempty_left :: forall (target :: Symbol). (KnownSymbol target) => MI target -> Proof
+{-@ mempty_left :: xs:MI target -> {mappend xs mempty == xs } @-}
+mempty_left (MI i1 is1) 
+  = let tg = fromString (symbolVal (Proxy :: Proxy target)) in 
+      mappend (MI i1 is1) (mempty :: MI target)
+  ==. mappend (MI i1 is1) (MI stringEmp N) 
+  ==. MI (concatString i1 stringEmp)
+         ((castGoodIndexRightList tg i1 stringEmp is1
+            `append`
+           makeNewIndices i1 stringEmp tg 
+         ) `append`
+         (map (shiftStringRight tg i1 stringEmp) N))
+      ? concatStringNeutralLeft i1 
+        -- NV ordering is important! 
+        -- concatString i1 stringEmp == i1 should come before application of MI
+  ==. MI i1
+         ((castGoodIndexRightList tg i1 stringEmp is1
+            `append`
+           makeNewIndices i1 stringEmp tg
+         ) `append`
+         (map (shiftStringRight tg i1 stringEmp) N))
+  ==. MI i1 ((is1 `append` N) `append` (map (shiftStringRight tg i1 stringEmp) N))
+      ? makeNewIndicesNullLeft i1 tg 
+  ==. MI i1 (is1 `append` map (shiftStringRight tg i1 stringEmp) N)
+      ? appendNil is1  
+  ==. MI i1 (is1 `append` N)
+      ? appendNil is1  
+  ==. MI i1 is1 
+  *** QED 
+
+mempty_right :: forall (target :: Symbol). (KnownSymbol target) => MI target -> Proof
+{-@ mempty_right :: xs:MI target -> {mappend mempty xs == xs } @-}
+mempty_right (MI i is)
+  =   let tg = (fromString (symbolVal (Proxy :: Proxy target))) in 
+      mappend (mempty :: MI target) (MI i is) 
+  ==. mappend (MI stringEmp N) (MI i is) 
+  ==. MI (concatString stringEmp i)
+       ((castGoodIndexRightList tg stringEmp i N
+          `append`
+        makeNewIndices stringEmp i tg 
+       ) `append`
+       (map (shiftStringRight tg stringEmp i) is)) 
+       ? concatStringNeutralRight i
+  ==. MI i
+        ((N`append` makeNewIndices stringEmp i tg
+        ) `append`
+        (map (shiftStringRight tg stringEmp i) is)) 
+  ==. MI i
+       (makeNewIndices stringEmp i tg
+        `append`
+       (map (shiftStringRight tg stringEmp i) is)) 
+  ==. MI i (N `append` (map (shiftStringRight tg stringEmp i) is)) 
+       ? makeNewIndicesNullRight i tg
+  ==. MI i (map (shiftStringRight tg stringEmp i) is)
+       ? mapShiftZero tg i is 
+  ==. MI i is 
+  *** QED 
+
+{-@ mappend_assoc :: x:MI target -> y:MI target -> z:MI target
+  -> { mappend x (mappend y z) = mappend (mappend x y) z}
+  @-}
+mappend_assoc 
+     :: forall (target :: Symbol). (KnownSymbol target) 
+     => MI target ->  MI target ->  MI target -> Proof
+mappend_assoc x@(MI xi xis) y@(MI yi yis) z@(MI zi zis)
+  | stringLen (fromString (symbolVal (Proxy :: Proxy target))) <= stringLen yi 
+  = let tg = (fromString (symbolVal (Proxy :: Proxy target))) in 
+      mappend x (mappend y z)
+  ==. mappend (MI xi xis) (mappend (MI yi yis) (MI zi zis))
+  ==. mappend (MI xi xis) 
+              (MI (concatString yi zi)
+                  ((castGoodIndexRightList tg yi zi yis
+                     `append`
+                   makeNewIndices yi zi tg
+                   ) `append`
+                  (map (shiftStringRight tg yi zi) zis)))
+  ==. MI (concatString xi (concatString yi zi))
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) ((castGoodIndexRightList tg yi zi yis
+                     `append`
+                   makeNewIndices yi zi tg
+                   ) `append`
+                  (map (shiftStringRight tg yi zi) zis))))
+      ? concatStringAssoc xi yi zi 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) ((castGoodIndexRightList tg yi zi yis
+                     `append`
+                   makeNewIndices yi zi tg
+                   ) `append`
+                  (map (shiftStringRight tg yi zi) zis))))
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) (castGoodIndexRightList tg yi zi yis
+                     `append`
+                   makeNewIndices yi zi tg
+                   ))
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+      ? mapAppend (shiftStringRight tg xi (concatString yi zi))
+                  (castGoodIndexRightList tg yi zi yis
+                     `append`
+                   makeNewIndices yi zi tg
+                   )
+                   (map (shiftStringRight tg yi zi) zis)
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) (castGoodIndexRightList tg yi zi yis)
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)
+           )
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+      ? mapAppend (shiftStringRight tg xi (concatString yi zi))
+                  (castGoodIndexRightList tg yi zi yis)
+                  (makeNewIndices yi zi tg)
+-- ((x1~x2) ~ (x3~x4)) ~ x5
+-- == 
+-- (x1~x2) ~ x3 ~ x4 ~ x5 
+
+  ==. MI (concatString (concatString xi yi) zi)
+         ((((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          map (shiftStringRight tg xi (concatString yi zi)) (castGoodIndexRightList tg yi zi yis))
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)
+           )
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+      ? appendReorder (castGoodIndexRightList tg xi (concatString yi zi) xis)
+                      (makeNewIndices xi (concatString yi zi) tg)
+                      (map (shiftStringRight tg xi (concatString yi zi)) (castGoodIndexRightList tg yi zi yis))
+                      (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))
+                      (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+
+  ==. MI (concatString (concatString xi yi) zi)
+         ((((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis) 
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          map (shiftStringRight tg xi (concatString yi zi)) (castGoodIndexRightList tg yi zi yis))
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)
+           )
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+      ? castConcat tg xi yi zi xis 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis)
+           `append`
+           castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)
+          ) `append`
+          map (shiftStringRight tg xi (concatString yi zi)) (castGoodIndexRightList tg yi zi yis))
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)
+           )
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+      ? shiftIndexesLeft xi yi zi tg 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis)
+           `append`
+           castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)
+          ) `append`
+          castGoodIndexRightList tg (concatString xi yi) zi (map (shiftStringRight tg xi yi) yis))
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)
+           )
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+         ? castEq3 tg xi yi zi yis 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis)
+           `append`
+           castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)
+          ) `append`
+          castGoodIndexRightList tg (concatString xi yi) zi (map (shiftStringRight tg xi yi) yis))
+            `append`
+           makeNewIndices (concatString xi yi) zi tg
+           )
+            `append`
+           map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+         ? shiftIndexesRight xi yi zi tg 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis)
+           `append`
+           castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)
+          ) `append`
+          castGoodIndexRightList tg (concatString xi yi) zi (map (shiftStringRight tg xi yi) yis))
+            `append`
+           makeNewIndices (concatString xi yi) zi tg
+           )
+            `append`
+           map (shiftStringRight tg (concatString xi yi) zi) zis)
+         ? mapLenFusion tg xi yi zi zis 
+  ==. MI (concatString (concatString xi yi) zi)
+         (((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis)
+              `append`
+           castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)
+           ) `append`
+           castGoodIndexRightList tg (concatString xi yi) zi (map (shiftStringRight tg xi yi) yis)
+            `append`
+          makeNewIndices (concatString xi yi) zi tg
+          ) `append`
+         (map (shiftStringRight tg (concatString xi yi) zi) zis)) 
+        ? castAppend tg (concatString xi yi) zi 
+                     (castGoodIndexRightList tg xi yi xis)
+                     (makeNewIndices xi yi tg)
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis
+              `append`
+            makeNewIndices xi yi tg
+           ) `append`
+           castGoodIndexRightList tg (concatString xi yi) zi (map (shiftStringRight tg xi yi) yis)
+            `append`
+          makeNewIndices (concatString xi yi) zi tg
+         ) `append`
+         (map (shiftStringRight tg (concatString xi yi) zi) zis)) 
+        ? castAppend tg (concatString xi yi) zi 
+             (castGoodIndexRightList tg xi yi xis
+              `append`
+             makeNewIndices xi yi tg
+             )
+             (map (shiftStringRight tg xi yi) yis)
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg (concatString xi yi) zi ((castGoodIndexRightList tg xi yi xis
+              `append`
+            makeNewIndices xi yi tg
+           ) `append`
+           (map (shiftStringRight tg xi yi) yis))
+            `append`
+          makeNewIndices (concatString xi yi) zi tg
+         ) `append`
+         (map (shiftStringRight tg (concatString xi yi) zi) zis)) 
+  ==. mappend (
+        MI (concatString xi yi)
+           ((castGoodIndexRightList tg xi yi xis
+              `append`
+            makeNewIndices xi yi tg
+           ) `append`
+           (map (shiftStringRight tg xi yi) yis))) (MI zi zis) 
+  ==. mappend (mappend (MI xi xis) (MI yi yis)) (MI zi zis)
+  *** QED 
+
+mappend_assoc x@(MI xi xis) y@(MI yi yis) z@(MI zi zis)
+  | stringLen yi < stringLen (fromString (symbolVal (Proxy :: Proxy target))) 
+  = let tg = (fromString (symbolVal (Proxy :: Proxy target))) in 
+      mappend x (mappend y z)
+  ==. mappend (MI xi xis) (mappend (MI yi yis) (MI zi zis))
+  ==. mappend (MI xi xis) 
+              (MI (concatString yi zi)
+                  ((castGoodIndexRightList tg yi zi yis
+                     `append`
+                   makeNewIndices yi zi tg
+                   ) `append`
+                  (map (shiftStringRight tg yi zi) zis)))
+  ==. MI (concatString xi (concatString yi zi))
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) ((castGoodIndexRightList tg yi zi yis
+                     `append`
+                   makeNewIndices yi zi tg
+                   ) `append`
+                  (map (shiftStringRight tg yi zi) zis))))
+      ? concatStringAssoc xi yi zi 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) ((castGoodIndexRightList tg yi zi yis
+                     `append`
+                   makeNewIndices yi zi tg
+                   ) `append`
+                  (map (shiftStringRight tg yi zi) zis))))
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) ((castGoodIndexRightList tg yi zi N
+                     `append`
+                   makeNewIndices yi zi tg
+                   ) `append`
+                  (map (shiftStringRight tg yi zi) zis))))
+        ? emptyIndices y yis
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) (
+                   makeNewIndices yi zi tg
+                   `append`
+                  (map (shiftStringRight tg yi zi) zis))))
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg xi (concatString yi zi) xis
+           `append`
+           makeNewIndices xi (concatString yi zi) tg
+          ) `append`
+          (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg) 
+             `append` 
+           map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis)))
+      ? mapAppend (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg) (map (shiftStringRight tg yi zi) zis)
+  ==. MI (concatString (concatString xi yi) zi)
+         (((castGoodIndexRightList tg xi (concatString yi zi) xis)
+           `append`
+           ((makeNewIndices xi (concatString yi zi) tg)
+           `append`
+           (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))))
+            `append`
+           (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis)))
+      ? appendGroupNew (castGoodIndexRightList tg xi (concatString yi zi) xis)
+                       (makeNewIndices xi (concatString yi zi) tg)
+                       (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))
+                       (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+  ==. MI (concatString (concatString xi yi) zi)
+         ( (castGoodIndexRightList tg xi (concatString yi zi) xis)
+           `append`
+           ((castGoodIndexRightList tg (concatString xi yi) zi ((makeNewIndices xi yi) tg))
+           `append`
+           (makeNewIndices (concatString xi yi) zi tg))
+            `append`
+           (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis)))
+      ? shiftNewIndices xi yi zi tg 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((((castGoodIndexRightList tg xi (concatString yi zi) xis)
+           `append`
+           (castGoodIndexRightList tg (concatString xi yi) zi ((makeNewIndices xi yi) tg)))
+           `append`
+           (makeNewIndices (concatString xi yi) zi tg))
+            `append`
+           (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis)))
+      ? appendUnGroupNew (castGoodIndexRightList tg xi (concatString yi zi) xis)
+                         (castGoodIndexRightList tg (concatString xi yi) zi ((makeNewIndices xi yi) tg))
+                         (makeNewIndices (concatString xi yi) zi tg)
+                         (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis))
+  ==. MI (concatString (concatString xi yi) zi)
+         ((((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis))
+           `append`
+           (castGoodIndexRightList tg (concatString xi yi) zi ((makeNewIndices xi yi) tg)))
+           `append`
+           (makeNewIndices (concatString xi yi) zi tg))
+            `append`
+           (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis)))
+      ? castConcat tg xi yi zi xis 
+  ==. MI (concatString (concatString xi yi) zi)
+         ( ((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis)
+            `append`
+             castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)
+           )
+            `append`
+          makeNewIndices (concatString xi yi) zi tg
+           ) `append`
+         (map (shiftStringRight tg (concatString xi yi) zi) zis)) 
+      ? mapLenFusion tg xi yi zi zis 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis
+              `append`
+            makeNewIndices xi yi tg
+           )
+            `append`
+          makeNewIndices (concatString xi yi) zi tg
+           ) `append`
+         (map (shiftStringRight tg (concatString xi yi) zi) zis)) 
+      ? castAppend tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis) (makeNewIndices xi yi tg)
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg (concatString xi yi) zi ((castGoodIndexRightList tg xi yi xis
+              `append`
+            makeNewIndices xi yi tg
+           ) `append`
+           N)
+            `append`
+          makeNewIndices (concatString xi yi) zi tg
+         ) `append`
+         (map (shiftStringRight tg (concatString xi yi) zi) zis)) 
+         ? appendNil (castGoodIndexRightList tg xi yi xis `append` makeNewIndices xi yi tg)
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg (concatString xi yi) zi ((castGoodIndexRightList tg xi yi xis
+              `append`
+            makeNewIndices xi yi tg
+           ) `append`
+           (map (shiftStringRight tg xi yi) N))
+            `append`
+          makeNewIndices (concatString xi yi) zi tg
+         ) `append`
+         (map (shiftStringRight tg (concatString xi yi) zi) zis)) 
+  ==. MI (concatString (concatString xi yi) zi)
+         ((castGoodIndexRightList tg (concatString xi yi) zi ((castGoodIndexRightList tg xi yi xis
+              `append`
+            makeNewIndices xi yi tg
+           ) `append`
+           (map (shiftStringRight tg xi yi) yis))
+            `append`
+          makeNewIndices (concatString xi yi) zi tg
+         ) `append`
+         (map (shiftStringRight tg (concatString xi yi) zi) zis)) 
+         ? emptyIndices y yis 
+  ==. mappend (
+        MI (concatString xi yi)
+           ((castGoodIndexRightList tg xi yi xis
+              `append`
+            makeNewIndices xi yi tg
+           ) `append`
+           (map (shiftStringRight tg xi yi) yis))) (MI zi zis) 
+  ==. mappend (mappend (MI xi xis) (MI yi yis)) (MI zi zis)
+  *** QED 
+
+-------------------------------------------------------------------------------
+----------  Lemmata on Casts --------------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ castAppend :: target:SMTString -> input:SMTString -> x:SMTString 
+     -> is1:List (GoodIndex input target) 
+     -> is2:List (GoodIndex input target) -> 
+   {castGoodIndexRightList target input x (append is1 is2) == append (castGoodIndexRightList target input x is1) (castGoodIndexRightList target input x is2)}
+    @-}
+castAppend :: SMTString -> SMTString -> SMTString -> List Int -> List Int -> Proof 
+castAppend target input x is1 is2 
+  =   castGoodIndexRightList target input x (append is1 is2)
+  ==. append is1 is2 
+  ==. append (castGoodIndexRightList target input x is1) (castGoodIndexRightList target input x is2)
+  *** QED 
+
+castConcat :: SMTString -> SMTString -> SMTString -> SMTString -> List Int -> Proof
+{-@ castConcat :: tg:SMTString -> xi:SMTString -> yi:SMTString -> zi:SMTString 
+             ->  xis:List (GoodIndex xi tg) 
+        -> {castGoodIndexRightList tg xi (concatString yi zi) xis == castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis)} @-}
+castConcat tg xi yi zi xis 
+  =   castGoodIndexRightList tg xi (concatString yi zi) xis
+  ==. xis 
+  ==. castGoodIndexRightList tg xi yi xis
+  ==. castGoodIndexRightList tg (concatString xi yi) zi (castGoodIndexRightList tg xi yi xis)
+  *** QED 
+
+
+castEq3 :: SMTString -> SMTString -> SMTString -> SMTString -> List Int -> Proof
+{-@ castEq3 :: tg:SMTString -> xi:SMTString -> yi:SMTString -> zi:SMTString 
+             ->  yis:List (GoodIndex yi tg) 
+        -> {castGoodIndexRightList tg (concatString xi yi) zi (map (shiftStringRight tg xi yi) yis) == map (shiftStringRight tg xi (concatString yi zi)) (castGoodIndexRightList tg yi zi yis)} @-}
+castEq3 tg xi yi zi yis 
+  =   castGoodIndexRightList tg (concatString xi yi) zi (map (shiftStringRight tg xi yi) yis)
+  ==. map (shiftStringRight tg xi yi) yis 
+  ==. map (shiftStringRight tg xi (concatString yi zi)) (castGoodIndexRightList tg yi zi yis)
+        ? mapShiftIndex tg xi yi zi yis 
+  *** QED 
+
+
+-------------------------------------------------------------------------------
+----------  Lemmata on Lists --------------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ appendNil :: xs:List a -> { append xs N = xs } @-} 
+appendNil :: List a -> Proof 
+appendNil N 
+  =   append N N
+  ==. N
+  *** QED 
+appendNil (C x xs) 
+  =   append (C x xs) N
+  ==. C x (append xs N)
+  ==. C x xs ? appendNil xs 
+  *** QED 
+
+-- (x1 ~ x2) ~ (x3 ~ x4)
+-- == 
+-- ((x1 ~ (x2 ~ x3)) ~ x4)
+
+
+appendGroupNew :: List a -> List a -> List a -> List a -> Proof
+{-@ appendGroupNew 
+  :: x1:List a 
+  -> x2:List a 
+  -> x3:List a 
+  -> x4:List a 
+  -> {   (append (append x1 x2) (append x3 x4))
+      == (append (append x1 (append x2 x3)) x4)
+     } @-}
+appendGroupNew x1 x2 x3 x4 
+  =   (append (append x1 x2) (append x3 x4))
+  ==. (append (append (append x1 x2) x3) x4)
+      ? appendAssoc (append x1 x2) x3 x4  
+  ==. (append (append x1 (append x2 x3)) x4)
+      ? appendAssoc x1 x2 x3
+  *** QED 
+
+
+
+-- (x1 ~ (x2 ~ x3)) ~ x4 == ((x1 ~ x2) ~ x3) ~ x4
+
+appendUnGroupNew :: List a -> List a -> List a -> List a -> Proof
+{-@ appendUnGroupNew 
+  :: x1:List a 
+  -> x2:List a 
+  -> x3:List a 
+  -> x4:List a 
+  -> {   ((append (append (append x1 x2) x3) x4))
+      == (append (append x1 (append x2 x3)) x4)
+     } @-}
+appendUnGroupNew x1 x2 x3 x4 
+  =   append (append (append x1 x2) x3) x4
+  ==. append (append x1 (append x2 x3)) x4
+      ? appendAssoc x1 x2 x3 
+  *** QED 
+
+
+
+appendReorder :: List a -> List a -> List a -> List a -> List a -> Proof
+{-@ appendReorder 
+  :: x1:List a 
+  -> x2:List a 
+  -> x3:List a 
+  -> x4:List a 
+  -> x5:List a 
+  -> {   (append (append x1 x2) (append (append x3 x4) x5))
+      == (append (append (append (append x1 x2) x3) x4) x5)
+     } @-}
+appendReorder x1 x2 x3 x4 x5 
+  =   append (append x1 x2) (append (append x3 x4) x5)
+  ==. append (append x1 x2) (append x3 (append x4 x5))
+       ? appendAssoc x3 x4 x5 
+  ==. append (append (append x1 x2) x3) (append x4 x5)
+      ? appendAssoc (append x1 x2) x3 (append x4 x5) 
+  ==. append ((append (append (append x1 x2) x3)) x4) x5
+      ? appendAssoc (append (append x1 x2) x3) x4 x5 
+  *** QED 
+
+{-@ appendAssoc :: x:List a -> y:List a -> z:List a 
+     -> {(append x (append y z)) == (append (append x y) z) } @-}
+appendAssoc :: List a -> List a -> List a -> Proof
+appendAssoc N y z 
+  =   append N (append y z)
+  ==. append y z
+  ==. append (append N y) z
+  *** QED 
+appendAssoc (C x xs) y z
+  =   append (C x xs) (append y z) 
+  ==. C x (append xs (append y z))
+  ==. C x (append (append xs y) z)
+        ? appendAssoc xs y z
+  ==. append (C x (append xs y)) z
+  ==. append (append (C x xs) y) z
+  *** QED 
+
+
+mapAppend :: (a -> b) -> List a -> List a -> Proof
+{-@ mapAppend 
+     :: f:(a -> b) -> xs:List a -> ys:List a 
+     -> {map f (append xs ys) == append (map f xs) (map f ys)}
+  @-}
+mapAppend f N ys 
+  =   map f (append N ys)
+  ==. map f ys 
+  ==. append N (map f ys)
+  ==. append (map f N) (map f ys)
+  *** QED 
+mapAppend f (C x xs) ys 
+  =   map f (append (C x xs) ys)
+  ==. map f (x `C` (append xs ys))
+  ==. f x `C` (map f (append xs ys))
+  ==. f x `C` (append (map f xs) (map f ys))
+      ? mapAppend f xs ys 
+  ==. append (f x `C` map f xs) (map f ys)
+  ==. append (map f (x `C` xs)) (map f ys)
+  *** QED 
+
+
+-------------------------------------------------------------------------------
+----------  Lemmata on Empty Indices ------------------------------------------
+-------------------------------------------------------------------------------
+
+emptyIndices :: forall (target :: Symbol). (KnownSymbol target) => MI target -> List Int  -> Proof
+{-@ emptyIndices :: mi:MI target
+                 -> is:{List (GoodIndex (inputMI mi) target) | is == indicesMI mi && stringLen (inputMI mi) < stringLen target}
+                 -> { is == N } @-}
+emptyIndices (MI _ _) N 
+  = trivial 
+emptyIndices (MI _ _) (C _ _)
+  = trivial 
+
+makeNewIndicesNullLeft :: SMTString -> SMTString -> Proof 
+{-@ makeNewIndicesNullLeft 
+  :: s:SMTString 
+  -> t:SMTString 
+  -> {makeNewIndices s stringEmp t == N } @-} 
+makeNewIndicesNullLeft s t 
+  | stringLen t < 2 
+  = makeNewIndices s stringEmp t ==. N *** QED 
+makeNewIndicesNullLeft  s t 
+  | 1 + stringLen s <= stringLen t
+  =   makeNewIndices s stringEmp t
+  ==. makeIndices (concatString s stringEmp) t
+                   (maxInt (1 + stringLen s - stringLen t)  0)
+                   (stringLen s - 1)
+  ==. makeIndices s t
+                   0
+                   (stringLen s - 1) 
+                   ? concatStringNeutralLeft s
+  ==. makeIndices s t
+                   0
+                   (stringLen s - 1)
+  ==. N ? makeNewIndicesNullSmallInput s t 0 (stringLen s - 1)
+  *** QED 
+makeNewIndicesNullLeft s t 
+  =   makeNewIndices s stringEmp t
+  ==. makeIndices (concatString s stringEmp) t
+                   (maxInt (1 + stringLen s - stringLen t)  0)
+                   (stringLen s - 1)
+  ==. makeIndices (concatString s stringEmp) t
+                   (1 + stringLen s - stringLen t)
+                   (stringLen s - 1)
+  ==. makeIndices s t
+                   (1 + stringLen s - stringLen t)
+                   (stringLen s - 1) ? concatStringNeutralLeft s 
+  ==. N ? makeNewIndicesNullSmallIndex s t (1 + stringLen s - stringLen t) (stringLen s - 1)
+  *** QED 
+
+makeNewIndicesNullSmallInput :: SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ makeNewIndicesNullSmallInput 
+  :: s:SMTString 
+  -> t:{SMTString | 1 + stringLen s <= stringLen t } 
+  -> lo:Nat 
+  -> hi:Int
+  -> {makeIndices s t lo hi == N } / [hi - lo] @-} 
+makeNewIndicesNullSmallInput s1 t lo hi
+  | hi < lo 
+  = makeIndices s1 t lo hi ==. N *** QED 
+  | lo == hi, not (isGoodIndex s1 t lo)
+  = makeIndices s1 t lo hi ==. N *** QED  
+  | not (isGoodIndex s1 t lo)
+  =   makeIndices s1 t lo hi
+  ==. makeIndices s1 t (lo + 1) hi 
+  ==. N ? makeNewIndicesNullSmallInput s1 t (lo+1) hi
+  *** QED 
+
+
+makeNewIndicesNullSmallIndex :: SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ makeNewIndicesNullSmallIndex 
+  :: s:SMTString 
+  -> t:{SMTString | stringLen t < 2 + stringLen s } 
+  -> lo:{Nat | 1 + stringLen s - stringLen t <= lo  } 
+  -> hi:{Int | lo <= hi}
+  -> {makeIndices s t lo hi == N } / [hi - lo] @-} 
+makeNewIndicesNullSmallIndex s1 t lo hi
+  | lo == hi, not (isGoodIndex s1 t lo)
+  = makeIndices s1 t lo hi ==. N *** QED  
+  | not (isGoodIndex s1 t lo)
+  =   makeIndices s1 t lo hi
+  ==. makeIndices s1 t (lo + 1) hi 
+  ==. N ? makeNewIndicesNullSmallIndex s1 t (lo+1) hi
+  *** QED 
+
+
+makeNewIndicesNullRight :: SMTString -> SMTString -> Proof 
+{-@ makeNewIndicesNullRight 
+  :: s1:SMTString 
+  -> t:SMTString 
+  -> {makeNewIndices stringEmp s1 t == N } @-} 
+makeNewIndicesNullRight s t 
+  | stringLen t < 2 
+  = makeNewIndices stringEmp s t  ==. N *** QED 
+makeNewIndicesNullRight s t 
+  =   makeNewIndices stringEmp s t
+  ==. makeIndices (concatString stringEmp s) t
+                   (maxInt (1 + stringLen stringEmp - stringLen t) 0)
+                   (stringLen stringEmp - 1)
+  ==. makeIndices s t
+                   (maxInt (1 - stringLen t) 0)
+                   (-1)
+      ? concatStringNeutralRight s 
+  ==. makeIndices s t 0 (-1)
+  ==. N  
+  *** QED
+
+-------------------------------------------------------------------------------
+----------  Lemmata on Shifting Indices ---------------------------------------
+-------------------------------------------------------------------------------
+
+mapLenFusion :: SMTString -> SMTString -> SMTString -> SMTString -> List Int -> Proof
+{-@ mapLenFusion :: tg:SMTString -> xi:SMTString -> yi:SMTString -> zi:SMTString 
+            -> zis:List (GoodIndex zi tg) 
+        -> {map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) zis) == map (shiftStringRight tg (concatString xi yi) zi) zis} 
+        / [llen zis ] @-}
+mapLenFusion tg xi yi zi N  
+  =   map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) N)
+  ==. map (shiftStringRight tg xi (concatString yi zi)) N 
+  ==. N 
+  ==. map (shiftStringRight tg (concatString xi yi) zi) N 
+  *** QED  
+mapLenFusion tg xi yi zi (C i is)  
+  =   map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) (C i is))
+  ==. map (shiftStringRight tg xi (concatString yi zi)) (shiftStringRight tg yi zi i `C` map (shiftStringRight tg yi zi) is)
+  ==. shiftStringRight tg xi (concatString yi zi) (shiftStringRight tg yi zi i) `C` (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) is))
+  ==. shiftStringRight tg (concatString xi yi) zi i `C` (map (shiftStringRight tg xi (concatString yi zi)) (map (shiftStringRight tg yi zi) is))
+  ==. shiftStringRight tg (concatString xi yi) zi i `C` (map (shiftStringRight tg (concatString xi yi) zi) is)
+       ? mapLenFusion tg xi yi zi is 
+  ==. map (shiftStringRight tg (concatString xi yi) zi) (C i is)
+  *** QED  
+
+{-@ shiftIndexesRight
+  :: xi:SMTString 
+  -> yi:SMTString 
+  -> zi:SMTString 
+  -> tg:{SMTString | stringLen tg <= stringLen yi } 
+  -> { map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg) == makeNewIndices (concatString xi yi) zi tg }
+  @-}
+shiftIndexesRight :: SMTString -> SMTString -> SMTString -> SMTString -> Proof
+shiftIndexesRight xi yi zi tg
+  | stringLen tg < 2 
+  =   makeNewIndices (concatString xi yi) zi tg 
+  ==. N
+  ==. map (shiftStringRight tg xi (concatString yi zi)) N
+  ==. map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)
+  *** QED 
+shiftIndexesRight xi yi zi tg
+-- NV NV NV 
+-- This is suspicious!!! it should require exactly the precondition 
+-- || tg || <= || yi || 
+--   | stringLen tg  <= stringLen yi + 1 
+  =   makeNewIndices (concatString xi yi) zi tg  
+  ==. makeIndices (concatString (concatString xi yi) zi) tg 
+                   (maxInt (stringLen (concatString xi yi) - (stringLen tg -1)) 0)
+                   (stringLen (concatString xi yi) - 1 )
+  ==. makeIndices (concatString (concatString xi yi) zi) tg 
+                   (stringLen (concatString xi yi) - (stringLen tg -1))
+                   (stringLen (concatString xi yi) - 1 )
+  ==. makeIndices (concatString (concatString xi yi) zi) tg 
+                   (stringLen xi + stringLen yi - stringLen tg + 1)
+                   (stringLen xi + stringLen yi - 1 )
+  ==. makeIndices (concatString xi (concatString yi zi)) tg 
+                   (stringLen xi + stringLen yi - stringLen tg + 1)
+                   (stringLen xi + stringLen yi - 1 )
+       ?concatStringAssoc xi yi zi
+  ==. map (shiftStringRight tg xi (concatString yi zi)) (makeIndices (concatString yi zi) tg (stringLen yi - stringLen tg + 1) (stringLen yi - 1))
+       ? shiftIndexesRight' (stringLen yi - stringLen tg + 1)
+                            (stringLen yi - 1)
+                            xi 
+                            (concatString yi zi)
+                            tg 
+  ==. map (shiftStringRight tg xi (concatString yi zi)) 
+               (makeIndices (concatString yi zi) tg 
+                             (maxInt (stringLen yi - (stringLen tg -1)) 0)
+                             (stringLen yi -1))
+  ==. map (shiftStringRight tg xi (concatString yi zi)) 
+          (makeNewIndices yi zi tg)
+  *** QED
+
+{-@ shiftIndexesRight'
+  :: lo:Nat 
+  -> hi:Int  
+  -> x:SMTString 
+  -> input:SMTString 
+  -> target:SMTString
+  -> { map (shiftStringRight target x input) (makeIndices input target lo hi) == makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi) }
+  / [if hi < lo then 0 else  hi-lo]
+  @-}
+shiftIndexesRight' :: Int -> Int -> SMTString -> SMTString -> SMTString -> Proof
+shiftIndexesRight' lo hi x input target
+  | hi < lo 
+  =   map (shiftStringRight target x input) (makeIndices input target lo hi)
+  ==. map (shiftStringRight target x input) N
+  ==. N
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+  *** QED 
+  | lo == hi, isGoodIndex input target lo 
+  =   map (shiftStringRight target x input) (makeIndices input target lo hi)
+  ==. map (shiftStringRight target x input) (lo `C` N)
+  ==. (shiftStringRight target x input lo) `C` (map (shiftStringRight target x input) N)
+  ==. (stringLen x + lo) `C` N
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+     ? isGoodIndexConcatFront input x target lo  -- ( => IsGoodIndex (concatString x input) target (stringLen x + lo))
+  *** QED 
+  | lo == hi
+  =   map (shiftStringRight target x input) (makeIndices input target lo hi)
+  ==. map (shiftStringRight target x input) N
+  ==. N
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+     ? (isGoodIndexConcatFront input x target lo *** QED)
+  *** QED 
+
+shiftIndexesRight' lo hi x input target
+  | isGoodIndex input target lo
+  =   map (shiftStringRight target x input) (makeIndices input target lo hi)
+  ==. map (shiftStringRight target x input) (lo `C` makeIndices input target (lo+1) hi)
+  ==. (shiftStringRight target x input lo) `C` (map (shiftStringRight target x input) (makeIndices input target (lo+1) hi))
+  ==. (shift (stringLen x) lo) `C` (makeIndices (concatString x input) target (stringLen x + (lo+1)) (stringLen x + hi))
+      ? shiftIndexesRight' (lo+1) hi x input target
+  ==. (stringLen x + lo) `C` (makeIndices (concatString x input) target (stringLen x + (lo+1)) (stringLen x + hi))
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+     ? (isGoodIndexConcatFront input x target lo *** QED)
+  *** QED 
+  | otherwise
+  =   map (shiftStringRight target x input) (makeIndices input target lo hi)
+  ==. map (shiftStringRight target x input) (makeIndices input target (lo + 1) hi)
+  ==. makeIndices (concatString x input) target (stringLen x + (lo+1)) (stringLen x + hi)
+      ? shiftIndexesRight' (lo+1) hi x input target
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+     ? (isGoodIndexConcatFront input x target lo *** QED)
+  *** QED 
+
+
+{-@ shiftIndexesLeft
+  :: xi:SMTString 
+  -> yi:SMTString 
+  -> zi:SMTString 
+  -> tg:{SMTString | stringLen tg <= stringLen yi } 
+  -> {  makeNewIndices xi (concatString yi zi) tg == castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)}
+  @-}
+shiftIndexesLeft :: SMTString -> SMTString -> SMTString -> SMTString -> Proof
+shiftIndexesLeft xi yi zi tg
+  | stringLen tg < 2 
+  =   makeNewIndices xi (concatString yi zi) tg 
+  ==. N
+  ==. makeNewIndices xi yi tg 
+  ==. castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)
+  *** QED 
+  | otherwise
+  =   makeNewIndices xi (concatString yi zi) tg 
+  ==. makeIndices (concatString xi (concatString yi zi)) tg 
+                   (maxInt (stringLen xi - (stringLen tg-1)) 0)
+                   (stringLen xi - 1)
+  ==. makeIndices (concatString (concatString xi yi) zi) tg 
+                   (maxInt (stringLen xi - (stringLen tg-1)) 0)
+                   (stringLen xi - 1)
+     ?concatStringAssoc xi yi zi 
+  ==. makeIndices (concatString xi yi) tg 
+                   (maxInt (stringLen xi - (stringLen tg-1)) 0)
+                   (stringLen xi - 1)                
+      ? concatmakeNewIndices (maxInt (stringLen xi - (stringLen tg-1)) 0) (stringLen xi - 1) tg (concatString xi yi) zi 
+  ==. makeNewIndices xi yi tg 
+  ==. castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)
+  *** QED 
+
+{-@ concatmakeNewIndices
+  :: lo:Nat -> hi:Int
+  -> target: SMTString
+  -> input : {SMTString | hi + stringLen target <= stringLen input } 
+  -> input': SMTString   
+  -> {  makeIndices (concatString input input') target lo hi == makeIndices input target lo hi }
+  / [hi - lo]  @-}
+concatmakeNewIndices :: Int -> Int -> SMTString -> SMTString -> SMTString  -> Proof
+concatmakeNewIndices lo hi target input input'
+  | hi < lo 
+  =   makeIndices input target lo hi
+  ==. N
+  ==. makeIndices (concatString input input') target lo hi 
+  *** QED 
+  | lo == hi, isGoodIndex input target lo
+  =   makeIndices input target lo hi
+  ==. lo `C` N
+  ==. makeIndices (concatString input input') target lo hi 
+      ? isGoodIndexConcatString input input' target lo  
+  *** QED 
+  | lo == hi
+  =  makeIndices input target lo hi 
+  ==. N
+  ==. makeIndices (concatString input input') target lo hi
+      ? isGoodIndexConcatString input input' target lo  
+  *** QED 
+concatmakeNewIndices lo hi target input input' 
+  | isGoodIndex input target lo
+  =   makeIndices input target lo hi
+  ==. lo `C` (makeIndices input target (lo + 1) hi)
+  ==. lo `C` (makeIndices (concatString input input') target (lo + 1) hi)
+       ? concatmakeNewIndices (lo+1) hi target input input'
+  ==. makeIndices  (concatString input input') target lo hi
+      ? isGoodIndexConcatString input input' target lo  
+  *** QED 
+  | otherwise 
+  =   makeIndices input target lo hi
+  ==. makeIndices input target (lo + 1) hi
+  ==. makeIndices (concatString input input') target (lo + 1) hi
+       ? concatmakeNewIndices (lo+1) hi target input input'
+  ==. makeIndices  (concatString input input') target lo hi
+      ? isGoodIndexConcatString input input' target lo  
+  *** QED 
+
+
+
+{-@ isGoodIndexConcatFront 
+  :: input:SMTString -> input':SMTString -> tg:SMTString -> i:Nat
+  -> {((isGoodIndex input tg i) <=> isGoodIndex (concatString input' input) tg (stringLen input' + i) )
+     } @-}
+isGoodIndexConcatFront :: SMTString -> SMTString -> SMTString -> Int -> Proof 
+isGoodIndexConcatFront input input' tg i 
+  =   isGoodIndex input tg i 
+  ==. (subString input i (stringLen tg)  == tg  
+      && i + stringLen tg <= stringLen input 
+      && 0 <= i)  
+  ==. (subString input i (stringLen tg)  == tg  
+      && (stringLen input' + i) + stringLen tg <= stringLen (concatString input' input) 
+      && 0 <= i)  
+  ==. (subString (concatString input' input) (stringLen input' + i) (stringLen tg)  == tg  
+      && (stringLen input' + i) + stringLen tg <= stringLen (concatString input' input) 
+      && 0 <= (stringLen input' + i))  
+      ? (subStringConcatFront input input' (stringLen tg) i *** QED)
+  ==. isGoodIndex (concatString input' input) tg (stringLen input' + i) 
+  *** QED 
+
+
+{-@ isGoodIndexConcatString 
+  :: input:SMTString -> input':SMTString -> tg:SMTString -> i:{Int | i + stringLen tg <= stringLen input }
+  -> {((isGoodIndex input tg i) <=> isGoodIndex (concatString input input') tg i)
+     } @-}
+isGoodIndexConcatString :: SMTString -> SMTString -> SMTString -> Int -> Proof 
+isGoodIndexConcatString input input' tg i 
+  =   isGoodIndex input tg i 
+  ==. (subString input i (stringLen tg)  == tg  
+      && i + stringLen tg <= stringLen input
+      && 0 <= i) 
+  ==. (subString (concatString input input') i (stringLen tg)  == tg  
+      && i + stringLen tg <= stringLen input 
+      && 0 <= i)   
+      ? (subStringConcatBack input input' (stringLen tg) i *** QED )
+  ==. (subString (concatString input input') i (stringLen tg)  == tg  
+      && i + stringLen tg <= stringLen (concatString input input') 
+      && 0 <= i)   
+      ? (((stringLen input <= stringLen (concatString input input') *** QED ) &&& (concatLen input input') *** QED))
+  ==. isGoodIndex (concatString input input') tg i 
+  *** QED 
+
+
+mapShiftZero :: SMTString -> SMTString -> List Int -> Proof
+{-@ mapShiftZero :: target:SMTString -> i:SMTString -> is:List (GoodIndex i target) 
+  -> {map (shiftStringRight target stringEmp i) is == is } 
+  / [llen is] @-}
+mapShiftZero target i N
+  =   map (shiftStringRight target stringEmp i) N ==. N *** QED  
+mapShiftZero target i (C x xs)
+  =   map (shiftStringRight target stringEmp i) (C x xs) 
+  ==. shiftStringRight target stringEmp i x `C` map (shiftStringRight target stringEmp i) xs
+  ==. shift (stringLen stringEmp) x `C` map (shiftStringRight target stringEmp i) xs
+  ==. shift 0 x `C` map (shiftStringRight target stringEmp i) xs
+  ==. x `C` map (shiftStringRight target stringEmp i) xs
+  ==. x `C` xs ? mapShiftZero target i xs 
+  *** QED 
+
+
+{-@ mapShiftIndex :: tg:SMTString -> xi:SMTString -> yi:SMTString -> zi:SMTString -> xs:List (GoodIndex yi tg)
+  -> {map (shiftStringRight tg xi yi) xs == map (shiftStringRight tg xi (concatString yi zi)) xs} / [llen xs] @-}
+mapShiftIndex :: SMTString -> SMTString -> SMTString -> SMTString -> List Int -> Proof
+mapShiftIndex tg xi yi zi N 
+  = map (shiftStringRight tg xi yi) N ==. N ==. map (shiftStringRight tg xi (concatString yi zi)) N *** QED 
+  *** QED 
+mapShiftIndex tg xi yi zi zs@(C i0 is0)
+  =   let is = castGoodIndexRightList tg yi zi is0 
+          i  = castGoodIndexRight     tg yi zi i0  in 
+      map (shiftStringRight tg xi yi) (C i is) 
+  ==. C (shiftStringRight tg xi yi i) (map (shiftStringRight tg xi yi) is)
+  ==. C (shift (stringLen xi) i) (map (shiftStringRight tg xi yi) is)
+  ==. C (shiftStringRight tg xi (concatString yi zi) i) (map (shiftStringRight tg xi yi) is)
+  ==. C (shiftStringRight tg xi (concatString yi zi) i) (map (shiftStringRight tg xi (concatString yi zi)) is)
+       ? mapShiftIndex tg xi yi zi is
+  ==. map (shiftStringRight tg xi (concatString yi zi)) (C i is)
+  *** QED 
+
+
+
+{-@ shiftNewIndices
+  :: xi:SMTString 
+  -> yi:SMTString 
+  -> zi:SMTString 
+  -> tg:{SMTString | stringLen yi < stringLen tg  } 
+  -> {  append (makeNewIndices xi (concatString yi zi) tg) (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)) == append (castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)) (makeNewIndices (concatString xi yi) zi tg)
+     }
+  @-}
+shiftNewIndices :: SMTString -> SMTString -> SMTString -> SMTString -> Proof
+shiftNewIndices xi yi zi tg 
+  | stringLen tg < 2 
+  =   append (makeNewIndices xi (concatString yi zi) tg) (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)) 
+  ==. append N (map (shiftStringRight tg xi (concatString yi zi)) N) 
+  ==. map (shiftStringRight tg xi (concatString yi zi)) N 
+  ==. N 
+  ==. append N N
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+
+shiftNewIndices xi yi zi tg 
+  | stringLen xi == 0 
+  =   append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))
+  ==. append (makeNewIndices stringEmp (concatString yi zi) tg) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))
+  ? stringEmpProp xi 
+  ==. append (makeNewIndices stringEmp (concatString yi zi) tg) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))
+  ? makeNewIndicesNullRight (concatString yi zi) tg
+  ==. append N
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))
+  ==. map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)
+       ? stringEmpProp xi
+  ==. map (shiftStringRight tg stringEmp (concatString yi zi)) (makeNewIndices yi zi tg)
+      ? mapShiftZero tg (concatString yi zi) (makeNewIndices yi zi tg)
+  ==. makeNewIndices yi zi tg
+  ==. makeNewIndices (concatString xi yi) zi tg
+        ? concatEmpLeft xi yi 
+  ==. append N (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (makeNewIndices stringEmp yi tg) (makeNewIndices (concatString xi yi) zi tg)
+       ? makeNewIndicesNullRight yi tg
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+      ? stringEmpProp xi
+  ==. append (castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+  | stringLen yi == 0 
+  =   append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))
+  ==. append (makeNewIndices xi zi tg) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg))
+      ? (stringEmpProp yi &&& concatEmpLeft yi zi)
+  ==. append (makeNewIndices xi zi tg) 
+                  (map (shiftStringRight tg xi zi) (makeNewIndices stringEmp zi tg))
+  ==. append (makeNewIndices xi zi tg) 
+                  (map (shiftStringRight tg xi (concatString stringEmp zi)) N)
+      ? makeNewIndicesNullRight zi tg 
+  ==. append (makeNewIndices xi zi tg) 
+                  N
+  ==. makeNewIndices xi zi tg 
+       ? appendNil (makeNewIndices xi zi tg)
+  ==. makeNewIndices (concatString xi yi) zi tg
+       ? concatEmpRight xi yi
+  ==. append N (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (makeNewIndices xi stringEmp tg) (makeNewIndices (concatString xi yi) zi tg)
+       ? makeNewIndicesNullLeft xi tg 
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)) (makeNewIndices (concatString xi yi) zi tg)
+       ? stringEmpProp yi
+  *** QED 
+  | stringLen yi - stringLen tg == -1 
+  = let minidx = maxInt (stringLen xi - stringLen tg + 1) 0 in 
+      append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          (maxInt (stringLen yi - stringLen tg +1) 0)
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          (maxInt 0 0)
+                                          (stringLen yi -1)
+                            ))  
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          0
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString xi (concatString yi zi)) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? shiftIndexesRight' 0 (stringLen yi -1) xi (concatString yi zi) tg 
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? concatStringAssoc xi yi zi 
+
+  ==. append (append 
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi)
+                                (stringLen xi -1))
+
+                                ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) 
+      ? mergeIndices (concatString (concatString xi yi) zi) tg 
+                     minidx -- maxInt (stringLen xi - stringLen tg + 1) 0
+                     (stringLen xi -1)
+                     (stringLen xi -1)
+  ==. append (append 
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                  N
+
+                                ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) 
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) 
+      ? appendNil (makeIndices (concatString (concatString xi yi) zi) tg
+                                    minidx
+                                    (stringLen xi + stringLen yi - stringLen tg))
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi -1))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                ((stringLen xi))
+                                (stringLen xi + stringLen yi -1))
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx 
+                                (stringLen (concatString xi yi)  - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1))
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+      ? catIndices (concatString xi yi) zi tg minidx (stringLen xi-1)
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx 
+                                -- maxInt (stringLen xi - stringLen tg + 1) 0 && 2 <= stringLen tg
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen xi) 0)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen xi + stringLen yi - stringLen tg + 1) 0)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeIndices (concatString xi yi) tg 
+                                (maxInt (stringLen xi - stringLen tg +1) 0)
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+shiftNewIndices xi yi zi tg 
+-- THIS ALWAYS HOLDS 
+--   | stringLen yi + 1 <= stringLen tg
+  | 0 <= stringLen xi + stringLen yi - stringLen tg
+ --  , 0 < stringLen xi 
+  = let minidx = maxInt (stringLen xi - stringLen tg + 1) 0 in 
+      append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          (maxInt (stringLen yi - stringLen tg +1) 0)
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) 
+                            (makeIndices (concatString yi zi) tg
+                                           0
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString xi (concatString yi zi)) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? shiftIndexesRight' 0 (stringLen yi -1) xi (concatString yi zi) tg 
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? concatStringAssoc xi yi zi 
+
+  ==. append (append 
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg + 1)
+                                (stringLen xi -1))
+
+                                ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) 
+      ? mergeIndices (concatString (concatString xi yi) zi) tg 
+                     minidx -- maxInt (stringLen xi - stringLen tg + 1) 0
+                     (stringLen xi + stringLen yi - stringLen tg)
+                     (stringLen xi -1)
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx 
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                 (append
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg +1)
+                                (stringLen xi -1))
+
+                                
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) )
+      ? appendAssoc
+              (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+              (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg+1)
+                                (stringLen xi -1))
+              (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1))
+
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                ((stringLen xi + stringLen yi - stringLen tg+1))
+                                (stringLen xi + stringLen yi -1))
+     ? mergeIndices (concatString (concatString xi yi) zi) tg 
+                  ((stringLen xi + stringLen yi - stringLen tg+1))
+                  (stringLen xi-1)
+                  (stringLen xi + stringLen yi -1)
+
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx 
+                                (stringLen (concatString xi yi)  - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg + 1)
+                                (stringLen xi + stringLen yi -1))
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg + 1)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+      ? catIndices (concatString xi yi) zi tg minidx (stringLen xi-1)
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen xi + stringLen yi - stringLen tg + 1) 0)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeIndices (concatString xi yi) tg 
+                                (maxInt (stringLen xi - stringLen tg +1) 0)
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+
+--   | stringLen yi + 1 <= stringLen tg
+  | stringLen xi + stringLen yi < stringLen tg
+  =   append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) (makeNewIndices yi zi tg)) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          (maxInt (stringLen yi - stringLen tg +1) 0)
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                0
+                                (stringLen xi -1)) 
+                  (map (shiftStringRight tg xi (concatString yi zi)) 
+                            (makeIndices (concatString yi zi) tg
+                                           0
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                0
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString xi (concatString yi zi)) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? shiftIndexesRight' 0 (stringLen yi -1) xi (concatString yi zi) tg 
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                0
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? concatStringAssoc xi yi zi 
+
+  ==. makeIndices (concatString (concatString xi yi) zi) tg
+                                0
+                                (stringLen (concatString xi yi) - 1)
+      ? mergeIndices (concatString (concatString xi yi) zi) tg 
+                    0 
+                    (stringLen xi-1) 
+                    (stringLen (concatString xi yi) -1)
+
+  ==. append N    (makeIndices (concatString (concatString xi yi) zi) tg
+                                0
+                                (stringLen (concatString xi yi) - 1)
+                  )
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                0
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                0
+                                (stringLen (concatString xi yi) - 1)
+                  )
+      ? smallInput (concatString xi yi) tg 0 (stringLen xi -1)
+  ==. append (makeIndices (concatString xi yi) tg 
+                                (maxInt (stringLen xi - stringLen tg +1) 0)
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (castGoodIndexRightList tg (concatString xi yi) zi (makeNewIndices xi yi tg)) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+
+
+smallInput :: SMTString -> SMTString -> Int -> Int -> Proof  
+{-@ smallInput :: input:SMTString -> target:{SMTString | stringLen input < stringLen target } -> lo:Nat -> hi:Int 
+           -> {makeIndices input target lo hi == N } 
+           / [hi -lo]
+  @-}
+smallInput input target lo hi 
+  | hi < lo 
+  = makeIndices input target lo hi 
+  ==. N
+  *** QED  
+  | lo == hi, not (isGoodIndex input target lo)
+  = makeIndices input target lo hi 
+  ==. N
+  *** QED  
+  | not (isGoodIndex input target lo)
+  = makeIndices input target lo hi 
+  ==. makeIndices input target (lo+1) hi
+  ==. N ? smallInput input target (lo+1) hi 
+  *** QED  
+
+maxIndices :: SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ maxIndices 
+  :: input:SMTString -> target:SMTString -> lo:{Nat | stringLen input < lo + stringLen target} -> hi:Int
+  -> {makeIndices input target lo hi = N}
+  / [hi - lo ] @-}
+maxIndices input target lo hi 
+  | hi < lo 
+  =   makeIndices input target lo hi  
+  ==. N
+  *** QED 
+  | lo == hi, not (isGoodIndex input target lo)
+  =   makeIndices input target lo hi  
+  ==. N
+  *** QED 
+  | not (isGoodIndex input target lo)
+  =   makeIndices input target lo hi
+  ==. N 
+  ==. makeIndices input target (lo+1) hi 
+      ? maxIndices input target (lo+1) hi 
+  *** QED 
+
+
+mergeIndices :: SMTString -> SMTString -> Int -> Int -> Int -> Proof
+{-@ mergeIndices 
+  :: input:SMTString -> target:SMTString -> lo:Nat -> mid:{Int | lo <= mid} -> hi:{Int | mid <= hi} 
+  -> {makeIndices input target lo hi == append (makeIndices input target lo mid) (makeIndices input target (mid+1) hi)} 
+  / [mid] @-}
+mergeIndices input target lo mid hi 
+  | lo == mid, isGoodIndex input target lo 
+  =   append (makeIndices input target lo mid) (makeIndices input target (mid+1) hi)
+  ==. append (makeIndices input target lo lo)  (makeIndices input target (mid+1) hi)
+  ==. append (lo `C` N)  (makeIndices input target (mid+1) hi)
+  ==. lo  `C` (append N  (makeIndices input target (lo+1) hi))
+  ==. lo  `C` (makeIndices input target (lo+1) hi)
+  ==. makeIndices input target lo hi
+  *** QED 
+  | lo == mid, not (isGoodIndex input target lo)
+  =   append (makeIndices input target lo mid) (makeIndices input target (mid+1) hi)
+  ==. append (makeIndices input target lo lo)  (makeIndices input target (mid+1) hi)
+  ==. append (lo `C` N)  (makeIndices input target (mid+1) hi)
+  ==. (append N  (makeIndices input target (lo+1) hi))
+  ==. makeIndices input target lo hi
+  *** QED 
+  | lo < mid, not (isGoodIndex input target mid)
+  =   makeIndices input target lo hi
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (makeIndices input target mid hi)
+       ? mergeIndices input target lo (mid-1) hi 
+
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (makeIndices input target (mid+1) hi)
+
+  ==. append (makeIndices input target lo mid) 
+                  (makeIndices input target (mid+1) hi)
+      ?makeNewIndicesBadLast input target lo mid
+  *** QED 
+  | lo < mid, isGoodIndex input target mid
+  =   makeIndices input target lo hi
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (makeIndices input target mid hi)
+       ? mergeIndices input target lo (mid-1) hi 
+
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (mid `C` makeIndices input target (mid+1) hi)
+
+
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (mid `C` (append N (makeIndices input target (mid+1) hi)))
+
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (append (C mid N) (makeIndices input target (mid+1) hi))
+
+  ==. append (append (makeIndices input target lo (mid-1)) (C mid N)) 
+                  (makeIndices input target (mid+1) hi)
+      ? appendAssoc (makeIndices input target lo (mid-1)) (C mid N) (makeIndices input target (mid+1) hi)
+
+  ==. append (makeIndices input target lo mid) 
+                  (makeIndices input target (mid+1) hi)
+      ?makeNewIndicesGoodLast input target lo mid
+  *** QED 
+
+
+makeNewIndicesGoodLast, makeNewIndicesBadLast 
+  :: SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ makeNewIndicesGoodLast 
+  :: input:SMTString -> target:SMTString -> lo:Nat -> hi:{Int | lo <= hi && (isGoodIndex input target hi)}
+  -> {makeIndices input target lo hi == append (makeIndices input target lo (hi-1)) (C hi N)}
+  / [hi - lo] @-}
+makeNewIndicesGoodLast input target lo hi 
+  | lo == hi, (isGoodIndex input target lo)
+  =   makeIndices input target lo hi 
+  ==. hi `C` N 
+  ==. append (N) (C hi N)
+  ==. append (makeIndices input target lo (hi-1)) (C hi N)
+  *** QED 
+  | not (isGoodIndex input target lo), isGoodIndex input target hi 
+  =   makeIndices input target lo hi 
+  ==. makeIndices input target (lo+1) hi
+  ==. append (makeIndices input target (lo+1) (hi-1)) (C hi N)
+       ? makeNewIndicesGoodLast input target (lo+1) hi  
+  ==. append (makeIndices input target lo (hi-1)) (C hi N)
+  *** QED 
+  | isGoodIndex input target lo, isGoodIndex input target hi
+  =   makeIndices input target lo hi 
+  ==. lo `C` makeIndices input target (lo+1) hi
+  ==. lo `C` (append (makeIndices input target (lo+1) (hi-1)) (C hi N))
+       ? makeNewIndicesGoodLast input target (lo+1) hi  
+  ==. (append (lo `C` makeIndices input target (lo+1) (hi-1)) (C hi N))
+  ==. append (makeIndices input target lo (hi-1)) (C hi N)
+  *** QED 
+
+{-@ makeNewIndicesBadLast 
+  :: input:SMTString -> target:SMTString -> lo:Nat -> hi:{Int | lo <= hi && (not (isGoodIndex input target hi))}
+  -> {makeIndices input target lo hi == makeIndices input target lo (hi-1)}
+  / [hi - lo]
+@-}
+-- NV sweet proof 
+makeNewIndicesBadLast input target lo hi 
+  | lo == hi, not (isGoodIndex input target lo)
+  =   makeIndices input target lo (hi-1) 
+  ==. N 
+  ==. makeIndices input target lo hi
+  *** QED 
+  | not (isGoodIndex input target lo), not (isGoodIndex input target hi) 
+  =   makeIndices input target lo hi 
+  ==. makeIndices input target (lo+1) hi
+  ==. makeIndices input target (lo+1) (hi-1)
+       ? makeNewIndicesBadLast input target (lo+1) hi   
+  ==. makeIndices input target lo (hi-1)
+  *** QED 
+  | isGoodIndex input target lo , not (isGoodIndex input target hi) 
+  =   makeIndices input target lo hi 
+  ==. lo `C` makeIndices input target (lo+1) hi
+  ==. lo `C` makeIndices input target (lo+1) (hi-1)
+       ? makeNewIndicesBadLast input target (lo+1) hi   
+  ==. makeIndices input target lo (hi-1)
+  *** QED 
+
+
+catIndices :: SMTString -> SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ catIndices 
+     :: input:SMTString -> x:SMTString 
+     -> target:{SMTString | 0 <= stringLen input - stringLen target + 1} 
+     -> lo:{Nat | lo <= stringLen input - stringLen target } 
+     -> hi:{Int | stringLen input - stringLen target <= hi}
+     -> { makeIndices input target lo hi == makeIndices (concatString input x) target lo (stringLen input - stringLen target) }
+  @-}
+catIndices input x target lo hi 
+  =   makeIndices input target lo hi
+  ==. append (makeIndices input target lo (stringLen input - stringLen target))
+                  (makeIndices input target (stringLen input - stringLen target + 1) hi)
+       ? mergeIndices input target lo (stringLen input - stringLen target) hi
+  ==. append (makeIndices input target lo (stringLen input - stringLen target))
+                  N
+       ? maxIndices input target (stringLen input - stringLen target + 1) hi
+  ==. makeIndices input target lo (stringLen input - stringLen target)
+       ? appendNil (makeIndices input target lo (stringLen input - stringLen target))
+  ==. makeIndices (concatString input x) target lo (stringLen input - stringLen target)
+       ? concatmakeNewIndices lo (stringLen input - stringLen target) target input x 
+  *** QED 
+
diff --git a/tests/strings/pos/StringIndexingStep1.hs b/tests/strings/pos/StringIndexingStep1.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/pos/StringIndexingStep1.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE GADTs               #-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--stringtheory"    @-}
+
+module StringIndexing where
+
+
+import GHC.TypeLits
+import Data.String 
+
+import Data.Proxy 
+-- Structure that defines valid indeces of a type level target 
+-- symbol in a value level string
+
+data MI (tagret :: Symbol) s where 
+  MI :: IsString s => s        -- input string
+                   -> [Int]    -- valid indeces of target in input
+                   -> MI target s
+
+{-@ MI :: input:s 
+       -> [{i:Int |	 subString input i (stringLen target)  == target }]
+       -> MI s @-}
+
+-- STEP 1:    Verification of valid structures
+
+misafe1 :: MI "cat" String 
+misafe1 = MI "catdogcatsdots" []
+
+misafe2 :: MI "cat" String
+misafe2 = MI "catdogcatsdots" [0]
+
+misafe3 :: MI "cat" String
+misafe3 = MI "catdogcatsdots" [0, 6]
+
+misafe4 :: MI "cat" String
+misafe4 = MI "catdogcatsdots" [6, 0]
+
+misafe5 :: MI "cat" String
+misafe5 = MI "catdogcatsdots" [6]
diff --git a/tests/strings/pos/StringIndexingStep2.hs b/tests/strings/pos/StringIndexingStep2.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/pos/StringIndexingStep2.hs
@@ -0,0 +1,91 @@
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE GADTs               #-}
+
+
+{-@ LIQUID "--totality"          @-}
+{-@ LIQUID "--stringtheory"      @-}
+
+module StringIndexing where
+
+
+import GHC.TypeLits
+import Data.String 
+
+import Data.Proxy 
+-- Structure that defines valid indeces of a type level target 
+-- symbol in a value level string
+
+data MI (tagret :: Symbol) s where 
+  MI :: IsString s => s        -- input string
+                   -> [Int]    -- valid indeces of target in input
+                   -> MI target s
+
+{-@ MI :: input:s 
+       -> [GoodIndex input target]
+       -> MI s @-}
+
+
+{-@ type GoodIndex Input Target 
+  = {i:Int |  IsGoodIndex Input Target i}
+  @-}
+
+{-@ predicate IsGoodIndex Input Target I
+  =  (subString Input I (stringLen Target)  == Target)
+  && (I + stringLen Target < stringLen Input)
+  && (0 <= I)
+  @-}
+
+{-@ measure stringLen    :: String -> Int @-}
+{-@ measure subString    :: String -> Int -> Int -> String @-}
+{-@ measure concatString :: String -> String -> String @-}
+
+mempty :: forall (target :: Symbol). MI target String
+mempty = MI "" []
+
+
+mappend :: forall (target :: Symbol). (KnownSymbol target) => MI target String -> MI target String -> MI target String
+mappend (MI i1 is1) (MI i2 is2)
+  = MI input (is ++ is1 ++ map ((length i1) +) is2)
+  where 
+    is     = filterIndex input target [(len1 - len) .. (len1 + len)]
+    input  = i1 `concatString` i2 
+    len1   = length i1 
+    len    = length target 
+    target = symbolVal (Proxy :: Proxy target)
+
+
+{-@ symbolVal :: forall n proxy. KnownSymbol n => proxy n -> {v:String | v == n} @-}
+
+filterIndex :: String -> String -> [Int] -> [Int]
+{-@ filterIndex :: input:String -> target:String -> is:[Int] -> [GoodIndex input target] / [len is] @-}
+filterIndex _ _ [] = []
+filterIndex input target (i:is)
+  | isGoodIndex input target i
+  = i:filterIndex input target is 
+  | otherwise 
+  =   filterIndex input target is 
+
+
+isGoodIndex :: String -> String -> Int -> Bool 
+{-@ isGoodIndex :: input:String -> target:String -> i:Int 
+  -> {b:Bool | Prop b <=> IsGoodIndex input target i} @-}
+isGoodIndex input target i 
+  =  subString input i (stringLen target)  == target  
+  && i + stringLen target < stringLen input
+  && 0 <= i
+
+{-@ concatString :: x:String -> y:String -> {v:String | v == concatString x y && stringLen v == stringLen x + stringLen y } @-}
+concatString :: String -> String -> String
+concatString = undefined 
+
+{-@ stringLen    :: s:String -> {v:Int | v == stringLen s} @-}
+stringLen :: String -> Int 
+stringLen = length 
+
+{-@ subString  :: s:String -> offset:Int -> ln:Int -> {v:String |v == subString s offset ln } @-}
+subString :: String -> Int -> Int -> String 
+subString = undefined 
diff --git a/tests/strings/pos/StringIndexingStep3.hs b/tests/strings/pos/StringIndexingStep3.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/pos/StringIndexingStep3.hs
@@ -0,0 +1,1735 @@
+{-
+NV TODO 
+1. refine data type
+2. connect it with Steps 1 & 2
+3. connect it with dyn programming 
+-}
+
+
+
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE GADTs               #-}
+
+
+{-@ LIQUID "--higherorder"         @-}
+{-@ LIQUID "--totality"            @-}
+{-@ LIQUID "--exactdc"             @-}
+
+module Main where
+
+import Language.Haskell.Liquid.String
+import GHC.TypeLits
+import Data.String hiding (fromString)
+import Data.Proxy 
+import Prelude hiding (mempty, mappend, id, mconcat, map)
+import Language.Haskell.Liquid.ProofCombinators 
+
+import Data.Maybe 
+
+-- | Interface 
+
+main :: IO ()
+main = 
+   do input     <- fromString <$> readFile "input.txt"
+      let mi1    = toMI input :: MI "abcab" SMTString
+      let is1    = getIndex mi1 
+      putStrLn ("Serial   Indices: " ++ show is1)
+      let mi2    = toMIPar input :: MI "abcab" SMTString
+      let is2    = getIndex mi2 
+      putStrLn ("Parallel Indices: " ++ show is2)
+      putStrLn ("Are equal? " ++ show (is1 == is2))
+
+{-
+main :: IO ()
+main = 
+  do input     <- fromString <$> readFile "input.txt"
+     case someSymbolVal "x" of 
+            SomeSymbol (_ :: Proxy y) ->            
+      let mi1    = toMI input :: MI y SMTString
+      let is1    = getIndex mi1 
+      putStrLn ("Serial   Indices: " ++ show is1)
+      let mi2    = toMIPar input :: MI "abcab" SMTString
+      let is2    = getIndex mi2 
+      putStrLn ("Parallel Indices: " ++ show is2)
+      putStrLn ("Are equal? " ++ show (is1 == is2))
+
+
+-}
+
+test1   = indices input1 
+input1  = fromString $ clone 100 "ababcabcab"
+
+
+indices :: SMTString -> List Int 
+indices input 
+  = case toMI input :: MI "abcab" SMTString  of 
+      MI _ i -> i 
+
+
+{-
+
+
+
+  |
+-}
+
+mconcatPar :: forall (target :: Symbol). (KnownSymbol target) =>  Int -> [MI target SMTString] -> MI target SMTString
+mconcatPar n xs = mconcat (mconcatPar' n xs)
+
+{-@ Lazy mconcatPar' @-}
+-- Termination proof is terribly slow and will change... 
+{-@ mconcatPar' :: forall (target :: Symbol). (KnownSymbol target) =>  Int -> xs:[MI target SMTString] -> [MI target SMTString] @-}
+mconcatPar' :: forall (target :: Symbol). (KnownSymbol target) =>  Int -> [MI target SMTString] -> [MI target SMTString]
+mconcatPar' n xs | length xs <= n = [mconcat xs]  
+mconcatPar' n xs = let (x, r) = splitAt n xs 
+                   in mconcatPar' n (mconcat x:mconcatPar' n r)
+
+toMIPar :: forall (target :: Symbol). (KnownSymbol target) => SMTString -> MI target SMTString 
+toMIPar input = undefined 
+
+toMI :: forall (target :: Symbol). (KnownSymbol target) => SMTString -> MI target SMTString 
+toMI input = if isNullString input then mempty else  MI input (makeIndices input (fromString (symbolVal (Proxy :: Proxy target))) 0 (stringLen input - 1))
+
+getIndex :: forall (target :: Symbol).  MI target SMTString -> List Int 
+getIndex (MI _ i) = i 
+
+clone :: Int -> [a] -> [a]
+clone i xs | i <= 0 = [] 
+clone 1 xs = xs 
+clone n xs = xs ++ clone (n-1) xs
+
+mconcat :: forall (target :: Symbol). (KnownSymbol target) => [MI target SMTString] -> MI target SMTString
+mconcat []       = mempty 
+mconcat [x]      = x 
+mconcat [x1, x2] = mappend x1 x2 
+mconcat (x:xs)   = mappend x (mconcat xs)
+
+
+-- | Indexing Structure Definition 
+
+-- Structure that defines valid indeces of a type level target 
+-- symbol in a value level string
+
+data MI (target :: Symbol) s where 
+  MI :: SMTString        -- input string
+     -> (List Int)      -- valid indeces of target in input
+     -> MI target s
+  deriving (Show)
+
+{-@ data MI target s 
+  = MI { input :: SMTString
+       , idxes   :: List Int 
+       } @-}
+
+
+{- data MI target s 
+  = MI { input :: SMTString
+       , List :: List (GoodIndex input target)
+       } @-}
+
+
+{-@ measure indixesMI @-}
+indixesMI (MI _ is) = is 
+{-@ measure inputMI @-}
+inputMI (MI i _) = i 
+
+
+
+{-@ type GoodIndex Input Target 
+  = {i:Int |  IsGoodIndex Input Target i}
+  @-}
+
+{-@ type GoodIndexTwo Input Input2 Target 
+  = {i:Int |  IsGoodIndex Input Target i && IsGoodIndex (concatString Input Input2) Target i }
+  @-}
+
+{-@ predicate IsGoodIndex Input Target I
+  =  (subString Input I (stringLen Target)  == Target)
+  && (I + stringLen Target <= stringLen Input)
+  && (0 <= I)
+  @-}
+
+
+-- | Monoid methods 
+
+{-@ reflect mempty @-}
+mempty :: forall (target :: Symbol). MI target SMTString
+mempty = MI stringEmp N
+
+{-@ reflect mappend @-}
+mappend :: forall (target :: Symbol).  (KnownSymbol target) => MI target SMTString -> MI target SMTString -> MI target SMTString
+mappend (MI i1 is1) (MI i2 is2)
+  = MI (concatString i1 i2) -- (mappendMakeIndixes i1 i2 (fromString (symbolVal (Proxy :: Proxy target))) is1 is2)
+    ((is1 
+        `append` 
+      makeNewIndices i1 i2 (fromString (symbolVal (Proxy :: Proxy target))))
+        `append` 
+      map (shift (stringLen i1)) is2)            
+ 
+
+-------------------------------------------------------------------------------
+--------------- PROOFS  -------------------------------------------------------
+-------------------------------------------------------------------------------
+
+mempty_left :: forall (target :: Symbol). (KnownSymbol target) => MI target SMTString -> Proof
+{-@ mempty_left :: xs:MI target SMTString -> {mappend xs mempty == xs } @-}
+mempty_left (MI i1 is1)
+  =   mappend (MI i1 is1) (mempty :: MI target SMTString)
+  ==. mappend (MI i1 is1) (MI stringEmp N) 
+  ==. MI (concatString i1 stringEmp)  
+       (is1 `append` map (shift (stringLen i1)) N
+            `append` makeNewIndices i1 stringEmp (fromString (symbolVal (Proxy :: Proxy target))))
+  ==. MI (concatString i1 stringEmp)  
+       ((is1 `append` N)
+            `append` makeNewIndices i1 stringEmp (fromString (symbolVal (Proxy :: Proxy target))))
+  ==. MI (concatString i1 stringEmp)  
+       (is1 `append` makeNewIndices i1 stringEmp (fromString (symbolVal (Proxy :: Proxy target))))
+      ? appendEmp is1 
+  ==. MI (concatString i1 stringEmp)  
+       (is1 `append` N) 
+      ? makeNewIndicesNullLeft i1 (fromString (symbolVal (Proxy :: Proxy target)))
+  ==. MI (concatString i1 stringEmp) is1 
+      ? appendEmp is1 
+  ==. MI i1 is1 
+      ? concatStringNeutral i1 
+  *** QED 
+
+
+
+
+
+mempty_right :: forall (target :: Symbol). (KnownSymbol target) => MI target SMTString -> Proof
+{-@ mempty_right :: xs:MI target SMTString -> {mappend mempty xs == xs } @-}
+mempty_right (MI i is)
+  =   mappend (mempty :: MI target SMTString) (MI i is) 
+  ==. mappend (MI stringEmp N) (MI i is) 
+  ==. MI (concatString stringEmp i)  
+       (N `append` makeNewIndices stringEmp i (fromString (symbolVal (Proxy :: Proxy target)))
+               `append` map (shift (stringLen stringEmp)) is)
+  ==. MI (concatString stringEmp i)  
+       ( makeNewIndices stringEmp i (fromString (symbolVal (Proxy :: Proxy target)))
+        `append`
+         map (shift (stringLen stringEmp)) is)
+  ==. MI (concatString stringEmp i)  
+       ( makeNewIndices stringEmp i (fromString (symbolVal (Proxy :: Proxy target)))
+         `append` 
+         map (shift 0) is)
+  ==. MI (concatString stringEmp i)  
+       (makeNewIndices stringEmp i (fromString (symbolVal (Proxy :: Proxy target)))
+        `append` 
+        is)
+       ? mapShiftZero is 
+  ==. MI (concatString stringEmp i)  
+       (N `append` is) 
+      ? makeNewIndicesNullRight i (fromString (symbolVal (Proxy :: Proxy target)))
+  ==. MI (concatString stringEmp i) is 
+  ==. MI i is 
+      ? concatStringNeutralRight i
+  *** QED 
+
+{-@ mappend_assoc 
+  :: x:MI target SMTString -> y:MI target SMTString -> z:MI target SMTString
+  -> {v:Proof | mappend x (mappend y z) = mappend (mappend x y) z}
+  @-}
+mappend_assoc 
+     :: forall (target :: Symbol). (KnownSymbol target) 
+     => MI target SMTString ->  MI target SMTString ->  MI target SMTString -> Proof
+mappend_assoc x@(MI xi xis) y@(MI yi yis) z@(MI zi zis)
+  | stringLen (fromString (symbolVal (Proxy :: Proxy target))) <= stringLen yi 
+  =   mappend x (mappend y z)
+  ==. mappend (MI xi xis) (mappend (MI yi yis) (MI zi zis))
+  ==. mappend (MI xi xis) 
+              (MI (concatString yi zi)  
+                  ((yis 
+                    `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                    `append` map (shift (stringLen yi)) zis))
+  ==. MI (concatString xi (concatString yi zi))  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  map (shift (stringLen xi)) 
+                  ((yis 
+                    `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                    `append` map (shift (stringLen yi)) zis)
+              )
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  map (shift (stringLen xi)) 
+                  ((yis 
+                    `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                    `append` map (shift (stringLen yi)) zis)
+              )
+      ? concatStringAssoc xi yi zi 
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  (
+                    (map (shift (stringLen xi)) (yis 
+                    `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target)))))
+                    `append` 
+                    map (shift (stringLen xi)) (map (shift (stringLen yi)) zis))
+              )
+      ? map_append (shift (stringLen xi)) 
+                   (yis `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target)))) 
+                   (map (shift (stringLen yi)) zis)
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  (
+                    (map (shift (stringLen xi)) yis 
+                    `append` (map (shift (stringLen xi)) (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))))
+                    `append` 
+                    map (shift (stringLen xi)) (map (shift (stringLen yi)) zis))
+              )
+      ? map_append (shift (stringLen xi)) yis (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  (
+                    (map (shift (stringLen xi)) yis 
+                    `append` (map (shift (stringLen xi)) (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))))
+                    `append` 
+                    map (shift (stringLen (concatString xi yi))) zis)
+              )
+      ? map_len_fusion xi yi zis 
+-- ((x1~x2) ~ ((x3~x4) ~ x5))
+-- == 
+--   ((((x1~x2) ~x3) ~x4) ~x5
+  ==. MI (concatString (concatString xi yi) zi)
+         (((( xis 
+               `append` 
+              makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))                      `append` map (shift (stringLen xi)) yis)
+               `append` 
+              map (shift (stringLen xi)) yis)
+               `append`
+              map (shift (stringLen (concatString xi yi))) zis)
+
+      ? appendReorder xis
+                      (makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+                      (map (shift (stringLen xi)) yis)
+                      (map (shift (stringLen xi)) (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target)))))
+                      (map (shift (stringLen (concatString xi yi))) zis)
+-- ((((x1 ~ x2) ~ x3) ~ x4) ~ x5)
+-- 
+-- ((((x1 ~ x2) ~ x3) ~ x4) ~ x5)
+
+  ==. MI (concatString (concatString xi yi) zi)
+         (((( xis 
+               `append` 
+              makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+              map (shift (stringLen xi)) yis)
+               `append`
+              makeNewIndices (concatString xi yi) zi (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+              map (shift (stringLen (concatString xi yi))) zis 
+          )
+      ? shiftIndexes xi yi zi (fromString (symbolVal (Proxy :: Proxy target)))
+  ==. mappend (MI (concatString xi yi)  
+                  ( (xis `append` makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+                       `append` map (shift (stringLen xi)) yis
+                  )
+              ) (MI zi zis)
+  ==. mappend (mappend (MI xi xis) (MI yi yis)) (MI zi zis)
+  *** QED 
+
+
+
+mappend_assoc x@(MI xi xis) y@(MI yi yis) z@(MI zi zis)
+  | stringLen yi < stringLen (fromString (symbolVal (Proxy :: Proxy target))) 
+  =   mappend x (mappend y z)
+  ==. mappend (MI xi xis) (mappend (MI yi yis) (MI zi zis))
+  ==. mappend (MI xi xis) 
+              (MI (concatString yi zi)  
+                  ((yis 
+                    `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                    `append` map (shift (stringLen yi)) zis))
+  ==. MI (concatString xi (concatString yi zi))  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  map (shift (stringLen xi)) 
+                  ((yis 
+                    `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                    `append` map (shift (stringLen yi)) zis)
+              )
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  map (shift (stringLen xi)) 
+                  ((yis 
+                    `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                    `append` map (shift (stringLen yi)) zis)
+              )
+      ? concatStringAssoc xi yi zi 
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  map (shift (stringLen xi)) 
+                  ((N 
+                    `append` makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                    `append` map (shift (stringLen yi)) zis)
+              )
+        ? emptyIndexes y (assumeGoodIndex yi (fromString (symbolVal (Proxy :: Proxy target))) yis)
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  map (shift (stringLen xi)) 
+                  (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target)))
+                    `append` map (shift (stringLen yi)) zis)
+              )
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                  `append` map (shift (stringLen xi)) (map (shift (stringLen yi)) zis))
+              )
+      ? map_append (shift (stringLen xi)) 
+                   (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target)))) 
+                   (map (shift (stringLen yi)) zis)
+
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+               `append` 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target))))
+                  `append` map (shift (stringLen xi)) (map (shift (stringLen yi)) zis))
+              )
+      ? map_len_fusion xi yi zis 
+-- ((x1~x2) ~ (x3~x4))
+-- == 
+-- (x1 ~ (x2~x3)) ~ x4
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               (makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target)))
+               `append` 
+                map (shift (stringLen xi)) (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target)))))
+                  `append` map (shift (stringLen xi)) (map (shift (stringLen yi)) zis))
+              )
+      ? appendGroupNew xis
+                       (makeNewIndices xi (concatString yi zi) (fromString (symbolVal (Proxy :: Proxy target))))
+                       (map (shift (stringLen xi)) (makeNewIndices yi zi (fromString (symbolVal (Proxy :: Proxy target)))))
+                       (map (shift (stringLen xi)) (map (shift (stringLen yi)) zis))
+
+
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               (makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target)))
+               `append` 
+                makeNewIndices (concatString xi yi) zi (fromString (symbolVal (Proxy :: Proxy target))))
+                  `append` map (shift (stringLen xi)) (map (shift (stringLen yi)) zis))
+              )
+      ? shiftNewIndexes xi yi zi (fromString (symbolVal (Proxy :: Proxy target)))
+  ==. MI (concatString (concatString xi yi) zi)  
+         ((xis `append` 
+               (makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target)))
+               `append` 
+                makeNewIndices (concatString xi yi) zi (fromString (symbolVal (Proxy :: Proxy target))))
+                  `append` map (shift (stringLen (concatString xi yi))) zis)
+              )
+      ? map_len_fusion xi yi zis 
+
+-- (x1 ~ (x2 ~ x3)) ~ x4 == ((x1 ~ x2) ~ x3) ~ x4
+  ==. MI (concatString (concatString xi yi) zi)  
+         (((xis `append` makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+         `append`
+            (makeNewIndices (concatString xi yi) zi (fromString (symbolVal (Proxy :: Proxy target)))))
+         `append` 
+            map (shift (stringLen (concatString xi yi))) zis )
+      ? appendUnGroupNew xis 
+                         (makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+                         (makeNewIndices (concatString xi yi) zi (fromString (symbolVal (Proxy :: Proxy target))))
+                         (map (shift (stringLen (concatString xi yi))) zis)
+
+  ==. MI (concatString (concatString xi yi) zi)  
+        ((((xis `append` makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+                       `append` N
+                  )
+         `append`
+            (makeNewIndices (concatString xi yi) zi (fromString (symbolVal (Proxy :: Proxy target)))))
+         `append` 
+            map (shift (stringLen (concatString xi yi))) zis )
+          ? appendEmp (xis `append` makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+  ==. MI (concatString (concatString xi yi) zi)  
+        ((((xis `append` makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+                       `append` map (shift (stringLen xi)) N
+                  )
+         `append`
+            (makeNewIndices (concatString xi yi) zi (fromString (symbolVal (Proxy :: Proxy target)))))
+         `append` 
+            map (shift (stringLen (concatString xi yi))) zis )
+  ==. MI (concatString (concatString xi yi) zi)  
+        ((((xis `append` makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+                       `append` map (shift (stringLen xi)) yis
+                  )
+         `append`
+            (makeNewIndices (concatString xi yi) zi (fromString (symbolVal (Proxy :: Proxy target)))))
+         `append` 
+            map (shift (stringLen (concatString xi yi))) zis )
+      ?emptyIndexes y (assumeGoodIndex yi (fromString (symbolVal (Proxy :: Proxy target))) yis)
+  ==. mappend (MI (concatString xi yi)  
+                  ( (xis `append` makeNewIndices xi yi (fromString (symbolVal (Proxy :: Proxy target))))
+                         `append` map (shift (stringLen xi)) yis
+                  )
+              ) (MI zi zis)
+  ==. mappend (mappend (MI xi xis) (MI yi yis)) (MI zi zis)
+  *** QED 
+
+-------------------------------------------------------------------------------
+------------------ Helper Proofs ----------------------------------------------
+-------------------------------------------------------------------------------
+
+
+{-@ assumeGoodIndex :: input:SMTString -> target:SMTString -> is:List Int 
+                    -> {v:List (GoodIndex input target) | v == is} @-} 
+assumeGoodIndex :: SMTString -> SMTString -> List Int -> List Int 
+assumeGoodIndex input target is 
+  = if isJust (areGoodIndexes input target is) then fromJust (areGoodIndexes input target is) else error ""  
+
+
+{-@ areGoodIndexes :: input:SMTString -> target:SMTString -> is:List Int 
+                   -> Maybe ({v:List (GoodIndex input target) | v == is}) @-} 
+areGoodIndexes :: SMTString -> SMTString -> List Int -> Maybe (List Int) 
+areGoodIndexes input target N
+  = Just N
+areGoodIndexes input target (C x xs)
+  | isGoodIndex input target x 
+  = case areGoodIndexes input target xs of 
+       Nothing -> Nothing 
+       Just is -> Just (C x is) 
+  | otherwise
+  = Nothing 
+
+  
+emptyIndexes :: forall (target :: Symbol). (KnownSymbol target) => MI target SMTString -> List Int  -> Proof
+{-@ emptyIndexes :: mi:MI target SMTString
+                 -> is:{List (GoodIndex (inputMI mi) target) | is == indixesMI mi && stringLen (inputMI mi) < stringLen target}
+                 -> { is == N } @-}
+emptyIndexes (MI _ _) N 
+  = trivial 
+emptyIndexes (MI _ _) (C _ _)
+  = trivial 
+
+
+{-@ shiftIndexes
+  :: xi:SMTString 
+  -> yi:SMTString 
+  -> zi:SMTString 
+  -> tg:{SMTString | stringLen tg <= stringLen yi } 
+  -> {  (makeNewIndices xi (concatString yi zi) tg == makeNewIndices xi yi tg)  
+        && 
+        (map (shift (stringLen xi)) (makeNewIndices yi zi tg) == makeNewIndices (concatString xi yi) zi tg)
+     }
+  @-}
+shiftIndexes :: SMTString -> SMTString -> SMTString -> SMTString -> Proof
+shiftIndexes xi yi zi tg = shiftIndexesLeft xi yi zi tg &&& shiftIndexesRight xi yi zi tg 
+
+{-@ reflect chunkString @-}
+{-@ chunkString :: Int -> xs:SMTString -> List (SMTString) / [stringLen xs] @-}
+chunkString :: Int -> SMTString -> List (SMTString)
+chunkString i xs 
+  | i <= 0 
+  = C xs N 
+  | stringLen xs <= i 
+  = C xs N 
+  | otherwise
+  = C (takeString i xs) (chunkString i (dropString i xs))
+
+
+
+{-@ shiftIndexesLeft
+  :: xi:SMTString 
+  -> yi:SMTString 
+  -> zi:SMTString 
+  -> tg:{SMTString | stringLen tg <= stringLen yi } 
+  -> {  makeNewIndices xi (concatString yi zi) tg == makeNewIndices xi yi tg}
+  @-}
+shiftIndexesLeft :: SMTString -> SMTString -> SMTString -> SMTString -> Proof
+shiftIndexesLeft xi yi zi tg
+  | stringLen tg < 2 
+  =   makeNewIndices xi (concatString yi zi) tg 
+  ==. N
+  ==. makeNewIndices xi yi tg 
+  *** QED 
+  | otherwise
+  =   makeNewIndices xi (concatString yi zi) tg 
+  ==. makeIndices (concatString xi (concatString yi zi)) tg 
+                   (maxInt (stringLen xi - (stringLen tg-1)) 0)
+                   (stringLen xi - 1)
+  ==. makeIndices (concatString (concatString xi yi) zi) tg 
+                   (maxInt (stringLen xi - (stringLen tg-1)) 0)
+                   (stringLen xi - 1)
+     ?concatStringAssoc xi yi zi 
+  ==. makeIndices (concatString xi yi) tg 
+                   (maxInt (stringLen xi - (stringLen tg-1)) 0)
+                   (stringLen xi - 1)                
+      ? concatmakeNewIndices (maxInt (stringLen xi - (stringLen tg-1)) 0) (stringLen xi - 1) tg (concatString xi yi) zi 
+  ==. makeNewIndices xi yi tg 
+  *** QED 
+
+
+
+{-@ concatmakeNewIndices
+  :: lo:Nat -> hi:Int
+  -> target: SMTString
+  -> input : {SMTString | hi + stringLen target <= stringLen input } 
+  -> input': SMTString   
+  -> {  makeIndices (concatString input input') target lo hi == makeIndices input target lo hi }
+  / [hi - lo]  @-}
+concatmakeNewIndices :: Int -> Int -> SMTString -> SMTString -> SMTString  -> Proof
+concatmakeNewIndices lo hi target input input'
+  | hi < lo 
+  =   makeIndices input target lo hi
+  ==. N
+  ==. makeIndices (concatString input input') target lo hi 
+  *** QED 
+  | lo == hi, isGoodIndex input target lo
+  =   makeIndices input target lo hi
+  ==. lo `C` N
+  ==. makeIndices (concatString input input') target lo hi 
+      ? isGoodIndexConcatString input input' target lo  
+  *** QED 
+  | lo == hi
+  =  makeIndices input target lo hi 
+  ==. N
+  ==. makeIndices (concatString input input') target lo hi
+      ? isGoodIndexConcatString input input' target lo  
+  *** QED 
+concatmakeNewIndices lo hi target input input' 
+  | isGoodIndex input target lo
+  =   makeIndices input target lo hi
+  ==. lo `C` (makeIndices input target (lo + 1) hi)
+  ==. lo `C` (makeIndices (concatString input input') target (lo + 1) hi)
+       ? concatmakeNewIndices (lo+1) hi target input input'
+  ==. makeIndices  (concatString input input') target lo hi
+      ? isGoodIndexConcatString input input' target lo  
+  *** QED 
+  | otherwise 
+  =   makeIndices input target lo hi
+  ==. makeIndices input target (lo + 1) hi
+  ==. makeIndices (concatString input input') target (lo + 1) hi
+       ? concatmakeNewIndices (lo+1) hi target input input'
+  ==. makeIndices  (concatString input input') target lo hi
+      ? isGoodIndexConcatString input input' target lo  
+  *** QED 
+
+
+
+{-@ isGoodIndexConcatFront 
+  :: input:SMTString -> input':SMTString -> tg:SMTString -> i:Nat
+  -> {((isGoodIndex input tg i) <=> isGoodIndex (concatString input' input) tg (stringLen input' + i) )
+     } @-}
+isGoodIndexConcatFront :: SMTString -> SMTString -> SMTString -> Int -> Proof 
+isGoodIndexConcatFront input input' tg i 
+  =   isGoodIndex input tg i 
+  ==. (subString input i (stringLen tg)  == tg  
+      && i + stringLen tg <= stringLen input 
+      && 0 <= i)  
+  ==. (subString input i (stringLen tg)  == tg  
+      && (stringLen input' + i) + stringLen tg <= stringLen (concatString input' input) 
+      && 0 <= i)  
+  ==. (subString (concatString input' input) (stringLen input' + i) (stringLen tg)  == tg  
+      && (stringLen input' + i) + stringLen tg <= stringLen (concatString input' input) 
+      && 0 <= (stringLen input' + i))  
+      ? (subStringConcatFront input input' (stringLen tg) i *** QED)
+  ==. isGoodIndex (concatString input' input) tg (stringLen input' + i) 
+  *** QED 
+
+
+{-@ isGoodIndexConcatString 
+  :: input:SMTString -> input':SMTString -> tg:SMTString -> i:{Int | i + stringLen tg <= stringLen input }
+  -> {((isGoodIndex input tg i) <=> isGoodIndex (concatString input input') tg i)
+     } @-}
+isGoodIndexConcatString :: SMTString -> SMTString -> SMTString -> Int -> Proof 
+isGoodIndexConcatString input input' tg i 
+  =   isGoodIndex input tg i 
+  ==. (subString input i (stringLen tg)  == tg  
+      && i + stringLen tg <= stringLen input
+      && 0 <= i) 
+  ==. (subString (concatString input input') i (stringLen tg)  == tg  
+      && i + stringLen tg <= stringLen input 
+      && 0 <= i)   
+      ? (subStringConcat input input' (stringLen tg) i *** QED )
+  ==. (subString (concatString input input') i (stringLen tg)  == tg  
+      && i + stringLen tg <= stringLen (concatString input input') 
+      && 0 <= i)   
+      ? (((stringLen input <= stringLen (concatString input input') *** QED ) &&& (lenConcat input input') *** QED))
+  ==. isGoodIndex (concatString input input') tg i 
+  *** QED 
+
+
+
+
+
+
+{-@ shiftIndexesRight
+  :: xi:SMTString 
+  -> yi:SMTString 
+  -> zi:SMTString 
+  -> tg:{SMTString | stringLen tg <= stringLen yi } 
+  -> { map (shift (stringLen xi)) (makeNewIndices yi zi tg) == makeNewIndices (concatString xi yi) zi tg }
+  @-}
+shiftIndexesRight :: SMTString -> SMTString -> SMTString -> SMTString -> Proof
+shiftIndexesRight xi yi zi tg
+  | stringLen tg < 2 
+  =   makeNewIndices (concatString xi yi) zi tg 
+  ==. N
+  ==. map (shift (stringLen xi)) N
+  ==. map (shift (stringLen xi)) (makeNewIndices yi zi tg)
+  *** QED 
+shiftIndexesRight xi yi zi tg
+-- NV NV NV 
+-- This is suspicious!!! it should require exactly the precondition 
+-- || tg || <= || yi || 
+--   | stringLen tg  <= stringLen yi + 1 
+  =   makeNewIndices (concatString xi yi) zi tg  
+  ==. makeIndices (concatString (concatString xi yi) zi) tg 
+                   (maxInt (stringLen (concatString xi yi) - (stringLen tg -1)) 0)
+                   (stringLen (concatString xi yi) - 1 )
+  ==. makeIndices (concatString (concatString xi yi) zi) tg 
+                   (stringLen (concatString xi yi) - (stringLen tg -1))
+                   (stringLen (concatString xi yi) - 1 )
+  ==. makeIndices (concatString (concatString xi yi) zi) tg 
+                   (stringLen xi + stringLen yi - stringLen tg + 1)
+                   (stringLen xi + stringLen yi - 1 )
+  ==. makeIndices (concatString xi (concatString yi zi)) tg 
+                   (stringLen xi + stringLen yi - stringLen tg + 1)
+                   (stringLen xi + stringLen yi - 1 )
+       ?concatStringAssoc xi yi zi
+  ==. map (shift (stringLen xi)) (makeIndices (concatString yi zi) tg (stringLen yi - stringLen tg + 1) (stringLen yi - 1))
+       ? shiftIndexesRight' (stringLen yi - stringLen tg + 1)
+                            (stringLen yi - 1)
+                            xi 
+                            (concatString yi zi)
+                            tg 
+  ==. map (shift (stringLen xi)) 
+               (makeIndices (concatString yi zi) tg 
+                             (maxInt (stringLen yi - (stringLen tg -1)) 0)
+                             (stringLen yi -1))
+  ==. map (shift (stringLen xi)) 
+               (makeNewIndices yi zi tg)
+  *** QED
+
+{-@ shiftIndexesRight'
+  :: lo:Nat 
+  -> hi:Int  
+  -> x:SMTString 
+  -> input:SMTString 
+  -> tg:SMTString
+  -> { map (shift (stringLen x)) (makeIndices input tg lo hi) == makeIndices (concatString x input) tg (stringLen x + lo) (stringLen x + hi) }
+  / [if hi < lo then 0 else  hi-lo]
+  @-}
+shiftIndexesRight' :: Int -> Int -> SMTString -> SMTString -> SMTString -> Proof
+shiftIndexesRight' lo hi x input target
+  | hi < lo 
+  =   map (shift (stringLen x)) (makeIndices input target lo hi)
+  ==. map (shift (stringLen x)) N
+  ==. N
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+  *** QED 
+  | lo == hi, isGoodIndex input target lo 
+  =   map (shift (stringLen x)) (makeIndices input target lo hi)
+  ==. map (shift (stringLen x)) (lo `C` N)
+  ==. ((shift (stringLen x)) lo) `C` (map (shift (stringLen x)) N)
+  ==. (stringLen x + lo) `C` N
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+     ? isGoodIndexConcatFront input x target lo  -- ( => IsGoodIndex (concatString x input) target (stringLen x + lo))
+  *** QED 
+  | lo == hi
+  =   map (shift (stringLen x)) (makeIndices input target lo hi)
+  ==. map (shift (stringLen x)) N
+  ==. N
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+     ? (isGoodIndexConcatFront input x target lo *** QED)
+  *** QED 
+
+shiftIndexesRight' lo hi x input target
+  | isGoodIndex input target lo
+  =   map (shift (stringLen x)) (makeIndices input target lo hi)
+  ==. map (shift (stringLen x)) (lo `C`(makeIndices input target (lo+1) hi))
+  ==. (shift (stringLen x) lo) `C` (map (shift (stringLen x)) (makeIndices input target (lo+1) hi))
+  ==. (shift (stringLen x) lo) `C` (makeIndices (concatString x input) target (stringLen x + (lo+1)) (stringLen x + hi))
+      ? shiftIndexesRight' (lo+1) hi x input target
+  ==. (stringLen x + lo) `C` (makeIndices (concatString x input) target (stringLen x + (lo+1)) (stringLen x + hi))
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+     ? (isGoodIndexConcatFront input x target lo *** QED)
+  *** QED 
+  | otherwise
+  =   map (shift (stringLen x)) (makeIndices input target lo hi)
+  ==. map (shift (stringLen x)) (makeIndices input target (lo + 1) hi)
+  ==. makeIndices (concatString x input) target (stringLen x + (lo+1)) (stringLen x + hi)
+      ? shiftIndexesRight' (lo+1) hi x input target
+  ==. makeIndices (concatString x input) target (stringLen x + lo) (stringLen x + hi)
+     ? (isGoodIndexConcatFront input x target lo *** QED)
+  *** QED 
+
+
+{-@ shiftNewIndexes
+  :: xi:SMTString 
+  -> yi:SMTString 
+  -> zi:SMTString 
+  -> tg:{SMTString | stringLen yi < stringLen tg  } 
+  -> {  append (makeNewIndices xi (concatString yi zi) tg) (map (shift (stringLen xi)) (makeNewIndices yi zi tg)) == append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+     }
+  @-}
+shiftNewIndexes :: SMTString -> SMTString -> SMTString -> SMTString -> Proof
+shiftNewIndexes xi yi zi tg 
+  | stringLen tg < 2 
+  =   append (makeNewIndices xi (concatString yi zi) tg) (map (shift (stringLen xi)) (makeNewIndices yi zi tg)) 
+  ==. append N (map (shift (stringLen xi)) N) 
+  ==. map (shift (stringLen xi)) N 
+  ==. N 
+  ==. append N N
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+
+shiftNewIndexes xi yi zi tg 
+  | stringLen xi == 0 
+  =   append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg))
+  ==. append (makeNewIndices stringEmp (concatString yi zi) tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg))
+  ? stringEmpProp xi 
+  ==. append (makeNewIndices stringEmp (concatString yi zi) tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg))
+  ? makeNewIndicesNullRight (concatString yi zi) tg
+  ==. append N
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg))
+  ==. map (shift (stringLen xi)) (makeNewIndices yi zi tg)
+  ==. map (shift 0) (makeNewIndices yi zi tg)
+      ? mapShiftZero (makeNewIndices yi zi tg)
+  ==. makeNewIndices yi zi tg
+  ==. makeNewIndices (concatString xi yi) zi tg
+        ? concatEmpLeft xi yi 
+  ==. append N (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (makeNewIndices stringEmp yi tg) (makeNewIndices (concatString xi yi) zi tg)
+       ? makeNewIndicesNullRight yi tg
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+      ? stringEmpProp xi
+  *** QED 
+  | stringLen yi == 0 
+  =   append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg))
+  ==. append (makeNewIndices xi zi tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg))
+      ? concatEmpLeft yi zi 
+  ==. append (makeNewIndices xi zi tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices stringEmp zi tg))
+      ? stringEmpProp yi
+  ==. append (makeNewIndices xi zi tg) 
+                  (map (shift (stringLen xi)) N)
+      ? makeNewIndicesNullRight zi tg 
+  ==. append (makeNewIndices xi zi tg) 
+                  N
+  ==. makeNewIndices xi zi tg 
+       ?appendEmp (makeNewIndices xi zi tg)
+  ==. makeNewIndices (concatString xi yi) zi tg
+       ? concatEmpRight xi yi
+  ==. append N (makeNewIndices (concatString xi yi) zi tg)
+  ==. append (makeNewIndices xi stringEmp tg) (makeNewIndices (concatString xi yi) zi tg)
+       ? makeNewIndicesNullLeft xi tg 
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+       ? stringEmpProp yi
+  *** QED 
+  | stringLen yi - stringLen tg == -1 
+  = let minidx = maxInt (stringLen xi - stringLen tg + 1) 0 in 
+      append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg)) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shift (stringLen xi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          (maxInt (stringLen yi - stringLen tg +1) 0)
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shift (stringLen xi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          (maxInt 0 0)
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shift (stringLen xi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          0
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString xi (concatString yi zi)) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? shiftIndexesRight' 0 (stringLen yi -1) xi (concatString yi zi) tg 
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? concatStringAssoc xi yi zi 
+
+  ==. append (append 
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi)
+                                (stringLen xi -1))
+
+                                ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) 
+      ? mergeIndixes (concatString (concatString xi yi) zi) tg 
+                     minidx -- maxInt (stringLen xi - stringLen tg + 1) 0
+                     (stringLen xi -1)
+                     (stringLen xi -1)
+  ==. append (append 
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                  N
+
+                                ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) 
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) 
+      ?appendEmp (makeIndices (concatString (concatString xi yi) zi) tg
+                                    minidx
+                                    (stringLen xi + stringLen yi - stringLen tg))
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi -1))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                ((stringLen xi))
+                                (stringLen xi + stringLen yi -1))
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx 
+                                (stringLen (concatString xi yi)  - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1))
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+      ? catIndixes (concatString xi yi) zi tg minidx (stringLen xi-1)
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx 
+                                -- maxInt (stringLen xi - stringLen tg + 1) 0 && 2 <= stringLen tg
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen xi) 0)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen xi + stringLen yi - stringLen tg + 1) 0)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeIndices (concatString xi yi) tg 
+                                (maxInt (stringLen xi - stringLen tg +1) 0)
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+shiftNewIndexes xi yi zi tg 
+-- THIS ALWAYS HOLDS 
+--   | stringLen yi + 1 <= stringLen tg
+  | 0 <= stringLen xi + stringLen yi - stringLen tg
+ --  , 0 < stringLen xi 
+  = let minidx = maxInt (stringLen xi - stringLen tg + 1) 0 in 
+      append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg)) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shift (stringLen xi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          (maxInt (stringLen yi - stringLen tg +1) 0)
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (map (shift (stringLen xi)) 
+                            (makeIndices (concatString yi zi) tg
+                                           0
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString xi (concatString yi zi)) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? shiftIndexesRight' 0 (stringLen yi -1) xi (concatString yi zi) tg 
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? concatStringAssoc xi yi zi 
+
+  ==. append (append 
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg + 1)
+                                (stringLen xi -1))
+
+                                ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) 
+      ? mergeIndixes (concatString (concatString xi yi) zi) tg 
+                     minidx -- maxInt (stringLen xi - stringLen tg + 1) 0
+                     (stringLen xi + stringLen yi - stringLen tg)
+                     (stringLen xi -1)
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx 
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                 (append
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg +1)
+                                (stringLen xi -1))
+
+                                
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1)) )
+      ? appendAssoc
+              (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+              (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg+1)
+                                (stringLen xi -1))
+              (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi)
+                                (stringLen xi + stringLen yi -1))
+
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx
+                                (stringLen xi + stringLen yi - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                ((stringLen xi + stringLen yi - stringLen tg+1))
+                                (stringLen xi + stringLen yi -1))
+     ? mergeIndixes (concatString (concatString xi yi) zi) tg 
+                  ((stringLen xi + stringLen yi - stringLen tg+1))
+                  (stringLen xi-1)
+                  (stringLen xi + stringLen yi -1)
+
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                minidx 
+                                (stringLen (concatString xi yi)  - stringLen tg))
+
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg + 1)
+                                (stringLen xi + stringLen yi -1))
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (stringLen xi + stringLen yi - stringLen tg + 1)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+      ? catIndixes (concatString xi yi) zi tg minidx (stringLen xi-1)
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen xi + stringLen yi - stringLen tg + 1) 0)
+                                (stringLen xi + stringLen yi  - 1)
+                  )
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                minidx
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeIndices (concatString xi yi) tg 
+                                (maxInt (stringLen xi - stringLen tg +1) 0)
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+
+--   | stringLen yi + 1 <= stringLen tg
+  | stringLen xi + stringLen yi < stringLen tg
+  =   append (makeNewIndices xi (concatString yi zi) tg) 
+                  (map (shift (stringLen xi)) (makeNewIndices yi zi tg)) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                (maxInt (stringLen xi - stringLen tg + 1) 0)
+                                (stringLen xi -1)) 
+                  (map (shift (stringLen xi)) 
+                            (makeIndices (concatString yi zi) tg
+                                          (maxInt (stringLen yi - stringLen tg +1) 0)
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                0
+                                (stringLen xi -1)) 
+                  (map (shift (stringLen xi)) 
+                            (makeIndices (concatString yi zi) tg
+                                           0
+                                          (stringLen yi -1)
+                            )) 
+  ==. append (makeIndices (concatString xi (concatString yi zi)) tg
+                                0
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString xi (concatString yi zi)) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? shiftIndexesRight' 0 (stringLen yi -1) xi (concatString yi zi) tg 
+  ==. append (makeIndices (concatString (concatString xi yi) zi) tg
+                                0
+                                (stringLen xi -1)) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg 
+                                (stringLen xi) 
+                                (stringLen xi + stringLen yi -1)) 
+      ? concatStringAssoc xi yi zi 
+
+  ==. makeIndices (concatString (concatString xi yi) zi) tg
+                                0
+                                (stringLen (concatString xi yi) - 1)
+      ?mergeIndixes (concatString (concatString xi yi) zi) tg 
+                    0 
+                    (stringLen xi-1) 
+                    (stringLen (concatString xi yi) -1)
+
+  ==. append N 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                0
+                                (stringLen (concatString xi yi) - 1)
+                  )
+
+  ==. append (makeIndices (concatString xi yi) tg 
+                                0
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                0
+                                (stringLen (concatString xi yi) - 1)
+                  )
+      ? smallInput (concatString xi yi) tg 0 (stringLen xi -1)
+  ==. append (makeIndices (concatString xi yi) tg 
+                                (maxInt (stringLen xi - stringLen tg +1) 0)
+                                (stringLen xi-1)
+                  ) 
+                  (makeIndices (concatString (concatString xi yi) zi) tg
+                                (maxInt (stringLen (concatString xi yi) - stringLen tg + 1) 0)
+                                (stringLen (concatString xi yi) - 1)
+                  )
+  ==. append (makeNewIndices xi yi tg) (makeNewIndices (concatString xi yi) zi tg)
+  *** QED 
+
+-- NIKI CHECK: Feels have done this proof before 
+maxIndixes 
+  :: SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ maxIndixes 
+  :: input:SMTString -> target:SMTString -> lo:{Nat | stringLen input < lo + stringLen target} -> hi:Int
+  -> {makeIndices input target lo hi = N}
+  / [hi - lo ] @-}
+maxIndixes input target lo hi 
+  | hi < lo 
+  =   makeIndices input target lo hi  
+  ==. N
+  *** QED 
+  | lo == hi, not (isGoodIndex input target lo)
+  =   makeIndices input target lo hi  
+  ==. N
+  *** QED 
+  | not (isGoodIndex input target lo)
+  =   makeIndices input target lo hi
+  ==. N 
+  ==. makeIndices input target (lo+1) hi 
+      ? maxIndixes input target (lo+1) hi 
+  *** QED 
+
+
+mergeIndixes :: SMTString -> SMTString -> Int -> Int -> Int -> Proof
+{-@ mergeIndixes 
+  :: input:SMTString -> target:SMTString -> lo:Nat -> mid:{Int | lo <= mid} -> hi:{Int | mid <= hi} 
+  -> {makeIndices input target lo hi == append (makeIndices input target lo mid) (makeIndices input target (mid+1) hi)} 
+  / [mid] @-}
+mergeIndixes input target lo mid hi 
+  | lo == mid, isGoodIndex input target lo 
+  =   append (makeIndices input target lo mid) (makeIndices input target (mid+1) hi)
+  ==. append (makeIndices input target lo lo)  (makeIndices input target (mid+1) hi)
+  ==. append (lo `C` N)  (makeIndices input target (mid+1) hi)
+  ==. lo  `C` (append N  (makeIndices input target (lo+1) hi))
+  ==. lo  `C` (makeIndices input target (lo+1) hi)
+  ==. makeIndices input target lo hi
+  *** QED 
+  | lo == mid, not (isGoodIndex input target lo)
+  =   append (makeIndices input target lo mid) (makeIndices input target (mid+1) hi)
+  ==. append (makeIndices input target lo lo)  (makeIndices input target (mid+1) hi)
+  ==. append (lo `C` N)  (makeIndices input target (mid+1) hi)
+  ==. (append N  (makeIndices input target (lo+1) hi))
+  ==. makeIndices input target lo hi
+  *** QED 
+  | lo < mid, not (isGoodIndex input target mid)
+  =   makeIndices input target lo hi
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (makeIndices input target mid hi)
+       ? mergeIndixes input target lo (mid-1) hi 
+
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (makeIndices input target (mid+1) hi)
+
+  ==. append (makeIndices input target lo mid) 
+                  (makeIndices input target (mid+1) hi)
+      ?makeNewIndicesBadLast input target lo mid
+  *** QED 
+  | lo < mid, isGoodIndex input target mid
+  =   makeIndices input target lo hi
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (makeIndices input target mid hi)
+       ? mergeIndixes input target lo (mid-1) hi 
+
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (mid `C` makeIndices input target (mid+1) hi)
+
+
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (mid `C` (append N (makeIndices input target (mid+1) hi)))
+
+  ==. append (makeIndices input target lo (mid-1)) 
+                  (append (C mid N) (makeIndices input target (mid+1) hi))
+
+  ==. append (append (makeIndices input target lo (mid-1)) (C mid N)) 
+                  (makeIndices input target (mid+1) hi)
+      ? appendAssoc (makeIndices input target lo (mid-1)) (C mid N) (makeIndices input target (mid+1) hi)
+
+  ==. append (makeIndices input target lo mid) 
+                  (makeIndices input target (mid+1) hi)
+      ?makeNewIndicesGoodLast input target lo mid
+  *** QED 
+
+
+makeNewIndicesGoodLast, makeNewIndicesBadLast 
+  :: SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ makeNewIndicesGoodLast 
+  :: input:SMTString -> target:SMTString -> lo:Nat -> hi:{Int | lo <= hi && (isGoodIndex input target hi)}
+  -> {makeIndices input target lo hi == append (makeIndices input target lo (hi-1)) (C hi N)}
+  / [hi - lo] @-}
+makeNewIndicesGoodLast input target lo hi 
+  | lo == hi, (isGoodIndex input target lo)
+  =   makeIndices input target lo hi 
+  ==. hi `C` N 
+  ==. append (N) (C hi N)
+  ==. append (makeIndices input target lo (hi-1)) (C hi N)
+  *** QED 
+  | not (isGoodIndex input target lo), isGoodIndex input target hi 
+  =   makeIndices input target lo hi 
+  ==. makeIndices input target (lo+1) hi
+  ==. append (makeIndices input target (lo+1) (hi-1)) (C hi N)
+       ? makeNewIndicesGoodLast input target (lo+1) hi  
+  ==. append (makeIndices input target lo (hi-1)) (C hi N)
+  *** QED 
+  | isGoodIndex input target lo, isGoodIndex input target hi
+  =   makeIndices input target lo hi 
+  ==. lo `C` makeIndices input target (lo+1) hi
+  ==. lo `C` (append (makeIndices input target (lo+1) (hi-1)) (C hi N))
+       ? makeNewIndicesGoodLast input target (lo+1) hi  
+  ==. (append (lo `C` makeIndices input target (lo+1) (hi-1)) (C hi N))
+  ==. append (makeIndices input target lo (hi-1)) (C hi N)
+  *** QED 
+
+{-@ makeNewIndicesBadLast 
+  :: input:SMTString -> target:SMTString -> lo:Nat -> hi:{Int | lo <= hi && (not (isGoodIndex input target hi))}
+  -> {makeIndices input target lo hi == makeIndices input target lo (hi-1)}
+  / [hi - lo]
+@-}
+-- NV sweet proof 
+makeNewIndicesBadLast input target lo hi 
+  | lo == hi, not (isGoodIndex input target lo)
+  =   makeIndices input target lo (hi-1) 
+  ==. N 
+  ==. makeIndices input target lo hi
+  *** QED 
+  | not (isGoodIndex input target lo), not (isGoodIndex input target hi) 
+  =   makeIndices input target lo hi 
+  ==. makeIndices input target (lo+1) hi
+  ==. makeIndices input target (lo+1) (hi-1)
+       ? makeNewIndicesBadLast input target (lo+1) hi   
+  ==. makeIndices input target lo (hi-1)
+  *** QED 
+  | isGoodIndex input target lo , not (isGoodIndex input target hi) 
+  =   makeIndices input target lo hi 
+  ==. lo `C` makeIndices input target (lo+1) hi
+  ==. lo `C` makeIndices input target (lo+1) (hi-1)
+       ? makeNewIndicesBadLast input target (lo+1) hi   
+  ==. makeIndices input target lo (hi-1)
+  *** QED 
+
+
+catIndixes :: SMTString -> SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ catIndixes 
+     :: input:SMTString -> x:SMTString 
+     -> target:{SMTString | 0 <= stringLen input - stringLen target + 1} 
+     -> lo:{Nat | lo <= stringLen input - stringLen target } 
+     -> hi:{Int | stringLen input - stringLen target <= hi}
+     -> { makeIndices input target lo hi == makeIndices (concatString input x) target lo (stringLen input - stringLen target) }
+  @-}
+catIndixes input x target lo hi 
+  =   makeIndices input target lo hi
+  ==. append (makeIndices input target lo (stringLen input - stringLen target))
+                  (makeIndices input target (stringLen input - stringLen target + 1) hi)
+       ? mergeIndixes input target lo (stringLen input - stringLen target) hi
+  ==. append (makeIndices input target lo (stringLen input - stringLen target))
+                  N
+       ? maxIndixes input target (stringLen input - stringLen target + 1) hi
+  ==. makeIndices input target lo (stringLen input - stringLen target)
+       ? appendEmp (makeIndices input target lo (stringLen input - stringLen target))
+  ==. makeIndices (concatString input x) target lo (stringLen input - stringLen target)
+       ? concatmakeNewIndices lo (stringLen input - stringLen target) target input x 
+  *** QED 
+
+
+
+
+map_len_fusion :: SMTString -> SMTString -> List Int -> Proof
+{-@ map_len_fusion 
+  :: xi:SMTString 
+  -> yi:SMTString 
+  -> zis:List Int 
+  -> {  map (shift (stringLen (concatString xi yi))) zis == map (shift (stringLen xi)) (map (shift (stringLen yi)) zis) 
+     }
+  @-}
+map_len_fusion xi yi N 
+  =   map (shift (stringLen (concatString xi yi))) N
+  ==. N
+  ==. map (shift (stringLen xi)) N
+  ==. map (shift (stringLen xi)) (map (shift (stringLen yi)) N)
+  *** QED  
+map_len_fusion xi yi (C i is)
+  =   map (shift (stringLen (concatString xi yi))) (C i is)
+  ==. shift (stringLen (concatString xi yi)) i `C` map (shift (stringLen (concatString xi yi))) is 
+  ==. shift (stringLen xi + stringLen yi) i `C` map (shift (stringLen (concatString xi yi))) is 
+      ? concatLen xi yi 
+  ==. shift (stringLen xi) (shift (stringLen yi) i) `C` map (shift (stringLen (concatString xi yi))) is 
+      ? concatLen xi yi 
+  ==. shift (stringLen xi) (shift (stringLen yi) i) `C` map (shift (stringLen xi)) (map (shift (stringLen yi)) is)
+      ? map_len_fusion xi yi is 
+  ==. map (shift (stringLen xi)) (shift (stringLen yi) i `C` map (shift (stringLen yi)) is)
+  ==. map (shift (stringLen xi)) (map (shift (stringLen yi)) (i `C` is))
+  *** QED 
+
+smallInput :: SMTString -> SMTString -> Int -> Int -> Proof  
+{-@ smallInput :: input:SMTString -> target:{SMTString | stringLen input < stringLen target } -> lo:Nat -> hi:Int 
+           -> {makeIndices input target lo hi == N } 
+           / [hi -lo]
+  @-}
+smallInput input target lo hi 
+  | hi < lo 
+  = makeIndices input target lo hi 
+  ==. N
+  *** QED  
+  | lo == hi, not (isGoodIndex input target lo)
+  = makeIndices input target lo hi 
+  ==. N
+  *** QED  
+  | not (isGoodIndex input target lo)
+  = makeIndices input target lo hi 
+  ==. makeIndices input target (lo+1) hi
+  ==. N ? smallInput input target (lo+1) hi 
+  *** QED  
+
+
+
+-------------------------------------------------------------------------------
+----------  Indexing ----------------------------------------------------------
+-------------------------------------------------------------------------------
+
+   
+data List a = N | C a (List a) deriving (Show, Eq)
+{-@ data List [idxlen] a = N | C {idxhd :: a , idxtl :: List a} @-}
+
+
+{-@ measure idxlen @-}
+{-@ idxlen :: List a -> Nat @-} 
+idxlen :: List a -> Int 
+idxlen N = 0 
+idxlen (C _ xs) = 1 + idxlen xs 
+
+{-@ reflect map @-}
+map :: (a -> b) -> List a -> List b
+map _ N = N
+map f (C x xs) = C (f x) (map f xs)
+
+{-@ reflect append @-}
+append :: List a -> List a -> List a 
+append N xs = xs 
+append (C x xs) ys = C x (append xs ys)
+
+{-@ reflect shift @-}
+shift :: Int -> Int -> Int 
+shift x y = x + y 
+
+{-@ symbolVal :: forall n proxy. KnownSymbol n => x:proxy n 
+  -> {v:String | v == n && v == symbolVal x } @-}
+{-@ measure symbolVal :: p n -> String @-}
+
+{-@ reflect makeNewIndices @-}
+{-@ makeNewIndices :: s1:SMTString -> s2:SMTString -> target:SMTString -> List (GoodIndex {concatString s1 s2} target) @-}
+makeNewIndices :: SMTString -> SMTString -> SMTString -> List Int 
+makeNewIndices s1 s2 target
+  | stringLen target < 2 
+  = N
+  | otherwise
+  = makeIndices (concatString s1 s2) target
+                 (maxInt (stringLen s1 - (stringLen target-1)) 0)
+                 (stringLen s1 - 1)
+
+
+{-@ reflect maxInt @-}
+maxInt :: Int -> Int -> Int 
+maxInt x y = if x <= y then y else x 
+
+{-@ reflect makeIndices @-}
+
+makeIndices :: SMTString -> SMTString -> Int -> Int -> List Int 
+{-@ makeIndices :: input:SMTString -> target:SMTString -> lo:{Int | 0 <= lo} -> hi:Int -> List (GoodIndex input target) 
+  / [hi - lo] @-}
+makeIndices input target lo hi 
+  | hi < lo 
+  = N
+  | lo == hi, isGoodIndex input target lo
+  = lo `C` N
+  | lo == hi 
+  = N
+makeIndices input target lo hi 
+  | isGoodIndex input target lo
+  = lo `C` (makeIndices input target (lo + 1) hi)
+  | otherwise 
+  =    makeIndices input target (lo + 1) hi 
+
+{-@ reflect isGoodIndex @-}
+isGoodIndex :: SMTString -> SMTString -> Int -> Bool 
+{-@ isGoodIndex :: input:SMTString -> target:SMTString -> i:Int 
+  -> {b:Bool | Prop b <=> IsGoodIndex input target i} @-}
+isGoodIndex input target i 
+  =  subString input i (stringLen target)  == target  
+  && i + stringLen target <= stringLen input
+  && 0 <= i    
+-------------------------------------------------------------------------------
+----------  Indexing Properties -----------------------------------------------
+-------------------------------------------------------------------------------
+
+{-@ appendEmp :: xs:List a -> {append xs N = xs } @-} 
+appendEmp :: List a -> Proof 
+appendEmp N 
+  =   append N N
+  ==. N
+  *** QED 
+appendEmp (C x xs) 
+  =   append (C x xs) N
+  ==. C x (append xs N)
+  ==. C x xs ? appendEmp xs 
+  *** QED 
+
+
+{-@ appendAssoc :: x:List a -> y:List a -> z:List a 
+     -> {(append x (append y z)) == (append (append x y) z) } @-}
+appendAssoc :: List a -> List a -> List a -> Proof
+appendAssoc N y z 
+  =   append N (append y z)
+  ==. append y z
+  ==. append (append N y) z
+  *** QED 
+appendAssoc (C x xs) y z
+  =   append (C x xs) (append y z) 
+  ==. C x (append xs (append y z))
+  ==. C x (append (append xs y) z)
+        ? appendAssoc xs y z
+  ==. append (C x (append xs y)) z
+  ==. append (append (C x xs) y) z
+  *** QED 
+
+
+
+
+makeNewIndicesNullRight :: SMTString -> SMTString -> Proof 
+{-@ makeNewIndicesNullRight 
+  :: s1:SMTString 
+  -> t:SMTString 
+  -> {makeNewIndices stringEmp s1 t == N } @-} 
+makeNewIndicesNullRight s t 
+  | stringLen t < 2 
+  = makeNewIndices stringEmp s t  ==. N *** QED 
+makeNewIndicesNullRight s t 
+  =   makeNewIndices stringEmp s t
+  ==. makeIndices (concatString stringEmp s) t
+                   (maxInt (1 + stringLen stringEmp - stringLen t) 0)
+                   (stringLen stringEmp - 1)
+  ==. makeIndices s t
+                   (maxInt (1 - stringLen t) 0)
+                   (-1)
+      ? concatStringNeutralRight s 
+  ==. makeIndices s t 0 (-1)
+  ==. N ? makeNewIndicesNullRightEmp s t  
+  *** QED 
+
+
+-- (x1 ~ x2) ~ (x3 ~ x4)
+-- == 
+-- ((x1 ~ (x2 ~ x3)) ~ x4)
+
+
+appendGroupNew :: List a -> List a -> List a -> List a -> Proof
+{-@ appendGroupNew 
+  :: x1:List a 
+  -> x2:List a 
+  -> x3:List a 
+  -> x4:List a 
+  -> {   (append (append x1 x2) (append x3 x4))
+      == (append (append x1 (append x2 x3)) x4)
+     } @-}
+appendGroupNew x1 x2 x3 x4 
+  =   (append (append x1 x2) (append x3 x4))
+  ==. (append (append (append x1 x2) x3) x4)
+      ? appendAssoc (append x1 x2) x3 x4  
+  ==. (append (append x1 (append x2 x3)) x4)
+      ? appendAssoc x1 x2 x3
+  *** QED 
+
+
+
+-- (x1 ~ (x2 ~ x3)) ~ x4 == ((x1 ~ x2) ~ x3) ~ x4
+
+appendUnGroupNew :: List a -> List a -> List a -> List a -> Proof
+{-@ appendUnGroupNew 
+  :: x1:List a 
+  -> x2:List a 
+  -> x3:List a 
+  -> x4:List a 
+  -> {   ((append (append (append x1 x2) x3) x4))
+      == (append (append x1 (append x2 x3)) x4)
+     } @-}
+appendUnGroupNew x1 x2 x3 x4 
+  =   append (append (append x1 x2) x3) x4
+  ==. append (append x1 (append x2 x3)) x4
+      ? appendAssoc x1 x2 x3 
+  *** QED 
+
+
+appendReorder :: List a -> List a -> List a -> List a -> List a -> Proof
+{-@ appendReorder 
+  :: x1:List a 
+  -> x2:List a 
+  -> x3:List a 
+  -> x4:List a 
+  -> x5:List a 
+  -> {   (append (append x1 x2) (append (append x3 x4) x5))
+      == (append (append (append (append x1 x2) x3) x4) x5)
+     } @-}
+appendReorder x1 x2 x3 x4 x5 
+  =   append (append x1 x2) (append (append x3 x4) x5)
+  ==. append (append x1 x2) (append x3 (append x4 x5))
+       ? appendAssoc x3 x4 x5 
+  ==. append (append (append x1 x2) x3) (append x4 x5)
+      ? appendAssoc (append x1 x2) x3 (append x4 x5) 
+  ==. append ((append (append (append x1 x2) x3)) x4) x5
+      ? appendAssoc (append (append x1 x2) x3) x4 x5 
+  *** QED 
+
+-- ((x1~x2) ~ ((x3~x4) ~ x5))
+-- == 
+--   ((((x1~x2) ~x3) ~x4) ~x5
+
+map_append :: (a -> b) -> List a -> List a -> Proof
+{-@ map_append 
+     :: f:(a -> b) -> xs:List a -> ys:List a 
+     -> {map f (append xs ys) == append (map f xs) (map f ys)}
+  @-}
+map_append f N ys 
+  =   map f (append N ys)
+  ==. map f ys 
+  ==. append N (map f ys)
+  ==. append (map f N) (map f ys)
+  *** QED 
+map_append f (C x xs) ys 
+  =   map f (append (C x xs) ys)
+  ==. map f (x `C` (append xs ys))
+  ==. f x `C` (map f (append xs ys))
+  ==. f x `C` (append (map f xs) (map f ys))
+      ? map_append f xs ys 
+  ==. append (f x `C` map f xs) (map f ys)
+  ==. append (map f (x `C` xs)) (map f ys)
+  *** QED 
+
+mapShiftZero :: List Int -> Proof
+{-@ mapShiftZero :: is:List Int -> {map (shift 0) is == is } @-}
+mapShiftZero N 
+  = map (shift 0) N ==. N *** QED
+mapShiftZero (C i is)
+  =   map (shift 0) (C i is)
+  ==. shift 0 i `C` map (shift 0) is 
+  ==. i `C` is ? mapShiftZero is  
+  *** QED 
+
+
+{-@ makeNewIndicesNullRightEmp :: s:SMTString -> t:SMTString -> {makeIndices s t 0 (-1) == N } @-}
+makeNewIndicesNullRightEmp :: SMTString -> SMTString -> Proof
+makeNewIndicesNullRightEmp s t 
+  =   makeIndices s t 0 (-1) 
+  ==. N
+  *** QED 
+
+makeNewIndicesNullLeft :: SMTString -> SMTString -> Proof 
+{-@ makeNewIndicesNullLeft 
+  :: s:SMTString 
+  -> t:SMTString 
+  -> {makeNewIndices s stringEmp t == N } @-} 
+makeNewIndicesNullLeft s t 
+  | stringLen t < 2 
+  = makeNewIndices s stringEmp t ==. N *** QED 
+makeNewIndicesNullLeft  s t 
+  | 1 + stringLen s <= stringLen t
+  =   makeNewIndices s stringEmp t
+  ==. makeIndices (concatString s stringEmp) t
+                   (maxInt (1 + stringLen s - stringLen t)  0)
+                   (stringLen s - 1)
+  ==. makeIndices s t
+                   0
+                   (stringLen s - 1) 
+                   ? concatStringNeutral s
+  ==. makeIndices s t
+                   0
+                   (stringLen s - 1)
+  ==. N ? makeNewIndicesNull1 s t 0 (stringLen s - 1)
+  *** QED 
+makeNewIndicesNullLeft s t 
+  =   makeNewIndices s stringEmp t
+  ==. makeIndices (concatString s stringEmp) t
+                   (maxInt (1 + stringLen s - stringLen t)  0)
+                   (stringLen s - 1)
+  ==. makeIndices (concatString s stringEmp) t
+                   (1 + stringLen s - stringLen t)
+                   (stringLen s - 1)
+  ==. makeIndices s t
+                   (1 + stringLen s - stringLen t)
+                   (stringLen s - 1) ? concatStringNeutral s 
+  ==. N ? makeNewIndicesNull2 s t (1 + stringLen s - stringLen t) (stringLen s - 1)
+  *** QED 
+
+
+makeNewIndicesNull1 :: SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ makeNewIndicesNull1 
+  :: s:SMTString 
+  -> t:{SMTString | 1 + stringLen s <= stringLen t } 
+  -> lo:Nat 
+  -> hi:Int
+  -> {makeIndices s t lo hi == N } / [hi - lo] @-} 
+makeNewIndicesNull1 s1 t lo hi
+  | hi < lo 
+  = makeIndices s1 t lo hi ==. N *** QED 
+  | lo == hi, not (isGoodIndex s1 t lo)
+  = makeIndices s1 t lo hi ==. N *** QED  
+  | not (isGoodIndex s1 t lo)
+  =   makeIndices s1 t lo hi
+  ==. makeIndices s1 t (lo + 1) hi 
+  ==. N ? makeNewIndicesNull1 s1 t (lo+1) hi
+  *** QED 
+
+
+makeNewIndicesNull2 :: SMTString -> SMTString -> Int -> Int -> Proof 
+{-@ makeNewIndicesNull2 
+  :: s:SMTString 
+  -> t:{SMTString | stringLen t < 2 + stringLen s } 
+  -> lo:{Int | -1 <= lo && 1 + stringLen s - stringLen t <= lo  } 
+  -> hi:{Int | lo <= hi}
+  -> {makeIndices s t lo hi == N } / [hi - lo] @-} 
+makeNewIndicesNull2 s1 t lo hi
+  | lo == hi, not (isGoodIndex s1 t lo)
+  = makeIndices s1 t lo hi ==. N *** QED  
+  | not (isGoodIndex s1 t lo)
+  =   makeIndices s1 t lo hi
+  ==. makeIndices s1 t (lo + 1) hi 
+  ==. N ? makeNewIndicesNull2 s1 t (lo+1) hi
+  *** QED 
+ 
diff --git a/tests/strings/todo/Boyer_Moore.hs b/tests/strings/todo/Boyer_Moore.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/todo/Boyer_Moore.hs
@@ -0,0 +1,232 @@
+{-@ LIQUID "--higherorder"       @-}
+{-@ LIQUID "--totality"          @-}
+{-@ LIQUID "--exactdc"           @-}
+
+module BoyerMoore where
+
+import Prelude hiding 
+  (foldl, map, fst, snd, scanl, filter, length, compose, endsWith, inits, reverse, take, 
+  Bool(..))
+
+import Proves 
+
+target, input :: L Int 
+target = C 1 (C 2 (C 3 (C 1 (C 2 N))))
+
+input = C 1 (C 2 N) `append` target `append` (C 3 (C 1 (C 2 N)))
+
+
+{-@ reflect map @-}
+{-@ reflect foldl @-}
+{-@ reflect fstV @-}
+{-@ reflect sndV @-}
+{-@ reflect scanl @-}
+{-@ reflect filter @-}
+{-@ reflect endsWith @-}
+{-@ reflect inits @-}
+{-@ reflect reverse @-}
+{-@ reflect append @-}
+{-@ reflect take @-}
+{-@ reflect range @-}
+{-@ reflect fork @-}
+
+matches ws = map length `compose` filter (endsWith ws) `compose` inits
+
+
+-- with map f `compose` filter p == map fst `compose` filter snd `compose` map (fork f p)
+
+-- matches ws = map fst `compose` filter snd `compose` map (fork length (endsWith ws)) `compose` inits
+
+-- with  map (fork length (endsWith ws)) `compose` inits == scanl step (P 0 N)
+
+-- matches ws = map fst `compose` filter snd `compose` scanl step (P 0 N)
+
+
+matchesBM ws
+  =  map fstV 
+      `compose`
+     filter ((reverse ws `isSubString`) `compose` sndV) 
+      `compose`
+     scanl step (P 0 N)
+
+
+
+
+
+
+-- Prop 16.1
+
+map_filter :: (a -> b) -> (a -> Bool) -> L a -> Proof 
+{-@ map_filter :: f:(a -> b) -> p:(a -> Bool) -> xs:L a 
+    ->  {map fstV (filter sndV (map (fork f p) xs)) == map f (filter p xs) }
+  @-}
+map_filter f p N 
+  =   map fstV (filter sndV (map (fork f p) N))
+  ==. map fstV (filter sndV N)
+  ==. map fstV N
+  ==. N
+  ==. map f N
+  ==. map f (filter p N) 
+  *** QED 
+
+map_filter f p (C x xs) | p x == True 
+  =   map fstV (filter sndV (map (fork f p) (C x xs)))
+  ==. map fstV (filter sndV ((fork f p x) `C` map (fork f p) xs))
+  ==. map fstV (filter sndV ((P (f x) (p x)) `C` map (fork f p) xs))
+       ? (sndV (P (f x) (p x)) ==. p x *** QED )  
+  ==. map fstV (P (f x) (p x) `C` filter sndV (map (fork f p) xs))
+  ==. fstV (P (f x) (p x)) `C` map fstV (filter sndV (map (fork f p) xs))
+  ==. (f x)  `C` map f (filter p xs) ? map_filter f p xs 
+  ==. map f (x `C` filter p xs) 
+  ==. map f (filter p (C x xs)) 
+  *** QED 
+
+map_filter f p (C x xs) 
+  =   map fstV (filter sndV (map (fork f p) (C x xs)))
+  ==. map fstV (filter sndV ((fork f p x) `C` map (fork f p) xs))
+  ==. map fstV (filter sndV ((P (f x) (p x)) `C` map (fork f p) xs))
+       ? (sndV (P (f x) (p x)) ==. p x *** QED )  
+  ==. map fstV (filter sndV (map (fork f p) xs))
+  ==. map f (filter p xs) ? map_filter f p xs 
+  ==. map f (filter p (C x xs)) 
+  *** QED 
+
+
+
+
+{-@ scan_lemma :: op:(b -> a -> b) -> e:b -> xs:L a 
+  -> {map (foldl op e) (inits xs) == scanl op e xs } @-}
+scan_lemma :: (b -> a -> b) -> b -> L a -> Proof
+scan_lemma op e N  
+  =   map (foldl op e) (inits N)
+  ==. map (foldl op e) (map (\i -> take i N) (range 0 (length N)))
+  ==. map (foldl op e) (map (\i -> take i N) (range 0 0))
+  ==. map (foldl op e) (map (\i -> take i N) (C 0 N))
+  ==. map (foldl op e) (take 0 N `C` map (\i -> take i N) N)
+  ==. map (foldl op e) (N `C` N)
+  ==. foldl op e N `C` N
+  ==. scanl op e N 
+  *** QED 
+
+scan_lemma op e xs  
+  =   map (foldl op e) (inits xs)
+  ==. scanl op e xs 
+  *** QED 
+
+step :: P Int (L a) -> a -> P Int (L a)
+step (P n sx) x = P (n+1) (x `C` sx)
+
+-- with reverse xs = foldl (flip C) N xs 
+
+
+fork :: (a -> b) -> (a -> c) -> a -> P b c 
+fork f g x = P (f x) (g x) 
+
+fstV :: P a b -> a 
+fstV (P x y) = x 
+
+sndV :: P a b -> b 
+sndV (P x y) = y 
+
+isSubString :: L Int -> L Int -> Bool 
+isSubString (C x xs) (C y ys)
+  | x == y 
+  = isSubString xs ys 
+  | otherwise 
+  = False 
+isSubString N _ 
+  = True 
+isSubString _ _ 
+  = False  
+
+compose :: (b -> c) -> (a -> b) -> a -> c
+compose f g x = f (g x)
+
+
+{-@ endsWith :: L Int -> xs:L Int -> Bool / [length xs] @-}
+endsWith :: L Int -> L Int -> Bool 
+endsWith N        N = True 
+endsWith N  (C _ _) = False
+endsWith (C _ _)  N = False
+endsWith (C x xs) (C y ys)
+  | x == y 
+  = endsWith xs ys 
+  | otherwise 
+  = endsWith (C x xs) ys 
+
+
+foldl :: (b -> a -> b) -> b -> L a -> b 
+foldl f b N        = b 
+foldl f b (C x xs) = foldl f (f b x) xs
+
+
+inits :: L a -> L (L a)
+inits xs = map f rng -- (`take` xs) (range 0 (length xs))
+  where
+    {-@ rng :: L {v:Nat | v <= length xs} @-}
+    rng = range 0 (length xs)
+    {-@ f :: i:{Nat | i <= length xs} -> L a @-}
+    f i = take i xs
+
+{-@ range :: i:Nat -> j:{Nat | i <= j} 
+          -> L {v:Nat | i <= v && v <= j} / [j - i] 
+  @-}
+range :: Int -> Int -> L Int 
+range i j 
+  | i == j 
+  = C i N 
+  | i <= j 
+  = C i (range (i+1) j)
+  | otherwise
+  = N
+
+{-@ measure length @-}
+{-@ length :: L a -> Nat @-} 
+length :: L a -> Int 
+length N        = 0 
+length (C _ xs) = 1 + length xs
+
+{-@ take :: i:Nat -> {v:L a | i <= length v} -> L a @-} 
+take :: Int -> L a -> L a 
+take i N        = N 
+take i (C x xs) = if i == 0 then N else x `C` take (i-1) xs 
+
+filter :: (a -> Bool) -> L a -> L a 
+filter _ N = N 
+filter p (C x xs)
+  | p x == True 
+  = x `C` filter p xs 
+  | otherwise
+  = filter p xs 
+
+reverse :: L a -> L a 
+reverse N = N 
+reverse (C x xs) = reverse xs `append` C x N 
+
+append :: L a -> L a -> L a 
+append N        ys = ys 
+append (C x xs) ys = C x (append xs ys)
+
+map :: (a -> b) -> L a -> L b 
+map _ N = N 
+map f (C x xs) = f x `C` map f xs 
+
+
+scanl :: (b -> a -> b) -> b -> L a -> L b
+scanl f q ls  = q `C` (case ls of
+                         N      -> N
+                         C x xs -> scanl f (f q x) xs)
+
+
+{-@ data P a b = P {pFs :: a, pSnd :: b} @-} 
+
+{-@ data Bool = True | False @-} 
+data Bool = True | False 
+  deriving (Show, Eq)
+
+data P a b = P a b 
+  deriving (Show)
+
+{-@ data L [length] a = N | C {lhead :: a, lCons :: (L a)} @-}
+data L a = N | C a (L a)
+  deriving (Show)
diff --git a/tests/strings/todo/StringIndexing.hs b/tests/strings/todo/StringIndexing.hs
new file mode 100644
--- /dev/null
+++ b/tests/strings/todo/StringIndexing.hs
@@ -0,0 +1,89 @@
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE GADTs               #-}
+{-@ LIQUID "--totality"        @-}
+
+module StringIndexing where
+
+
+import GHC.TypeLits
+import Data.String 
+
+import Data.Proxy 
+-- Structure that defines valid indeces of a type level target 
+-- symbol in a value level string
+
+data MI (tagret :: Symbol) s where 
+  MI :: IsString s => s        -- input string
+                   -> [Int]    -- valid indeces of target in input
+                   -> MI target s
+
+{-@ MI :: input:s 
+       -> [{i:Int |	 str.substr input i (str.len target)  == target }]
+       -> MI s @-}
+
+-- STEP 1:    Verification of valid structures
+-- CHALLENGE: String interepretations from SMT 
+
+
+-- THESE SHOULD BE SAFE 
+misafe1 :: MI "cat" String 
+misafe1 = MI "catdogcatsdots" []
+
+misafe2 :: MI "cat" String
+misafe2 = MI "catdogcatsdots" [1]
+
+misafe3 :: MI "cat" String
+misafe3 = MI "catdogcatsdots" [1, 7]
+
+misafe4 :: MI "cat" String
+misafe4 = MI "catdogcatsdots" [7, 1]
+
+misafe5 :: MI "cat" String
+misafe5 = MI "catdogcatsdots" [7]
+
+
+-- THIS SHOULD BE UNSAFE 
+miunsafe :: MI "dog" String
+miunsafe = MI "catdogcatsdots" [1]
+
+
+-- STEP 2: Verify that mempty and mappend satisfy the invariants 
+{-@ axiomatize mempty @-}
+mempty :: forall (target :: Symbol). MI target String
+mempty = MI "" []
+
+{-@ axiomatize mappend @-}
+mappend :: forall (target :: Symbol). (KnownSymbol target) => MI target String -> MI target String -> MI target String
+mappend (MI i1 is1) (MI i2 is2)
+  = MI input (is1 ++ (map (+ length i1) is2) ++ is)
+  where 
+  	is     = filter (\i -> substr input i len  == target) [(len1 - len) .. (len1 + len)]
+  	input  = i1 ++ i2 
+  	len1   = length i1 
+  	len    = length target 
+  	target = symbolVal (Proxy :: Proxy target)
+
+
+substr :: IsString s => s -> Int -> Int -> s 
+substr = undefined 
+
+
+-- STEP 3: Verify that mempty and mappend satisfy the monoid laws
+
+mempty_left      :: forall (target :: Symbol) s. IsString s => MI target s -> ()
+{-@ mempty_left  :: x:MI target s -> {mappend mempty x == x } @-}
+mempty_left _    = undefined 
+
+
+mempty_right     :: forall (target :: Symbol) s. IsString s => MI target s -> ()
+{-@ mempty_right :: x:MI target s -> {mappend x mempty == x } @-}
+mempty_right _   = undefined 
+
+mappend_assoc     :: forall (target :: Symbol) s. IsString s => MI target s -> MI target s -> MI target s -> ()
+{-@ mappend_assoc :: x:MI target s -> y:MI target s -> z:MI target s 
+                  -> {mappend x (mappend y z) == mappend (mappend x y) z } @-}
+mappend_assoc _ _ _ = undefined 
diff --git a/tests/test.hs b/tests/test.hs
--- a/tests/test.hs
+++ b/tests/test.hs
@@ -3,8 +3,11 @@
 {-# LANGUAGE DoAndIfThenElse     #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedStrings #-}
 module Main where
 
+
 import Control.Applicative
 import qualified Control.Concurrent.STM as STM
 import qualified Control.Monad.State as State
@@ -12,9 +15,11 @@
 import Data.Char
 import qualified Data.Functor.Compose as Functor
 import qualified Data.IntMap as IntMap
+import qualified Data.Map as Map
 import Data.Maybe (fromMaybe)
 import Data.Monoid (Sum(..))
 import Data.Proxy
+import Data.String
 import Data.Tagged
 import Data.Typeable
 import Options.Applicative
@@ -34,12 +39,14 @@
 
 import Text.Printf
 
+testRunner :: Ingredient
 testRunner = rerunningTests
                [ listingTests
                , combineReporters myConsoleReporter antXMLRunner
                , myConsoleReporter
                ]
 
+myConsoleReporter :: Ingredient
 myConsoleReporter = combineReporters consoleTestReporter loggingTestReporter
 
 main :: IO ()
@@ -53,6 +60,7 @@
                                  , Option (Proxy :: Proxy SmtSolver) ]
               ]
     tests = group "Tests" [ unitTests, benchTests ]
+    -- tests = group "Tests" [ benchTests ]
     -- tests = group "Tests" [ selfTests ]
 
 data SmtSolver = Z3 | CVC4 deriving (Show, Read, Eq, Ord, Typeable)
@@ -67,7 +75,12 @@
       <> help (untag (optionHelp :: Tagged SmtSolver String))
       )
 
-newtype LiquidOpts = LO String deriving (Show, Read, Eq, Ord, Typeable)
+newtype LiquidOpts = LO String deriving (Show, Read, Eq, Ord, Typeable, IsString)
+instance Monoid LiquidOpts where
+  mempty = LO ""
+  mappend (LO "") y = y
+  mappend x (LO "") = x
+  mappend (LO x) (LO y) = LO $ x ++ (' ' : y)
 instance IsOption LiquidOpts where
   defaultValue = LO ""
   parseValue = Just . LO
@@ -79,28 +92,38 @@
       <> help (untag (optionHelp :: Tagged LiquidOpts String))
       )
 
+unitTests :: IO TestTree
 unitTests
   = group "Unit" [
-      testGroup "pos"         <$> dirTests "tests/pos"                            []           ExitSuccess
-    , testGroup "neg"         <$> dirTests "tests/neg"                            []           (ExitFailure 1)
-    , testGroup "crash"       <$> dirTests "tests/crash"                          []           (ExitFailure 2)
-    , testGroup "parser/pos"  <$> dirTests "tests/parser/pos"                     []           ExitSuccess
-    , testGroup "error/crash" <$> dirTests "tests/error_messages/crash"           []           (ExitFailure 2)
-    , testGroup "eq_pos"      <$> dirTests "tests/equationalproofs/pos"           ["Axiomatize.hs"]           ExitSuccess
-    , testGroup "eq_neg"      <$> dirTests "tests/equationalproofs/neg"           ["Axiomatize.hs"]           (ExitFailure 1)
+      testGroup "pos"         <$> dirTests "tests/pos"                            ["mapreduce.hs"]   ExitSuccess
+    , testGroup "neg"         <$> dirTests "tests/neg"                            negIgnored        (ExitFailure 1)
+    , testGroup "crash"       <$> dirTests "tests/crash"                          []                (ExitFailure 2)
+    , testGroup "parser/pos"  <$> dirTests "tests/parser/pos"                     []                ExitSuccess
+    , testGroup "error/crash" <$> dirTests "tests/error_messages/crash"           []                (ExitFailure 2)
+    , testGroup "gradual_pos" <$> dirTests "tests/gradual/pos"                    gPosIgnored       ExitSuccess
+    , testGroup "gradual_neg" <$> dirTests "tests/gradual/neg"                    gNegIgnored       (ExitFailure 1)
+    -- , testGroup "eq_pos"      <$> dirTests "tests/equationalproofs/pos"           ["Axiomatize.hs", "Equational.hs"]           ExitSuccess
+    -- , testGroup "eq_neg"      <$> dirTests "tests/equationalproofs/neg"           ["Axiomatize.hs", "Equational.hs"]           (ExitFailure 1)
    ]
 
+gPosIgnored = ["Intro.hs"]
+gNegIgnored = ["Interpretations.hs", "Gradual.hs"]
+
+benchTests :: IO TestTree
 benchTests
   = group "Benchmarks" [
-      testGroup "text"        <$> dirTests "benchmarks/text-0.11.2.3"             textIgnored               ExitSuccess
-    , testGroup "bytestring"  <$> dirTests "benchmarks/bytestring-0.9.2.1"        []                        ExitSuccess
-    , testGroup "esop"        <$> dirTests "benchmarks/esop2013-submission"       ["Base0.hs"]              ExitSuccess
-    , testGroup "vect-algs"   <$> dirTests "benchmarks/vector-algorithms-0.5.4.2" []                        ExitSuccess
-    , testGroup "hscolour"    <$> dirTests "benchmarks/hscolour-1.20.0.0"         ["HsColour.hs"]           ExitSuccess
-    , testGroup "icfp_pos"    <$> dirTests "benchmarks/icfp15/pos"                ["RIO.hs", "DataBase.hs"] ExitSuccess
-    , testGroup "icfp_neg"    <$> dirTests "benchmarks/icfp15/neg"                ["RIO.hs", "DataBase.hs"] (ExitFailure 1)
-    ]
+       testGroup "text"        <$> dirTests "benchmarks/text-0.11.2.3"             textIgnored               ExitSuccess
+     , testGroup "bytestring"  <$> dirTests "benchmarks/bytestring-0.9.2.1"        []                        ExitSuccess
+     , testGroup "esop"        <$> dirTests "benchmarks/esop2013-submission"       ["Base0.hs"]              ExitSuccess
+     , testGroup "vect-algs"   <$> dirTests "benchmarks/vector-algorithms-0.5.4.2" []                        ExitSuccess
+     , testGroup "icfp_pos"    <$> dirTests "benchmarks/icfp15/pos"                icfpIgnored               ExitSuccess
+     , testGroup "icfp_neg"    <$> dirTests "benchmarks/icfp15/neg"                icfpIgnored               (ExitFailure 1)
+     , testGroup "pldi17_pos"  <$> dirTests "benchmarks/pldi17/pos"                proverIgnored             ExitSuccess
+     , testGroup "pldi17_neg"  <$> dirTests "benchmarks/pldi17/neg"                proverIgnored             (ExitFailure 1)
+     , testGroup "instances"   <$> dirTests "benchmarks/proofautomation/pos"       proverIgnored             ExitSuccess
+     ]
 
+selfTests :: IO TestTree
 selfTests
   = group "Self" [
       testGroup "liquid"      <$> dirTests "src"  [] ExitSuccess
@@ -130,8 +153,10 @@
       else do
         createDirectoryIfMissing True $ takeDirectory log
         bin <- binPath "liquid"
+        hSetBuffering stdout LineBuffering -- or even NoBuffering
         withFile log WriteMode $ \h -> do
-          let cmd     = testCmd bin dir file smt opts
+          let cmd     = testCmd bin dir file smt $ mappend (extraOptions dir test) opts
+          -- let cmd     = testCmd bin dir file smt $ mappend (extraOptions dir test) $ mappend "-v" opts
           (_,_,_,ph) <- createProcess $ (shell cmd) {std_out = UseHandle h, std_err = UseHandle h}
           c          <- waitForProcess ph
           renameFile log $ log <.> (if code == c then "pass" else "fail")
@@ -142,10 +167,12 @@
     test = dir </> file
     log = "tests/logs/cur" </> test <.> "log"
 
+binPath :: FilePath -> IO FilePath
 binPath pkgName = do
   testPath <- getExecutablePath
-  return    $ (takeDirectory $ takeDirectory testPath) </> pkgName </> pkgName
+  return    $ takeDirectory (takeDirectory testPath) </> pkgName </> pkgName
 
+knownToFail :: SmtSolver -> [FilePath]
 knownToFail CVC4 = [ "tests/pos/linspace.hs"
                    , "tests/pos/RealProps.hs"
                    , "tests/pos/RealProps1.hs"
@@ -155,19 +182,74 @@
                    , "tests/neg/maps.hs"
                    , "tests/pos/Product.hs"
                    , "tests/pos/Gradual.hs"
+                   , "tests/equationalproofs/pos/MapAppend.hs"
                    ]
 
 knownToFail Z3   = [ "tests/pos/linspace.hs"
-                   , "tests/pos/Gradual.hs"
+                   , "tests/equationalproofs/pos/MapAppend.hs"
                    ]
 
+--------------------------------------------------------------------------------
+extraOptions :: FilePath -> FilePath -> LiquidOpts
+--------------------------------------------------------------------------------
+extraOptions dir test = mappend (dirOpts dir) (testOpts test)
+  where
+    dirOpts = flip (Map.findWithDefault mempty) $ Map.fromList
+      [ ( "benchmarks/bytestring-0.9.2.1"
+        , "-iinclude --c-files=cbits/fpstring.c"
+        )
+      , ( "benchmarks/text-0.11.2.3"
+        , "-i../bytestring-0.9.2.1 -i../bytestring-0.9.2.1/include --c-files=../bytestring-0.9.2.1/cbits/fpstring.c -i../../include --c-files=cbits/cbits.c"
+        )
+      , ( "benchmarks/vector-0.10.0.1"
+        , "-i."
+        )
+      ]
+    testOpts = flip (Map.findWithDefault mempty) $ Map.fromList
+      [ ( "tests/pos/Class2.hs"
+        , "-i../neg"
+        )
+      , ( "tests/pos/FFI.hs"
+        , "-i../ffi-include --c-files=../ffi-include/foo.c"
+        )
+      ]
+
 ---------------------------------------------------------------------------
 testCmd :: FilePath -> FilePath -> FilePath -> SmtSolver -> LiquidOpts -> String
 ---------------------------------------------------------------------------
 testCmd bin dir file smt (LO opts)
   = printf "cd %s && %s --smtsolver %s %s %s" dir bin (show smt) file opts
 
+icfpIgnored :: [FilePath]
+icfpIgnored = [ "RIO.hs"
+              , "DataBase.hs" 
+              ]
 
+proverIgnored  :: [FilePath]
+proverIgnored = [ "OverviewListInfix.hs"
+                , "Proves.hs"
+                , "Helper.hs"
+                 
+                , "FunctorReader.hs"      -- NOPROP: TODO: Niki please fix!
+                , "MonadReader.hs"        -- NOPROP: ""
+                , "ApplicativeReader.hs"  -- NOPROP: ""
+                , "FunctorReader.NoExtensionality.hs" -- Name resolution issues
+                ]
+
+
+hscIgnored :: [FilePath]
+hscIgnored = [ "HsColour.hs"
+             , "Language/Haskell/HsColour/Classify.hs"      -- eliminate
+             , "Language/Haskell/HsColour/Anchors.hs"       -- eliminate
+             , "Language/Haskell/HsColour/ACSS.hs"          -- eliminate
+             ]
+
+negIgnored :: [FilePath]
+negIgnored = [ "Lib.hs"
+             , "LibSpec.hs" 
+             ]
+
+textIgnored :: [FilePath]
 textIgnored = [ "Data/Text/Axioms.hs"
               , "Data/Text/Encoding/Error.hs"
               , "Data/Text/Encoding/Fusion.hs"
@@ -193,9 +275,10 @@
               , "Data/Text/Unsafe/Base.hs"
               , "Data/Text/UnsafeShift.hs"
               , "Data/Text/Util.hs"
+              , "Data/Text/Fusion-debug.hs"
               ]
 
-
+demosIgnored :: [FilePath]
 demosIgnored = [ "Composition.hs"
                , "Eval.hs"
                , "Inductive.hs"
@@ -207,7 +290,7 @@
 ----------------------------------------------------------------------------------------
 -- Generic Helpers
 ----------------------------------------------------------------------------------------
-
+group :: (Monad m) => TestName -> [m TestTree] -> m TestTree
 group n xs = testGroup n <$> sequence xs
 
 gitTimestamp :: IO String
@@ -234,7 +317,7 @@
 notNoise a = a /= '\"' && a /= '\n' && a /= '\r'
 
 headerDelim :: String
-headerDelim = take 80 $ repeat '-'
+headerDelim = replicate 80 '-'
 
 ----------------------------------------------------------------------------------------
 walkDirectory :: FilePath -> IO [FilePath]
@@ -265,6 +348,7 @@
 --
 -- Runs the reporters in sequence, so it's best to start with the one
 -- that will produce incremental output, e.g. 'consoleTestReporter'.
+combineReporters :: Ingredient -> Ingredient -> Ingredient
 combineReporters (TestReporter opts1 run1) (TestReporter opts2 run2)
   = TestReporter (opts1 ++ opts2) $ \opts tree -> do
       f1 <- run1 opts tree
@@ -276,6 +360,7 @@
 
 -- this is largely based on ocharles' test runner at
 -- https://github.com/ocharles/tasty-ant-xml/blob/master/Test/Tasty/Runners/AntXML.hs#L65
+loggingTestReporter :: Ingredient
 loggingTestReporter = TestReporter [] $ \opts tree -> Just $ \smap -> do
   let
     runTest _ testName _ = Traversal $ Functor.Compose $ do
diff --git a/tests/tmp/Class2.hs b/tests/tmp/Class2.hs
new file mode 100644
--- /dev/null
+++ b/tests/tmp/Class2.hs
@@ -0,0 +1,86 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-@ LIQUID "--no-termination" @-}
+module Class () where
+
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (sum, length, (!!), Functor(..))
+
+{- qualif Size(v:Int, xs:a): v = size xs @-}
+{- qualif Size(v:Int, xs:MList a): v = size xs @-}
+
+data MList a = Nil | Cons a (MList a)
+
+{-@ (!!) :: xs:MList a -> {v:Nat | v < sz xs} -> a @-}
+(!!) :: MList a -> Int -> a
+(Cons x _)  !! 0 = x
+(Cons _ xs) !! i = xs !! (i - 1)
+
+{-@ class measure sz :: forall a. a -> Int  @-}
+
+{-@ class Sized s where
+      size :: forall a. x:s a -> {v:Nat | v = sz x}
+  @-}
+class Sized s where
+  size :: s a -> Int
+
+instance Sized MList where
+  {-@ instance measure sz :: MList a -> Int
+      sz (Nil)       = 0
+      sz (Cons x xs) = 1 + sz xs
+    @-}
+  size = length
+
+{-@ length :: xs:MList a -> {v:Nat | v = sz xs} @-}
+length :: MList a -> Int
+length Nil         = 0
+length (Cons _ xs) = 1 + length xs
+
+{-@ bob :: xs:MList a -> {v:Nat | v = sz xs} @-}
+bob :: MList a -> Int
+bob = length
+
+
+instance Sized [] where
+  {-@ instance measure sz :: [a] -> Int
+      sz ([])   = 0
+      sz (x:xs) = 1 + (sz xs)
+    @-}
+  size [] = 0
+  size (_:xs) = 1 + size xs
+
+{-@ class (Sized s) => Indexable s where
+      index :: forall a. x:s a -> {v:Nat | v < sz x} -> a
+  @-}
+class (Sized s) => Indexable s where
+  index :: s a -> Int -> a
+
+
+
+instance Indexable MList where
+  index = (!!)
+
+{-@ sum :: Indexable s => s Int -> Int @-}
+sum :: Indexable s => s Int -> Int
+sum xs = go n 0
+  where
+    n = size xs
+    go (d::Int) i
+      | i < n     = index xs i + go (d-1) (i+1)
+      | otherwise = 0
+
+
+{-@ sumMList :: MList Int -> Int @-}
+sumMList :: MList Int -> Int
+sumMList xs = go max 0
+  where
+    max = size xs
+    go (d::Int) i
+      | i < max   = index xs i + go (d-1) (i+1)
+      | otherwise = 0
+
+
+{-@ mlist3 :: {v:MList Int | sz v = 3}  @-}
+mlist3 :: MList Int
+mlist3 = 1 `Cons` (2 `Cons` (3 `Cons` Nil))
+
+foo = liquidAssert $ size (Cons 1 Nil) == size [1]
diff --git a/tests/tmp/Class3.hs b/tests/tmp/Class3.hs
new file mode 100644
--- /dev/null
+++ b/tests/tmp/Class3.hs
@@ -0,0 +1,16 @@
+-- | LH refuses to parse the `allPos` measure
+
+module Class3 where
+
+{-@ class Pos s where
+      allPos :: x:s Int -> {v:Bool | Prop v <=> allPos x}
+  @-}
+class Pos s where
+  allPos :: s Int -> Bool
+
+instance Pos [] where
+  {-@ instance measure allPos :: [Int] -> Bool
+      allPos ([])   = true
+      allPos (x:xs) = ((x > 0) && (allPos xs))          @-}
+  allPos []     = True
+  allPos (x:xs) = (x > 0) && (allPos xs)
diff --git a/tests/tmp/LiquidR.hs b/tests/tmp/LiquidR.hs
new file mode 100644
--- /dev/null
+++ b/tests/tmp/LiquidR.hs
@@ -0,0 +1,328 @@
+-- The following file includes several refinements that have been
+-- commented out, marked with 'UNCOMMENT'. As-is, running LiquidHaskell
+-- on this file produces the message:
+--    liquid: Prelude.head: empty list
+-- The refinemnts marked with UNCOMMENT can be uncommented one-by-one,
+-- each producing a different error.
+
+{-# LANGUAGE
+      Rank2Types,
+      TypeFamilies,
+      ExplicitForAll,
+      FlexibleInstances,
+      MultiParamTypeClasses,
+      ConstraintKinds,
+      FunctionalDependencies
+ #-}
+
+module LiquidR
+  (array,
+   combine,
+   and,
+   add,
+   indexNullary,
+   indexUnary,
+   indexNAry) where
+
+import Prelude ()
+-- UNCOMMENT this to avoid 'Not in scope' error
+-- Note that `Char` isn't used anywhere in this file.
+import Data.Char
+import Data.Int
+import Data.Bool
+import Data.Ord
+import Data.Maybe
+
+import qualified Mode
+
+unimplemented :: a
+unimplemented = unimplemented
+
+------------------------------------------------------------------------
+-- Container Types -----------------------------------------------------
+------------------------------------------------------------------------
+
+type Vector a = [a]
+
+data Array a = Array{
+    shape :: [Mode.Numeric],
+    elems :: [a]
+  }
+
+{-@ type ListN a N =
+      {v:[a] | (size v) = N}
+@-}
+
+{-@ measure product :: [Mode.Numeric] -> real
+      product([]) = 1
+      product(x:xs) = (fromJust x) * (product xs)
+@-}
+
+{-@ data Array a = Array{
+      shape :: (NonEmptyList PositiveNumeric),
+      elems :: (ListN a (product shape))
+    }
+@-}
+
+{-@ type NonEmptyList a =
+      {v:[a] | (size v) > 0}
+@-}
+
+{-@ type NonNegativeNumeric =
+      {v:Mode.Numeric |
+        (isJust v) =>
+          (fromJust v) >= 0 }
+@-}
+
+{-@ type PositiveNumeric =
+      {v:Mode.Numeric |
+        (isJust v) =>
+          (fromJust v) > 0 }
+@-}
+
+{-@ measure nonNegativeNumeric :: (Mode.Numeric) -> Bool @-}
+nonNegativeNumeric (Just a)  = a >= 0
+nonNegativeNumeric (Nothing) = True
+
+{-@ measure nonPositiveNumeric :: (Mode.Numeric) -> Bool @-}
+nonPositiveNumeric (Just a)  = a <= 0
+nonPositiveNumeric (Nothing) = True
+
+{-@ type NonPositiveNumeric =
+      {v:Mode.Numeric |
+        (isJust v) =>
+          (fromJust v) >= 0 }
+@-}
+
+{-@ class measure allNonNegative :: (R a) -> Bool @-}
+{-@ instance measure allNonNegative :: (Array a) -> Bool
+  allNonNegative (Array shape elems) = allNonNegative elems
+@-}
+
+{-@ instance measure allNonNegative :: [(Mode.Numeric)] -> Bool @-}
+allNonNegative ([])   = True
+allNonNegative (y:ys) = (nonNegativeNumeric y) && (allNonNegative ys)
+
+{-@ class measure allNonPositive :: (R a) -> Bool @-}
+{-@ instance measure allNonPositive :: (Array a) -> Bool
+  allNonPositive (Array shape elems) = allNonPositive elems
+@-}
+{-@ instance measure allNonPositive :: [(Mode.Numeric)] -> Bool @-}
+allNonPositive ([])   = True
+allNonPositive (y:ys) = (nonPositiveNumeric y) && (allNonPositive ys)
+
+{-@ instance measure size :: [a] -> Int
+    size ([])   = 0
+    size (x:xs) = 1 + (size xs)
+@-}
+
+{-@ instance measure size :: (Array a) -> Int
+  size (Array shape elems)   = len elems
+@-}
+
+class R m where
+  type Elem m
+  length :: m -> Int
+  length = unimplemented
+
+instance R (Vector a) where
+  type Elem (Vector a) = a
+
+instance R (Array a) where
+  type Elem (Array a) = a
+
+type ROf c m = (R c, Elem c ~ m)
+
+{-@ type RNonEmpty t m =
+      {v:(R t m) | (size v) > 0}
+  @-}
+
+{-@ type RNonEmptyOf t m =
+      {v:(ROf t m) | (size v) > 0}
+@-}
+
+
+------------------------------------------------------------------------
+-- Container Constructors ----------------------------------------------
+------------------------------------------------------------------------
+
+-- Constructor for vectors
+{-@ measure lsize :: [[a]] -> Int
+    lsize ([])   = 0
+    lsize (x:xs) = (size x) + (lsize xs)
+@-}
+
+{-@ combine ::
+     ys:([[_]]) ->
+     {v:([_]) | (size v) = (lsize ys)}
+@-}
+combine :: [[a]] ->  [a]
+combine = unimplemented
+
+-- Constructor for arrays
+{- array :: forall t u m.(R t, R u, Mode.Mode m) =>
+    a:(RNonEmptyOf t NonNegativeNumeric) => t ->
+    b:(RNonEmptyOf u m)                  => u ->
+      (Array m)
+@-}
+array :: forall a b m.(R a, R b, Mode.Mode m) =>
+            (ROf b Mode.Numeric) => b
+         -> (ROf a m) => a
+         -> (Array m)
+array shape elems = unimplemented
+
+
+-- x = array [Just 2.0 :: Mode.Numeric] [Just 2.0 :: Mode.Numeric]
+
+------------------------------------------------------------------------
+-- Subscript -----------------------------------------------------------
+------------------------------------------------------------------------
+-- UNCOMMENT; Produces error:
+-- > Error: Bad Type Specification
+-- > LiquidR.indexNullary :: (R a, Mode b) =>
+-- >                         ((R a), (~ (Elem a) b)) -> a -> {VV : [b] | size a == size VV}
+-- >     Sort Error in Refinement: {VV : [m_a17t] | size a == size VV}
+-- >     Unbound Symbol a
+-- > Perhaps you meant: VV
+
+{- indexNullary :: forall t m.(R t, Mode.Mode m) =>
+      a:(ROf t m) => t ->
+     {b:(Vector m) | (size a) = (size b) }
+@-}
+indexNullary :: forall t m.(R t, Mode.Mode m) =>
+  (ROf t m) => t -> (Vector m)
+indexNullary _ = unimplemented
+
+
+class (R a, R b, Mode.Mode c, (Elem b) ~ c)
+    => UnarySubscript a b c where
+  indexUnary :: a -> b -> (Vector (Elem a))
+  indexUnary = unimplemented
+
+-- UNCOMMENT; produces error:
+-- > liquid: <no location info>: Error: Uh oh.
+-- >     This should never happen! If you are seeing this message,
+-- > please submit a bug report at
+-- > https://github.com/ucsd-progsys/liquidhaskell/issues
+-- > with this message and the source file that caused this error.
+-- >
+-- > RefType.toType cannot handle: {v##0 : _ | allNonNegative a
+-- >             || allNonPositive v##0}
+{- instance (R t, R u, _)
+      => UnarySubscript t u (Mode.Numeric) where
+  indexUnary ::
+    a:t ->
+    b:{v:_ |
+          (allNonNegative a)
+       || (allNonPositive v)} ->
+   {c:t | if (allNonNegative b)
+          then (size c) == (size b)
+          else if (allNonPositive b)
+          then (size c) <= (size b)
+          else false}
+@-}
+instance (R a, R b, (Elem b) ~ Mode.Numeric)
+    => UnarySubscript a b Mode.Numeric
+
+{- don't know how to say anything meaningful here yet -}
+instance (R a, R b, (Elem b) ~ Mode.Logical)
+    => UnarySubscript a b Mode.Logical
+
+
+class (R a, R b) => NarySubscript a b where
+  indexNAry :: (R c, Elem a ~ Elem c) => a -> [b] -> c
+  indexNAry = unimplemented
+
+instance (Mode.Mode a, R b) => NarySubscript (Array a) b
+
+
+
+------------------------------------------------------------------------
+--Binary Operations ----------------------------------------------------
+------------------------------------------------------------------------
+
+-- The length of the result of any numeric or logical binary operation
+-- should be the length of the longest operand. The length of the
+-- longest operand must be a multiple of the length of the shortest
+-- operand. If either operand has length 0, the length of the result
+-- is 0.
+{-@ predicate ArithmeticResult A B C =
+      if (size A) = 0 || (size B) = 0
+      then (size C) = 0
+      else if (size A) >= (size B)
+           && (size A) mod (size B) = 0
+        then (size C) = (size A)
+      else if (size A) < (size B)
+           && (size B) mod (size A) = 0
+        then (size C) = (size B)
+      else false
+@-}
+
+-- UNCOMMENT; (error omitted for brevity)
+{- class (R t, R u, R v) => Addition t u v where
+    add :: a:t ->
+           b:u ->
+          {c:v | ArithmeticResult a b c }
+@-}
+class (R a, R b, R c) => Addition a b c | a b -> c  where
+  add  :: a -> b -> c
+  add  = unimplemented
+
+-- Container type of binop result depends on
+-- container type of arguments:
+--    Vector `op` Vector = Array
+--    Vector `op` Array  = Array
+--    Array  `op` Vector = Array
+--    Array  `op` Array  = Array
+
+instance (Mode.IntoNumeric a, Mode.IntoNumeric b)
+    => Addition (Vector a) (Vector b) (Vector Mode.Numeric)
+
+instance (Mode.IntoNumeric a, Mode.IntoNumeric b)
+    => Addition (Array a) (Vector b) (Array Mode.Numeric)
+
+instance (Mode.IntoNumeric a, Mode.IntoNumeric b)
+    => Addition (Vector a) (Array b) (Array Mode.Numeric)
+
+instance (Mode.IntoNumeric a, Mode.IntoNumeric b)
+    => Addition (Array a) (Array b) (Array Mode.Numeric)
+
+-- UNCOMMENT; produces same error as previous class annotation
+{- class (R t, R u, R v) => Conjunction t u v where
+    and :: a:t ->
+           b:u ->
+          {c:v | ArithmeticResult a b c }
+@-}
+class (R a, R b, R c) => Conjunction a b c | a b -> c  where
+  and :: a -> b -> c
+  and = unimplemented
+
+-- Alternatively, we can use instance refinements. These produce errors
+-- as well, but note that the error changes between one being
+-- uncommented vs. multiple being uncommented.
+-- UNCOMMENT;
+{-@ instance (Mode.IntoLogical t, Mode.IntoLogical u)
+    => Conjunction (Vector t) (Vector u) (Vector Mode.Logical) where
+    and :: a:(Vector t) ->
+           b:(Vector u) ->
+          {c:(Vector Mode.Logical) | ArithmeticResult a b c }
+@-}
+instance (Mode.IntoLogical a, Mode.IntoLogical b)
+    => Conjunction (Vector a) (Vector b) (Vector Mode.Logical)
+-- UNCOMMENT;
+{- instance (Mode.IntoLogical t, Mode.IntoLogical u)
+    => Conjunction (Array t) (Vector u) (Array Mode.Logical) where
+    and :: a:(Array t) ->
+           b:(Vector u) ->
+          {c:(Array Mode.Logical) | ArithmeticResult a b c }
+@-}
+instance (Mode.IntoLogical a, Mode.IntoLogical b)
+    => Conjunction (Array a) (Vector b) (Array Mode.Logical)
+
+instance (Mode.IntoLogical a, Mode.IntoLogical b)
+    => Conjunction (Vector a) (Array b) (Array Mode.Logical)
+
+instance (Mode.IntoLogical a, Mode.IntoLogical b)
+    => Conjunction (Array a) (Array b) (Array Mode.Logical)
+
+-- and so on...
diff --git a/tests/tmp/LiquidR2.hs b/tests/tmp/LiquidR2.hs
new file mode 100644
--- /dev/null
+++ b/tests/tmp/LiquidR2.hs
@@ -0,0 +1,150 @@
+{-@ LIQUID "--prune-unsorted" @-}
+{-@ LIQUID "--total"          @-}
+
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE QuasiQuotes          #-}
+
+module LiquidR
+  ( array
+  , combine
+  , indexNullary
+   -- and,
+   -- add,
+   -- indexUnary,
+   -- indexNAry
+  ) where
+
+import Prelude hiding (product, length)
+-- import LiquidHaskell
+
+--------------------------------------------------------------------------------
+-- Basic List Refinements ------------------------------------------------------
+--------------------------------------------------------------------------------
+
+{-@ class measure size :: forall a. a -> Int @-}
+
+{-@ instance measure size :: xs:[a] -> Int
+    size []     = 0
+    size (_:xs) = 1 + size xs   @-}
+
+{-@ listLength :: xs:[a] -> {v:Nat | v = size xs} @-}
+listLength :: [a] -> Int
+listLength []     = 0
+listLength (x:xs) = 1 + listLength xs
+
+{-@ type ListN a N = {v:[a] | size v = N} @-}
+{-@ type ListNE a = {v:[a] | size v > 0}  @-}
+{-@ type Pos      = {v:Int | 0 < v}       @-}
+
+-- Generic R Container Types ---------------------------------------------------
+
+{-@ class R c where
+      index  :: forall a. c a -> Int -> a
+      length :: forall a. me:c a -> {v:Nat | v = size me}
+  @-}
+class R c where
+  index  :: c a -> Int -> a
+  length :: c a -> Int
+
+-- A Generic Non-Empty Container -----------------------------------------------
+
+{-@ type RNE c a = {v:c a | 0 < size v} @-}
+
+-- Vector Instance -------------------------------------------------------------
+
+newtype Vector a = V [a]
+
+{-@ instance measure size :: Vector a -> Int
+    size (V xs) = size xs
+  @-}
+
+instance R Vector where
+  index  (V xs) i = xs `at` i
+  length (V xs)   = listLength xs
+
+at :: [a] -> Int -> a
+at (x:_) 0  = x
+at (_:xs) n = at xs (n-1)
+at _      _ = undefined
+
+-- Arrays ----------------------------------------------------------------------
+
+data Array a = Array {
+    shape :: [Int]
+  , elems :: [a]
+  }
+
+{-@ measure product @-}
+product :: [Int] -> Int
+product []     = 1
+product (x:xs) = x * product xs
+
+{-@ data Array a = Array {
+      shape :: ListNE Pos,
+      elems :: ListN a (product shape)
+    }                                     @-}
+
+instance R Array where
+  index  = undefined
+  length = undefined
+
+-- Modes -----------------------------------------------------------------------
+
+class Mode a
+
+type Logical = Maybe Bool
+type Numeric = Maybe Int
+
+-- | `Dim` is a refinement of `Numeric` where the values are defined
+
+type Dim = Numeric
+{-@ type Dim = {v:Numeric | isJust v} @-}
+
+instance Mode Logical
+instance Mode Numeric
+
+class (Mode a) => IntoNumeric a where
+  intoNumeric :: a -> Numeric
+
+instance IntoNumeric Numeric where
+  intoNumeric = id
+
+instance IntoNumeric Logical where
+  intoNumeric Nothing = Nothing
+  intoNumeric (Just True)  = Just 1 -- (1.0 :: Double)
+  intoNumeric (Just False) = Just 0 -- (0.0 :: Double)
+
+-- Constructor for Arrays ------------------------------------------------------
+
+array :: (R sh, R el, Mode v) => sh Dim -> el v -> Array v
+
+{-@ array :: (R sh, R el, Mode v) => RNE sh Dim -> RNE el v -> Array v @-}
+array _shape _elems = undefined
+
+-- IndexNullary ----------------------------------------------------------------
+{-@ type VectorN a N = {v:Vector a | size v = N} @-}
+
+{-@ indexNullary :: (R c) => a:(c m) -> VectorN m (size a) @-}
+indexNullary :: (R c) => c a -> (Vector a)
+indexNullary _ = undefined
+
+--------------------------------------------------------------------------------
+-- Container Constructors ------------------------------------------------------
+--------------------------------------------------------------------------------
+
+{-@ append :: xs:_ -> ys:_ -> ListN _ {size xs + size ys} @-}
+append :: [a] -> [a] -> [a]
+append []     ys = ys
+append (x:xs) ys = x : append xs ys
+
+-- Constructor for vectors
+{-@ measure lsize :: [[a]] -> Int
+    lsize []     = 0
+    lsize (x:xs) = size x + lsize xs
+  @-}
+
+{-@ combine :: ys:[[a]] -> ListN a (lsize ys) @-}
+combine :: [[a]] ->  [a]
+combine []       = []
+combine (xs:xss) = append xs (combine xss)
diff --git a/tests/tmp/Mode.hs b/tests/tmp/Mode.hs
new file mode 100644
--- /dev/null
+++ b/tests/tmp/Mode.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE FlexibleInstances #-}
+
+module Mode where
+
+type Logical = Maybe Bool
+type Numeric = Maybe Double
+
+class Mode a
+instance Mode Logical
+instance Mode Numeric
+
+
+class (Mode a) => IntoNumeric a where
+  intoNumeric :: a -> Numeric
+
+instance IntoNumeric Numeric where
+  intoNumeric = id
+
+instance IntoNumeric Logical where
+  intoNumeric Nothing = Nothing
+  intoNumeric (Just True)  = Just (1.0 :: Double)
+  intoNumeric (Just False) = Just (0.0 :: Double)
+
+
+class (Mode a) => IntoLogical a where
+  intoLogical :: a -> Logical
+
+instance IntoLogical Logical where
+  intoLogical = id
+
+instance IntoLogical Numeric where
+  intoLogical Nothing    = Nothing
+  intoLogical (Just 0.0) = Just False
+  intoLogical (Just   _) = Just True
+
+
+add :: (IntoNumeric a, IntoNumeric b) => a -> b -> Numeric
+add l r = case (intoNumeric l, intoNumeric r) of
+  ((Just l),(Just r)) -> Just (l + r)
+  (       _,       _) -> Nothing
+
+and :: (IntoLogical a, IntoLogical b) => a -> b -> Logical
+and l r = case (intoLogical l, intoLogical r) of
+  ((Just l),(Just r)) -> Just (l && r)
+  (       _,       _) -> Nothing
diff --git a/tests/tmp/T776.hs b/tests/tmp/T776.hs
new file mode 100644
--- /dev/null
+++ b/tests/tmp/T776.hs
@@ -0,0 +1,28 @@
+{- | There are 2 bugs here, that have to do with `--prune-unsorted`.
+
+     1. Why is the `prod` measure being used in the generic `size`
+        function where it doesn't fit?
+
+     2. Why are we getting such a meaningless error message?!
+
+        At the very least some mention of try `prune-unsorted` ?
+
+        Can we not put in a simple check in Bare for now:
+
+        The measure `prod` is not-polymorphic, please run with --prune-unsorted.
+        
+ -}
+
+{-@ LIQUID "--prune-unsorted" @-}
+
+module LiquidR where
+
+{-@ measure size @-}
+size        :: [a] -> Int
+size []     = 0
+size (_:xs) = 1 + size xs
+
+{-@ measure prod @-}
+prod :: [Int] -> Int
+prod []     = 1
+prod (x:xs) = x + prod xs
diff --git a/tests/tmp/T777.hs b/tests/tmp/T777.hs
new file mode 100644
--- /dev/null
+++ b/tests/tmp/T777.hs
@@ -0,0 +1,6 @@
+module Goo where 
+
+{-@ instance measure glub @-}
+glub :: [Int] -> Bool
+glub []     = True
+glub (x:xs) = ((x > 0) && (glub xs))
diff --git a/tests/todo/12-case-study-AVL.lhs b/tests/todo/12-case-study-AVL.lhs
new file mode 100644
--- /dev/null
+++ b/tests/todo/12-case-study-AVL.lhs
@@ -0,0 +1,821 @@
+Case Study: AVL Trees {#case-study-avltree}
+================================
+
+
+\begin{comment}
+\begin{code}
+{- Example of AVL trees by michaelbeaumont -}
+
+{-@ LIQUID "--diff"           @-}
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--totality"       @-}
+
+module AVL (AVL, empty, singleton, insert, insert', delete) where
+
+import qualified Data.Set as S
+import Prelude hiding (max)
+-- import Language.Haskell.Liquid.Prelude (liquidAssume)
+
+-- Test
+main = do
+    mapM_ print [a, b, c, d]
+  where
+    a = singleton 5
+    b = insert 2 a
+    c = insert 3 b
+    d = insert 7 c
+
+-- | Height is actual height (will disappear with measure-generated-invariants) ------------
+
+{-@ invariant {v:AVL a | 0 <= realHeight v && realHeight v = getHeight v} @-}
+
+{-@ inv_proof  :: t:AVL a -> {v:_ | 0 <= realHeight t && realHeight t = getHeight t } @-}
+inv_proof Leaf           = True
+inv_proof (Node k l r n) = inv_proof l && inv_proof r
+
+{-@ node :: x:a -> l:AVLL a x -> r:{AVLR a x | isBal l r 1} -> {v:AVL a | realHeight v = nodeHeight l r} @-}
+node v l r = Node v l r (nodeHeight l r)
+
+balR0, balRL, balRR :: a -> AVL a -> AVL a -> AVL a
+insR :: a -> AVL a -> AVL a
+merge :: a -> AVL a -> AVL a -> AVL a
+member :: (Ord a) => a -> AVL a -> Bool
+-- FIXME bigHt l r t  = if (realHeight l >= realHeight r) then (eqOrUp l t) else (eqOrUp r t)
+\end{code}
+\end{comment}
+
+
+One of the most fundamental abstractions in computing is that of a
+*collection* of values -- names, numbers, records -- into which we can
+rapidly `insert`, `delete` and check for `member`ship.
+
+\newthought{Trees} offer an an attractive means of implementing
+collections in the immutable setting. We can *order* the values
+to ensure that each operation takes time proportional to the
+*path* from the root to the datum being operated upon.
+If we additionally keep the tree *balanced* then each path
+is small (relative to the size of the collection), thereby
+giving us an efficient implementation for collections.
+
+\newthought{As in real life}
+maintaining order and balance is rather easier said than done.
+Often we must go through rather sophisticated gymnastics to ensure
+everything is in its right place. Fortunately, LiquidHaskell can help.
+Lets see a concrete example, that should be familiar from your introductory
+data structures class: the Georgy Adelson-Velsky and Landis' or [AVL Tree][avl-wiki].
+
+AVL Trees
+---------
+
+An `AVL` tree is defined by the following Haskell datatype:^[This chapter is based on code by Michael Beaumont.]
+
+\begin{code}
+data AVL a =
+    Leaf
+  | Node { key :: a      -- value
+         , l   :: AVL a  -- left subtree
+         , r   :: AVL a  -- right subtree
+         , ah  :: Int    -- height
+         }
+    deriving (Show)
+\end{code}
+
+While the Haskell type signature describes any old binary tree, an
+`AVL` tree like that shown in Figure [auto](#fig:avl) actually satisfies
+two crucial invariants: it should be binary search ordered and
+balanced.
+
+<div class="marginfigure"
+     id="fig:avl"
+     height="150px"
+     file="img/avl.png"
+     caption="An AVL tree is an ordered, height-balanced tree.">
+</div>
+
+\newthought{A Binary Search Ordered} tree is one where at *each*
+`Node`, the values of the `left` and `right` subtrees are strictly
+less and greater than the values at the `Node`. In the
+tree in Figure [auto](#fig:avl) the root has value `50` while its left
+and right subtrees have values in the range `9-23` and `54-76`
+respectively.  This holds at all nodes, not just the root. For
+example, the node `12` has left and right children strictly less and
+greater than `12`.
+
+\newthought{A Balanced} tree is one where at *each* node, the *heights*
+of the left and right subtrees differ by at most `1`. In
+Figure [auto](#fig:avl), at the root, the heights of the left and right subtrees
+are the same, but at the node `72` the left subtree has height `2` which is
+one more then the right subtree.
+
+\newthought{The Invariants Lead To Fast Operations.}
+Order ensures that there is at most a single path of `left` and
+`right` moves from the root at which an element can be found; balance
+ensures that each such path in the tree is of size $O(\log\ n)$ where
+$n$ is the numbers of nodes. Thus, together they ensure that the
+collection operations are efficient: they take time logarithmic in the
+size of the collection.
+
+Specifying AVL Trees
+--------------------
+
+The tricky bit is to ensure order and balance. Before we can ensure
+anything, lets tell LiquidHaskell what we mean by these terms, by
+defining legal or valid AVL trees.
+
+\newthought{To Specify Order} we just define two aliases `AVLL` and `AVLR`
+-- read *AVL-left* and *AVL-right* -- for trees whose values are strictly less
+than and greater than some value `X`:
+
+\begin{code}
+-- | Trees with value less than X
+{-@ type AVLL a X = AVL {v:a | v < X}  @-}
+
+-- | Trees with value greater than X
+{-@ type AVLR a X = AVL {v:a | X < v}  @-}
+\end{code}
+
+
+\newthought{The Real Height} of a tree is defined recursively as `0`
+for `Leaf`s and one more than the larger of left and right subtrees
+for `Node`s.  Note that we cannot simply use the `ah` field because
+thats just some arbitrary `Int` -- there is nothing to prevent a buggy
+implementation from just filling that field with `0` everywhere.  In
+short, we need the ground truth: a measure that computes the *actual*
+height of a tree. ^[**FIXME** The `inline` pragma indicates that the
+Haskell functions can be directly lifted into and used inside the
+refinement logic and measures.]
+
+\begin{code}
+{-@ measure realHeight @-}
+realHeight                :: AVL a -> Int
+realHeight Leaf           = 0
+realHeight (Node _ l r _) = nodeHeight l r
+
+{-@ inline nodeHeight @-}
+nodeHeight l r = 1 + max hl hr
+  where
+    hl         = realHeight l
+    hr         = realHeight r
+
+{-@ inline max @-}
+max :: Int -> Int -> Int
+max x y = if x > y then x else y
+\end{code}
+
+\newthought{A Reality Check} predicate ensures that a value
+`v` is indeed the *real* height of a node with subtrees `l` and `r`:
+
+\begin{code}
+{-@ inline isReal @-}
+isReal v l r = v == nodeHeight l r
+\end{code}
+
+\newthought{A Node is $n$-Balanced} if its left and right subtrees
+have a (real) height difference of at most $n$. We can specify this
+requirement as a predicate `isBal l r n`
+
+\begin{code}
+{-@ inline isBal @-}
+isBal l r n = 0 - n <= d && d <= n
+  where
+    d       = realHeight l - realHeight r
+\end{code}
+
+\newthought{A Legal AVL Tree} can now be defined via the following
+[refined data type](#refineddatatypes), which states that each `Node`
+is $1$-balanced, and that the saved height field is indeed the *real* height:
+
+\begin{code}
+{-@ data AVL a = Leaf
+               | Node { key :: a
+                      , l   :: AVLL a key
+                      , r   :: {v:AVLR a key | isBal l v 1}
+                      , ah  :: {v:Nat        | isReal v l r}
+                      }                                  @-}
+\end{code}
+
+Smart Constructors
+------------------
+
+Lets use the type to construct a few small trees which will
+also be handy in a general collection API. First, lets write
+an alias for trees of a given height:
+
+\begin{code}
+-- | Trees of height N
+{-@ type AVLN a N = {v: AVL a | realHeight v = N} @-}
+
+-- | Trees of height equal to that of another T
+{-@ type AVLT a T = AVLN a {realHeight T} @-}
+\end{code}
+
+\newthought{An Empty} collection is represented by a `Leaf`,
+which has height `0`:
+
+\begin{code}
+{-@ empty :: AVLN a 0 @-}
+empty = Leaf
+\end{code}
+
+<div class="hwex" id="Singleton">
+Consider the function `singleton` that builds an `AVL`
+tree from a single element. Fix the code below so that
+it is accepted by LiquidHaskell.
+</div>
+
+\begin{code}
+{-@ singleton :: a -> AVLN a 1 @-}
+singleton x =  Node x empty empty 0
+\end{code}
+
+As you can imagine, it can be quite tedious to keep the saved height
+field `ah` *in sync* with the *real* height. In general in such
+situations, which arose also with [lazy queues](#lazyqueue), the right
+move is to eschew the data constructor and instead use a *smart
+constructor* that will fill in the appropriate values correctly. ^[Why
+bother to save the height anyway? Why not just recompute it instead?]
+
+\newthought{The Smart Constructor} `node` takes as input the node's value `x`,
+left and right subtrees `l` and `r` and returns a tree by filling in the right
+value for the height field.
+
+\begin{code}
+{-@ mkNode :: a -> l:AVL a -> r:AVL a
+           -> AVLN a {nodeHeight l r}
+  @-}
+mkNode v l r = Node v l r h
+ where
+   h       = 1 + max hl hr
+   hl      = getHeight l
+   hr      = getHeight r
+\end{code}
+
+<div class="hwex" id="Constructor">Unfortunately, LiquidHaskell  rejects
+the above smart constructor `node`. Can you explain why? Can you fix the
+code (implementation or specification) so that the function is accepted?
+</div>
+
+\hint Think about the (refined) type of the actual constructor `Node`, and
+the properties it requires and ensures.
+
+
+Inserting Elements
+------------------
+
+Next, lets turn our attention to the problem of *adding* elements to
+an `AVL` tree. The basic strategy is this:
+
+1. *Find* the appropriate location (per ordering) to add the value,
+2. *Replace* the `Leaf` at that location with the singleton value.
+
+\noindent If you prefer the spare precision of code to the
+informality of English, here is a first stab at implementing
+insertion: ^[`node` is a fixed variant of the smart
+constructor `mkNode`. Do the exercise *without* looking at it.]
+
+
+\begin{code}
+{-@ insert0    :: (Ord a) => a -> AVL a -> AVL a @-}
+insert0 y t@(Node x l r _)
+  | y < x      = insL0 y t
+  | x < y      = insR0 y t
+  | otherwise  = t
+insert0 y Leaf = singleton y
+
+insL0 y (Node x l r _) = node x (insert0 y l) r
+insR0 y (Node x l r _) = node x l (insert0 y r)
+\end{code}
+
+
+\newthought{Unfortunately} `insert0` does not work.
+If you did the exercise above, you can replace it with `mkNode` and
+you will see that the above function is rejected by LiquidHaskell.
+The error message would essentially say that at the calls to the
+smart constructor, the arguments violate the balance requirement.
+
+\newthought{Insertion Increases The Height} of a sub-tree, making
+it *too large* relative to its sibling. For example, consider the
+tree `t0` defined as:
+
+~~~~~{.ghci}
+ghci> let t0 = Node { key = 'a'
+                    , l   = Leaf
+                    , r   = Node {key = 'd'
+                                 , l  = Leaf
+                                 , r  = Leaf
+                                 , ah = 1 }
+                    , ah = 2}
+~~~~~
+
+If we use `insert0` to add the key `'e'` (which goes after `'d'`) then we end up
+with the result:
+
+\vfill
+
+~~~~~{.ghci}
+ghci> insert0 'e' t0
+  Node { key = 'a'
+       , l   = Leaf
+       , r   = Node { key = 'd'
+                    , l   = Leaf
+                    , r   = Node { key = 'e'
+                                 , l   = Leaf
+                                 , r   = Leaf
+                                 , ah  = 1   }
+                    , ah = 2                 }
+       , ah = 3}
+~~~~~
+
+<div class="marginfigure"
+     height="150px"
+     file="img/avl-insert0.png"
+     id="fig:avl-insert0"
+     caption="Naive insertion breaks balancedness">
+</div>
+
+
+\noindent In the above, illustrated in Figure [auto](#fig:avl-insert0)
+the value `'e'` is inserted into the valid tree `t0`; it is inserted
+using `insR0`, into the *right* subtree of `t0` which already has
+height `1` and causes its height to go up to `2` which is too large
+relative to the empty left subtree of height `0`.
+
+\newthought{LiquidHaskell catches the imbalance} by rejecting `insert0`.
+The new value `y` is inserted into the right subtree `r`, which (may
+already be bigger than the left by a factor of `1`).
+As insert can return a tree with arbitrary height, possibly
+much larger than `l` and hence, LiquidHaskell rejects the call to
+the constructor `node` as the balance requirement does not hold.
+
+\newthought{Two lessons} can be drawn from the above exercise. First,
+`insert` may *increase* the height of a tree by at most `1`. So,
+second, we need a way to *rebalance* sibling trees where one has
+height `2` more than the other.
+
+Rebalancing Trees
+-----------------
+
+The brilliant insight of Adelson-Velsky and Landis was that we can,
+in fact, perform such a rebalancing with a clever bit of gardening.
+Suppose we have inserted a value into the *left* subtree `l` to
+obtain a new tree `l'` (the right case is symmetric.)
+
+\newthought{The relative heights} of `l'` and `r` fall under one of three cases:
+
++ *(RightBig)* `r`  is two more than `l'`,
++ *(LeftBig)*  `l'` is two more than `r`, and otherwise
++ *(NoBig)*    `l'` and `r` are within a factor of `1`,
+
+\newthought{We can specify} these cases as follows.
+
+\begin{code}
+{-@ inline leftBig @-}
+leftBig l r = diff l r == 2
+
+{-@ inline rightBig @-}
+rightBig l r = diff r l == 2
+
+{-@ inline diff @-}
+diff s t = getHeight s - getHeight t
+\end{code}
+
+\noindent the function `getHeight` accesses the saved height field.
+
+\begin{code}
+{-@ measure getHeight @-}
+getHeight Leaf           = 0
+getHeight (Node _ _ _ n) = n
+\end{code}
+
+In `insL`, the *RightBig* case cannot arise as `l'` is at least as
+big as `l`, which was within a factor of `1` of `r` in the valid
+input tree `t`.  In *NoBig*, we can safely link  `l'` and `r` with
+the smart constructor as they satisfy the balance requirements.
+The *LeftBig* case is the tricky one: we need a way to shuffle
+elements from the left subtree over to the right side.
+
+\newthought{What is a LeftBig tree?} Lets split into the possible
+cases for `l'`, immediately ruling out the *empty* tree because
+its height is `0` which cannot be `2` larger than any other tree.
+
++ *(NoHeavy)* the left and right subtrees of `l'` have the same height,
++ *(LeftHeavy)* the left subtree of `l'` is bigger than the right,
++ *(RightHeavy)* the right subtree of `l'` is bigger than the left.
+
+\newthought{The Balance Factor} of a tree can be used to make the above
+cases precise. Note that while the `getHeight` function returns the saved
+height (for efficiency), thanks to the invariants, we know it is in fact
+equal to the `realHeight` of the given tree.
+
+\begin{code}
+{-@ measure balFac @-}
+balFac Leaf           = 0
+balFac (Node _ l r _) = getHeight l - getHeight r
+\end{code}
+
+\newthought{Heaviness} can be encoded by testing the balance factor:
+
+\begin{code}
+{-@ inline leftHeavy @-}
+leftHeavy  t = balFac t > 0
+
+{-@ inline rightHeavy @-}
+rightHeavy t = balFac t < 0
+
+{-@ inline noHeavy @-}
+noHeavy    t = balFac t == 0
+\end{code}
+
+Adelson-Velsky and Landis observed that once you've drilled
+down  into these three cases, the shuffling suggests itself.
+
+<div class="figure"
+     id="fig:avl-balL0"
+     height="150px"
+     file="img/avl-balL0.png"
+     caption="Rotating when in the LeftBig, NoHeavy case.">
+</div>
+
+\newthought{In the NoHeavy} case, illustrated in
+Figure [auto](#fig:avl-balL0),
+the subtrees  `ll` and `lr` have the same height which is one more than that
+of `r`. Hence, we can link up `lr` and `r` and link the result with `l`.
+Here's how you would implement the rotation. Note how the preconditions
+capture the exact case we're in: the left subtree is *NoHeavy* and the right
+subtree is smaller than the left by `2`. Finally, the output type captures
+the exact height of the result, relative to the input subtrees.
+
+\begin{code}
+{-@ balL0 :: x:a
+          -> l:{AVLL a x | noHeavy l}
+          -> r:{AVLR a x | leftBig l r}
+          -> AVLN a {realHeight l + 1 }
+  @-}
+balL0 v (Node lv ll lr _) r = node lv ll (node v lr r)
+\end{code}
+
+<div class="figure"
+     height="150px"
+     file="img/avl-balLL.png"
+     caption="Rotating when in the LeftBig, LeftHeavy case."
+     id="fig:avl-balLL">
+</div>
+
+\newthought{In the LeftHeavy} case, illustrated in
+Figure [auto](#fig:avl-balLL), the subtree `ll` is larger than `lr`;
+hence `lr` has the same height as `r`, and again we can link up
+`lr` and `r` and link the result with `l`. As in the *NoHeavy* case,
+the input types capture the exact case, and the output the height of
+the resulting tree.
+
+ \begin{code}
+{-@ balLL :: x:a
+          -> l:{AVLL a x | leftHeavy l}
+          -> r:{AVLR a x | leftBig l r}
+          -> AVLT a l
+  @-}
+balLL v (Node lv ll lr _) r = node lv ll (node v lr r)
+\end{code}
+
+<div class="figure"
+     height="150px"
+     file="img/avl-balLR.png"
+     caption="Rotating when in the LeftBig, RightHeavy case."
+     id="fig:avl-balLR">
+</div>
+
+\newthought{In the RightHeavy} case, illustrated in Figure [auto](#fig:avl-balLR),
+the subtree  `lr` is larger than  `ll`. We cannot directly link it with `r` as
+the result would again be too large. Hence, we split it further into its own
+subtrees `lrl` and `lrr` and link the latter with `r`. Again, the types capture
+the requirements and guarantees of the rotation.
+
+\begin{code}
+{-@ balLR :: x:a
+          -> l:{AVLL a x | rightHeavy l}
+          -> r:{AVLR a x | leftBig l r}
+          -> AVLT a l
+  @-}
+balLR v (Node lv ll (Node lrv lrl lrr _) _) r
+  = node lrv (node lv ll lrl) (node v lrr r)
+\end{code}
+
+
+The *RightBig* cases are symmetric to the above cases where the
+left subtree is the larger one.
+
+<div class="hwex" id="RightBig, NoHeavy">
+Fix the implementation of `balR0` so that it implements the given type.
+</div>
+
+\vspace{1.0in}
+\vspace*{\fill}
+
+\begin{code}
+{-@ balR0 :: x:a
+          -> l: AVLL a x
+          -> r: {AVLR a x | rightBig l r && noHeavy r}
+          -> AVLN a {realHeight r + 1}
+  @-}
+balR0 v l r = undefined
+\end{code}
+
+<div class="hwex" id="RightBig, RightHeavy">
+Fix the implementation of `balRR` so that it implements the given type.
+</div>
+
+
+\begin{code}
+{-@ balRR :: x:a
+          -> l: AVLL a x
+          -> r:{AVLR a x | rightBig l r && rightHeavy r}
+          -> AVLT a r
+  @-}
+balRR v l r = undefined
+\end{code}
+
+<div class="hwex" id="RightBig, LeftHeavy">
+Fix the implementation of `balRL` so that it implements the given type.
+</div>
+
+\begin{code}
+{-@ balRL :: x:a
+          -> l: AVLL a x
+          -> r:{AVLR a x | rightBig l r && leftHeavy r}
+          -> AVLT a r
+  @-}
+balRL v l r = undefined
+\end{code}
+
+
+\newthought{To Correctly Insert} an element, we recursively add it
+to the left or right subtree as appropriate and then determine which
+of the above cases hold in order to call the corresponding *rebalance*
+function which restores the invariants.
+
+\begin{code}
+{-@ insert :: a -> s:AVL a -> {t: AVL a | eqOrUp s t} @-}
+insert y Leaf = singleton y
+insert y t@(Node x _ _ _)
+  | y < x     = insL y t
+  | y > x     = insR y t
+  | otherwise = t
+\end{code}
+
+\noindent The refinement, `eqOrUp` says that the height of `t` is the same
+as `s` or goes *up* by atmost `1`.
+
+\begin{code}
+{-@ inline eqOrUp @-}
+eqOrUp s t = d == 0 || d == 1
+  where
+    d      = diff t s
+\end{code}
+
+\newthought{The hard work} happens inside `insL` and `insR`. Here's the
+first; it simply inserts into the left subtree to get `l'` and then determines
+which rotation to apply.
+
+\begin{code}
+{-@ insL :: x:a
+         -> t:{AVL a | x < key t && 0 < realHeight t}
+         -> {v: AVL a | eqOrUp t v}
+  @-}
+insL a (Node v l r _)
+  | isLeftBig && leftHeavy l'  = balLL v l' r
+  | isLeftBig && rightHeavy l' = balLR v l' r
+  | isLeftBig                  = balL0 v l' r
+  | otherwise                  = node  v l' r
+  where
+    isLeftBig                  = leftBig l' r
+    l'                         = insert a l
+\end{code}
+
+<div class="hwex" id="InsertRight"> \singlestar
+\noindent The code for `insR` is symmetric. To make sure you're
+following along, why don't you fill it in?
+</div>
+
+\begin{code}
+{-@ insR :: x:a
+         -> t:{AVL a  | key t < x && 0 < realHeight t }
+         -> {v: AVL a | eqOrUp t v}
+  @-}
+insR = undefined
+\end{code}
+
+Refactoring Rebalance
+---------------------
+
+Next, lets write a function to `delete` an element from a tree.
+In general, we can apply the same strategy as `insert`:
+
+1. remove the element without worrying about heights,
+2. observe that deleting can *decrease* the height by at most `1`,
+3. perform a rotation to fix the imbalance caused by the decrease.
+
+\newthought{We painted ourselves into a corner} with `insert`: the code
+for actually inserting an element is intermingled with the code for
+determining and performing the rotation. That is, see how the code
+that determines which rotation to apply -- `leftBig`, `leftHeavy`, etc. --
+is *inside* the `insL` which does the insertion as well.
+This is correct, but it means we would have to *repeat* the case
+analysis when deleting a value, which is unfortunate.
+
+\newthought{Instead lets refactor} the rebalancing code into a
+separate function, that can be used by *both* `insert` and `delete`.
+It looks like this:
+
+\begin{code}
+{-@ bal :: x:a
+        -> l:AVLL a x
+        -> r:{AVLR a x | isBal l r 2}
+        -> {t:AVL a | reBal l r t}
+  @-}
+bal v l r
+  | isLeftBig  && leftHeavy l  = balLL v l r
+  | isLeftBig  && rightHeavy l = balLR v l r
+  | isLeftBig                  = balL0 v l r
+  | isRightBig && leftHeavy r  = balRL v l r
+  | isRightBig && rightHeavy r = balRR v l r
+  | isRightBig                 = balR0 v l r
+  | otherwise                  = node  v l r
+  where
+    isLeftBig                  = leftBig l r
+    isRightBig                 = rightBig l r
+\end{code}
+
+The `bal` function is a combination of the case-splits and rotation calls
+made by `insL` (and ahem, `insR`); it takes as input a value `x` and valid
+left and right subtrees for `x` whose heights are off by at most `2` because
+as we will have created them by inserting or deleting a value from a sibling
+whose height was at most `1` away. The `bal` function returns a valid `AVL` tree,
+whose height is constrained to satisfy the predicate `reBal l r t`, which says:
+
++ (`bigHt`) The height of `t` is the same or one bigger than the larger of `l` and `r`, and
++ (`balHt`) If `l` and `r` were already balanced (i.e. within `1`) then the height
+   of `t` is exactly equal to that of a tree built by directly linking `l`
+   and `r`.
+
+\begin{code}
+{-@ inline reBal @-}
+reBal l r t = bigHt l r t && balHt l r t
+
+{-@ inline balHt @-}
+balHt l r t = not (isBal l r 1) || isReal (realHeight t) l r
+
+{-@ inline bigHt @-}
+bigHt l r t = lBig && rBig
+  where
+    lBig    = not (hl >= hr) || (eqOrUp l t)
+    rBig    = (hl >= hr)     || (eqOrUp r t)
+    hl      = realHeight l
+    hr      = realHeight r
+\end{code}
+
+\newthought{Insert} can now be written very simply as the following function that
+recursively inserts into the appropriate subtree and then calls `bal` to fix any imbalance:
+
+\begin{code}
+{-@ insert' :: a -> s:AVL a -> {t: AVL a | eqOrUp s t} @-}
+insert' a t@(Node v l r n)
+  | a < v      = bal v (insert' a l) r
+  | a > v      = bal v l (insert' a r)
+  | otherwise  = t
+insert' a Leaf = singleton a
+\end{code}
+
+Deleting Elements
+-----------------
+
+Now we can write the `delete` function in a manner similar to `insert`:
+the easy cases are the recursive ones; here we just delete from the
+subtree and summon `bal` to clean up. Notice that the height of the
+output `t` is at most `1` *less* than that of the input `s`.
+
+\begin{code}
+{-@ delete    :: a -> s:AVL a -> {t:AVL a | eqOrDn s t} @-}
+delete y (Node x l r _)
+  | y < x     = bal x (delete y l) r
+  | x < y     = bal x l (delete y r)
+  | otherwise = merge x l r
+delete _ Leaf = Leaf
+
+{-@ inline eqOrDn @-}
+eqOrDn s t = eqOrUp t s
+\end{code}
+
+\newthought{The tricky case} is when we actually *find* the
+element that is to be removed. Here, we call `merge` to link
+up the two subtrees `l` and `r` after hoisting the smallest
+element from the right tree `r` as the new root which replaces
+the deleted element `x`.
+
+\begin{code}
+{-@ merge :: x:a -> l:AVLL a x -> r:{AVLR a x | isBal l r 1}
+          -> {t:AVL a | bigHt l r t}
+  @-}
+merge _ Leaf r = r
+merge _ l Leaf = l
+merge x l r    = bal y l r'
+  where
+   (y, r')     = getMin r
+\end{code}
+
+`getMin` recursively finds the smallest (i.e. leftmost) value
+in a tree, and returns the value and the remainder tree.  The height
+of each remainder `l'` may be lower than `l` (by at most `1`.) Hence,
+we use `bal` to restore the invariants when linking against the
+corresponding right subtree `r`.
+
+\begin{code}
+getMin (Node x Leaf r _) = (x, r)
+getMin (Node x l r _)    = (x', bal x l' r)
+  where
+    (x', l')             = getMin l
+\end{code}
+
+
+Functional Correctness
+----------------------
+
+We just saw how to implement some tricky data structure gynastics.
+Fortunately, with LiquidHaskell as a safety net we can be sure to have
+gotten all the rotation cases right and to have preserved the
+invariants crucial for efficiency and correctness.  However, there is
+nothing in the types above that captures "functional correctness",
+which, in this case, means that the operations actually implement a
+collection or set API, for example, as described [here](#mapapi).
+Lets use the techniques from that chapter to precisely specify
+and verify that our AVL operations indeed implement sets correctly, by:
+
+1. *Defining* the set of elements in a tree,
+2. *Specifying* the desired semantics of operations via types,
+3. *Verifying* the implemetation. ^[By adding [ghost operations](#lemmas), if needed.]
+
+We've done this [once before](#lemmas) already, so this is a good exercise
+to solidify your understanding of that material.
+
+\newthought{The Elements} of an `AVL` tree can be described via a measure
+defined as follows:
+
+\begin{code}
+{-@ measure elems @-}
+elems                :: (Ord a) => AVL a -> S.Set a
+elems (Node x l r _) = (S.singleton x) `S.union`
+                       (elems l)       `S.union`
+                       (elems r)
+elems Leaf           = S.empty
+\end{code}
+
+\noindent Let us use the above `measure` to specify and verify that our `AVL` library
+actually implements a `Set` or collection API.
+
+
+<div class="hwex" id="Membership">Complete the implementation of the implementation of
+`member` that checks if an element is in an `AVL` tree:
+</div>
+
+\begin{code}
+-- FIXME https://github.com/ucsd-progsys/liquidhaskell/issues/332
+{-@ member :: (Ord a) => x:a -> t:AVL a -> {v: Bool | Prop v <=> hasElem x t} @-}
+member x t = undefined
+
+{-@ type BoolP P = {v:Bool | Prop v <=> Prop P} @-}
+
+{-@ inline hasElem @-}
+hasElem x t = True
+-- FIXME hasElem x t = S.member x (elems t)
+\end{code}
+
+
+<div class="hwex" id="Insertion">Modify `insert'` to obtain
+a function `insertAPI` that states that the output tree
+contains the newly inserted element (in addition to the old elements):
+</div>
+
+\begin{code}
+{-@ insertAPI :: (Ord a) => a -> s:AVL a -> {t:AVL a | addElem x s t} @-}
+insertAPI x s = insert' x s
+
+{-@ inline addElem @-}
+addElem       :: Ord a => a -> AVL a -> AVL a -> Bool
+addElem x s t = True
+-- FIXME addElem x s t = (elems t) == (elems s) `S.union` (S.singleton x)
+\end{code}
+
+
+<div class="hwex" id="Insertion">Modify `delete` to obtain
+a function `deleteAPI` that states that the output tree
+contains the old elements minus the removed element:
+</div>
+
+\begin{code}
+{-@ deleteAPI :: (Ord a) => a -> s:AVL a -> {t: AVL a | delElem x s t} @-}
+deleteAPI x s = delete x s
+
+{-@ inline delElem @-}
+delElem       :: Ord a => a -> AVL a -> AVL a -> Bool
+delElem x s t = True
+-- FIXME delElem x s t = (elems t) == (elems s) `S.difference` (S.singleton x)
+\end{code}
diff --git a/tests/todo/2013-01-10-measuring-lists-I.lhs b/tests/todo/2013-01-10-measuring-lists-I.lhs
new file mode 100644
--- /dev/null
+++ b/tests/todo/2013-01-10-measuring-lists-I.lhs
@@ -0,0 +1,299 @@
+---
+layout: post
+title: "Measuring Lists I"
+date: 2013-01-05 16:12
+author: Ranjit Jhala
+published: false 
+comments: true
+external-url:
+categories: basic
+demo: lenMapReduce.hs
+---
+
+[Previously][vecbounds] we saw how liquid refinements can be pretty 
+handy for enforcing invariants about integers, for example the about 
+whether a `Vector` is being indexed within bounds. Now, lets see how
+they can be used to encode structural invariants about data types, in
+particular, lets see how to use the `measure` mechanism to talk about 
+the **size** of a list, and thereby write safe versions of potentially
+list manipulating functions.
+
+<!-- more -->
+
+\begin{code}
+module ListLengths where
+
+import Prelude hiding (length, map, filter, head, tail, foldl1)
+-- import Language.Haskell.Liquid.Prelude (liquidError)
+import qualified Data.HashMap.Strict as M
+import Data.Hashable 
+
+liquidError = error 
+\end{code}
+
+Measuring the Length of a List
+------------------------------
+
+To begin, we need some instrument by which to measure the length of a list.
+[Recall][vecbounds] the auxiliary functions used to represent the number of 
+elements of a `Vector`. Lets reuse this mechanism, this time, providing a 
+[definition](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/GHC/Base.spec)
+for the measure
+
+\begin{code}Specifying the length of a list 
+measure len :: forall a. [a] -> GHC.Types.Int
+len ([])     = 0
+len (y:ys)   = 1 + (len ys) 
+\end{code}
+
+The description of `len` above should be quite easy to follow. Underneath the 
+covers, LiquidHaskell transforms the above description into refined versions 
+of the types for the constructors `(:)` and `[]`,
+\begin{code}Something like 
+data [a] where 
+  []  :: forall a. {v: [a] | (len v) = 0 }
+  (:) :: forall a. y:a -> ys:[a] -> {v: [a] | (len v) = 1 + (len ys) } 
+\end{code}
+
+To appreciate this, note that we can now check that
+
+\begin{code}
+{-@ xs :: {v:[String] | (len v) = 1 } @-}
+xs = "dog" : []
+
+{-@ ys :: {v:[String] | (len v) = 2 } @-}
+ys = ["cat", "dog"]
+
+{-@ zs :: {v:[String] | (len v) = 3 } @-}
+zs = "hippo" : ys
+\end{code}
+
+Hover your mouse over the `:` and `[]` above to confirm their types!
+
+Dually, when we *de-construct* the lists, LiquidHaskell is able to relate
+the type of the outer list with its constituents. For example,
+
+\begin{code}
+{-@ zs' :: {v:[String] | (len v) = 2 } @-}
+zs' = case zs of 
+        h : t -> t
+\end{code}
+
+Here, from the use of the `:` in the pattern, LiquidHaskell can determine
+that `(len zs) = 1 + (len t)`; by combining this fact with the nugget
+that `(len zs) = 3` LiquidHaskell concludes that `t`, and hence, `zs'`
+contains two elements.
+
+Reasoning about Lengths
+-----------------------
+
+Great! Lets flex our new vocabulary by uttering types that describe the
+behavior of the usual list functions. 
+
+First up: a somewhat simplified version of the [standard library's][ghclist] 
+`length` from, slightly simplified for exposition.
+
+\begin{code}
+{-@ length :: xs:[a] -> {v: Int | v = (len xs)} @-}
+length :: [a] -> Int
+length []     = 0
+length (x:xs) = 1 + length xs
+\end{code}
+
+Similarly, we can speak and have confirmed, the types for the usual
+list-manipulators like
+
+\begin{code}
+{-@ map      :: (a -> b) -> xs:[a] -> {v:[b] | (len v) = (len xs)} @-}
+map _ []     = [] 
+map f (x:xs) = (f x) : (map f xs)
+\end{code}
+
+and
+
+\begin{code}
+{-@ filter :: (a -> Bool) -> xs:[a] -> {v:[a] | (len v) <= (len xs)} @-}
+filter _ []     = []
+filter f (x:xs) 
+  | f x         = x : filter f xs
+  | otherwise   = filter f xs
+\end{code}
+
+and, since, doubtless you are wondering,
+
+\begin{code}
+{-@ append :: xs:[a] -> ys:[a] -> {v:[a] | (len v) = (len xs) + (len ys)} @-}
+append [] ys     = ys 
+append (x:xs) ys = x : append xs ys
+\end{code}
+
+Warm Up: Safely Catching A List by The `head` (or `tail`)
+---------------------------------------------------------
+
+Now, lets see how we can use these new incantations to banish, forever,
+certain irritating kinds of errors. To wit, recall how we always summon 
+functions like `head` and `tail` with a degree of trepidation, unsure
+whether the arguments are empty, which will awaken certain beasts
+
+```
+Prelude> head []
+*** Exception: Prelude.head: empty list
+```
+
+Well, now LiquidHaskell can allow us to use these functions with confidence
+and surety, once we type them as:
+
+\begin{code}
+{-@ head   :: {v:[a] | (len v) > 0} -> a @-}
+head (x:_) = x
+head []    = liquidError "Fear not! 'twill ne'er come to pass"
+\end{code}
+
+As with the case of [divide-by-zero][ref101], LiquidHaskell deduces that
+the second equation is *dead code* since the precondition (input) type
+states that the length of the input is strictly positive, which *precludes*
+the case where the parameter is `[]`.
+
+Similarly, we may write
+
+\begin{code}
+{-@ tail :: {v:[a] | (len v) > 0} -> [a] @-}
+tail (_:xs) = xs
+tail []     = liquidError "Relaxeth! this too shall ne'er be"
+\end{code}
+
+Once again, LiquidHaskell will use the precondition to verify that the 
+`liquidError` is never invoked. 
+
+Lets use the above to write a function that eliminates stuttering, that
+is which converts "ssstringssss liiiiiike thisss"` to "strings like this".
+
+\begin{code}
+{-@ eliminateStutter :: (Eq a) => [a] -> [a] @-}
+eliminateStutter xs = map head $ groupEq xs 
+\end{code}
+
+The heavy lifting is done by `groupEq`
+
+\begin{code}
+groupEq []     = []
+groupEq (x:xs) = (x:ys) : groupEq zs
+                 where (ys,zs) = span (x ==) xs
+\end{code}
+
+which gathers consecutive equal elements in the list into a single list.
+
+ 
+By using the fact that *each element* in the output returned by 
+`groupEq` is in fact of the form `x:ys`, LiquidHaskell infers that
+`groupEq` returns a *list of non-empty lists*. 
+
+(Put your mouse over the `groupEq` identifier in the code above to see this.)
+
+Next, by automatically instantiating the type parameter for the `map` 
+in `eliminateStutter` to `(len v) > 0` LiquidHaskell deduces `head` 
+is only called on non-empty lists, thereby verifying the safety of 
+`eliminateStutter`.
+
+
+A Longer Example: MapReduce 
+---------------------------
+
+The above examples of `head` and `tail` are simple, but non-empty lists pop
+up in many places, and it is rather convenient to have the type system
+track non-emptiness without having to make up special types. Here's a
+longer example.
+
+First, lets write a function `keyMap` that expands a list of inputs into a 
+list of key-value pairs:
+
+\begin{code}
+keyMap :: (a -> [(k, v)]) -> [a] -> [(k, v)]
+keyMap f xs = concatMap f xs
+\end{code}
+
+Next, lets write a function `group` that gathers the key-value pairs into a
+`Map` from *keys* to the lists of values with that same key.
+
+\begin{code}
+group kvs = foldr (\(k, v) m -> inserts k v m) M.empty kvs 
+\end{code}
+
+The function `inserts` simply adds the new value `v` to the list of 
+previously known values `lookupDefault [] k m` for the key `k`.
+
+\begin{code}
+inserts k v m = M.insert k (v : vs) m 
+  where vs    = M.lookupDefault [] k m
+\end{code}
+
+Finally, we can write a function that *reduces* the list of values for a given
+key in the table to a single value:
+
+\begin{code}
+reduce    :: (v -> v -> v) -> M.HashMap k [v] -> M.HashMap k v
+reduce op = M.map (foldl1 op)
+\end{code}
+
+where `foldl1` is a [left-fold over *non-empty* lists][foldl1]
+
+\begin{code}
+foldl1 f (x:xs) =  foldl f x xs
+foldl1 _ []     =  liquidError "will. never. happen."
+\end{code}
+
+We can put the whole thing together to write a (*very*) simple *Map-Reduce* library
+
+\begin{code}
+{-@ mapReduce   :: (Eq k, Hashable k) 
+                => (a -> [(k, v)]) -- ^ key-mapper
+                -> (v -> v -> v)   -- ^ reduction operator
+                -> [a]             -- ^ inputs
+                -> [(k, v)]        -- ^ output key-values
+  @-}
+
+mapReduce f op  = M.toList 
+                . reduce op 
+                . group 
+                . keyMap f
+\end{code}
+
+Now, if we want to compute the frequency of `Char` in a given list of words, we can write:
+
+\begin{code}
+{-@ charFrequency :: [String] -> [(Char, Int)] @-}
+charFrequency     :: [String] -> [(Char, Int)]
+charFrequency     = mapReduce wordChars (+)
+  where wordChars = map (\c -> (c, 1)) 
+\end{code}
+
+You can take it out for a spin like so:
+
+\begin{code}
+f0 = charFrequency [ "the", "quick" , "brown"
+                   , "fox", "jumped", "over"
+                   , "the", "lazy"  , "cow"   ]
+\end{code}
+
+
+LiquidHaskell will gobble the whole thing up, and verify that none of the
+undesirable `liquidError` calls are triggered. 
+
+Conveniently, we *needn't write down any types* for `mapReduce` and friends. 
+
+The main invariant, from which safety follows is that the `Map` 
+returned by the `group` function binds each key to a *non-empty* list 
+of values. LiquidHaskell deduces this invariant by inferring suitable 
+types for `group`, `inserts`, `foldl1` and `reduce`, thereby relieving 
+us of that tedium. 
+
+In short, by riding on the broad and high shoulders of SMT, LiquidHaskell 
+makes a little typing go a long way.
+
+
+
+[vecbounds]:  /blog/2012/01/05/bounding-vectors.lhs/ 
+[ghclist]  : https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/GHC/List.lhs#L125
+[ref101]   :  /blog/2013/01/01/refinement-types-101.lhs/ 
+
+[foldl1]   : http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#foldl1
diff --git a/tests/todo/AVLTree.hs b/tests/todo/AVLTree.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/AVLTree.hs
@@ -0,0 +1,117 @@
+module AVLTree where 
+
+-- from: https://gist.github.com/gerard/109729
+
+data BT a = L 
+          | N { dep   :: !Int 
+              , value :: a   
+              , left  :: !(BT a)
+              , right :: !(BT a) 
+              }
+          deriving (Show, Eq)
+
+{-@ data BT a [dep] = L 
+                    | N (dep   :: !Int) 
+                        (value :: a   )
+                        (left  :: Bt a) 
+                        (right :: BT a) 
+  @-}
+
+-- Nice, small and useful functions
+empty = L 
+ 
+-- You could say, depth L == Nothing depth (N v L L) == Just 0, but works for
+-- me better this way:
+depth L = 0
+depth (N d _ _ _) = d 
+
+{-@ measure depth   :: BT a -> Int 
+    depth (L)         = 0
+    depth (N d x l r) = 1 + (if (depth l) <= (depth r) then (depth r) else (depth l)) 
+  @-}
+
+inorder             :: BT a -> [a]
+inorder L           = []
+inorder (N _ v l r) = inorder l ++ [v] ++ inorder r
+ 
+-- left (N _ t _) = t
+-- right (N _ _ u) = u
+-- value (N v _ _) = v
+ 
+btmin = head . inorder
+ 
+-- FIXME: Could be cleaner BT -> Int using left and right of BT
+balFactor :: BT -> BT -> Int
+balFactor t u = (depth t) - (depth u)
+ 
+-- Tricky but easy: we return a binary list with the route to the node
+search :: BT -> Int -> Maybe [Int]
+search L s = Nothing
+search (N v t u) s 
+    | v == s                  = Just []
+    | (search t s) /= Nothing = fmap ((:) 0) (search t s)
+    | (search u s) /= Nothing = fmap ((:) 1) (search u s)
+    | otherwise               = Nothing
+ 
+-- Complementary to search: get the node with the path
+getelem :: BT -> [Int] -> Maybe Int
+getelem L _ = Nothing
+getelem (N v _ _) [] = Just v
+getelem (N v t u) (x:xs)
+    | x == 0    = getelem t xs
+    | otherwise = getelem u xs
+ 
+-- If you get confused (I do), check this nice picture:
+-- http://en.wikipedia.org/wiki/Image:Tree_Rebalancing.gif
+balanceLL (N v (N vl tl ul) u)              = (N vl tl (N v ul u))
+balanceLR (N v (N vl tl (N vlr tlr ulr)) u) = (N vlr (N vl tl tlr) (N v ulr u))
+balanceRL (N v t (N vr (N vrl trl url) ur)) = (N vrl (N v t trl) (N vr url ur)) 
+balanceRR (N v t (N vr tr ur))              = (N vr (N v t tr) ur)
+ 
+-- Balanced insert
+insert :: BT -> Int -> BT
+insert L i = (N i L L)
+insert (N v t u) i
+    | i == v = (N v t u)
+    | i < v && (balFactor ti u) ==  2 && i < value t = balanceLL (N v ti u)
+    | i < v && (balFactor ti u) ==  2 && i > value t = balanceLR (N v ti u)
+    | i > v && (balFactor t ui) == -2 && i < value u = balanceRL (N v t ui)
+    | i > v && (balFactor t ui) == -2 && i > value u = balanceRR (N v t ui)
+    | i < v  = (N v ti u)
+    | i > v  = (N v t ui)
+        where ti = insert t i
+              ui = insert u i
+ 
+-- Balanced delete
+delete :: BT -> Int -> BT
+delete L d = L
+delete (N v L L) d = if v == d then L else (N v L L)
+delete (N v t L) d = if v == d then t else (N v t L)
+delete (N v L u) d = if v == d then u else (N v L u)
+delete (N v t u) d
+    | v == d                            = (N mu t dmin)
+    | v > d && abs (balFactor dt u) < 2 = (N v dt u)
+    | v < d && abs (balFactor t du) < 2 = (N v t du)
+    | v > d && (balFactor (left u) (right u)) < 0 = balanceRR (N v dt u) 
+    | v < d && (balFactor (left t) (right t)) > 0 = balanceLL (N v t du)
+    | v > d                                       = balanceRL (N v dt u)
+    | v < d                                       = balanceLR (N v t du)
+        where dmin = delete u mu
+              dt   = delete t d
+              du   = delete u d
+              mu   = btmin u
+ 
+-- Test Functions
+load :: BT -> [Int] -> BT
+load t []     = t
+load t (x:xs) = insert (load t xs) x
+ 
+unload :: BT -> [Int] -> BT
+unload t []     = t
+unload t (x:xs) = delete (unload t xs) x
+ 
+sort :: [Int] -> [Int]
+sort = inorder . (load empty)
+ 
+isBalanced L = True
+isBalanced (N _ t u) = isBalanced t && isBalanced u && abs (balFactor t u) < 2
diff --git a/tests/todo/AbsRef.hs b/tests/todo/AbsRef.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/AbsRef.hs
@@ -0,0 +1,10 @@
+module AbsRef where
+
+data F a = F a
+{-@ data F a <p :: a -> Prop> = F (x :: a)@-}
+
+
+
+{-@ foo :: F <{\v -> true}, {\v -> true}> Int @-}
+foo :: F Int
+foo = F 5
diff --git a/tests/todo/AbsRefNameClash.hs b/tests/todo/AbsRefNameClash.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/AbsRefNameClash.hs
@@ -0,0 +1,177 @@
+
+-----------------------------------------------------------------------
+-- Weight-Biased Leftist Heap, verified using LiquidHaskell -----------
+-----------------------------------------------------------------------
+-- ORIGINAL SOURCE ----------------------------------------------------
+-----------------------------------------------------------------------
+-- Copyright: 2014, Jan Stolarek, Politechnika Łódzka                --
+--                                                                   --
+-- License: See LICENSE file in root of the repo                     --
+-- Repo address: https://github.com/jstolarek/dep-typed-wbl-heaps-hs --
+--                                                                   --
+-- Basic implementation of weight-biased leftist heap. No proofs     --
+-- and no dependent types. Uses a two-pass merging algorithm.        --
+-----------------------------------------------------------------------
+
+{-@ LIQUID "--no-termination" @-}
+
+module WBL where 
+
+type Priority = Int
+
+type Rank     = Int
+
+type Nat      = Int
+
+data Heap a   = Empty | Node { pri   :: a
+                             , rnk   :: Rank
+                             , left  :: Heap a
+                             , right :: Heap a
+                             }
+
+{-@ data Heap a <p :: a -> a -> Prop> =
+      Empty | Node { pri   :: a
+                   , rnk   :: Nat 
+                   , left  :: {v: Heap<p> (a<p pri>) | ValidRank v}
+                   , right :: {v: Heap<p> (a<p pri>) | ValidRank v}
+                   }
+ @-}
+
+{-@ predicate ValidRank V = okRank V && realRank V = rank V  @-}
+{-@ type PHeap a = {v:OHeap a | ValidRank v}                 @-} 
+{-@ type OHeap a = Heap <{\root v -> root <= v}> a           @-}
+
+{-@ measure okRank        :: Heap a -> Prop
+    okRank (Empty)        = true
+    okRank (Node p k l r) = (realRank l >= realRank r && k = 1 + realRank l + realRank r  )
+  @-}
+
+{-@ measure realRank :: Heap a -> Int 
+    realRank (Empty)        = 0
+    realRank (Node p k l r) = (1 + realRank l + realRank r)
+  @-}
+
+{-@ measure rank @-}
+{-@ rank :: h:PHeap a -> {v:Nat | v = realRank h} @-}
+rank Empty          = 0 
+rank (Node _ r _ _) = r
+
+
+-- Creates heap containing a single element with a given Priority
+{-@ singleton :: a -> PHeap a  @-}
+singleton p = Node p 1 Empty Empty
+
+-- Note [Two-pass merging algorithm]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--
+-- We use a two-pass implementation of merging algorithm. One pass,
+-- implemented by merge, performs merging in a top-down manner. Second
+-- one, implemented by makeT, ensures that rank invariant of weight
+-- biased leftist tree is not violated after merging.
+--
+-- Notation:
+--
+--  h1, h2 - heaps being merged
+--  p1, p2 - priority of root element in h1 and h2
+--  l1     - left  subtree in the first  heap
+--  r1     - right subtree in the first  heap
+--  l2     - left  subtree in the second heap
+--  r2     - right subtree in the second heap
+--
+-- Merge function analyzes four cases. Two of them are base cases:
+--
+--    a) h1 is empty - return h2
+--
+--    b) h2 is empty - return h1
+--
+-- The other two cases form the inductive definition of merge:
+--
+--    c) priority p1 is higher than p2 - p1 becomes new root, l1
+--       becomes its one child and result of merging r1 with h2
+--       becomes the other child:
+--
+--               p1
+--              /  \
+--             /    \
+--            l1  r1+h2 -- here "+" denotes merging
+--
+--    d) priority p2 is higher than p2 - p2 becomes new root, l2
+--       becomes its one child and result of merging r2 with h1
+--       becomes the other child.
+--
+--               p2
+--              /  \
+--             /    \
+--            l2  r2+h1
+--
+-- Note that there is no guarantee that rank of r1+h2 (or r2+h1) will
+-- be smaller than rank of l1 (or l2). To ensure that merged heap
+-- maintains the rank invariant we pass both childred - ie. either l1
+-- and r1+h2 or l2 and r2+h1 - to makeT, which creates a new node by
+-- inspecting sizes of children and swapping them if necessary.
+
+-- makeT takes an element (Priority) and two heaps (trees). It
+-- constructs a new heap with element at the root and two heaps as
+-- children. makeT ensures that WBL heap rank invariant is maintained
+-- in the newly created tree by reversing left and right subtrees when
+-- necessary (note the inversed r and l in the False alternative of
+-- case expression).
+{-@ makeT   :: p:a -> h1:PHeap {v:a | p <= v} -> h2:PHeap {v:a | p <= v}
+            -> {v:PHeap a | realRank v = 1 + realRank h1 + realRank h2} @-}
+makeT p l r = case rank l >= rank r of
+                True  ->  Node p (1 + rank l + rank r) l r
+                False ->  Node p (1 + rank l + rank r) r l
+
+-- merge combines two heaps into one. There are two base cases and two
+-- recursive cases - see [Two-pass Merging algorithm]. Recursive cases
+-- call makeT to ensure that rank invariant is maintained after
+-- merging.
+{-@ merge :: (Ord a) => h1:PHeap a -> h2:PHeap a -> {v:PHeap a | realRank v = realRank h1 + realRank h2}  @-}
+merge Empty h2 = h2
+merge h1 Empty = h1
+merge h1@(Node p1 k1 l1 r1) h2@(Node p2 k2 l2 r2) = case p1 < p2 of
+  True  -> makeT p1 l1 (merge r1 (Node p2 k2 l2 r2))
+  False -> makeT p2 l2 (merge (Node p1 k1 l1 r1) r2)
+
+-- Inserting into a heap is performed by merging that heap with newly
+-- created singleton heap.
+{-@ insert :: (Ord a) => a -> PHeap a -> PHeap a @-}
+insert p h = merge (singleton p) h
+
+-- findMin returns element with highest priority, ie. root
+-- element. Here we encounter first serious problem: we can't return
+-- anything sensible for empty node.
+{-@ findMin :: PHeap a -> a @-}
+findMin Empty          = undefined
+findMin (Node p _ _ _) = p
+
+-- and write a safer version of findMinM
+{-@ findMinM :: PHeap a -> Maybe a @-} 
+findMinM Empty          = Nothing
+findMinM (Node p _ _ _) = Just p
+
+-- deleteMin removes the element with the highest priority by merging
+-- subtrees of a root element. Again the case of empty heap is
+-- problematic. We could give it semantics by returning Empty, but
+-- this just doesn't feel right. Why should we be able to remove
+-- elements from an empty heap?
+{-@ deleteMin :: (Ord a) => PHeap a -> PHeap a @-}
+deleteMin Empty          = undefined -- should we insert empty?
+deleteMin (Node _ _ l r) = merge l r
+
+-- As a quick sanity check let's construct some examples. Here's a
+-- heap constructed by inserting following priorities into an empty
+-- heap: 3, 0, 1, 2.
+{-@ heap :: PHeap Int @-}
+heap = insert (2 :: Int) 
+      (insert 1 
+      (insert 0 
+      (insert 3 Empty)))
+
+-- Example usage of findMin
+findMinInHeap :: Priority
+findMinInHeap = findMin heap
+
+-- Example usage of deleteMin
+deleteMinFromHeap :: Heap Int
+deleteMinFromHeap = deleteMin heap
diff --git a/tests/todo/Aliases.hs b/tests/todo/Aliases.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Aliases.hs
@@ -0,0 +1,9 @@
+module Foo where
+
+{-@ type Foos = [Foo] @-}
+
+{-@ type Foo = {v:Int | vv > 0} @-}
+
+foo :: [Int]
+{-@ foo :: Foos @-}
+foo = []
diff --git a/tests/todo/AmortizedQueue.hs b/tests/todo/AmortizedQueue.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/AmortizedQueue.hs
@@ -0,0 +1,159 @@
+module AmortizedQueue where
+
+import Prelude hiding (head)
+
+data AbsQueue a = AQ { front :: [a]
+                     , rear  :: [a] }
+
+{-@ data AbsQueue a = AQ { front :: [a]
+                         , rear  :: {v:[a] | size v <= size front} }  @-}
+
+{-@ die :: {v:String | false} -> a @-}
+die :: String -> a
+die x = error x
+
+{-@ measure size @-}
+size        :: [a] -> Int
+size []     = 0
+size (x:xs) = 1 + size xs
+
+{-@ measure qsize @-}
+qsize            :: AbsQueue a -> Int
+qsize (AQ xs ys) = size xs + size ys
+
+{-@ invariant {v:[a]        | size v >=  0} @-}
+{-@ invariant {v:AbsQueue a | qsize v >= 0} @-}
+
+{-@ type NEList  a = {v:[a]        | size v > 0} @-}
+{-@ type NEQueue a = {v:AbsQueue a | qsize v > 0} @-}
+
+
+makeQueue            :: [a] -> [a] -> AbsQueue a
+makeQueue f b
+  | size b <= size f = AQ f b
+  | otherwise        = AQ (f ++ reverse b) []
+
+                       
+{- measure qhead @-}
+
+{-@ qhead      :: NEQueue a -> a @-}
+qhead (AQ f _) = head f
+qhead _        = die "never"
+
+{- measure head @-}
+
+{-@ head   :: NEList a -> a @-}
+head (x:_) = x
+-- head _     = die "never"
+
+
+{- toList :: q:AbsQueue a -> {v:[a] | 0 < len v => head v = front q} @-}
+toList :: AbsQueue a -> [a]
+toList = undefined 
+-- forall q :: AbsQueue a, xs:: [a], x::a.
+--    not (isEmpty(q)) && asList(q) == xs =>                    
+{-
+import leon.lang._
+import leon.annotation._
+
+object AmortizedQueue {
+  sealed abstract class List
+  case class Cons(head : Int, tail : List) extends List
+  case object Nil extends List
+
+  sealed abstract class AbsQueue
+  case class Queue(front : List, rear : List) extends AbsQueue
+
+  def size(list : List) : Int = (list match {
+    case Nil => 0
+    case Cons(_, xs) => 1 + size(xs)
+  }) ensuring(_ >= 0)
+
+  def content(l: List) : Set[Int] = l match {
+    case Nil => Set.empty[Int]
+    case Cons(x, xs) => Set(x) ++ content(xs)
+  }
+  
+  def asList(queue : AbsQueue) : List = queue match {
+    case Queue(front, rear) => concat(front, reverse(rear))
+  }
+
+  def concat(l1 : List, l2 : List) : List = (l1 match {
+    case Nil => l2
+    case Cons(x,xs) => Cons(x, concat(xs, l2))
+  }) ensuring (res => size(res) == size(l1) + size(l2) && content(res) == content(l1) ++ content(l2))
+
+  def isAmortized(queue : AbsQueue) : Boolean = queue match {
+    case Queue(front, rear) => size(front) >= size(rear)
+  }
+
+  def isEmpty(queue : AbsQueue) : Boolean = queue match {
+    case Queue(Nil, Nil) => true
+    case _ => false
+  }
+
+  def reverse(l : List) : List = (l match {
+    case Nil => Nil
+    case Cons(x, xs) => concat(reverse(xs), Cons(x, Nil))
+  }) ensuring (content(_) == content(l))
+
+  def amortizedQueue(front : List, rear : List) : AbsQueue = {
+    if (size(rear) <= size(front))
+      Queue(front, rear)
+    else
+      Queue(concat(front, reverse(rear)), Nil)
+  } ensuring(isAmortized(_))
+
+  def enqueue(queue : AbsQueue, elem : Int) : AbsQueue = (queue match {
+    case Queue(front, rear) => amortizedQueue(front, Cons(elem, rear))
+  }) ensuring(isAmortized(_))
+
+  def tail(queue : AbsQueue) : AbsQueue = {
+    require(isAmortized(queue) && !isEmpty(queue))
+    queue match {
+      case Queue(Cons(f, fs), rear) => amortizedQueue(fs, rear)
+    }
+  } ensuring (isAmortized(_))
+
+  def front(queue : AbsQueue) : Int = {
+    require(isAmortized(queue) && !isEmpty(queue))
+    queue match {
+      case Queue(Cons(f, _), _) => f
+    }
+  }
+
+  @induct
+  def propFront(queue : AbsQueue, list : List) : Boolean = {
+    require(!isEmpty(queue) && isAmortized(queue))
+    if (asList(queue) == list) {
+      list match {
+        case Cons(x, _) => front(queue) == x
+      }
+    } else
+      true
+  } holds
+
+  def enqueueAndFront(queue : AbsQueue, elem : Int) : Boolean = {
+    if (isEmpty(queue))
+      front(enqueue(queue, elem)) == elem
+    else
+      true
+  } holds
+
+  def enqueueDequeueThrice(queue : AbsQueue, e1 : Int, e2 : Int, e3 : Int) : Boolean = {
+    if (isEmpty(queue)) {
+      val q1 = enqueue(queue, e1)
+      val q2 = enqueue(q1, e2)
+      val q3 = enqueue(q2, e3)
+      val e1prime = front(q3)
+      val q4 = tail(q3)
+      val e2prime = front(q4)
+      val q5 = tail(q4)
+      val e3prime = front(q5)
+      e1 == e1prime && e2 == e2prime && e3 == e3prime
+    } else
+      true
+  } holds
+}
+
+-}
diff --git a/tests/todo/Append.hs b/tests/todo/Append.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Append.hs
@@ -0,0 +1,41 @@
+{-
+  A first example in equalional reasoning. 
+  From the definition of append we should be able to 
+  semi-automatically prove the three axioms.
+ -}
+
+{-@ LIQUID "--newcheck" @-}
+{-@ LIQUID "--no-termination" @-}
+
+module Append where
+
+data L a = N |  C a (L a) deriving (Eq)
+
+{-@ measure append :: L a -> L a -> L a @-}
+append :: L a -> L a -> L a 
+append N xs        = xs
+append (C y ys) xs = C y (append ys xs) 
+
+
+{-@ type Valid = {v:Bool | Prop v <=> true } @-}
+
+{-@ prop_nil_left :: xs:L a -> Valid @-}
+prop_nil_left     :: Eq a => L a -> Bool
+prop_nil_left xs = let tmp1 = append N xs in 
+                   let tmp2 = axiom_nil_left tmp1 in 
+                   tmp2 == xs
+
+
+{-@ assume axiom_nil_left :: xs:L a ->  {v:L a | v == xs &&  append N v == v} @-}
+axiom_nil_left :: L a ->  L a
+axiom_nil_left xs = xs
+
+
+{- axiom_nil_right :: xs:L a ->  {v:L a | v == xs &&  append v N == v} @-}
+axiom_nil_right :: L a ->  L a
+axiom_nil_right xs = xs
+
+
+{- axiom_assoc :: xs:L a -> ys: L a ->  zs: L a -> {v: Bool | append xs (append ys zs) == append (append xs ys) zs } @-}
+axiom_assoc :: L a ->  L a -> L a -> Bool 
+axiom_assoc xs ys zs = True 
diff --git a/tests/todo/Append0.hs b/tests/todo/Append0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Append0.hs
@@ -0,0 +1,13 @@
+module Reverse where
+
+{-@ LIQUID "--no-termination" @-}
+
+import Prelude hiding (reverse)
+
+data List a = N | C a (List a)
+
+{-@ measure reverse @-}
+
+reverse :: List a -> List a -> List a
+reverse zs N        = zs 
+reverse zs (C y ys) = C y (reverse zs ys)
diff --git a/tests/todo/ApplicativeMaybe0.hs b/tests/todo/ApplicativeMaybe0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ApplicativeMaybe0.hs
@@ -0,0 +1,35 @@
+{-@ LIQUID "--higherorder"     @-}
+{- LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+{-@ LIQUID "--fuel=10" @-}
+
+{-# LANGUAGE IncoherentInstances   #-}
+{-# LANGUAGE FlexibleContexts #-}
+module ListFunctors where
+
+import MaybeReflect0 
+import Prelude hiding (Maybe(..))
+import Language.Haskell.Liquid.ProofCombinators
+
+
+{-
+
+liquid: liquid: panic! (the 'impossible' happened)
+  (GHC version 7.10.3 for x86_64-apple-darwin):
+  lookupRdrNameInModule
+
+Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug
+
+-}
+
+
+{-@ composition :: x:Maybe (a -> a)
+                -> y:Maybe (a -> a)
+                -> z:Maybe a
+                -> { seq x (seq y z)  = seq x (seq y z) } @-}
+composition :: Maybe (a -> a) -> Maybe (a -> a) -> Maybe a -> Proof
+composition = undefined 
+
+
+
diff --git a/tests/todo/ApplicativeMaybe1.hs b/tests/todo/ApplicativeMaybe1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ApplicativeMaybe1.hs
@@ -0,0 +1,55 @@
+{-@ LIQUID "--higherorder"     @-}
+{- LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+{-@ LIQUID "--fuel=10" @-}
+
+{-# LANGUAGE IncoherentInstances   #-}
+{-# LANGUAGE FlexibleContexts #-}
+module ListFunctors where
+
+import MaybeReflect1
+import Prelude hiding (Maybe(..))
+import Language.Haskell.Liquid.ProofCombinators
+
+
+-- This is OK
+
+{-@ compositionOK :: x:Maybe (a -> a)
+                -> y:Maybe (a -> a)
+                -> z:Maybe a
+                -> { seqm x (seqm y z)  = seqm x (seqm y z) } @-}
+
+compositionOK :: Maybe (a -> a) -> Maybe (a -> a) -> Maybe a -> Proof
+compositionOK = undefined 
+
+
+
+-- But the following says "unbound symbol seqm"
+-- Which is weird as seqm is OK in the above signature
+
+{-
+
+
+ /Users/niki/liquidtypes/liquidhaskell/tests/todo/ApplicativeMaybe1.hs:28:20: Error: Bad Type Specification
+ ListFunctors.composition :: x:(Maybe (a -> a)) -> y:(Maybe (a -> a)) -> z:(Maybe a) -> {VV : () | seqm (seqm (seqm (purem composem) x) y) z == seqm x (seqm y z)}
+     Sort Error in Refinement: {VV : Tuple | seqm (seqm (seqm (purem composem) x) y) z == seqm x (seqm y z)}
+     Unbound Symbol seqm
+ Perhaps you meant: head, len, snd
+
+-}
+
+{-@ composition :: x:Maybe (a -> a)
+                -> y:Maybe (a -> a)
+                -> z:Maybe a
+                -> { (seqm (seqm (seqm (purem composem) x) y) z)  = seqm x (seqm y z) } @-}
+
+composition :: Maybe (a -> a) -> Maybe (a -> a) -> Maybe a -> Proof
+composition = undefined 
+
+
+
+
+
+
+
diff --git a/tests/todo/Ast.hs b/tests/todo/Ast.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Ast.hs
@@ -0,0 +1,69 @@
+-- FAILING TEST: this test SHOULD FAIL BUT DOESN'T
+-- issue #519
+
+{-# LANGUAGE DeriveFunctor #-}
+module Main where
+
+data AstIndex = IxExpr | IxType
+
+{-@ measure isExprIndex @-}
+isExprIndex :: AstIndex -> Bool
+isExprIndex IxExpr = True
+isExprIndex _      = False
+
+{-@ measure isTypeIndex @-}
+isTypeIndex :: AstIndex -> Bool
+isTypeIndex IxType = True
+isTypeIndex _      = False
+
+data AstF f = Lit Int    AstIndex
+            | Var String AstIndex
+            | App f f
+            | Paren f
+
+{-@
+  data AstF f <ix :: AstIndex -> Prop>
+    = Lit Int    (i :: AstIndex<ix>)
+    | Var String (i :: AstIndex<ix>)
+    | App (fn :: f) (arg :: f)
+    | Paren (ast :: f)
+  @-}
+
+{-@ type AstFE = AstF <{\ix -> isExprIndex ix}> @-}
+{-@ type AstFT = AstF <{\ix -> isTypeIndex ix}> @-}
+
+
+-- Now lets tie the knot!
+
+newtype Fix f = In { out :: f (Fix f) }
+
+{-@ In :: f (Fix f) -> Fix f @-}
+{- In :: f (Fix f) -> Fix f @-}
+
+type Ast = Fix AstF
+
+{-@ type AstE = Fix AstFE @-}
+{-@ type AstT = Fix AstFT @-}
+
+{-@ astExprF :: AstF <{\ix -> isExprIndex ix}> (Fix (AstF <{\ix -> isExprIndex ix}>)) @-}
+astExprF :: AstF Ast
+astExprF = Lit 10 IxExpr
+
+{-@ astExpr :: Fix (AstF <{\ix -> isExprIndex ix}>)  @-}
+astExpr :: Ast
+astExpr = In astExprF
+
+
+{-@ astType :: AstT @-}
+astType :: Ast 
+astType = In (Lit 10 IxType)
+
+{-@ app :: forall <p :: AstIndex -> Prop>. Fix (AstF <p>) -> Fix (AstF <p>) -> Fix (AstF <p>) @-}
+app f x = In $ App f x
+
+{-@ id1 :: forall <p :: AstIndex -> Prop>. Fix (AstF <p>) -> Fix (AstF <p>)  @-}
+id1 :: Fix AstF -> Fix AstF
+id1 z = z
+
+{-@ wrong :: AstT @-}
+wrong = id1 astExpr
diff --git a/tests/todo/AxiomBug.hs b/tests/todo/AxiomBug.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/AxiomBug.hs
@@ -0,0 +1,14 @@
+module Nats where
+
+{-@ poo :: {v:Int | v == 0 } @-}
+poo :: Int
+poo = 1
+
+data Peano = Z
+
+{-@ axiomatize zero @-}
+zero :: Peano
+zero = Z
+
+goober :: String
+goober = "I am a cat"
diff --git a/tests/todo/Axiomatize.hs b/tests/todo/Axiomatize.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Axiomatize.hs
@@ -0,0 +1,131 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE QuasiQuotes     #-}
+
+module Axiomatize where
+
+import Language.Haskell.TH
+import Language.Haskell.TH.Quote
+import Language.Haskell.TH.Syntax
+
+import Debug.Trace
+
+import Control.Applicative
+import Data.List ((\\))
+import Data.Maybe (fromMaybe)
+
+data Proof = Proof
+
+
+{-@ auto :: Int -> b:{v:Bool |Prop v} -> Proof @-}
+auto :: Int -> Bool -> Proof
+auto _ _ = Proof
+
+{-@ cases :: Int -> b:{v:Bool |Prop v} -> Proof @-}
+cases :: Int -> Bool -> Proof
+cases _ _ = Proof
+
+
+axiomatize :: Q [Dec] -> Q [Dec]
+axiomatize q = do d <- q
+                  let vts = [(x, t) | FunD x _ <- d, SigD y t <- d, x == y ]
+                  ds <- mapM (axiomatizeOne vts) d
+                  return $ concat ds
+
+axiomatizeOne :: [(Name, Type)] -> Dec -> Q [Dec]
+axiomatizeOne env f@(FunD name cs)
+  = do axioms <- makeAxioms (lookup name env) name cs
+       return $ f:axioms
+axiomatizeOne _ (SigD _ _)
+  = return []
+axiomatizeOne _ d
+  = error $ "axiomatizeOne: Cannot axiomatize" ++ show d
+
+makeAxioms :: Maybe Type -> Name -> [Clause] -> Q [Dec]
+makeAxioms t f cs = concat <$> mapM go cs
+  where
+    go :: Clause -> Q [Dec]
+    go (Clause ps (NormalB (CaseE e ms)) []) = mapM (makeAxiomMatch f ps e) ms
+    go (Clause ps (NormalB _) [])            = makeAxiomPattern t f ps
+    go d = error $ "makeAxioms: Cannot axiomatize\n" ++ show d
+
+
+
+makeAxiomPattern :: Maybe Type -> Name -> [Pat] -> Q [Dec]
+makeAxiomPattern t g ps
+  = do ifs <- mapM reify (fst <$> ds)
+       ff <- makeFun f xs <$> axiom_body
+       ft <- makeSigT t f ps
+       return $ [ff] ++ ft
+  where
+    f = mkName $ makeNamePattern g (fst <$> ds)
+    ds = [(n, dps) |  ConP n dps <- ps]
+    xs = [x | VarP x <- (ps ++ concat (snd <$> ds))]
+
+makeSigT Nothing _ _
+  = return []
+makeSigT (Just t) f ps
+  = do r <- [t|Proof|]
+       ifs <- mapM reify (fst . snd <$> ds)
+       let ts2 = concat $ zipWith makePTys ds ifs
+       return [SigD f $ mkUnivArrow (as, ts1 ++ ts2, r)]
+  where
+    (as, ts, _) = bkUnivFun t
+    ts1 = [t | (t, VarP _) <- zip ts ps]
+    ds  = [(t, (n, dps)) |  (t, ConP n dps) <- zip ts ps]
+
+makePTys :: (Type, (Name, [Pat])) -> Info -> [Type]
+makePTys (tr, (n, dps)) (DataConI m t _ _) | n == m
+  = (applySub θ <$> [t | (t, VarP _) <- zip ts dps])
+  where (as, ts, r) = bkUnivFun t
+        θ = unify r tr
+makePTys _ _ = error "makePTys: on invalid arguments"
+
+
+unify (VarT n) t = [(n,t)]
+unify t (VarT n) = [(n,t)]
+unify (AppT t1 t2) (AppT t1' t2') = unify t1 t1' ++ unify t2 t2'
+unify (ForallT _ _ t1) t2 = unify t1 t2
+unify t1 (ForallT _ _ t2) = unify t1 t2
+unify _ _  = []
+
+applySub :: [(Name, Type)] -> Type -> Type
+applySub θ t@(VarT v) = fromMaybe t (lookup v θ)
+applySub θ (AppT t1 t2) = AppT (applySub θ t1) (applySub θ t2)
+applySub θ (ForallT _ _ _) = error "applySub: TODO"
+applySub θ t = t
+
+
+bkUnivFun = go [] []
+  where
+    go as xs (ForallT vs _ t)   = go (as ++ vs) xs t
+    go as xs (AppT (AppT ArrowT tx) t) = go as (tx:xs) t
+    go as xs t                  = (as, reverse xs, t)
+
+mkUnivArrow (as, ts, r) = ForallT as [] $ mkArrow ts r
+  where
+    mkArrow []     r = r
+    mkArrow (t:ts) r = AppT (AppT ArrowT t) $ mkArrow ts r
+
+makeAxiomMatch :: Name -> [Pat] -> Exp -> Match -> Q Dec
+makeAxiomMatch g ps (VarE x) (Match (ConP dc dps) bd decs)
+  = makeFun f xs <$> axiom_body
+  where f  = mkName $ makeName g x dc
+        xs = [p | VarP p <- ps ++ dps] \\ [x]
+
+makeFun :: Name -> [Name] -> Exp -> Dec
+makeFun f xs bd = FunD f [Clause (VarP <$> xs) (NormalB bd) []]
+
+axiom_body :: Q Exp
+axiom_body = [|Proof|]
+
+sep = "_"
+mkSep :: [String] -> String
+mkSep []  = []
+mkSep [x] = x
+mkSep (x:xs) = x ++ sep ++ mkSep xs
+
+eq  = "is"
+makeName fname x dc
+  = mkSep ["axiom", nameBase fname, nameBase x, eq, nameBase dc]
+
+makeNamePattern fname dcs = mkSep $ ["axiom", nameBase fname] ++ (nameBase <$> dcs)
diff --git a/tests/todo/BadArguments.hs b/tests/todo/BadArguments.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/BadArguments.hs
@@ -0,0 +1,10 @@
+import Prelude hiding (init)
+
+data List a = Emp               -- Nil
+            | (:::) a (List a)  -- Cons
+
+
+{-@ init :: (Int -> a) -> n:Nat -> List a n @-}
+init :: (Int -> a) -> Int -> List a
+init _ 0 = Emp
+init f n = f n ::: init f (n-1)
diff --git a/tests/todo/Box.hs b/tests/todo/Box.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Box.hs
@@ -0,0 +1,67 @@
+module Box (Box, get, put, emp) where
+
+import Data.Dynamic
+
+--------------------------------------------------------------------------------
+type Key    = Int 
+newtype Box = Box [(Key, Dynamic)]
+
+--------------------------------------------------------------------------------
+emp :: Box
+--------------------------------------------------------------------------------
+emp = Box []
+
+
+--------------------------------------------------------------------------------
+-- put :: k:Key -> v -> b:Box -> {bb:Box | bb = upd b k (Just 't)}   
+put :: (Typeable v) => Key -> v -> Box -> Box
+--------------------------------------------------------------------------------
+put k v (Box kvs) = Box ((k, toDyn v) : kvs) 
+
+
+--------------------------------------------------------------------------------
+-- get :: k:Key -> {b:Box | sel b k = Just 'v} -> v   
+get :: (Typeable v) => Key -> Box -> v 
+--------------------------------------------------------------------------------
+get k (Box kvs) = fromJust k $ fromDynamic =<< lookup k kvs
+
+
+--------------------------------------------------------------------------------
+-- | Helpers
+--------------------------------------------------------------------------------
+
+{-@ fromJust :: Key -> {v: Maybe a | isJust v} -> a @-}
+fromJust     :: Key -> Maybe a -> a
+fromJust _ (Just x) = x
+fromJust k Nothing  = safeError $ "Error on key: " ++ show k
+
+{-@ safeError :: {v:_ | false} -> a @-}
+safeError = error
+
+--------------------------------------------------------------------------------
+-- | Unit Test 
+--------------------------------------------------------------------------------
+
+b0 :: Box
+b0 = put 0 "Apple"
+   $ put 1 (4.5 :: Double)
+   $ put 2 ([1,2,3] :: [Int])
+   $ emp
+
+okFruit  :: String
+okFruit  = get 0 b0
+
+badFruit :: String
+badFruit = get 1 b0
+
+okPi     :: Double
+okPi     = get 1 b0
+
+badPi    :: Double
+badPi    = get 0 b0
+
+---------------------------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------------------------
+
+-- Whats a good signature for CONCATENATING two `Box`?
diff --git a/tests/todo/CatMaybes.hs b/tests/todo/CatMaybes.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/CatMaybes.hs
@@ -0,0 +1,24 @@
+module Fixme where
+
+
+import qualified Data.Set
+
+
+{-@ foo :: x:[a]  
+          -> {v:[a] | Set_sub (listElts v) (listElts x)}
+  @-}
+
+foo = catMaybes . map bar 
+  where
+    catMaybes [] = []
+    catMaybes (Nothing:xs) = catMaybes xs
+    catMaybes (Just x : xs) = x:catMaybes xs
+
+bar :: a -> Maybe a
+{-@ bar :: x:a -> Maybe {v:a | v = x } @-}
+bar x = if prop x then Nothing else Just x
+
+{-@ prop :: a -> Bool @-}
+prop :: a -> Bool
+prop = undefined
+
diff --git a/tests/todo/Class3.hs b/tests/todo/Class3.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Class3.hs
@@ -0,0 +1,16 @@
+module Class3 where
+
+{-@ class Pos s where
+      allPos :: x:s Int -> {v:Bool | Prop v <=> allPos x}
+  @-}
+class Pos s where
+  allPos :: s Int -> Bool
+
+instance Pos [] where
+  {-@ instance measure allPos :: [Int] -> Bool
+        allPos []     = (0 < 1)
+        allPos (x:xs) = (0 < 1)
+    @-}
+  allPos :: [a]
+  allPos []     = True
+  allPos (x:xs) = (x > 0) && (allPos xs)
diff --git a/tests/todo/Class4.hs b/tests/todo/Class4.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Class4.hs
@@ -0,0 +1,7 @@
+module Class3 where
+
+{-@ class Pos s where
+      allPos :: s a -> Bool
+  @-}
+class Pos s where
+  allPos :: s a -> Bool
diff --git a/tests/todo/Class4Import.hs b/tests/todo/Class4Import.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Class4Import.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-@ LIQUID "--no-termination" @-}
+
+module Class4Import where
+
+import Class4
+
+instance Frog () where
diff --git a/tests/todo/CmpBug.hs b/tests/todo/CmpBug.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/CmpBug.hs
@@ -0,0 +1,10 @@
+module Fixme where
+
+zipWith :: (Char -> Char -> a) -> b -> b -> [a]
+zipWith f = zipWith' ((. w2c) . f . w2c)
+
+zipWith' :: (b -> b -> a) -> c -> c -> [a]
+zipWith' = undefined
+
+w2c :: a -> Char
+w2c = undefined
diff --git a/tests/todo/CountMonadMap.hs b/tests/todo/CountMonadMap.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/CountMonadMap.hs
@@ -0,0 +1,138 @@
+module Count () where
+
+import Prelude hiding (map)
+
+
+{-@ measure count :: Count a -> Int @-}
+
+data Count a = Count a
+
+instance Functor Count where
+	fmap = undefined
+instance Applicative Count where
+  pure  = undefined
+  (<*>) = undefined
+
+instance Monad Count where
+{-@
+instance Monad Count where
+  >>=    :: forall <r :: Count a -> Prop, p :: Count b -> Prop, q :: Count b -> Prop>.
+            {x::Count a <<r>>, y :: Count b <<p>>  |- {v:Count b | count v == count x + count y} <: Count b <<q>>}
+            Count a <<r>> -> (a -> Count b<<p>>) -> Count b <<q>> ;
+  >>     :: x:Count a -> y:Count b -> {v:Count b | count v == count x + count y};
+  return :: a -> {v:Count a | count v == 0 }
+@-}
+  return x        = let r = Count x in assertCount 0 (Count x)
+  (Count x) >>= f = let r = f x in assertCount (getCount (Count x) + getCount r) r
+  x >> y = assertCount (getCount x + getCount y) y
+  fail          = error
+
+
+
+{-@ assume assertCount :: i:Int -> x:Count a -> {v:Count a | v == x && count v == i } @-}
+assertCount :: Int -> Count a -> Count a
+assertCount _ x = x
+
+{-@ assume getCount :: x:Count a -> {v:Int | v == count x } @-}
+getCount :: Count a -> Int
+getCount _ = 0
+
+
+{-@ assume incr :: a -> {v:Count a | count v == 1 } @-}
+incr :: a -> Count a
+incr = Count
+
+{-@ assume unit :: {v:Count () | count v == 0 } @-}
+unit = Count ()
+
+
+type L a = [a]
+
+{-@  map :: forall <p :: Count b -> Prop, q :: Count [b] -> Prop, l :: L a  -> Prop >.
+            {x::a, xs::[a], y :: Count b <<p>>, ys :: {v:Count [b] | count v == len xs * count y} |- {v:Count [b] | count v == count y * (len xs + 1)} <: Count [b] <<q>>}
+            (a -> Count b <<p>>) -> xs:L a -> Count {v:[b] | len v == len xs } <<q>>
+@-}
+
+map :: (a -> Count b) -> [a] -> Count [b]
+-- map f []     = return []
+
+
+{-
+
+y :: Count b 
+ys :: {c:Count {v:[b] | len v == len xs} | count c == (count y) * (len xs) }
+
+-}
+
+map f (x:xs) = 
+  let y  = f x   
+      ys = map f xs          -- count v == len xs * count y 
+      -- g y ys = return (y:ys) -- count v == 0 
+      -- h z = ys >>= (g xs y ys z)       -- count v == (len xs * count y) +count y
+  in  y >>= (h xs y ys)
+
+
+{-@ g :: xs:[a] -> y:Count b -> {v:Count [b] | count v == len xs * count y} -> z:b -> zs:[b] -> {v:Count {v:[b] | len v == len zs + 1} | count v == 0 } @-}
+g :: [a] -> Count b -> Count [b] -> b -> [b] -> Count [b]
+g _ _ _ y ys = return (y:ys)
+
+
+{-@ h :: xs:[a] -> y:Count b -> ys:{v:Count [b] | count v == len xs * count y} -> z:b -> {v:Count [b] | count v == (len xs) * (count y)} @-}
+h :: [a] -> Count b -> Count [b] -> b ->  Count [b]
+h xs y ys z = ys >>= (g xs y ys z)
+
+
+{-
+  do y <- f x
+     ys <- map f xs 
+     -- {v: ??? | count v == len xs * count c }
+     return (y:ys)
+
+-}
+
+{-
+map f (x:xs) = 
+  let y  = f x 
+      ys = map f xs
+  in y:ys     
+
+-}
+
+
+--             {xs :: L a <<l>>, ys:: {v:[a] | len v == 0 && v == xs}|- {v:Count [b] | count v == 0} <: Count [b] <<q>>}
+
+{-@ map' :: c:Count b -> xs:[a] -> {v:Count [b] | count v == (len xs) * (count c)} @-}
+map' :: Count b -> [a] -> Count [b]
+map' f []     = return []
+map' f (x:xs) = 
+  do y <- f 
+     ys <- map' f xs 
+     return (y:ys)
+
+
+{-@ foo :: a -> {v:Count a | count v == 0 }  @-}
+foo :: a -> Count a
+foo y = return y
+
+{-@ test1 :: {v:Count () | count v == 0 } @-}
+test1 :: Count ()
+test1 = do
+  unit
+  unit
+  unit
+
+{-@ test2 :: {v:Count () | count v == 1 } @-}
+test2 = do
+  unit
+  y <- incr ()
+  unit
+  foo y
+  unit
+
+{-@ test3 :: {v:Count () | count v == 2 } @-}
+test3 = do
+  unit
+  unit
+  incr ()
+  incr ()
+  unit
diff --git a/tests/todo/DB0.hs b/tests/todo/DB0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/DB0.hs
@@ -0,0 +1,27 @@
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "totality" @-}
+
+module DataBase (values) where
+
+{-@ values :: forall <range :: key -> val -> Prop>.
+  k:key -> [Dict <range> key val]  -> [val<range k>] @-}
+values :: key -> [Dict key val]  -> [val]
+values k = map go
+  where
+    go (D _ f) = f k
+
+data Dict key val = D {ddom :: [key], dfun :: key -> val}
+{-@ ddom :: forall <range :: key -> val -> Prop>.
+           x:Dict <range> key val  -> [key]
+  @-}
+
+{-@ dfun :: forall <range :: key -> val -> Prop>.
+               x:Dict <range> key val
+            -> i:key -> val<range i>
+  @-}
+
+{-@ data Dict key val <range :: key -> val -> Prop>
+  = D ( ddom :: [key])
+      ( dfun :: i:key -> val<range i>)
+  @-}
diff --git a/tests/todo/DBMovies0.hs b/tests/todo/DBMovies0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/DBMovies0.hs
@@ -0,0 +1,35 @@
+module MovieClient where
+
+
+data Tag 
+data Value
+
+
+type Table t v = [Dict t v]
+
+data Dict key val = D {ddom :: [key], dfun :: key -> val}
+
+
+{-@ fromList :: forall <range :: key -> val -> Prop, p :: Dict key val -> Prop>.
+                x:[Dict <range> key val <<p>>] -> {v:[Dict <range> key val <<p>>] | x = v}
+  @-}
+fromList :: [Dict key val] -> Table key val
+fromList xs = xs
+
+
+{-@ data Dict key val <range :: key -> val -> Prop>
+  = D ( ddom :: [key])
+      ( dfun :: i:key -> val<range i>)
+  @-}
+
+
+{-@ type Movies      = [MovieScheme] @-}
+{-@ type MovieScheme = {v:Dict <{\t val -> (t ~~ "year")}> Tag Value | true } @-}
+
+type Movies    = Table Tag Value
+
+movies :: Movies
+{-@ movies :: Movies @-}
+movies = fromList []
+
+y = "year"
diff --git a/tests/todo/DerivingRead.hs b/tests/todo/DerivingRead.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/DerivingRead.hs
@@ -0,0 +1,13 @@
+{-@ checkNat :: Nat -> Int @-} 
+checkNat :: Int -> Int 
+checkNat x = x
+
+unsound :: Int
+unsound = checkNat (-1)
+
+
+data TestBS = TestBS Int deriving (Read)
+
+-- | Possible fixes
+-- | 1. add trust-internals flag to ignore the deriving instances
+-- | 2. delete the deriving (Read) instance
diff --git a/tests/todo/DiffCheck.hs b/tests/todo/DiffCheck.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/DiffCheck.hs
@@ -0,0 +1,68 @@
+{- TODO: We need an automated test for DiffCheck. That said, our current
+   testing infrastructure isn't set up to test internals, so I'd have to
+   jimmy-rig it to work. Meanwhile, it has been decided (rightfully) that
+   the mechanism I had planned on using was an affront to all that is good,
+   and was fixed as a bug. So this test is now pointless. That said, it
+   should serve as the basis for a good test in the future, so I think we
+   should perserve it for posterity. What follows is my original plan for
+   this test.
+
+   Test diffcheck. Has been rigged with a saved diff in .liquid in the
+   following ways:
+
+   1) goodFn has changed from the saved diff.
+   2) badFn has not changed from the saved diff.
+   3) badFn has violated the invariant of badDep.
+
+   What should happen is: LH will test this file, and will test the
+   goodFn and amazingAlgorithm binders. It will see that goodDep has
+   not changed and is protected by a liquid type signature, and not
+   check it. It will see that badFn has not changed, and is protected
+   by a liquid type signature and not check it. LH will return safe,
+   having checked only goodFn and amazingAlorithm if the diff logic
+   works. If something is broken, it will check badFn and return unsafe. -}
+
+{-@ LIQUID "--diffcheck" @-}
+
+module DiffCheck where
+
+{-@ type Zero = {v:Int | v == 0} @-}
+{-@ type One = {v:Int | v == 1} @-}
+{-@ type Two = {v:Int | v == 2} @-}
+{-@ type Three = {v:Int | v == 3} @-}
+
+{-@ badFn :: Zero -> Bool @-}
+badFn :: Int -> Bool
+badFn 0 = badDep 0
+badFn _ = False
+
+{-@ goodFn :: One -> Bool @-}
+goodFn :: Int -> Bool
+goodFn 1 = goodDep 2 -- I changed!
+goodFn _ = False
+
+{-@ goodDep :: Two -> Bool @-}
+goodDep :: Int -> Bool
+goodDep 2 = True
+goodDep _ = False
+
+{-@ badDep :: Three -> Bool @-}
+badDep :: Int -> Bool
+badDep 3 = True
+badDep _ = False
+
+amazingAlgorithm :: (Bool, Bool)
+amazingAlgorithm = (goodFn 1, badFn 0)
+
+-- These guys aren't involved in the above, and should be ignored
+-- by DiffCheck
+
+{-@ innocentBystander :: One -> Bool @-}
+innocentBystander :: Int -> Bool
+innocentBystander 1 = goodSamaritan 1
+innocentBystander _ = True
+
+{-@ goodSamaritan :: One -> Bool @-}
+goodSamaritan :: Int -> Bool
+goodSamaritan 1 = True
+goodSamaritan _ = False
diff --git a/tests/todo/Eff0.hs b/tests/todo/Eff0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Eff0.hs
@@ -0,0 +1,16 @@
+-- | Trivial test for effects
+
+module Eff0 (test0) where
+
+import EffSTT
+
+
+{-@ type IntN N = {v:Int | v = N} @-}
+
+{-@ test0 :: STT (IntN {10}) @-}
+test0 :: STT Int
+test0 =
+  newPtr 0       `bind` \p  ->
+  writePtr p 10  `bind` \_  ->
+  readPtr p      `bind` \v1 ->
+  return v1
diff --git a/tests/todo/Eff1.hs b/tests/todo/Eff1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Eff1.hs
@@ -0,0 +1,22 @@
+-- | Trivial test for effects
+
+module Eff0 (test0, test1) where
+
+import EffSTT
+
+{-@ type IntN N = {v:Int | v = N} @-}
+
+{-@ test0 :: STT (IntN {10}) @-}
+test0 :: STT Int
+test0 = do p  <- newPtr 0
+           _  <- writePtr p 10
+           v1 <- readPtr p
+           return v1
+
+{-@ test1 :: STT (IntN {0}, IntN {10}) @-}
+test1 :: STT (Int, Int)
+test1 = do p  <- newPtr   0
+           v0 <- readPtr  p
+           _  <- writePtr p 10
+           v1 <- readPtr  p
+           return (v0, v1)
diff --git a/tests/todo/Eff2.hs b/tests/todo/Eff2.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Eff2.hs
@@ -0,0 +1,22 @@
+-- | Trivial test for effects
+
+module Eff0 (test0, test1) where
+
+import Data.IORef
+
+{-@ type IntN N = {v:Int | v = N} @-}
+
+{-@ test0 :: IO (IntN {0}) @-}
+test0 :: IO Int
+test0 = do p  <- newIORef   0
+           _  <- writeIORef p 10
+           v1 <- readIORef  p
+           return v1
+
+{-@ test1 :: IO (IntN {0}, IntN {10}) @-}
+test1 :: IO (Int, Int)
+test1 = do p  <- newIORef   0
+           v0 <- readIORef  p
+           _  <- writeIORef p 10
+           v1 <- readIORef  p
+           return (v0, v1)
diff --git a/tests/todo/EffSTT.hs b/tests/todo/EffSTT.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/EffSTT.hs
@@ -0,0 +1,79 @@
+module EffSTT (
+
+  -- * Basic STT type and instances
+    STT
+  , Ptr
+    
+  -- * Monadic operators
+  , ret
+  , bind
+
+  -- * Create a reference
+  , newPtr
+ 
+  -- * Read a reference
+  , readPtr
+
+  -- * Write a reference
+  , writePtr
+    
+  )where
+
+import qualified Data.Map as M
+
+type State  = M.Map Int Int
+newtype Ptr = Ptr Int
+data STT a  = STT (State -> (a, State)) 
+
+----------------------------------------------------------------
+-- | Accessing State via Ptr
+----------------------------------------------------------------
+
+{-@ newPtr :: forall <H :: HProp>.
+                 n:Int
+              -> STT <{H}, {\l -> H * l := n}> Ptr
+  @-} 
+newPtr   :: Int -> STT Ptr
+newPtr n = STT $ \m0 ->
+  let p  = M.size m0
+      m1 = M.insert p n m0
+  in
+      (Ptr p, m1)
+
+{-@ readPtr :: forall <p :: Int -> Prop, H :: HProp>.
+                  l:Ptr
+               -> STT <{H * l := Int<p>}, {\_ -> H * l := Int<p>}> Int<p>
+  @-}
+readPtr         :: Ptr -> STT Int
+readPtr (Ptr p) = STT $ \m0 ->
+  (M.findWithDefault (error "readPtr DIES") p m0, m0)
+
+
+{-@ writePtr :: forall <p :: Int -> Prop, H :: HProp>.
+                   l:Ptr
+                -> Int<p>
+                -> STT <{H * l := Int}, {\_ -> H * l := Int<p>}> () 
+  @-} 
+writePtr :: Ptr -> Int -> STT () 
+writePtr (Ptr p) n = STT $ \m0 ->
+  ((), M.insert p n m0)
+
+----------------------------------------------------------------
+-- | Monad instance for STT
+----------------------------------------------------------------
+
+instance Monad STT where
+  return = ret
+  (>>=)  = bind
+
+ret   :: a -> STT a
+ret x = STT (\s0 -> (x, s0))
+
+bind :: STT a -> (a -> STT b) -> STT b
+bind (STT f) k = STT $ \s0 ->
+  let (x, s1) = f s0
+      STT fk  = k x
+  in
+      fk s1
+
+----------------------------------------------------------------
diff --git a/tests/todo/Ensure.hs b/tests/todo/Ensure.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Ensure.hs
@@ -0,0 +1,19 @@
+module Ensure where
+
+{-@ qualif Diff(v:int,l:int,d:int): v = l-d @-}
+
+{-@ encodeUtf8 :: Nat -> Nat @-}
+encodeUtf8 :: Int -> Int
+encodeUtf8 len = start 1 0
+  where
+    start size n0 = go (len-n0) n0
+      where
+        go :: Int -> Int -> Int
+        go d n
+          | n == len  = n
+          | otherwise = ensure 1 (\n -> go (d-1) (n+1))
+              where
+                ensure :: Int -> (Int -> Int) -> Int
+                ensure k cont
+                  | size-k >= n = cont n
+                  | otherwise   = start (size*2) n
diff --git a/tests/todo/EnumFromTo.hs b/tests/todo/EnumFromTo.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/EnumFromTo.hs
@@ -0,0 +1,13 @@
+module Foo where
+
+new :: l -> [i] -> [sd] -> ([i], [(Int, sd)])
+new l wids m | not (null wids) && length m <= length wids && not (null m)
+  = (unseen, visi)
+  where (seen,unseen) = splitAt (length m) wids
+        (cur:visi)    = [ (s, sd) |  (s, sd) <- zip [0..(length m) ] m ]
+                -- now zip up visibles with their screen id
+new _ _ _ = error "non-positive argument to StackSet.new"
+
+foo :: Num a => a -> [a]
+foo = undefined
+{-@ assume foo :: Num a => x:a -> {v:[a] | (len v) = x} @-}
diff --git a/tests/todo/Equational.hs b/tests/todo/Equational.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Equational.hs
@@ -0,0 +1,35 @@
+module Equational where
+
+
+import Language.Haskell.Liquid.Prelude
+import Axiomatize
+
+
+{-@ toProof :: l:a -> r:{a | l == r} -> {v:Proof | l == r } @-}
+toProof :: a -> a -> Proof
+toProof x y = Proof
+
+
+{-@ (===) :: l:a -> r:a -> {v:Proof | l = r} -> {v:a | v = l } @-}
+(===) :: a -> a -> Proof -> a
+(===) x y _ = y
+
+
+
+{-@ type Equal X Y = {v:Proof | X == Y} @-}
+
+{-@ bound chain @-}
+chain :: (Proof -> Bool) -> (Proof -> Bool) -> (Proof -> Bool)
+      -> Proof -> Proof -> Proof -> Bool
+chain p q r = \v1 v2 v3 -> p v1 ==> q v2 ==> r v3
+
+{-@  by :: forall <p :: Proof -> Prop, q :: Proof -> Prop, r :: Proof -> Prop>.
+                 {vp::Proof<p> |- Proof<q> <: Proof<r> }
+                 Proof<p> -> Proof<q> -> Proof<r>
+@-}
+by :: Proof -> Proof -> Proof
+by _ r = r
+
+{-@ refl :: x:a -> Equal x x @-}
+refl :: a -> Proof
+refl x = Proof
diff --git a/tests/todo/FixCrash.hs b/tests/todo/FixCrash.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/FixCrash.hs
@@ -0,0 +1,12 @@
+module Interpreter where 
+
+{- The following code crashes fixpoint see issue 
+https://github.com/ucsd-progsys/liquid-fixpoint/issues/77
+-}
+
+data List a = Nil 
+
+{-@ measure progDenote :: List Int -> Maybe (List Int) @-}
+{-@ compile :: {v:Bool | (progDenote Nil) == Nothing } @-}
+compile :: Bool
+compile = undefined 
diff --git a/tests/todo/FldBug.hs b/tests/todo/FldBug.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/FldBug.hs
@@ -0,0 +1,10 @@
+module Foo where
+
+{-@ data Foo = F { thing :: Nat } @-}
+data Foo = F { thing :: Int }
+
+
+{-@ bar :: Foo -> Nat @-}
+bar z = thing z
+
+
diff --git a/tests/todo/Foo.hs b/tests/todo/Foo.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Foo.hs
@@ -0,0 +1,31 @@
+{-@ LIQUID "--short-names" @-}
+{-@ LIQUID "--no-termination" @-}
+
+module Foo where
+
+import Prelude hiding (map, reverse)
+
+
+baz :: Int
+baz = 1
+
+{-@ poo :: ListN Int 1 @-}
+poo = [baz, baz]
+
+reverse :: [a] -> [a]
+
+{-@ measure size @-}
+size :: [a] -> Int
+size []     = 0
+size (_:xs) = size xs + 1
+
+{-@ type List  a    = [a]                    @-}
+{-@ type ListN a N  = {v:[a] | size v == N } @-}
+{-@ type ListX a Xs = ListN a {size Xs}      @-}
+
+{-@ reverse :: xs:List a -> ListN a {size xs} @-}
+reverse           = go []
+  where
+    {-@ go :: acc:_ -> xs:_ -> ListN a {1 + size acc + size xs} @-}
+    go acc []     = acc
+    go acc (x:xs) = go (x:acc) xs
diff --git a/tests/todo/GhcListSort.hs b/tests/todo/GhcListSort.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/GhcListSort.hs
@@ -0,0 +1,101 @@
+
+---------------------------------------------------------------------------
+---------------------------  Official GHC Sort ----------------------------
+---------------------------------------------------------------------------
+
+sort1 = sortBy1 compare
+sortBy1 cmp = mergeAll . sequences
+  where
+    sequences (a:b:xs)
+      | a `cmp` b == GT = descending b [a]  xs
+      | otherwise       = ascending  b (a:) xs
+    sequences xs = [xs]
+
+    descending a as (b:bs)
+      | a `cmp` b == GT = descending b (a:as) bs
+    descending a as bs  = (a:as): sequences bs
+
+    ascending a as (b:bs)
+      | a `cmp` b /= GT = ascending b (\ys -> as (a:ys)) bs
+    ascending a as bs   = as [a]: sequences bs
+
+    mergeAll [x] = x
+    mergeAll xs  = mergeAll (mergePairs xs)
+
+    mergePairs (a:b:xs) = merge a b: mergePairs xs
+    mergePairs xs       = xs
+
+    merge as@(a:as') bs@(b:bs')
+      | a `cmp` b == GT = b:merge as  bs'
+      | otherwise       = a:merge as' bs
+    merge [] bs         = bs
+    merge as []         = as
+
+---------------------------------------------------------------------------
+------------------- Mergesort ---------------------------------------------
+---------------------------------------------------------------------------
+
+sort2 l = mergesort compare l
+sortBy2 cmp l = mergesort cmp l
+
+mergesort :: (a -> a -> Ordering) -> [a] -> [a]
+mergesort cmp = mergesort' cmp . map wrap
+
+mergesort' :: (a -> a -> Ordering) -> [[a]] -> [a]
+mergesort' _   [] = []
+mergesort' _   [xs] = xs
+mergesort' cmp xss = mergesort' cmp (merge_pairs cmp xss)
+
+merge_pairs :: (a -> a -> Ordering) -> [[a]] -> [[a]]
+merge_pairs _   [] = []
+merge_pairs _   [xs] = [xs]
+merge_pairs cmp (xs:ys:xss) = merge cmp xs ys : merge_pairs cmp xss
+
+merge :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
+merge _   [] ys = ys
+merge _   xs [] = xs
+merge cmp (x:xs) (y:ys)
+ = case x `cmp` y of
+        GT -> y : merge cmp (x:xs)   ys
+        _  -> x : merge cmp    xs (y:ys)
+
+wrap :: a -> [a]
+wrap x = [x]
+
+----------------------------------------------------------------------
+-------------------- QuickSort ---------------------------------------
+----------------------------------------------------------------------
+
+sort3 = qsort compare
+
+-- qsort is stable and does not concatenate.
+qsort :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
+qsort _   []     r = r
+qsort _   [x]    r = x:r
+qsort cmp (x:xs) r = qpart cmp x xs [] [] r
+
+-- qpart partitions and sorts the sublists
+qpart :: (a -> a -> Ordering) -> a -> [a] -> [a] -> [a] -> [a] -> [a]
+qpart cmp x [] rlt rge r =
+    -- rlt and rge are in reverse order and must be sorted with an
+    -- anti-stable sorting
+    rqsort cmp rlt (x:rqsort cmp rge r)
+qpart cmp x (y:ys) rlt rge r =
+    case cmp x y of
+        GT -> qpart cmp x ys (y:rlt) rge r
+        _  -> qpart cmp x ys rlt (y:rge) r
+
+-- rqsort is as qsort but anti-stable, i.e. reverses equal elements
+rqsort :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
+rqsort _   []     r = r
+rqsort _   [x]    r = x:r
+rqsort cmp (x:xs) r = rqpart cmp x xs [] [] r
+
+rqpart :: (a -> a -> Ordering) -> a -> [a] -> [a] -> [a] -> [a] -> [a]
+rqpart cmp x [] rle rgt r =
+    qsort cmp rle (x:qsort cmp rgt r)
+rqpart cmp x (y:ys) rle rgt r =
+    case cmp y x of
+        GT -> rqpart cmp x ys rle (y:rgt) r
+        _  -> rqpart cmp x ys (y:rle) rgt r
+
diff --git a/tests/todo/ImportBound.hs b/tests/todo/ImportBound.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ImportBound.hs
@@ -0,0 +1,14 @@
+module ImportBound where
+
+data Proof
+
+{-@ bound chain @-}
+chain :: (Proof -> Bool) -> (Proof -> Bool) -> (Proof -> Bool)
+      -> Proof -> Bool
+chain p q r = \v -> p v
+
+{-@  by :: forall <p :: Proof -> Prop, q :: Proof -> Prop, r :: Proof -> Prop>.
+                 (Chain p q r) => Proof<p> -> Proof<q> -> Proof<r>
+@-}
+by :: Proof -> Proof -> Proof
+by _ r = r
diff --git a/tests/todo/ImportedNumericInstances.hs b/tests/todo/ImportedNumericInstances.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ImportedNumericInstances.hs
@@ -0,0 +1,20 @@
+module ImportedNumericInstances where
+
+{- embed System.Posix.Types.Fd as int @-}
+
+import System.Posix.Types (Fd)
+-- Fd is a data type that is imported to be a num instance
+
+testToFix :: Maybe [a] -> Fd 
+testToFix =  maybe 0 (fromIntegral . getFoo)
+
+
+testOK :: Maybe [a] -> Boo 
+testOK =  maybe 0 (fromIntegral . getFoo)
+
+instance Num Boo where
+data Boo 
+
+{-@ getFoo :: {v:[a] | 0 <= len v}  -> Int @-} 
+getFoo :: [a] -> Int 
+getFoo = undefined 
diff --git a/tests/todo/Incr.hs b/tests/todo/Incr.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Incr.hs
@@ -0,0 +1,6 @@
+module Incr (incr) where 
+
+
+{-@ axiomatize incr @-}
+incr :: Int -> Int
+incr x = x + 1
diff --git a/tests/todo/InfiniteLists.hs b/tests/todo/InfiniteLists.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/InfiniteLists.hs
@@ -0,0 +1,50 @@
+module Fixme where
+
+import Prelude hiding (repeat, take, head)
+import Language.Haskell.Liquid.Prelude
+
+
+{-@ LIQUID "--no-termination" @-}
+
+{-@ measure inf :: [a] -> Prop 
+    inf([])   = false
+    inf(x:xs) = (inf xs)
+  @-}
+
+
+-- or any pred *implied* by (inf v)
+{-@ repeat :: a -> {v:[a] | (inf v)} @-}
+repeat :: a -> [a]
+repeat x = x : repeat x
+
+{-@ repeat' :: l:Int -> a -> {v:[a] | (len v) = l} @-}
+repeat' :: Int -> a -> [a]
+repeat' k x = x : repeat' (k-1) x
+
+
+{-@ take :: xs:[a] -> {v:Nat|((inf xs) || (v < (len xs))) } -> [a] @-}
+take :: [a] -> Int -> [a]
+take [] _ = liquidError "take"
+take _ 0 = []
+take (x:xs) i = x : take xs (i-1)
+
+
+{-@ head :: {v:[a] | (((len v) > 0) || (inf v)) } -> a @-}
+head :: [a] -> a
+head (x:_) = x
+head _     = liquidError "head"
+
+
+
+good1 = let x = head (repeat 0) in liquidAssert (x == 0)
+good2 = let x = head ([0, 1]) in liquidAssert (True) -- x == 0
+bad1  = let x = head (repeat 0) in liquidAssert (x == 12)
+bad2  = let x = head [] in liquidAssert (x == 12)
+
+
+foo = take (repeat 0) 5
+
+-- bar = (\x -> liquidAssert (False)) (repeat 0)
+
+
+
diff --git a/tests/todo/InlineMeasure.hs b/tests/todo/InlineMeasure.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/InlineMeasure.hs
@@ -0,0 +1,27 @@
+{-@ LIQUID "--short-names"    @-}
+
+module InlineMeasures where
+
+{-@ measure mmax @-}
+mmax       :: (Int, Int) -> Int
+mmax (x,y) = if x > y then x else y
+
+{-@ measure foo @-}
+foo        :: [Int] -> Int
+foo []     = 0
+foo (x:xs) = if (x > 0) then x else 0 
+
+{-@ measure bar @-}
+bar        :: [Int] -> Int
+bar []     = 0
+bar (x:xs) = y + z where y = x
+                         z = 10
+
+{-@ measure llen @-}
+llen        :: [a] -> Int
+llen []     = 0
+llen (x:xs) = 1 + z where z = llen xs
+
+{-@ goo :: _ -> xs:_ -> {v:_ | llen v = llen xs } @-}
+goo f []     = []
+goo f (x:xs) = f x : goo f xs 
diff --git a/tests/todo/IntInvariants.hs b/tests/todo/IntInvariants.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/IntInvariants.hs
@@ -0,0 +1,18 @@
+module Invariant where
+
+
+{-@ invariant {v : Int | v > 0 } @-}
+
+
+-- This is unsoundly safe
+
+{-@ bar :: Nat @-}
+bar :: Int
+bar = let x = -5 in x
+
+-- but this is not
+--
+{-@ foo :: Nat @-}
+foo :: Int
+foo = -5
+
diff --git a/tests/todo/Interpreter.hs b/tests/todo/Interpreter.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Interpreter.hs
@@ -0,0 +1,126 @@
+module Interpreter where 
+{-@ LIQUID "--totality" @-}
+data BinOp a = Plus | Times
+
+data Exp a  = EConst Int | EBinOp (BinOp a) (Exp a) (Exp a)
+
+data Instr a = IConst Int | IBinOp (BinOp a)
+
+data List a = Nil | Cons a (List a)
+
+
+{-@ autosize Prog @-}
+data Prog a = Emp | PInst (Instr a) (Prog a)
+type Stack = List Int
+
+data SMaybe a = SNothing a | SJust a
+
+{-@ measure binOpDenote @-}
+binOpDenote :: Int -> Int -> BinOp a -> Int 
+binOpDenote x y Plus  = (x+y)
+binOpDenote x y Times = (x*y)
+
+{-@ measure expDenote @-}
+expDenote :: Exp a -> Int 
+expDenote (EConst n)       = n
+expDenote (EBinOp b e1 e2) = binOpDenote (expDenote e1) (expDenote e2) b
+
+{-@foo :: s:Stack -> {v:SMaybe Stack| v = SNothing s || v = SJust s } @-}
+foo :: Stack -> SMaybe Stack
+foo = undefined 
+
+{-@ measure instrDenote @-}
+instrDenote :: Stack -> Instr a -> SMaybe Stack
+{-@ instrDenote :: s:Stack -> i:{v:Instr a | isIBinOp v => lenL s >= 2} 
+                -> {v:SMaybe {st:Stack | if (isIBinOp i) then (lenL st = lenL s - 1) else (lenL st = lenL s + 1)} | v = instrDenote s i} @-}
+instrDenote s (IConst n) = SJust (Cons n s)
+instrDenote s (IBinOp b) = 
+	let x  = headL s in 
+	let s1 = tailL s in 
+	let y  = headL s1 in 
+	let s2 = tailL s1 in 
+	SJust (Cons (binOpDenote x y b) s2)
+
+
+{-@ invariant {v:Prog a | binOps v >= 0} @-}
+{-@ measure binOps @-}
+binOps :: Prog a -> Int 
+binOps Emp = 0 
+binOps (PInst x xs) = if isIBinOp x then 1 + (binOps xs) else binOps xs 
+
+
+
+{- measure progDenote :: Stack -> Prog -> SMaybe Stack @-}
+{-@ measure progDenote @-}
+{-@ Decrease progDenote 2 @-}
+progDenote :: Stack -> Prog a -> SMaybe Stack
+{-@ progDenote :: s:Stack -> p:{v:Prog a | lenL s >= 2 * binOps v }  -> {v: SMaybe Stack | v = progDenote s p} @-}
+progDenote s Emp = SJust s
+progDenote s (PInst x xs) = SNothing s 
+{-
+progDenote s (PInst x xs) | SJust s' <- instrDenote s x = progDenote s' xs
+                          | otherwise                   = SNothing s
+-}
+
+{-
+{- compile :: e:Exp -> {v:Prog | (progDenote Nil v) == Nothing } @-}
+{- compile :: e:Exp -> {v:Prog | (progDenote Nil v) == Just (Cons (expDenote e) Nil)} @-}
+compile :: Exp -> Prog
+compile (EConst n)       = single (IConst n)  
+compile (EBinOp b e1 e2) = compile e2 `append` compile e1 `append` (single $ IBinOp b) 
+
+-}
+
+
+
+-- Hard Wire the measures so that I can provide exact types for Nil and Cons
+{-@ SNothing :: s:s -> {v:SMaybe s | v = SNothing s && not (isSJust v)} @-}
+{-@ SJust    :: s:s -> {v:SMaybe s | v = SJust s && (isSJust v) && (fromSJust v = s)} @-}
+{-@ Cons     :: x:a -> xs:List a -> {v:List a | v = Cons x xs && headL v = x && tailL v = xs && lenL v = 1 + lenL xs} @-}
+{-@ Nil      :: {v:List a | v = Nil  && lenL v = 0} @-}
+iconst = IConst
+
+
+{-@ measure isSJust :: SMaybe a -> Prop @-}
+{-@ isSJust :: x:SMaybe a -> {v:Bool | Prop v <=> isSJust x}  @-}
+isSJust (SJust _) = True 
+isSJust (SNothing _ ) = False
+
+{-@ measure fromSJust :: SMaybe a -> a @-}
+{-@ fromSJust :: x:{v:SMaybe a | isSJust v} -> {v:a | v = fromSJust x}  @-}
+fromSJust (SJust x) = x
+
+{-@ measure isIBinOp @-}
+isIBinOp (IBinOp _) = True
+isIBinOp _          = False
+
+{-@ measure headL :: List a -> a @-}
+{-@ headL :: xs:{v:List a | lenL v > 0} -> {v:a | v = headL xs} @-}
+headL :: List a -> a
+headL (Cons x _) = x
+
+{-@ measure tailL :: List a -> List a @-}
+{-@ tailL :: xs:{v:List a | lenL v > 0} -> {v: List a | v = tailL xs && lenL v = lenL xs - 1} @-}
+tailL :: List a -> List a
+tailL (Cons _ xs) = xs
+
+
+{-@ measure lenL :: List a -> Int @-}
+{-@ invariant {v:List a | lenL v >= 0 } @-}
+lenL :: List a -> Int 
+lenL (Cons _ xs) = 1 + lenL xs 
+lenL Nil         = 0 
+
+
+
+-- List operations
+{-@ autosize Exp @-}
+{-@ data List [lenL] @-}
+
+(Cons x xs) `append` ys = cons x $ append xs ys
+Nil         `append` ys = ys 
+
+emp      = Nil
+single x = Cons x Nil
+cons x xs = Cons x xs
+
diff --git a/tests/todo/InvBug.hs b/tests/todo/InvBug.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/InvBug.hs
@@ -0,0 +1,27 @@
+module Isort () where
+
+data F = F 
+
+{-@ measure lenF @-}
+lenF :: F -> Int
+lenF F = 0
+
+
+{- some interaction needed to check the def of lenF satisfies the invariant! -}
+
+{-@ using (F) as  {v: F | (lenF v > 0)} @-}
+
+{-
+
+Mt has type 
+
+  {v:F | lenF v == 0  }  -- from measure 
+  {v:F | lenF v > 0}  -- from invariant
+
+which is inconsistent !
+-}
+
+{-@ insert :: F -> {v: F |  false }  @-}
+insert :: F -> F
+insert F = F
+
diff --git a/tests/todo/Invariants.hs b/tests/todo/Invariants.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Invariants.hs
@@ -0,0 +1,16 @@
+module Invariant where
+
+data F a = F {fx :: a, fy :: a, fzz :: a} 
+         | G {fx :: a, fy :: a}
+
+{-@ data F a = F {fx :: a, fy :: a, fz :: a}
+             | G {fx :: a, fy :: a} 
+  @-}
+
+{-@ invariant {v : F a | (fy v) = (fx v) } @-}
+
+-- F :: x:a -> y:a -> z:a -> { prove this } -> F a
+
+
+bar :: a -> F a -> F a
+bar _ f@(F x y z) = f{fx = y}
diff --git a/tests/todo/Invariants1.hs b/tests/todo/Invariants1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Invariants1.hs
@@ -0,0 +1,13 @@
+module Foo where
+
+{-@ invariant {v:[Nat] | (sum v) >= 0} @-}
+
+{-@ measure sum :: [Int] -> Int
+    sum([]) = 0
+    sum(x:xs) = x + (sum xs)
+  @-}
+
+{-@ bad :: [Int] -> {v:[Nat] | (sum v) >= 0} @-}
+bad :: [Int] -> [Int]
+bad x = x
+
diff --git a/tests/todo/Invariants2.hs b/tests/todo/Invariants2.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Invariants2.hs
@@ -0,0 +1,11 @@
+module Invariants where
+
+{-@ measure sum :: [Int] -> Nat
+    sum()     = 0
+    sum(x:xs) = x + (sum xs)
+  @-}
+
+
+{-@ good :: xs:[Int] -> {v:[Int] | (sum xs) >= 0} @-}
+good :: [Int] -> [Int]
+good x = x
diff --git a/tests/todo/InvariantsTermination.hs b/tests/todo/InvariantsTermination.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/InvariantsTermination.hs
@@ -0,0 +1,52 @@
+module InvariantsTermination where
+
+
+data Inv  
+  = InvZero
+  |	InvOne Inv 
+  | InvTwo Inv Inv 
+
+{-@ data Inv [isize] @-}
+
+{-@ measure isize @-}
+{-@ isize :: Inv -> Nat @-}
+isize :: Inv -> Int
+isize d = 
+  case d of 
+  	InvZero      -> 0  
+  	InvOne i     -> 1 + isize i 
+  	InvTwo i1 i2 -> let s1 = isize i1 
+  	                    s2 = isize i2 
+  	                in 1 + s1 + s2  
+
+{-
+to prove both the invariant 
+
+   {v:Inv | invariant v }
+
+  invariant v <=> 0 <= isize v 
+
+and termination on isize 
+the environment is extended with 
+ 
+   forall v. 
+      isize v < isize d => invariant v  
+   
+This is not good enought to prove the InvTwo case: 
+
+  isize i1 < isize d => 0 <= isize i1  
+  isize i2 < isize d => 0 <= isize i2 
+  isize d = isize i1 + isize i2
+  ------------------------------
+  0 <= isize i1 < isize d 
+
+
+
+  isize i1 < 1 + isize i1 + isize i2 => 0 <= isize i1  
+  isize i2 < 1 + isize i1 + isize i2 => 0 <= isize i2 
+  ------------------------------
+    0 <  1+ isize i1 
+
+
+
+-}
diff --git a/tests/todo/LambdaDeBruijn.hs b/tests/todo/LambdaDeBruijn.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LambdaDeBruijn.hs
@@ -0,0 +1,16 @@
+module LambdaDeBruijn where
+
+{-@ LIQUID "--native" @-}
+type Var = Int
+data Typ
+data Expr = EVar Var
+          | ELam Typ Expr
+          | EUnit
+          | EApp Expr Expr
+
+{-@ autosize Expr @-}
+
+{-@measure isVar @-}
+isVar :: Expr -> Bool
+isVar (EVar _) = True
+isVar _        = False
diff --git a/tests/todo/LambdaDeBruijn0.hs b/tests/todo/LambdaDeBruijn0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LambdaDeBruijn0.hs
@@ -0,0 +1,81 @@
+module LambdaDeBruijn where
+
+{- Proving Termination of Parallel Substitutions,
+   see  § 3.2.2 of Dependent Types and Multi Monadic Effects in F*
+ -}
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ LIQUID "--native"   @-}
+{-@ LIQUID "--totality" @-}
+
+type Var = Int
+{-@ type EVar = {v:Expr| isEVar v} @-}
+
+type Subst = [(Var,Expr)]
+{-@ type RenamingSubst = {su: [(Var,Expr)] | isRenaming su} @-}
+
+data Typ
+
+data Expr = EVar Var
+          | ELam Typ Expr
+          | EUnit
+          | EApp Expr Expr
+{-@ data Expr [elen] @-}
+
+{-@ type MEVar E SU = {e:Expr | if (isEVar E && isRenaming SU) then (isEVar e) else true } @-}
+
+{-@ sub :: su:Subst -> v:Var -> {v:Expr | if (isRenaming su) then (isEVar v) else true } @-}
+sub [] v                       = EVar v
+sub ((vx, x):su) v | v == vx   = x
+                   | otherwise = sub su v
+
+
+{-@ subst :: e:Expr -> su:Subst -> MEVar e su / [if (isEVar e) then 0 else 1, if (isRenaming su) then 0 else 1, elen e] @-}
+subst EUnit        su = EUnit
+subst (EVar v)     su = sub su v
+subst (EApp e1 e2) su = EApp (subst e1 su) (subst e2 su)
+
+subst (ELam t e)   su | isRenaming su =
+  let su' =  toRem $ (0, EVar 0): map (\i -> (i, subst (sub su (i-1)) $ incrsubst ())) [1..]
+  in ELam t $ subst e su'
+
+subst (ELam t e)   su = -- | not $ isRenaming su
+    let su' =  (0, EVar 0): map (\i -> (i, subst (sub su (i-1)) $ incrsubst ())) [1..]
+    in ELam t $ subst e su'
+
+
+
+
+{-@ incrsubst :: () -> RenamingSubst @-}
+incrsubst :: () -> Subst
+incrsubst _ = toRem $  map (\i -> (i, EVar $ i+1)) [0..]
+
+{-@ measure isEVar @-}
+isEVar :: Expr -> Bool
+isEVar (EVar _) = True
+isEVar _        = False
+
+
+
+toRem :: Subst -> Subst
+{-@ toRem :: [(Var, EVar)] -> RenamingSubst @-}
+toRem [] = []
+toRem ((x, y):sus) = (x, y):toRem sus
+
+
+{-@ measure isRenaming @-}
+isRenaming :: Subst -> Bool
+isRenaming (vx:sus) = isEVar (mysnd vx) && isRenaming sus
+isRenaming [] = True
+
+{-@ measure mysnd @-}
+mysnd (_,y) = y
+
+{-@ invariant {v:Expr | elen v >= 0 } @-}
+{-@ measure elen @-}
+elen :: Expr -> Int
+elen EUnit    = 0
+elen (EVar v) = 0
+elen (ELam _ e) = 1 + elen e
+elen (EApp e1 e2) = 1 + elen e1 + elen e2
diff --git a/tests/todo/LazyVar.hs b/tests/todo/LazyVar.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LazyVar.hs
@@ -0,0 +1,15 @@
+module LazyVar where
+
+{-@ foo :: a -> Bool @-}
+foo :: a -> Bool
+foo = undefined
+
+{-@ bar :: [a] -> Nat -> a @-}
+bar :: [a] -> Int -> a
+bar xs i
+  | i < l && foo x = x
+  | otherwise      = undefined
+  where
+    l = length xs
+    {-@ LAZYVAR x @-}
+    x = xs !! i
diff --git a/tests/todo/ListDataCons-Neg.hs b/tests/todo/ListDataCons-Neg.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ListDataCons-Neg.hs
@@ -0,0 +1,16 @@
+module Fixme where
+
+data L a = N 
+
+
+{-@ lnil :: {v:L a | v == Fixme.N } @-} 
+lnil :: L a 
+lnil = N
+
+{-@ hnil :: {v:[Int] | v == []} @-} 
+hnil :: [Int] 
+hnil = [0] 
+
+{-@ hcons :: x:a -> a -> xs:[a] -> {v:[a] | v == x:xs} @-} 
+hcons :: a -> a -> [a] -> [a] 
+hcons _ = (:)
diff --git a/tests/todo/ListDataCons-Pos.hs b/tests/todo/ListDataCons-Pos.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ListDataCons-Pos.hs
@@ -0,0 +1,16 @@
+module Fixme where
+
+data L a = N 
+
+
+{-@ lnil :: {v:L a | v == Fixme.N } @-} 
+lnil :: L a 
+lnil = N
+
+{-@ hnil :: {v:[a] | v == []} @-} 
+hnil :: [a] 
+hnil = [] 
+
+{-@ hcons :: x:a -> xs:[a] -> {v:[a] | v == x:xs} @-} 
+hcons :: a -> [a] -> [a] 
+hcons = (:)
diff --git a/tests/todo/ListDataCons.hs b/tests/todo/ListDataCons.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ListDataCons.hs
@@ -0,0 +1,24 @@
+module Fixme where
+
+
+{-@ hsig :: x:a -> {v:[a] | v == (x:[])} @-} 
+hsig :: a -> [a] 
+hsig x = [x] 
+
+
+{-
+
+This crashes with 
+
+(VV#F1 = fix#GHC.Types.#58##35#64([x#aJP; fix#GHC.Types.#91##93##35#6m([])]))
+
+z3Pred: error converting (VV#F1 = fix#GHC.Types.#58##35#64([x#aJP; fix#GHC.Types.#91##93##35#6m([])]))
+Fatal error: exception Failure("bracket hits exn: TpGen.MakeProver(SMT).Z3RelTypeError
+")
+
+Unless these edits
+
+https://github.com/ucsd-progsys/liquid-fixpoint/commit/63e1e1ccfbde4d7a26bd3e328ad111423172a7e9
+
+
+-}
diff --git a/tests/todo/ListMem.hs b/tests/todo/ListMem.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ListMem.hs
@@ -0,0 +1,79 @@
+module ListMem where
+
+
+import Data.Set hiding (partition)
+
+
+{-@ member' :: Eq a 
+           => x:a 
+           -> xs:[a] 
+           -> {v:([{vv:a|vv=x}], [{vv:a|vv!=x}]) | (PairEqElts xs v)}
+  @-}
+member' :: Eq a => a -> [a] -> ([a], [a])
+member' x ls = partition (cmp x) ls 
+
+{-@ member :: Eq a 
+           => x:a 
+           -> xs:[a] 
+           -> {v:Bool|((Prop v) <=> (ListElt x xs))}
+  @-}
+member :: Eq a => a -> [a] -> Bool
+member x ls 
+  = case partition (cmp x) ls of
+     ([], _) -> False -- can not prove this!
+     (_, _)  -> True
+
+{-@ predicate ListElt N LS =
+       (Set_mem N (listElts LS)) 
+  @-}
+
+{-@ predicate PairEqElts X P =
+ ((listElts X) = (Set_cup (listElts (getFst P)) (listElts (getSnd P))))
+  @-}
+
+{-@ predicate UnionElts X Y Z W =
+       ((listElts X) = (Set_cup (listElts Y) (Set_cup (listElts Z) (listElts W)))) 
+  @-}
+
+{-@ measure getFst :: (a, b) -> a
+    getFst(a, b) = a 
+  @-}
+
+{-@ measure getSnd :: (a, b) -> b
+    getSnd(a, b) = b
+  @-}
+
+
+{-@ cmp :: Eq a 
+        => x:a 
+        -> y:a 
+        -> Either {v:a| ((v = y) && (v = x))} 
+                  {v:a| ((v != x) && (v = y))} 
+  @-}
+cmp :: Eq a => a -> a ->  Either a a
+cmp x y | x == y    = Left  y
+        | otherwise = Right y
+
+
+{-@ partition :: forall <p :: a -> Prop, q :: a -> Prop>.
+                 (x:a -> Either {v:a<p>|v = x} {v:a<q>|v=x})
+              -> xs:[a] 
+              -> {v:([a<p>], [a<q>]) | (PairEqElts xs v) }
+  @-}
+partition :: (a -> Either a a) -> [a] -> ([a], [a])
+partition f xs = partition' f xs xs ([], [])
+
+{-@ partition' :: forall <p :: a -> Prop, q :: a -> Prop>.
+                 (x:a -> Either {v:a<p>|v = x} {v:a<q>|v=x})
+              -> init:[a] 
+              -> xs:[a] 
+              -> ack:{v:([a<p>], [a<q>]) | ((listElts init) = (Set_cup (listElts xs) (Set_cup (listElts (getFst v)) (listElts (getSnd v))))) }
+              -> {v:([a<p>], [a<q>]) | (listElts init) = (Set_cup (listElts (getFst v)) (listElts (getSnd v)))}
+  @-}
+partition' :: (a -> Either a a) -> [a] -> [a] -> ([a], [a]) -> ([a], [a])
+partition' _ a [] (x, y) = (x, y)
+partition' f a (x:xs) (pos, neg) 
+  = case f x of
+    Left _  -> partition' f a xs (x:pos, neg) 
+    Right _ -> partition' f a xs (pos, x:neg) 
+
diff --git a/tests/todo/LocalRecursiveFuns.hs b/tests/todo/LocalRecursiveFuns.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LocalRecursiveFuns.hs
@@ -0,0 +1,37 @@
+module Blank where
+
+data Tree a = Tip | Node a (Tree a) (Tree a)
+
+tmap                :: (a -> b) -> Tree a -> Tree b
+tmap f Tip          = Tip
+tmap f (Node x l r) = Node (f x) (tmap f l) (tmap f r)
+
+-----------------------------------------------------------
+{-@ union :: t1:(Tree a) -> t2:(Tree a) -> (Tree a) /[(sz t1) + (sz t2)] @-}
+-- union :: Tree a -> Tree a -> Tree a
+union Tip          t = t
+union (Node x a b) t = Node x taa tbb
+  where
+    taa              = union ta a
+    tbb              = union tb b
+    (ta,  tb)        = split x t
+
+-----------------------------------------------------------
+
+{-@ split :: a -> t:Tree a -> (TreeLe a t, TreeLe a t) @-}
+split :: a -> Tree a -> (Tree a, Tree a)
+split = undefined
+
+{-@ type TreeLe a T = {v:Tree a | (sz v) <= (sz T)} @-}
+
+{-@ data Tree [sz]  @-}
+
+{-@ measure sz      :: Tree a -> Int
+    sz (Tip)        = 0
+    sz (Node x l r) = 1 + (sz l) + (sz r)
+  @-}
+  
+{-@ invariant {v:(Tree a) | (sz v) >= 0} @-}
+
+{-@ qualif TreeLt(v:Tree a, t:Tree b): (sz v) < (sz t) @-}
+
diff --git a/tests/todo/LocalSpec.hs b/tests/todo/LocalSpec.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LocalSpec.hs
@@ -0,0 +1,17 @@
+module LocalSpec () where
+
+import Language.Haskell.Liquid.Prelude (choose)
+
+
+prop = if x > 0 then bar x else foo x
+  where x = choose 0
+    {-@ Local bar :: Nat -> Nat @-}
+        bar :: Int -> Int
+        bar x = x
+    {-@ Local foo :: Nat -> Nat @-}
+        foo :: Int -> Int
+        foo x = x
+
+{-@ bar :: a -> {v:Int | v = 9} @-}
+bar :: a -> Int
+bar _ = 9
diff --git a/tests/todo/LocalSpec1.hs b/tests/todo/LocalSpec1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LocalSpec1.hs
@@ -0,0 +1,14 @@
+module Foo where
+
+{-@ filterElts :: forall <p :: a -> Prop>. Eq a => [a<p>] -> [a] -> [a<p>] @-}
+filterElts :: Eq a => [a] -> [a] -> [a]
+filterElts xs ys = go xs xs ys
+
+
+{-@ go :: forall <p :: a -> Prop>. Eq a => xs:[a<p>] -> ws:[a<p>] -> zs:[a] -> [a<p>] /[(len zs), (len ws)] @-}
+go :: Eq a => [a] -> [a] -> [a] -> [a]
+go xs (w:ws) (z:zs) | w == z    = z : go xs xs zs
+                    | otherwise = go xs ws (z:zs)
+go xs []     (z:zs)             = go xs xs zs
+go xs ws     []                 = []
+
diff --git a/tests/todo/LocalSpecImport.hs b/tests/todo/LocalSpecImport.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LocalSpecImport.hs
@@ -0,0 +1,7 @@
+module LocalSpecImport where
+
+import LocalSpec
+
+{-@ baz :: Nat -> Nat @-}
+baz :: Int -> Int
+baz x = x
diff --git a/tests/todo/LocalSpecTyVar.hs b/tests/todo/LocalSpecTyVar.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LocalSpecTyVar.hs
@@ -0,0 +1,7 @@
+module LocalSpecTyVar where
+
+foo = go
+  where
+    {-@ go :: xs:[a] -> {v:[a] | (len v) > (len xs)} @-}
+    go []     = []
+    go (x:xs) = x : go xs
diff --git a/tests/todo/LocalTermExpr1.hs b/tests/todo/LocalTermExpr1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/LocalTermExpr1.hs
@@ -0,0 +1,20 @@
+module LocalTermExpr where
+
+{-@ assume (!!) :: xs:[a] -> {v:Nat | v < len xs} -> a @-}
+
+mysum xs = go 0 0
+  where
+    i = 0
+    n = length xs
+    {-@ go :: i:_ -> _ -> _ / [len xs - i] @-}
+    go i acc
+      | i >= n    = acc
+      | otherwise = go (i+1) (acc + xs !! i)
+
+myfoo = foo 5 True
+  where
+    n = False
+    {-@ foo :: n:_ -> b:{_ | n >= 0 && Prop b} -> {v:_ | n >= 0 && (Prop b)} / [n-0] @-}
+    foo :: Int -> Bool -> Bool
+    foo 0 _ = True
+    foo n b = foo (n-1) b
diff --git a/tests/todo/Machine.hs b/tests/todo/Machine.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Machine.hs
@@ -0,0 +1,145 @@
+{-# LANGUAGE LambdaCase, DeriveDataTypeable, OverloadedStrings, GeneralizedNewtypeDeriving #-}
+
+{-@ LIQUID "--no-case-expand" @-}
+{-@ LIQUID "--trustinternals" @-}
+
+import qualified Data.Map as Map
+import qualified Data.Generics as SYB
+import Data.String
+import Text.PrettyPrint
+
+-- Syntax
+
+newtype Var = Var String
+  deriving (Eq, Ord, Show, SYB.Data, SYB.Typeable, IsString)
+
+newtype Con = Con String
+  deriving (Eq, Ord, Show, SYB.Data, SYB.Typeable, IsString)
+
+type Alts = [(Con, [Var], Expr)]
+
+data Expr
+  = EVar Var
+  | ELam Var Expr
+  | EApp Expr Var
+  | ELet [(Var, Expr)] Expr
+  | ECon Con [Var]
+  | ECase Expr Alts
+  deriving (Eq, Ord, Show, SYB.Data, SYB.Typeable)
+
+instance IsString Expr where
+  fromString = EVar . fromString
+
+isValue :: Expr -> Bool
+isValue = \case
+  ELam {} -> True
+  ECon {} -> True
+  _ -> False
+
+-- Abstract machine
+type Heap = Map.Map Var Expr
+type Stack = [StackItem]
+data StackItem
+  = StackUpdate Var
+  | StackVar Var
+  | StackAlts Alts
+  deriving (Show, SYB.Data, SYB.Typeable)
+data Machine = Machine Heap Expr Stack
+  deriving (Show)
+
+step :: Machine -> Machine
+step (Machine heap e stack)
+  -- Lookup
+  | EVar x <- e =
+      let m = heap Map.! x
+      in Machine heap m (StackUpdate x : stack)
+  -- Update
+  | isValue e, StackUpdate v : stack' <- stack =
+      Machine (Map.insert v e heap) e stack'
+  -- Unwind
+  | EApp m x <- e = Machine heap m (StackVar x : stack)
+  -- Subst
+  | ELam x m <- e, StackVar y : stack' <- stack =
+      Machine heap (subst (Map.singleton x y) e) stack'
+  -- Case
+  | ECase m alts <- e = Machine heap m (StackAlts alts : stack)
+  -- Branch
+  | ECon con xs <- e, StackAlts alts : stack' <- stack =
+      let [(boundVars, body)] = [(boundVars, body) | (con', boundVars, body) <- alts, con == con']
+          e' = subst (Map.fromList $ zip boundVars xs) body
+      in Machine heap e' stack'
+  -- Letrec
+  | ELet binds body <- e = Machine (Map.union (Map.fromList binds) heap) body stack
+
+
+-- Example refinements on Map.Map
+{-@ measure mlen :: Map.Map a b -> Int @-}
+{-@ invariant {v:Map.Map k v | (mlen v >= 0) } @-}
+{-@ assume Map.delete :: Ord k => x:k -> m:Map.Map k v -> {v:Map.Map k v |(melem x m) =>  mlen v < mlen m} @-}
+
+{-@ measure melem :: k -> Map.Map k v -> Prop @-}
+-- 
+
+-- Sizing Expressions:
+-- TODO: define elen for the rest of the cases 
+
+{-@ invariant {v:Expr | elen v > 0} @-}
+{-@ measure elen :: Expr -> Int 
+    elen (ELam x e)   = 1 + (elen e)
+  @-}
+
+{-@ subst :: (Map.Map Var Var) -> e:Expr -> Expr / [elen e]  @-}
+subst :: Map.Map Var Var -> Expr -> Expr
+subst sm = \case
+  EVar x | Just y <- Map.lookup x sm -> EVar y
+  e@(ELam z body) -> ELam z (subst (Map.delete z sm) body)
+  e -> SYB.gmapT (SYB.mkT $ subst sm) e
+
+initMachine :: Expr -> Machine
+initMachine e = Machine Map.empty e []
+
+isFinished :: Machine -> Bool
+isFinished (Machine _ e stack) = isValue e && null stack
+
+run :: Machine -> Machine
+run m
+  | isFinished m = m
+  | otherwise = run $ step m
+
+-- Pretty-printing
+ppVar (Var x) = text x
+ppCon (Con x) = text x
+ppExpr :: Expr -> Doc
+ppExpr = ppExpr' False
+ppExpr' :: Bool -> Expr -> Doc
+ppExpr' p e =
+  let maybeParens = if p then parens else id in
+  case e of
+    EVar x -> ppVar x
+    ELam x body -> maybeParens $
+      text "Î»" <> ppVar x <> text "." <> ppExpr' False body
+    EApp a b -> ppExpr' False a <+> ppVar b
+    ECon con xs -> sep $ ppCon con : map ppVar xs
+    ELet binds body ->
+      vcat
+        [ "let" $$ nest 2 (vcat (punctuate semi (map (\(v,e) -> ppVar v <+> hang "=" 2 (ppExpr e)) binds)))
+        , "in" $$ nest 2 (ppExpr body)
+        ]
+    ECase e alts ->
+      let ppAlt (con, vars, body) =
+            ppCon con <+> sep (map ppVar vars) <+> "->" <+> ppExpr body
+      in text "case" <+> ppExpr e <+> "of" $$ nest 2 (vcat (map ppAlt alts))
+
+-- Some object-language programs
+nil, cons :: Expr
+nil = ECon "nil" []
+cons = ELam "x" $ ELam "y" $ ECon "cons" ["x", "y"]
+append = ELet [("append", appendBind)] "append"
+  where
+    appendBind =
+      ELam "a" $ ELam "b" $ ECase "a"
+        [("nil", [], "b")
+        ,("cons", ["x", "xs"],
+          ELet [("r", "append" `EApp` "xs" `EApp` "b")]
+            (cons `EApp` "x" `EApp` "r"))
+        ]
diff --git a/tests/todo/Map-strict.hs b/tests/todo/Map-strict.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Map-strict.hs
@@ -0,0 +1,25 @@
+module Data.Map.Base (Map(..), singleton) where
+
+data Map k a  = Bin {-# UNPACK #-} !Size !k a !(Map k a) !(Map k a)
+              | Tip
+
+type Size     = Int
+
+{-@ 
+  data Map k a <l :: root:k -> k -> Bool, r :: root:k -> k -> Bool>
+       = Bin (sz    :: Size) 
+             (key   :: k) 
+             (value :: a) 
+             (left  :: Map <l, r> (k <l key>) a) 
+             (right :: Map <l, r> (k <r key>) a) 
+       | Tip 
+  @-}
+
+{-@ type OMap k a = Map <{v:k | v < root}, {v:k | v > root}> k a @-}
+
+{-@ singleton :: k -> a -> OMap k a @-}
+singleton :: k -> a -> Map k a
+singleton k x = Bin 1 k x Tip Tip
+{-# INLINE singleton #-}
+
+
diff --git a/tests/todo/Map-wierd.hs b/tests/todo/Map-wierd.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Map-wierd.hs
@@ -0,0 +1,171 @@
+module Map where
+
+import Language.Haskell.Liquid.Prelude
+
+-- LIQUID: There is some bizarre interaction between the names in Map-pred
+-- and Pair-pred -- because the error goes away if you remove "Pair"
+-- altogether from the code.
+
+{-@ 
+  data Map k a <l :: x00:k -> x1:k -> Bool, r :: x00:k -> x1:k -> Bool>
+      = Tip 
+      | Bin (sz    :: Size) 
+            (key   :: k) 
+            (value :: a) 
+            (left  :: Map <l, r> (k <l key>) a) 
+            (right :: Map <l, r> (k <r key>) a) 
+  @-}
+
+{-@ type OMap k a = Map <{v:k | v < x00 }, {v:k | v > x00}> k a @-}
+
+data Map k a = Tip
+             | Bin Size k a (Map k a) (Map k a)
+
+type Size    = Int
+{-@
+data Pair k v <p :: x0:k -> x1:k -> Bool, l :: x0:k -> x1:k -> Bool, r :: x0:k -> x1:k -> Bool>
+  = P (fld0 :: k) (fld1 :: v) (tree :: Map <l, r> (k <p fld0>) v) 
+  @-}
+data Pair k v = P k v (Map k v)
+
+{-@ singleton :: k -> a -> OMap k a @-}
+singleton :: k -> a -> Map k a
+singleton k x
+  = Bin 1 k x Tip Tip
+
+{-@ insert :: Ord k => k -> a -> OMap k a -> OMap k a @-}
+insert :: Ord k => k -> a -> Map k a -> Map k a
+insert kx x t
+  = case t of 
+     Tip -> singleton kx x
+     Bin sz ky y l r
+         -> case compare kx ky of
+              LT -> balance ky y (insert kx x l) r
+              GT -> balance ky y l (insert kx x r)
+              EQ -> Bin sz kx x l r
+
+{-@ delete :: (Ord k) => k -> OMap k a -> OMap k a @-}
+delete :: Ord k => k -> Map k a -> Map k a
+delete k t 
+  = case t of 
+      Tip -> Tip
+      Bin _ kx x l r
+          -> case compare k kx of 
+               LT -> balance kx x (delete k l) r
+               GT -> balance kx x l (delete k r)
+               EQ -> glue kx l r 
+
+
+glue :: k -> Map k a -> Map k a -> Map k a
+glue k Tip r = r
+glue k l Tip = l
+glue k l r
+  | size l > size r = let P km1 vm lm = deleteFindMax l in balance km1 vm lm r
+  | otherwise       = let P km2 vm rm = deleteFindMin r in balance km2 vm l rm
+
+deleteFindMax :: Map k a -> Pair k a
+deleteFindMax t 
+  = case t of
+      Bin _ k x l Tip -> P k x l
+      Bin _ k x l r -> let P km3 vm rm = deleteFindMax r in P km3 vm (balance k x l rm) 
+      Tip             -> P (error ms) (error ms) Tip
+  where ms = "Map.deleteFindMax : can not return the maximal element of an empty Map"   
+
+
+deleteFindMin :: Map k a -> Pair k a
+deleteFindMin t 
+  = case t of
+      Bin _ k x Tip r -> P k x r
+      Bin _ k x l r -> let P km4 vm lm = deleteFindMin l in P km4 vm (balance k x lm r) 
+      Tip             -> P (error ms) (error ms) Tip
+  where ms = "Map.deleteFindMin : can not return the maximal element of an empty Map"   
+
+
+-------------------------------------------------------------------------------
+--------------------------------- BALANCE -------------------------------------
+-------------------------------------------------------------------------------
+
+delta, ratio :: Int
+delta = 5
+ratio = 2
+
+balance :: k -> a -> Map k a -> Map k a -> Map k a 
+balance k x l r 
+  | sizeL + sizeR <= 1   = Bin sizeX k x l r
+  | sizeR >= delta*sizeL = rotateL k x l r
+  | sizeL >= delta*sizeR = rotateR k x l r
+  | otherwise            = Bin sizeX k x l r
+  where sizeL = size l
+        sizeR = size r
+        sizeX = sizeL + sizeR + 1
+
+-- rotate
+rotateL :: a -> b -> Map a b -> Map a b -> Map a b
+rotateL k x l r@(Bin _ _ _ ly ry) 
+  | size ly < ratio*size ry  = singleL k x l r
+  | otherwise                = doubleL k x l r
+rotateL _ _ _ Tip = error "rotateL Tip"
+
+rotateR :: a -> b -> Map a b -> Map a b -> Map a b
+rotateR k x l@(Bin _ _ _ ly ry) r
+  | size ry < ratio*size ly  = singleR k x l r
+  | otherwise                = doubleR k x l r
+rotateR _ _ _ Tip = error "rotateR Tip"
+
+-- basic rotations
+singleL, singleR :: a -> b -> Map a b -> Map a b -> Map a b
+singleL k1 x1 t1 (Bin _ k2 x2 t2 t3) = bin k2 x2 (bin k1 x1 t1 t2) t3
+singleL _  _  _ Tip = error "sinlgeL Tip"
+singleR k1 x1 (Bin _ k2 x2 t1 t2) t3 = Bin 0 k2 x2 t1 (Bin 0 k1 x1 t2 t3)
+singleR _  _  _ Tip = error "sinlgeR Tip"
+
+doubleL, doubleR :: a -> b -> Map a b -> Map a b -> Map a b
+doubleL k1 x1 t1 (Bin _ k2 x2 (Bin _ k3 x3 t2 t3) t4)
+ =bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4)
+doubleL _ _ _ _ = error "doubleL" 
+doubleR k1 x1 (Bin _ k2 x2 t1 (Bin _ k3 x3 t2 t3)) t4 
+  = bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4)
+doubleR _ _ _ _ = error "doubleR" 
+
+bin :: k -> a -> Map k a -> Map k a -> Map k a
+bin k x l r 
+  = Bin (size l + size r + 1) k x l r
+
+size :: Map k a -> Int
+size t 
+  = case t of 
+      Tip            -> 0
+      Bin sz _ _ _ _ -> sz
+
+
+chkDel x Tip                = liquidAssertB True  
+chkDel x (Bin sz k v lt rt) = liquidAssertB (not (x == k)) && chkDel x lt && chkDel x rt
+
+chkMin x Tip                = liquidAssertB True  
+chkMin x (Bin sz k v lt rt) = liquidAssertB (x<k) && chkMin x lt && chkMin x rt
+
+chk Tip               = liquidAssertB True  
+chk (Bin s k v lt rt) = chk lt && chk rt && chkl k lt && chkr k rt
+		
+chkl k Tip              = liquidAssertB True
+chkl k (Bin _ kl _ _ _) = liquidAssertB (kl < k)
+
+chkr k Tip              = liquidAssertB True
+chkr k (Bin _ kr _ _ _) = liquidAssertB (k < kr)
+
+key, key1, val, val1 :: Int
+key = choose 0
+val = choose 1
+key1 = choose 0
+val1 = choose 1
+
+bst1 = insert key val Tip
+bst  = insert key val $ insert key1 val1 Tip
+
+mkBst = foldl (\t (k, v) -> insert k v t) Tip
+
+prop        = chk bst1
+prop1       = chk $ mkBst $ zip [1..] [1..]
+
+propDelete  = chk $ delete x bst
+   where x = choose 0
diff --git a/tests/todo/MaybeReflect0.hs b/tests/todo/MaybeReflect0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/MaybeReflect0.hs
@@ -0,0 +1,28 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+
+
+{-# LANGUAGE IncoherentInstances   #-}
+{-# LANGUAGE FlexibleContexts #-}
+module MaybeReflect0 where
+
+
+import Prelude hiding (Maybe(..))
+
+data Maybe a = Nothing | Just a
+{-@ data Maybe a = Nothing | Just a @-}
+
+
+{-@ reflect seq @-}
+seq :: Maybe (a -> b) -> Maybe a -> Maybe b
+seq (Just f) (Just x) = Just (f x)
+seq _         _       = Nothing
+
+{-@ reflect compose @-}
+compose :: (b -> c) -> (a -> b) -> a -> c
+compose f g x = f (g x)
+
+{-@ reflect pure @-}
+pure :: a -> Maybe a
+pure x = Just x
diff --git a/tests/todo/MaybeReflect1.hs b/tests/todo/MaybeReflect1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/MaybeReflect1.hs
@@ -0,0 +1,28 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+
+
+{-# LANGUAGE IncoherentInstances   #-}
+{-# LANGUAGE FlexibleContexts #-}
+module MaybeReflect1 where
+
+
+import Prelude hiding (Maybe(..))
+
+data Maybe a = Nothing | Just a
+{-@ data Maybe a = Nothing | Just a @-}
+
+
+{-@ reflect seqm @-}
+seqm :: Maybe (a -> b) -> Maybe a -> Maybe b
+seqm (Just f) (Just x) = Just (f x)
+seqm _         _       = Nothing
+
+{-@ reflect composem @-}
+composem :: (b -> c) -> (a -> b) -> a -> c
+composem f g x = f (g x)
+
+{-@ reflect purem @-}
+purem :: a -> Maybe a
+purem x = Just x
diff --git a/tests/todo/Means.hs b/tests/todo/Means.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Means.hs
@@ -0,0 +1,122 @@
+{-# LANGUAGE TypeSynonymInstances #-}
+
+module Means where
+
+import Prelude hiding ((*))
+import qualified Prelude as Pr
+import Language.Haskell.Liquid.Prelude
+
+type Scalar = Double
+
+{-@ assume (*) :: x:Scalar -> y:Scalar -> {v:Scalar | v = (times x y)} @-}
+(*) :: Scalar -> Scalar -> Scalar
+(*) = (Pr.*)
+
+{-@ assume inverse :: x:{v:Scalar | v != 0} -> {v:Scalar | v = (inverse x)} @-}
+inverse :: Scalar -> Scalar
+inverse x | x == zero = error "inverse a zero value"
+          | otherwise = one / x
+
+-- Double 1 does not take a singleton type
+{-@ assume one :: {v:Scalar | v = 1} @-}
+one :: Scalar
+one = 1
+
+{-@ assume two :: {v:Scalar | v = 2} @-}
+two :: Scalar
+two = 2
+
+{-@ assume zero :: {v:Scalar | v = 0} @-}
+zero :: Scalar
+zero = 0
+
+
+{-@
+  measure times :: Scalar -> Scalar -> Scalar
+  @-}
+
+{-@
+  measure inverse :: Scalar -> Scalar
+  @-}
+
+-- Properties of multiplication
+
+{-@ mulNeutral :: x:Scalar -> {v:Bool | x = (times 1 x)} @-}
+mulNeutral :: Scalar -> Bool
+mulNeutral x | x == one * x = True
+      --        | otherwise  = error "mulNeutral fails"
+
+{-@ mulExpTwo :: x:Scalar -> {v:Bool | (times 2 x) = x + x } @-}
+mulExpTwo :: Scalar -> Bool
+mulExpTwo x  | two * x == x + x = True
+      --        | otherwise  = error "mulAssoc fails"
+
+{-@ mulTrans :: x:Scalar -> y:Scalar -> z:Scalar -> {v:Bool | (times (times x y) z) = (times x (times y z))} @-}
+mulTrans :: Scalar -> Scalar -> Scalar -> Bool
+mulTrans x y z | x * y * z == x * (y * z) = True
+      --        | otherwise  = error "mulAssoc fails"
+
+{-@ mulAssoc :: x:Scalar -> y:Scalar -> {v:Bool | (times x y) = (times y x)} @-}
+mulAssoc :: Scalar -> Scalar -> Bool
+mulAssoc x y | x * y == y * x = True
+      --        | otherwise  = error "mulAssoc fails"
+
+{-@ mulDivId :: x:{v:Scalar|v/= 0} -> {v:Bool | 1 = (times x (inverse x))} @-}
+mulDivId :: Scalar -> Bool
+mulDivId x | one == x * inverse x = True
+      --   | otherwise  = error "mulDivId fails"
+
+-- Class Specifications
+class Vec a where
+  norm :: a -> Scalar
+  mean :: a -> a -> Scalar
+  {-@ dist :: Vec a => x:a -> y:a -> {v:Scalar | v = (dist x y) } @-}
+  dist :: a -> a -> Scalar
+
+{-@ class measure dist :: forall a . a -> a -> Scalar @-}
+
+-- Assumptions:
+-- Triangle Inequality
+
+{-@ triangleInequality :: Vec a => x:a -> y:a -> c:a ->
+      {v:Bool | ((((dist x c) + (dist c y)) >= (dist x y)))} @-}
+triangleInequality :: Vec a => a -> a -> a -> Bool
+triangleInequality x y c 
+  | (dist x c + dist c y) >= (dist x y) 
+  = True
+  | otherwise                           
+  = error "Vec.dist does not satisfy triangleInequality"            
+
+
+
+{-@ foo :: x:Scalar -> {v:Scalar |  v= x} @-}
+foo :: Scalar -> Scalar
+foo x = liquidAssume (mulNeutral x) $ one * x 
+
+
+{-@ type Valid = {v:Bool | ((Prop v) <=> true)} @-}
+
+{-@ prop1 :: Vec a => a -> a -> a -> Valid @-}
+prop1 :: Vec a => a -> a -> a -> Bool
+prop1 x y c = liquidAssume ( triangleInequality x y c 
+                          && mulNeutral dxy 
+                          && mulDivId two
+                          && mulTrans two itwo dxy
+                          && mulExpTwo itwo_dxy
+                           ) $ 
+              (dist x c) + (dist c y) >= (itwo_dxy + itwo_dxy')
+  where c'  = mean x y
+        dxy = dist x y
+        itwo = inverse two
+        itwo_dxy = itwo * dxy              -- = dist (y, mean x y)
+        itwo_dxy' = inverse two * dist x y -- = dist (x, mean x y)
+
+
+-- Q: how do we enforce linear arithmetic now? tests/pos/mul.hs
+-- Step 1: encode everything as Real and use nlsat tactick
+--         (check-sat-using qfnra-nlsat)
+--         http://rise4fun.com/Z3/1EYC
+-- Step 2: encode class theorems, like triangleInequality
+--         at every environment with 3 Vecs enforce the theorem
+-- Step 3: "prove" the theorems for class instances
+--           testing?
diff --git a/tests/todo/Measure.hs b/tests/todo/Measure.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Measure.hs
@@ -0,0 +1,10 @@
+module Measure where
+
+
+
+data Foo a = F a 
+
+{-@ measure foo :: a -> Int @-}
+
+{-@ measure bar :: (Foo a) -> Bool
+    bar(F xs) = (foo xs)         @-}
diff --git a/tests/todo/NameClash.hs b/tests/todo/NameClash.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/NameClash.hs
@@ -0,0 +1,68 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+{-@ LIQUID "--no-termination" @-}
+
+module LinSpace () where
+
+
+data PVector = PVector [Integer] [Integer] (Space PVector) -- { 
+
+-- | Orthogonalized vector bn* and squared lattice determinant 
+data Space a = Null | Real a Integer
+
+{-@ data PVector = PVector { 
+      pec_  :: [Integer]   
+    , mu_   :: [Integer] 
+    , orth_ :: {v: (Space (PVectorN (len pec_))) | (dim v) = (len mu_)}
+    } 
+  @-}
+
+{-@ data Space [dim] @-}
+
+{-@ measure dim     :: (Space PVector) -> Int 
+    dim (Null)      = 0
+    dim (Real pv n) = 1 + (dim (orthSpace pv))
+  @-}
+
+{-@ measure spaceVec     :: (Space PVector) -> PVector
+    spaceVec (Real pv n) = pv
+  @-}
+
+{-@ measure vec :: PVector -> [Integer]
+    vec (PVector p m o) = p
+  @-}
+{-@ measure orthSpace :: PVector -> (Space PVector)
+    orthSpace (PVector v m o) = o
+  @-}
+
+{-@ measure muCoeff :: PVector -> [Integer]
+    muCoeff (PVector v m o) = m 
+  @-}
+
+--  If the above v is renames to anything else the test is SAFE
+-- this v creates a type for PVector
+-- PVector :: v{} -> m {} -> o{}
+-- and the argument bind v clashs with the special value v....
+
+{-@ invariant {v: PVector | (Inv v) }    @-}
+{-@ invariant {v: Space | (dim v) >= 0 } @-}
+
+-- RJ: Helpers for defining properties
+
+{-@ predicate Inv V        = (dim (orthSpace V)) = (len (muCoeff V)) @-}
+{-@ predicate SameLen  X Y = ((len (vec X))  = (len (vec Y)))  @-}
+{-@ predicate SameOrth X Y = ((orthSpace X) = (orthSpace Y)) @-}
+
+-- RJ: Useful type aliases for specs
+
+{-@ type SameSpace X       = {v:PVector | ((Inv v) && (SameLen X v) && (SameOrth X v))} @-}
+{-@ type PVectorN N        = {v: PVector | (len (vec v)) = N}   @-} 
+{-@ type PVectorP P        = {v: PVector | (SameLen v P)}       @-} 
+
+--------------------
+
+
+{-@ orthSpace_ :: p:PVector -> (Space (PVectorP p))  @-} 
+orthSpace_ (PVector v m o) = o
+
+
diff --git a/tests/todo/NativeFixCrash.hs b/tests/todo/NativeFixCrash.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/NativeFixCrash.hs
@@ -0,0 +1,14 @@
+module Interpreter where 
+
+data Instr = I
+
+data List a = Nil | Cons a (List a)
+
+type Prog  = List Instr
+type Stack = List Int
+
+{-@ measure progDenote :: Stack -> Prog -> Maybe Stack @-}
+progDenote :: Stack -> Prog -> Maybe Stack
+progDenote s Nil = Just s
+progDenote s (Cons x xs) | Just s' <- Just s  = progDenote s' xs
+
diff --git a/tests/todo/NeuralNetwork.hs b/tests/todo/NeuralNetwork.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/NeuralNetwork.hs
@@ -0,0 +1,136 @@
+#!/usr/bin/env stack
+-- stack --resolver lts-5.15 --install-ghc runghc --package hmatrix --package MonadRandom
+
+-- FROM: https://github.com/mstksg/inCode/blob/master/code-samples/dependent-haskell/NetworkUntyped.hs
+
+{-# LANGUAGE BangPatterns        #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE GADTs               #-}
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+import Control.Monad
+import Control.Monad.Random
+import Data.List
+import Data.Maybe
+import Numeric.LinearAlgebra
+import System.Environment
+import Text.Read
+
+data Weights = W { wBiases :: !(Vector Double)  -- n
+                 , wNodes  :: !(Matrix Double)  -- n x m
+                 }                              -- "m to n" layer
+
+data Network = Last !Weights
+             | Link !Weights Network
+
+logistic :: Floating a => a -> a
+logistic x = 1 / (1 + exp (-x))
+
+logistic' :: Floating a => a -> a
+logistic' x = logix * (1 - logix)
+  where
+    logix = logistic x
+
+runLayer :: Weights -> Vector Double -> Vector Double
+runLayer (W wB wN) v = wB + wN #> v
+
+runNet :: Network -> Vector Double -> Vector Double
+runNet (O w)      !v = logistic (runLayer w v)
+runNet (w :&~ n') !v = let v' = logistic (runLayer w v)
+                       in  runNet n' v'
+
+randomWeights :: MonadRandom m => Int -> Int -> m Weights
+randomWeights i o = do
+    seed1 :: Int <- getRandom
+    seed2 :: Int <- getRandom
+    let wB = randomVector  seed1 Uniform o * 2 - 1
+        wN = uniformSample seed2 o (replicate i (-1, 1))
+    return $ W wB wN
+
+randomNet :: MonadRandom m => Int -> [Int] -> Int -> m Network
+randomNet i []     o =     O <$> randomWeights i o
+randomNet i (h:hs) o = (:&~) <$> randomWeights i h <*> randomNet h hs o
+
+train :: Double           -- ^ learning rate
+      -> Vector Double    -- ^ input vector
+      -> Vector Double    -- ^ target vector
+      -> Network          -- ^ network to train
+      -> Network
+train rate x0 target = fst . go x0
+  where
+    go :: Vector Double    -- ^ input vector
+       -> Network          -- ^ network to train
+       -> (Network, Vector Double)
+    -- handle the output layer
+    go !x (O w@(W wB wN))
+        = let y    = runLayer w x
+              o    = logistic y
+              -- the gradient (how much y affects the error)
+              --   (logistic' is the derivative of logistic)
+              dEdy = logistic' y * (o - target)
+              -- new bias weights and node weights
+              wB'  = wB - scale rate dEdy
+              wN'  = wN - scale rate (dEdy `outer` x)
+              w'   = W wB' wN'
+              -- bundle of derivatives for next step
+              dWs  = tr wN #> dEdy
+          in  (O w', dWs)
+    -- handle the inner layers
+    go !x (w@(W wB wN) :&~ n)
+        = let y          = runLayer w x
+              o          = logistic y
+              -- get dWs', bundle of derivatives from rest of the net
+              (n', dWs') = go o n
+              -- the gradient (how much y affects the error)
+              dEdy       = logistic' y * dWs'
+              -- new bias weights and node weights
+              wB'  = wB - scale rate dEdy
+              wN'  = wN - scale rate (dEdy `outer` x)
+              w'   = W wB' wN'
+              -- bundle of derivatives for next step
+              dWs  = tr wN #> dEdy
+          in  (w' :&~ n', dWs)
+
+netTest :: MonadRandom m => Double -> Int -> m String
+netTest rate n = do
+    inps <- replicateM n $ do
+      s <- getRandom
+      return $ randomVector s Uniform 2 * 2 - 1
+    let outs = flip map inps $ \v ->
+                 if v `inCircle` (fromRational 0.33, 0.33)
+                      || v `inCircle` (fromRational (-0.33), 0.33)
+                   then fromRational 1
+                   else fromRational 0
+    net0 <- randomNet 2 [16,8] 1
+    let trained = foldl' trainEach net0 (zip inps outs)
+          where
+            trainEach :: Network -> (Vector Double, Vector Double) -> Network
+            trainEach nt (i, o) = train rate i o nt
+
+        outMat = [ [ render (norm_2 (runNet trained (vector [x / 25 - 1,y / 10 - 1])))
+                   | x <- [0..50] ]
+                 | y <- [0..20] ]
+        render r | r <= 0.2  = ' '
+                 | r <= 0.4  = '.'
+                 | r <= 0.6  = '-'
+                 | r <= 0.8  = '='
+                 | otherwise = '#'
+
+    return $ unlines outMat
+  where
+    inCircle :: Vector Double -> (Vector Double, Double) -> Bool
+    v `inCircle` (o, r) = norm_2 (v - o) <= r
+
+main :: IO ()
+main = do
+    args <- getArgs
+    let n    = readMaybe =<< (args !!? 0)
+        rate = readMaybe =<< (args !!? 1)
+    putStrLn "Training network..."
+    putStrLn =<< evalRandIO (netTest (fromMaybe 0.25   rate)
+                                     (fromMaybe 500000 n   )
+                            )
+
+(!!?) :: [a] -> Int -> Maybe a
+xs !!? i = listToMaybe (drop i xs)
diff --git a/tests/todo/NewType00.hs b/tests/todo/NewType00.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/NewType00.hs
@@ -0,0 +1,12 @@
+module NT where
+
+{- newtype Natural = Natural { toInt :: Nat } @-}
+newtype Natural = Natural { toInt :: Int }
+
+foo :: Int -> Maybe Natural
+foo n
+  | 0 <= n    = Just (Natural n)
+  | otherwise = Nothing
+
+{-@ bar :: Natural -> Nat @-}
+bar (Natural n) = n
diff --git a/tests/todo/NoInstance.hs b/tests/todo/NoInstance.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/NoInstance.hs
@@ -0,0 +1,15 @@
+module SClass where
+
+import qualified Data.Set
+
+data Stack a = S [a]
+
+data Foo a = F {stack :: Stack a}
+
+{-@ class measure elts  :: forall f a. f a -> Data.Set.Set a @-}
+
+{-@ measure  eltss :: [(Foo a)] -> (Data.Set.Set a)
+    eltss([]) = {v| (? (Set_emp v))}
+    eltss(x:xs) = (Set_cup (elts x) (eltss xs))
+  @-}
+
diff --git a/tests/todo/NotesOnProductivityTest.hs b/tests/todo/NotesOnProductivityTest.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/NotesOnProductivityTest.hs
@@ -0,0 +1,21 @@
+module Fixme where
+
+import Prelude hiding (repeat, filter)
+
+-- Checking productivity
+--  1. Leino : syntactically ignore checks in syntactically productive locations
+--  PLUS  fivesUp
+
+{-@ fivesUp :: n:Nat -> Int -> [Int] @-}
+fivesUp :: Int -> Int -> [Int]
+fivesUp n m | n == 0    = m : fivesUp 5 (m+1)
+            | otherwise = fivesUp (n-1) (m+1)
+
+
+-- VS : Mini-adga: check that recursive calls return codata with *smaller* size
+-- MINUS : fivesUp
+-- PLUS  : depth preserving functions
+
+{-map :: f:(a -> b) -> xs:[a] -> {v : [a]| (len v) = (len xs)}
+ -}
+bar (x:xs) = x : map id xs 
diff --git a/tests/todo/Parse.hs b/tests/todo/Parse.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Parse.hs
@@ -0,0 +1,9 @@
+module Fixme where
+
+
+data L a
+  = C {x :: a , xs :: L a} 
+
+{-@ data L a 
+   = C { x:: a , xs :: L a} 
+ @-}
diff --git a/tests/todo/Parse1.hs b/tests/todo/Parse1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Parse1.hs
@@ -0,0 +1,5 @@
+module BadParse where
+
+
+{-@ test :: v:a -> (r:a, l:a) @-}
+test x = (x, x)
diff --git a/tests/todo/PartialAbsApplication.hs b/tests/todo/PartialAbsApplication.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/PartialAbsApplication.hs
@@ -0,0 +1,14 @@
+module Fixme where
+
+data World = W Int
+{-@ data FIO a <pre :: World -> Prop, post :: World -> a -> World -> Prop>
+  = FIO (rs :: (x:World<pre> -> (a, World)<\y -> {v:World<post x y> | true}>))  @-}
+data FIO a  = FIO {runState :: World -> (a, World)}
+
+{-@ createFile :: forall <p :: Int -> World -> Prop,
+                          q :: Int -> World -> Int -> World -> Prop>.
+  {f::Int |- World<p f> <: World}
+  {f::Int, w::World<p f>,  x::Int |- World <: World<q f w x>}
+  a:Int -> FIO <p a, \x z -> {v:World<q a x z> | true}> Int @-}
+createFile :: Int -> FIO Int
+createFile = undefined
diff --git a/tests/todo/Plus.hs b/tests/todo/Plus.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Plus.hs
@@ -0,0 +1,15 @@
+module Plus where
+
+go :: Int -> Int -> Int -> Int
+{-@ go :: x:Int -> y:Int -> {v:Int|v = x-y+1} -> Int @-}
+go _ _ _ = undefined
+
+
+go' :: Int -> Int -> Int -> Int
+{-@ go' :: x:Int -> y:Int -> {v:Int|v = (x-y)+1} -> Int @-}
+go' _ _ _ = undefined
+
+
+bar x y z 
+  = if z then go x y (x-y+1) 
+         else go' x y (x-y+1)
diff --git a/tests/todo/QualifCheck.hs b/tests/todo/QualifCheck.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/QualifCheck.hs
@@ -0,0 +1,8 @@
+module Foo where
+
+{-@ qualif Foo(v:a, x:List a) : (Set_mem v (listElts xs)) @-}
+
+{-@ foo :: Nat -> Nat @-}
+foo :: Int -> Int
+foo x = x
+
diff --git a/tests/todo/RG.hs b/tests/todo/RG.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/RG.hs
@@ -0,0 +1,12 @@
+{- this is a test for the "bug" introduced in liquid-fixpoint by 
+   commit: 9608cb6e4dd33bf142b50db4630c629defceb91e             -}
+
+module RG where
+
+data RGRef a
+
+{-@ measure tv :: RGRef a -> a @-}
+
+{-@ qualif TERMINALVALUE(r:RGRef a): (tv r) @-}
+
+
diff --git a/tests/todo/RecordAccessors.hs b/tests/todo/RecordAccessors.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/RecordAccessors.hs
@@ -0,0 +1,7 @@
+module RecordAccessors where
+
+{-@ data Foo = F { thing :: Nat } @-}
+data Foo = F { thing :: Int }
+
+{-@ bar :: Foo -> Nat @-}
+bar = thing
diff --git a/tests/todo/Recursion.hs b/tests/todo/Recursion.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Recursion.hs
@@ -0,0 +1,18 @@
+module Rec where
+
+import Language.Haskell.Liquid.Prelude
+
+newtype Rec a = In { out :: Rec a -> a }
+ 
+y :: (a -> a) -> a
+y = \f -> (\x -> f (out x x)) (In (\x -> f (out x x)))
+
+
+{-@ foo :: n:Nat -> {v:Nat | v < n} @-}
+foo :: Int -> Int
+foo = y go
+  where go f n =  if n > 0 then n-1 else f n
+
+
+prop = let x = 0 in
+       liquidAssert ((\n -> 0==1) (foo 0))
diff --git a/tests/todo/Recursion1.hs b/tests/todo/Recursion1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Recursion1.hs
@@ -0,0 +1,26 @@
+module Rec1 where
+
+import Control.Monad.ST 
+import Data.IORef 
+
+import System.IO.Unsafe
+
+-- recursion with references in ocaml
+--
+-- bar = 
+--   let f = ref (fun _ => 0) in 
+--   let foo f n = if n > 0 then n-1 else !f n
+--   f := (foo f); !f
+
+-- translation to Haskell
+
+f n = unsafePerformIO $ (unsafePerformIO bar) n
+
+bar :: IO (Int -> IO Int)
+bar  = do f <- newIORef (\_ -> return 0)
+          writeIORef f (foo f)
+          readIORef f
+
+foo     :: (IORef (Int -> IO Int)) -> Int -> IO Int
+foo f n  | n > 0     = return $ n-1 
+         | otherwise = readIORef f >>= \g -> g n
diff --git a/tests/todo/RedBlack.hs b/tests/todo/RedBlack.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/RedBlack.hs
@@ -0,0 +1,90 @@
+module RedBlack where
+
+----------------------------------------------------------------------------------- 
+-- From: http://www.mew.org/~kazu/proj/red-black-tree/ ----------------------------
+----------------------------------------------------------------------------------- 
+
+data RBTree a = Leaf | Fork Color (RBTree a) a (RBTree a)
+data Color    = Red  | Black
+
+{-@
+inline measure cheight :: Color -> Int
+cheight (x) = if (x == Black) then 1 else 0
+@-}
+
+{-@ 
+measure height        :: RBTree a -> Int   
+height (Leaf)         = 0
+height (Fork c l x r) = (cheight c) + (height l)
+@-}
+
+{-@ 
+measure color        :: RBTree a -> Color 
+color (Leaf)         = Black
+color (Fork c l x r) = c
+@-}
+
+{-@ predicate isBlack X     = (X == Black)                                                 @-}
+{-@ predicate isRed X       = (X == Red)                                                   @-}
+{-@ predicate okRoot1 C L R = ((isRed C)  => ((isBlack (color L)) || (isBlack (color R)))) @-}
+{-@ predicate okRoot2 C L R = ((isRed C)  => ((isBlack (color L)) && (isBlack (color R)))) @-}
+{-@ predicate eqHeight  L R = ((height L) == (height R))                                   @-}
+
+{-@ 
+measure invKids2        :: RBTree a -> Prop 
+invKids2 (Leaf)         =  true
+invKids2 (Fork c l x r) =  (OkRoot2 c l r) && (invKids2 l) && (invKids2 r) 
+@-}
+
+{-@ 
+measure invKids1        :: RBTree a -> Prop 
+invKids1 (Leaf)         = true
+invKids1 (Fork c l x r) = (OkRoot1 c l r) && (invKids2 l) && (invKids2 r)
+@-}
+
+{-@ 
+measure invHeight        :: RBTree a -> Prop 
+invHeight (Leaf)         =  true
+invHeight (Fork c l x r) =  (eqHeight l r) && (invHeight l) && (invHeight r)
+@-}
+
+{-@ type RB1Tree a = {v: (RBTree a) | (invKids1 v) && (invHeight v)} @-}
+{-@ type RB2Tree a = {v: (RBTree a) | (invKids2 v) && (invHeight v)} @-}
+
+----------------------------------------------------------------------------------- 
+
+{-@ empty :: IRBTree a @-}
+empty     = Leaf
+
+{-@ insert       :: Ord a => a -> RB2Tree a -> RB2Tree a @-}
+insert x t       = Fork Black d e f
+  where
+    Fork _ d e f = ins x t
+
+ins x Leaf             = Fork R Leaf x Leaf
+ins x t@(Fork c l y r) = case compare x y of
+                           LT -> balanceL c (ins x l) y r
+                           GT -> balanceR c l y (ins x r)
+                           EQ -> t
+
+{-@ balanceL :: c:Color 
+             -> l:(RB1Tree a) 
+             -> x:a 
+             -> r:{v : (RB2Tree a) | (eqHeight l v)} 
+             -> {v:(RB2Tree a) | (height v) = (cheight c) + (height l) } @-}
+balanceL :: Color -> RBTree a -> a -> RBTree a -> RBTree a
+balanceL B (Fork R (Fork R a x b) y c) z d = Fork R (Fork B a x b) y (Fork B c z d)
+balanceL B (Fork R a x (Fork R b y c)) z d = Fork R (Fork B a x b) y (Fork B c z d)
+balanceL k a x b                           = Fork k a x b
+
+{-@ balanceR :: c:Color 
+             -> l:(RB2Tree a) 
+             -> x:a 
+             -> r:{v : (RB1Tree a) | (eqHeight l v)} 
+             -> {v:(RB2Tree a) | (height v) = (cheight c) + (height l) } @-}
+balanceR :: Color -> RBTree a -> a -> RBTree a -> RBTree a
+balanceR B a x (Fork R b y (Fork R c z d)) = Fork R (Fork B a x b) y (Fork B c z d)
+balanceR B a x (Fork R (Fork R b y c) z d) = Fork R (Fork B a x b) y (Fork B c z d)
+balanceR k a x b                           = Fork k a x b
+
+
diff --git a/tests/todo/RefinedData.hs b/tests/todo/RefinedData.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/RefinedData.hs
@@ -0,0 +1,5 @@
+module Foo where
+
+data F = F {f1 :: Int, f2 :: Bool}
+
+{-@ data F = F {f2 :: Bool, f1 :: Int} @-}
diff --git a/tests/todo/ReflImp.hs b/tests/todo/ReflImp.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ReflImp.hs
@@ -0,0 +1,18 @@
+{-@ LIQUID "--higherorder"     @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+{-@ LIQUID "--higherorderqs"   @-}
+
+module Peano where
+
+import ProofCombinators
+
+import Incr (incr)
+
+{-@ pf :: () -> { incr 2 == 3 }  @-}
+pf () = incr 2 *** QED
+
+
+
+
+pf :: () -> Proof
diff --git a/tests/todo/ReflectClient3.hs b/tests/todo/ReflectClient3.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ReflectClient3.hs
@@ -0,0 +1,14 @@
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectClient3a where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+import ReflectLib3a
+
+stupidity = [ undefined gapp ]
+
+{-@ test4 :: { gapp Nil = Nil } @-}
+test4 = gapp Nil ==. Nil *** QED 
diff --git a/tests/todo/ReflectClient3a.hs b/tests/todo/ReflectClient3a.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ReflectClient3a.hs
@@ -0,0 +1,58 @@
+
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectClient3 where
+
+import Language.Haskell.Liquid.ProofCombinators
+import ReflectLib3
+
+forceImports = [ undefined next
+               , undefined llen
+               , undefined lDay
+               , undefined app
+               ]
+
+{-@ test2 :: { next Mon == Tue } @-}
+test2 = next Mon ==. Tue *** QED
+
+{-@ test4 :: { lDay Nil == Mon } @-}
+test4 = lDay Nil ==. Mon *** QED
+
+{-@ test3 :: { llen Nil == 0 } @-}
+test3 = trivial
+-- {- thmAppSize :: xs:List a -> ys:List a ->
+      -- { lSize (app xs ys) == lSize xs + lSize ys}
+  -- -}
+-- thmAppSize :: List a -> List a -> Proof
+-- thmAppSize Nil ys
+  -- =   lSize (app Nil ys)
+  -- ==. lSize ys
+  -- ==. lSize Nil + lSize ys
+  -- *** QED
+
+--  thmAppLen (Cons x xs) ys
+  --  =   llen (app (Cons x xs) ys)
+  --  ==. llen (Cons x (app xs ys))
+  --  ==. 1 + llen (app xs ys)
+      --  ? thmAppLen xs ys
+  --  ==. 1 + llen xs + llen ys
+  --  ==. llen (Cons x xs) + llen ys
+  --  *** QED
+
+--
+--------------------------------------------------------------------------------
+-- Random Debug Stuff
+--------------------------------------------------------------------------------
+
+{-@ zen :: xs:List a -> {v:Nat | v = llen xs} @-}
+zen :: List a -> Int
+zen Nil        = 0
+zen (Cons h t) = 1 + zen t
+
+-- THIS FAILS
+{-@ zoo :: List a -> {v:Int | v == 0} @-}
+zoo :: List a -> Int
+zoo Nil         = llen Nil
+zoo (Cons x xs) = zoo xs
diff --git a/tests/todo/ReflectClient4.hs b/tests/todo/ReflectClient4.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ReflectClient4.hs
@@ -0,0 +1,64 @@
+
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectClient4 where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+import ReflectLib4
+
+-- THIS IS NEEDED TO BRING THE NAMES INTO SCOPE FOR GHC ...
+forceImports = [ ]
+
+{-@ test1 :: {v:List a | v = Nil} @-}
+test1 :: List a
+test1 = Nil
+
+
+{-@ test2 :: {v:Proof | llen (Cons 1 Nil) = 1} @-}
+test2 :: Proof
+test2 =  llen (Cons 1 Nil)
+      ==. 1 + llen Nil
+      ==. 1
+      *** QED
+
+{-@ test3 :: {v:Proof | llen (Cons 1 (Cons 2 Nil)) = 2} @-}
+test3 :: Proof
+test3 =  llen (Cons 1 (Cons 2 Nil))
+      ==. 1 + llen (Cons 2 Nil)
+      ==. 1 + 1 + llen Nil
+      *** QED
+
+{-@ zen :: xs:List a -> {v:Nat | v = llen xs} @-}
+zen :: List a -> Int
+zen Nil        = 0
+zen (Cons h t) = 1 + zen t
+
+{-@ test5 :: { app (Cons 1 Nil) (Cons 2 (Cons 3 Nil)) = Cons 1 (Cons 2 (Cons 3 Nil)) } @-}
+test5 =   app (Cons 1 Nil) (Cons 2 (Cons 3 Nil))
+      ==. Cons 1 (app Nil (Cons 2 (Cons 3 Nil)))
+      ==. Cons 1 (Cons 2 (Cons 3 Nil))
+      *** QED
+
+{-@ thmAppLen :: xs:List a -> ys:List a ->
+      { llen (app xs ys) == llen xs + llen ys}
+  @-}
+
+-- thmAppLen :: List a -> List a -> Proof
+
+thmAppLen Nil ys
+  =   llen (app Nil ys)
+  ==. llen ys
+  ==. llen Nil + llen ys
+  *** QED
+
+thmAppLen (Cons x xs) ys
+  =   llen (app (Cons x xs) ys)
+  ==. llen (Cons x (app xs ys))
+  ==. 1 + llen (app xs ys)
+      ? thmAppLen xs ys
+  ==. 1 + llen xs + llen ys
+  ==. llen (Cons x xs) + llen ys
+  *** QED
diff --git a/tests/todo/ReflectClient4a.hs b/tests/todo/ReflectClient4a.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ReflectClient4a.hs
@@ -0,0 +1,32 @@
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectClient4a where
+
+import Language.Haskell.Liquid.ProofCombinators
+import ReflectLib3
+
+stupidity = [ undefined gapp ]
+
+{- test1 :: { llen Nil == 0 } @-}
+test1 = ()
+
+{- test2 :: { llen (Cons 2 Nil) == 1 } @-}
+test2 = ()
+
+{- test3 :: { llen (Cons 1 (Cons 2 Nil)) == 2 } @-}
+test3 = ()
+
+{- test4 :: { app Nil Nil == Nil } @-}
+
+{-@ test4 :: { gapp Nil = Nil } @-}
+test4 = ()
+
+
+-- {- thmAppLen :: xs:List a -> ys:List a ->
+      -- { llen (app xs ys) == llen xs + llen ys}
+  -- @-}
+-- thmAppLen :: List a -> List a -> Proof
+-- thmAppLen Nil         ys = trivial
+-- thmAppLen (Cons x xs) ys = thmAppLen xs ys
diff --git a/tests/todo/ReflectLib3.hs b/tests/todo/ReflectLib3.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ReflectLib3.hs
@@ -0,0 +1,37 @@
+
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectLib3 where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+-- | Days ---------------------------------------------------------------------
+
+{-@ data Day = Mon | Tue @-}
+data Day = Mon | Tue
+
+{-@ reflect next @-}
+next :: Day -> Day
+next Mon = Tue
+next Tue = Mon
+
+{-@ reflect lDay @-}
+lDay :: List a -> Day
+lDay Nil      = Mon
+lDay (Cons x) = Tue
+
+-- | Lists ---------------------------------------------------------------------
+
+{-@ data List  a = Nil | Cons {lHd :: a} @-}
+data List a = Nil | Cons a
+
+
+{-@ reflect gapp @-}
+gapp :: List a -> List a
+gapp Nil      = Nil
+gapp (Cons x) = Cons x
+
+{-@ test4 :: { gapp Nil = Nil } @-}
+test4 = ()
diff --git a/tests/todo/ReflectLib4.hs b/tests/todo/ReflectLib4.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ReflectLib4.hs
@@ -0,0 +1,32 @@
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectLib4 where
+
+-- | Lists ---------------------------------------------------------------------
+
+{-@ data List [llen] a = Nil | Cons {lHd :: a, lTl :: List a} @-}
+data List a = Nil | Cons a (List a)
+
+{-@ measure llen @-}
+{-@ llen :: List a -> Nat @-}
+llen :: List a -> Int
+llen Nil        = 0
+llen (Cons h t) = 1 + llen t
+
+-- TODO: make this work WITHOUT the invariant
+{-@ invariant {v:List a | 0 <= llen v} @-}
+
+{-@ reflect app @-}
+app :: List a -> List a -> List a
+app Nil         ys = ys
+app (Cons x xs) ys = Cons x (app xs ys)
+
+{-@ reflect gapp @-}
+gapp :: List a -> List a
+gapp Nil         = Nil
+gapp (Cons x xs) = Nil
+
+{-@ test4 :: { gapp Nil = Nil } @-}
+test4 = ()
diff --git a/tests/todo/ReflectLib5.hs b/tests/todo/ReflectLib5.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ReflectLib5.hs
@@ -0,0 +1,66 @@
+
+{-@ LIQUID "--exact-data-con"                      @-}
+{- LIQUID "--higherorder"                         @-}
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module ReflectLib3 where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+-- | Lists ---------------------------------------------------------------------
+
+{-@ data Day = Mon | Tue @-}
+data Day = Mon | Tue
+
+{-@ reflect next @-}
+next :: Day -> Day
+next Mon = Tue
+next Tue = Mon
+
+-- | Lists ---------------------------------------------------------------------
+
+{-@ data List [llen] a = Nil | Cons {lHd :: a, lTl :: List} @-}
+data List a = Nil | Cons a (List a)
+
+{-@ measure llen @-}
+{-@ llen :: xs:List a -> {v:Nat | v = llen xs} @-}
+llen :: List a -> Int
+llen Nil        = 0
+llen (Cons h t) = 1 + llen t
+
+{-@ reflect lSize @-}
+lSize :: List a -> Int
+lSize Nil        = 0
+lSize (Cons h t) = 1 + lSize t
+
+{-@ reflect lDay @-}
+lDay Nil         = Mon 
+lDay (Cons x xs) = Tue
+
+-- TODO: NEEDED for the IMPORT to work.
+{-@ invariant { v:List a | 0 <= llen v } @-}
+
+{-@ reflect app @-}
+app :: List a -> List a -> List a
+app Nil         ys = ys
+app (Cons x xs) ys = Cons x (app xs ys)
+
+--------------------------------------------------------------------------------
+{-@ thmAppLen :: xs:List a -> ys:List a ->
+      { llen (app xs ys) == llen xs + llen ys}
+  @-}
+thmAppLen :: List a -> List a -> Proof
+thmAppLen Nil ys
+  =   llen (app Nil ys)
+  ==. llen ys
+  ==. llen Nil + llen ys
+  *** QED
+thmAppLen (Cons x xs) ys
+  =   llen (app (Cons x xs) ys)
+  ==. llen (Cons x (app xs ys))
+  ==. 1 + llen (app xs ys)
+      ? thmAppLen xs ys
+  ==. 1 + llen xs + llen ys
+  ==. llen (Cons x xs) + llen ys
+  *** QED
diff --git a/tests/todo/SMTDiverge.hs b/tests/todo/SMTDiverge.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/SMTDiverge.hs
@@ -0,0 +1,7 @@
+module Chunks where
+
+{-@ go :: Nat -> {v:Int | 1 < v} -> () @-}
+go :: Int -> Int -> ()
+go d n 
+  | d <= n    = ()
+  | otherwise = go (d `div` n) n 
diff --git a/tests/todo/SS.hs b/tests/todo/SS.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/SS.hs
@@ -0,0 +1,464 @@
+{-# LANGUAGE PatternGuards #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  XMonad.StackSet
+-- Copyright   :  (c) Don Stewart 2007
+-- License     :  BSD3-style (see LICENSE)
+--
+-- Maintainer  :  dons@galois.com
+-- Stability   :  experimental
+-- Portability :  portable, Haskell 98
+--
+
+module XMonad.StackSet where
+
+import Prelude hiding (filter, reverse, (++), elem) -- LIQUID
+import Data.Maybe   (listToMaybe,isJust,fromMaybe)
+import qualified Data.List as L (deleteBy,find,splitAt,filter,nub)
+import Data.List ( (\\) )
+import qualified Data.Map  as M (Map,insert,delete,empty)
+import qualified Data.Set -- LIQUID
+
+-------------------------------------------------------------------------------
+----------------------------- Refinements on  Lists ---------------------------
+-------------------------------------------------------------------------------
+
+-- measures
+
+{-@
+  measure head :: [a] -> a
+  head([])   = {v | false}
+  head(x:xs) = {v | v = x} 
+  @-}
+
+{-@
+  measure listDup :: [a] -> (Data.Set.Set a)
+  listDup([]) = {v | (? Set_emp (v))}
+  listDup(x:xs) = {v | v = ((Set_mem x (listElts xs))?(Set_cup (Set_sng x) (listDup xs)):(listDup xs)) }
+  @-}
+
+-- predicates 
+
+{-@ predicate EqElts X Y =
+       ((listElts X) = (listElts Y)) @-}
+
+{-@ predicate SubElts X Y =
+       (Set_sub (listElts X) (listElts Y)) @-}
+
+{-@ predicate UnionElts X Y Z =
+       ((listElts X) = (Set_cup (listElts Y) (listElts Z))) @-}
+
+{-@ predicate ListElt N LS =
+       (Set_mem N (listElts LS)) @-}
+
+{-@ predicate ListUnique LS =
+       (Set_emp (listDup LS)) @-}
+
+{-@ predicate ListUniqueDif LS X =
+       ((ListUnique LS) && (not (ListElt X LS))) @-}
+
+
+{-@ predicate ListDisjoint X Y =
+       (Set_emp (Set_cap (listElts X) (listElts Y))) @-}
+
+
+-- types
+
+{-@ type UList a = {v:[a] | (ListUnique v)} @-}
+
+{-@ type UListDif a N = {v:[a] | ((not (ListElt N v)) && (ListUnique v))} @-}
+
+
+
+-------------------------------------------------------------------------------
+----------------------------- Refinements on Stacks ---------------------------
+-------------------------------------------------------------------------------
+
+{-@
+data Stack a = Stack { focus :: a   
+                     , up    :: UListDif a focus
+                     , down  :: UListDif a focus }
+@-}
+
+{-@ type UStack a = {v:(Stack a) | (ListDisjoint (getUp v) (getDown v))}@-}
+
+{-@ measure getUp :: forall a. (Stack a) -> [a] 
+    getUp (Stack focus up down) = up
+  @-}
+
+{-@ measure getDown :: forall a. (Stack a) -> [a] 
+    getDown (Stack focus up down) = down
+  @-}
+
+{-@ measure getFocus :: forall a. (Stack a) -> a
+    getFocus (Stack focus up down) = focus
+  @-}
+
+{-@ predicate StackElt N S =
+       (((ListElt N (getUp S)) 
+       || (Set_mem N (Set_sng (getFocus S))) 
+       || (ListElt N (getDown S))))
+  @-}
+
+{-@ predicate StackSetVisibleElt N S = true @-}
+{-@ predicate StackSetHiddenElt N S = true @-}
+
+
+-------------------------------------------------------------------------------
+-----------------------  Grap StackSet Elements -------------------------------
+-------------------------------------------------------------------------------
+
+{-@ measure stackSetElts :: (StackSet i l a sid sd) -> (Data.Set.Set a)
+    stackSetElts(StackSet current visible hidden f) = (Set_cup (Set_cup (screenElts current) (screensElts visible)) (workspacesElts hidden))
+   @-}
+
+{-@ measure screensElts :: [(Screen i l a sid sd)] -> (Data.Set.Set a)
+    screensElts([])   = {v|(? (Set_emp v))} 
+    screensElts(x:xs) = (Set_cup (screenElt x) (screensElts xs))
+  @-}
+
+{-@ measure screenElts :: (Screen i l a sid sd) -> (Data.Set.Set a)
+    screenElts(Screen w s sd) = (workspaceElts w) @-}
+
+{-@ measure workspacesElts :: [(Workspace i l a)] -> (Data.Set.Set a)
+    workspacesElts([])   = {v|(? (Set_emp v))} 
+    workspacesElts(x:xs) = (Set_cup (workspaceElts x) (workspacesElts xs))
+  @-}
+
+{-@ measure workspaceElts :: (Workspace i l a) -> (Data.Set.Set a)
+    workspaceElts(Workspace t l s) = {v| (if (isJust s) then (stackElts (fromJust s)) else (? (Set_emp v)))} @-}
+
+{-@ measure stackElts :: (StackSet i l a sid sd) -> (Data.Set.Set a)
+    stackElts(Stack f up down) = (Set_cup (Set_sng f) (Set_cup (listElts up) (listElts down))) @-}
+
+{-@ predicate EmptyStackSet X = (? (Set_emp (stackSetElts X)))@-}
+
+
+-------------------------------------------------------------------------------
+-----------------------  Talking about Tags --- -------------------------------
+-------------------------------------------------------------------------------
+
+{-@ measure getTag :: (Workspace i l a) -> i
+    getTag(Workspace t l s) = t
+  @-}
+
+{-@ predicate IsCurrentTag X Y = 
+      (X = (getTag (getWorkspaceScreen (getCurrentScreen Y))))
+  @-}
+
+-- $intro
+--
+-- The 'StackSet' data type encodes a window manager abstraction. The
+-- window manager is a set of virtual workspaces. On each workspace is a
+-- stack of windows. A given workspace is always current, and a given
+-- window on each workspace has focus. The focused window on the current
+-- workspace is the one which will take user input. It can be visualised
+-- as follows:
+--
+-- > Workspace  { 0*}   { 1 }   { 2 }   { 3 }   { 4 }
+-- >
+-- > Windows    [1      []      [3*     [6*]    []
+-- >            ,2*]            ,4
+-- >                            ,5]
+--
+-- Note that workspaces are indexed from 0, windows are numbered
+-- uniquely. A '*' indicates the window on each workspace that has
+-- focus, and which workspace is current.
+
+-- $zipper
+--
+-- We encode all the focus tracking directly in the data structure, with a 'zipper':
+--
+--    A Zipper is essentially an `updateable' and yet pure functional
+--    cursor into a data structure. Zipper is also a delimited
+--    continuation reified as a data structure.
+--
+--    The Zipper lets us replace an item deep in a complex data
+--    structure, e.g., a tree or a term, without an  mutation.  The
+--    resulting data structure will share as much of its components with
+--    the old structure as possible.
+--
+--      Oleg Kiselyov, 27 Apr 2005, haskell\@, "Zipper as a delimited continuation"
+--
+-- We use the zipper to keep track of the focused workspace and the
+-- focused window on each workspace, allowing us to have correct focus
+-- by construction. We closely follow Huet's original implementation:
+--
+--      G. Huet, /Functional Pearl: The Zipper/,
+--      1997, J. Functional Programming 75(5):549-554.
+-- and:
+--      R. Hinze and J. Jeuring, /Functional Pearl: The Web/.
+--
+-- and Conor McBride's zipper differentiation paper.
+-- Another good reference is:
+--
+--      The Zipper, Haskell wikibook
+
+-- $xinerama
+-- Xinerama in X11 lets us view multiple virtual workspaces
+-- simultaneously. While only one will ever be in focus (i.e. will
+-- receive keyboard events), other workspaces may be passively
+-- viewable.  We thus need to track which virtual workspaces are
+-- associated (viewed) on which physical screens.  To keep track of
+-- this, 'StackSet' keeps separate lists of visible but non-focused
+-- workspaces, and non-visible workspaces.
+
+-- $focus
+--
+-- Each stack tracks a focused item, and for tiling purposes also tracks
+-- a 'master' position. The connection between 'master' and 'focus'
+-- needs to be well defined, particularly in relation to 'insert' and
+-- 'delete'.
+--
+
+------------------------------------------------------------------------
+-- |
+-- A cursor into a non-empty list of workspaces.
+--
+-- We puncture the workspace list, producing a hole in the structure
+-- used to track the currently focused workspace. The two other lists
+-- that are produced are used to track those workspaces visible as
+-- Xinerama screens, and those workspaces not visible anywhere.
+
+data StackSet i l a sid sd =
+    StackSet { current  :: !(Screen i l a sid sd)    -- ^ currently focused workspace
+             , visible  :: [Screen i l a sid sd]     -- ^ non-focused workspaces, visible in xinerama
+             , hidden   :: [Workspace i l a]         -- ^ workspaces not visible anywhere
+             , floating :: M.Map a RationalRect      -- ^ floating windows
+             } deriving (Show, Eq)
+-- LIQUID             } deriving (Show, Read, Eq)
+
+{-@ 
+data StackSet i l a sid sd =
+    StackSet { current  :: (Screen i l a sid sd)   
+             , visible  :: [Screen i l a sid sd]   
+             , hidden   :: [Workspace i l a]       
+             , floating :: M.Map a RationalRect    
+             }
+@-}
+
+{- invariant {v:(StackSet i l a sid sd) | 
+     (((?(
+       Set_emp (Set_cap (screenElts (getCurrentScreen v)) 
+                        (screensElts (getVisible v))
+      ))) && (?(
+       Set_emp (Set_cap (screenElts (getCurrentScreen v)) 
+                        (workspacesElts (getHidden v))
+      )))) && (?(
+       Set_emp (Set_cap (workspacesElts (getHidden v)) 
+                        (screensElts (getVisible v))
+      ))))} @-}
+
+{-@ measure getCurrentScreen :: (StackSet i l a sid sd) -> (Screen i l a sid sd)
+    getCurrentScreen(StackSet current v h f) = current @-}
+
+{-@ measure getVisible :: (StackSet i l a sid sd) -> [(Screen i l a sid sd)]
+    getVisible(StackSet current v h f) = v @-}
+
+{-@ measure getHidden :: (StackSet i l a sid sd) -> [(Workspace i l a)]
+    getHidden(StackSet current v h f) = h @-}
+
+{-@ predicate StackSetCurrentElt N S = 
+      (ScreenElt N (getCurrentScreen S))
+  @-}
+
+{-@ current :: s:(StackSet i l a sid sd) 
+            -> {v:(Screen i l a sid sd) | v = (getCurrentScreen s)}
+  @-}
+
+{-@ stack :: w:(Workspace i l a) 
+          -> {v:(Maybe (UStack a)) | v = (getStackWorkspace w)}
+  @-}
+
+{-@ workspace :: s:(Screen i l a sid sd) 
+              -> {v:(Workspace i l a) | v = (getWorkspaceScreen s)}
+  @-}
+
+{-@ tag :: w:(Workspace i l a) -> {v:i|v = (getTag w)} @-}
+
+-- | Visible workspaces, and their Xinerama screens.
+data Screen i l a sid sd = Screen { workspace :: !(Workspace i l a)
+                                  , screen :: !sid
+                                  , screenDetail :: !sd }
+    deriving (Show, Eq)
+-- LIQUID    deriving (Show, Read, Eq)
+
+{-@ 
+data Screen i l a sid sd = Screen { workspace :: (Workspace i l a)
+                                  , screen :: sid
+                                  , screenDetail :: sd }
+@-}
+
+{-@ measure getWorkspaceScreen :: (Screen i l a sid sd) -> (Workspace i l a)
+    getWorkspaceScreen(Screen w screen s) = w @-}
+
+
+{-@ predicate ScreenElt N S = 
+      (WorkspaceElt N (getWorkspaceScreen S))
+  @-}
+
+
+-- |
+-- A workspace is just a tag, a layout, and a stack.
+--
+data Workspace i l a = Workspace  { tag :: !i, layout :: l, stack :: Maybe (Stack a) }
+    deriving (Show, Eq)
+--     deriving (Show, Read, Eq)
+
+{-@
+data Workspace i l a = Workspace  { tag :: i, layout :: l, stack :: Maybe (UStack a) }
+  @-}
+
+{-@ measure getStackWorkspace :: (Workspace i l a) -> (Maybe(Stack a))
+    getStackWorkspace(Workspace t l stack) = stack @-}
+
+{-@ predicate WorkspaceElt N W =
+  ((isJust (getStackWorkspace W)) && (StackElt N (fromJust (getStackWorkspace W)))) @-}
+
+-- | A structure for window geometries
+data RationalRect = RationalRect Rational Rational Rational Rational
+    deriving (Show, Read, Eq)
+
+-- |
+-- A stack is a cursor onto a window list.
+-- The data structure tracks focus by construction, and
+-- the master window is by convention the top-most item.
+-- Focus operations will not reorder the list that results from
+-- flattening the cursor. The structure can be envisaged as:
+--
+-- >    +-- master:  < '7' >
+-- > up |            [ '2' ]
+-- >    +---------   [ '3' ]
+-- > focus:          < '4' >
+-- > dn +----------- [ '8' ]
+--
+-- A 'Stack' can be viewed as a list with a hole punched in it to make
+-- the focused position. Under the zipper\/calculus view of such
+-- structures, it is the differentiation of a [a], and integrating it
+-- back has a natural implementation used in 'index'.
+--
+data Stack a = Stack { focus  :: !a        -- focused thing in this set
+                     , up     :: [a]       -- clowns to the left
+                     , down   :: [a] }     -- jokers to the right
+     deriving (Show, Eq)
+-- LIQUID      deriving (Show, Read, Eq)
+{-@ predicate IsTagInStackSet T ST = 
+    ((( (T = (getTag (getWorkspaceScreen (getCurrentScreen ST))))
+     )) || ((
+      (Set_mem T (getTagScreens (getVisible ST)))
+    ) || (false)))
+  @-}
+
+--       (Set_mem T (getTagScreens (getVisible ST)))
+{-@ view :: (Eq s, Eq i) 
+         => t:i 
+         -> st: {v:(StackSet i l a s sd) | true}
+         -> {v:StackSet i l a s sd|((IsTagInStackSet t st) => (IsCurrentTag t v))} @-}
+view :: (Eq s, Eq i) => i -> StackSet i l a s sd -> StackSet i l a s sd
+view i s
+    | i == currentTag s = s  -- current
+
+    | Just x <- findTagInScreen i (visible s)
+    -- if it is visible, it is just raised
+    = s { current = x, visible = current s : L.deleteBy (equating screen) x (visible s) }
+
+--     | Just x <- findTagInWorkspace i (hidden  s) -- must be hidden then
+    -- if it was hidden, it is raised on the xine screen currently used
+--     = s { current = (current s) { workspace = x }
+--         , hidden = workspace (current s) : L.deleteBy (equating tag) x (hidden s) }
+
+--     | otherwise = s -- not a member of the stackset
+
+  where equating f = \x y -> f x == f y
+
+{-@ findTagInScreen :: (Eq i) 
+         => t:i 
+         -> s:([Screen i l a sid sd])
+         -> {v:(Maybe (Screen i l a sid sd)) | ( ((isJust v) =>  (t = (getTag (getWorkspaceScreen (fromJust v))))))}
+  @-}
+findTagInScreen :: (Eq i) => i -> [Screen i l a sid sd] -> Maybe (Screen i l a sid sd)
+findTagInScreen i []     = Nothing
+findTagInScreen i (x:xs) 
+  | i == (tag (workspace x)) = Just x
+  | otherwise                = findTagInScreen i xs
+
+{-@ findTagInWorkspace :: (Eq i) 
+         => t:i 
+         -> [Workspace i l a] 
+         -> {v:(Maybe (Workspace i l a)) | ((isJust v) => (t = (getTag (fromJust v))))}
+  @-}
+findTagInWorkspace :: (Eq i) => i -> [Workspace i l a] -> Maybe (Workspace i l a)
+findTagInWorkspace i []     = Nothing
+findTagInWorkspace i (x:xs) 
+  | i == (tag x) = Just x
+  | otherwise    = findTagInWorkspace i xs
+
+{-@ qview :: x:(Workspace i l a) -> {v:(Screen i l a sid sd)|(getWorkspaceScreen v) = x} @-}
+qview :: Workspace i l a -> Screen i l a sid sd 
+qview = undefined
+
+{-@ qview1 :: x:(Screen i l a sid sd) -> {v:(StackSet i l a sid sd)|(getCurrentScreen v) = x} @-}
+qview1 :: Screen i l a sid sd -> StackSet i l a sid sd 
+qview1 = undefined
+
+{-@ qview2 :: x:([Workspace i l a]) -> {v:(StackSet i l a sid sd)|(getHidden v) = x} @-}
+qview2 :: [Workspace i l a] -> StackSet i l a sid sd 
+qview2 = undefined
+
+{-@ qview3 :: x:([Screen i l a sid sd]) -> {v:(StackSet i l a sid sd)|(getVisible v) = x} @-}
+qview3 :: [Screen i l a sid sd] -> StackSet i l a sid sd 
+qview3 = undefined
+
+{-@ 
+qview4 :: x : (Screen i l a sid sd)
+       -> y : ([Screen i l a sid sd])
+       -> z : Workspace i l a
+       -> {v:(StackSet i l a sid sd)|(stackSetElts v) = 
+         (Set_cup (Set_cup (screenElts x) (screensElts y)) 
+                   (workspaceElts z))}
+@-}
+qview4 :: (Screen i l a sid sd)
+       -> [Screen i l a sid sd]
+       -> Workspace i l a
+       -> StackSet i l a sid sd
+qview4 = undefined
+
+    -- 'Catch'ing this might be hard. Relies on monotonically increasing
+    -- workspace tags defined in 'new'
+    --
+    -- and now tags are not monotonic, what happens here?
+
+-- |
+-- Set focus to the given workspace.  If that workspace does not exist
+-- in the stackset, the original workspace is returned.  If that workspace is
+-- 'hidden', then display that workspace on the current screen, and move the
+-- current workspace to 'hidden'.  If that workspace is 'visible' on another
+-- screen, the workspaces of the current screen and the other screen are
+-- swapped.
+
+{-@ measure getTagWorkspace :: (Workspace i l a) -> (Data.Set.Set i)
+    getTagWorkspace(Workspace t l s) = (Set_sng t)
+  @-}
+
+{-@ measure getTagScreen :: (Screen i l a sid sd) -> (Data.Set.Set i)
+    getTagScreen(Screen w s sd) = (getTagWorkspace w)
+  @-}
+
+{-@ measure getTagScreens :: ([(Screen i l a sid sd)]) -> (Data.Set.Set i)
+    getTagScreens([])   = {v | (?(Set_emp v))}
+    getTagScreens(x:xs) = (Set_cap (getTagScreen x) (getTagScreens xs))
+  @-}
+
+
+{-@ currentTag :: s: StackSet i l a s sd -> {v:i|(IsCurrentTag v s)} @-}
+currentTag :: StackSet i l a s sd -> i
+currentTag = tag . workspace . current
+
+-- LIQUID : qualifier missing for currentTag
+{-@ qcurrentTag :: s:(StackSet i l a s sd) 
+                -> {v:(Workspace i l a) | v = (getWorkspaceScreen (getCurrentScreen s))} @-}
+qcurrentTag :: StackSet i l a s sd -> Workspace i l a 
+qcurrentTag = workspace . current
+
+
diff --git a/tests/todo/SYB_Literals.hs b/tests/todo/SYB_Literals.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/SYB_Literals.hs
@@ -0,0 +1,125 @@
+{-@ LIQUID "--no-case-expand" @-}
+{-# LANGUAGE LambdaCase, DeriveDataTypeable, OverloadedStrings, GeneralizedNewtypeDeriving #-}
+
+import qualified Data.Map as Map
+import qualified Data.Generics as SYB
+import Data.String
+import Text.PrettyPrint
+
+-- Syntax
+
+newtype Var = Var String
+  deriving (Eq, Ord, Show, SYB.Data, SYB.Typeable, IsString)
+
+newtype Con = Con String
+  deriving (Eq, Ord, Show, SYB.Data, SYB.Typeable, IsString)
+
+type Alts = [(Con, [Var], Expr)]
+
+data Expr
+  = EVar Var
+  | ELam Var Expr
+  | EApp Expr Var
+  | ELet [(Var, Expr)] Expr
+  | ECon Con [Var]
+  | ECase Expr Alts
+  deriving (Eq, Ord, Show, SYB.Data, SYB.Typeable)
+
+instance IsString Expr where
+  fromString = EVar . fromString
+
+isValue :: Expr -> Bool
+isValue = \case
+  ELam {} -> True
+  ECon {} -> True
+  _ -> False
+
+-- Abstract machine
+type Heap = Map.Map Var Expr
+type Stack = [StackItem]
+data StackItem
+  = StackUpdate Var
+  | StackVar Var
+  | StackAlts Alts
+  deriving (Show, SYB.Data, SYB.Typeable)
+data Machine = Machine Heap Expr Stack
+  deriving (Show)
+
+step :: Machine -> Machine
+step (Machine heap e stack)
+  -- Lookup
+  | EVar x <- e =
+      let m = heap Map.! x
+      in Machine heap m (StackUpdate x : stack)
+  -- Update
+  | isValue e, StackUpdate v : stack' <- stack =
+      Machine (Map.insert v e heap) e stack'
+  -- Unwind
+  | EApp m x <- e = Machine heap m (StackVar x : stack)
+  -- Subst
+  | ELam x m <- e, StackVar y : stack' <- stack =
+      Machine heap (subst (Map.singleton x y) e) stack'
+  -- Case
+  | ECase m alts <- e = Machine heap m (StackAlts alts : stack)
+  -- Branch
+  | ECon con xs <- e, StackAlts alts : stack' <- stack =
+      let [(boundVars, body)] = [(boundVars, body) | (con', boundVars, body) <- alts, con == con']
+          e' = subst (Map.fromList $ zip boundVars xs) body
+      in Machine heap e' stack'
+  -- Letrec
+  | ELet binds body <- e = Machine (Map.union (Map.fromList binds) heap) body stack
+
+subst :: Map.Map Var Var -> Expr -> Expr
+subst sm = \case
+  EVar x | Just y <- Map.lookup x sm -> EVar y
+  e@(ELam z body) -> ELam z (subst (Map.delete z sm) body)
+  e -> SYB.gmapT (SYB.mkT $ subst sm) e
+
+initMachine :: Expr -> Machine
+initMachine e = Machine Map.empty e []
+
+isFinished :: Machine -> Bool
+isFinished (Machine _ e stack) = isValue e && null stack
+
+run :: Machine -> Machine
+run m
+  | isFinished m = m
+  | otherwise = run $ step m
+
+-- Pretty-printing
+ppVar (Var x) = text x
+ppCon (Con x) = text x
+ppExpr :: Expr -> Doc
+ppExpr = ppExpr' False
+ppExpr' :: Bool -> Expr -> Doc
+ppExpr' p e =
+  let maybeParens = if p then parens else id in
+  case e of
+    EVar x -> ppVar x
+    ELam x body -> maybeParens $
+      text "λ" <> ppVar x <> text "." <> ppExpr' False body
+    EApp a b -> ppExpr' False a <+> ppVar b
+    ECon con xs -> sep $ ppCon con : map ppVar xs
+    ELet binds body ->
+      vcat
+        [ "let" $$ nest 2 (vcat (punctuate semi (map (\(v,e) -> ppVar v <+> hang "=" 2 (ppExpr e)) binds)))
+        , "in" $$ nest 2 (ppExpr body)
+        ]
+    ECase e alts ->
+      let ppAlt (con, vars, body) =
+            ppCon con <+> sep (map ppVar vars) <+> "->" <+> ppExpr body
+      in text "case" <+> ppExpr e <+> "of" $$ nest 2 (vcat (map ppAlt alts))
+
+-- Some object-language programs
+nil, cons :: Expr
+nil = ECon "nil" []
+cons = ELam "x" $ ELam "y" $ ECon "cons" ["x", "y"]
+append = ELet [("append", appendBind)] "append"
+  where
+    appendBind =
+      ELam "a" $ ELam "b" $ ECase "a"
+        [("nil", [], "b")
+        ,("cons", ["x", "xs"],
+          ELet [("r", "append" `EApp` "xs" `EApp` "b")]
+            (cons `EApp` "x" `EApp` "r"))
+        ]
diff --git a/tests/todo/SearchTree.hs b/tests/todo/SearchTree.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/SearchTree.hs
@@ -0,0 +1,157 @@
+-- ISSUE: 
+-- This file takes nearly a MINUTE when automatic-instances is off,
+-- and FOREVER when automatic-instances is on.
+
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--higherorder"                         @-}
+{-@ LIQUID "--totality"                            @-}
+
+{- LIQUID "--automatic-instances=liquidinstances" @-}
+
+module SearchTree where
+
+import Language.Haskell.Liquid.ProofCombinators
+import Prelude hiding (max)
+
+-- | Options -------------------------------------------------------------------
+
+{-@ data Option a = None | Some a @-}
+data Option a = None | Some a
+
+-- | Maps ----------------------------------------------------------------------
+
+{-@ data Map [size] k v =
+      Leaf
+    | Node { mKey   :: k
+           , mVal   :: v
+           , mLeft  :: Map k v
+           , mRigsize :: Map k v }
+  @-}
+
+data Map k v
+  = Leaf
+  | Node k v (Map k v) (Map k v)
+
+{-@ measure size @-}
+{-@ size :: Map k v -> Nat @-}
+size :: Map k v -> Int
+size Leaf           = 0
+size (Node k v l r) = 1 + size l + size r     -- TODO: silly termination error
+
+{-@ invariant {v:Map k v | 0 <= size v } @-}
+
+-- | Map Operations ------------------------------------------------------------
+
+{-@ reflect get @-}
+
+get :: (Ord k) => k -> Map k v -> Option v
+get key Leaf           = None
+get key (Node k v l r)
+  | key == k           = Some v
+  | key <  k           = get key l
+  | otherwise          = get key r
+
+
+{-@ reflect put @-}
+
+put :: (Ord k) => k -> v -> Map k v -> Map k v
+put key val Leaf       = Node key val Leaf Leaf
+put key val (Node k v l r)
+  | key == k           = Node key val l r
+  | key <  k           = Node k v (put key val l) r
+  | otherwise          = Node k v l (put key val r)
+
+-- | Map Laws ------------------------------------------------------------------
+
+{-@ thmGetEq :: (Ord k) => key:k -> val:v -> m:Map k v ->
+      { get key (put key val m) = Some val }
+  @-}
+thmGetEq :: (Ord k) => k -> v -> Map k v -> Proof
+thmGetEq key val Leaf =   get key (put key val Leaf)
+                      ==. get key (Node key val Leaf Leaf)
+                      ==. Some val
+                      *** QED
+
+thmGetEq key val (Node k v l r)
+  | key == k          =   get key (put key val (Node k v l r))
+                      ==. get key (Node key val l r)
+                      ==. Some val
+                      *** QED
+
+  | key <  k          =   get key (put key val (Node k v l r))
+                      ==. get key (Node k v (put key val l) r)    -- THIS LINE IS NEEDED
+                      ==. get key (put key val l)
+                          ? thmGetEq key val l
+                      ==. Some val
+                      *** QED
+
+  | otherwise         =   get key (put key val (Node k v l r))
+                      ==. get key (Node k v l (put key val r))    -- THIS LINE IS NEEDED
+                      ==. get key (put key val r)
+                          ? thmGetEq key val r
+                      ==. Some val
+                      *** QED
+
+{-@ thmGetNeq :: (Ord k) => k1:k -> k2:{k | k1 /= k2} -> v2:v -> m:Map k v ->
+      { get k1 (put k2 v2 m) = get k1 m }
+  @-}
+thmGetNeq :: (Ord k) => k -> k -> v -> Map k v -> Proof
+thmGetNeq k1 k2 v2 Leaf
+  | k1 < k2             =   get k1 (put k2 v2 Leaf)
+                        ==. get k1 (Node k2 v2 Leaf Leaf)
+                        ==. get k1 Leaf
+                        *** QED
+
+  | otherwise           =   get k1 (put k2 v2 Leaf)
+                        ==. get k1 (Node k2 v2 Leaf Leaf)
+                        ==. get k1 Leaf
+                        *** QED
+
+thmGetNeq k1 k2 v2 (Node k v l r)
+  | k1 <  k, k <  k2    =   get k1 (put k2 v2 (Node k v l r))
+                        ==. get k1 (Node k v l (put k2 v2 r))
+                        ==. get k1 (Node k v l r)
+                        *** QED
+
+  | k1 <  k, k == k2    =   get k1 (put k2 v2 (Node k v l r))
+                        ==. get k1 (Node k v2 l r)
+                        ==. get k1 (Node k v l r)
+                        *** QED
+
+  | k1 == k, k <  k2    =   get k1 (put k2 v2 (Node k v l r))
+                        ==. get k1 (Node k v l (put k2 v2 r))
+                        ==. get k1 (Node k v l r)
+                        *** QED
+
+
+  | k2 <  k, k <  k1    =   get k1 (put k2 v2 (Node k v l r))
+                        ==. get k1 (Node k v (put k2 v2 l) r)
+                        ==. get k1 r
+                        ==. get k1 (Node k v l r)
+                        *** QED
+
+  | k2 <  k, k == k1    =   get k1 (put k2 v2 (Node k v l r))
+                        ==. get k1 (Node k v (put k2 v2 l) r)
+                        ==. get k1 (Node k v l r)
+                        *** QED
+
+  | k2 == k, k < k1     =   get k1 (put k2 v2 (Node k v l r))
+                        ==. get k1 (Node k v2 l r)
+                        ==. get k1 (Node k v l r)
+                        *** QED
+
+  | k1 < k, k2 < k      =   get k1 (put k2 v2 (Node k v l r))
+                        ==. get k1 (Node k v (put k2 v2 l) r)
+                        ==. get k1 (put k2 v2 l)
+                            ? thmGetNeq k1 k2 v2 l
+                        ==. get k1 l
+                        ==. get k1 (Node k v l r)
+                        *** QED
+
+  | k < k1, k < k2      =   get k1 (put k2 v2 (Node k v l r))
+                        ==. get k1 (Node k v l (put k2 v2 r))
+                        ==. get k1 (put k2 v2 r)
+                            ? thmGetNeq k1 k2 v2 r
+                        ==. get k1 r
+                        ==. get k1 (Node k v l r)
+                        *** QED
diff --git a/tests/todo/SelfRefPredicates.hs b/tests/todo/SelfRefPredicates.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/SelfRefPredicates.hs
@@ -0,0 +1,16 @@
+module Fixme where
+
+{-@ bindST :: forall <p :: s -> Prop, q :: s -> a -> s -> Prop, r :: s -> b -> s -> Prop>.
+            (xm:s<p> -> (a, s)<q xm>) 
+         -> (xbind:a ->  xk:(exists[xxxa:a].exists[xxa:s<p>].s<q xxa xxxa>) -> (b, s)<r xk>) 
+         -> xr:s<p> -> exists[xa:a]. exists[xxx:s<q xr xa>]. (b, s)<r xxx>
+ @-}
+bindST :: (s -> (a, s)) -> (a -> (s -> (b, s))) -> (s ->  (b, s))
+bindST m k s =  let (a, s') = m s in (k a) s'
+
+
+
+{-@ returnST :: forall <p :: s -> a -> s -> Prop>.
+                   xa:a -> xs:s<p v xa> -> (a,s)<p xs> @-}
+returnST :: a -> s -> (a, s)
+returnST x s = (x, s) 
diff --git a/tests/todo/Signal.hs b/tests/todo/Signal.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Signal.hs
@@ -0,0 +1,77 @@
+
+--
+-- The MoCC of Signal in Haskell (clocked)
+-- Jean-Pierre.Talpin@inria.fr 12/3/15
+--
+
+Module Signals where
+
+-- an event is (now) present with a value or (determined) absent
+
+data Event a = absent | now a
+
+-- a signal is a (non empty?) lazy list of events 
+-- type Signal a = {v: [Event a] | len(v) > 0}
+
+type Signal a = [Event a]
+
+-- the clock of a signal 
+
+measure clk :: a Signal -> Bool
+clk (absent : _) = false
+clk ((now _) : _) = true
+
+-- the value of a signal 
+
+measure val :: a Signal -> a
+val ((now v) : _) = v
+
+-- not defined if absent ... how to say that val v => clk v ?
+
+-- feedback: pre initially returns w and then the stored head of x
+-- pre's, y's and w property should be a fixpoint p
+--
+--      {-@ pre :: forall <p :: Prop>. Signal a<p> -> a<p> -> Signal a<p> @-}
+--
+-- p should contain clk x = clk pre here just true
+
+pre :: Signal a -> a -> Signal a
+pre (x as ((now v) : _) w = (now w) : pre x v
+pre (x as (absent  : _) w =  absent : pre x w
+infix pre
+
+-- synchronous sample à la Lustre
+
+{-@ sample :: x:Signal a -> y:Signal Bool -> {v:Signal a| clk v = clk x = clk y} @-}
+
+sample :: Signal a -> Signal Bool -> Signal a
+sample ((now v) : x) ((now True)  : y) = v : sample x y
+sample ((now _) : x) ((now False) : y) = absent : sample x y
+sample (absent  : x) (absent      : y) = absent : sample x y
+
+-- synchronous merge à la Lustre
+
+{-@ merge :: x:Signal Bool -> y:Signal a -> z:Signal a -> {v:Signal a| clk v = clk x = clk y = clk z} @-}
+
+merge :: Signal Bool -> Signal a -> Signal a -> Signal a
+merge ((now True)  : x) ((now v) : y) ((now _) : z) = v : merge x y z
+merge ((now False) : x) ((now _) : y) ((now v) : z) = v : merge x y z
+merge (absent      : x) (absent  : y) (absent  : z) = absent : merge x y z
+
+-- sample à la Signal
+
+{-@ when :: x:Signal a -> y:Signal Bool -> {v:Signal a| clk v = clk x and val y} @-}
+
+when :: Signal a -> Signal Bool -> Signal a
+when ((now v) : x) ((now True)  : y) = v : when x y
+when (_       : x) ((now False) : y) = absent : when x y
+when (_       : x) (absent      : y) = absent : when x y
+
+-- merge à la Signal
+
+{-@ combine :: x:Signal Bool -> y:Signal a -> z:Signal a -> {v:Signal a| clk v = clk x or clk y} @-}
+
+combine :: Signal a -> Signal a -> Signal a
+combine ((now v) : x) (_ : y) = v : combine x y 
+combine (absent  : x) (v : y) = v : combine x y
+
diff --git a/tests/todo/SortedLists.lhs b/tests/todo/SortedLists.lhs
new file mode 100644
--- /dev/null
+++ b/tests/todo/SortedLists.lhs
@@ -0,0 +1,58 @@
+\begin{code}
+module SortedLists where
+\end{code}
+
+I want to prove that in a sorted list every element is `>=` than the head:
+
+\begin{code}
+{-@ type SL a = [a]<{\x v -> x <= v}> @-}
+
+{-@ measure head :: [a] -> a
+    head (x:xs) = x
+  @-}
+\end{code}
+
+
+Turns out that to prove it I have to compose the list using `:`
+(liquidHaskell only proves `proveOK`)
+\begin{code}
+{-@ propOKA, propOKB, propBADA, propBADB, propBADC :: 
+      Ord a => xs:(SL a)  -> [{v:a|v >= (head xs)}] 
+  @-}
+propOKA, propOKB, propBADA, propBADB, propBADC :: 
+      Ord a => [a] -> [a]
+\end{code}
+
+\begin{code}
+propOKA xxs@(x:xs) = x:xs
+propOKB xxs@(x:xs) = listID xxs
+
+listID (x:xs) = (x:xs)
+listID []     = []
+\end{code}
+
+We know that both `x` and `xs` satisfy the desired property 
+but polymorphism on `:` is the way to transfer this information to the result.
+Any attempt that doesn't use this information fails:
+\begin{code}
+propBADA xxs@(x:xs) = xxs
+propBADB xxs@(x:xs) = id xxs
+propBADC xxs@(x:xs) = listID' xxs
+
+{-@ listID' :: forall <p :: a -> a -> Prop> . [a]<p> -> [a]<p> @-}
+listID' :: [a] -> [a]
+listID' (x:xs) = (x:xs)
+listID' []     = []
+\end{code}
+
+So, the following version of `merge` fails:
+
+\begin{code}
+{-@ LIQUID "--no-termination" @-}
+{-@ merge :: Ord a => (SL a) -> (SL a) -> (SL a) @-}
+merge :: Ord a => [a] -> [a] -> [a]
+merge xxs@(x:xs) yys@(y:ys)
+  | x <= y    = x : merge xs yys
+  | otherwise = y : merge xxs ys
+\end{code}
+
diff --git a/tests/todo/StateConstraints.hs b/tests/todo/StateConstraints.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/StateConstraints.hs
@@ -0,0 +1,109 @@
+module Compose where
+
+
+
+
+data ST s a = ST {runState :: s -> (a,s)}
+
+{-@ data ST s a <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop> 
+  = ST (runState :: x:s<p> -> (a<r x>, s<q x>)) @-}
+
+ {-@ runState :: forall <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop>. ST <p, q, r> s a -> x:s<p> -> (a<r x>, s<q x>) @-}
+
+
+
+{-
+cmp :: forall < pref :: s -> Prop, postf :: s -> s -> Prop
+              , pre  :: s -> Prop, postg :: s -> s -> Prop
+              , post :: s -> s -> Prop
+              , rg   :: s -> a -> Prop
+              , rf   :: s -> b -> Prop
+              , r    :: s -> b -> Prop
+              >. 
+       {xx:s<pre> -> w:s<postg xx> -> s<postf w> -> s<post xx>}
+       {ww:s<pre> -> s<postg ww> -> s<pref>}
+       (ST <pre, postg, rg> s a)
+    -> (ST <pref, postf, rf> s b)
+    -> (ST <pre, post, r> s b)
+@-}
+
+cmp :: (ST s a)
+    -> (ST s b)
+    -> (ST s b)
+
+cmp (ST g) (ST f) = ST (\x -> case g x of {(_, s) -> f s})    
+
+{-@ 
+bind :: forall < pref :: s -> Prop, postf :: s -> s -> Prop
+              , pre  :: s -> Prop, postg :: s -> s -> Prop
+              , post :: s -> s -> Prop
+              , rg   :: s -> a -> Prop
+              , rf   :: s -> b -> Prop
+              , r    :: s -> b -> Prop
+              , pref0 :: a -> Prop 
+              >. 
+       {x:s<pre> -> a<rg x> -> a<pref0>}      
+       {x:s<pre> -> y:s<postg x> -> b<rf y> -> b<r x>}
+       {xx:s<pre> -> w:s<postg xx> -> s<postf w> -> s<post xx>}
+       {ww:s<pre> -> s<postg ww> -> s<pref>}
+       (ST <pre, postg, rg> s a)
+    -> (a<pref0> -> ST <pref, postf, rf> s b)
+    -> (ST <pre, post, r> s b)
+@-}
+
+bind :: (ST s a)
+    -> (a -> ST s b)
+    -> (ST s b)
+
+bind (ST g) f = ST (\x -> case g x of {(y, s) -> (runState (f y)) s})    
+
+
+{-@ unit :: forall s a <p :: s -> Prop>. x:a -> ST <p, {\s v -> v == s}, {\s v -> x == v}> s a @-}
+unit :: a -> ST s a
+unit x = ST $ \s -> (x, s)
+
+{-@ incr :: ST <{\x -> x >= 0}, {\x v -> v = x + 1}, {\x v -> v = x}>  Nat Nat @-}
+incr :: ST Int Int
+incr = ST $ \x ->  (x, x + 1)
+
+{-@ incr' :: ST <{\x -> x >= 0}, {\x v -> v = x + 1}, {\w vw -> vw = w}>  Nat Nat @-}
+incr' :: ST Int Int
+incr' = bind incr (\x -> unit x)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/todo/Strings.hs b/tests/todo/Strings.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Strings.hs
@@ -0,0 +1,39 @@
+module DBC where
+
+import GHC.CString  -- This import interprets Strings as constants!
+
+
+import Data.Set
+{-
+bar :: () -> String 
+{- bar :: () -> {x:String | x = unpack "foo" && len x >= 0} @-}
+bar _ = "foo"
+
+
+{- prop :: {v:Bool | Prop v <=> true} @-}
+prop :: Bool
+prop = foo1 == foo2 
+  where foo1 = "foo"
+        foo2 = "foo"
+-}
+
+
+data Foo = FFFF | QQQQ deriving Eq
+
+{-@ prop2 :: {v:Bool | Prop v <=> true} @-}
+prop2 :: Bool
+prop2 = foo1 /= foo2 
+  where foo1 = FFFF
+        foo2 = QQQQ
+
+
+-- one character strings seems to crash....
+{-@ prop3 :: {v:[String] | listElts v ~~ Set_sng "x"} @-}
+prop3 :: [String]
+prop3 = ["x"]
+
+{-@ prop1 :: {v:Bool | Prop v <=> true} @-}
+prop1 :: Bool
+prop1 = foo1 /= foo2 
+  where foo1 = "foo"
+        foo2 = "bar"
diff --git a/tests/todo/SubType.hs b/tests/todo/SubType.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/SubType.hs
@@ -0,0 +1,22 @@
+module HOSubtype where
+
+{-@ foo :: f:(x:{v:Int | false} -> {v:Int | v = x}) -> () @-}
+foo    :: (Int -> Int) -> ()
+foo pf = ()
+
+test0 :: ()
+test0  = foo useless_proof
+
+{-@ generic_accept_stable ::
+                    f:(x:a -> {v:a | (v = x)}) ->
+                    ()
+                    @-}
+generic_accept_stable :: (a -> a) -> ()
+generic_accept_stable pf = ()
+
+{-@ useless_proof :: x:{v:Int | v > 0} -> {v:Int | v > 0} @-}
+useless_proof :: Int -> Int
+useless_proof _ = 5
+
+test :: ()
+test = generic_accept_stable useless_proof
diff --git a/tests/todo/SuperClassBounds.hs b/tests/todo/SuperClassBounds.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/SuperClassBounds.hs
@@ -0,0 +1,37 @@
+module Compose where
+
+import Prelude hiding (Functor, Monad)
+
+data ST s a = ST {runState :: s -> (a,s)}
+
+{-@ data ST s a <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop> 
+  = ST (runState :: x:s<p> -> (a<r x>, s<q x>)) @-}
+
+{-@ runState :: forall <p :: s -> Prop, q :: s -> s -> Prop, r :: s -> a -> Prop>. ST <p, q, r> s a -> x:s<p> -> (a<r x>, s<q x>) @-}
+
+class Functor f where
+  fmap :: (a -> b) -> f a -> f b
+
+instance Functor (ST s) where
+  fmap f (ST g) = ST (\s -> let (a, s') = g s in (f a, s'))
+
+class Functor m => Monad m where
+  (>>) :: m a -> m b -> m b
+
+instance Monad (ST s) where
+  {-@ instance Monad ST s where
+    >>  :: forall s a b  < pref :: s -> Prop, postf :: s -> s -> Prop
+              , pre  :: s -> Prop, postg :: s -> s -> Prop
+              , post :: s -> s -> Prop
+              , rg   :: s -> a -> Prop
+              , rf   :: s -> b -> Prop
+              , r    :: s -> b -> Prop
+              >. 
+       {x::s<pre>, y::s<postg x> |- b<rf y> <: b<r x>}
+       {xx::s<pre>, w::s<postg xx> |- s<postf w> <: s<post xx>}
+       {ww::s<pre> |- s<postg ww> <: s<pref>}
+       (ST <pre, postg, rg> s a)
+    -> (ST <pref, postf, rf> s b)
+    -> (ST <pre, post, r> s b)
+    @-}
+  (ST g) >>  f = ST (\x -> case g x of {(y, s) -> (runState f) s})    
diff --git a/tests/todo/T658.hs b/tests/todo/T658.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T658.hs
@@ -0,0 +1,13 @@
+-- #658, fails if you comment out test1 (and test2?)
+
+{-@ test1 :: n: {v : Int | v >= 0} -> lst: {v : [a] | n < len v} -> {v : [a] | len v = len lst - n } @-}
+test1 :: Int -> [a] -> [a]
+test1 n lst = b where (_, b) = splitAt n lst
+
+{-@ test2 :: n: {v : Int | v >= 0} -> lst: {v : [a] | n < len v} -> {v : [a] | len v = n } @-}
+test2 :: Int -> [a] -> [a]
+test2 n lst = a where (a, _) = splitAt n lst
+
+{-@ test3 :: n: {v : Int | v >= 0} -> lst: {v : [a] | n < len v} -> {v : [a] | len v = len lst } @-}
+test3 :: Int -> [a] -> [a]
+test3 n lst = a ++ b where (a, b) = splitAt n lst
diff --git a/tests/todo/T765.hs b/tests/todo/T765.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T765.hs
@@ -0,0 +1,10 @@
+-- | issue #765 we get complete gibberish for inferred types
+-- * nothing for 'gunk'
+-- * {v = 1} for `z`
+
+module Bar where
+
+{-@ bar :: Nat -> Nat @-}
+bar :: Int -> Int 
+bar z = let gunk = z + 1 
+        in gunk
diff --git a/tests/todo/T770.hs b/tests/todo/T770.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T770.hs
@@ -0,0 +1,37 @@
+{- This fails with
+
+```
+/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/lts-5.9/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.spec:43:20: Error: GHC Error
+
+43 | type FF      = {v: Bool          | not (Prop v)}
+                        ^
+
+    Not in scope: type constructor or class `Bool'
+```
+
+if we UNCOMMENT import (1) then we get the error
+
+```
+ /Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/lts-5.9/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/CString.spec:7:10: Error: GHC Error
+
+ 7 |   -> {v:[Char] | v ~~ x && len v == strLen x}
+              ^
+
+     Not in scope: type constructor or class `Char'
+```
+
+if we UNCOMMENT import (2) then we get no errors
+
+-}
+
+module Wrenn where
+
+import Prelude ()
+
+import Data.Int
+
+-- (1) import Data.Bool
+-- (2) import Data.Char
+
+incr :: Int
+incr = 1
diff --git a/tests/todo/T771.hs b/tests/todo/T771.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T771.hs
@@ -0,0 +1,20 @@
+{- This fails with the error:
+
+```
+ /Users/rjhala/research/stack/liquidhaskell/tests/todo/T771.hs:7:13: Error: Bad Type Specification
+ Wrenn.incr :: (Num a) => a -> {VV : a | VV == thing}
+     Sort Error in Refinement: {VV : a_amT | VV == thing}
+     Unbound Symbol thing
+```
+
+which is accurate, but misleading, as the *real* problem is you can't have
+binders on typeclass constraints.
+
+-}
+
+module Wrenn where
+
+{-@ incr :: thing:(Num a) => a -> {v:a | v = thing} @-}
+
+incr :: (Num a) => a -> a
+incr x = x
diff --git a/tests/todo/T772.hs b/tests/todo/T772.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T772.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
+
+module LiquidR where
+
+class R m where
+
+class (R a, R b) => UnarySubscript a b where
+  indexUnary :: a -> b -> [a]
+
+{-@ instance (R t, R u) => UnarySubscript t u where
+      indexUnary :: a:t -> b:{v:_ | 1 + 2 = 3 } -> t
+  @-}
+instance (R a, R b) => UnarySubscript a b
+
+-- Note this works:
+--   indexUnary :: a:t -> b:{v:_ | 1 + 2 = 3 } -> [t]
+
+{-@ predicate Bloop A = (size A) = 0 @-}
+
+-- UNCOMMENT; (error omitted for brevity)
+{-@ class (R t, R u, R v) => Addition t u v where
+    add :: a:t ->
+           b:u ->
+          {c:v | ArithmeticResult a b c }
+@-}
+class (R a, R b, R c) => Addition a b c | a b -> c  where
+  add  :: a -> b -> c
+  add  = unimplemented
diff --git a/tests/todo/T776.hs b/tests/todo/T776.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T776.hs
@@ -0,0 +1,28 @@
+{- | There are 2 bugs here, that have to do with `--prune-unsorted`.
+
+     1. Why is the `prod` measure being used in the generic `size`
+        function where it doesn't fit?
+
+     2. Why are we getting such a meaningless error message?!
+
+        At the very least some mention of try `prune-unsorted` ?
+
+        Can we not put in a simple check in Bare for now:
+
+        The measure `prod` is not-polymorphic, please run with --prune-unsorted.
+        
+ -}
+
+{-@ LIQUID "--prune-unsorted" @-}
+
+module LiquidR where
+
+{-@ measure size @-}
+size        :: [a] -> Int
+size []     = 0
+size (_:xs) = 1 + size xs
+
+{-@ measure prod @-}
+prod :: [Int] -> Int
+prod []     = 1
+prod (x:xs) = x + prod xs
diff --git a/tests/todo/T781.hs b/tests/todo/T781.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T781.hs
@@ -0,0 +1,88 @@
+-- | Issue 781: why the lame error message, even though we HAVE source information.
+
+{-# LANGUAGE ScopedTypeVariables #-}
+{-@ LIQUID "--no-termination" @-}
+module Class () where
+
+import Language.Haskell.Liquid.Prelude
+import Prelude hiding (sum, length, (!!), Functor(..))
+
+{- qualif Size(v:Int, xs:a): v = size xs @-}
+{- qualif Size(v:Int, xs:MList a): v = size xs @-}
+
+data MList a = Nil | Cons a (MList a)
+
+{-@ (!!) :: xs:MList a -> {v:Nat | v < size xs} -> a @-}
+(!!) :: MList a -> Int -> a
+(Cons x _)  !! 0 = x
+(Cons _ xs) !! i = xs !! (i - 1)
+
+{-@ class measure sz :: forall a. a -> Int  @-}
+
+{-@ class Sized s where
+      size :: forall a. x:s a -> {v:Nat | v = sz x}
+  @-}
+class Sized s where
+  size :: s a -> Int
+
+instance Sized MList where
+  {-@ instance measure size :: MList a -> Int
+      sz (Nil)       = 0
+      sz (Cons x xs) = 1 + sz xs
+    @-}
+  size = length
+
+{-@ length :: xs:MList a -> {v:Nat | v = sz xs} @-}
+length :: MList a -> Int
+length Nil         = 0
+length (Cons _ xs) = 1 + length xs
+
+{-@ bob :: xs:MList a -> {v:Nat | v = sz xs} @-}
+bob :: MList a -> Int
+bob = length
+
+
+instance Sized [] where
+  {-@ instance measure sz :: [a] -> Int
+      sz ([])   = 0
+      sz (x:xs) = 1 + (sz xs)
+    @-}
+  size [] = 0
+  size (_:xs) = 1 + size xs
+
+{-@ class (Sized s) => Indexable s where
+      index :: forall a. x:s a -> {v:Nat | v < sz x} -> a
+  @-}
+class (Sized s) => Indexable s where
+  index :: s a -> Int -> a
+
+
+
+instance Indexable MList where
+  index = (!!)
+
+{-@ sum :: Indexable s => s Int -> Int @-}
+sum :: Indexable s => s Int -> Int
+sum xs = go n 0
+  where
+    n = size xs
+    go (d::Int) i
+      | i < n     = index xs i + go (d-1) (i+1)
+      | otherwise = 0
+
+
+{-@ sumMList :: MList Int -> Int @-}
+sumMList :: MList Int -> Int
+sumMList xs = go max 0
+  where
+    max = size xs
+    go (d::Int) i
+      | i < max   = index xs i + go (d-1) (i+1)
+      | otherwise = 0
+
+
+{-@ x :: {v:MList Int | (sz v) = 3}  @-}
+x :: MList Int
+x = 1 `Cons` (2 `Cons` (3 `Cons` Nil))
+
+foo = liquidAssert $ size (Cons 1 Nil) == size [1]
diff --git a/tests/todo/T791.hs b/tests/todo/T791.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T791.hs
@@ -0,0 +1,23 @@
+import Prelude hiding (null, head, tail, notElem, empty)
+
+import Data.Vector hiding (singleton, empty)
+import qualified Data.Vector.Mutable as M
+import qualified Data.Vector as V
+import Control.Monad.Primitive
+
+{-@ measure mvlen :: forall a. (MVector s a) -> Int @-}
+{-@ invariant {mv:MVector s a | 0 <= mvlen mv } @-}
+{-@ assume Data.Vector.Mutable.new :: PrimMonad m => n:Nat -> m ({vs:MVector (PrimState m) a | mvlen vs == n }) @-}
+
+{-@ minimal :: v:Vector a -> Vector a @-}
+minimal :: Vector a -> Vector a
+minimal v = create (M.new n >>= (\x -> go n x))
+  where
+    {-@ n :: {n:Nat | n == vlen v} @-}
+    n = V.length v
+    {-@ go :: n:Nat -> {mv:MVector (PrimState m) a | mvlen mv == n} -> m (MVector (PrimState m) a) @-}
+    go :: (PrimMonad m) => Int -> MVector (PrimState m) a -> m (MVector (PrimState m) a)
+    go _ mv = pure mv
+
+{-@ qualif EqLen(v:MVector s a, x:Vector b): (mvlen v == vlen x) @-}
+{-@ qualif MVLen(v:MVector s a, n:Int): (mvlen v == n) @-}
diff --git a/tests/todo/T791a.hs b/tests/todo/T791a.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T791a.hs
@@ -0,0 +1,12 @@
+import Prelude hiding (null, head, tail, notElem, empty)
+
+import Data.Vector hiding (singleton, empty)
+import qualified Data.Vector.Mutable as M
+import Control.Monad.Primitive
+import qualified Data.Vector as V
+
+minimal1 mickey = create (M.new 0 >>= go)
+
+{-@ go :: {v:MVector (PrimState m) a | false } -> m (MVector (PrimState m) a) @-}
+go :: (PrimMonad m) => MVector (PrimState m) a -> m (MVector (PrimState m) a)
+go mv = pure mv
diff --git a/tests/todo/T870.hs b/tests/todo/T870.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T870.hs
@@ -0,0 +1,28 @@
+
+-- https://github.com/ucsd-progsys/liquidhaskell/issues/870 
+-- the following succeeds normally, but fails if we switch on the higher-order 
+
+{- LIQUID "--higherorder" @-}
+
+import Prelude hiding (splitAt)
+
+
+data Vec a = Nil | Cons a (Vec a)
+
+{-@ invariant {v:Vec a | 0 <= vlen v} @-}
+
+{-@ measure vlen :: Vec a -> Int
+    vlen Nil         = 0
+    vlen (Cons x xs) = 1 + vlen xs
+  @-}
+
+
+{-@ splitAt :: n:Nat
+            -> a:{Vec t|vlen a >= n}
+            -> {b:(Vec t, Vec t)|vlen (snd b) = vlen a - n && n = vlen (fst b)} @-}
+
+splitAt :: Int -> Vec a -> (Vec a, Vec a)
+splitAt 0         as  = (Nil, as)
+splitAt n (Cons a as) = let (b1, b2) = splitAt (n - 1) as
+                        in (Cons a b1, b2)
+
diff --git a/tests/todo/T995.hs b/tests/todo/T995.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T995.hs
@@ -0,0 +1,42 @@
+{-@ LIQUID "--exact-data-con" @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+module Basics
+  ( Peano(..)
+  , toNat
+  ) where
+
+import           Prelude (Char, Int)
+import qualified Prelude
+import           Language.Haskell.Liquid.ProofCombinators
+
+--------------------------------------------------------------------------------
+-- | Booleans ------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+{-@ data Bool = True | False @-}
+data Bool = True | False
+
+--------------------------------------------------------------------------------
+-- | Peano ---------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+{-@ data Peano [toNat] = O | S Peano @-}
+data Peano = O | S Peano
+
+{-@ measure toNat @-}
+{-@ toNat :: Peano -> Nat @-}
+toNat :: Peano -> Int
+toNat O     = 0
+toNat (S n) = 1 Prelude.+ toNat n
+
+{-@ reflect natEven @-}
+natEven :: Peano -> Bool
+natEven O         = True
+natEven (S O)     = False
+natEven (S (S n)) = natEven n
+
+-- fails
+{-@ test_Even4 :: { natEven (S (S (S (S O)))) == True } @-}
+test_Even4 :: Proof
+test_Even4 = trivial
diff --git a/tests/todo/T996.hs b/tests/todo/T996.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T996.hs
@@ -0,0 +1,35 @@
+{-@ LIQUID "--exact-data-con"                      @-}
+
+module Induction where
+
+import qualified Prelude
+import           Prelude (Char, Int)
+import Language.Haskell.Liquid.ProofCombinators
+
+{-@ data Peano [toNat] = O | S Peano @-}
+data Peano = O | S Peano
+
+{-@ measure toNat @-}
+{-@ toNat :: Peano -> Nat @-}
+toNat :: Peano -> Int
+toNat O     = 0
+toNat (S n) = 1 Prelude.+ toNat n
+
+{-@ reflect plus @-}
+plus :: Peano -> Peano -> Peano
+plus O     n = n
+plus (S m) n = S (plus m n)
+
+{-@ data Bool = True | False @-}
+data Bool = True | False
+
+{-@ reflect even @-}
+even :: Peano -> Bool
+even O         = True
+even (S O)     = False
+even (S (S n)) = even n
+
+{-@ thmPlusCom :: n:Peano -> m:Peano -> { plus n m == plus m n} @-}
+thmPlusCom :: Peano -> Peano -> Proof
+thmPlusCom O     m = trivial
+thmPlusCom (S n) m = [ thmPlusCom n m ] *** QED
diff --git a/tests/todo/T997.hs b/tests/todo/T997.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T997.hs
@@ -0,0 +1,28 @@
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--higherorder"                         @-}
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+
+{-@ data List [llen] = Nil | Cons {lTl :: List} @-}
+data List = Nil | Cons List
+
+{-@ measure llen @-}
+{-@ llen :: List -> Nat @-}
+llen :: List -> Int
+llen Nil      = 0
+llen (Cons t) = 1 + llen t
+
+{-@ reflect sz @-}
+{-@ sz :: List -> Nat @-}
+sz :: List -> Int
+sz Nil      = 0
+sz (Cons t) = 1 + sz t
+
+-- THIS IS OK
+{-@ ok :: { llen ((Cons Nil)) == 1 } @-}
+ok = ()
+
+-- THIS IS NOT
+{-@ fails :: { sz (Cons Nil) == 1 } @-}
+fails = ()
+ 
diff --git a/tests/todo/T997a.hs b/tests/todo/T997a.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/T997a.hs
@@ -0,0 +1,33 @@
+{-@ LIQUID "--exact-data-con"                      @-}
+{-@ LIQUID "--higherorder"                         @-}
+{-@ LIQUID "--totality"                            @-}
+{-@ LIQUID "--automatic-instances=liquidinstances" @-}
+{-@ LIQUID "--diff"                                @-}
+
+module Lists where
+
+import Language.Haskell.Liquid.ProofCombinators
+
+
+{-@ data List [llen] = Nil | Cons {lHd :: Int, lTl :: List} @-}
+data List = Nil | Cons Int List
+
+{-@ measure llen @-}
+{-@ llen :: List -> Nat @-}
+llen :: List -> Int
+llen Nil        = 0
+llen (Cons h t) = 1 Prelude.+ llen t
+
+{-@ reflect beqList @-}
+beqList :: List -> List -> Bool
+beqList (Cons x xs) (Cons y ys) = x == y && beqList xs ys
+beqList Nil         Nil         = True
+beqList Nil         (Cons y ys) = False
+beqList (Cons x xs) Nil         = False
+
+
+{-@ testBeqList2 :: { beqList (Cons 1 Nil) (Cons 1 Nil) } @-}
+testBeqList2  = trivial
+
+{-@ testBeqList3 :: { beqList (Cons 1 (Cons 2 Nil)) (Cons 1 (Cons 3 Nil)) == False } @-}
+testBeqList3  = trivial
diff --git a/tests/todo/Times.hs b/tests/todo/Times.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Times.hs
@@ -0,0 +1,61 @@
+{-@ LIQUID "--no-termination" @-}
+module Times where
+
+import Foreign
+
+{-@ times :: forall <p :: Int -> a -> Prop>. 
+             n:Nat -> a<p 0> -> (m:{Nat | m <= n} -> a<p m> -> a<p (m+1)>) -> a<p n>
+  @-}
+times :: Int -> a -> (Int -> a -> a) -> a
+times n z f = go 0 z
+  where
+    go m z | m == n    = z
+           | otherwise = go (m+1) (f m z)
+
+{-@ predicate Btwn Lo N Hi = Lo <= N && N < Hi @-}
+{-@ predicate Uint8 N = Btwn 0 N 256 @-}
+
+
+{-@ assume addUint8 :: x:{Int | Uint8 x} -> y:{Int | Uint8 y && Uint8 (x+y)}
+                    -> {v:Int | Uint8 v && v = x + y}
+  @-}
+addUint8 :: Int -> Int -> Int
+addUint8 = (+)
+
+{-@ ten :: {v:Int | Uint8 v} @-}
+ten = times 10 0 (\n x -> add1 x)
+
+{-@ gt10 :: x:Int -> {v:Bool | Prop v <=> x >= 10} @-}
+gt10 :: Int -> Bool
+gt10 x = x >= 10
+
+{-@ add1 :: x:{Int | Btwn 0 x 255} -> {v:Int | Uint8 v && v = x + 1} @-}
+add1 x = addUint8 x 1
+
+{-@ qualif TimesTwo(v:int, x:int): v = x * 2 @-}
+{-@ qualif PlusTwo(v:int, x:int): v = x + 2 @-}
+
+timesM :: Int -> (Int -> IO ()) -> IO ()
+timesM n f = go 0
+  where
+    go m | m == n    = return ()
+         | otherwise = f m >> go (m+1)
+
+{-@ tenM :: Ptr <{\x -> x = 0}> Int -> IO () @-}
+tenM :: Ptr Int -> IO ()
+tenM p = timesM 10 $ \i -> do
+           x <- peek p
+           poke p $ x `addUint8` 1
+
+{-@ data Ptr a <p :: a -> Prop> = GHC.Ptr.Ptr (x::GHC.Base.Addr#) @-}
+
+{-@ poke :: forall <p :: a -> Prop>. (Storable a)
+         => Ptr <p> a
+         -> a<p>
+         -> (IO ())
+  @-}
+
+{-@ peek :: forall <p :: a -> Prop>. (Storable a)
+         => (Ptr <p> a)
+         -> (IO (a<p>))
+  @-}
diff --git a/tests/todo/TreeMap.hs b/tests/todo/TreeMap.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/TreeMap.hs
@@ -0,0 +1,55 @@
+module Trees where
+
+{- LIQUID "--no-termination" @-}
+
+import Language.Haskell.Liquid.Prelude
+
+data Tree a = Leaf a | Node [Tree a] 
+
+{-@ data Tree a = Leaf (xx :: a) | Node (subtrees :: {vv : [{v:Tree a | size v < sizes vv}] | true}) @-}
+
+{-@ measure size  @-}
+{-@ measure sizes @-}
+
+{-@ invariant {v: [Tree a] | sizes v >= size (head v)} @-}
+{-@ invariant {v: [Tree a] | sizes v >= 0}             @-}
+{-@ invariant {v: Tree a   | size v >= 0}              @-}
+
+{-@ measure head :: [a] -> a 
+    head (x:xs) = x
+  @-}
+
+{-@ size           :: x:Tree a -> {v:Nat | v = size x} / [size x, 0] @-}
+size :: Tree a -> Int
+size (Leaf _)  = 1
+size (Node xs) = 1 + sizes xs
+
+{-@ sizes         :: xs:[Tree a] -> {v:Nat | v = sizes xs} / [sizes xs, len xs] @-}
+sizes :: [Tree a ] -> Int
+sizes []      = 0
+sizes (t:ts)  = size t + sizes ts
+
+{- data Tree a [sizes] @-}
+
+
+{-@ tmap :: _ -> tt:Tree a -> Tree b / [size tt, 1, 0] @-}
+-- tmap f tt = case tt of
+tmap f (Leaf x) = Leaf (f x)
+tmap f tt@(Node ts) = Node (goo f (Node ts) (lemmasize ts (Node ts)))
+
+{-@ lemmasize :: ts:[Tree a] -> tt:{v:Tree a | ts = subtrees v} -> [{v:Tree a | size v < size tt}] @-}
+lemmasize :: [Tree a] -> Tree a  -> [Tree a]
+lemmasize _ (Node (t:ts)) = t : lemmasize ts (Node ts)
+
+
+{-@ goo :: (a -> b) -> tt:Tree a -> ts:[{v: Tree a | size v < size tt}] -> [Tree b] / [size tt, 0, len ts] @-}
+goo :: (a -> b) -> Tree a -> [Tree a] -> [Tree b]
+goo f tt [] = []
+goo f tt (t:ts) = tmap f t : goo f tt ts
+
+{-@ qualif SZ(v:Tree a, x:Tree a): size v < size x @-}
+
+{-@ qual :: xs:[Tree a] -> {v:Tree a | size v = 1 + sizes xs} @-}
+qual :: [Tree a] -> Tree a
+qual = undefined
+
diff --git a/tests/todo/TreeMap0.hs b/tests/todo/TreeMap0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/TreeMap0.hs
@@ -0,0 +1,54 @@
+module Trees where
+
+{-@ LIQUID "--no-termination" @-}
+
+import Language.Haskell.Liquid.Prelude
+
+data Tree a = Leaf a | Node [Tree a] 
+
+{-@ data Tree a = Leaf (xx :: a) | Node (yy :: {mickeymouse : [{v:Tree a | size v < sizes mickeymouse}] | true}) @-}
+
+{-@ measure size  @-}
+{-@ measure sizes  @-}
+
+{-@ invariant {v: [Tree a] | sizes v >= 0  } @-}
+{-@ invariant {v: Tree a | size v >= 0  } @-}
+
+{-@ size           :: t:Tree a -> {v:Nat | v = size t} / [size t, 0] @-}
+size :: Tree a -> Int
+size (Leaf _)  = 1
+size (Node xs) = 1 + sizes xs
+
+{-@ sizes         :: xs:[Tree a] -> {v:Nat | v = sizes xs} / [sizes xs, len xs] @-}
+sizes :: [Tree a ] -> Int
+sizes []      = 0
+sizes (t:ts)  = size t + sizes ts
+
+{-@ test1 :: tt:Tree a -> Tree a / [size tt] @-}
+test1 tt = case tt of
+             Leaf x  -> Leaf x
+             Node ts -> liquidAssert (sizes ts < size tt) $ Node (goo tt ts)
+
+{-@ goo :: tt:Tree a -> [{v: Tree a | size v < size tt}] -> [Tree a] @-}
+goo :: Tree a -> [Tree a] -> [Tree a]
+goo _ []      = []
+goo tt (t:ts) = t : goo tt ts
+
+{-@ test2 :: tt:Tree a -> Tree a / [size tt] @-}
+test2 tt = case tt of
+             Leaf x  -> Leaf x
+             Node ts -> liquidAssert (sizes ts < size tt) $ Node (moo ts ts)
+
+{-@ moo :: ts:[Tree a] -> [{v: Tree a | size v < sizes ts}] -> [Tree a] @-}
+moo :: [Tree a] -> [Tree a] -> [Tree a]
+moo _  []      = []
+moo ts (t:ts') = t : moo ts ts'
+
+
+
+{-@ qualif SZ(v:a, x:b): size v < size x @-}
+
+foo tt = case tt of
+           Leaf x  -> () 
+           Node ts -> liquidAssert (1 + sizes ts == size tt) ()
+
diff --git a/tests/todo/TypeError.hs b/tests/todo/TypeError.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/TypeError.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
+
+
+{-@ LIQUID "--autoproofs"      @-}
+{-@ LIQUID "--totality"        @-}
+{-@ LIQUID "--exact-data-cons" @-}
+module Append where
+
+import Axiomatize
+import Equational
+import Prelude hiding (return, (>>=))
+
+
+data L a = N 
+
+-- | Definition of the list monad
+
+{-@ axiomatize return @-}
+$(axiomatize
+  [d| return :: a -> L a
+      return x = N
+    |])
+
+{-@ axiomatize append @-}
+$(axiomatize
+  [d| append :: L a -> L a -> L a
+      append N ys        = ys
+    |])
+
+{-@ axiomatize bind @-}
+$(axiomatize
+  [d| bind :: L a -> (a -> L a) -> L a
+      bind N        f = N
+    |])
+
+
+-- | Right Identity m >>= return ≡  m
+{-@ prop_right_identity :: Eq a => L a -> {v:Proof | bind N return == N } @-}
+prop_right_identity :: Eq a => L a -> Proof
+prop_right_identity N =  refl (bind N return) `by` pr1 
+  where
+    e1  = bind N return
+    pr1 = axiom_bind_N return
+    e2  = N
+
+
+
+-- | List definition
+
+
+instance Eq a => Eq (L a) where
+  N == N                 = True
+
+{-@ data L [llen] @-}
+{-@ invariant {v: L a | llen v >= 0} @-}
+
+{-@ measure llen @-}
+llen :: L a -> Int
+llen N = 0
diff --git a/tests/todo/TypeFun.hs b/tests/todo/TypeFun.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/TypeFun.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE DataKinds    #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE FunctionalDependencies    #-}
+{-# LANGUAGE MultiParamTypeClasses    #-}
+{-# LANGUAGE RankNTypes   #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+module TypeFun where
+
+{-@ predicate Btwn Lo N Hi = Lo <= N && N < Hi @-}
+
+{-@ addUint8 :: x:_ -> y:{_ | Btwn 0 (x+y) 256} -> {v:_ | v = x + y} @-}
+addUint8 :: Int -> Int -> Int
+addUint8 = (+)
+
+{-@ double :: Def (Arr (Cons {v:Int | Btwn 0 v 128} Nil) Int) @-}
+double = proc body
+  where 
+    {-@ body :: {v:Int | Btwn 0 v 128} -> _ @-}
+    body x = Body $ x `addUint8` x
+
+type Arr = (:->)
+
+type Cons = '(:)
+type Nil = '[]
+
+data Proc k = [k] :-> k
+
+proc :: forall proc impl. IvoryProcDef proc impl => impl -> Def proc
+proc x = Def
+
+data Def (proc :: Proc *)
+  = Def
+
+data Body r = Body r
+
+class IvoryProcDef (proc :: Proc *) impl | impl -> proc where
+
+instance IvoryProcDef ('[] :-> a) (Body a) where
+
+instance IvoryProcDef (args :-> ret) k
+      => IvoryProcDef ((a ': args) :-> ret) (a -> k) where
+
diff --git a/tests/todo/TypeSynonyms.hs b/tests/todo/TypeSynonyms.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/TypeSynonyms.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE DataKinds #-} -- Type level straings
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE KindSignatures #-}
+
+module Foo where
+import GHC.TypeLits
+
+{-@ foo :: x:Int -> {v:Int | v > x } @-}
+
+foo :: x  ::: Int -> (v ::: Int || v > x) 
+bar :: xs ::: [a] -> (v ::: Int || v == length xs)
+
+
+
+bar xs = length xs
+foo x = x + 1
+
+infixr 7 :::
+infixr 6 ||
+
+type x ::: t = t
+type t || p  = t
+type x > y   = Bool
+type x == y   = Bool
+-- type (x :: Symbol) > (y :: Symbol)   = Bool
+
diff --git a/tests/todo/UnboundSigs.hs b/tests/todo/UnboundSigs.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/UnboundSigs.hs
@@ -0,0 +1,9 @@
+module DependeTypes where
+
+
+
+data MI s
+  = Small { mi_input :: String  }
+
+
+{-@ Small :: forall s. {v:String | s == v } -> MI s @-}
diff --git a/tests/todo/UnfoldDataCons.hs b/tests/todo/UnfoldDataCons.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/UnfoldDataCons.hs
@@ -0,0 +1,10 @@
+
+{-@ boo :: [{v:a | false }] -> {v:[a] | len v == 0 } @-}
+boo :: [a] -> [a]
+boo []     = [] 
+boo (x:xs) = (x:xs)
+
+
+{-@ foo :: [{v:a | false }] -> {v:[a] | len v == 0 } @-}
+foo :: [a] -> [a]
+foo x = x 
diff --git a/tests/todo/Unsound.hs b/tests/todo/Unsound.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Unsound.hs
@@ -0,0 +1,7 @@
+module Unsound where
+
+{-@ assume magic :: {v:() | false} @-}
+magic :: ()
+magic = undefined 
+
+bar = head []
diff --git a/tests/todo/UnsoundMeasure.hs b/tests/todo/UnsoundMeasure.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/UnsoundMeasure.hs
@@ -0,0 +1,16 @@
+module Blank where
+
+-- This example is unsound due to non-recursive definition of llen 
+
+import Language.Haskell.Liquid.Prelude
+
+data L a = N | C a (L a)
+
+
+{-@ measure llen :: (L a) -> Int 
+    llen(N) = 0
+    llen(C x xs) = 1 + (llen (C x xs))
+  @-}
+  
+foo :: L a -> L a
+foo (C _ xs) = liquidAssert (0==1) xs
diff --git a/tests/todo/Until.hs b/tests/todo/Until.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/Until.hs
@@ -0,0 +1,52 @@
+{-@ LIQUID "--no-termination" @-}
+module Until where
+
+import Prelude hiding (until)
+
+{-@ until :: forall <p :: a -> Prop, i :: a -> Prop>.
+             (a:a<i> -> {v:Bool | Prop v <=> papp1 p a})
+          -> ({v:a<i> | not (papp1 p v)} -> a<i>)
+          -> a<i>
+          -> a<p>
+  @-}
+until :: (a -> Bool) -> (a -> a) -> a -> a
+until p f = go
+  where
+    go x | p x          = x
+         | otherwise    = go (f x)
+
+{-@ predicate Btwn Lo N Hi = Lo <= N && N < Hi @-}
+{-@ predicate Uint8 N = Btwn 0 N 256 @-}
+
+
+{-@ assume addUint8 :: x:{Int | Uint8 x} -> y:{Int | Uint8 y && Uint8 (x+y)}
+                    -> {v:Int | Uint8 v && v = x + y}
+  @-}
+addUint8 :: Int -> Int -> Int
+addUint8 = (+)
+
+{-@ ten :: {v:Int | Uint8 v && v >= 10} @-}
+ten = until (\x -> gt10 x) (\x -> add1 x) 0 
+
+{-@ gt10 :: x:Int -> {v:Bool | Prop v <=> x >= 10} @-}
+gt10 :: Int -> Bool
+gt10 x = x >= 10
+
+{-@ add1 :: x:{Int | Btwn 0 x 255} -> {v:Int | Uint8 v && v = x +1} @-}
+add1 x = addUint8 x 1
+
+
+{-@ untilMono :: (x:{Int | Uint8 x && x <= 10} -> {v:Bool | Prop v <=> x >= 10})
+              -> ({v:Int | Uint8 v && v < 10} -> {v:Int | Uint8 v && v <= 10})
+              -> {v:Int | Uint8 v && v <= 10}
+              -> {v:Int | Uint8 v && v >= 10}
+  @-}
+untilMono :: (Int -> Bool) -> (Int -> Int) -> Int -> Int
+-- untilMono p f x = until p f x
+untilMono p f = go
+  where
+    go x | p x          = x
+         | otherwise    = go (f x)
+
+{-@ tenMono :: {v:Int | Uint8 v && v >= 10} @-}
+tenMono = untilMono gt10 add1 0 
diff --git a/tests/todo/UseBound.hs b/tests/todo/UseBound.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/UseBound.hs
@@ -0,0 +1,8 @@
+module UseBound where
+
+import ImportBound
+
+-- This crashes because the type of `by` has a bound Chain that
+-- is unknown at import
+
+myby = by
diff --git a/tests/todo/VerifiedNum.hs b/tests/todo/VerifiedNum.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/VerifiedNum.hs
@@ -0,0 +1,31 @@
+module VerifiedNum where
+
+-- Hiding numeric operations, because they get by default translated to SMT equivalent
+import Prelude hiding (Num(..))
+
+import qualified Prelude as Prelude 
+
+class VerifiedNum a where 
+  (+) :: a -> a -> a 
+  (-) :: a -> a -> a 
+
+{-@ predicate BoundInt X = 0 < X + 10000 && X < 10000 @-}
+
+{-@ type OkInt N = {v:Int | BoundInt N => v == N} @-}
+
+{-@ type ValidInt = {v:Int | BoundInt v} @-}
+
+
+instance VerifiedNum Int where
+{-@ instance VerifiedNum Int where 
+    + :: x:Int -> y:Int -> OkInt {x + y} 
+  @-}
+	x + y = (Prelude.+) x y  
+{-@ instance VerifiedNum Int where 
+    - :: x:Int -> y:Int -> OkInt {x - y} 
+  @-}
+	x - y = (Prelude.-) x y  
+
+
+
+
diff --git a/tests/todo/WBL-crash.hs b/tests/todo/WBL-crash.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/WBL-crash.hs
@@ -0,0 +1,177 @@
+
+-----------------------------------------------------------------------
+-- Weight-Biased Leftist Heap, verified using LiquidHaskell -----------
+-----------------------------------------------------------------------
+-- ORIGINAL SOURCE ----------------------------------------------------
+-----------------------------------------------------------------------
+-- Copyright: 2014, Jan Stolarek, Politechnika Łódzka                --
+--                                                                   --
+-- License: See LICENSE file in root of the repo                     --
+-- Repo address: https://github.com/jstolarek/dep-typed-wbl-heaps-hs --
+--                                                                   --
+-- Basic implementation of weight-biased leftist heap. No proofs     --
+-- and no dependent types. Uses a two-pass merging algorithm.        --
+-----------------------------------------------------------------------
+
+{-@ LIQUID "--no-termination" @-}
+
+module WBL where
+
+type Priority = Int
+
+type Rank     = Int
+
+type Nat      = Int
+
+data Heap a   = Empty | Node { pri   :: a
+                             , rnk   :: Rank
+                             , left  :: Heap a
+                             , right :: Heap a
+                             }
+
+{-@ data Heap a <q :: a -> a -> Prop> =
+      Empty | Node { pri   :: a
+                   , rnk   :: Nat
+                   , left  :: {v: Heap<q> (a<q pri>) | ValidRank v}
+                   , right :: {v: Heap<q> (a<q pri>) | ValidRank v}
+                   }
+ @-}
+
+{-@ predicate ValidRank V = okRank V && realRank V = rank V  @-}
+{-@ type PHeap a = {v:OHeap a | ValidRank v}                 @-}
+{-@ type OHeap a = Heap <{\root v -> root <= v}> a           @-}
+
+{-@ measure okRank @-}
+okRank :: Heap a -> Bool
+okRank (Empty)        = True
+okRank (Node p k l r) = realRank l >= realRank r && k == 1 + realRank l + realRank r
+
+{-@ measure realRank @-}
+realRank :: Heap a -> Int
+realRank (Empty)        = 0
+realRank (Node p k l r) = 1 + realRank l + realRank r
+
+{-@ measure rank @-}
+{-@ rank :: h:PHeap a -> {v:Nat | v = realRank h} @-}
+rank Empty          = 0
+rank (Node _ r _ _) = r
+
+
+-- Creates heap containing a single element with a given Priority
+{-@ singleton :: a -> PHeap a  @-}
+singleton p = Node p 1 Empty Empty
+
+-- Note [Two-pass merging algorithm]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--
+-- We use a two-pass implementation of merging algorithm. One pass,
+-- implemented by merge, performs merging in a top-down manner. Second
+-- one, implemented by makeT, ensures that rank invariant of weight
+-- biased leftist tree is not violated after merging.
+--
+-- Notation:
+--
+--  h1, h2 - heaps being merged
+--  p1, p2 - priority of root element in h1 and h2
+--  l1     - left  subtree in the first  heap
+--  r1     - right subtree in the first  heap
+--  l2     - left  subtree in the second heap
+--  r2     - right subtree in the second heap
+--
+-- Merge function analyzes four cases. Two of them are base cases:
+--
+--    a) h1 is empty - return h2
+--
+--    b) h2 is empty - return h1
+--
+-- The other two cases form the inductive definition of merge:
+--
+--    c) priority p1 is higher than p2 - p1 becomes new root, l1
+--       becomes its one child and result of merging r1 with h2
+--       becomes the other child:
+--
+--               p1
+--              /  \
+--             /    \
+--            l1  r1+h2 -- here "+" denotes merging
+--
+--    d) priority p2 is higher than p2 - p2 becomes new root, l2
+--       becomes its one child and result of merging r2 with h1
+--       becomes the other child.
+--
+--               p2
+--              /  \
+--             /    \
+--            l2  r2+h1
+--
+-- Note that there is no guarantee that rank of r1+h2 (or r2+h1) will
+-- be smaller than rank of l1 (or l2). To ensure that merged heap
+-- maintains the rank invariant we pass both childred - ie. either l1
+-- and r1+h2 or l2 and r2+h1 - to makeT, which creates a new node by
+-- inspecting sizes of children and swapping them if necessary.
+
+-- makeT takes an element (Priority) and two heaps (trees). It
+-- constructs a new heap with element at the root and two heaps as
+-- children. makeT ensures that WBL heap rank invariant is maintained
+-- in the newly created tree by reversing left and right subtrees when
+-- necessary (note the inversed r and l in the False alternative of
+-- case expression).
+{-@ makeT   :: p:a -> h1:PHeap {v:a | p <= v} -> h2:PHeap {v:a | p <= v}
+            -> {v:PHeap a | realRank v = 1 + realRank h1 + realRank h2} @-}
+makeT p l r = case rank l >= rank r of
+                True  ->  Node p (1 + rank l + rank r) l r
+                False ->  Node p (1 + rank l + rank r) r l
+
+-- merge combines two heaps into one. There are two base cases and two
+-- recursive cases - see [Two-pass Merging algorithm]. Recursive cases
+-- call makeT to ensure that rank invariant is maintained after
+-- merging.
+{-@ merge :: (Ord a) => h1:PHeap a -> h2:PHeap a -> {v:PHeap a | realRank v = realRank h1 + realRank h2}  @-}
+merge Empty h2 = h2
+merge h1 Empty = h1
+merge h1@(Node p1 k1 l1 r1) h2@(Node p2 k2 l2 r2) = case p1 < p2 of
+  True  -> makeT p1 l1 (merge r1 (Node p2 k2 l2 r2))
+  False -> makeT p2 l2 (merge (Node p1 k1 l1 r1) r2)
+
+-- Inserting into a heap is performed by merging that heap with newly
+-- created singleton heap.
+{-@ insert :: (Ord a) => a -> PHeap a -> PHeap a @-}
+insert p h = merge (singleton p) h
+
+-- findMin returns element with highest priority, ie. root
+-- element. Here we encounter first serious problem: we can't return
+-- anything sensible for empty node.
+{-@ findMin :: PHeap a -> a @-}
+findMin Empty          = undefined
+findMin (Node p _ _ _) = p
+
+-- and write a safer version of findMinM
+{-@ findMinM :: PHeap a -> Maybe a @-}
+findMinM Empty          = Nothing
+findMinM (Node p _ _ _) = Just p
+
+-- deleteMin removes the element with the highest priority by merging
+-- subtrees of a root element. Again the case of empty heap is
+-- problematic. We could give it semantics by returning Empty, but
+-- this just doesn't feel right. Why should we be able to remove
+-- elements from an empty heap?
+{-@ deleteMin :: (Ord a) => PHeap a -> PHeap a @-}
+deleteMin Empty          = undefined -- should we insert empty?
+deleteMin (Node _ _ l r) = merge l r
+
+-- As a quick sanity check let's construct some examples. Here's a
+-- heap constructed by inserting following priorities into an empty
+-- heap: 3, 0, 1, 2.
+{-@ heap :: PHeap Int @-}
+heap = insert (2 :: Int)
+      (insert 1
+      (insert 0
+      (insert 3 Empty)))
+
+-- Example usage of findMin
+findMinInHeap :: Priority
+findMinInHeap = findMin heap
+
+-- Example usage of deleteMin
+deleteMinFromHeap :: Heap Int
+deleteMinFromHeap = deleteMin heap
diff --git a/tests/todo/When.hs b/tests/todo/When.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/When.hs
@@ -0,0 +1,17 @@
+module When (foo, fooOk) where
+
+{-@ assume div :: x:_ -> y:{_ | y /= 0} -> _ @-}
+
+{- when :: b:Bool -> {v:_ | ???} -> _ -}
+when b x = if b then x else return ()
+
+
+foo :: Int -> IO ()
+foo x = when (x > 0) $ print (1 `div` x)
+
+{-@ whenT :: b:_ -> ({v:_ | Prop b} -> _) -> _ @-}
+whenT :: Bool -> (() -> IO ()) -> IO ()
+whenT b k = if b then k () else return ()
+
+fooOk :: Int -> IO ()
+fooOk x = whenT (x > 0) $ \() -> print (1 `div` x)
diff --git a/tests/todo/absref-crash0.hs b/tests/todo/absref-crash0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/absref-crash0.hs
@@ -0,0 +1,34 @@
+{-@ LIQUID "--short-names"    @-}
+module Foo where
+
+data List a = N | C a (List a)
+
+
+{-@ crashC :: forall a b <p :: List a -> b -> Prop>.
+               x:a -> xs: List a 
+               -> ys:b<p (C x xs)> 
+               -> b<p ys>                            @-}
+crashC :: a -> List a -> b -> b 
+crashC = undefined
+
+
+{-@ crashN :: forall a b <p :: List a -> b -> Prop>.
+               x:a -> xs: List a 
+               -> ys:b<p N> 
+               -> b<p ys>                            @-}
+crashN :: a -> List a -> b -> b 
+crashN = undefined
+
+
+-- Currenlty the liternals are grapped only from the haskell code
+-- and not from the types. 
+-- Thus the above two specifications cash unless
+-- N and C appear in the Haskell code, as below 
+
+{-
+cons :: a -> List a -> List a
+cons = C 
+
+nil :: List a 
+nil = N
+-}
diff --git a/tests/todo/alias.hs b/tests/todo/alias.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/alias.hs
@@ -0,0 +1,12 @@
+module Foo where
+
+{-@ type Pos = {v:Int | 0 < v} @-}
+type Pos = Int
+
+-- If I add the explicit @-annotation then of course liquid marks this program
+-- unsafe, but it would be nice if we could get the same result (i.e. unsafe)
+-- directly by using the Haskell type. (This would be a step towards
+-- @spindakin's summer project using TF).
+
+incr   :: Pos -> Pos
+incr x = x - 1
diff --git a/tests/todo/aliasConst.hs b/tests/todo/aliasConst.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/aliasConst.hs
@@ -0,0 +1,9 @@
+module Foo where
+
+-- TODO: Expressions inside applications of type and predicate aliases.
+
+{-@ predicate Rng Lo V Hi = (Lo <= V && V < Hi) @-}
+
+{-@ bog :: {v:Int | (Rng 0 v 10)} @-}
+bog :: Int
+bog = 5
diff --git a/tests/todo/aliasError.hs b/tests/todo/aliasError.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/aliasError.hs
@@ -0,0 +1,16 @@
+module Foo where
+
+-- TODO: return a civilized error message about the line number with the
+-- problematic predicate application, instead of just a groan about safeZip
+-- failing.
+
+{-@ predicate Rng Lo V Hi = (Lo <= V && V < Hi) @-}
+{-@ type NNN a b  = {v:[(a, b)] | 0 <= 0} @-}
+
+{-@ bog :: {v:Int | (Rng 0 10 11)} @-}
+bog :: Int
+bog = 5
+
+{-@ foo :: NNN Int @-}
+foo :: [(Int, Char)]
+foo = [(1, 'c')]
diff --git a/tests/todo/appCheck.hs b/tests/todo/appCheck.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/appCheck.hs
@@ -0,0 +1,21 @@
+module Foo where
+
+import Language.Haskell.Liquid.Prelude
+
+prop :: Bool
+prop = undefined
+
+{-@ app :: forall <p :: a -> Prop, q :: a -> Prop>. 
+   {x:a<q> -> a<p> -> {v:a | v <= x}}
+   {a<q> -> a<p>}
+   Num a => (a<p> -> b) -> a<q> -> b @-}
+app :: Num a => (a -> b) -> a -> b
+app f x = if prop then app f (x+1) else f x
+
+
+{-@ check :: Ord a => x:a ->  {v:a | x <= v} -> () @-}
+check :: Ord a => a ->  a -> ()
+check x y | x <= y = ()
+          | otherwise = liquidError ""
+
+main i = app (check i) i       
diff --git a/tests/todo/apply.hs b/tests/todo/apply.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/apply.hs
@@ -0,0 +1,17 @@
+module StateMonad where
+
+data ST a = S (Int -> (a, Int))
+{-@ data ST a <p1 :: old:Int -> a -> Prop,
+               p2 :: old:Int -> Int -> Prop> 
+     = S (x::(state:Int -> (a<p1 state>, Int<p2 state>))) 
+  @-}
+
+
+{-@
+apply :: forall a <p1 :: old:Int -> a -> Prop, 
+                   p2 :: old:Int -> Int -> Prop>.
+          instate:(ST a) <p1, p2> -> x:Int -> (a<p1 x>, Int<p2 x>)
+  @-}
+apply :: ST a -> Int -> (a, Int)
+apply (S f) x = f x
+
diff --git a/tests/todo/baderror.hs b/tests/todo/baderror.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/baderror.hs
@@ -0,0 +1,9 @@
+module DataBase   where
+
+import qualified Data.Set
+
+{-@ (\\) :: Eq a => forall<p :: a -> Prop>. xs:[a<p>] -> ys:[a] -> {v:[a<p>] | (listElts v)  = (Set_dif (listElts xs) (listElts ys))} @-}
+(\\) :: Eq a => [a] -> [a] -> [a]
+[]     \\ _ = []
+(x:xs) \\ ys = if x `elem` ys then xs \\ ys else x:(xs \\ ys)
+
diff --git a/tests/todo/baffled.hs b/tests/todo/baffled.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/baffled.hs
@@ -0,0 +1,140 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{- LIQUID "--diffcheck"     @-}
+
+module AVL where
+
+main :: IO ()
+main = return ()
+
+-- Source: https://gist.github.com/gerard/109729
+
+-- | PORTED from: http://docs.camlcity.org/docs/godipkg/4.00/godi-ocaml/lib/ocaml/std-lib/map.ml
+
+
+data AVL k v = Leaf
+             | Node { key :: k
+                    , val :: v
+                    , lt  :: AVL k v
+                    , rt  :: AVL k v
+                    , ht  :: Int }
+               deriving (Show, Eq)
+
+{-@ data AVL k v = Leaf
+                 | Node { key :: k
+                        , val :: v
+                        , lt  :: AVLL k v key
+                        , rt  :: AVLR k v key
+                        , ht  :: AVLH lt rt 
+                        }
+  @-}
+
+{-@ type AVLL k v Key    = AVL {k:k | k < Key} v             @-}
+{-@ type AVLR k v Key    = AVL {k:k | Key < k} v             @-}
+{-@ type AVLH L R        = {v:Nat   | Ht v L R && Bal L R 2} @-}
+{-@ type AVLN k v N      = {v:AVL k v | tht v = N}           @-}
+
+{-@ predicate LeMax1 V X Y = V <= if X >= Y then 1+X else 1+Y   @-}
+{-@ predicate EqMax1 V X Y = V = if X >= Y then 1+X else 1+Y   @-}
+{-@ predicate Diff X Y N = 0 <= X - Y + N && X - Y <= N      @-}
+{-@ predicate Bal L R N  = Diff (tht L) (tht R) N      @-}
+{-@ predicate Ht V L R   = EqMax1 V (tht L) (tht R)      @-}
+
+{-@ invariant {v:AVL k v | 0 <= ht v} @-}
+
+{-@ measure tht          :: AVL k v -> Int
+    tht (Leaf)           = 0
+    tht (Node k v l r z) = if (tht l >= tht r) then (1 + tht l) else (1 + tht r)
+  @-}
+
+{-@ height              :: t:_ -> {v:Nat | v = tht t} @-}
+height (Leaf)           = 0 :: Int
+height (Node k v l r z) = if (height l >= height r) then (1 + height l) else (1 + height r)
+ 
+                        
+empty = Leaf
+
+{-@ ht :: t:AVL k v -> {v:Nat | v = tht t}  @-}
+
+{-@ create     :: key:k -> v -> l:AVLL k v key -> r:{AVLR k v key | Bal l r 2} -> {v:AVL k v | Ht (tht v) l r} @-}
+create k v l r = Node k v l r (nodeHeight l r) 
+
+{-@ nodeHeight :: l:_ -> r:_ -> {v:Nat | Ht v l r} @-}
+nodeHeight l r = h
+  where
+   h           = if hl >= hr then hl + 1 else hr + 1
+   hl          = height l
+   hr          = height r 
+
+{-@ singleton  :: k -> v -> AVLN k v 1 @-}
+singleton k v  = Node k v Leaf Leaf 1 
+
+{-@ fox :: k -> v -> thing:AVL k v -> {v: AVL k v | tht thing - 1 <= tht v && tht v <= tht thing + 1} @-}
+fox :: k -> v -> AVL k v -> AVL k v
+fox key val tree = error "z"
+
+
+{-@ predicate HtDiff S T D = (tht S) - (tht T) == D @-}
+
+{-@ add :: k -> v -> t:AVL k v -> {v: AVL k v | (tht t - 1 <= tht v || tht t - 2 = tht v) && tht v <= tht t + 1} @-}
+add k' v' t@(Node k v l r h)
+  -- RJ: This case is obviously fine
+  
+  | k' == k     = Node k' v' l r h  
+
+  -- RJ: Maddeningly, this case is fine too
+                  
+--   | k' <  k     = let mickey = fox k' v' l
+--                   in
+--                      bal k v mickey r   
+  -- NV: This is fine
+--   | k < k', height l >= height r = let mouse = fox k' v' r  in
+--                                   bal k v l mouse 
+
+  -- RJ: HEREHEREHERE this is the problem (I GIVE UP)
+  -- here it might be the case that 'tht t - 2 = tht v'
+     | k < k', height l < height r = let mouse = fox k' v' r  in
+                                   bal k v l mouse 
+
+
+
+add k' v' Leaf  = singleton k' v'
+
+{-@ bal         :: key:k -> v -> l:AVLL k v key -> r:{AVLR k v key | Bal l r 3} -> {v:AVL k v  | tht l <= tht v && tht r <= tht v && (tht l >= tht r => tht v <= 1 + tht l) && (tht r >= tht l => tht v <= 1 + tht r) } @-}
+bal :: k -> v -> AVL k v -> AVL k v -> AVL k v
+bal k v l r 
+  | hl > hr + 2 = balL   k v l r
+  | hr > hl + 2 = balR   k v l r 
+  | otherwise   = create k v l r 
+  where
+    hl          = height l
+    hr          = height r
+
+
+{-@ balL :: k:_ -> v:_ -> l:AVLL k v k -> r:AVLN {v:_ | k < v} v {(tht l) - 3} -> {v:AVL k v | tht l <= tht v && tht v <= 1 + tht l} @-}    
+balL k v l@(Node lk lv ll lr _) r
+  | height ll >= height lr = let tmp = create k v lr r in lAssert (height tmp <= height l) $ create lk lv ll tmp
+  | otherwise              = case lr of
+                               Node lrk lrv lrl lrr _ -> create lrk lrv (create lk lv ll lrl) (create k v lrr r)
+                               Leaf                   -> die  "all done" 
+
+-- balL k v (Node lk lv ll lr@(Node lrk lrv lrl lrr _) _) r
+--   | height ll < height lr  = create lrk lrv (create lk lv ll lrl) (create k v lrr r)
+
+{-@ balR :: k:_ -> v:_ -> l:AVLL k v k -> r:AVLN {v:_ | k < v} v {(tht l) + 3} -> {v: AVL k v | tht r <= tht v && tht v <= 1 + tht r} @-}    
+balR k v l r@(Node rk rv rl rr _) 
+  | height rr >= height rl = create rk rv (create k v l rl) rr
+  | otherwise              = case rl of 
+                              Node rlk rlv rll rlr _ -> create rlk rlv (create k v l rll) (create rk rv rlr rr)
+                              Leaf                   -> die "all done"
+                              
+-- balR k v l r@(Node rk rv rl@(Node rlk rlv rll rlr _) rr _)
+--   | height rr < height rl  = create rlk rlv (create k v l rll) (create rk rv rlr rr) 
+
+{-@ die :: {v:String | false } -> a @-}
+die x = error x
+
+{-@ lAssert    :: {v:Bool | Prop v} -> a -> a @-}
+lAssert True x = x
+lAssert _    z = z
+
diff --git a/tests/todo/binsearch.hs b/tests/todo/binsearch.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/binsearch.hs
@@ -0,0 +1,32 @@
+module BinSearch where
+
+import Language.Haskell.Liquid.Prelude
+import Data.Vector
+
+foobar = div
+
+gobble n lo hi 
+  | hi < lo   = True 
+  | otherwise = let mid = (hi - lo) `div` 2 
+                in assert (mid >= 0)
+
+z = gobble n 0 n
+    where n = choose 0
+
+
+--binarySearch :: (Ord a) => Vector a -> a -> Int -> Int -> Maybe Int
+--binarySearch haystack needle lo hi
+--  | hi < lo	        = Nothing
+--  | pivot > needle	= binarySearch haystack needle lo (mid - 1)
+--  | pivot < needle	= binarySearch haystack needle (mid + 1) hi
+--  | otherwise	    = Just mid
+--  where mid	    = lo + ((hi - lo) `div` 2)
+--        pivot	= haystack ! mid
+--
+--runBinarySearch haystack needle 
+--  = binarySearch haystack needle 0 (Data.Vector.length haystack)
+--
+--pos = runBinarySearch vec val
+--  where vec = fromList [0..siz]
+--        siz = choose 0
+--        val = choose 1
diff --git a/tests/todo/boolparse.hs b/tests/todo/boolparse.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/boolparse.hs
@@ -0,0 +1,19 @@
+module Goo where
+
+
+-- It would be nice to parse the below: 
+
+{-@ type BoolP P = {v:Bool | Prop v <=> P} @-}
+
+-- The below works fine (obviously)
+{- type BoolP P = {v:Bool | true } @-}
+
+-- We can then write things like:
+
+{-@ inline gt @-}
+gt :: Int -> Int -> Bool
+gt x y = x > y
+
+{-@ isNat :: x:Int -> BoolP {gt x 0} @-}
+isNat :: Int -> Bool
+isNat x = x > 0
diff --git a/tests/todo/cases.hs b/tests/todo/cases.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/cases.hs
@@ -0,0 +1,8 @@
+module Zoo where
+
+import Language.Haskell.Liquid.Prelude
+
+data L a = C a (L a) | N | C2 a a (L a)
+
+bob (C x _) = x
+bob _       = liquidError "asdasd"
diff --git a/tests/todo/cont.hs b/tests/todo/cont.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/cont.hs
@@ -0,0 +1,25 @@
+module Cont (funkyId, funkyIds) where
+
+------------------------------------------------------------------------------------------
+{-@ funkyId :: x:Int -> {v:Int | v = x} @-}
+funkyId :: Int -> Int
+funkyId n = cont (\_ -> n)
+
+
+{-@ cont :: forall <p :: Int -> Prop>. (() -> Int<p>) -> Int<p> @-}
+cont :: (() -> Int) -> Int
+cont f = f () 
+------------------------------------------------------------------------------------------
+
+{-@ funkyIds :: a -> n:Int -> {v:[a] | (len v) = n} @-}
+funkyIds :: a -> Int -> [a]
+funkyIds y n = conts y (\_ -> n)
+
+{-@ conts :: forall <p :: Int -> Prop>. a -> (() -> Int<p>) -> exists z:Int<p>. {v:[a] | z = (len v)} @-}
+{-@ conts :: forall <p :: Int -> Prop>. a -> (() -> Int<p>) -> {v:[a] | (p (len v))} @-}
+conts :: a -> (() -> Int) -> [a] 
+conts x f = clone (f ()) x 
+
+{-@ clone :: n:Int -> a -> {v:[a] | (len v) = n} @-}
+clone :: Int -> a -> [a]
+clone = undefined
diff --git a/tests/todo/contra.hs b/tests/todo/contra.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/contra.hs
@@ -0,0 +1,68 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+
+module Foo () where
+
+import Language.Haskell.Liquid.Prelude (liquidAssert)
+import Data.IORef
+
+{-@ type Upto N = {v:Nat | v < N} @-} 
+
+{-@ job :: IO () @-}
+job = do
+  p <- newIORef (0 :: Int)
+  writeIORef p 10
+  v <- readIORef p
+  liquidAssert (v == 0) $ return ()
+  
+{-@ bob :: Nat -> IO () @-}
+bob n = do
+  t <- newIO (n+1) (\_ -> 0)
+  setIO t 0 100
+  r <- getIO t 0
+  liquidAssert (r == 0) $ return ()
+
+ 
+data IOArr a = IOA { size :: Int
+                   , pntr :: IORef (Arr a)
+                   }
+
+data Arr a   = A { alen :: Int
+                 , aval :: Int -> a
+                 }
+
+
+
+{-@ data IOArr a <p :: Int -> a -> Prop>
+      = IOA { size :: Nat
+            , pntr :: IORef ({v:Arr<p> a | alen v = size})
+            }
+  @-}
+
+
+{-@ data Arr a <p :: Int -> a -> Prop>
+             = A { alen :: Nat 
+                 , aval :: i:Upto alen -> a<p i>
+                 }
+  @-}
+
+
+
+{-@ newIO :: forall <p :: Int -> a -> Prop>.
+               n:Nat -> (i:Upto n -> a<p i>) -> IO ({v: IOArr<p> a | size v = n})
+  @-}
+newIO :: Int -> (Int -> a) -> IO (IOArr a)
+newIO n f = undefined
+
+{-@ getIO :: forall <p :: Int -> a -> Prop>.
+              a:IOArr<p> a -> i:Upto (size a) -> IO (a<p i>)
+  @-}
+getIO :: IOArr a -> Int-> IO a
+getIO a@(IOA sz p) i = undefined
+
+{-@ setIO :: forall <p :: Int -> a -> Prop>.
+              a:IOArr<p> a -> i:Upto (size a) -> a<p i> -> IO ()
+  @-}
+setIO :: IOArr a -> Int -> a -> IO ()
+setIO a@(IOA sz p) i v = undefined
+
diff --git a/tests/todo/decr.hs b/tests/todo/decr.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/decr.hs
@@ -0,0 +1,127 @@
+-- | The below gives a reasonable error message when
+--   we REMOVE the liquid signature (with the termination metric)
+--   but gives an incomprehensible "termination error" otherwise.
+--   # Issue 1. Why?!
+--
+-- | The above error goes away if you give an explicit HS type
+--   signature, which causes a different GHC core term to be analyzed.
+--   I suppose this is because the refined-type is for the top-level
+--   binder, not the inner-letrec. BUT THEN, we should produce
+--   THE SAME ERROR as if there was NO refined-signature AND add to
+--   the error message, "Please make sure you add a HS type signature too"
+
+module Blank  where
+
+{-@ spacePrefix :: _ -> s:_ -> _ / [len s] @-}
+
+-- spacePrefix :: String -> String -> Bool
+spacePrefix str (c:cs)
+  | isSpace c   = spacePrefix str cs
+  | otherwise   = take (length str) (c:cs) == str
+spacePrefix _ _ = False
+
+isSpace :: Char -> Bool
+isSpace = undefined
+
+
+{- This is GHC core _without_ the signature:
+[ Blank.spacePrefix :: [GHC.Types.Char] -> [GHC.Types.Char] -> GHC.Types.Bool
+ [LclIdX, Str=DmdType]
+ Blank.spacePrefix =
+   let {
+     $dEq_a16t :: GHC.Classes.Eq [GHC.Types.Char]
+     [LclId, Str=DmdType]
+     $dEq_a16t =
+       GHC.Classes.$fEq[] @ GHC.Types.Char GHC.Classes.$fEqChar } in
+   letrec {
+     spacePrefix [Occ=LoopBreaker]
+       :: [GHC.Types.Char] -> [GHC.Types.Char] -> GHC.Types.Bool
+     [LclId, Str=DmdType]
+     spacePrefix =
+       \ (str :: [GHC.Types.Char]) (ds_d16X :: [GHC.Types.Char]) ->
+         case ds_d16X of lq_anf$_d172 {
+           [] ->
+             (\ _ [Occ=Dead, OS=OneShot] -> GHC.Types.False) GHC.Prim.void#;
+           : c cs ->
+             let {
+               lq_anf$_d173 :: GHC.Types.Bool
+               [LclId, Str=DmdType]
+               lq_anf$_d173 = Blank.isSpace c } in
+             case lq_anf$_d173 of lq_anf$_d174 {
+               GHC.Types.False ->
+                 (\ _ [Occ=Dead, OS=OneShot] ->
+                    let {
+                      lq_anf$_d175 :: GHC.Types.Int
+                      [LclId, Str=DmdType]
+                      lq_anf$_d175 =
+                        Data.Foldable.length
+                          @ [] Data.Foldable.$fFoldable[] @ GHC.Types.Char str } in
+                    let {
+                      lq_anf$_d176 :: [GHC.Types.Char]
+                      [LclId, Str=DmdType]
+                      lq_anf$_d176 = GHC.Types.: @ GHC.Types.Char c cs } in
+                    let {
+                      lq_anf$_d177 :: [GHC.Types.Char]
+                      [LclId, Str=DmdType]
+                      lq_anf$_d177 =
+                        GHC.List.take @ GHC.Types.Char lq_anf$_d175 lq_anf$_d176 } in
+                    GHC.Classes.== @ [GHC.Types.Char] $dEq_a16t lq_anf$_d177 str)
+                   GHC.Prim.void#;
+               GHC.Types.True -> spacePrefix str cs
+             }
+         }; } in
+   spacePrefix]
+
+ -}
+
+{- This is GHC core _with_ the signature
+
+*************** Transform Rec Expr CoreBinds *****************
+[Blank.isSpace :: GHC.Types.Char -> GHC.Types.Bool
+ [LclIdX, Str=DmdType]
+ Blank.isSpace =
+   GHC.Err.undefined @ (GHC.Types.Char -> GHC.Types.Bool),
+ $dEq_a16d :: GHC.Classes.Eq [GHC.Types.Char]
+ [LclId, Str=DmdType]
+ $dEq_a16d =
+   GHC.Classes.$fEq[] @ GHC.Types.Char GHC.Classes.$fEqChar,
+ Blank.spacePrefix [Occ=LoopBreaker]
+   :: GHC.Base.String -> GHC.Base.String -> GHC.Types.Bool
+ [LclIdX, Str=DmdType]
+ Blank.spacePrefix =
+   \ (str :: GHC.Base.String) (ds_d16D :: [GHC.Types.Char]) ->
+     case ds_d16D of lq_anf$_d16I {
+       [] ->
+         (\ _ [Occ=Dead, OS=OneShot] -> GHC.Types.False) GHC.Prim.void#;
+       : c cs ->
+         let {
+           lq_anf$_d16J :: GHC.Types.Bool
+           [LclId, Str=DmdType]
+           lq_anf$_d16J = Blank.isSpace c } in
+         case lq_anf$_d16J of lq_anf$_d16K {
+           GHC.Types.False ->
+             (\ _ [Occ=Dead, OS=OneShot] ->
+                let {
+                  lq_anf$_d16L :: GHC.Types.Int
+                  [LclId, Str=DmdType]
+                  lq_anf$_d16L =
+                    Data.Foldable.length
+                      @ [] Data.Foldable.$fFoldable[] @ GHC.Types.Char str } in
+                let {
+                  lq_anf$_d16M :: [GHC.Types.Char]
+                  [LclId, Str=DmdType]
+                  lq_anf$_d16M = GHC.Types.: @ GHC.Types.Char c cs } in
+                let {
+                  lq_anf$_d16N :: [GHC.Types.Char]
+                  [LclId, Str=DmdType]
+                  lq_anf$_d16N =
+                    GHC.List.take @ GHC.Types.Char lq_anf$_d16L lq_anf$_d16M } in
+                GHC.Classes.== @ [GHC.Types.Char] $dEq_a16d lq_anf$_d16N str)
+               GHC.Prim.void#;
+           GHC.Types.True -> Blank.spacePrefix str cs
+         }
+     };]
+*************** Slicing Out Unchanged CoreBinds *****************
+
+
+ -}
diff --git a/tests/todo/doubleError.hs b/tests/todo/doubleError.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/doubleError.hs
@@ -0,0 +1,15 @@
+-- https://github.com/ucsd-progsys/liquidhaskell/issues/427
+
+module Blank where
+
+{-@ measure myprop @-} 
+myprop :: Double -> Bool
+myprop x = (fromIntegral (floor d) - d) == 0.0
+  where d = (x / 3.0)
+
+{-@ type Mytype = {v:Double | myprop v} @-}
+type Mytype = Double
+
+{-@ ok :: Mytype @-}
+ok :: Mytype
+ok = 6.0
diff --git a/tests/todo/dyn.hs b/tests/todo/dyn.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/dyn.hs
@@ -0,0 +1,43 @@
+module Dyn where
+
+import Data.Dynamic 
+import Data.Maybe
+
+b0    = put 0 ("cat" :: String) 
+      $ put 1 (12    :: Int) 
+      $ emp
+
+ok    = 10 `plus` (get 1 b0)
+
+bad   = 10 `plus` (get 0 b0)
+
+-------------------------------------------------
+plus :: Int -> Int -> Int
+plus = (+)
+
+concat :: String -> String -> String
+concat = (++)
+-------------------------------------------------
+
+type Field   = Int
+
+newtype DBox = DB [(Field, Dynamic)]
+
+emp :: DBox 
+emp = DB []
+
+put :: (Typeable a) => Field -> a -> DBox -> DBox 
+put k v (DB b) = DB ((k, toDyn v) : b)
+
+get :: (Typeable a) => Field -> DBox -> a 
+get k (DB kvs) = ofD $ fromMaybe err $ lookup k kvs 
+  where 
+    err        = error $ "NOT FOUND" ++ show k
+
+{-@ toD :: (Typeable a) => x:a -> {v:Dyn | (tag v) = (typeRep a)} @-}
+toD :: (Typeable a) => a -> Dynamic 
+toD = toDyn 
+
+{-@ ofD :: {v:Dyn | (tag v) = (typeRep a)} -> a @-}
+ofD :: (Typeable a) => Dynamic -> a
+ofD = fromMaybe (error "DYNAMIC ERROR") . fromDynamic 
diff --git a/tests/todo/empty-or.hs b/tests/todo/empty-or.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/empty-or.hs
@@ -0,0 +1,21 @@
+module EmptyOr where
+
+import GHC.Base
+import GHC.ForeignPtr
+import GHC.Ptr
+
+{-@ updPtr :: forall <q :: Ptr a -> Prop>.
+              (z:Ptr a -> (Ptr a)<q>) -> x:ForeignPtr a
+           -> exists [p:(Ptr a)<q>].{v:ForeignPtr a | (fpLen v) = (pLen p)}
+  @-}
+updPtr :: (Ptr a -> Ptr a) -> ForeignPtr a -> ForeignPtr a
+updPtr f (ForeignPtr p c) = case f (Ptr p) of { Ptr q -> ForeignPtr q c }
+{-# INLINE updPtr #-}
+
+{-@ measure addrLen :: Addr# -> Int @-}
+{-@ measure pLen :: Ptr a -> Int
+    pLen (Ptr a) = (addrLen a)
+  @-}
+{-@ measure fpLen :: ForeignPtr a -> Int
+    fpLen (ForeignPtr a c) = (addrLen a)
+  @-}
diff --git a/tests/todo/err0.hs b/tests/todo/err0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err0.hs
@@ -0,0 +1,17 @@
+-- | Error Message Test: parse error in spec
+
+module Err0 where
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ qualif Zog(v:FooBar, x:FooBar): v = x + @-}
+
+data FooBar = Foo Int
+
+
+x = choose 0
+
+prop_abs ::  Bool
+prop_abs = if x > 0 then baz x else False
+
+baz gooberding = liquidAssertB (gooberding >= 0)
diff --git a/tests/todo/err1.hs b/tests/todo/err1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err1.hs
@@ -0,0 +1,26 @@
+-- | Error Message Test: ghc error
+
+module Err1 where
+
+import Language.Haskell.Liquid.Prelude
+
+toss :: Boo 
+toss = (choose 0) > 10
+
+prop_abs :: Bool
+prop_abs = if toss 
+             then (if toss then liquidAssertB toss else False) 
+             else False
+
+
+foo :: Int -> Int
+foo x = (liquidAssert (x > 0) x) + 1
+
+goo = foo 12
+
+incr :: Int -> Int
+incr zzz = zzz + 1
+
+zoo = incr 29
+
+
diff --git a/tests/todo/err10.hs b/tests/todo/err10.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err10.hs
@@ -0,0 +1,11 @@
+{--! run liquid with no-termination -}
+
+module Intro where
+
+import Language.Haskell.Liquid.Prelude  (liquidAssert)
+
+-- doesn't work with WEB demo (just says "ERROR" with no message...
+--
+{-@ Prelude.head :: {v:[a] | false} -> a @-}
+
+bob z = head z
diff --git a/tests/todo/err11.hs b/tests/todo/err11.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err11.hs
@@ -0,0 +1,9 @@
+module ParsingErrorWoes where
+  
+{-@ measure vsize :: a -> Int                                   @-}
+{-@ type AOkIdx X          = {v:Nat | (OkRng v X (-1))}         @-}
+{-@ predicate InRng V L U  = (L <= V && V <= U)                 @-}
+{-@ predicate OkRng V X N  = (InRng V 0 ((vsize X) - (N + 1)))  @-}
+
+foo :: Int
+foo = 0
diff --git a/tests/todo/err12.hs b/tests/todo/err12.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err12.hs
@@ -0,0 +1,10 @@
+module BareCrash where
+
+{-@ measure isReal :: Space -> Prop
+    isReal (Null)       = false
+    isReal (Rreal pv n) = true
+ @-}
+
+
+data Space = Null | Real Int Int 
+  deriving (Show, Eq)
diff --git a/tests/todo/err13.hs b/tests/todo/err13.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err13.hs
@@ -0,0 +1,3 @@
+{-@ plus :: x:a -> y:a -> {v:a | v = x} @-}
+plus :: a -> a -> a
+plus = undefined
diff --git a/tests/todo/err2.hs b/tests/todo/err2.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err2.hs
@@ -0,0 +1,26 @@
+-- | Error Message Test: liquid-ghc type divergence 
+
+module Err1 where
+
+import Language.Haskell.Liquid.Prelude
+
+{-@ toss :: Int @-}
+toss     = (choose 0) > 10
+
+prop_abs :: Bool
+prop_abs = if toss 
+             then (if toss then liquidAssertB toss else False) 
+             else False
+
+
+foo :: Int -> Int
+foo x = (liquidAssert (x > 0) x) + 1
+
+goo = foo 12
+
+incr :: Int -> Int
+incr zzz = zzz + 1
+
+zoo = incr 29
+
+
diff --git a/tests/todo/err3.hs b/tests/todo/err3.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err3.hs
@@ -0,0 +1,26 @@
+-- | Error Message Test: ghc parse error
+
+module Err1 where
+
+import Language.Haskell.Liquid.Prelude
+
+toss :: Boo 
+toss = (choose 0) > 10
+
+prop_abs :: Bool
+prop_abs = if toss 
+             then (if toss then liquidAssertB toss else False) 
+             els False
+
+
+foo :: Int -> Int
+foo x = (liquidAssert (x > 0) x) + 1
+
+goo = foo 12
+
+incr :: Int -> Int
+incr zzz = zzz + 1
+
+zoo = incr 29
+
+
diff --git a/tests/todo/err4.hs b/tests/todo/err4.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err4.hs
@@ -0,0 +1,9 @@
+-- | Error Message Test: liquid type error
+
+module Err0 where
+
+{-@ zonk :: {v:Int | v = 0} @-}
+zonk     = (12 :: Int)
+
+{-@ tonk :: {v:Int | v = 0} @-}
+tonk     = (45 :: Int)
diff --git a/tests/todo/err5.hs b/tests/todo/err5.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err5.hs
@@ -0,0 +1,11 @@
+module Test0 where
+
+import Language.Haskell.Liquid.Prelude
+
+x = choose 0
+
+prop_abs = if x > 0 then baz x else False
+
+gob z = liquidAssertB (z `geq` 10)
+
+baz z = liquidAssertB (z `geq` 100)
diff --git a/tests/todo/err6.hs b/tests/todo/err6.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err6.hs
@@ -0,0 +1,8 @@
+-- | Error Message Test: liquid type error
+
+module Err0 where
+
+{-@ zonk :: {v:Int | v = z} @-}
+zonk     = (12 :: Int)
+
+
diff --git a/tests/todo/err7.hs b/tests/todo/err7.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err7.hs
@@ -0,0 +1,7 @@
+-- | Error Message Test: liquid type error
+
+module Err0 where
+
+{-@ tonk :: {v:Int | (Prop v) = v } @-}
+tonk     = (12 :: Int)
+
diff --git a/tests/todo/err8.hs b/tests/todo/err8.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err8.hs
@@ -0,0 +1,9 @@
+module Blank where
+
+-- instead of "ERROR ERROR ERROR" fail GRACEFULLY when spec has unknown var
+
+{-@ zoo :: Nat @-}
+
+{-@ x :: Poo @-}
+x :: Int
+x = 12
diff --git a/tests/todo/err9.hs b/tests/todo/err9.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/err9.hs
@@ -0,0 +1,11 @@
+module Blank where
+
+
+{-@ type ListN a N = {v:[a] | (len v) = N} @-}
+
+-- TODO: extend parser to allow expressions, at the very least, 
+--       literals as arguments! Currently, the below is rejected by the parser.
+
+{-@ xs :: (ListN Int 2) @-}
+xs :: [Int]
+xs = [1,2] 
diff --git a/tests/todo/existsAbs.hs b/tests/todo/existsAbs.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/existsAbs.hs
@@ -0,0 +1,81 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+
+
+
+module Exists where
+
+import Prelude hiding (exists)
+
+
+
+{-
+exists :: forall <p :: Bool -> Prop, q :: a -> Bool -> Prop, r :: a -> Prop>.
+          (x:a -> Bool<q x>) -> [a<r>] -> Bool<p>
+
+1. The result is True
+    forall x::a, v :: Bool . r x => q x True  |- v = True => p v 
+2. The result is False
+    forall x::a, v :: Bool . r x /\ q x True => false  |- v = False => p v 
+
+Eg:
+1. If all the elements of the list satisfy q x True, then the result is true
+exists isPos ([1, 2]  :: [Pos])        :: {v = True}
+2. If all the elements of the list contradict q x True, then the result is false
+exists isPos ([0, -1] :: [NonPos]) :: {v = False}
+3. Otherwise, I have no info
+exists isPos ([1, 0]  :: [Nat])        :: {true}
+
+-}
+
+
+
+
+
+
+{-@ exists :: forall <p :: Bool -> Prop, q :: a -> Bool -> Prop, r :: a -> Prop>.
+                  {x::a, flag:: {v:Bool<q x> | Prop v}, y::a<r>, bb::{v:Bool | x = y} |- {v:Bool | Prop v <=> Prop flag } <: Bool<p>}
+                  {x::a, flag:: {v:Bool<q x> | Prop v}, y::a<r>, bb::{v:Bool | x != y} |- {v:Bool | not (Prop v) <=> Prop flag } <: Bool<p>}
+                  (x:a -> Bool<q x>) -> [a<r>] -> Bool<p>
+  @-}
+
+
+exists :: (a -> Bool) -> [a] -> Bool
+exists f (x:xs)
+  | f x       = True
+  | otherwise = exists f xs 
+exists _ []   = False
+	
+{-@ isPos :: x:Int -> {v:Bool | Prop v <=> x > 0} @-}
+isPos :: Int -> Bool
+isPos n = n > 0
+
+
+{-@ isNeg :: x:Int -> {v:Bool | Prop v <=> x < 0} @-}
+isNeg :: Int -> Bool
+isNeg n = n < 0
+
+prop0 :: Bool
+{- prop0 :: {v:Bool | Prop v} @-}
+prop0 = exists isPos [0, 1]
+prop1 :: Bool
+{- prop1 :: {v:Bool | not (Prop v)} @-}
+prop1 = exists isPos [0, -1]
+
+{-
+-- | `positives` works by instantiating:
+-- p := \v   -> 0 < v
+-- q := \x v -> Prop v <=> 0 < x  (NV ??)
+
+
+{- positives :: [Int] -> [{v:Int | v > 0}] @-}
+positives xs = filter isPos xs
+
+
+-- | `negatives` works by instantiating:
+-- p := \v   -> 0 > v
+-- q := \x v -> Prop v <=> x < 0
+
+{- negatives :: [Int] -> [{v:Int | v < 0}] @-}
+negatives xs = filter isNeg xs
+-}
diff --git a/tests/todo/false.hs b/tests/todo/false.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/false.hs
@@ -0,0 +1,12 @@
+module Foo where
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--native" @-}
+
+{-@ foo :: {v:a | false} @-}
+foo  = foo
+
+
+nat :: Int
+{-@ nat :: Nat @-}
+nat = 42
diff --git a/tests/todo/fft.hs b/tests/todo/fft.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/fft.hs
@@ -0,0 +1,84 @@
+{-# LANGUAGE BangPatterns #-}
+
+module FFT where
+
+import Prelude hiding ((++))
+import qualified Data.ByteString.Lazy.Char8      as BS
+import qualified Data.ByteString.Lex.Lazy.Double as BS
+import qualified Data.Vector as V
+import Data.Vector ((!),(++),Vector)
+import Data.List hiding ((++))
+import Data.Complex
+import System.Environment
+
+headerSize bs = (+) 4 (BS.length . BS.concat . Prelude.take 4 . BS.lines $ bs)  
+ 
+dropHeader bs = BS.drop (headerSize bs) $ bs
+
+main = do
+   [f] <- getArgs
+   s   <- BS.readFile f
+   print . V.map (round. realPart) . ifft_CT. fft_CT . parse $ (dropHeader s)
+
+dft :: Vector (Double) -> Vector (Complex Double)
+dft xr = V.map (\k -> V.sum (V.imap (arg k) xr)) (numvec n)
+ where
+   n = V.length xr
+   nf = fromIntegral n
+   numvec n = V.enumFromStepN 0 1 n
+   arg k i x = (x:+0) * exp (-2 * pi * kf * ifl * (0:+1)/nf)
+             where
+               kf = fromIntegral k
+               ifl = fromIntegral i
+     
+idft :: Vector (Complex Double) -> Vector (Complex Double)
+idft xs = V.map (\k ->(/) (V.sum (V.imap (arg k) xs)) nf) (numvec n)
+ where
+   n = V.length xs
+   nf = fromIntegral n
+   numvec n = V.enumFromStepN 0 1 n
+   arg k i x = x * exp (2 * pi * kf * ifl * (0:+1)/nf)
+             where
+               kf = fromIntegral k
+               ifl = fromIntegral i
+
+fft_CT xs = if V.length xs == 1 then
+             dft xs
+           else
+             let xtop = V.zipWith3 fft_top (fft_CT xse) (fft_CT xso) (V.enumFromStepN 0 1 m)
+             
+                 xbottom = V.zipWith3 fft_bottom (fft_CT xse) (fft_CT xso) (V.enumFromStepN 0 1 m)
+                 xse = V.map (xs !) (V.enumFromStepN 0 2 m)
+                 xso = V.map (xs !) (V.enumFromStepN 1 2 m)
+                 n = V.length xs
+                 nf = fromIntegral n
+                 m = n `div` 2
+                 fft_top xe xo k = xe + xo * exp (-2 * (0:+1) * pi * k / nf)
+                 fft_bottom xe xo k = xe - xo * exp (-2 * (0:+1) * pi * k / nf)
+             in              
+                 xtop ++ xbottom
+
+ifft_CT xs = if V.length xs == 1 then
+              idft xs
+           else
+              let xtop = V.zipWith3 fft_top (ifft_CT xse) (ifft_CT xso) (V.enumFromStepN 0 1 m)
+                  xtop_scaled = V.map (/2) xtop
+                  xbottom = V.zipWith3 fft_bottom (ifft_CT xse) (ifft_CT xso) (V.enumFromStepN 0 1 m)
+                  xbottom_scaled = V.map (/2) xbottom
+                  xse = V.map (xs !) (V.enumFromStepN 0 2 m)
+                  xso = V.map (xs !) (V.enumFromStepN 1 2 m)
+                  n = V.length xs
+                  nf = fromIntegral n
+                  m = n `div` 2
+                  fft_top xe xo k = xe + xo * exp (2 * (0:+1) * pi * k / nf)
+                  fft_bottom xe xo k = xe - xo * exp (2 * (0:+1) * pi * k / nf)
+             in              
+                xtop_scaled ++ xbottom_scaled
+
+
+-- Fill a new vector from a file containing a list of numbers.
+parse = V.unfoldr step
+ where
+   step !s = case BS.readDouble s of
+     Nothing       -> Nothing
+     Just (!k, !t) -> Just (k, BS.tail t)
diff --git a/tests/todo/fio.hs b/tests/todo/fio.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/fio.hs
@@ -0,0 +1,104 @@
+module RIO where
+
+import Prelude hiding (read)
+
+{-@ data FIO a <pre :: World -> Prop, post :: World -> a -> World -> Prop> 
+  = FIO (rs :: (x:World<pre> -> (a, World)<\w -> {v:World<post x w> | true}>))
+  @-}
+data FIO a  = FIO {runState :: World -> (a, World)}
+
+{-@ runState :: forall <pre :: World -> Prop, post :: World -> a -> World -> Prop>. 
+                FIO <pre, post> a -> x:World<pre> -> (a, World)<\w -> {v:World<post x w> | true}> @-}
+
+data World  = W
+
+
+-- | forall m k v k'. sel (upd m k v) k' = if (k == k') then v else sel m k'
+
+{-@ measure sel :: World -> FilePath -> Int          @-}
+{-@ measure upd :: World -> FilePath -> Int -> World @-}
+
+
+{-@ open :: fp:FilePath -> FIO <{\w0 -> true}, {\w0 r w1 -> w1 = w0  && sel w0 fp = 1}> () @-}
+open :: FilePath -> FIO () 
+open = undefined
+
+{-@ read :: fp:FilePath -> FIO <{\w0 -> sel w0 fp = 1}, {\w0 r w1 -> w1 = w0}> String @-}
+read :: FilePath -> FIO String
+read = undefined
+
+--------------------------
+
+
+{-@
+bind :: forall < pre   :: World -> Prop 
+               , pre2  :: World -> Prop 
+               , p     :: a -> Prop
+               , post1 :: World -> a -> World -> Prop
+               , post2 :: World -> b -> World -> Prop
+               , post :: World -> b -> World -> Prop>.
+       {w:World<pre> -> x:a -> World<post1 w x> -> World<pre2>}        
+       {w:World<pre> -> y:a -> w2:World<post1 w y> -> x:b -> World<post2 w2 x> -> World<post w x>}        
+       FIO <pre, post1> a
+    -> (a -> FIO <pre2, post2> b)
+    -> FIO <pre, post> b 
+
+  @-}
+bind :: FIO a -> (a -> FIO b) -> FIO b
+bind (FIO g) f = FIO (\x -> case g x of {(y, s) -> (runState (f y)) s})    
+
+
+-- is the precondition true or p?
+{-@ ret :: forall <p :: World -> Prop>.
+           x:a -> FIO <p, {\w0 y w1 -> w0 == w1 && y == x }> a @-}
+ret :: a -> FIO a
+ret w      = FIO $ \x -> (w, x)
+
+
+ok1 f = open f
+
+{-@ fail1 :: FilePath -> FIO String @-}
+fail1 :: FilePath -> FIO String
+fail1 f   = read f
+
+
+ok2 f = open f `bind` \_ -> read f
+
+instance Monad FIO where
+
+{-@ instance Monad FIO where
+ >>= :: forall < pre   :: World -> Prop 
+               , pre2  :: World -> Prop 
+               , p     :: a -> Prop
+               , post1 :: World -> a -> World -> Prop
+               , post2 :: World -> b -> World -> Prop
+               , post :: World -> b -> World -> Prop>.
+       {w:World<pre> -> x:a -> World<post1 w x> -> World<pre2>}        
+       {w:World<pre> -> y:a -> w2:World<post1 w y> -> x:b -> World<post2 w2 x> -> World<post w x>}        
+       FIO <pre, post1> a
+    -> (a -> FIO <pre2, post2> b)
+    -> FIO <pre, post> b ;
+ >>  :: forall < pre   :: World -> Prop 
+               , pre2  :: World -> Prop 
+               , p     :: a -> Prop
+               , post1 :: World -> a -> World -> Prop
+               , post2 :: World -> b -> World -> Prop
+               , post :: World -> b -> World -> Prop>.
+       {w:World<pre> -> x:a -> World<post1 w x> -> World<pre2>}        
+       {w:World<pre> -> y:a -> w2:World<post1 w y> -> x:b -> World<post2 w2 x> -> World<post w x>}        
+       FIO <pre, post1> a
+    -> FIO <pre2, post2> b
+    -> FIO <pre, post> b ;
+ return :: forall <p :: World -> Prop>.
+           x:a -> FIO <p, {\w0 y w1 -> w0 == w1 && y == x }> a
+  @-}  
+  (FIO g) >>= f = FIO $ \x -> case g x of {(y, s) -> (runState (f y)) s} 
+  (FIO g) >>  f = FIO $ \x -> case g x of {(y, s) -> (runState f    ) s}    
+  return w      = FIO $ \x -> (w, x)
+  fail          = error
+
+
+{-@ ok3   :: FilePath -> FIO String @-}
+ok3 f = do open f
+           read f
+
diff --git a/tests/todo/fixme.lhs b/tests/todo/fixme.lhs
new file mode 100644
--- /dev/null
+++ b/tests/todo/fixme.lhs
@@ -0,0 +1,9 @@
+foo :: Int 
+foo = 1 
+
+bar :: Int 
+bar = 1 
+{-@ LIQUID "--higher-order" @-}
+{-@ unsound :: () -> {v:Bool |  foo == bar } @-}
+unsound :: () -> Bool
+unsound _ = foo == bar 
diff --git a/tests/todo/funrec.hs b/tests/todo/funrec.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/funrec.hs
@@ -0,0 +1,5 @@
+module Foo () where
+
+data F a = F { f :: Int -> a }
+
+{-@ data F a = F { f :: Nat -> a } @-}
diff --git a/tests/todo/gadtEval.hs b/tests/todo/gadtEval.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/gadtEval.hs
@@ -0,0 +1,91 @@
+
+module Eval () where 
+
+import Language.Haskell.Liquid.Prelude (liquidError)
+
+-- "Classic" GADT 
+-- 
+-- data Expr a where
+--   I :: Int -> Expr Int
+--   B :: Bool -> Expr Bool
+--   Eq :: Expr a -> Expr a -> Expr Bool
+--   Pl :: Expr Int -> Expr Int -> Expr Int
+-- 
+-- eval :: Expr a -> a
+-- eval (I i)      = i
+-- eval (B b)      = b
+-- eval (Eq e1 e2) = (eval e1) == (eval e2)
+-- eval (Pl e1 e2) = (eval e1) + (eval e2)
+
+data Ty   = TInt 
+          | TBool
+
+data Expr = I     Int
+          | B     Bool
+          | Equal Expr Expr
+          | Plus  Expr Expr
+          deriving (Eq, Show)
+
+
+{-@ check          :: e:ValidExpr  -> {v:Ty | (v = (eType e))} @-}
+check (I _)        = TInt
+check (B _)        = TBool
+check (Plus e1 e2) = TInt
+check (Equal _ _)  = TBool
+
+{-@ Strict eval @-}
+
+{-@ eval           :: e:ValidExpr  -> {v:ValidExpr | ((isValue v) && (((eType e) = (eType v))))} @-}
+eval e@(I _)       = e
+eval e@(B _)       = e
+eval (Plus e1 e2)  = (eval e1) `plus` (eval e2)
+eval (Equal e1 e2) = (eval e1) `equal` (eval e2)
+
+plus (I i) (I j)   = I (i + j)
+plus _       _     = liquidError "don't worry, its impossible" 
+
+equal (I i) (I j)  = B (i == j)
+equal (B x) (B y)  = B (x == y)
+equal _       _    = liquidError "don't worry, its impossible" 
+
+-- | The next two are silly, for scraping quals. Yuck. Should scrape from measure-DEFS etc.
+
+{-@ toInt :: IntExpr -> Int @-}
+toInt (I i) = i
+toInt _     = liquidError "impossible"
+
+{-@ toBool :: BoolExpr -> Bool @-}
+toBool (B b) = b
+toBool _     = liquidError "impossible"
+
+
+{-@ predicate TInt X   = ((eType X) = TInt)  @-}
+{-@ predicate TBool X  = ((eType X) = TBool) @-}
+
+
+{-@ type ValidExpr     = {v: Expr | (isValid v)}                @-}
+{-@ type IntExpr       = {v: Expr | ((isValue v) && (TInt  v))} @-}
+{-@ type BoolExpr      = {v: Expr | ((isValue v) && (TBool v))} @-}
+
+
+{-@ measure isValue       :: Expr -> Prop
+    isValue (I i)         = true
+    isValue (B b)         = true
+    isValue (Equal e1 e2) = false 
+    isValue (Plus e1 e2)  = false
+  @-}  
+
+{-@ measure eType       :: Expr -> Ty 
+    eType (I i)         = TInt  
+    eType (Plus  e1 e2) = TInt 
+    eType (B b)         = TBool 
+    eType (Equal e1 e2) = TBool 
+  @-}
+
+{-@ measure isValid       :: Expr -> Prop
+    isValid (I i)         = true
+    isValid (B b)         = true
+    isValid (Equal e1 e2) = (((eType e1) = (eType e2)) && (isValid e1) && (isValid e2))
+    isValid (Plus e1 e2)  = ((TInt e1) && (TInt e2) && (isValid e1) && (isValid e2))
+  @-}
+
diff --git a/tests/todo/if.hs b/tests/todo/if.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/if.hs
@@ -0,0 +1,27 @@
+module If where
+
+-- what's a reasonable type to give to `if_` so that we can verify `bog` ? 
+
+{-@ type TT = {v: Bool |     (Prop v)} @-}
+{-@ type FF = {v: Bool | not (Prop v)} @-}
+
+
+{-@ if_  :: b:Bool -> x:a -> y:a -> a @-}
+if_ :: Bool -> a -> a -> a
+if_ True  x _ = x
+if_ False _ y = y
+
+
+{-@ bog :: Nat @-}
+bog :: Int
+bog =
+  let b  = (0 < 1)      -- :: TT
+      xs = [1 ,  2,  3] -- :: [Nat]
+      ys = [-1, -2, -3] -- :: [Int]
+      zs = if_ b xs ys  -- :: [Nat] 
+  in 
+      case xs of
+        h:_ -> h 
+        _   -> 0
+
+
diff --git a/tests/todo/inccheck0.hs b/tests/todo/inccheck0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/inccheck0.hs
@@ -0,0 +1,40 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+
+module Test0 () where
+
+{-@ decr :: x:Int -> {v:Int | v < x} @-}
+decr :: Int -> Int
+decr xo = xo - 100
+
+{-@ plus :: x:Int -> y:Int -> {v:Int | v = x + y} @-}
+plus :: Int -> Int -> Int
+plus x yo = x + yo
+
+{-@ goo :: Int -> Nat @-}
+goo :: Int -> Int
+goo x = x +  1
+
+{-@ incr :: x:Int -> {v:Int | v > x} @-}
+incr :: Int -> Int
+incr xoo = xoo  `plus` zaa
+  where
+     zaa = a00 - b00
+     a00 = 300
+     b00 = 2
+
+{-@ jog :: x:Int -> {v:Int | v = x} @-}
+jog  :: Int -> Int
+jog x = x `plus` z
+  where 
+    z = a - b
+    a = 2
+    b = 2
+
+{-@ ping, pong :: n:Int -> {v:Int | v > n} @-}
+ping, pong :: Int -> Int
+ping 0 = 1
+ping n = 1 `plus` pong (n-1)
+
+pong 0 = 1 
+pong n = 1 `plus` ping (n-1)
diff --git a/tests/todo/intP.hs b/tests/todo/intP.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/intP.hs
@@ -0,0 +1,6 @@
+module Qoo where
+
+{-@ intid :: forall <r :: y0: Int -> Bool>. i: Int<r> -> Int<r> @-}
+intid :: Int -> Int
+intid i = i
+
diff --git a/tests/todo/kmpMonad.hs b/tests/todo/kmpMonad.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/kmpMonad.hs
@@ -0,0 +1,180 @@
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--short-names"    @-}
+{- LIQUID "--diff"           @-}
+
+module KMP (search) where
+
+import Language.Haskell.Liquid.Prelude (liquidError, liquidAssert)
+import Data.IORef
+import Control.Applicative ((<$>))
+import qualified Data.Map as M
+import Prelude hiding (map)
+
+{-@ type Upto N = {v:Nat | v < N} @-}
+
+---------------------------------------------------------------------------
+{-@ search :: pat:String -> str:String -> IO (Maybe (Upto (len str))) @-}
+---------------------------------------------------------------------------
+search :: String -> String -> IO (Maybe Int)
+search pat str = do
+  p <- ofListIO pat
+  s <- ofListIO str
+  kmpSearch p s
+
+---------------------------------------------------------------------------
+-- | Do the Search --------------------------------------------------------
+---------------------------------------------------------------------------
+
+kmpSearch p@(IOA m _) s@(IOA n _) = do
+  t <- kmpTable p
+  find p s t 0 0
+
+find p@(IOA m _) s@(IOA n _) t = go
+  where
+    go i j
+      | i >= n    = return $ Nothing
+      | j >= m    = return $ Just (i - m)
+      | otherwise = do si <- getIO s i
+                       pj <- getIO p j
+                       tj <- getIO t j
+                       case () of
+                        _ | si == pj  -> go (i+1) (j+1)
+                          | j == 0    -> go (i+1) j
+                          | otherwise -> go i     tj
+
+---------------------------------------------------------------------------
+-- | Make Table -----------------------------------------------------------
+---------------------------------------------------------------------------
+
+-- BUG WHAT's going on?
+{-@ bob :: Nat -> IO () @-}
+bob n = do
+  t <- newIO (n + 1) (\_ -> 0)
+  setIO t 0 100
+  r <- getIO t 0
+  liquidAssert (r == 0) $ return ()
+
+
+kmpTable p@(IOA m _) = do
+  t <- newIO m (\_ -> 0)
+  fill p t 1 0
+  return t
+
+fill p t@(IOA m _) = go
+  where
+    go i j
+      | i < m - 1  = do
+          pi <- getIO p (id i)
+          pj <- getIO p j
+          case () of
+            _ | pi == pj -> do
+                  let i' = i + 1
+                  let j' = j + 1
+                  setIO t i' j'
+                  go i' j'
+              | j == 0 -> do
+                  let i' = i + 1
+                  setIO t i' 0
+                  go i' j
+              | otherwise -> do
+                  j' <- getIO t j
+                  go i j'
+      | otherwise = return t
+
+
+-------------------------------------------------------------------------------
+-- | An Imperative Array ------------------------------------------------------
+-------------------------------------------------------------------------------
+
+data IOArr a = IOA { size :: Int
+                   , pntr :: IORef (Arr a)
+                   }
+
+{-@ data IOArr a <p :: Int -> a -> Prop>
+      = IOA { size :: Nat
+            , pntr :: IORef ({v:Arr<p> a | alen v = size})
+            }
+  @-}
+
+
+{-@ newIO :: forall <p :: Int -> a -> Prop>.
+               n:Nat -> (i:Upto n -> a<p i>) -> IO ({v: IOArr<p> a | size v = n})
+  @-}
+newIO n f = IOA n <$> newIORef (new n f)
+
+{-@ getIO :: forall <p :: Int -> a -> Prop>.
+              a:IOArr<p> a -> i:Upto (size a) -> IO (a<p i>)
+  @-}
+getIO a@(IOA sz p) i
+  = do arr   <- readIORef p
+       return $ (arr ! i)
+
+{-@ setIO :: forall <p :: Int -> a -> Prop>.
+              a:IOArr<p> a -> i:Upto (size a) -> a<p i> -> IO ()
+  @-}
+setIO a@(IOA sz p) i v
+  = do arr     <- readIORef p
+       let arr' = set arr i v
+       writeIORef p arr'
+
+
+{-@ ofListIO :: xs:[a] -> IO ({v:IOArr a | size v = len xs}) @-}
+ofListIO xs  = newIO n f
+  where
+    n        = length xs
+    m        = M.fromList $ zip [0..] xs
+    f i      = (M.!) m i
+
+
+{-@ mapIO :: (a -> b) -> a:IOArr a -> IO ({v:IOArr b | size v = size a}) @-}
+mapIO f (IOA n p)
+  = do a <- readIORef p
+       IOA n <$> newIORef (map f a)
+
+
+
+-------------------------------------------------------------------------------
+-- | A Pure Array -------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+data Arr a   = A { alen :: Int
+                 , aval :: Int -> a
+                 }
+
+{-@ data Arr a <p :: Int -> a -> Prop>
+             = A { alen :: Nat
+                 , aval :: i:Upto alen -> a<p i>
+                 }
+  @-}
+
+
+{-@ new :: forall <p :: Int -> a -> Prop>.
+             n:Nat -> (i:Upto n -> a<p i>) -> {v: Arr<p> a | alen v = n}
+  @-}
+new n v = A { alen = n
+            , aval = \i -> if (0 <= i && i < n)
+                             then v i
+                             else liquidError "Out of Bounds!"
+            }
+
+{-@ (!) :: forall <p :: Int -> a -> Prop>.
+             a:Arr<p> a -> i:Upto (alen a) -> a<p i>
+  @-}
+
+(A _ f) ! i = f i
+
+{-@ set :: forall <p :: Int -> a -> Prop>.
+             a:Arr<p> a -> i:Upto (alen a) -> a<p i> -> {v:Arr<p> a | alen v = alen a}
+  @-}
+set a@(A _ f) i v = a { aval = \j -> if (i == j) then v else f j }
+
+
+{-@ ofList :: xs:[a] -> {v:Arr a | alen v = len xs} @-}
+ofList xs = new n f
+  where
+    n     = length xs
+    m     = M.fromList $ zip [0..] xs
+    f i   = (M.!) m i
+
+{-@ map :: (a -> b) -> a:Arr a -> {v:Arr b | alen v = alen a} @-}
+map f a@(A n z) = A n (f . z)
diff --git a/tests/todo/liftbug.hs b/tests/todo/liftbug.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/liftbug.hs
@@ -0,0 +1,9 @@
+module AVL where
+
+data Tree = Nil | Tree Int Tree Tree
+
+{-@ measure height @-}
+height :: Tree -> Int
+height Nil          = 0 :: Int
+height (Tree _ l r) = (if height l > height r then 1 + height l else 1 + height r)
+
diff --git a/tests/todo/linspace-crash.hs b/tests/todo/linspace-crash.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/linspace-crash.hs
@@ -0,0 +1,207 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+{-@ LIQUID "--no-termination" @-}
+{-@ LIQUID "--diff" @-}
+
+module LinSpace (dotPV, sameSpace, enumCVP) where
+
+import Language.Haskell.Liquid.Prelude (liquidAssert, liquidError)
+import Prelude hiding (zipWith)
+
+data PVector = PVector { 
+    vec       :: [Integer]      -- vector coordinates
+  , muCoeff   :: [Integer]      -- <vec,bn*>det^2(b[1..n-1]) : ... 
+  , orthSpace :: Space PVector  -- lattice basis
+  } deriving (Show, Eq)
+
+-- | Orthogonalized vector bn* and squared lattice determinant 
+data Space a = Null | Real a Integer
+  deriving (Show, Eq)
+
+{-@ data PVector = PVector { 
+      vec_  :: [Integer]   
+    , mu_   :: [Integer] 
+    , orth_ :: {v: (Space (PVectorN (len vec_))) | dim v = (len mu_)}
+    } 
+  @-}
+
+{-@ measure dim     :: (Space PVector) -> Int 
+    dim (Null)      = 0
+    dim (Real pv n) = 1 + (dim (orthSpace pv))
+  @-}
+
+{-@ measure spaceVec     :: (Space PVector) -> PVector
+    spaceVec (Real pv n) = pv
+  @-}
+
+{-@ measure vec :: PVector -> [Integer]
+    vec (PVector v m o) = v 
+  @-}
+
+{-@ measure muCoeff :: PVector -> [Integer]
+    muCoeff (PVector v m o) = m 
+  @-}
+
+{-@ measure orthSpace :: PVector -> (Space PVector)
+    orthSpace (PVector p m o) = o
+  @-}
+
+{-@ invariant {v: PVector | (Inv v) }    @-}
+{-@ invariant {v: Space PVector | (dim v) >= 0 } @-}
+
+-- RJ: Helpers for defining properties
+
+{-@ predicate Inv V        = (dim (orthSpace V)) = (len (muCoeff V)) @-}
+{-@ predicate SameLen  X Y = ((len (vec X))  = (len (vec Y)))  @-}
+{-@ predicate SameOrth X Y = ((orthSpace X) = (orthSpace Y)) @-}
+
+-- RJ: Useful type aliases for specs
+
+{-@ type SameSpace X       = {v:PVector | ((Inv v) && (SameLen X v) && (SameOrth X v))} @-}
+{-@ type PVectorN N        = {v: PVector | (len (vec v)) = N}   @-} 
+{-@ type PVectorP P        = {v: PVector | (SameLen v P)}       @-} 
+
+--------------------
+
+{-@ dim         :: s:(Space PVector) -> {v:Int | v = (dim s)} @-}
+dim Null        = (0 :: Int)
+dim (Real pv _) = 1 + dim (orthSpace_ pv)
+
+sameSpace         :: PVector -> PVector -> Bool
+sameSpace pv1 pv2 = (length (vec pv1) == length (vec pv2)) && (orthSpace pv1 == orthSpace pv2)
+
+
+{-@ muCoeff_   :: p:PVector -> {v:[Integer] | v = (muCoeff p) }            @-}
+muCoeff_ (PVector v m o) = m
+
+{-@ orthSpace_ :: p:PVector -> {v:(Space (PVectorP p)) | v = (orthSpace p)} @-} 
+orthSpace_ (PVector v m o) = o
+
+{-@ vec_       :: p:PVector -> {v:[Integer] | v = (vec p)}                  @-}
+vec_     (PVector v m o) = v
+
+--------------------
+
+-- squared determinant of orthSpace
+detPV :: PVector -> Integer 
+detPV (PVector _ _ Null)       = 1
+detPV (PVector _ _ (Real _ n)) = n
+
+
+{-@ liftPV :: pv:PVector -> {v:(PVectorP pv) | ((orthSpace v) = (orthSpace (spaceVec (orthSpace pv))) && ((dim (orthSpace v)) = (dim (orthSpace pv)) - 1))} @-}
+liftPV (PVector v (m:mu) (Real pv _)) = PVector v mu (orthSpace_ pv)
+
+{-@ dot :: (Num a) => xs:[a] -> {v:[a] | (len v) = (len xs)} -> a @-}
+dot xs ys = sum (zipWith (*) xs ys)
+
+-- scaled dot product of two projected vectors: output is <v*,w*>det^2(orthSpace) 
+{-@ dotPV :: pv1:PVector -> pv2:(SameSpace pv1) -> Integer @-}
+dotPV (PVector v1 [] _) (PVector v2 [] _) 
+  = dot v1 v2
+dotPV pv1@(PVector _ mu1 _) pv2@(PVector _ mu2 _) 
+  = liquidAssert (length mu1 == length mu2) q
+  where
+    dd          = dotPV (liftPV pv1) (liftPV pv2)
+    Real pv0 rr = orthSpace_ pv1       -- same as orthSpace v2
+    x           = dd * rr - (head mu1) * (head mu2)
+    (q, 0)      = divMod x (detPV pv0) -- check remainder is 0
+
+-- ASSERT: (x .+. y) ==> sameSpace x y
+{-@ (.+.) :: x:PVector -> (SameSpace x) -> (SameSpace x) @-}
+(PVector v1 m1 o) .+. (PVector v2 m2 _) = PVector (zipWith  (+) v1 v2) (zipWith (+) m1 m2) o
+
+-- ASSERT: (x .-. y) ==> sameSpace x y
+{-@ (.-.) :: x:PVector -> (SameSpace x) -> (SameSpace x) @-}
+(PVector v1 m1 o) .-. (PVector v2 m2 _) = PVector (zipWith  (-) v1 v2) (zipWith (-) m1 m2) o
+
+{-@ (*.) :: Integer -> x:PVector -> (SameSpace x) @-}
+(*.) :: Integer -> PVector -> PVector
+x *. (PVector v m o) = PVector (map (x *)  v) (map (x *) m) o
+
+-- Some auxiliary functions
+
+{-@ space2vec :: n:Int -> s:(Space (PVectorN n)) -> {v: (PVectorN n) | (orthSpace v) = s} @-}
+space2vec (n :: Int) sp@(Real bn r) = PVector (vec_ bn) (r : muCoeff_ bn) sp
+
+{-@ makeSpace :: p:PVector -> (Space (PVectorP p)) @-}
+makeSpace pvec = Real pvec (dotPV pvec pvec)
+
+{-@ makePVector :: vs:[Integer] -> s:(Space (PVectorN (len vs))) -> {v: (PVectorN (len vs)) | (orthSpace v) = s} @-}
+makePVector :: [Integer] -> Space PVector -> PVector
+makePVector v s@Null = PVector v [] s 
+makePVector v s@(Real s1 _) = 
+  let v1 = makePVector v (orthSpace_ s1) 
+  in PVector v (dotPV v1 s1 : muCoeff_ v1)  s
+
+{-@ gramSchmidt :: n:Nat -> [(List Integer n)] -> (Space (PVectorN n)) @-}
+gramSchmidt (n :: Int) = foldl (\sp v -> makeSpace (makePVector v sp)) Null 
+
+{-@ getBasis :: n:Nat -> Space (PVectorN n) -> [(List Integer n)] @-}
+getBasis (n::Int) s = worker s [] 
+  where
+    worker Null bs = bs
+    worker (Real pv _) bs = worker (orthSpace_ pv) (vec pv : bs)
+
+{-@ qualif EqMu(v:PVector, x:PVector): (len (muCoeff v)) = (len (muCoeff x)) @-}
+
+sizeReduce1 :: PVector -> PVector
+sizeReduce1 pv@(PVector v (m:_) sn@(Real _ r)) = 
+  let c  = div (2*m + r) (2*r) -- division with rounded remainder
+      n  = length v    
+  in  pv  .-.  (c *. (space2vec n sn))
+
+-- ASSERT: sameSpace (sizeReduce x) x
+{-@ sizeReduce :: x:PVector -> (SameSpace x) @-}
+sizeReduce pv@(PVector v [] Null) = pv
+sizeReduce pv@(PVector _ _ sp@(Real _ _)) = 
+  let pv1 = sizeReduce1 pv
+      (PVector v mu _) = sizeReduce (liftPV pv1)
+  in PVector v (head (muCoeff_ pv1) : mu) sp
+
+-- Two example algorithms using the library: enumCVP and lll
+
+enumCVP :: PVector -> Integer -> Maybe [Integer]
+enumCVP (PVector v mu Null) r 
+  | dot v v < r = Just v 
+  | otherwise   = Nothing 
+enumCVP t@(PVector _ (_:_) (Real bn _)) r = 
+  let t0 = sizeReduce1  t
+      cs = if (head (muCoeff_ t0) < 0) 
+           then 0 : concat [[x,negate x] | x <- [1,2..]]
+           else 0 : concat [[negate x,x] | x <- [1,2..]]
+      branch :: (Integer, Maybe [Integer]) -> [PVector] -> (Integer, Maybe [Integer])
+      branch (r,v) (t:ts) = 
+        if (dotPV t t >= r * detPV t) then (r,v)
+        else case enumCVP t r of
+          Nothing -> branch (r,v) ts
+          Just w  -> branch (dot w w, Just w) ts
+  in snd $ branch (r,Nothing) [liftPV t0 .+. (c *. bn) | c <- cs]
+
+-- make this parametric on n
+{- Fraction free LLL Algorithm with exact arithmetic and delta=99/100 -}
+{-@ lll :: n:Nat -> [(List Integer n)] -> [(List Integer n)] @-}
+lll :: Int -> [[Integer]] -> [[Integer]]
+lll n = getBasis n . lll_worker n Null Nothing
+
+{-@ lll_worker :: n:Nat -> (Space (PVectorN n)) -> (Maybe (PVectorN n)) -> [(List Integer n)] -> (Space (PVectorN n)) @-}
+lll_worker (n :: Int) bs Nothing [] = bs
+lll_worker n bs Nothing (v:vs)      = lll_worker n bs (Just (makePVector v bs)) vs
+lll_worker n Null (Just pv) vs      = lll_worker n (makeSpace pv) Nothing vs
+lll_worker n (Real bn r) (Just pv) vs = 
+    let pv1 = sizeReduce pv
+        pv2 = liftPV pv1
+    in if (100*(dotPV pv2 pv2) < 99*r)
+       then lll_worker n (orthSpace_ bn) (Just pv2) (vec bn : vs)
+       else lll_worker n (makeSpace pv1) Nothing vs
+
+------------------------------------------------------------------------------------
+-- RJ: Included for illustration...
+------------------------------------------------------------------------------------
+
+{-@ type List a N = {v : [a] | (len v) = N} @-}
+
+{-@ zipWith :: (a -> b -> c) -> xs:[a] -> (List b (len xs)) -> (List c (len xs)) @-}
+zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
+zipWith _ [] []         = []
+zipWith _ (_:_) []      = liquidError "Dead Code"
+zipWith _ [] (_:_)      = liquidError "Dead Code"
diff --git a/tests/todo/linspace.hs b/tests/todo/linspace.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/linspace.hs
@@ -0,0 +1,210 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+{-@ LIQUID "--no-termination" @-}
+
+module LinSpace (dotPV, sameSpace, enumCVP) where
+
+import Language.Haskell.Liquid.Prelude (liquidAssume, liquidAssert, liquidError)
+import Prelude hiding (zipWith)
+
+data PVector = PVector { 
+    vec       :: [Integer]      -- vector coordinates
+  , muCoeff   :: [Integer]      -- <vec,bn*>det^2(b[1..n-1]) : ... 
+  , orthSpace :: Space PVector  -- lattice basis
+  } deriving (Show, Eq)
+
+-- | Orthogonalized vector bn* and squared lattice determinant 
+data Space a = Null | Real a Integer
+  deriving (Show, Eq)
+
+{-@ data PVector = PVector { 
+      vec_  :: [Integer]   
+    , mu_   :: [Integer] 
+    , orth_ :: {v: (Space (PVectorN (len vec_))) | (dim v) = (len mu_)}
+    } 
+  @-}
+
+{-@ data Space [dim] @-}
+
+{-@ measure dim     :: (Space PVector) -> Int 
+    dim (Null)      = 0
+    dim (Real pv n) = 1 + (dim (orthSpace pv))
+  @-}
+
+{-@ measure spaceVec     :: (Space PVector) -> PVector
+    spaceVec (Real pv n) = pv
+  @-}
+
+{-@ measure vec :: PVector -> [Integer]
+    vec (PVector v m o) = v 
+  @-}
+
+{-@ measure muCoeff :: PVector -> [Integer]
+    muCoeff (PVector v m o) = m 
+  @-}
+
+{-@ measure orthSpace :: PVector -> (Space PVector)
+    orthSpace (PVector p m o) = o
+  @-}
+
+{-@ invariant {v: PVector | (Inv v) }    @-}
+{-@ invariant {v: Space PVector | (dim v) >= 0 } @-}
+
+-- RJ: Helpers for defining properties
+
+{-@ predicate Inv V        = (dim (orthSpace V)) = (len (muCoeff V)) @-}
+{-@ predicate SameLen  X Y = ((len (vec X))  = (len (vec Y)))  @-}
+{-@ predicate SameOrth X Y = ((orthSpace X) = (orthSpace Y)) @-}
+
+-- RJ: Useful type aliases for specs
+
+{-@ type SameSpace X       = {v:PVector | ((Inv v) && (SameLen X v) && (SameOrth X v))} @-}
+{-@ type PVectorN N        = {v: PVector | (len (vec v)) = N}   @-} 
+{-@ type PVectorP P        = {v: PVector | (SameLen v P)}       @-} 
+
+--------------------
+
+{-@ dim         :: s:(Space PVector) -> {v:Int | v = (dim s)} @-}
+dim Null        = (0 :: Int)
+dim (Real pv _) = 1 + dim (orthSpace_ pv)
+
+sameSpace         :: PVector -> PVector -> Bool
+sameSpace pv1 pv2 = (length (vec pv1) == length (vec pv2)) && (orthSpace pv1 == orthSpace pv2)
+
+
+{-@ muCoeff_   :: p:PVector -> {v:[Integer] | v = (muCoeff p) }            @-}
+muCoeff_ (PVector v m o) = m
+
+{-@ orthSpace_ :: p:PVector -> {v:(Space (PVectorP p)) | v = (orthSpace p)} @-} 
+orthSpace_ (PVector v m o) = o
+
+{-@ vec_       :: p:PVector -> {v:[Integer] | v = (vec p)}                  @-}
+vec_     (PVector v m o) = v
+
+--------------------
+
+-- squared determinant of orthSpace
+detPV :: PVector -> Integer 
+detPV (PVector _ _ Null)       = 1
+detPV (PVector _ _ (Real _ n)) = n
+
+
+{-@ liftPV :: pv:PVector -> {v:(PVectorP pv) | ((orthSpace v) = (orthSpace (spaceVec (orthSpace pv))) && ((dim (orthSpace v)) = (dim (orthSpace pv)) - 1))} @-}
+liftPV (PVector v (m:mu) (Real pv _)) = PVector v mu (orthSpace_ pv)
+
+{-@ dot :: (Num a) => xs:[a] -> {v:[a] | (len v) = (len xs)} -> a @-}
+dot xs ys = sum (zipWith (*) xs ys)
+
+-- scaled dot product of two projected vectors: output is <v*,w*>det^2(orthSpace) 
+{-@ dotPV :: pv1:PVector -> pv2:(SameSpace pv1) -> Integer @-}
+dotPV (PVector v1 [] _) (PVector v2 [] _) 
+  = dot v1 v2
+dotPV pv1@(PVector _ mu1 _) pv2@(PVector _ mu2 _) 
+  = liquidAssert (length mu1 == length mu2) q
+  where
+    dd          = dotPV (liftPV pv1) (liftPV pv2)
+    Real pv0 rr = orthSpace_ pv1                         -- same as orthSpace v2
+    x           = dd * rr - (head mu1) * (head mu2)
+    (q, 0)      = divMod x (liquidAssume (rem /= 0) rem) -- check remainder is 0
+    rem         = detPV pv0
+
+-- ASSERT: (x .+. y) ==> sameSpace x y
+{-@ (.+.) :: x:PVector -> (SameSpace x) -> (SameSpace x) @-}
+(PVector v1 m1 o) .+. (PVector v2 m2 _) = PVector (zipWith  (+) v1 v2) (zipWith (+) m1 m2) o
+
+-- ASSERT: (x .-. y) ==> sameSpace x y
+{-@ (.-.) :: x:PVector -> (SameSpace x) -> (SameSpace x) @-}
+(PVector v1 m1 o) .-. (PVector v2 m2 _) = PVector (zipWith  (-) v1 v2) (zipWith (-) m1 m2) o
+
+{-@ (*.) :: Integer -> x:PVector -> (SameSpace x) @-}
+(*.) :: Integer -> PVector -> PVector
+x *. (PVector v m o) = PVector (map (x *)  v) (map (x *) m) o
+
+-- Some auxiliary functions
+
+{-@ space2vec :: n:Int -> s:(Space (PVectorN n)) -> {v: (PVectorN n) | (orthSpace v) = s} @-}
+space2vec (n :: Int) sp@(Real bn r) = PVector (vec_ bn) (r : muCoeff_ bn) sp
+
+{-@ makeSpace :: p:PVector -> (Space (PVectorP p)) @-}
+makeSpace pvec = Real pvec (dotPV pvec pvec)
+
+{-@ makePVector :: vs:[Integer] -> s:(Space (PVectorN (len vs))) -> {v: (PVectorN (len vs)) | (orthSpace v) = s} @-}
+makePVector :: [Integer] -> Space PVector -> PVector
+makePVector v s@Null = PVector v [] s 
+makePVector v s@(Real s1 _) = 
+  let v1 = makePVector v (orthSpace_ s1) 
+  in PVector v (dotPV v1 s1 : muCoeff_ v1)  s
+
+{-@ gramSchmidt :: n:Nat -> [(List Integer n)] -> (Space (PVectorN n)) @-}
+gramSchmidt (n :: Int) = foldl (\sp v -> makeSpace (makePVector v sp)) Null 
+
+{-@ getBasis :: n:Nat -> Space (PVectorN n) -> [(List Integer n)] @-}
+getBasis (n::Int) s = worker s [] 
+  where
+    worker Null bs = bs
+    worker (Real pv _) bs = worker (orthSpace_ pv) (vec pv : bs)
+
+{-@ qualif EqMu(v:PVector, x:PVector): (len (muCoeff v)) = (len (muCoeff x)) @-}
+
+sizeReduce1 :: PVector -> PVector
+sizeReduce1 pv@(PVector v (m:_) sn@(Real _ r)) = 
+  let c  = div (2*m + r) (liquidAssume (r2 /= 0) r2) -- division with rounded remainder
+      r2 = 2 * r
+      n  = length v    
+  in  pv  .-.  (c *. (space2vec n sn))
+
+-- ASSERT: sameSpace (sizeReduce x) x
+{-@ sizeReduce :: x:PVector -> (SameSpace x) @-}
+sizeReduce pv@(PVector v [] Null) = pv
+sizeReduce pv@(PVector _ _ sp@(Real _ _)) = 
+  let pv1 = sizeReduce1 pv
+      (PVector v mu _) = sizeReduce (liftPV pv1)
+  in PVector v (head (muCoeff_ pv1) : mu) sp
+
+-- Two example algorithms using the library: enumCVP and lll
+
+enumCVP :: PVector -> Integer -> Maybe [Integer]
+enumCVP (PVector v mu Null) r 
+  | dot v v < r = Just v 
+  | otherwise   = Nothing 
+enumCVP t@(PVector _ (_:_) (Real bn _)) r = 
+  let t0 = sizeReduce1  t
+      cs = if (head (muCoeff_ t0) < 0) 
+           then 0 : concat [[x,negate x] | x <- [1,2..]]
+           else 0 : concat [[negate x,x] | x <- [1,2..]]
+      branch :: (Integer, Maybe [Integer]) -> [PVector] -> (Integer, Maybe [Integer])
+      branch (r,v) (t:ts) = 
+        if (dotPV t t >= r * detPV t) then (r,v)
+        else case enumCVP t r of
+          Nothing -> branch (r,v) ts
+          Just w  -> branch (dot w w, Just w) ts
+  in snd $ branch (r,Nothing) [liftPV t0 .+. (c *. bn) | c <- cs]
+
+-- make this parametric on n
+{- Fraction free LLL Algorithm with exact arithmetic and delta=99/100 -}
+{-@ lll :: n:Nat -> [(List Integer n)] -> [(List Integer n)] @-}
+lll :: Int -> [[Integer]] -> [[Integer]]
+lll n = getBasis n . lll_worker n Null Nothing
+
+{-@ lll_worker :: n:Nat -> (Space (PVectorN n)) -> (Maybe (PVectorN n)) -> [(List Integer n)] -> (Space (PVectorN n)) @-}
+lll_worker (n :: Int) bs Nothing [] = bs
+lll_worker n bs Nothing (v:vs)      = lll_worker n bs (Just (makePVector v bs)) vs
+lll_worker n Null (Just pv) vs      = lll_worker n (makeSpace pv) Nothing vs
+lll_worker n (Real bn r) (Just pv) vs = 
+    let pv1 = sizeReduce pv
+        pv2 = liftPV pv1
+    in if (100*(dotPV pv2 pv2) < 99*r)
+       then lll_worker n (orthSpace_ bn) (Just pv2) (vec bn : vs)
+       else lll_worker n (makeSpace pv1) Nothing vs
+
+------------------------------------------------------------------------------------
+-- RJ: Included for illustration...
+------------------------------------------------------------------------------------
+
+{-@ type List a N = {v : [a] | (len v) = N} @-}
+
+{-@ zipWith :: (a -> b -> c) -> xs:[a] -> (List b (len xs)) -> (List c (len xs)) @-}
+zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
+zipWith _ [] []         = []
+zipWith _ (_:_) []      = liquidError "Dead Code"
+zipWith _ [] (_:_)      = liquidError "Dead Code"
diff --git a/tests/todo/list-screen.hs b/tests/todo/list-screen.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/list-screen.hs
@@ -0,0 +1,113 @@
+{-@ LIQUID "--no-termination" @-}
+
+module ListDemo where
+
+-----------------------------------------------------------------------
+-- 1. Lets define a List data-type
+-----------------------------------------------------------------------
+
+data List a = E | (:::) { h :: a, t :: List a }
+
+-- We'll want to use the "cons" in an infix fashion
+
+infixr  9 ::: 
+
+-- Ok, now here are some lists
+
+aList :: List Int
+aList = 0 ::: 2 ::: 7 ::: E
+
+-- Lets define some simple refinements.
+
+-- | The set of things  that are greater then `N`
+
+{-@ type Geq a N = {v:a | N <= v} @-}
+
+-- | now we can define the *natural* and *positive* numbers as:
+
+{-@ type Nat   = Geq Int 0    @-}
+{-@ type Grand = Geq Int 1000 @-}
+
+-- > Lets go back and see if we can refine our lists:
+
+{- up  :: List Grand @-}
+
+-- Whoops, that didn't work of course, how about
+
+{- up  :: List Nat  @-}
+
+-----------------------------------------------------------------------
+-- 2. Lets write a function that generates a sequence: n, n+1, n+2, ...
+-----------------------------------------------------------------------
+
+{-@ countUp :: n:Nat -> List Nat @-}
+countUp n  = n ::: countUp (n + 1)
+
+-- > How shall we type it? Well, one option:
+
+{- countUp :: n:Nat -> List Nat @-}
+
+-- So if you start with a `Nat` you get a list of `Nat`
+
+-- > How about 
+
+{- countUp :: n:Nat -> List Grand @-}
+
+-- Of course not! Lets see the error. Ah, so you can do:
+
+{- countUp :: n:Grand -> List Grand @-}
+
+
+-----------------------------------------------------------------------
+-- 3. ORDERED sequences ...
+-----------------------------------------------------------------------
+
+-- Now, really we want to say that `countUp` returns ORDERED sequences,
+-- i.e. it returns an INCREASING list of numbers (starting at `n`).
+
+-- Lets specify this by REFINING `List` to only allow INCREASING sequences ...
+
+-- > Lets look at the data type.
+-- > Key: INCREASING means `t` must ONLY contain values GREATER THAN head `h`.
+                                      
+-- that is,
+
+-- t :: List (Geq a h)
+
+-- lets specify that in a REFINED definition of `List`
+
+{-@ data List a = E | (:::) { h :: a, t :: List (Geq a h) } @-}
+
+-- Now lets look at some lists
+
+ups = 0 ::: 1 ::: 3 ::: E 
+
+-- But how about
+
+downs = 7 ::: 2 ::: E
+
+-- > Now lets go back and revisit `countUp` ... whoops there is an ERROR!
+-- > This is because we only know the TAIL is a list of Nat, we ALSO need that
+-- > the tail is greater than `n` and so ...
+
+{- countUp :: n:Nat -> List (Geq n) @-}
+
+
+insert x E          = x ::: E
+insert x (y ::: ys)
+  | x <= y          = x ::: y ::: ys
+  | otherwise       = y ::: insert x ys
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/todo/lit01.hs b/tests/todo/lit01.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/lit01.hs
@@ -0,0 +1,17 @@
+module Nats (poo) where
+
+import Language.Haskell.Liquid.Prelude 
+
+poo :: () 
+poo = liquidAssert (alice /= bob) () 
+
+-- && bob == charlie) ()
+
+alice :: String 
+alice = "I am a dog"
+
+bob :: String 
+bob = "I am a cat"
+
+charlie :: String 
+charlie = "I am a cat"
diff --git a/tests/todo/mapreduce.hs b/tests/todo/mapreduce.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/mapreduce.hs
@@ -0,0 +1,140 @@
+{-@ LIQUID "--higherorder"         @-}
+{-@ LIQUID "--totality"            @-}
+{-@ LIQUID "--exactdc"             @-}
+{-@ LIQUID "--no-measure-fields"   @-}
+
+
+module DivideAndQunquer where 
+
+import Prelude hiding (error, map, take, drop)
+import Language.Haskell.Liquid.ProofCombinators 
+
+{-@ reflect mapReduce @-}
+mapReduce :: Int -> (List a -> b) -> (b -> b -> b) -> List a -> b 
+mapReduce n f op N  = f N  
+mapReduce n f op is = reduce op (map f (chunk n is)) 
+
+chunk  :: Int -> List a -> List (List a)
+map    :: (a -> b) -> List a -> List b
+reduce :: (b -> b -> b) -> List b -> b  
+
+{-@ mapReduceTheorem :: n:Int -> f:(List a -> b) -> op:(b -> b -> b) -> is:List a
+      -> distributionThm:(is1:List a -> is2:List a -> {op (f is1) (f is2) == f (append is1 is2)} ) -> 
+      { f is == mapReduce n f op is } / [llen is] @-}
+mapReduceTheorem :: Int -> (List a -> b) -> (b -> b -> b) -> List a -> (List a -> List a -> Proof)  -> Proof 
+mapReduceTheorem n f op N _
+  =   mapReduce n f op N 
+  ==. f N 
+  *** QED 
+
+mapReduceTheorem n f op is _ 
+  | llen is <= n || n <= 1 
+  =   mapReduce n f op is 
+  ==. reduce op (map f (chunk n is))
+  ==. reduce op (map f (C is N))
+  ==. reduce op (f is `C` map f N)
+  ==. reduce op (f is `C` N)
+  ==. f is
+  *** QED 
+
+mapReduceTheorem n f op is distributionThm 
+  = undefined   
+{-  =   mapReduce n f op is 
+  ==. reduce op (map f (chunk n is))
+  ==. reduce op (map f (C (take n is) (chunk n (drop n is))))
+  ==. reduce op (f (take n is) `C` map f (chunk n (drop n is)))
+  ==. op (f (take n is)) (reduce op (map f (chunk n (drop n is))))
+  ==. op (f (take n is)) (mapReduce n f op (drop n is))
+  ==. op (f (take n is)) (f (drop n is))
+        ? mapReduceTheorem n f op (drop n is) distributionThm
+  ==. f (append (take n is) (drop n is))
+        ? distributionThm (take n is) (drop n is)
+  ==. f is 
+        ? appendTakeDrop n is
+  *** QED  
+ -}
+-------------------------------------------------------------------------------
+-----------  List Definition --------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+{-@ data List [llen] a = N | C {lhead :: a, ltail :: List a} @-}
+data List a = N | C a (List a)
+
+llen :: List a -> Int 
+{-@ measure llen @-}
+{-@ llen :: List a -> Nat @-}
+llen N        = 0 
+llen (C _ xs) = 1 + llen xs
+
+-------------------------------------------------------------------------------
+-----------  List Manipulation ------------------------------------------------
+-------------------------------------------------------------------------------
+{-@ reflect map @-}
+{-@ map :: (a -> b) -> xs:List a -> {v:List b | llen v == llen xs } @-}
+map _  N       = N
+map f (C x xs) = f x `C` map f xs 
+
+{-@ reflect append @-}
+append :: List a -> List a -> List a 
+append N        ys = ys  
+append (C x xs) ys = x `C` (append xs ys)
+
+{-@ reflect reduce @-}
+{-@ reduce :: (b -> b -> b) -> is:{List b | 1 <= llen is } -> b @-}  
+reduce _  (C x N)  = x 
+reduce op (C x xs) = op x (reduce op xs)
+
+{-@ reflect chunk @-}
+{-@ chunk :: i:Int -> xs:List a -> {v:List (List a) | (1 <= llen v) &&  (if (i <= 1 || llen xs <= i) then (llen v == 1) else (llen v < llen xs)) } / [llen xs] @-}
+chunk i xs 
+  | i <= 1 
+  = C xs N 
+  | llen xs <= i 
+  = C xs N 
+  | otherwise
+  = C (take i xs) (chunk i (drop i xs))
+
+{-@ reflect drop @-}
+{-@ drop :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == llen xs - i } @-} 
+drop :: Int -> List a -> List a 
+drop i N = N 
+drop i (C x xs)
+  | i == 0 
+  = C x xs  
+  | otherwise 
+  = drop (i-1) xs 
+
+{-@ reflect take @-}
+{-@ take :: i:Nat -> xs:{List a | i <= llen xs } -> {v:List a | llen v == i} @-} 
+take :: Int -> List a -> List a 
+take i N = N 
+take i (C x xs)
+  | i == 0 
+  = N  
+  | otherwise 
+  = C x (take (i-1) xs)
+
+-- | Helper Theorem 
+{-@ appendTakeDrop :: i:Nat -> xs:{List a | i <= llen xs} 
+  -> {xs == append (take i xs) (drop i xs) }  @-}
+
+appendTakeDrop :: Int -> List a -> Proof 
+appendTakeDrop i N 
+  =   append (take i N) (drop i N)
+  ==. append N N 
+  ==. N 
+  *** QED 
+appendTakeDrop i (C x xs)
+  | i == 0 
+  =   append (take 0 (C x xs)) (drop 0 (C x xs))
+  ==. append N (C x xs)
+  ==. C x xs 
+  *** QED 
+  | otherwise
+  =   append (take i (C x xs)) (drop i (C x xs))
+  ==. append (C x (take (i-1) xs)) (drop (i-1) xs)
+  ==. C x (append (take (i-1) xs) (drop (i-1) xs))
+  ==. C x xs ? appendTakeDrop (i-1) xs 
+  *** QED 
+
diff --git a/tests/todo/maps.hs b/tests/todo/maps.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/maps.hs
@@ -0,0 +1,36 @@
+module Maps where
+
+import Prelude hiding (lookup)
+import Data.Map
+
+{-@ prop0   :: _ -> x:_ -> y:{_ | y == x} -> TT @-}
+prop0       :: Map Int Int -> Int -> Int -> Bool
+prop0 m x y = (a == b)
+  where
+    a       = m ! x 
+    b       = m ! y 
+
+{-@ prop1   :: _ -> x:_ -> y:{_ | y /= x} -> TT @-}
+prop1       :: Map Int Int -> Int -> Int -> Bool
+prop1 m x y = (z == 10)
+  where
+    m1      = insert x 10 m 
+    m2      = insert y 20 m1
+    z       = m2 ! x 
+
+{-@ prop2   :: _ -> x:_ -> y:{_ | y == x} -> TT @-}
+prop2 m x y = (z == 20)
+  where
+    m1      = insert x 10 m 
+    m2      = insert y 20 m1
+    z       = m2 ! x
+
+-----------------------------------------------------------------------
+
+{-@ embed Map as Map_t @-}
+{-@ measure Map_select :: Map k v -> k -> v @-}
+{-@ measure Map_store  :: Map k v -> k -> v -> Map k v @-}
+{-@ assume (!)         :: (Ord k) => m:Map k v -> k:k -> {v:v | v = Map_select m k} @-}
+{-@ assume insert      :: (Ord k) => key:k -> value:v -> m:Map k v -> {n:Map k v | n = Map_store m key value} @-}
+
+-----------------------------------------------------------------------
diff --git a/tests/todo/maybe0.hs b/tests/todo/maybe0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/maybe0.hs
@@ -0,0 +1,45 @@
+module Foo where
+
+-- remove the ! and it is safe...
+data MaybeS a = NothingS | JustS !a
+
+{-@ measure isJustS :: forall a. MaybeS a -> Bool 
+    isJustS (JustS x)  = true
+    isJustS (NothingS) = false
+  @-}
+
+{-@ measure fromJustS :: forall a. MaybeS a -> a
+    fromJustS (JustS x) = x 
+  @-}
+
+gloop = poop True
+
+{-@ poop :: z:a -> {v: MaybeS a | fromJustS(v) = z} @-}
+poop z = JustS z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/todo/maybe0000.hs b/tests/todo/maybe0000.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/maybe0000.hs
@@ -0,0 +1,55 @@
+module Foo where
+
+data MaybeS a = NothingS | JustS a
+
+-- crashes with : 
+-- Fixpoint: Testing Solution 
+-- z3Pred: error converting && [ (isJust(lq_anf__ddc) <=> false)
+--                             ; (lq_anf__ddc = ds_dd9)
+--                             ; (fromJustS([gloop#r9K]) = True#6u)
+--                             ; (Bexp True#6u)
+--                             ; (~ ((Bexp False#68)))]
+--
+-- Fatal error: exception Failure("Z3: type error")
+
+
+myisJust :: Maybe a -> Bool
+myisJust Nothing  = True
+myisJust (Just x) = False
+
+{-@ measure fromJustS :: MaybeS a -> a
+    fromJustS (JustS x) = x 
+  @-}
+
+gloop :: MaybeS Bool
+gloop = poop True
+
+{- poop :: z:a -> {v: MaybeS a | fromJustS(v) = z} @-}
+poop z = JustS z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/todo/maybe4.hs b/tests/todo/maybe4.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/maybe4.hs
@@ -0,0 +1,17 @@
+module Foo where
+
+
+moo = poo z z 
+  where z       = blerg True 
+        blerg True = Nothing
+
+{-@ poo :: x:Maybe a -> {v: Maybe a | v = x } -> Bool @-}
+poo :: Maybe a -> Maybe a -> Bool
+poo x y = True
+
+
+
+
+
+
+
diff --git a/tests/todo/measbug.hs b/tests/todo/measbug.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/measbug.hs
@@ -0,0 +1,15 @@
+module MeasureBug where
+
+data Heap a   = Empty | Node { pri   :: a
+                             , rnk   :: Int 
+                             , left  :: Heap a
+                             , right :: Heap a
+                             }
+{-@ data Heap [zoo] @-}
+
+{-@ invariant {v:Heap a| (zoo v) >=0} @-}
+
+{-@ measure zoo @-}
+zoo :: Heap a -> Int
+zoo (Empty)        = 0
+zoo (Node _ _ l r) = 1 + zoo l + zoo r
diff --git a/tests/todo/measfield.hs b/tests/todo/measfield.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/measfield.hs
@@ -0,0 +1,11 @@
+module Goo (Vec (..)) where
+
+data Vec a = V { vsz :: Int, velems :: [a] }
+
+{-@ data Vec a  = V { vsz :: Int, velems :: {v:[a] | len v = vsz} } @-}
+
+{-@ foo :: x:Vec a -> {v:[a] | len v = vsz x} @-}
+foo v = velems v 
+
+{-@ bar :: x:Vec a -> {v:[a] | len v = vsz x} @-}
+bar (V _ ys) = ys 
diff --git a/tests/todo/overload.hs b/tests/todo/overload.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/overload.hs
@@ -0,0 +1,21 @@
+module Overload where
+
+import Data.Monoid
+
+bar1, bar2 :: List Int
+
+type List a = [a]
+
+{-@ type ListN a N = { v:[a] | len v == N } @-}
+
+{-@ instance Monoid (List a) where
+      mempty  :: ListN a 0
+      mappend :: xs:[a] -> ys:[a] -> ListN a {len xs + len ys}
+      mconcat :: List (List a) -> List a
+  @-}
+
+{-@ bar1 :: ListN Int 6 @-}
+bar1 = [1,2,3] ++ [4,5,6]
+
+{-@ bar2 :: ListN Int 6 @-}
+bar2 = [1,2,3] <> [4,5,6]
diff --git a/tests/todo/partialmeasureOld.hs b/tests/todo/partialmeasureOld.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/partialmeasureOld.hs
@@ -0,0 +1,21 @@
+module Head where
+
+{-@ measure hd :: [a] -> a
+    hd (x:xs) = x
+  @-}
+
+-- Strengthened constructors
+--   data [a] where
+--     []  :: [a]    -- as before
+--     (:) :: x:a -> xs:[a] -> {v:[a] | hd v = x}
+
+{-@ cons :: x:a -> _ -> {v:[a] | hd v = x} @-}
+cons x xs = x : xs
+
+{-@ test :: {v:_ | hd v = 0} @-}
+test     :: [Int]
+test     =  cons 0 [1,2,3,4]
+
+
+
+
diff --git a/tests/todo/ptr.hs b/tests/todo/ptr.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ptr.hs
@@ -0,0 +1,195 @@
+{--! run liquid with idirs=../../benchmarks/bytestring-0.9.2.1 idirs=../../include no-termination -}
+{-# OPTIONS_GHC -cpp -fglasgow-exts -fno-warn-orphans #-}
+
+-- GET THIS TO WORK WITHOUT THE "base" measure and realated theorem,
+-- but with raw pointer arithmetic. I.e. give plusPtr the right signature:
+--   (v = base + off)
+-- Can do so now, by:
+--
+--   embed Ptr as int 
+--
+-- but the problem is that then it throws off all qualifier definitions like
+--  
+--   qualif EqPLen(v: ForeignPtr a, x: Ptr a): (fplen v) = (plen x)
+--   qualif EqPLen(v: Ptr a, x: ForeignPtr a): (plen v) = (fplen x) 
+-- 
+-- because there is no such thing as Ptr a by the time we get to Fixpoint. yuck.
+-- Meaning we have to rewrite the above to the rather lame:
+
+--   qualif EqPLenPOLY2(v: a, x: b): (plen v) = (fplen x)           
+
+
+module Data.ByteString (
+        ByteString,            -- abstract, instances: Eq, Ord, Show, Read, Data, Typeable, Monoid
+        foldl                  -- :: (a -> Word8 -> a) -> a -> ByteString -> a
+  ) where
+
+import Language.Haskell.Liquid.Prelude
+
+import qualified Prelude as P
+import Prelude hiding           (reverse,head,tail,last,init,null
+                                ,length,map,lines,foldl,foldr,unlines
+                                ,concat,any,take,drop,splitAt,takeWhile
+                                ,dropWhile,span,break,elem,filter,maximum
+                                ,minimum,all,concatMap,foldl1,foldr1
+                                ,scanl,scanl1,scanr,scanr1
+                                ,readFile,writeFile,appendFile,replicate
+                                ,getContents,getLine,putStr,putStrLn,interact
+                                ,zip,zipWith,unzip,notElem)
+
+import Data.ByteString.Internal
+import Data.ByteString.Unsafe
+import Data.ByteString.Fusion
+
+import qualified Data.List as List
+
+import Data.Word                (Word8)
+import Data.Maybe               (listToMaybe)
+import Data.Array               (listArray)
+import qualified Data.Array as Array ((!))
+
+-- Control.Exception.bracket not available in yhc or nhc
+#ifndef __NHC__
+import Control.Exception        (bracket, assert)
+import qualified Control.Exception as Exception
+#else
+import IO			(bracket)
+#endif
+import Control.Monad            (when)
+
+import Foreign.C.String         (CString, CStringLen)
+import Foreign.C.Types          (CSize)
+import Foreign.ForeignPtr
+import Foreign.Marshal.Alloc    (allocaBytes, mallocBytes, reallocBytes, finalizerFree)
+import Foreign.Marshal.Array    (allocaArray)
+import Foreign.Ptr
+import Foreign.Storable         (Storable(..))
+
+-- hGetBuf and hPutBuf not available in yhc or nhc
+import System.IO                (stdin,stdout,hClose,hFileSize
+                                ,hGetBuf,hPutBuf,openBinaryFile
+                                ,Handle,IOMode(..))
+
+import Data.Monoid              (Monoid, mempty, mappend, mconcat)
+
+#if !defined(__GLASGOW_HASKELL__)
+import System.IO.Unsafe
+import qualified System.Environment
+import qualified System.IO      (hGetLine)
+#endif
+
+#if defined(__GLASGOW_HASKELL__)
+
+import System.IO                (hGetBufNonBlocking)
+import System.IO.Error          (isEOFError)
+
+import GHC.Handle
+import GHC.Prim                 (Word#, (+#), writeWord8OffAddr#)
+import GHC.Base                 (build)
+import GHC.Word hiding (Word8)
+import GHC.Ptr                  (Ptr(..))
+import GHC.ST                   (ST(..))
+import GHC.IOBase
+
+#endif
+
+-- An alternative to Control.Exception (assert) for nhc98
+#ifdef __NHC__
+#define assert  assertS "__FILE__ : __LINE__"
+assertS :: String -> Bool -> a -> a
+assertS _ True  = id
+assertS s False = error ("assertion failed at "++s)
+#endif
+
+-- LIQUID
+import GHC.IO.Buffer
+import Language.Haskell.Liquid.Prelude (intCSize)
+import qualified Data.ByteString.Lazy.Internal 
+import qualified Data.ByteString.Fusion
+import qualified Data.ByteString.Internal
+import qualified Data.ByteString.Unsafe
+import qualified Foreign.C.Types
+
+{-@ memcpy_ptr_baoff :: p:(Ptr a) 
+                     -> RawBuffer b 
+                     -> Int 
+                     -> {v:CSize | (OkPLen v p)} -> IO (Ptr ())
+  @-}
+memcpy_ptr_baoff :: Ptr a -> RawBuffer b -> Int -> CSize -> IO (Ptr ())
+memcpy_ptr_baoff = error "LIQUIDCOMPAT"
+
+readCharFromBuffer :: RawBuffer b -> Int -> IO (Char, Int)
+readCharFromBuffer x y = error "LIQUIDCOMPAT"
+
+wantReadableHandleLIQUID :: String -> Handle -> (Handle__ -> IO a) -> IO a
+wantReadableHandleLIQUID x y f = error $ show $ liquidCanaryFusion 12 -- "LIQUIDCOMPAT"
+
+{-@ qualif Gimme(v:a, n:b, acc:a): (len v) = (n + 1 + (len acc)) @-}
+{-@ qualif Zog(v:a, p:a)         : (plen p) <= (plen v)          @-}
+{-@ qualif Zog(v:a)              : 0 <= (plen v)                 @-}
+
+{- type ByteStringNE   = {v:ByteString | (bLength v) > 0} @-}
+{- type ByteStringSZ B = {v:ByteString | (bLength v) = (bLength B)} @-}
+-- -----------------------------------------------------------------------------
+--
+-- Useful macros, until we have bang patterns
+--
+
+#define STRICT1(f) f a | a `seq` False = undefined
+#define STRICT2(f) f a b | a `seq` b `seq` False = undefined
+#define STRICT3(f) f a b c | a `seq` b `seq` c `seq` False = undefined
+#define STRICT4(f) f a b c d | a `seq` b `seq` c `seq` d `seq` False = undefined
+#define STRICT5(f) f a b c d e | a `seq` b `seq` c `seq` d `seq` e `seq` False = undefined
+
+-- -----------------------------------------------------------------------------
+
+{-@ foldl :: (a -> Word8 -> a) -> a -> ByteString -> a @-}
+foldl :: (a -> Word8 -> a) -> a -> ByteString -> a
+foldl f v (PS x s l) = inlinePerformIO $ withForeignPtr x $ \ptr ->
+        lgo v (ptr `plusPtr` s) (ptr `plusPtr` (s+l))
+    where
+        STRICT3(lgo)
+        lgo z p q | eqPtr p q    = return z
+                  | otherwise = do c <- peek p
+                                   lgo (f z c) (p `plusPtr` 1) q
+{-# INLINE foldl #-}
+
+{- liquid_thm_ptr_cmp :: p:PtrV a
+                       -> q:{v:(PtrV a) | ((plen v) <= (plen p) && v != p && (pbase v) = (pbase p))} 
+                       -> {v: (PtrV a)  | ((v = p) && ((plen q) < (plen p))) } 
+  @-}
+liquid_thm_ptr_cmp :: Ptr a -> Ptr a -> Ptr a
+liquid_thm_ptr_cmp p q = p 
+
+-- | 'foldl\'' is like 'foldl', but strict in the accumulator.
+-- Though actually foldl is also strict in the accumulator.
+foldl' :: (a -> Word8 -> a) -> a -> ByteString -> a
+foldl' = foldl
+{-# INLINE foldl' #-}
+
+
+-- | Perform an operation with a temporary ByteString
+withPtr :: ForeignPtr a -> (Ptr a -> IO b) -> b
+withPtr fp io = inlinePerformIO (withForeignPtr fp io)
+{-# INLINE withPtr #-}
+
+-- Common up near identical calls to `error' to reduce the number
+-- constant strings created when compiled:
+{-@ errorEmptyList :: {v:String | false} -> a @-}
+errorEmptyList :: String -> a
+errorEmptyList fun = moduleError fun "empty ByteString"
+{-# NOINLINE errorEmptyList #-}
+
+moduleError :: String -> String -> a
+moduleError fun msg = error ("Data.ByteString." ++ fun ++ ':':' ':msg)
+{-# NOINLINE moduleError #-}
+
+-- LIQUID -- -- Find from the end of the string using predicate
+-- LIQUID -- findFromEndUntil :: (Word8 -> Bool) -> ByteString -> Int
+-- LIQUID -- STRICT2(findFromEndUntil)
+-- LIQUID -- findFromEndUntil f ps@(PS x s l) =
+-- LIQUID --     if null ps then 0
+-- LIQUID --     else if f (last ps) then l
+-- LIQUID --          else findFromEndUntil f (PS x s (l-1))
+
+
diff --git a/tests/todo/ptr2.hs b/tests/todo/ptr2.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ptr2.hs
@@ -0,0 +1,146 @@
+{-@ LIQUID "--idirs=../../benchmarks/bytestring-0.9.2.1/" @-}
+{-@ LIQUID "--idirs=../../include" @-}
+{-@ LIQUID "--no-termination" @-}
+{-# OPTIONS_GHC -cpp -fglasgow-exts -fno-warn-orphans #-}
+
+-- look for `n0` and `n1` below. Why does this work with `n1` but not `n0` or `0-1` ?
+-- the latter is likely some wierd qualifier issue.
+
+
+module Data.ByteString (
+        ByteString,            -- abstract, instances: Eq, Ord, Show, Read, Data, Typeable, Monoid
+        foldr                  -- :: (a -> Word8 -> a) -> a -> ByteString -> a
+  , wantReadableHandleLIQUID
+  ) where
+
+
+import qualified Prelude as P
+import Prelude hiding           (reverse,head,tail,last,init,null
+                                ,length,map,lines,foldl,foldr,unlines
+                                ,concat,any,take,drop,splitAt,takeWhile
+                                ,dropWhile,span,break,elem,filter,maximum
+                                ,minimum,all,concatMap,foldl1,foldr1
+                                ,scanl,scanl1,scanr,scanr1
+                                ,readFile,writeFile,appendFile,replicate
+                                ,getContents,getLine,putStr,putStrLn,interact
+                                ,zip,zipWith,unzip,notElem)
+
+import Data.ByteString.Internal
+import Data.ByteString.Unsafe
+import Data.ByteString.Fusion
+
+import qualified Data.List as List
+
+import Data.Word                (Word8)
+import Data.Maybe               (listToMaybe)
+import Data.Array               (listArray)
+import qualified Data.Array as Array ((!))
+
+-- Control.Exception.bracket not available in yhc or nhc
+#ifndef __NHC__
+import Control.Exception        (bracket, assert)
+import qualified Control.Exception as Exception
+#else
+import IO			(bracket)
+#endif
+import Control.Monad            (when)
+
+import Foreign.C.String         (CString, CStringLen)
+import Foreign.C.Types          (CSize)
+import Foreign.ForeignPtr
+import Foreign.Marshal.Alloc    (allocaBytes, mallocBytes, reallocBytes, finalizerFree)
+import Foreign.Marshal.Array    (allocaArray)
+import Foreign.Ptr
+import Foreign.Storable         (Storable(..))
+
+-- hGetBuf and hPutBuf not available in yhc or nhc
+import System.IO                (stdin,stdout,hClose,hFileSize
+                                ,hGetBuf,hPutBuf,openBinaryFile
+                                ,Handle,IOMode(..))
+
+import Data.Monoid              (Monoid, mempty, mappend, mconcat)
+
+#if !defined(__GLASGOW_HASKELL__)
+import System.IO.Unsafe
+import qualified System.Environment
+import qualified System.IO      (hGetLine)
+#endif
+
+#if defined(__GLASGOW_HASKELL__)
+
+import System.IO                (hGetBufNonBlocking)
+import System.IO.Error          (isEOFError)
+
+import GHC.Handle
+import GHC.Prim                 (Word#, (+#), writeWord8OffAddr#)
+import GHC.Base                 (build)
+import GHC.Word hiding (Word8)
+import GHC.Ptr                  (Ptr(..))
+import GHC.ST                   (ST(..))
+import GHC.IOBase
+
+#endif
+
+-- An alternative to Control.Exception (assert) for nhc98
+#ifdef __NHC__
+#define assert  assertS "__FILE__ : __LINE__"
+assertS :: String -> Bool -> a -> a
+assertS _ True  = id
+assertS s False = error ("assertion failed at "++s)
+#endif
+
+-- LIQUID
+import GHC.IO.Buffer
+import Language.Haskell.Liquid.Foreign (intCSize, eqPtr) 
+import qualified Data.ByteString.Lazy.Internal 
+import qualified Data.ByteString.Fusion
+import qualified Data.ByteString.Internal
+import qualified Data.ByteString.Unsafe
+import qualified Foreign.C.Types
+
+{-@ memcpy_ptr_baoff :: p:(Ptr a) 
+                     -> RawBuffer b 
+                     -> Int 
+                     -> {v:CSize | (OkPLen v p)} -> IO (Ptr ())
+  @-}
+memcpy_ptr_baoff :: Ptr a -> RawBuffer b -> Int -> CSize -> IO (Ptr ())
+memcpy_ptr_baoff = error "LIQUIDCOMPAT"
+
+readCharFromBuffer :: RawBuffer b -> Int -> IO (Char, Int)
+readCharFromBuffer x y = error "LIQUIDCOMPAT"
+
+wantReadableHandleLIQUID :: String -> Handle -> (Handle__ -> IO a) -> IO a
+wantReadableHandleLIQUID x y f = error $ show $ liquidCanaryFusion 12 -- "LIQUIDCOMPAT"
+
+{-@ qualif Gimme(v:a, n:b, acc:a): (len v) = (n + 1 + (len acc)) @-}
+{-@ qualif Zog(v:a, p:a)         : (plen p) <= (plen v)          @-}
+{-@ qualif Zog(v:a)              : 0 <= (plen v)                 @-}
+
+{- type ByteStringNE   = {v:ByteString | (bLength v) > 0} @-}
+{- type ByteStringSZ B = {v:ByteString | (bLength v) = (bLength B)} @-}
+-- -----------------------------------------------------------------------------
+--
+-- Useful macros, until we have bang patterns
+--
+-- -----------------------------------------------------------------------------
+{-@ foldr :: (Word8 -> a -> a) -> a -> ByteString -> a @-}
+foldr :: (Word8 -> a -> a) -> a -> ByteString -> a
+foldr k v (PS x s l) = inlinePerformIO $ withForeignPtr x $ \ptr ->
+        ugo k v (ptr `plusPtr` (s+l-1)) (ptr `plusPtr` (s-1))
+
+{-@ ugo :: (Word8 -> a -> a) -> a -> p:(PtrV Word8) -> {v:Ptr Word8 | ((pbase v) = (pbase p) &&  (plen v) >= (plen p)) } -> IO a @-}
+ugo :: (Word8 -> a -> a) -> a -> Ptr Word8 -> Ptr Word8 -> IO a
+ugo k z p q | eqPtr q p   = return z
+            | otherwise = do c  <- peek p
+                             let n0  = -1               -- BAD  
+                             let n1  = 0 - 1            -- OK
+                             let p' = p `plusPtr` n1 {- BAD (0 - 1) -}
+                             ugo k (c `k` z) p' q -- tail recursive
+
+
+{- liquid_thm_ptr_cmp' :: p:PtrV a
+                        -> q:{v:(PtrV a) | ((plen v) >= (plen p) && v != p && (pbase v) = (pbase p))} 
+                        -> {v: (PtrV a)  | ((v = p) && ((plen v) > 0) && ((plen q) > (plen p))) } 
+  @-}
+liquid_thm_ptr_cmp' :: Ptr a -> Ptr a -> Ptr a
+liquid_thm_ptr_cmp' p q = undefined 
diff --git a/tests/todo/ptr3.hs b/tests/todo/ptr3.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/ptr3.hs
@@ -0,0 +1,117 @@
+{--! run liquid with idirs=../../benchmarks/bytestring-0.9.2.1 idirs=../../include no-termination -}
+{-# OPTIONS_GHC -cpp -fglasgow-exts -fno-warn-orphans #-}
+
+-- look for `n0` and `n1` below. Why does this work with `n1` but not `n0` or `0-1` ?
+-- the latter is likely some wierd qualifier issue.
+
+
+module Data.ByteString (
+        ByteString,            -- abstract, instances: Eq, Ord, Show, Read, Data, Typeable, Monoid
+  ) where
+
+import Language.Haskell.Liquid.Prelude
+
+import qualified Prelude as P
+import Prelude hiding           (reverse,head,tail,last,init,null
+                                ,length,map,lines,foldl,foldr,unlines
+                                ,concat,any,take,drop,splitAt,takeWhile
+                                ,dropWhile,span,break,elem,filter,maximum
+                                ,minimum,all,concatMap,foldl1,foldr1
+                                ,scanl,scanl1,scanr,scanr1
+                                ,readFile,writeFile,appendFile,replicate
+                                ,getContents,getLine,putStr,putStrLn,interact
+                                ,zip,zipWith,unzip,notElem)
+
+import Data.ByteString.Internal
+import Data.ByteString.Unsafe
+import Data.ByteString.Fusion
+
+import qualified Data.List as List
+
+import Data.Word                (Word8)
+import Data.Maybe               (listToMaybe)
+import Data.Array               (listArray)
+import qualified Data.Array as Array ((!))
+
+-- Control.Exception.bracket not available in yhc or nhc
+#ifndef __NHC__
+import Control.Exception        (bracket, assert)
+import qualified Control.Exception as Exception
+#else
+import IO			(bracket)
+#endif
+import Control.Monad            (when)
+
+import Foreign.C.String         (CString, CStringLen)
+import Foreign.C.Types          (CSize)
+import Foreign.ForeignPtr
+import Foreign.Marshal.Alloc    (allocaBytes, mallocBytes, reallocBytes, finalizerFree)
+import Foreign.Marshal.Array    (allocaArray)
+import Foreign.Ptr
+import Foreign.Storable         (Storable(..))
+
+-- hGetBuf and hPutBuf not available in yhc or nhc
+import System.IO                (stdin,stdout,hClose,hFileSize
+                                ,hGetBuf,hPutBuf,openBinaryFile
+                                ,Handle,IOMode(..))
+
+import Data.Monoid              (Monoid, mempty, mappend, mconcat)
+
+#if !defined(__GLASGOW_HASKELL__)
+import System.IO.Unsafe
+import qualified System.Environment
+import qualified System.IO      (hGetLine)
+#endif
+
+#if defined(__GLASGOW_HASKELL__)
+
+import System.IO                (hGetBufNonBlocking)
+import System.IO.Error          (isEOFError)
+
+import GHC.Handle
+import GHC.Prim                 (Word#, (+#), writeWord8OffAddr#)
+import GHC.Base                 (build)
+import GHC.Word hiding (Word8)
+import GHC.Ptr                  (Ptr(..))
+import GHC.ST                   (ST(..))
+import GHC.IOBase
+
+#endif
+
+-- An alternative to Control.Exception (assert) for nhc98
+#ifdef __NHC__
+#define assert  assertS "__FILE__ : __LINE__"
+assertS :: String -> Bool -> a -> a
+assertS _ True  = id
+assertS s False = error ("assertion failed at "++s)
+#endif
+
+-- LIQUID
+import GHC.IO.Buffer
+import Language.Haskell.Liquid.Prelude (intCSize) 
+import qualified Data.ByteString.Lazy.Internal 
+import qualified Data.ByteString.Fusion
+import qualified Data.ByteString.Internal
+import qualified Data.ByteString.Unsafe
+import qualified Foreign.C.Types
+
+-- WHY ON EARTH IS THAT LIQUIDASSERT NEEDED?!!!!
+
+{-@ split :: Word8 -> ByteStringNE -> [ByteString] @-}
+split :: Word8 -> ByteString -> [ByteString]
+-- split _ (PS _ _ 0) = []
+split w (PS xanadu s l) = inlinePerformIO $ withForeignPtr xanadu $ \pz -> do
+    let p   = liquidAssert (fpLen xanadu == pLen pz) pz
+    let ptr = p `plusPtr` s
+        loop n =
+            let q = inlinePerformIO $ memchr (ptr `plusPtr` n)
+                                           w (fromIntegral (l-n))
+            in if isNullPtr q {- LIQUID q == nullPtr -}
+                then [PS xanadu (s+n) (l-n)]
+                else let i' = q `minusPtr` ptr 
+                         i  = liquidAssert (i < l) i'       -- LIQUID MYSTERY: why is assert NEEDED HERE (it is!)
+                     in PS xanadu (s+n) (i-n) : loop (i+1)
+
+    return (loop 0)
+
+
diff --git a/tests/todo/read.hs b/tests/todo/read.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/read.hs
@@ -0,0 +1,8 @@
+module Read where
+
+import Language.Haskell.Liquid.Prelude
+
+data Foo = Foo deriving Read
+
+bad  = liquidAssertB (0 == 1)
+bad' = liquidAssert  (0 == 1) True
diff --git a/tests/todo/satsolver.hs b/tests/todo/satsolver.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/satsolver.hs
@@ -0,0 +1,56 @@
+module SatSolver where
+
+-- | Formula
+
+type Var     = Int
+data Lit     = Pos Var | Neg Var
+type Clause  = [Lit]
+type Formula = [Clause]
+
+-- | Assignment
+
+type Asgn = [(Var, Bool)]
+
+-- | Top-level "solver"
+
+{-@ solve :: f:_ -> Maybe {a:Asgn | sat a f} @-}
+solve   :: Formula -> Maybe Asgn
+solve f = find (\a -> sat a f) (asgns f) 
+
+find :: (a -> Bool) -> [a] -> Maybe a
+find f [] = Nothing
+find f (x:xs) | f x       = Just x 
+              | otherwise = Nothing 
+-- | Generate all assignments
+
+asgns :: Formula -> [Asgn] -- generates all possible T/F vectors
+asgns = undefined
+ 
+
+-- | Satisfaction
+
+{-@ measure sat @-}
+sat :: Asgn -> Formula -> Bool
+sat a []         = True
+sat a (c:cs)     = satCls a c && sat a cs
+
+{-@ measure satCls @-}
+satCls :: Asgn -> Clause -> Bool
+satCls a []      = False
+satCls a (l:ls)  = satLit a l || satCls a ls
+
+{-@ measure satLit @-}
+satLit :: Asgn -> Lit -> Bool
+satLit a (Pos x) = isTrue x a 
+satLit a (Neg x) = isFalse x a
+
+{-@ measure isTrue @-}
+isTrue           :: Var -> Asgn -> Bool
+isTrue x ((y, v):as)  = if x == y then v else isTrue x as 
+isTrue _ []           = False 
+
+{-@ measure isFalse @-}
+isFalse          :: Var -> Asgn -> Bool
+isFalse x ((y, v):as) = if x == y then not v else isFalse x as 
+isFalse _ []          = False 
+
diff --git a/tests/todo/satsolver0.hs b/tests/todo/satsolver0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/satsolver0.hs
@@ -0,0 +1,62 @@
+module SatSolver where
+
+{-@ LIQUID "--no-termination" @-}
+
+-- | Formula
+
+type Var     = Int
+data Lit     = Pos Var | Neg Var
+type Clause  = [Lit]
+type Formula = [Clause]
+
+-- | Assignment
+
+type Asgn = [(Var, Bool)]
+
+-- | Top-level "solver"
+
+{-@ solve :: f:_ -> Maybe {a:Asgn | Prop (sat a f)} @-}
+solve   :: Formula -> Maybe Asgn
+solve f = go (asgns f)
+  where
+  	go []     = Nothing
+  	go (x:xs) | sat x f = Just x
+  	          | otherwise = go xs 
+
+-- | Generate all assignments
+
+asgns :: Formula -> [Asgn] -- generates all possible T/F vectors
+asgns = undefined
+ 
+
+-- | Satisfaction
+
+{-@ measure sat :: Asgn -> Formula -> Bool @-}
+sat :: Asgn -> Formula -> Bool
+{-@ sat :: a:Asgn -> f:Formula -> {v:Bool | Prop (sat a f)} @-}
+sat a []         = True
+sat a (c:cs)     = satCls a c && sat a cs
+
+{- measure satCls @-}
+satCls :: Asgn -> Clause -> Bool
+satCls a []      = False
+satCls a (l:ls)  = satLit a l || satCls a ls
+
+{- measure satLit @-}
+satLit :: Asgn -> Lit -> Bool
+satLit a (Pos x) = isTrue x a 
+satLit a (Neg x) = isFalse x a
+
+{- measure isTrue @-}
+isTrue           :: Var -> Asgn -> Bool
+isTrue x ((y, v):as)  = if x == y then v else isTrue x as 
+isTrue _ []           = False 
+
+{- measure isFalse @-}
+isFalse          :: Var -> Asgn -> Bool
+isFalse x ((y, v):as) = if x == y then not v else isFalse x as 
+isFalse _ []          = False
+
+
+
+
diff --git a/tests/todo/splash-total.hs b/tests/todo/splash-total.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/splash-total.hs
@@ -0,0 +1,162 @@
+{-@ LIQUID "--totality" @-}
+
+module SplashTotal where
+
+import Prelude hiding (foldr1, head)
+
+head       :: [a] -> a
+incr       :: Int -> Int
+average    :: [Int] -> Int
+group      :: (Eq a) => [a] -> [[a]]
+foldr1     :: (a -> a -> a) -> [a] -> a
+impossible :: String -> a
+merge      :: Ord a => [a] -> [a] ->  [a]
+fib        :: Int -> Int
+ups        :: [Int]
+insertSort :: (Ord a) => [a] -> [a]
+insert     :: (Ord a) => a -> [a] -> [a]
+
+-- REPLACE `-` with `+`
+
+{-@ incr :: Nat -> Nat @-}
+incr x = x + 1
+
+{-@ impossible :: {v: String | False} -> a @-}
+impossible = error
+
+--------------------------------------------------------------------------------
+
+-- TOTALITY A 1
+{- type NonEmpty a = {v:[a] | 0 < len v } @-}
+
+-- replace input with NonEmpty a
+
+
+
+
+
+
+
+{-@ type NonEmpty a = {v:[a] | 0 < len v} @-}
+
+{-@ head :: NonEmpty a -> a @-}
+head (x:_) = x
+
+
+
+
+
+
+-- head []    = impossible "head on empty list"
+
+
+
+
+
+
+
+
+
+
+-- TOTALITY A 2
+
+-- replace output with NonEmpty a
+
+
+-- >>> unstutter "ssslllyttthhherrrinnn"
+-- "slytherin"
+unstutter :: String -> String
+unstutter = map head . group
+
+{-@ group :: (Eq a) => [a] -> [[a]] @-}
+group []      = []
+group (x:xs)  = (x:ys) : group zs
+  where
+    (ys, zs)  = span (x ==) xs
+
+
+
+--------------------------------------------------------------------------------
+-- replace input with NonEmpty a
+-- ADD signature: foldr1 :: (a -> a -> a) -> {v:[a] | len v > 0} -> a
+
+
+{-@ foldr1 :: (a -> a -> a) -> [a] -> a @-}
+foldr1 op (x:xs) = foldr op x xs
+foldr1 _  _      = impossible "foldr1 on empty list"
+
+{-@ average :: [Int] -> Int @-}
+average xs = foldr1 (+) xs `div` length xs
+
+
+--------------------------------------------------------------------------------
+
+-- TERMINATION
+-- ADD / [len xs + len ys]
+
+
+{-@ fib :: Nat -> Nat @-}
+fib 0 = 1
+fib 1 = 1
+fib n = fib (n-1) + fib (n-2)
+
+
+
+
+
+
+                                              -- .
+
+{-@ merge :: Ord a => xs:[a] -> ys:[a] -> [a]
+                    / [ len xs + len ys]  @-}
+merge xs []         = xs
+merge [] ys         = ys
+merge (x:xs) (y:ys)
+  | x <= y          = x : merge xs (y:ys)
+  | otherwise       = y : merge (x:xs) ys
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------------
+
+-- type OrdList a = [a]<{\x v -> x <= v}>       .
+-- USER DEFINED INVARIANTS
+
+{-@ type OrdList a = [a]<{\x v -> x <= v}> @-}
+
+
+{-@ ups :: OrdList Int @-}
+ups = [1, 2, 3, 4, 5]
+
+{-@ insertSort :: (Ord a) => [a] -> OrdList a @-}
+insertSort = foldr insert []
+
+{-@ insert :: (Ord a) => a -> OrdList a -> OrdList a @-}
+insert x []     = [x]
+insert x (y:ys)
+  | x <= y      = x : y : ys
+  | otherwise   = y : insert x ys
+
+
+
+
+
+--------------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------------
diff --git a/tests/todo/splash-vector.hs b/tests/todo/splash-vector.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/splash-vector.hs
@@ -0,0 +1,81 @@
+{-# LANGUAGE OverloadedStrings #-}
+module SplashVector where
+
+import Prelude hiding (length)
+import Data.Vector (Vector, (!), length)
+-- import qualified Data.Vector            as V
+import qualified Data.ByteString        as B
+import qualified Data.ByteString.Unsafe as B
+
+vectorSum :: (Num a) => Vector a -> a
+dotProduct :: (Num a) => Vector a -> Vector a -> a
+
+-- vectorSum  :: `[0 .. n] ` with `[0 .. n - 1]`
+-- dotProduct :: (Num a) => x:Vector a -> {y:Vector a | vlen y = vlen x} -> a
+-- type VectorN a N = {v:Vector a | vlen v == N}
+-- dotProduct :: (Num a) => x:Vector a -> VectorN a {vlen x} -> a
+
+
+
+{-@ vectorSum :: (Num a) => Vector a -> a @-}
+vectorSum x = sum [ x ! i | i <- [ 0 .. n - 1 ]]
+  where
+    n       = length x
+
+
+{-@ type VectorN a N = {v:Vector a | vlen v == N} @-}
+
+{- type VectorX a X = {v:Vector a | vlen v == vlen X} -}
+
+{-@ type VectorEq a X = {v:Vector a | vlen v == vlen X} @-}
+
+{-@ dotProduct :: (Num a) => x:Vector a -> VectorEq a x -> a @-}
+dotProduct x y = sum [ (x ! i) * (y ! i) | i <- [0 .. n - 1]]
+  where
+    n          = length x
+
+
+
+
+
+
+-- 60
+-- 6
+-- 16
+-- 14
+
+
+liquid :: B.ByteString
+liquid = B.unsafeTake 14 (pack "LiquidHaskell  ")
+
+
+
+{-@ assume pack :: s:String -> {v:B.ByteString | bslen v == len s} @-}
+pack :: String -> B.ByteString
+pack = undefined
+
+{-@ foo :: n:Int -> [{v:Nat | v <= n}] @-}
+foo :: Int -> [Int]
+foo n = [0 .. n]
+
+{-@ assume GHC.Enum.enumFromTo :: (Enum a) => lo:a -> hi:a -> [{v:a | lo <= v && v <= hi}] @-}
+
+{-@ assume B.unsafeTake
+    :: n : Nat
+    -> { i : B.ByteString | n <= bslen i }
+    -> { o : B.ByteString | bslen o == n }
+  @-}
+
+
+
+
+
+
+
+
+
+
+
+
+
+--------------------------------------------------------------------------------
diff --git a/tests/todo/stacks1.hs b/tests/todo/stacks1.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/stacks1.hs
@@ -0,0 +1,112 @@
+module StackSet where
+
+import Data.Set (Set(..)) 
+
+data LL a = Nil | Cons { head :: a, tail :: LL a }
+
+{-@ data LL a = Nil | Cons { head :: a 
+                           , tail :: {v: LL a | not (Set_mem head (LLElts v))  } } 
+  @-}
+
+{-@ measure LLElts     :: LL a -> (Set a) 
+    LLElts (Nil)       = {v | (Set_emp v)}
+    LLElts (Cons x xs) = {v | v = (Set_cup (Set_sng x) (LLElts xs)) }
+  @-}
+
+{-@ predicate Disjoint x y   = (Set_emp (Set_cap x y))            @-}  
+{-@ predicate NotIn    x y = not (Set_mem x (LLElts y))           @-} 
+
+
+---------------------------------------------------------------------------------------------
+
+{-@ measure StackElts    :: Stack a -> (Set a) 
+    StackElts (St f u d) = (Set_cup (Set_sng f) (Set_cup (LLElts u) (LLElts d)))
+  @-}
+
+{-@ data Stack a = St { focus  :: a    
+                      , up     :: {vu: LL a | (NotIn focus vu) } 
+                      , down   :: {vd: LL a | ((NotIn focus vd) && (Disjoint (LLElts up) (LLElts vd))) } 
+                      } 
+  @-}
+
+data Stack a = St { focus  :: !a    
+                  , up     :: !(LL a) 
+                  , down   :: !(LL a)
+                  } 
+
+---------------------------------------------------------------------------------------------
+
+--| Super Vanilla Operations on Stacks
+
+{-@ fresh :: a -> Stack a @-}
+fresh x = St x Nil Nil
+
+{-@ moveUp :: Stack a -> Stack a @-}
+moveUp (St x (Cons y ys) zs) = St y ys (Cons x zs)
+moveUp s                     = s 
+
+{-@ moveDn :: Stack a -> Stack a @-}
+moveDn (St x ys (Cons z zs)) = St z (Cons x ys) zs
+moveDn s                     = s 
+
+
+---------------------------------------------------------------------------------------------
+
+{-@ measure MaybeStackElts :: Maybe (Stack a) -> (Set a) 
+    MaybeStackElts Nothing  = {v | (? Set_emp(v))  }
+    MaybeStackElts (Just s) = {v | v = StackElts s }
+  @-}
+
+{-@ measure WorkspaceElts :: Workspace i l a -> (Set a) 
+    WorkspaceElts (Workspace t l s) = (MaybeStackElts s) 
+  @-}
+
+data Workspace i l a = Workspace  { tag :: !i, layout :: l, stack :: Maybe (Stack a) }
+
+---------------------------------------------------------------------------------------------
+
+{-@ measure ScreenElts :: Screen i l a sid sd -> (Set a) 
+    ScreenElts (ScreenElts w s d) = (WorkspaceElts w) 
+  @-}
+
+data Screen i l a sid sd = Screen { workspace :: !(Workspace i l a)
+                                  , screen :: !sid
+                                  , screenDetail :: !sd }
+
+---------------------------------------------------------------------------------------------
+
+{-@ measure ListScreenElts :: [Screen i l a sid sd] -> (Set a) 
+    ListScreenElts ([])    =  {v | (Set_emp v)}
+    ListScreenElts (x:xs)  =  {v | v = (Set_cup (ScreenElts x) (ListScreenElts xs)) }
+  @-}
+
+
+{-@ measure ListWorkspaceElts :: [Workspace i l a] -> (Set a) 
+    ListWorkspaceElts ([])    =  {v | (Set_emp v)}
+    ListWorkspaceElts (x:xs)  =  {v | v = (Set_cup (WorkspaceElts x) (ListWorkspaceElts xs)) }
+  @-}
+
+data StackSet i l a sid sd =
+    StackSet { current  :: !(Screen i l a sid sd)    
+             , visible  :: {v : [Screen i l a sid sd] | (Disjoint  (ScreenElts current)     (ListScreenElts v)) }
+             , hidden   :: {v : [Workspace i l a]     | ((Disjoint (ScreenElts current)     (ListWorkspaceElts v)) && 
+                                                         (Disjoint (ListScreenElts visible) (ListWorkspaceElts v))) }        
+             , floating :: M.Map a RationalRect
+             } 
+
+data RationalRect = RationalRect Rational Rational Rational Rational
+
+----------------------------------------------------------------------------------------------------------------
+
+new :: (Integral s) => l -> [i] -> [sd] -> StackSet i l a s sd
+new l wids m 
+  | not (null wids) && length m <= length wids && not (null m)
+  = StackSet cur visi unseen M.empty
+  where (seen,unseen) = L.splitAt (length m) $ map (\i -> Workspace i l Nothing) wids
+        (cur:visi)    = [ Screen i s sd |  (i, s, sd) <- zip3 seen [0..] m ]
+                -- now zip up visibles with their screen id
+new _ _ _ = abort "non-positive argument to StackSet.new"
+
+
+abort :: {v: String | (0 = 1) } -> a
+abort x = error $ "xmonad: StackSet: " ++ x
diff --git a/tests/todo/state.hs b/tests/todo/state.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/state.hs
@@ -0,0 +1,74 @@
+module Compose where
+
+
+
+
+data ST s a = ST {runState :: s -> s}
+
+{-@ data ST s a <p :: s -> Prop, q :: s -> s -> Prop> = ST (runState :: x:s<p> -> s<q x>) @-}
+
+
+
+
+{-@ 
+cmp :: forall < pref :: s -> Prop, postf :: s -> s -> Prop
+              , pre  :: s -> Prop, postg :: s -> s -> Prop
+              , post :: s -> s -> Prop
+              >. 
+       {y:s -> s<postg y> -> s<pref>}
+       {x:s<pre> -> z:s<postg x> -> s<postf z> -> s<post x> }
+       f:(ST <pref, postf> s a)
+    -> g:(ST <pre , postg> s b)
+    ->   (ST <pre , post > s b)
+@-}
+
+cmp :: ST s a
+    -> ST s b
+    -> ST s b
+
+cmp (ST f) (ST g) = ST $ \s -> f (g s)
+
+
+{-@ incr :: ST <{\x -> x >= 0}, {\x v -> v = x + 1}> Nat Int @-}
+incr :: ST Int Int 
+incr = ST $ \x -> x + 1
+
+{-@ incr2 :: ST <{\x -> x >= 0}, {\x v -> v = x + 4}> Nat Int @-}
+incr2 :: ST Int Int 
+incr2 = cmp incr incr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/todo/tdb.hs b/tests/todo/tdb.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/tdb.hs
@@ -0,0 +1,13 @@
+module Main where
+
+zero' :: Int
+zero' = 0
+{-@ zero' :: {v: Int | false } @-}
+
+-- Throws NASTY GHC error because "Int" is not a tycon * -> *
+-- Should be some nicer error message that we can produce...
+{-@ print' :: Int {v: Int | true } -> IO () @-}
+print' :: Int -> IO ()
+print' = print
+
+main = print' zero'
diff --git a/tests/todo/trans.lhs b/tests/todo/trans.lhs
new file mode 100644
--- /dev/null
+++ b/tests/todo/trans.lhs
@@ -0,0 +1,27 @@
+
+
+module Tx where
+
+import Language.Haskell.Liquid.Prelude
+
+{- THIS IS A RANDOM COMMENT -}
+
+{-@ foo :: x: Int -> Int @-}
+foo :: Int -> Int
+foo x = x + 1
+
+{-@ transpose :: n:Int
+              -> m:{v:Int | v > 0} 
+              -> {v:[{v:[a] | len(v) = n}] | len(v) = m} 
+              -> {v:[{v:[a] | len(v) = m}] | len(v) = n} 
+  @-}
+transpose :: Int -> Int -> [[a]] -> [[a]]
+transpose 0 _ _              = []
+transpose n m ((x:xs) : xss) = (x : map head xss) : transpose (n - 1) m (xs : map tail xss)
+transpose n m ([] : _)       = liquidError "transpose1" 
+transpose n m []             = liquidError "transpose2"
+
+-- NEEDS TAGS: map head xss = [ h | (h:_) <- xss]
+-- NEEDS TAGS: map tail xss = [t | (_:t) <- xss]
+
+
diff --git a/tests/todo/tupleplus.hs b/tests/todo/tupleplus.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/tupleplus.hs
@@ -0,0 +1,18 @@
+module Goo where
+
+
+{-@ foo :: x:_ -> {v:_ | fst v + snd v = x} @-}
+foo :: Int -> (Int, Int)
+foo x = (2, x-2)
+
+
+{-@ test10 :: {v:_ | Prop v} @-}
+test10     = x + y == 10
+  where
+    (x, y) = foo 10
+
+-- THESE are also in GHC.Base.Spec
+{-@ qualif Fst(v:a, y:b): v = fst y @-}
+{-@ qualif Snd(v:a, y:b): v = snd y @-}
+
+
diff --git a/tests/todo/txrec0.hs b/tests/todo/txrec0.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/txrec0.hs
@@ -0,0 +1,27 @@
+module Test where
+
+{-@ type OList a = [a]<{v: a | (v >= fld)}> @-}
+
+{-@ filterGt :: (Ord a) => Maybe a -> OList a -> OList a @-}
+
+filterGt ::  Ord a => Maybe a -> [a] -> [a]
+filterGt Nothing  xs = xs
+filterGt (Just x) xs = filter' x xs
+-- The following works fine, because toplevel recs go through TXREC?
+-- filterGt (Just x) xs = filter'' x xs
+  where filter' _  []     = [] 
+        filter' b' (x:xs) = case compare b' x of 
+                              GT -> x : filter' b' xs 
+                              LT -> x:xs 
+                              EQ -> xs 
+
+filter'' _  []     = [] 
+filter'' b' (x:xs) = case compare b' x of 
+                      GT -> x : filter'' b' xs 
+                      LT -> x:xs 
+                      EQ -> xs 
+
+
+
+
+-- {- filter' :: (Ord a) => a -> OList a -> OList a @-}
diff --git a/tests/todo/vector2.hs b/tests/todo/vector2.hs
new file mode 100644
--- /dev/null
+++ b/tests/todo/vector2.hs
@@ -0,0 +1,15 @@
+module Vec0 where
+
+import qualified Data.Vector as V 
+
+propVec = (vs V.! 3) == 3
+  where xs    = [1,2,3,4] :: [Int]
+        vs    = V.fromList xs
+        
+{-@ unsafeLookup :: V.Vector a -> Int -> a @-}
+unsafeLookup x i = x V.! i
+
+{-@ safeLookup :: V.Vector a -> Int -> Maybe a @-}
+safeLookup x i 
+  | 0 <= i && i < V.length x = Just (x V.! i)
+  | otherwise                = Nothing 
